Decompiled source of Pages Of The Peak v0.1.1
Pages Of The Peak.dll
Decompiled 2 weeks 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.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using TMPro; using UnityEngine; using UnityEngine.Animations; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Playables; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("PagesOfThePeak")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.1.0")] [assembly: AssemblyInformationalVersion("0.1.1")] [assembly: AssemblyProduct("PagesOfThePeak")] [assembly: AssemblyTitle("PagesOfThePeak")] [assembly: AssemblyVersion("0.1.1.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace PagesOfThePeak { internal sealed class DrowsyVisualSuppressor : MonoBehaviour { private Plugin plugin; private FieldInfo drowsyFxField; private MethodInfo disableMethod; private object lastFx; private float nextClear; private bool logged; public void Initialize(Plugin owner) { plugin = owner; ResolveMembers(); } private void ResolveMembers() { if (drowsyFxField == null) { drowsyFxField = AccessTools.Field(typeof(GUIManager), "drowsyFX"); } if (drowsyFxField != null && disableMethod == null) { disableMethod = AccessTools.Method(drowsyFxField.FieldType, "Disable", Type.EmptyTypes, (Type[])null); } } private bool ShouldSuppress() { if ((Object)(object)plugin != (Object)null && plugin.IsCurseActive && plugin.State != null && plugin.State.phase == "Watching" && plugin.SuppressDrowsyCameraFX != null) { return plugin.SuppressDrowsyCameraFX.Value; } return false; } private void Update() { if (!ShouldSuppress()) { logged = false; lastFx = null; } else if (!(Time.unscaledTime < nextClear)) { nextClear = Time.unscaledTime + 0.15f; ClearCurrentEffect(); } } private void ClearCurrentEffect() { ResolveMembers(); GUIManager instance = GUIManager.instance; if (!Object.op_Implicit((Object)(object)instance) || drowsyFxField == null || disableMethod == null) { return; } try { object value = drowsyFxField.GetValue(instance); if (value != null) { disableMethod.Invoke(value, null); lastFx = value; if (!logged) { logged = true; plugin.Trace("Drowsy camera FX suppressed through GUIManager.drowsyFX ScreenVFX.Disable(); Drowsy status/meter remains active."); } } } catch (Exception ex) { plugin.InternalWarn("Drowsy camera FX clear failed safely: " + ex.GetBaseException().Message); } } public void Dispose() { plugin = null; lastFx = null; } private void OnDestroy() { Dispose(); } } internal sealed class FlashlightController : MonoBehaviour { private Plugin plugin; private GameObject lightObject; private Light spot; private Camera attachedCamera; private bool isOn; private float nextCameraCheck; private float nextSettingsRefresh; private bool lastDesiredEnabled; public bool IsOn => isOn; public void Initialize(Plugin owner) { plugin = owner; isOn = plugin.FlashlightStartOn.Value; EnsureLight(); ApplySettings(); SetEnabled(isOn); } private void EnsureLight() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown Camera main = Camera.main; if (Object.op_Implicit((Object)(object)main) && (!Object.op_Implicit((Object)(object)lightObject) || !((Object)(object)attachedCamera == (Object)(object)main))) { if (Object.op_Implicit((Object)(object)lightObject)) { Object.Destroy((Object)(object)lightObject); } attachedCamera = main; lightObject = new GameObject("POTP_CameraFlashlight"); lightObject.transform.SetParent(((Component)main).transform, false); spot = lightObject.AddComponent<Light>(); spot.type = (LightType)0; spot.renderMode = (LightRenderMode)1; ApplyTransform(); ApplySettings(); SetEnabled(isOn); } } private void ApplyTransform() { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)lightObject) && !((Object)(object)plugin == (Object)null)) { lightObject.transform.localPosition = new Vector3(plugin.FlashlightHorizontalOffset.Value, plugin.FlashlightVerticalOffset.Value, plugin.FlashlightForwardOffset.Value); lightObject.transform.localRotation = Quaternion.identity; } } private void ApplySettings() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)spot) && !((Object)(object)plugin == (Object)null)) { float value = plugin.FlashlightColorTemperature.Value; spot.color = Mathf.CorrelatedColorTemperatureToRGB(value); spot.intensity = plugin.FlashlightIntensity.Value; spot.range = plugin.FlashlightRange.Value; spot.spotAngle = plugin.FlashlightSpotAngle.Value; spot.innerSpotAngle = Mathf.Min(plugin.FlashlightInnerSpotAngle.Value, Mathf.Max(1f, spot.spotAngle - 1f)); spot.shadows = (LightShadows)(plugin.FlashlightShadows.Value ? 2 : 0); spot.shadowStrength = plugin.FlashlightShadowStrength.Value; spot.shadowBias = plugin.FlashlightShadowBias.Value; spot.shadowNormalBias = plugin.FlashlightShadowNormalBias.Value; } } private void SetEnabled(bool value) { isOn = value; if (Object.op_Implicit((Object)(object)spot)) { ((Behaviour)spot).enabled = value && (Object)(object)plugin != (Object)null && plugin.EnableBuiltInFlashlight.Value; } } private void Update() { if ((Object)(object)plugin == (Object)null) { return; } if (!Object.op_Implicit((Object)(object)lightObject) || !Object.op_Implicit((Object)(object)attachedCamera) || Time.unscaledTime >= nextCameraCheck) { nextCameraCheck = Time.unscaledTime + 1f; EnsureLight(); } if (Time.unscaledTime >= nextSettingsRefresh) { nextSettingsRefresh = Time.unscaledTime + 0.25f; ApplyTransform(); ApplySettings(); } Keyboard current = Keyboard.current; if (current != null && plugin.EnableBuiltInFlashlight.Value && ((ButtonControl)current.lKey).wasPressedThisFrame) { SetEnabled(!isOn); plugin.Trace("Flashlight " + (isOn ? "ON" : "OFF")); } if (Object.op_Implicit((Object)(object)spot)) { bool flag = plugin.EnableBuiltInFlashlight.Value && isOn; if (flag != lastDesiredEnabled || ((Behaviour)spot).enabled != flag) { lastDesiredEnabled = flag; ((Behaviour)spot).enabled = flag; } } } private void LateUpdate() { if (!Object.op_Implicit((Object)(object)lightObject) || !Object.op_Implicit((Object)(object)attachedCamera)) { EnsureLight(); } } public float BeamExposureAt(Vector3 worldPoint) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: 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_014b: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)plugin == (Object)null || !plugin.EnableBuiltInFlashlight.Value || !isOn || !Object.op_Implicit((Object)(object)spot) || !((Behaviour)spot).enabled || !Object.op_Implicit((Object)(object)lightObject)) { return 0f; } Vector3 position = lightObject.transform.position; Vector3 val = worldPoint - position; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude <= 0.01f || magnitude > spot.range) { return 0f; } Vector3 val2 = val / magnitude; float num = Vector3.Angle(lightObject.transform.forward, val2); float num2 = Mathf.Max(1f, spot.spotAngle * 0.5f); float num3 = Mathf.Clamp(spot.innerSpotAngle * 0.5f, 0f, num2 - 0.01f); if (num >= num2) { return 0f; } float num4 = ((num <= num3) ? 1f : (1f - Mathf.InverseLerp(num3, num2, num))); float num5 = Mathf.Clamp01(magnitude / Mathf.Max(0.01f, spot.range)); float num6 = 1f - num5 * num5; if (!World.ClearSight(position, worldPoint)) { return 0f; } return Mathf.Clamp01(num4 * num6); } public void Dispose() { if (Object.op_Implicit((Object)(object)lightObject)) { Object.Destroy((Object)(object)lightObject); } lightObject = null; spot = null; attachedCamera = null; } private void OnDestroy() { Dispose(); } } internal sealed class PagePromptController : MonoBehaviour { private Plugin plugin; private GameObject root; private TextMeshProUGUI text; private bool wanted; private bool peakFontApplied; private float nextFontSearch; private float lastFontSize = -1f; public void Initialize(Plugin owner) { plugin = owner; BuildUI(); } private void BuildUI() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_006e: 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_0099: Expected O, but got Unknown //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: 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_010a: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)root)) { root = new GameObject("POTP_PagePromptCanvas"); root.transform.SetParent(((Component)this).transform, false); Canvas obj = root.AddComponent<Canvas>(); obj.renderMode = (RenderMode)0; obj.sortingOrder = 250; CanvasScaler obj2 = root.AddComponent<CanvasScaler>(); obj2.uiScaleMode = (ScaleMode)1; obj2.referenceResolution = new Vector2(1920f, 1080f); obj2.matchWidthOrHeight = 0.5f; root.AddComponent<GraphicRaycaster>(); GameObject val = new GameObject("PagePrompt"); val.transform.SetParent(root.transform, false); RectTransform obj3 = val.AddComponent<RectTransform>(); obj3.anchorMin = new Vector2(0.5f, 0.35f); obj3.anchorMax = new Vector2(0.5f, 0.35f); obj3.pivot = new Vector2(0.5f, 0.5f); obj3.anchoredPosition = Vector2.zero; obj3.sizeDelta = new Vector2(900f, 90f); text = val.AddComponent<TextMeshProUGUI>(); ((TMP_Text)text).text = "[F] Grab Page"; ((TMP_Text)text).alignment = (TextAlignmentOptions)514; ((TMP_Text)text).fontSize = plugin.PagePromptFontSize.Value; ((TMP_Text)text).fontStyle = (FontStyles)1; ((Graphic)text).color = Color.white; ((Graphic)text).raycastTarget = false; ((TMP_Text)text).textWrappingMode = (TextWrappingModes)0; ((TMP_Text)text).overflowMode = (TextOverflowModes)0; root.SetActive(false); TryCopyPeakFont(); } } private TMP_Text FindPeakPromptText() { GUIManager instance = GUIManager.instance; if (!Object.op_Implicit((Object)(object)instance)) { return null; } string[] array = new string[5] { "interactPromptText", "promptText", "interactText", "interactNameText", "secondaryInteractPromptText" }; foreach (string text in array) { try { FieldInfo fieldInfo = AccessTools.Field(typeof(GUIManager), text); if (!(fieldInfo == null)) { object? value = fieldInfo.GetValue(instance); TMP_Text val = (TMP_Text)((value is TMP_Text) ? value : null); if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.font)) { return val; } } } catch { } } return ((IEnumerable<TMP_Text>)((Component)instance).GetComponentsInChildren<TMP_Text>(true)).FirstOrDefault((Func<TMP_Text, bool>)((TMP_Text t) => Object.op_Implicit((Object)(object)t) && Object.op_Implicit((Object)(object)t.font))); } private void TryCopyPeakFont() { if (!Object.op_Implicit((Object)(object)text) || peakFontApplied) { return; } TMP_Text val = FindPeakPromptText(); if (Object.op_Implicit((Object)(object)val)) { ((TMP_Text)text).font = val.font; peakFontApplied = true; if (Object.op_Implicit((Object)(object)val.fontSharedMaterial)) { ((TMP_Text)text).fontSharedMaterial = val.fontSharedMaterial; } plugin.Trace("Page interaction prompt is using PEAK TMP font: " + ((Object)val.font).name); } } public void SetVisible(bool value) { wanted = value; if (!Object.op_Implicit((Object)(object)root)) { BuildUI(); } if (Object.op_Implicit((Object)(object)root) && root.activeSelf != wanted) { root.SetActive(wanted); } } private void Update() { if (!Object.op_Implicit((Object)(object)root)) { return; } if (Time.unscaledTime >= nextFontSearch) { nextFontSearch = Time.unscaledTime + 1f; TryCopyPeakFont(); } if (Object.op_Implicit((Object)(object)text)) { float value = plugin.PagePromptFontSize.Value; if (Mathf.Abs(value - lastFontSize) > 0.01f) { lastFontSize = value; ((TMP_Text)text).fontSize = value; } } } public void Dispose() { if (Object.op_Implicit((Object)(object)root)) { Object.Destroy((Object)(object)root); } root = null; text = null; } private void OnDestroy() { Dispose(); } } internal sealed class PageVisualController : MonoBehaviour { private Plugin plugin; private readonly Dictionary<Material, Color> baseColors = new Dictionary<Material, Color>(); private float currentVisibility = 1f; private float targetVisibility = 1f; private float nextExposureSample; private float lastAppliedVisibility = -1f; private bool lastRevealEnabled; public void Initialize(Plugin owner) { plugin = owner; CaptureColors(); } public void SetRevealEnabled(bool value) { if (!value) { targetVisibility = 1f; currentVisibility = 1f; ApplyVisibility(1f, force: true); ((Behaviour)this).enabled = false; } else { ((Behaviour)this).enabled = true; nextExposureSample = 0f; lastAppliedVisibility = -1f; } } private void CaptureColors() { //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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) baseColors.Clear(); Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if (!Object.op_Implicit((Object)(object)val)) { continue; } Material[] sharedMaterials = val.sharedMaterials; foreach (Material val2 in sharedMaterials) { if (Object.op_Implicit((Object)(object)val2) && !baseColors.ContainsKey(val2)) { Color value = Color.white; if (val2.HasProperty("_BaseColor")) { value = val2.GetColor("_BaseColor"); } else if (val2.HasProperty("_Color")) { value = val2.GetColor("_Color"); } baseColors[val2] = value; } } } } private void ApplyVisibility(float visibility, bool force = false) { //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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) if (!force && lastAppliedVisibility >= 0f && Mathf.Abs(visibility - lastAppliedVisibility) < 0.004f) { return; } lastAppliedVisibility = visibility; Color val = default(Color); foreach (KeyValuePair<Material, Color> baseColor in baseColors) { Material key = baseColor.Key; if (Object.op_Implicit((Object)(object)key)) { Color value = baseColor.Value; ((Color)(ref val))..ctor(value.r * visibility, value.g * visibility, value.b * visibility, value.a); if (key.HasProperty("_BaseColor")) { key.SetColor("_BaseColor", val); } if (key.HasProperty("_Color")) { key.SetColor("_Color", val); } if (key.HasProperty("_EmissionColor")) { key.SetColor("_EmissionColor", Color.black); } key.DisableKeyword("_EMISSION"); } } } private void Update() { //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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)plugin == (Object)null) && !(Time.unscaledTime < nextExposureSample)) { float num = ((nextExposureSample <= 0f) ? 0.05f : Mathf.Max(0.001f, Time.unscaledTime - (nextExposureSample - 0.05f))); nextExposureSample = Time.unscaledTime + 0.05f; Vector3 worldPoint = ((Component)this).transform.position + Vector3.up * 0.15f; float num2 = plugin.FlashlightExposureAt(worldPoint); num2 = Mathf.Clamp01(num2 * plugin.PageFlashlightRevealBoost.Value); targetVisibility = Mathf.Lerp(plugin.PageDarkVisibility.Value, 1f, num2); currentVisibility = Mathf.MoveTowards(currentVisibility, targetVisibility, num * plugin.PageRevealFadeSpeed.Value); ApplyVisibility(currentVisibility); } } private void OnDestroy() { //IL_003b: 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) foreach (KeyValuePair<Material, Color> baseColor in baseColors) { Material key = baseColor.Key; if (Object.op_Implicit((Object)(object)key)) { if (key.HasProperty("_BaseColor")) { key.SetColor("_BaseColor", baseColor.Value); } if (key.HasProperty("_Color")) { key.SetColor("_Color", baseColor.Value); } } } } } [HarmonyPatch(typeof(Scoutmaster), "Start")] internal static class EnemyStartPatch { private static void Prefix(Scoutmaster __instance) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown if (!((Object)(object)Plugin.Instance == (Object)null) && Plugin.Instance.IsOurEnemy(__instance) && Object.op_Implicit((Object)(object)__instance.mat)) { __instance.mat = new Material(__instance.mat); } } private static void Postfix(Scoutmaster __instance) { if (!((Object)(object)Plugin.Instance == (Object)null) && Plugin.Instance.IsOurEnemy(__instance)) { (AccessTools.Field(typeof(Scoutmaster), "AllScoutmasters").GetValue(null) as IList)?.Remove(__instance); Plugin.Instance.AttachCustomVisual(__instance); } } } [HarmonyPatch(typeof(Scoutmaster), "OnDestroy")] internal static class EnemyDestroyPatch { private static void Prefix(Scoutmaster __instance) { if ((Object)(object)Plugin.Instance != (Object)null && Plugin.Instance.IsOurEnemy(__instance)) { Plugin.Instance.DetachCustomVisual(__instance); if (Object.op_Implicit((Object)(object)__instance.mat)) { Object.Destroy((Object)(object)__instance.mat); } } } } [HarmonyPatch(typeof(Scoutmaster), "Update")] internal static class EnemyUpdatePatch { private static bool Prefix(Scoutmaster __instance) { Plugin instance = Plugin.Instance; if ((Object)(object)instance == (Object)null || !instance.IsOurEnemy(__instance)) { return true; } instance.EnemyUpdate(__instance); return false; } } [HarmonyPatch(typeof(Scoutmaster), "FixedUpdate")] internal static class EnemyPhysicsPatch { private static bool Prefix(Scoutmaster __instance) { if (!((Object)(object)Plugin.Instance == (Object)null)) { return !Plugin.Instance.IsOurEnemy(__instance); } return true; } } [HarmonyPatch(typeof(GUIManager), "DrowsyFX")] internal static class DrowsyCameraVisualPatch { private static bool Prefix() { Plugin instance = Plugin.Instance; if ((Object)(object)instance == (Object)null) { return true; } if (instance.IsCurseActive && instance.SuppressDrowsyCameraFX != null) { return !instance.SuppressDrowsyCameraFX.Value; } return true; } } [HarmonyPatch(typeof(Character), "UpdateVariablesFixed")] internal static class RegenPatch { private static float Scale(float amount, Character character) { if (!((Object)(object)Plugin.Instance == (Object)null)) { return Plugin.Instance.Regen(amount, character); } return amount; } private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = instructions.ToList(); MethodInfo add = AccessTools.Method(typeof(Character), "AddStamina", new Type[1] { typeof(float) }, (Type[])null); if (list.Count((CodeInstruction val2) => CodeInstructionExtensions.Calls(val2, add)) != 1) { throw new InvalidOperationException("Natural regen hook changed: expected exactly one AddStamina call."); } foreach (CodeInstruction i in list) { if (CodeInstructionExtensions.Calls(i, add)) { CodeInstruction val = new CodeInstruction(OpCodes.Ldarg_0, (object)null); CodeInstructionExtensions.MoveLabelsTo(i, val); yield return val; yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(RegenPatch), "Scale", (Type[])null, (Type[])null)); } yield return i; } } } internal enum SlenderContactOutcome { KnockoutOnly, AlwaysKill, FirstKnockoutThenKill } [BepInPlugin("CircusFriendsStudios.PagesOfThePeak", "Pages of the Peak", "0.1.1")] public sealed class Plugin : BaseUnityPlugin, IOnEventCallback { public const string Guid = "CircusFriendsStudios.PagesOfThePeak"; public const string Version = "0.1.1"; private const string PlayerKey = "CFS.POTP.Version"; private const string PlayerUseKey = "CFS.POTP.Use"; private const string RoomStateKey = "CFS.POTP.State"; private const string NetworkBuild = "0.1.1-mpfix5"; private const byte EventCode = 179; public static Plugin Instance; internal RunState State = new RunState(); internal ConfigEntry<int> PageCount; internal ConfigEntry<int> HuntAt; internal ConfigEntry<float> Bonus; internal ConfigEntry<float> StaticStrength; internal ConfigEntry<float> WatchDrowsyPerSecond; internal ConfigEntry<float> WatchGazeThreshold; internal ConfigEntry<float> WatchEffectDistance; internal ConfigEntry<float> HuntMaxRunSpeed; internal ConfigEntry<float> HuntMaxClimbSpeed; internal ConfigEntry<int> HuntSprintAtPages; internal ConfigEntry<SlenderContactOutcome> HuntContactOutcome; internal ConfigEntry<float> EventCooldownMin; internal ConfigEntry<float> EventCooldownMax; internal ConfigEntry<float> EventCooldownReductionPerPage; internal ConfigEntry<float> EventCooldownFloor; internal ConfigEntry<bool> DebugKeys; internal ConfigEntry<bool> ShowDebugText; internal ConfigEntry<bool> VerboseNetworkLogging; internal ConfigEntry<bool> EnableStatic; internal ConfigEntry<bool> EnableWatchDrowsy; internal ConfigEntry<bool> SuppressDrowsyCameraFX; internal ConfigEntry<bool> EnableBuiltInFlashlight; internal ConfigEntry<bool> FlashlightStartOn; internal ConfigEntry<bool> FlashlightShadows; internal ConfigEntry<float> FlashlightIntensity; internal ConfigEntry<float> FlashlightRange; internal ConfigEntry<float> FlashlightSpotAngle; internal ConfigEntry<float> FlashlightInnerSpotAngle; internal ConfigEntry<float> FlashlightColorTemperature; internal ConfigEntry<float> FlashlightShadowStrength; internal ConfigEntry<float> FlashlightShadowBias; internal ConfigEntry<float> FlashlightShadowNormalBias; internal ConfigEntry<float> FlashlightHorizontalOffset; internal ConfigEntry<float> FlashlightVerticalOffset; internal ConfigEntry<float> FlashlightForwardOffset; internal ConfigEntry<bool> EnableCustomSlender; internal ConfigEntry<bool> HideNativeScoutmaster; internal ConfigEntry<bool> EnableSlenderAudio; internal ConfigEntry<bool> ForceSlenderLitMaterials; internal ConfigEntry<bool> DisableSlenderEmission; internal ConfigEntry<bool> SlenderAutoLighting; internal ConfigEntry<bool> SlenderFlashlightRevealMode; internal ConfigEntry<bool> DisableSlenderEnvironmentReflections; internal ConfigEntry<float> SlenderVisualScale; internal ConfigEntry<float> SlenderVisualYOffset; internal ConfigEntry<float> SlenderVisualYaw; internal ConfigEntry<float> SlenderAlbedoMultiplier; internal ConfigEntry<float> SlenderDarkVisibility; internal ConfigEntry<float> SlenderRevealFadeSpeed; internal ConfigEntry<float> SlenderFlashlightRevealBoost; internal ConfigEntry<float> SlenderHuntAudioVolume; internal ConfigEntry<float> SlenderHuntAudioMinDistance; internal ConfigEntry<float> SlenderHuntAudioMaxDistance; internal ConfigEntry<float> SlenderHuntAudioFadeSeconds; internal ConfigEntry<string> ScrollName; internal ConfigEntry<bool> EnableCustomPageModels; internal ConfigEntry<bool> ShowPageLabel; internal ConfigEntry<bool> RandomizePageYaw; internal ConfigEntry<bool> ForcePageLitMaterials; internal ConfigEntry<bool> DisablePageEmission; internal ConfigEntry<bool> DisablePageEnvironmentReflections; internal ConfigEntry<bool> PageFlashlightRevealMode; internal ConfigEntry<float> CustomPageScale; internal ConfigEntry<float> CustomPageVerticalOffset; internal ConfigEntry<float> CustomPagePitch; internal ConfigEntry<float> CustomPageYaw; internal ConfigEntry<float> CustomPageRoll; internal ConfigEntry<float> PageDarkVisibility; internal ConfigEntry<float> PageFlashlightRevealBoost; internal ConfigEntry<float> PageRevealFadeSpeed; internal ConfigEntry<float> PagePromptFontSize; internal ConfigEntry<float> PageFloatingLabelSize; internal ConfigEntry<float> PageFloatingLabelHeight; private Harmony harmony; private World world; private FlashlightController flashlight; private DrowsyVisualSuppressor drowsyVisualSuppressor; private PagePromptController pagePrompt; private float tick; private float broadcast; private float nextRequest; private float nextRoomPoll; private float nextNetworkHeartbeat; private float eventAt; private float eventEnd; private float pendingUntil; private float nextMapLookup; private float nextModRosterCheck; private float nextFallbackPoll; private float nextPromptProbe; private int mapId; private int masterId; private int lastSegment = -1; private MapHandler cachedMap; private bool cachedAllModded; private int useNonce; private int lastRemoteAttackSerial; private float lastSnapshot; private float moveCheck; private float attackGrace; private float watchDrowsyPending; private string huntDiagnostic = ""; private Vector3 lastEnemyPosition; private readonly Dictionary<int, int> attempts = new Dictionary<int, int>(); private readonly Dictionary<int, float> requests = new Dictionary<int, float>(); private readonly Dictionary<int, string> lastUseFallback = new Dictionary<int, string>(); private readonly HashSet<int> knocked = new HashSet<int>(); private readonly HashSet<int> mercyUsedThisSegment = new HashSet<int>(); private string notice = "Waiting for a climb"; private string waitingReason = ""; private bool active; private bool advertised; private bool watchEffectFaulted; private Scoutmaster localEnemy; private Character localTarget; private float lastWatchDot; private string watchGazeReason = "idle"; private float nextGazeErrorLog; private AssetBundle slenderBundle; private GameObject slenderPrefab; private float nextSlenderLightingDetection; private bool cachedPitchBlackDetected; private bool? lastReportedSlenderBlackoutMode; private string slenderBundlePath = ""; private readonly Dictionary<int, GameObject> slenderVisuals = new Dictionary<int, GameObject>(); internal bool Host { get { if (PhotonNetwork.InRoom) { return PhotonNetwork.IsMasterClient; } return false; } } internal bool IsCurseActive => active; internal static bool Alive(Character c) { if (Object.op_Implicit((Object)(object)c) && c.IsInitialized && !c.isBot && !c.isScoutmaster && !c.isZombie && !c.IsGhost && !c.data.dead) { return !c.data.passedOut; } return false; } internal void Log(string s) { ((BaseUnityPlugin)this).Logger.LogInfo((object)s); notice = s; } internal void Trace(string s) { ((BaseUnityPlugin)this).Logger.LogInfo((object)s); } internal void InternalWarn(string s) { ((BaseUnityPlugin)this).Logger.LogWarning((object)s); } private void Awake() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Expected O, but got Unknown //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Expected O, but got Unknown //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Expected O, but got Unknown //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Expected O, but got Unknown //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Expected O, but got Unknown //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Expected O, but got Unknown //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Expected O, but got Unknown //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Expected O, but got Unknown //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Expected O, but got Unknown //IL_0381: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Expected O, but got Unknown //IL_03bf: Unknown result type (might be due to invalid IL or missing references) //IL_03c9: Expected O, but got Unknown //IL_03fd: Unknown result type (might be due to invalid IL or missing references) //IL_0407: Expected O, but got Unknown //IL_043b: Unknown result type (might be due to invalid IL or missing references) //IL_0445: Expected O, but got Unknown //IL_0479: Unknown result type (might be due to invalid IL or missing references) //IL_0483: Expected O, but got Unknown //IL_04f9: Unknown result type (might be due to invalid IL or missing references) //IL_0503: Expected O, but got Unknown //IL_059a: Unknown result type (might be due to invalid IL or missing references) //IL_05a4: Expected O, but got Unknown //IL_05d8: Unknown result type (might be due to invalid IL or missing references) //IL_05e2: Expected O, but got Unknown //IL_0616: Unknown result type (might be due to invalid IL or missing references) //IL_0620: Expected O, but got Unknown //IL_0675: Unknown result type (might be due to invalid IL or missing references) //IL_067f: Expected O, but got Unknown //IL_06f5: Unknown result type (might be due to invalid IL or missing references) //IL_06ff: Expected O, but got Unknown //IL_0733: Unknown result type (might be due to invalid IL or missing references) //IL_073d: Expected O, but got Unknown //IL_0771: Unknown result type (might be due to invalid IL or missing references) //IL_077b: Expected O, but got Unknown //IL_07f1: Unknown result type (might be due to invalid IL or missing references) //IL_07fb: Expected O, but got Unknown //IL_082f: Unknown result type (might be due to invalid IL or missing references) //IL_0839: Expected O, but got Unknown //IL_086d: Unknown result type (might be due to invalid IL or missing references) //IL_0877: Expected O, but got Unknown //IL_08ab: Unknown result type (might be due to invalid IL or missing references) //IL_08b5: Expected O, but got Unknown //IL_08e9: Unknown result type (might be due to invalid IL or missing references) //IL_08f3: Expected O, but got Unknown //IL_0927: Unknown result type (might be due to invalid IL or missing references) //IL_0931: Expected O, but got Unknown //IL_0965: Unknown result type (might be due to invalid IL or missing references) //IL_096f: Expected O, but got Unknown //IL_09a3: Unknown result type (might be due to invalid IL or missing references) //IL_09ad: Expected O, but got Unknown //IL_0a02: Unknown result type (might be due to invalid IL or missing references) //IL_0a0c: Expected O, but got Unknown //IL_0a40: Unknown result type (might be due to invalid IL or missing references) //IL_0a4a: Expected O, but got Unknown //IL_0a7e: Unknown result type (might be due to invalid IL or missing references) //IL_0a88: Expected O, but got Unknown //IL_0b65: Unknown result type (might be due to invalid IL or missing references) //IL_0b6f: Expected O, but got Unknown //IL_0ba3: Unknown result type (might be due to invalid IL or missing references) //IL_0bad: Expected O, but got Unknown //IL_0be1: Unknown result type (might be due to invalid IL or missing references) //IL_0beb: Expected O, but got Unknown //IL_0c1f: Unknown result type (might be due to invalid IL or missing references) //IL_0c29: Expected O, but got Unknown //IL_0c5d: Unknown result type (might be due to invalid IL or missing references) //IL_0c67: Expected O, but got Unknown //IL_0cdd: Unknown result type (might be due to invalid IL or missing references) //IL_0ce7: Expected O, but got Unknown //IL_0d1b: Unknown result type (might be due to invalid IL or missing references) //IL_0d25: Expected O, but got Unknown //IL_0ddd: Unknown result type (might be due to invalid IL or missing references) //IL_0de7: Expected O, but got Unknown //IL_0e1b: Unknown result type (might be due to invalid IL or missing references) //IL_0e25: Expected O, but got Unknown //IL_0e59: Unknown result type (might be due to invalid IL or missing references) //IL_0e63: Expected O, but got Unknown //IL_0e97: Unknown result type (might be due to invalid IL or missing references) //IL_0ea1: Expected O, but got Unknown //IL_0f15: Unknown result type (might be due to invalid IL or missing references) //IL_0f1f: Expected O, but got Unknown Instance = this; PageCount = ((BaseUnityPlugin)this).Config.Bind<int>("Pages", "PagesPerBiome", 24, new ConfigDescription("Pages placed in each mountain biome/segment. Progress and regen reset when the next segment becomes active. Increase this for larger multiplayer lobbies.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 48), Array.Empty<object>())); Bonus = ((BaseUnityPlugin)this).Config.Bind<float>("Reward", "RegenPerPage", 0.02f, new ConfigDescription("Additive natural stamina regeneration bonus to the collector for the current biome. Resets on segment transition.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.1f), Array.Empty<object>())); HuntAt = ((BaseUnityPlugin)this).Config.Bind<int>("Threat", "HuntsStartAtPages", 3, new ConfigDescription("Shared pages needed to enable hunts.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 30), Array.Empty<object>())); HuntMaxRunSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Hunt", "MaxRunSpeedMultiplier", 2f, new ConfigDescription("Ground chase speed multiplier reached at the biome page maximum. 1.0 = vanilla movement pace.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), Array.Empty<object>())); HuntMaxClimbSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Hunt", "MaxClimbSpeedMultiplier", 2f, new ConfigDescription("Climbing speed multiplier reached at the biome page maximum.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), Array.Empty<object>())); HuntSprintAtPages = ((BaseUnityPlugin)this).Config.Bind<int>("Hunt", "ForceSprintAtPages", 6, new ConfigDescription("At this many collected pages, Hunt mode holds Scoutmaster sprint while chasing. This is editable independently of PagesPerBiome.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 48), Array.Empty<object>())); HuntContactOutcome = ((BaseUnityPlugin)this).Config.Bind<SlenderContactOutcome>("Hunt", "ContactOutcome", SlenderContactOutcome.FirstKnockoutThenKill, "What happens when Slenderman catches a player. KnockoutOnly always passes the player out; AlwaysKill uses PEAK's full death path; FirstKnockoutThenKill gives each player one knockout/mercy per biome, then later catches in that biome are fatal."); EventCooldownMin = ((BaseUnityPlugin)this).Config.Bind<float>("Threat", "CooldownMinSeconds", 20f, new ConfigDescription("Lower end of the encounter cooldown at low page counts.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 90f), Array.Empty<object>())); EventCooldownMax = ((BaseUnityPlugin)this).Config.Bind<float>("Threat", "CooldownMaxSeconds", 36f, new ConfigDescription("Upper end of the encounter cooldown at low page counts.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(8f, 120f), Array.Empty<object>())); EventCooldownReductionPerPage = ((BaseUnityPlugin)this).Config.Bind<float>("Threat", "CooldownReductionPerPage", 1.25f, new ConfigDescription("Seconds removed from the encounter cooldown for each page after the first.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>())); EventCooldownFloor = ((BaseUnityPlugin)this).Config.Bind<float>("Threat", "CooldownFloorSeconds", 10f, new ConfigDescription("Hard minimum encounter cooldown at high page counts.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(4f, 60f), Array.Empty<object>())); EnableCustomSlender = ((BaseUnityPlugin)this).Config.Bind<bool>("Slender Model", "EnableCustomModel", true, "Load pagesofthepeak_slender from the BepInEx plugins folder and use it as the visible enemy model."); HideNativeScoutmaster = ((BaseUnityPlugin)this).Config.Bind<bool>("Slender Model", "HideNativeScoutmaster", true, "Hide the PEAK Scoutmaster renderers after the custom Slender model attaches. Physics and AI remain active."); EnableSlenderAudio = ((BaseUnityPlugin)this).Config.Bind<bool>("Slender Audio", "EnableHuntAudio", true, "Play the custom Slender prefab audio only during Hunt mode. Audio is fully 3D/spatial and follows Slender, so distance and direction are audible."); SlenderHuntAudioVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Slender Audio", "HuntAudioVolume", 0.7f, new ConfigDescription("Master volume for Slender Hunt audio.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); SlenderHuntAudioMinDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Slender Audio", "MinDistance", 4f, new ConfigDescription("Distance in metres at which Hunt audio is at full volume.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 20f), Array.Empty<object>())); SlenderHuntAudioMaxDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Slender Audio", "MaxDistance", 45f, new ConfigDescription("Distance in metres at which Hunt audio fades to effectively inaudible.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 120f), Array.Empty<object>())); SlenderHuntAudioFadeSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Slender Audio", "FadeSeconds", 0.35f, new ConfigDescription("Fade-in/fade-out time when Hunt starts or ends.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.02f, 3f), Array.Empty<object>())); SlenderVisualScale = ((BaseUnityPlugin)this).Config.Bind<float>("Slender Model", "Scale", 1f, new ConfigDescription("Uniform scale of the custom Slender visual.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 4f), Array.Empty<object>())); SlenderVisualYOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Slender Model", "VerticalOffset", 0f, new ConfigDescription("Vertical local offset of the custom Slender visual in metres.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-3f, 3f), Array.Empty<object>())); SlenderVisualYaw = ((BaseUnityPlugin)this).Config.Bind<float>("Slender Model", "YawOffset", 0f, new ConfigDescription("Local Y-axis rotation correction for the custom Slender visual.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-180f, 180f), Array.Empty<object>())); ForceSlenderLitMaterials = ((BaseUnityPlugin)this).Config.Bind<bool>("Slender Model", "ForceLitMaterials", true, "Force every custom Slender material onto PEAK/URP Lit so blackout/night lighting and the built-in flashlight affect him normally."); DisableSlenderEmission = ((BaseUnityPlugin)this).Config.Bind<bool>("Slender Model", "DisableMaterialEmission", true, "Strip emission/self-illumination from the custom Slender materials so he cannot glow in darkness."); SlenderAlbedoMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Slender Model", "AlbedoMultiplier", 1f, new ConfigDescription("Optional overall material darkness multiplier. 1.0 preserves the original colors; lower values darken the model while still allowing lights/flashlight to illuminate it.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.15f, 1f), Array.Empty<object>())); DisableSlenderEnvironmentReflections = ((BaseUnityPlugin)this).Config.Bind<bool>("Slender Model", "DisableEnvironmentReflections", true, "When blackout rendering is active, suppress reflection/light probes and environment specular highlights so Slender cannot glow from ambient sky/probe lighting."); SlenderAutoLighting = ((BaseUnityPlugin)this).Config.Bind<bool>("Slender Model", "AutoLightingCompatibility", true, "Automatically use normal PEAK lighting for vanilla day/night gameplay and enable the special flashlight-only blackout treatment when a loaded BepInEx plugin is detected as Pitch Black/PitchBlack. Turn OFF to use FlashlightRevealMode manually."); SlenderFlashlightRevealMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Slender Model", "FlashlightRevealMode", true, "Manual blackout override used only when AutoLightingCompatibility is OFF. ON = flashlight-only blackout treatment; OFF = normal PEAK/URP lighting."); SlenderDarkVisibility = ((BaseUnityPlugin)this).Config.Bind<float>("Slender Model", "DarkVisibility", 0.02f, new ConfigDescription("How visible Slender remains when FlashlightRevealMode is enabled but the beam is not on him. 0 = completely black, 0.01 = tiny silhouette.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.35f), Array.Empty<object>())); SlenderFlashlightRevealBoost = ((BaseUnityPlugin)this).Config.Bind<float>("Slender Model", "FlashlightRevealBoost", 2f, new ConfigDescription("How quickly the flashlight restores Slender to full material brightness inside the beam.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 4f), Array.Empty<object>())); SlenderRevealFadeSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Slender Model", "RevealFadeSpeed", 10f, new ConfigDescription("How quickly Slender fades between darkness and flashlight-lit appearance.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 40f), Array.Empty<object>())); EnableStatic = ((BaseUnityPlugin)this).Config.Bind<bool>("Watching", "EnableStatic", true, "Show the static overlay only while directly looking at Slender during a Watching event. Never applies during a Hunt."); StaticStrength = ((BaseUnityPlugin)this).Config.Bind<float>("Watching", "StaticOpacity", 0.12f, new ConfigDescription("Maximum Watching-mode static opacity. Also respects PEAK photosensitivity.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.3f), Array.Empty<object>())); EnableWatchDrowsy = ((BaseUnityPlugin)this).Config.Bind<bool>("Watching", "EnableDrowsyOnGaze", true, "Fill the normal PEAK Drowsy/Sleepy status while directly staring at Slender during Watching events. Never applies during Hunts."); SuppressDrowsyCameraFX = ((BaseUnityPlugin)this).Config.Bind<bool>("Watching", "SuppressDrowsyCameraFX", true, "Keep the real PEAK Drowsy meter/status but suppress the vanilla sleepy camera/post-processing effect while Pages of the Peak is active."); WatchDrowsyPerSecond = ((BaseUnityPlugin)this).Config.Bind<float>("Watching", "DrowsyPerSecond", 0.08f, new ConfigDescription("Drowsiness added per second of direct Watching-mode eye contact. 0.08 is roughly 8% of the bar per second before PEAK's own reductions.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 0.25f), Array.Empty<object>())); WatchGazeThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("Watching", "DirectLookThreshold", 0.93f, new ConfigDescription("How directly the camera must face Slender before Watching gaze effects apply. Higher is stricter.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.75f, 0.995f), Array.Empty<object>())); WatchEffectDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Watching", "EffectDistance", 45f, new ConfigDescription("Maximum distance in metres for Watching gaze effects.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 100f), Array.Empty<object>())); EnableBuiltInFlashlight = ((BaseUnityPlugin)this).Config.Bind<bool>("Flashlight", "EnableBuiltInFlashlight", true, "Enable the built-in camera-centered flashlight. Press L to toggle."); FlashlightStartOn = ((BaseUnityPlugin)this).Config.Bind<bool>("Flashlight", "StartOn", false, "Start each game session with the built-in flashlight switched on."); FlashlightIntensity = ((BaseUnityPlugin)this).Config.Bind<float>("Flashlight", "Intensity", 12f, new ConfigDescription("Flashlight brightness.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 15f), Array.Empty<object>())); FlashlightRange = ((BaseUnityPlugin)this).Config.Bind<float>("Flashlight", "Range", 80f, new ConfigDescription("Flashlight beam range in metres.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 100f), Array.Empty<object>())); FlashlightSpotAngle = ((BaseUnityPlugin)this).Config.Bind<float>("Flashlight", "SpotAngle", 90f, new ConfigDescription("Outer flashlight cone angle. Higher = wider beam.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(15f, 120f), Array.Empty<object>())); FlashlightInnerSpotAngle = ((BaseUnityPlugin)this).Config.Bind<float>("Flashlight", "InnerSpotAngle", 90f, new ConfigDescription("Bright inner flashlight cone angle.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(3f, 110f), Array.Empty<object>())); FlashlightColorTemperature = ((BaseUnityPlugin)this).Config.Bind<float>("Flashlight", "ColorTemperatureKelvin", 5000f, new ConfigDescription("Beam color temperature. Lower = warmer/yellower; higher = cooler/bluer.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2500f, 9000f), Array.Empty<object>())); FlashlightHorizontalOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Flashlight", "HorizontalOffset", 0f, new ConfigDescription("Camera-local horizontal beam origin offset.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-0.5f, 0.5f), Array.Empty<object>())); FlashlightVerticalOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Flashlight", "VerticalOffset", -0.015f, new ConfigDescription("Camera-local vertical beam origin offset.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-0.5f, 0.5f), Array.Empty<object>())); FlashlightForwardOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Flashlight", "ForwardOffset", 0.08f, new ConfigDescription("Camera-local forward beam origin offset.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); FlashlightShadows = ((BaseUnityPlugin)this).Config.Bind<bool>("Flashlight", "EnableShadows", false, "Use soft realtime shadows for the flashlight. Disable if performance is poor."); FlashlightShadowStrength = ((BaseUnityPlugin)this).Config.Bind<float>("Flashlight", "ShadowStrength", 0.72f, new ConfigDescription("Flashlight shadow darkness.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); FlashlightShadowBias = ((BaseUnityPlugin)this).Config.Bind<float>("Flashlight", "ShadowBias", 0.05f, new ConfigDescription("Shadow bias. Increase slightly if you see shadow acne.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.5f), Array.Empty<object>())); FlashlightShadowNormalBias = ((BaseUnityPlugin)this).Config.Bind<float>("Flashlight", "ShadowNormalBias", 0.4f, new ConfigDescription("Shadow normal bias.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>())); DebugKeys = ((BaseUnityPlugin)this).Config.Bind<bool>("Development", "EnableDebugKeys", true, "Enable F6-F11 development/test shortcuts."); ShowDebugText = ((BaseUnityPlugin)this).Config.Bind<bool>("Development", "ShowDebugText", false, "Show the Pages of the Peak diagnostic/status text in the upper-left corner. Disabled by default for normal/release gameplay."); VerboseNetworkLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Development", "VerboseNetworkLogging", false, "Write frequent multiplayer publish/event/heartbeat diagnostics to LogOutput.log. Leave OFF for normal gameplay; F6 diagnostics still work."); ScrollName = ((BaseUnityPlugin)this).Config.Bind<string>("Pages", "ScrollPrefabName", "", "Optional exact native Item object name; blank searches names containing scroll. F6 logs candidates. Missing mesh uses a labeled paper placeholder."); EnableCustomPageModels = ((BaseUnityPlugin)this).Config.Bind<bool>("Page Model", "EnableCustomPageModels", true, "Load pagesofthepeak_pages from the PagesOfThePeak plugin folder and use the bundled Slenderman paper meshes instead of PEAK's scroll visual."); CustomPageScale = ((BaseUnityPlugin)this).Config.Bind<float>("Page Model", "Scale", 10f, new ConfigDescription("Uniform scale of the custom paper model. The supplied Slendpg FBX is authored very small; around 10 works well in PEAK.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.02f, 20f), Array.Empty<object>())); CustomPageVerticalOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Page Model", "VerticalOffset", 0f, new ConfigDescription("Additional vertical offset for the custom paper model. A small positive value gives the page a deliberate floating collectible look.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-2f, 2f), Array.Empty<object>())); CustomPagePitch = ((BaseUnityPlugin)this).Config.Bind<float>("Page Model", "PitchOffset", 0f, new ConfigDescription("X-axis rotation correction for the custom paper model.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-180f, 180f), Array.Empty<object>())); CustomPageYaw = ((BaseUnityPlugin)this).Config.Bind<float>("Page Model", "YawOffset", 0f, new ConfigDescription("Y-axis rotation correction for the custom paper model.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-180f, 180f), Array.Empty<object>())); CustomPageRoll = ((BaseUnityPlugin)this).Config.Bind<float>("Page Model", "RollOffset", 0f, new ConfigDescription("Z-axis rotation correction for the custom paper model.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-180f, 180f), Array.Empty<object>())); RandomizePageYaw = ((BaseUnityPlugin)this).Config.Bind<bool>("Page Model", "RandomizeYaw", true, "Give each page a deterministic random Y rotation so the papers do not all face exactly the same direction."); ShowPageLabel = ((BaseUnityPlugin)this).Config.Bind<bool>("Page Model", "ShowFloatingPAGELabel", true, "Show the old floating PAGE text above custom paper models. Disabled by default for immersion."); PageFloatingLabelSize = ((BaseUnityPlugin)this).Config.Bind<float>("Page Model", "FloatingPAGELabelSize", 0.025f, new ConfigDescription("World-space size of the floating PAGE label. This is independent of the custom page model Scale.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.008f, 0.15f), Array.Empty<object>())); PageFloatingLabelHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Page Model", "FloatingPAGELabelHeight", 0.55f, new ConfigDescription("World-space height of the floating PAGE label above the page origin.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 2.5f), Array.Empty<object>())); ForcePageLitMaterials = ((BaseUnityPlugin)this).Config.Bind<bool>("Page Model", "ForceLitMaterials", true, "Convert custom page materials to URP/Lit so darkness and the Pages of the Peak flashlight affect them normally."); DisablePageEmission = ((BaseUnityPlugin)this).Config.Bind<bool>("Page Model", "DisableMaterialEmission", true, "Remove emission/self-illumination from custom page materials."); DisablePageEnvironmentReflections = ((BaseUnityPlugin)this).Config.Bind<bool>("Page Model", "DisableEnvironmentReflections", true, "Disable light/reflection probes and specular environment highlights on custom pages so white paper does not glow in darkness."); PageFlashlightRevealMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Page Model", "FlashlightRevealMode", false, "Blackout helper: keep custom pages dark unless the built-in flashlight beam is hitting them. Turn this ON when using Pitch Black PEAK/night mods."); PageDarkVisibility = ((BaseUnityPlugin)this).Config.Bind<float>("Page Model", "DarkVisibility", 0.03f, new ConfigDescription("How visible custom pages remain outside the flashlight when FlashlightRevealMode is enabled.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.5f), Array.Empty<object>())); PageFlashlightRevealBoost = ((BaseUnityPlugin)this).Config.Bind<float>("Page Model", "FlashlightRevealBoost", 2f, new ConfigDescription("How strongly the built-in flashlight restores page brightness.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 5f), Array.Empty<object>())); PageRevealFadeSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Page Model", "RevealFadeSpeed", 12f, new ConfigDescription("How quickly pages fade between darkness and flashlight-lit appearance.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 40f), Array.Empty<object>())); PagePromptFontSize = ((BaseUnityPlugin)this).Config.Bind<float>("Page Model", "PromptFontSize", 38f, new ConfigDescription("Size of the no-box '[F] Grab Page' PEAK-font interaction prompt.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(18f, 72f), Array.Empty<object>())); world = new World(this); flashlight = ((Component)this).gameObject.AddComponent<FlashlightController>(); flashlight.Initialize(this); drowsyVisualSuppressor = ((Component)this).gameObject.AddComponent<DrowsyVisualSuppressor>(); drowsyVisualSuppressor.Initialize(this); pagePrompt = ((Component)this).gameObject.AddComponent<PagePromptController>(); pagePrompt.Initialize(this); LoadSlenderBundle(); harmony = new Harmony("CircusFriendsStudios.PagesOfThePeak"); harmony.PatchAll(); PhotonNetwork.AddCallbackTarget((object)this); Log("Loaded Pages of the Peak 0.1.1 MULTIPLAYER FIX 5 PERFORMANCE [0.1.1-mpfix5]. L flashlight; F6 MP diagnostics; F7 pages; F8 debug reward; F9 watch; F10 hunt; F11 reset. F activates pages."); ((BaseUnityPlugin)this).Logger.LogInfo((object)("POTP NETWORK BUILD=0.1.1-mpfix5 | protocol=CFS.PagesOfThePeak.3 | StateWire=v1 | eventCode=" + (byte)179)); } private void OnDestroy() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown if (Host) { DestroyEnemy(); } PhotonNetwork.RemoveCallbackTarget((object)this); if (PhotonNetwork.InRoom) { PhotonNetwork.LocalPlayer.SetCustomProperties(new Hashtable { [(object)"CFS.POTP.Version"] = null, [(object)"CFS.POTP.Use"] = null }, (Hashtable)null, (WebFlags)null); if (Host && PhotonNetwork.CurrentRoom != null) { PhotonNetwork.CurrentRoom.SetCustomProperties(new Hashtable { [(object)"CFS.POTP.State"] = null }, (Hashtable)null, (WebFlags)null); } } Harmony obj3 = harmony; if (obj3 != null) { obj3.UnpatchSelf(); } world?.Dispose(); flashlight?.Dispose(); flashlight = null; drowsyVisualSuppressor?.Dispose(); drowsyVisualSuppressor = null; pagePrompt?.Dispose(); pagePrompt = null; foreach (GameObject value in slenderVisuals.Values) { if (Object.op_Implicit((Object)(object)value)) { Object.Destroy((Object)(object)value); } } slenderVisuals.Clear(); if ((Object)(object)slenderBundle != (Object)null) { slenderBundle.Unload(false); } slenderBundle = null; slenderPrefab = null; Instance = null; } private bool AllModded() { object value; string[] array = (from p in PhotonNetwork.PlayerList where !((Dictionary<object, object>)(object)p.CustomProperties).TryGetValue((object)"CFS.POTP.Version", out value) || !object.Equals(value, "0.1.1-mpfix5") select p.NickName).ToArray(); waitingReason = ((array.Length == 0) ? "" : ("Waiting for matching mod: " + string.Join(", ", array))); return array.Length == 0; } private bool InClimb() { if (PhotonNetwork.InRoom && MapHandler.ExistsAndInitialized && Object.op_Implicit((Object)(object)Character.localCharacter)) { return !Character.localCharacter.inAirport; } return false; } private MapHandler ResolveMapFast() { if (Object.op_Implicit((Object)(object)cachedMap)) { return cachedMap; } if (Time.unscaledTime < nextMapLookup) { return null; } nextMapLookup = Time.unscaledTime + 1f; cachedMap = Object.FindFirstObjectByType<MapHandler>(); return cachedMap; } private void Update() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_0415: Unknown result type (might be due to invalid IL or missing references) //IL_041c: Expected I4, but got Unknown if (!PhotonNetwork.InRoom) { if (active) { ClearLocal(); } advertised = false; cachedMap = null; cachedAllModded = false; masterId = 0; mapId = 0; return; } if (!advertised) { PhotonNetwork.LocalPlayer.SetCustomProperties(new Hashtable { [(object)"CFS.POTP.Version"] = "0.1.1-mpfix5" }, (Hashtable)null, (WebFlags)null); advertised = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)("MP ADVERTISE actor=" + PhotonNetwork.LocalPlayer.ActorNumber + " build=0.1.1-mpfix5 master=" + PhotonNetwork.MasterClient.ActorNumber + " isMaster=" + PhotonNetwork.IsMasterClient)); } int actorNumber = PhotonNetwork.MasterClient.ActorNumber; if (masterId != 0 && masterId != actorNumber) { if (Host) { DestroyEnemy(); } ClearLocal(); mapId = 0; Log("Host changed: curse progress restarts; PEAK match continues."); } masterId = actorNumber; if (VerboseNetworkLogging.Value && Time.unscaledTime >= nextNetworkHeartbeat) { nextNetworkHeartbeat = Time.unscaledTime + 5f; LogNetworkSummary("heartbeat"); } if (!InClimb()) { if (active) { if (Host) { DestroyEnemy(); } ClearLocal(); } mapId = 0; return; } MapHandler val = ResolveMapFast(); if (!Object.op_Implicit((Object)(object)val)) { return; } if (mapId != 0 && mapId != ((Object)val).GetInstanceID()) { if (Host) { DestroyEnemy(); } ClearLocal(); } mapId = ((Object)val).GetInstanceID(); if (Host && Time.unscaledTime >= nextModRosterCheck) { nextModRosterCheck = Time.unscaledTime + 0.5f; cachedAllModded = AllModded(); } if (Host && !cachedAllModded) { if (active) { DestroyEnemy(); ClearLocal(); } notice = waitingReason; return; } if (Host && !active) { Begin(); } if (!Host && Time.unscaledTime >= nextRoomPoll) { bool flag = !active || lastSnapshot <= 0f || Time.unscaledTime - lastSnapshot > 2.5f; nextRoomPoll = Time.unscaledTime + (flag ? 0.35f : 1.5f); if (flag) { TryApplyRoomSnapshot(); } } if (Host && Time.unscaledTime >= nextFallbackPoll) { nextFallbackPoll = Time.unscaledTime + 0.1f; PollPageUseFallbacks(); } if (!Host && Time.unscaledTime >= nextRequest) { nextRequest = Time.unscaledTime + 2f; Send(new Message { kind = "sync" }, (ReceiverGroup)2); } if (!Host && active && Time.unscaledTime - lastSnapshot > 5f) { ClearLocal(); } if (DebugKeys.Value && Keyboard.current != null && ((ButtonControl)Keyboard.current.f6Key).wasPressedThisFrame) { LogNetworkSummary("F6"); world.Diagnostics(); } if (!active) { pagePrompt?.SetVisible(value: false); return; } world.Refresh(State); if (Time.unscaledTime >= nextPromptProbe) { nextPromptProbe = Time.unscaledTime + 1f / 15f; pagePrompt?.SetVisible(world.LookingAt(State) != null); } UpdateNetworkPresentation(); if (Host) { if (Time.time >= tick) { tick = Time.time + 5f; int num = (int)MapHandler.CurrentSegmentNumber; if (num != lastSegment) { EnterSegment(num); } SeedPages(num); } Scoutmaster val2 = ResolveEnemy(); if ((State.phase == "Watching" || State.phase == "Hunt") && !Object.op_Implicit((Object)(object)val2)) { EndEvent(); } else if (Object.op_Implicit((Object)(object)val2) && Time.time >= eventEnd) { EndEvent(); } if (State.pages > 0 && !Object.op_Implicit((Object)(object)ResolveEnemy()) && Time.time >= eventAt) { StartEvent(forceHunt: false); } if (Time.unscaledTime >= broadcast) { broadcast = Time.unscaledTime + 2f; Publish(); } } if (Keyboard.current != null && ((ButtonControl)Keyboard.current.fKey).wasPressedThisFrame && Time.unscaledTime >= pendingUntil) { Page page = world.LookingAt(State); if (page != null) { pendingUntil = Time.unscaledTime + 1f; if (Host) { Collect(page.id, PhotonNetwork.LocalPlayer.ActorNumber); } else { RequestPageUse(page.id); } } } if (DebugKeys.Value) { Keys(); } SafeUpdateWatchGazeEffects(); } private void Begin() { Scoutmaster[] array = Object.FindObjectsByType<Scoutmaster>((FindObjectsSortMode)0); foreach (Scoutmaster val in array) { if (IsOurEnemy(val)) { DestroyEnemyObject(((Component)val).gameObject); } } localEnemy = null; localTarget = null; active = true; State = new RunState { run = System.Guid.NewGuid().ToString("N"), bonusPerPage = Bonus.Value }; attempts.Clear(); knocked.Clear(); mercyUsedThisSegment.Clear(); lastUseFallback.Clear(); lastRemoteAttackSerial = 0; eventAt = Time.time + 12f; tick = 0f; lastSegment = -1; Log("New curse started. " + PageCount.Value + " pages per biome; page count and regen reset at each segment transition. F to activate."); Publish(); } private void ClearLocal() { localEnemy = null; localTarget = null; active = false; State = new RunState(); world.Clear(); attempts.Clear(); knocked.Clear(); mercyUsedThisSegment.Clear(); requests.Clear(); lastUseFallback.Clear(); lastRemoteAttackSerial = 0; lastSnapshot = 0f; watchDrowsyPending = 0f; watchEffectFaulted = false; lastSegment = -1; } private void EnterSegment(int segment) { if (Object.op_Implicit((Object)(object)ResolveEnemy())) { DestroyEnemy(); } world.Clear(); State.ResetSegment(segment); attempts.Clear(); knocked.Clear(); mercyUsedThisSegment.Clear(); lastRemoteAttackSerial = 0; attackGrace = 0f; moveCheck = 0f; huntDiagnostic = ""; watchDrowsyPending = 0f; watchEffectFaulted = false; eventEnd = 0f; eventAt = Time.time + 12f; lastSegment = segment; Log("Entered segment " + segment + ": page count and stamina regen reset; seeding " + PageCount.Value + " pages."); Publish(); } private void SeedPages(int segment) { //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) if (!Alive(Character.localCharacter)) { return; } int num = State.worldPages.Count((Page p) => p.segment == segment); if (num >= PageCount.Value || State.worldPages.Count >= 96) { return; } attempts.TryGetValue(segment, out var value); if (value >= 120) { return; } attempts[segment] = value + 1; MapSegment currentMapSegment = MapHandler.CurrentMapSegment; GameObject val = ((currentMapSegment != null) ? currentMapSegment.segmentParent : null); Transform root = (Object.op_Implicit((Object)(object)val) ? val.transform : null); Campfire currentCampfire = MapHandler.CurrentCampfire; List<Vector3> list = (from p in State.worldPages where p.segment == segment select p.position).ToList(); if (Object.op_Implicit((Object)(object)currentCampfire)) { list.Add(((Component)currentCampfire).transform.position); } float[] array = new float[3] { 12f, 9f, 6f }; for (int num2 = 0; num2 < array.Length; num2++) { float spacing = array[num2]; for (int num3 = 0; num3 < 60; num3++) { if (num >= PageCount.Value) { break; } if (world.BiomeGround(root, list, spacing, out var pos) && (!Object.op_Implicit((Object)(object)currentCampfire) || !(Vector3.Distance(pos, ((Component)currentCampfire).transform.position) < 8f)) && !State.worldPages.Any((Page p) => p.segment == segment && Vector3.Distance(p.position, pos) < spacing)) { State.worldPages.Add(new Page { id = State.worldPages.Count + 1, segment = segment, position = pos }); list.Add(pos); num++; ((BaseUnityPlugin)this).Logger.LogInfo((object)("PAGE placed id=" + State.worldPages.Count + " segment=" + segment + " pos=" + ((object)Unsafe.As<Vector3, Vector3>(ref pos)/*cast due to .constrained prefix*/).ToString() + " spacingPass=" + spacing.ToString("0") + "m")); } } if (num >= PageCount.Value) { break; } } Log("Segment " + segment + ": " + num + "/" + PageCount.Value + " pages placed across biome."); Publish(); } private void Collect(int id, int actor) { //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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) if (!Host || !active) { return; } Page page = State.worldPages.Find((Page x) => x.id == id); Character val = ((IEnumerable<Character>)Character.AllCharacters).FirstOrDefault((Func<Character, bool>)((Character x) => Alive(x) && ((MonoBehaviourPun)x).photonView.OwnerActorNr == actor)); if (page != null && !page.used && Object.op_Implicit((Object)(object)val) && !(Vector3.Distance(val.Center, page.position) > 4f) && World.ClearSight(val.Head, page.position) && State.Collect(id, actor)) { if (State.pages == 1) { eventAt = Time.time + Random.Range(6f, 12f); } Log("Page " + id + " activated. Shared threat: " + State.pages + "; collector regen +" + ((float)State.Owned(actor) * State.bonusPerPage * 100f).ToString("0") + "%."); Publish(); } } private void SendJson(string json, ReceiverGroup group, int actor = 0) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) object obj; if (actor == 0) { obj = (object)new RaiseEventOptions { Receivers = group }; } else { RaiseEventOptions val = new RaiseEventOptions(); val.TargetActors = new int[1] { actor }; obj = val; } RaiseEventOptions val2 = (RaiseEventOptions)obj; PhotonNetwork.RaiseEvent((byte)179, (object)json, val2, SendOptions.SendReliable); } private void Send(Message m, ReceiverGroup group, int actor = 0) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) SendJson(JsonUtility.ToJson((object)m), group, actor); } private void Publish(int actor = 0) { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown if (!Host || !active) { return; } State.revision++; string text = StateWire.Encode(State); if (string.IsNullOrEmpty(text)) { ((BaseUnityPlugin)this).Logger.LogError((object)"MP PUBLISH aborted: StateWire.Encode returned an empty payload."); return; } string text2 = JsonUtility.ToJson((object)new Message { kind = "state", run = State.run, payload = text }); if (PhotonNetwork.CurrentRoom != null) { PhotonNetwork.CurrentRoom.SetCustomProperties(new Hashtable { [(object)"CFS.POTP.State"] = text2 }, (Hashtable)null, (WebFlags)null); } if (VerboseNetworkLogging.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("MP PUBLISH rev=" + State.revision + " pages=" + State.pages + " worldPages=" + ((State.worldPages == null) ? (-1) : State.worldPages.Count) + " phase=" + State.phase + " enemy=" + State.enemy + " target=" + State.target + " payloadLen=" + text.Length + " jsonLen=" + text2.Length + " targetActor=" + actor)); } SendJson(text2, (ReceiverGroup)0, actor); } private bool ApplyStateSnapshot(RunState incoming, string source) { if (incoming == null || incoming.worldPages == null || incoming.worldPages.Count > 96 || string.IsNullOrEmpty(incoming.run)) { return false; } if (State.run == incoming.run && incoming.revision <= State.revision) { lastSnapshot = Time.unscaledTime; return false; } bool num = State.run != incoming.run; bool flag = State.segment != incoming.segment; if (num || flag) { world.Clear(); lastRemoteAttackSerial = 0; } State = incoming; active = true; lastSnapshot = Time.unscaledTime; if (VerboseNetworkLogging.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("MP STATE applied via " + source + " rev=" + State.revision + " segment=" + State.segment + " pages=" + State.pages + " worldPages=" + State.worldPages.Count + " phase=" + State.phase + " enemy=" + State.enemy + " target=" + State.target)); } return true; } private void TryApplyRoomSnapshot() { if (Host || !PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null || !((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"CFS.POTP.State", out object value)) { return; } if (!(value is string text)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("MP ROOM SNAPSHOT rejected: room property exists but is " + ((value == null) ? "null" : value.GetType().FullName))); return; } if (string.IsNullOrEmpty(text) || text.Length > 100000) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("MP ROOM SNAPSHOT rejected: invalid length=" + (text?.Length ?? (-1)))); return; } Message message; try { message = JsonUtility.FromJson<Message>(text); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("MP ROOM SNAPSHOT JSON failed: " + ex.GetBaseException().Message)); return; } if (message == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"MP ROOM SNAPSHOT rejected: deserialized message is null."); return; } if (message.mod != "CFS.PagesOfThePeak.3") { ((BaseUnityPlugin)this).Logger.LogWarning((object)("MP ROOM SNAPSHOT rejected: protocol=" + (message.mod ?? "<null>") + " expected=CFS.PagesOfThePeak.3")); return; } if (message.kind != "state") { ((BaseUnityPlugin)this).Logger.LogWarning((object)("MP ROOM SNAPSHOT rejected: kind=" + (message.kind ?? "<null>"))); return; } if (string.IsNullOrEmpty(message.payload)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"MP ROOM SNAPSHOT rejected: payload is empty."); return; } RunState runState = StateWire.Decode(message.payload); if (runState == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("MP ROOM SNAPSHOT rejected: StateWire decode failed. payloadLen=" + message.payload.Length)); } else { ApplyStateSnapshot(runState, "room-cache"); } } private void RequestPageUse(int pageId) { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown if (!Host && active && !string.IsNullOrEmpty(State.run)) { Send(new Message { kind = "use", run = State.run, id = pageId }, (ReceiverGroup)2); useNonce++; string text = State.run + "|" + pageId + "|" + useNonce; PhotonNetwork.LocalPlayer.SetCustomProperties(new Hashtable { [(object)"CFS.POTP.Use"] = text }, (Hashtable)null, (WebFlags)null); if (VerboseNetworkLogging.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("MP PAGE request id=" + pageId + " run=" + State.run + " nonce=" + useNonce)); } } } private void PollPageUseFallbacks() { if (!Host || !active) { return; } Player[] playerList = PhotonNetwork.PlayerList; foreach (Player val in playerList) { if (val != null && val.ActorNumber != PhotonNetwork.LocalPlayer.ActorNumber && ((Dictionary<object, object>)(object)val.CustomProperties).TryGetValue((object)"CFS.POTP.Use", out object value) && value is string text && !string.IsNullOrEmpty(text) && (!lastUseFallback.TryGetValue(val.ActorNumber, out var value2) || !(value2 == text))) { lastUseFallback[val.ActorNumber] = text; string[] array = text.Split('|'); if (array.Length == 3 && !(array[0] != State.run) && int.TryParse(array[1], out var result)) { Collect(result, val.ActorNumber); } } } } private void UpdateNetworkPresentation() { if (!active) { return; } Scoutmaster val = ResolveEnemy(); if (!Object.op_Implicit((Object)(object)val)) { return; } AttachCustomVisual(val); if (!Host) { bool flag = State.phase == "Hunt"; Character component = ((Component)val).GetComponent<Character>(); bool runPreferred = flag && State.pages >= HuntSprintAtPages.Value && (!Object.op_Implicit((Object)(object)component) || (Object)(object)component.data == (Object)null || !component.data.isClimbingAnything); UpdateCustomVisualMotion(val, runPreferred); UpdateCustomVisualHuntAudio(val, flag); if (State.attackSerial > lastRemoteAttackSerial) { lastRemoteAttackSerial = State.attackSerial; TriggerCustomVisualAttack(val); } } } public void OnEvent(EventData e) { if (e.Code != 179 || !(e.CustomData is string { Length: <=100000 } text) || !PhotonNetwork.InRoom) { return; } if (VerboseNetworkLogging.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("MP EVENT received sender=" + e.Sender + " bytes=" + text.Length + " host=" + Host)); } Message message; try { message = JsonUtility.FromJson<Message>(text); } catch { return; } if (message == null || message.mod != "CFS.PagesOfThePeak.3") { return; } if (VerboseNetworkLogging.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("MP MESSAGE parsed kind=" + (message.kind ?? "<null>") + " run=" + (message.run ?? "<null>") + " payloadLen=" + ((message.payload == null) ? (-1) : message.payload.Length))); } if (Host && (message.kind == "sync" || message.kind == "use")) { if (active && AllModded() && (!requests.TryGetValue(e.Sender, out var value) || !(Time.unscaledTime - value < 0.15f))) { requests[e.Sender] = Time.unscaledTime; if (message.kind == "sync") { Publish(e.Sender); } else if (message.run == State.run) { Collect(message.id, e.Sender); } } } else { if (e.Sender != PhotonNetwork.MasterClient.ActorNumber || Host || !InClimb()) { return; } if (message.kind == "state") { if (string.IsNullOrEmpty(message.payload)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"MP EVENT state rejected: payload is empty."); return; } RunState runState = StateWire.Decode(message.payload); if (runState == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("MP EVENT state rejected: StateWire decode failed. payloadLen=" + message.payload.Length)); } else { ApplyStateSnapshot(runState, "RaiseEvent"); } } else { if ((!(message.kind == "down") && !(message.kind == "kill")) || !active || !(message.run == State.run)) { return; } Character localCharacter = Character.localCharacter; if (!Alive(localCharacter) || !Object.op_Implicit((Object)(object)((MonoBehaviourPun)localCharacter).photonView) || ((MonoBehaviourPun)localCharacter).photonView.ViewID != message.id) { return; } if (message.kind == "kill") { if (!KillCharacterCompat(localCharacter)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Full-death API was unavailable; falling back to knockout."); localCharacter.PassOutInstantly(); } } else { localCharacter.PassOutInstantly(); } } } } private void LogNetworkSummary(string reason) { try { bool inRoom = PhotonNetwork.InRoom; int num = ((PhotonNetwork.LocalPlayer != null) ? PhotonNetwork.LocalPlayer.ActorNumber : 0); int num2 = ((inRoom && PhotonNetwork.MasterClient != null) ? PhotonNetwork.MasterClient.ActorNumber : 0); string text = "<none>"; if (PhotonNetwork.LocalPlayer != null && ((Dictionary<object, object>)(object)PhotonNetwork.LocalPlayer.CustomProperties).TryGetValue((object)"CFS.POTP.Version", out object value)) { text = ((value == null) ? "<null>" : value.ToString()); } bool flag = false; int num3 = 0; string text2 = "<none>"; if (inRoom && PhotonNetwork.CurrentRoom != null && ((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"CFS.POTP.State", out object value2)) { flag = true; text2 = ((value2 == null) ? "<null>" : value2.GetType().FullName); if (value2 is string text3) { num3 = text3.Length; } } List<string> list = new List<string>(); if (inRoom) { Player[] playerList = PhotonNetwork.PlayerList; foreach (Player val in playerList) { string text4 = "<none>"; if (((Dictionary<object, object>)(object)val.CustomProperties).TryGetValue((object)"CFS.POTP.Version", out object value3)) { text4 = ((value3 == null) ? "<null>" : value3.ToString()); } list.Add(val.ActorNumber + ":" + val.NickName + "=" + text4); } } ((BaseUnityPlugin)this).Logger.LogInfo((object)("MP DIAG [" + reason + "] build=0.1.1-mpfix5 inRoom=" + inRoom + " actor=" + num + " master=" + num2 + " isMaster=" + PhotonNetwork.IsMasterClient + " inClimb=" + InClimb() + " active=" + active + " advertised=" + advertised + " localProp=" + text + " roomState=" + flag + " roomStateType=" + text2 + " roomStateLen=" + num3 + " stateRun=" + (string.IsNullOrEmpty(State.run) ? "<none>" : State.run) + " rev=" + State.revision + " segment=" + State.segment + " pages=" + State.pages + " worldPages=" + ((State.worldPages == null) ? (-1) : State.worldPages.Count) + " phase=" + State.phase + " lastSnapshotAge=" + ((lastSnapshot <= 0f) ? "never" : ((Time.unscaledTime - lastSnapshot).ToString("0.00") + "s")) + " peers=[" + string.Join(", ", list) + "]")); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("MP DIAG failed: " + ex.GetBaseException().Message)); } } private Scoutmaster ResolveEnemy() { if (State.enemy != 0) { PhotonView val = PhotonView.Find(State.enemy); if (Object.op_Implicit((Object)(object)val)) { Scoutmaster component = ((Component)val).GetComponent<Scoutmaster>(); if (Object.op_Implicit((Object)(object)component) && IsOurEnemy(component)) { return component; } } } if (Object.op_Implicit((Object)(object)localEnemy)) { return localEnemy; } return null; } private Character ResolveTarget() { if (State.target != 0) { Character val = ((IEnumerable<Character>)Character.AllCharacters).FirstOrDefault((Func<Character, bool>)((Character c) => Alive(c) && Object.op_Implicit((Object)(object)((MonoBehaviourPun)c).photonView) && ((MonoBehaviourPun)c).photonView.ViewID == State.target)); if (Object.op_Implicit((Object)(object)val)) { return val; } } if (Object.op_Implicit((Object)(object)localTarget) && Alive(localTarget)) { return localTarget; } if (PhotonNetwork.OfflineMode && Alive(Character.localCharacter)) { return Character.localCharacter; } return null; } private bool HasEnemy() { return Object.op_Implicit((Object)(object)ResolveEnemy()); } private void DestroyEnemyObject(GameObject go) { if (!Object.op_Implicit((Object)(object)go)) { return; } try { PhotonView component = go.GetComponent<PhotonView>(); if (PhotonNetwork.InRoom && Object.op_Implicit((Object)(object)component) && component.ViewID != 0) { PhotonNetwork.Destroy(go); } else { Object.Destroy((Object)(object)go); } } catch { if (Object.op_Implicit((Object)(object)go)) { Object.Destroy((Object)(object)go); } } } private void LoadSlenderBundle() { if (!EnableCustomSlender.Value) { return; } try { string[] files = Directory.GetFiles(Paths.PluginPath, "pagesofthepeak_slender", SearchOption.AllDirectories); if (files == null || files.Length == 0) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Custom Slender model enabled, but pagesofthepeak_slender was not found under BepInEx/plugins. Native Scoutmaster visual will be used."); return; } slenderBundlePath = files[0]; slenderBundle = AssetBundle.LoadFromFile(slenderBundlePath); if ((Object)(object)slenderBundle == (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not load Slender AssetBundle: " + slenderBundlePath + ". Native Scoutmaster visual will be used.")); return; } string[] allAssetNames = slenderBundle.GetAllAssetNames(); string text = allAssetNames.FirstOrDefault((string n) => n.EndsWith("/slender.prefab", StringComparison.OrdinalIgnoreCase)); if (string.IsNullOrEmpty(text)) { text = allAssetNames.FirstOrDefault((string n) => n.EndsWith(".prefab", StringComparison.OrdinalIgnoreCase) && n.IndexOf("slender", StringComparison.OrdinalIgnoreCase) >= 0); } if (string.IsNullOrEmpty(text)) { text = allAssetNames.FirstOrDefault((string n) => n.EndsWith(".prefab", StringComparison.OrdinalIgnoreCase)); } if (string.IsNullOrEmpty(text)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Slender AssetBundle loaded, but it contains no prefab. Assets: " + string.Join(", ", allAssetNames))); slenderBundle.Unload(false); slenderBundle = null; return; } slenderPrefab = slenderBundle.LoadAsset<GameObject>(text); if (!Object.op_Implicit((Object)(object)slenderPrefab)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Slender prefab could not be loaded from AssetBundle entry: " + text)); slenderBundle.Unload(false); slenderBundle = null; return; } ((BaseUnityPlugin)this).Logger.LogInfo((object)("Custom Slender bundle ready: " + Path.GetFileName(slenderBundlePath) + " | prefab=" + text)); Animator componentInChildren = slenderPrefab.GetComponentInChildren<Animator>(true); if (Object.op_Implicit((Object)(object)componentInChildren) && Object.op_Implicit((Object)(object)componentInChildren.runtimeAnimatorController)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Slender animation clips: " + string.Join(", ", (from c in componentInChildren.runtimeAnimatorController.animationClips where Object.op_Implicit((Object)(object)c) select ((Object)c).name).Distinct().ToArray()))); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Slender animator parameters: " + string.Join(", ", componentInChildren.parameters.Select((AnimatorControllerParameter p) => p.name + ":" + ((object)p.type/*cast due to .constrained prefix*/).ToString()).ToArray()))); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Custom Slender bundle load failed; native Scoutmaster visual will be used. " + ex.GetBaseException().Message)); slenderPrefab = null; if ((Object)(object)slenderBundle != (Object)null) { slenderBundle.Unload(false); slenderBundle = null; } } } private void FixSlenderMaterials(GameObject visual) { //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Expected O, but got Unknown //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Expected O, but got Unknown //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_04e5: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)visual)) { return; } bool flag = UseSlenderBlackoutRendering(); Shader val = Shader.Find("Universal Render Pipeline/Lit"); if (!Object.op_Implicit((Object)(object)val)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"URP/Lit shader was not found. Slender materials could not be forced to scene lighting."); return; } Dictionary<int, Material> dictionary = new Dictionary<int, Material>(); Renderer[] componentsInChildren = visual.GetComponentsInChildren<Renderer>(true); foreach (Renderer val2 in componentsInChildren) { if (!Object.op_Implicit((Object)(object)val2)) { continue; } val2.receiveShadows = true; val2.shadowCastingMode = (ShadowCastingMode)1; if (DisableSlenderEnvironmentReflections.Value && flag) { val2.reflectionProbeUsage = (ReflectionProbeUsage)0; val2.lightProbeUsage = (LightProbeUsage)0; } else { val2.reflectionProbeUsage = (ReflectionProbeUsage)1; val2.lightProbeUsage = (LightProbeUsage)1; } Material[] sharedMaterials = val2.sharedMaterials; for (int j = 0; j < sharedMaterials.Length; j++) { Material val3 = sharedMaterials[j]; if (!Object.op_Implicit((Object)(object)val3)) { continue; } if (dictionary.TryGetValue(((Object)val3).GetInstanceID(), out var value) && Object.op_Implicit((Object)(object)value)) { sharedMaterials[j] = value; continue; } Texture val4 = null; Texture val5 = null; Texture val6 = null; Texture val7 = null; Color val8 = Color.white; float num = 0.35f; float num2 = 0f; if (val3.HasProperty("_BaseMap")) { val4 = val3.GetTexture("_BaseMap"); } if (!Object.op_Implicit((Object)(object)val4) && val3.HasProperty("_MainTex")) { val4 = val3.GetTexture("_MainTex"); } if (val3.HasProperty("_BumpMap")) { val5 = val3.GetTexture("_BumpMap"); } if (val3.HasProperty("_MetallicGlossMap")) { val6 = val3.GetTexture("_MetallicGlossMap"); } if (val3.HasProperty("_OcclusionMap")) { val7 = val3.GetTexture("_OcclusionMap"); } if (val3.HasProperty("_BaseColor")) { val8 = val3.GetColor("_BaseColor"); } else if (val3.HasProperty("_Color")) { val8 = val3.GetColor("_Color"); } if (val3.HasProperty("_Smoothness")) { num = val3.GetFloat("_Smoothness"); } else if (val3.HasProperty("_Glossiness")) { num = val3.GetFloat("_Glossiness"); } if (val3.HasProperty("_Metallic")) { num2 = val3.GetFloat("_Metallic"); } val8.r *= SlenderAlbedoMultiplier.Value; val8.g *= SlenderAlbedoMultiplier.Value; val8.b *= SlenderAlbedoMultiplier.Value; Material val9 = ((!ForceSlenderLitMaterials.Value) ? new Material(val3) : new Material(val)); ((Object)val9).name = ((Object)val3).name + "_POTP_Lit"; if (val9.HasProperty("_BaseMap") && Object.op_Implicit((Object)(object)val4)) { val9.SetTexture("_BaseMap", val4); } if (val9.HasProperty("_BaseColor")) { val9.SetColor("_BaseColor", val8); } if (val9.HasProperty("_Smoothness")) { val9.SetFloat("_Smoothness", Mathf.Clamp01(num)); } if (val9.HasProperty("_Metallic")) { val9.SetFloat("_Metallic", (DisableSlenderEnvironmentReflections.Value && flag) ? 0f : Mathf.Clamp01(num2)); } if (DisableSlenderEnvironmentReflections.Value && flag) { if (val9.HasProperty("_EnvironmentReflections")) { val9.SetFloat("_EnvironmentReflections", 0f); } if (val9.HasProperty("_SpecularHighlights")) { val9.SetFloat("_SpecularHighlights", 0f); } if (val9.HasProperty("_Smoothness")) { val9.SetFloat("_Smoothness", Mathf.Min(0.12f, val9.GetFloat("_Smoothness"))); } val9.EnableKeyword("_ENVIRONMENTREFLECTIONS_OFF"); val9.EnableKeyword("_SPECULARHIGHLIGHTS_OFF"); } else { if (val9.HasProperty("_EnvironmentReflections")) { val9.SetFloat("_EnvironmentReflections", 1f); } if (val9.HasProperty("_SpecularHighlights")) { val9.SetFloat("_SpecularHighlights", 1f); } val9.DisableKeyword("_ENVIRONMENTREFLECTIONS_OFF"); val9.DisableKeyword("_SPECULARHIGHLIGHTS_OFF"); } if (Object.op_Implicit((Object)(object)val5) && val9.HasProperty("_BumpMap")) { val9.SetTexture("_BumpMap", val5); val9.EnableKeyword("_NORMALMAP"); } if (Object.op_Implicit((Object)(object)val6) && val9.HasProperty("_MetallicGlossMap")) { val9.SetTexture("_MetallicGlossMap", val6); val9.EnableKeyword("_METALLICSPECGLOSSMAP"); } if (Object.op_Implicit((Object)(object)val7) && val9.HasProperty("_OcclusionMap")) { val9.SetTexture("_OcclusionMap", val7); val9.EnableKeyword("_OCCLUSIONMAP"); } if (DisableSlenderEmission.Value) { if (val9.HasProperty("_EmissionColor")) { val9.SetColor("_EmissionColor", Color.black); } if (val9.HasProperty("_EmissionMap")) { val9.SetTexture("_EmissionMap", (Texture)null); } val9.DisableKeyword("_EMISSION"); val9.globalIlluminationFlags = (MaterialGlobalIlluminationFlags)4; } if (val9.HasProperty("_Surface")) { val9.SetFloat("_Surface", 0f); } if (val9.HasProperty("_AlphaClip")) { val9.SetFloat("_AlphaClip", 0f); } val9.DisableKeyword("_SURFACE_TYPE_TRANSPARENT"); val9.DisableKeyword("_ALPHATEST_ON"); val9.renderQueue = -1; dictionary[((Object)val3).GetInstanceID()] = val9; sharedMaterials[j] = val9; } val2.sharedMaterials = sharedMaterials; } ((BaseUnityPlugin)this).Logger.LogInfo((object)("Custom Slender materials sanitized: " + dictionary.Count + " material(s), lit=" + ForceSlenderLitMaterials.Value + ", emissionOff=" + DisableSlenderEmission.Value + ", reflectionsOff=" + DisableSlenderEnvironmentReflections.Value + ", albedo=" + SlenderAlbedoMultiplier.Value.ToString("0.00"))); } private bool DetectPitchBlackMod() { try { foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos) { PluginInfo value = pluginInfo.Value; BepInPlugin val = ((value != null) ? value.Metadata : null); string text = ((val != null) ? val.GUID : ""); string text2 = ((val != null) ? val.Name : ""); string text3 = pluginInfo.Key ?? ""; if ((text + " " + text2 + " " + text3).Replace(" ", "").Replace("_", "").Replace("-", "") .ToLowerInvariant() .Contains("pitchblack")) { return true; } } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Automatic Pitch Black detection failed safely: " + ex.GetBaseException().Message)); } return false; } internal bool UseSlenderBlackoutRendering() { bool flag; if (SlenderAutoLighting != null && SlenderAutoLighting.Value) { if (Time.unscaledTime >= nextSlenderLightingDetection) { nextSlenderLightingDetection = Time.unscaledTime + 2f; cachedPitchBlackDetected = DetectPitchBlackMod(); } flag = cachedPitchBlackDetected; } else { flag = SlenderFlashlightRevealMode != null && SlenderFlashlightRevealMode.Value; } if (!lastReportedSlenderBlackoutMode.HasValue || lastReportedSlenderBlackoutMode.Value != flag) { lastReportedSlenderBlackoutMode = flag; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Slender lighting mode: " + (flag ? "BLACKOUT / flashlight reveal" : "NORMAL PEAK day-night lighting") + " | Auto=" + (SlenderAutoLighting != null && SlenderAutoLighting.Value) + " | PitchBlackDetected=" + cachedPitchBlackDetected)); } return flag; } internal float FlashlightExposureAt(Vector3 worldPoint) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)flashlight != (Object)null)) { return 0f; } return flashlight.BeamExposureAt(worldPoint); } internal void AttachCustomVisual(Scoutmaster scout) { //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_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) if (!EnableCustomSlender.Value || !Object.op_Implicit((Object)(object)slenderPrefab) || !Object.op_Implicit((Object)(object)scout)) { return; } int instanceID = ((Object)scout).GetInstanceID(); if (slenderVisuals.TryGetValue(instanceID, out var value) && Object.op_Implicit((Object)(object)value)) { return; } Renderer[] array = (from r in ((Component)scout).GetComponentsInChildren<Renderer>(true) where Object.op_Implicit((Object)(object)r) select r).ToArray(); try { GameObject val = Object.Instantiate<GameObject>(slenderPrefab); if (!Object.op_Implicit((Object)(object)val)) { throw new Exception("Instantiate returned null"); } ((Object)val).name = "POTP_CustomSlenderVisual"; val.transform.position = ((Component)scout).transform.position + Vector3.up * SlenderVisualYOffset.Value; val.transform.rotation = ((Component)scout).transform.rotation * Quaternion.Euler(0f, SlenderVisualYaw.Value, 0f); val.transform.localScale = Vector3.one * SlenderVisualScale.Value; Collider[] componentsInChildren = val.GetComponentsInChildren<Collider>(true); foreach (Collider val2 in componentsInChildren)