Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of SagaLens v0.1.7
BepInEx/plugins/SagaLens/SagaLens.dll
Decompiled 5 days agousing System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.InputSystem; using UnityEngine.UI; [assembly: AssemblyInformationalVersion("0.1.7")] [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyDescription("Valheim Photo Mode. Coded with the assistance of ChatGPT 6.0.")] [assembly: AssemblyFileVersion("0.1.7.0")] [assembly: AssemblyTitle("Saga Lens")] [assembly: AssemblyVersion("0.1.7.0")] namespace ValheimPhotoMode; internal static class CameraRules { internal const float MinimumDistance = 0.12f; internal const float MaximumFov = 130f; internal static float WheelSteps(float raw) { if (float.IsNaN(raw) || float.IsInfinity(raw)) { return 0f; } float val = ((Math.Abs(raw) >= 10f) ? (raw / 120f) : raw); return Math.Max(-8f, Math.Min(8f, val)); } internal static float Dolly(float distance, float forward, float wheel, float maximum) { float num = Math.Max(0.025f, Math.Min(1.5f, distance * 0.15f)); return Math.Max(0.12f, Math.Min(maximum, distance - forward - wheel * num)); } } internal sealed class FrozenEffects { private struct LightState { internal bool Enabled; internal float Intensity; internal float Range; internal Color Color; } private readonly List<ParticleSystem> particles = new List<ParticleSystem>(); private readonly Dictionary<Light, LightState> lights = new Dictionary<Light, LightState>(); private bool frozen; internal void Freeze(Vector3 centre, float radius) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Invalid comparison between Unknown and I4 //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) if (frozen) { return; } frozen = true; ParticleSystem[] array = Object.FindObjectsByType<ParticleSystem>((FindObjectsSortMode)0); foreach (ParticleSystem val in array) { Vector3 val2 = ((Component)val).transform.position - centre; if (!(((Vector3)(ref val2)).sqrMagnitude > radius * radius) && val.isPlaying) { particles.Add(val); val.Pause(false); } } Light[] array2 = Object.FindObjectsByType<Light>((FindObjectsSortMode)0); foreach (Light val3 in array2) { if ((int)val3.type != 1) { Vector3 val4 = ((Component)val3).transform.position - centre; if (((Vector3)(ref val4)).sqrMagnitude <= radius * radius) { lights[val3] = new LightState { Enabled = ((Behaviour)val3).enabled, Intensity = val3.intensity, Range = val3.range, Color = val3.color }; } } } } internal void Hold() { //IL_00af: Unknown result type (might be due to invalid IL or missing references) if (!frozen) { return; } foreach (ParticleSystem particle in particles) { if (Object.op_Implicit((Object)(object)particle) && particle.isPlaying) { particle.Pause(false); } } foreach (KeyValuePair<Light, LightState> light in lights) { if (Object.op_Implicit((Object)(object)light.Key)) { Light key = light.Key; LightState value = light.Value; ((Behaviour)key).enabled = value.Enabled; key.intensity = value.Intensity; key.range = value.Range; key.color = value.Color; } } } internal void Resume() { if (!frozen) { return; } foreach (ParticleSystem particle in particles) { if (Object.op_Implicit((Object)(object)particle) && particle.isPaused) { particle.Play(false); } } particles.Clear(); lights.Clear(); frozen = false; } } internal sealed class NativePhotoHints { private sealed class Hint { internal RectTransform root; internal TMP_Text label; internal string binding; internal readonly List<RectTransform> tokens = new List<RectTransform>(); internal float width; } private readonly Transform parent; private readonly TMP_Text keyStyle; private readonly TMP_Text labelStyle; private readonly Image keyBackground; private readonly List<Hint> hints = new List<Hint>(); private readonly TMP_Text status; private int count; internal NativePhotoHints(Transform parent, TMP_Text nativeKey, TMP_Text nativeLabel, Image background) { this.parent = parent; keyStyle = nativeKey; labelStyle = nativeLabel; keyBackground = background; status = Text(parent, "Status", labelStyle); status.alignment = (TextAlignmentOptions)514; } internal static Image FindKeyBackground(TMP_Text key) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)key)) { return null; } Transform transform = key.transform; int num = 0; while (Object.op_Implicit((Object)(object)transform) && num < 3) { Image component = ((Component)transform).GetComponent<Image>(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.sprite)) { return component; } foreach (Transform item in transform) { Transform val = item; component = ((Component)val).GetComponent<Image>(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.sprite)) { return component; } } num++; transform = transform.parent; } return null; } private static RectTransform Rect(Transform parent, string name) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) RectTransform component = new GameObject(name, new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>(); ((Transform)component).SetParent(parent, false); Vector2 anchorMin = (component.anchorMax = Vector2.zero); component.anchorMin = anchorMin; component.pivot = Vector2.zero; return component; } private TMP_Text Text(Transform parent, string value, TMP_Text style) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) RectTransform val = Rect(parent, value); TextMeshProUGUI val2 = ((Component)val).gameObject.AddComponent<TextMeshProUGUI>(); if (Object.op_Implicit((Object)(object)style)) { ((TMP_Text)val2).font = style.font; ((TMP_Text)val2).fontSharedMaterial = style.fontSharedMaterial; ((TMP_Text)val2).fontStyle = style.fontStyle; ((Graphic)val2).color = ((Graphic)style).color; } else { ((TMP_Text)val2).font = TMP_Settings.defaultFontAsset; ((Graphic)val2).color = Color.white; } ((TMP_Text)val2).fontSize = 24f; ((TMP_Text)val2).textWrappingMode = (TextWrappingModes)0; ((TMP_Text)val2).richText = false; ((TMP_Text)val2).alignment = (TextAlignmentOptions)4097; ((Graphic)val2).raycastTarget = false; ((TMP_Text)val2).text = value; return (TMP_Text)(object)val2; } internal void Begin() { count = 0; } internal void Add(string action, string binding) { //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_0304: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) Hint hint; if (count == hints.Count) { hint = new Hint(); hint.root = Rect(parent, "Photo hint"); hint.label = Text((Transform)(object)hint.root, action, labelStyle); hints.Add(hint); } else { hint = hints[count]; } count++; ((Component)hint.root).gameObject.SetActive(true); hint.label.text = action; if (hint.binding != binding) { foreach (RectTransform token in hint.tokens) { Object.Destroy((Object)(object)((Component)token).gameObject); } hint.tokens.Clear(); hint.binding = binding; string[] array = binding.Replace("+", "|+|").Replace("/", "|/|").Split(new char[1] { '|' }); foreach (string text in array) { string text2 = text.Trim(); if (text2.Length != 0) { bool flag = text2 == "+" || text2 == "/"; RectTransform val = Rect((Transform)(object)hint.root, "Key " + text2); if (!flag && Object.op_Implicit((Object)(object)keyBackground)) { Image val2 = ((Component)val).gameObject.AddComponent<Image>(); val2.sprite = keyBackground.sprite; val2.type = keyBackground.type; ((Graphic)val2).color = ((Graphic)keyBackground).color; ((Graphic)val2).material = ((Graphic)keyBackground).material; val2.pixelsPerUnitMultiplier = keyBackground.pixelsPerUnitMultiplier; ((Graphic)val2).raycastTarget = false; } TMP_Text val3 = Text((Transform)(object)val, text2, flag ? labelStyle : keyStyle); val3.alignment = (TextAlignmentOptions)4098; float num = val3.GetPreferredValues(text2).x + (float)(flag ? 4 : 18); val.sizeDelta = new Vector2(num, 34f); RectTransform rectTransform = val3.rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; Vector2 offsetMin = (rectTransform.offsetMax = Vector2.zero); rectTransform.offsetMin = offsetMin; hint.tokens.Add(val); } } } float x = hint.label.GetPreferredValues(action).x; hint.label.rectTransform.sizeDelta = new Vector2(x, 34f); x += 9f; foreach (RectTransform token2 in hint.tokens) { token2.anchoredPosition = new Vector2(x, 0f); x += token2.sizeDelta.x + 4f; } hint.width = x - 4f; hint.root.sizeDelta = new Vector2(hint.width, 34f); } internal void Finish(string message) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) for (int i = count; i < hints.Count; i++) { ((Component)hints[i].root).gameObject.SetActive(false); } RectTransform val = (RectTransform)parent; Rect rect = val.rect; float num = Mathf.Max(300f, ((Rect)(ref rect)).width - 48f); List<List<Hint>> list = new List<List<Hint>>(); List<float> list2 = new List<float>(); for (int j = 0; j < count; j++) { Hint hint = hints[j]; if (list.Count == 0 || list2[list2.Count - 1] + 24f + hint.width > num) { list.Add(new List<Hint>()); list2.Add(0f); } int index = list.Count - 1; if (list[index].Count > 0) { list2[index] += 24f; } list[index].Add(hint); list2[index] += hint.width; } for (int k = 0; k < list.Count; k++) { Rect rect2 = val.rect; float num2 = (((Rect)(ref rect2)).width - list2[k]) * 0.5f; foreach (Hint item in list[k]) { item.root.anchoredPosition = new Vector2(num2, (float)(18 + (list.Count - 1 - k) * 44)); num2 += item.width + 24f; } } status.text = message; status.rectTransform.anchoredPosition = new Vector2(24f, (float)(22 + list.Count * 44)); status.rectTransform.sizeDelta = new Vector2(num, 32f); } } internal sealed class PhotoEnvironment { private static readonly FieldInfo Fraction = AccessTools.Field(typeof(EnvMan), "m_smoothDayFraction"); private static readonly MethodInfo Render = AccessTools.Method(typeof(EnvMan), "SetEnv", (Type[])null, (Type[])null); private static readonly FieldInfo CurrentParticles = AccessTools.Field(typeof(EnvMan), "m_currentPSystems"); private readonly List<EnvSetup> weather = new List<EnvSetup>(); private readonly Dictionary<ParticleSystem, bool> simulated = new Dictionary<ParticleSystem, bool>(); private EnvMan owner; private int selection = -1; private float? time; private bool applied; private float wet; internal static bool Allowed { get { if (Object.op_Implicit((Object)(object)ZNet.instance)) { return ZNet.IsSinglePlayer; } return false; } } internal string Weather { get { if (selection >= 0) { return weather[selection].m_name; } return "Natural"; } } internal string Clock { get { if (!time.HasValue) { return "Natural"; } int num = Mathf.FloorToInt(time.Value * 1440f); return (num / 60).ToString("00") + ":" + (num % 60).ToString("00"); } } internal void Begin() { owner = EnvMan.instance; selection = -1; time = null; applied = false; weather.Clear(); if (!Object.op_Implicit((Object)(object)owner) || !Allowed) { return; } string[] array = new string[8] { "Clear", "Heath clear", "Misty", "LightRain", "Rain", "ThunderStorm", "Snow", "SnowStorm" }; foreach (string name in array) { List<EnvSetup> environments = owner.m_environments; Func<EnvSetup, bool> predicate = (EnvSetup e) => e.m_name == name; EnvSetup val = environments.FirstOrDefault(predicate); if (val != null) { weather.Add(val); } } wet = Shader.GetGlobalFloat("_Wet"); } internal void ShiftTime(float amount) { if (Allowed && Object.op_Implicit((Object)(object)owner)) { time = Mathf.Repeat((time.HasValue ? time.Value : owner.GetDayFraction()) + amount, 1f); } } internal void CycleWeather() { if (Allowed && Object.op_Implicit((Object)(object)owner)) { RestoreParticles(); selection++; if (selection >= weather.Count) { selection = -1; } if (selection < 0 && !time.HasValue) { Reset(); } } } internal void Apply(bool frozen) { if (!Allowed) { Reset(); } else { if (!Object.op_Implicit((Object)(object)owner) || (Object)(object)owner != (Object)(object)EnvMan.instance || (!time.HasValue && selection < 0)) { return; } if (!frozen) { RestoreParticles(); } applied = true; Paint((selection < 0) ? owner.GetCurrentEnvironment() : weather[selection], time.HasValue ? time.Value : owner.GetDayFraction()); if (!frozen || selection < 0 || weather[selection].m_psystems == null) { return; } GameObject[] psystems = weather[selection].m_psystems; foreach (GameObject val in psystems) { if (!Object.op_Implicit((Object)(object)val) || !val.activeInHierarchy) { continue; } ParticleSystem[] componentsInChildren = val.GetComponentsInChildren<ParticleSystem>(); foreach (ParticleSystem val2 in componentsInChildren) { if (!simulated.ContainsKey(val2)) { simulated[val2] = val2.isPlaying; } val2.Simulate(Mathf.Min(Time.unscaledDeltaTime, 0.05f), false, false, false); } } } } private void RestoreParticles() { foreach (KeyValuePair<ParticleSystem, bool> item in simulated) { if (Object.op_Implicit((Object)(object)item.Key) && item.Value && item.Key.isPaused) { item.Key.Play(false); } } simulated.Clear(); } private void Paint(EnvSetup env, float fraction) { if (env != null) { GameObject[] outgoing = (GameObject[])CurrentParticles.GetValue(owner); float num = Mathf.Sqrt(Mathf.Max(1f - Mathf.Clamp01(fraction / 0.25f), Mathf.Clamp01((fraction - 0.75f) / 0.25f))); float num2 = Mathf.Sqrt(1f - Mathf.Clamp01(Mathf.Abs(fraction - 0.5f) / 0.25f)); float num3 = Mathf.Min(1f - Mathf.Clamp01((fraction - 0.26f) / (0f - owner.m_sunHorizonTransitionL)), 1f - Mathf.Clamp01((fraction - 0.26f) / owner.m_sunHorizonTransitionH)); float num4 = Mathf.Min(1f - Mathf.Clamp01((fraction - 0.74f) / (0f - owner.m_sunHorizonTransitionH)), 1f - Mathf.Clamp01((fraction - 0.74f) / owner.m_sunHorizonTransitionL)); float num5 = num2 + num + num3 + num4; float num6 = (float)Fraction.GetValue(owner); try { Fraction.SetValue(owner, fraction); Render.Invoke(owner, new object[6] { env, num2 / num5, num / num5, num3 / num5, num4 / num5, Time.unscaledDeltaTime }); } finally { Fraction.SetValue(owner, num6); } ClearOutgoingWeather(outgoing, (GameObject[])CurrentParticles.GetValue(owner)); } } private static void ClearOutgoingWeather(GameObject[] outgoing, GameObject[] incoming) { if (outgoing == null || object.ReferenceEquals(outgoing, incoming)) { return; } HashSet<ParticleSystem> hashSet = new HashSet<ParticleSystem>(); if (incoming != null) { foreach (GameObject val in incoming) { if (Object.op_Implicit((Object)(object)val)) { ParticleSystem[] componentsInChildren = val.GetComponentsInChildren<ParticleSystem>(true); foreach (ParticleSystem item in componentsInChildren) { hashSet.Add(item); } } } } foreach (GameObject val2 in outgoing) { if (!Object.op_Implicit((Object)(object)val2)) { continue; } ParticleSystem[] componentsInChildren2 = val2.GetComponentsInChildren<ParticleSystem>(true); foreach (ParticleSystem val3 in componentsInChildren2) { if (!hashSet.Contains(val3)) { val3.Clear(false); } } } } internal void Reset() { RestoreParticles(); time = null; selection = -1; if (!applied) { return; } applied = false; if (!Object.op_Implicit((Object)(object)owner) || !((Object)(object)owner == (Object)(object)EnvMan.instance)) { return; } try { Paint(owner.GetCurrentEnvironment(), owner.GetDayFraction()); } finally { Shader.SetGlobalFloat("_Wet", wet); } } } internal static class PhotoFiles { internal static string DirectoryPath(string configured) { if (!string.IsNullOrWhiteSpace(configured)) { return Path.GetFullPath(Environment.ExpandEnvironmentVariables(configured)); } string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures); if (string.IsNullOrEmpty(folderPath)) { folderPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); } if (string.IsNullOrEmpty(folderPath)) { throw new IOException("No Pictures or Documents folder is available. Set OutputDirectory in the config."); } return Path.Combine(folderPath, "Valheim Photo Mode"); } internal static string Save(string directory, byte[] png) { if (png == null || png.Length == 0) { throw new IOException("Screenshot encoding returned no image."); } Directory.CreateDirectory(directory); string text = Path.Combine(directory, "Valheim_" + DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss-fff") + "_" + Guid.NewGuid().ToString("N").Substring(0, 8) + ".png"); string text2 = text + ".part"; bool flag = false; try { using (FileStream fileStream = new FileStream(text2, FileMode.CreateNew, FileAccess.Write, FileShare.None)) { flag = true; fileStream.Write(png, 0, png.Length); } File.Move(text2, text); return text; } finally { if (flag && File.Exists(text2)) { File.Delete(text2); } } } } [BepInPlugin("au.tyvalheim.photomode", "Saga Lens - Photo Mode", "0.1.7")] public sealed class Plugin : BaseUnityPlugin { public const string Id = "au.tyvalheim.photomode"; public const string Version = "0.1.7"; internal static Plugin Instance; internal static bool ReadingInput; internal bool Active; internal bool Frozen; private bool orbit = true; private bool hidePlayer; private bool hideHud = true; private bool capturing; private float releaseAt; private float yaw; private float pitch; private float roll; private float distance; private float fov; private float originalFov; private float originalNear; private float originalSkyFov; private float nextRenderScan; private float nextCanvasScan; private Camera skyCamera; private readonly FrozenEffects effects = new FrozenEffects(); private readonly PhotoEnvironment environment = new PhotoEnvironment(); private float homeYaw; private float homePitch; private float homeDistance; private int lastBusyFrame = -2; private Vector3 lastSubjectPosition; private Vector3 position; private Vector3 pivot; private Camera camera; private Player subject; private CursorLockMode originalLock; private bool originalCursor; private Harmony harmony; private GameObject strip; private NativePhotoHints hints; private float nextHintRefresh; private string notice = ""; private float noticeUntil; private readonly Dictionary<Renderer, bool> renderers = new Dictionary<Renderer, bool>(); private readonly Dictionary<Canvas, bool> canvases = new Dictionary<Canvas, bool>(); private readonly Dictionary<string, ConfigEntry<KeyboardShortcut>> keys = new Dictionary<string, ConfigEntry<KeyboardShortcut>>(); private ConfigEntry<bool> freezeDefault; private ConfigEntry<float> speed; private ConfigEntry<float> sensitivity; private ConfigEntry<float> range; private ConfigEntry<string> output; internal static bool CapturingInput { get { if (Object.op_Implicit((Object)(object)Instance)) { if (!Instance.Active) { return Time.unscaledTime < Instance.releaseAt; } return true; } return false; } } internal static bool PauseScene { get { if (Object.op_Implicit((Object)(object)Instance) && Instance.Active && Instance.Frozen && Object.op_Implicit((Object)(object)ZNet.instance)) { return ZNet.IsSinglePlayer; } return false; } } private void Awake() { //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Expected O, but got Unknown //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Expected O, but got Unknown //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Expected O, but got Unknown //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Expected O, but got Unknown Instance = this; Bind("Toggle", (KeyCode)293); Bind("Capture", (KeyCode)13); Bind("CameraMode", (KeyCode)9); Bind("Character", (KeyCode)118); Bind("HUD", (KeyCode)104); Bind("Freeze", (KeyCode)112); Bind("Reset", (KeyCode)114); Bind("Forward", (KeyCode)119); Bind("Back", (KeyCode)115); Bind("Left", (KeyCode)97); Bind("Right", (KeyCode)100); Bind("Up", (KeyCode)32); Bind("Down", (KeyCode)306); Bind("Fast", (KeyCode)304); Bind("Slow", (KeyCode)308); Bind("TimeEarlier", (KeyCode)281); Bind("TimeLater", (KeyCode)280); Bind("Weather", (KeyCode)278); Bind("NaturalConditions", (KeyCode)279); Bind("RollLeft", (KeyCode)113); Bind("RollRight", (KeyCode)101); Bind("WiderLens", (KeyCode)91); Bind("NarrowerLens", (KeyCode)93); freezeDefault = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera", "FreezeSinglePlayer", true, "Freeze on entry in offline single-player only. P toggles. Multiplayer always stays live."); speed = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "MovementSpeed", 4f, new ConfigDescription("Metres per second; Shift is 3x faster.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 15f), new object[0])); sensitivity = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "MouseSensitivity", 0.12f, new ConfigDescription("Degrees per mouse pixel.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 1f), new object[0])); range = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "MaximumDistance", 40f, new ConfigDescription("Camera tether to the player; does not load remote scenery.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 60f), new object[0])); output = ((BaseUnityPlugin)this).Config.Bind<string>("Capture", "OutputDirectory", "", "Empty saves to Pictures/Valheim Photo Mode. An absolute custom path is supported. PNG at current screen resolution."); harmony = new Harmony("au.tyvalheim.photomode"); harmony.PatchAll(); } private void Bind(string name, KeyCode key) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) keys[name] = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Keys", name, new KeyboardShortcut(key, (KeyCode[])(object)new KeyCode[0]), "Photo-mode binding. Restart the game after editing. Escape always exits."); } private bool Held(string name) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = keys[name].Value; if ((int)((KeyboardShortcut)(ref value)).MainKey != 0 && ZInput.GetKey(((KeyboardShortcut)(ref value)).MainKey, true)) { return ((KeyboardShortcut)(ref value)).Modifiers.All((KeyCode k) => ZInput.GetKey(k, true)); } return false; } private bool Pressed(string name) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = keys[name].Value; if ((int)((KeyboardShortcut)(ref value)).MainKey != 0 && ZInput.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey, true)) { return ((KeyboardShortcut)(ref value)).Modifiers.All((KeyCode k) => ZInput.GetKey(k, true)); } return false; } private string Key(string name) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected I4, but got Unknown KeyboardShortcut value = keys[name].Value; return string.Join(" + ", ((KeyboardShortcut)(ref value)).Modifiers.Concat((IEnumerable<KeyCode>)(object)new KeyCode[1] { (KeyCode)(int)((KeyboardShortcut)(ref value)).MainKey }).Select(KeyName).ToArray()); } private static string KeyName(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Invalid comparison between Unknown and I4 //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected I4, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected I4, but got Unknown if ((int)key != 13) { switch (key - 91) { default: switch (key - 305) { case 1: return "L Ctrl"; case 0: return "R Ctrl"; } break; case 0: return "["; case 2: return "]"; case 1: break; } return ((object)key).ToString().Replace("Alpha", "").Replace("Left", "L ") .Replace("Right", "R "); } return "Enter"; } private static bool Typing() { if (TextInput.IsVisible() || UnifiedPopup.WasVisibleThisFrame() || (Object.op_Implicit((Object)(object)Chat.instance) && Chat.instance.HasFocus())) { return true; } if (Object.op_Implicit((Object)(object)TextInput.instance) && Object.op_Implicit((Object)(object)TextInput.instance.m_panel) && TextInput.instance.m_panel.activeInHierarchy) { return true; } GameObject val = (Object.op_Implicit((Object)(object)EventSystem.current) ? EventSystem.current.currentSelectedGameObject : null); if (Object.op_Implicit((Object)(object)val) && val.activeInHierarchy) { if (!Object.op_Implicit((Object)(object)val.GetComponentInParent<TMP_InputField>())) { return Object.op_Implicit((Object)(object)val.GetComponentInParent<InputField>()); } return true; } return false; } private static bool Busy() { if (!Typing() && !Console.IsVisible() && !Menu.IsVisible()) { return StoreGui.IsVisible(); } return true; } private void Update() { //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_041e: Unknown result type (might be due to invalid IL or missing references) //IL_0423: Unknown result type (might be due to invalid IL or missing references) //IL_0498: Unknown result type (might be due to invalid IL or missing references) //IL_049f: Unknown result type (might be due to invalid IL or missing references) //IL_04a6: Unknown result type (might be due to invalid IL or missing references) //IL_04ab: Unknown result type (might be due to invalid IL or missing references) //IL_04b8: Unknown result type (might be due to invalid IL or missing references) //IL_05b3: Unknown result type (might be due to invalid IL or missing references) //IL_05b8: Unknown result type (might be due to invalid IL or missing references) //IL_05ba: Unknown result type (might be due to invalid IL or missing references) //IL_05bc: Unknown result type (might be due to invalid IL or missing references) //IL_05c1: Unknown result type (might be due to invalid IL or missing references) //IL_05c6: Unknown result type (might be due to invalid IL or missing references) //IL_051b: Unknown result type (might be due to invalid IL or missing references) //IL_0520: Unknown result type (might be due to invalid IL or missing references) //IL_052c: Unknown result type (might be due to invalid IL or missing references) //IL_0531: Unknown result type (might be due to invalid IL or missing references) //IL_0536: Unknown result type (might be due to invalid IL or missing references) //IL_0547: Unknown result type (might be due to invalid IL or missing references) //IL_054d: Unknown result type (might be due to invalid IL or missing references) //IL_055d: Unknown result type (might be due to invalid IL or missing references) //IL_0562: Unknown result type (might be due to invalid IL or missing references) //IL_0578: Unknown result type (might be due to invalid IL or missing references) //IL_057d: Unknown result type (might be due to invalid IL or missing references) //IL_0582: Unknown result type (might be due to invalid IL or missing references) //IL_0589: Unknown result type (might be due to invalid IL or missing references) //IL_058e: Unknown result type (might be due to invalid IL or missing references) //IL_0590: Unknown result type (might be due to invalid IL or missing references) //IL_0595: Unknown result type (might be due to invalid IL or missing references) //IL_05a0: Unknown result type (might be due to invalid IL or missing references) //IL_05a5: Unknown result type (might be due to invalid IL or missing references) //IL_05aa: Unknown result type (might be due to invalid IL or missing references) //IL_05fb: Unknown result type (might be due to invalid IL or missing references) //IL_0601: Unknown result type (might be due to invalid IL or missing references) //IL_0611: Unknown result type (might be due to invalid IL or missing references) //IL_0616: Unknown result type (might be due to invalid IL or missing references) //IL_0626: Unknown result type (might be due to invalid IL or missing references) //IL_062b: Unknown result type (might be due to invalid IL or missing references) //IL_0630: Unknown result type (might be due to invalid IL or missing references) ReadingInput = true; try { if (!Active) { bool flag = Busy(); if (flag) { lastBusyFrame = Time.frameCount; } if (Time.unscaledTime >= releaseAt && !flag && Time.frameCount > lastBusyFrame + 1 && Pressed("Toggle")) { Enter(); } } else if (!Object.op_Implicit((Object)(object)subject) || (Object)(object)subject != (Object)(object)Player.m_localPlayer || ((Character)subject).IsDead() || ((Character)subject).IsTeleporting() || ((Character)subject).InCutscene() || !Object.op_Implicit((Object)(object)camera) || !Application.isFocused) { Exit(); } else if (Pressed("Toggle") || ZInput.GetKeyDown((KeyCode)27, true)) { if (!capturing) { Exit(); } } else if (Busy()) { if (!capturing) { Exit(); } } else { if (capturing) { return; } if (orbit) { pivot += ((Component)subject).transform.position - lastSubjectPosition; } lastSubjectPosition = ((Component)subject).transform.position; if (Pressed("CameraMode")) { SwitchCameraMode(); } if (Pressed("Character")) { hidePlayer = !hidePlayer; UpdateVisibility(force: true); } if (Pressed("HUD")) { hideHud = !hideHud; UpdateVisibility(force: true); } if (Pressed("Freeze")) { if (!Object.op_Implicit((Object)(object)ZNet.instance) || !ZNet.IsSinglePlayer) { SetFrozen(value: false); Notify("Multiplayer stays live"); } else { SetFrozen(!Frozen); } } if (Pressed("Reset")) { ResetPose(); } if (PhotoEnvironment.Allowed) { float num = (float)((Held("TimeLater") ? 1 : 0) - (Held("TimeEarlier") ? 1 : 0)) * Time.unscaledDeltaTime / 48f; if (num != 0f) { environment.ShiftTime(num); } if (Pressed("Weather")) { environment.CycleWeather(); } if (Pressed("NaturalConditions")) { environment.Reset(); } } float num2 = Mathf.Min(Time.unscaledDeltaTime, 0.05f); float num3 = (Held("Slow") ? 0.15f : (Held("Fast") ? 3f : 1f)); float num4 = speed.Value * num2 * num3; Mouse current = Mouse.current; Vector2 val = ((current == null) ? Vector2.zero : ((InputControl<Vector2>)(object)((Pointer)current).delta).ReadValue()); yaw += val.x * sensitivity.Value; pitch = Mathf.Clamp(pitch - val.y * sensitivity.Value, -85f, 85f); if (orbit) { yaw += (float)(((Held("Right") ? 1 : 0) - (Held("Left") ? 1 : 0)) * 45) * num2 * num3; } roll = Mathf.Clamp(roll + (float)(((Held("RollRight") ? 1 : 0) - (Held("RollLeft") ? 1 : 0)) * 30) * num2, -90f, 90f); fov = Mathf.Clamp(fov + (float)(((Held("WiderLens") ? 1 : 0) - (Held("NarrowerLens") ? 1 : 0)) * 30) * num2, 15f, 130f); Quaternion val2 = Quaternion.Euler(pitch, yaw, roll); Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor((float)((Held("Right") ? 1 : 0) - (Held("Left") ? 1 : 0)), (float)((Held("Up") ? 1 : 0) - (Held("Down") ? 1 : 0)), (float)((Held("Forward") ? 1 : 0) - (Held("Back") ? 1 : 0))); val3 = Vector3.ClampMagnitude(val3, 1f) * num4; float num5 = ((current == null) ? 0f : ((InputControl<Vector2>)(object)current.scroll).ReadValue().y); if (Mathf.Approximately(num5, 0f)) { num5 = ZInput.GetMouseScrollWheel(); } float num6 = CameraRules.WheelSteps(num5); if (orbit) { distance = CameraRules.Dolly(distance, val3.z, num6, range.Value); pivot += Vector3.up * val3.y; pivot = ((Component)subject).transform.position + Vector3.ClampMagnitude(pivot - ((Component)subject).transform.position, range.Value * 0.5f); position = pivot - val2 * Vector3.forward * distance; } else { position += val2 * val3; fov = Mathf.Clamp(fov - num6 * 3f, 15f, 130f); } position = ((Component)subject).transform.position + Vector3.ClampMagnitude(position - ((Component)subject).transform.position, range.Value); if (Pressed("Capture")) { ((MonoBehaviour)this).StartCoroutine(Capture()); } } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)ex); if (Active) { Exit(); } } finally { ReadingInput = false; } } private void Enter() { //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: 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_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Invalid comparison between Unknown and I4 //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Invalid comparison between Unknown and I4 subject = Player.m_localPlayer; camera = (Object.op_Implicit((Object)(object)GameCamera.instance) ? ((Component)GameCamera.instance).GetComponent<Camera>() : null); if (Object.op_Implicit((Object)(object)subject) && !((Character)subject).IsDead() && !((Character)subject).IsTeleporting() && !((Character)subject).InCutscene() && Object.op_Implicit((Object)(object)camera)) { originalFov = camera.fieldOfView; originalNear = camera.nearClipPlane; homeYaw = ((Component)camera).transform.eulerAngles.y; homePitch = Mathf.DeltaAngle(0f, ((Component)camera).transform.eulerAngles.x); homeDistance = Mathf.Clamp(Vector3.Distance(((Component)camera).transform.position, ((Component)subject).transform.position + Vector3.up * 1.3f), 2f, 8f); lastSubjectPosition = ((Component)subject).transform.position; originalLock = Cursor.lockState; originalCursor = Cursor.visible; environment.Begin(); Active = true; SetFrozen(freezeDefault.Value && Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.IsSinglePlayer); orbit = true; hideHud = !Object.op_Implicit((Object)(object)Minimap.instance) || (int)Minimap.instance.m_mode != 2; hidePlayer = false; ResetPose(); EnsureStrip(); UpdateVisibility(force: true); Notify((Object.op_Implicit((Object)(object)Minimap.instance) && (int)Minimap.instance.m_mode == 2) ? ("Map photo ready - " + Key("Capture") + " saves; " + Key("HUD") + " toggles HUD") : (Frozen ? "Frozen" : "Live world")); } } private void ResetPose() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_0097: 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) pivot = ((Component)subject).transform.position + Vector3.up * 1.55f; yaw = homeYaw; pitch = homePitch; roll = 0f; distance = homeDistance; fov = originalFov; position = pivot - Quaternion.Euler(pitch, yaw, 0f) * Vector3.forward * distance; } private void SetFrozen(bool value) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (value && !Frozen) { effects.Freeze(((Component)subject).transform.position, range.Value + 30f); } if (!value) { effects.Resume(); } Frozen = value; } private void SwitchCameraMode() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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) orbit = !orbit; if (orbit) { pivot = ((Component)subject).transform.position + Vector3.up * 1.55f; Vector3 val = pivot - position; distance = Mathf.Clamp(((Vector3)(ref val)).magnitude, 0.12f, range.Value); if (((Vector3)(ref val)).sqrMagnitude > 0.0001f) { Quaternion val2 = Quaternion.LookRotation(val, Vector3.up); Vector3 eulerAngles = ((Quaternion)(ref val2)).eulerAngles; yaw = eulerAngles.y; pitch = Mathf.Clamp(Mathf.DeltaAngle(0f, eulerAngles.x), -85f, 85f); } } Notify(orbit ? "Orbit — mouse or A/D circles character" : "Free — mouse looks, A/D strafes"); } internal void ApplyCamera(Camera sky) { //IL_0022: 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) if (!Active || !Object.op_Implicit((Object)(object)camera)) { return; } ((Component)camera).transform.SetPositionAndRotation(position, Quaternion.Euler(pitch, yaw, roll)); camera.fieldOfView = fov; camera.nearClipPlane = 0.01f; if (Object.op_Implicit((Object)(object)sky)) { if (!Object.op_Implicit((Object)(object)skyCamera)) { skyCamera = sky; originalSkyFov = sky.fieldOfView; } sky.fieldOfView = fov; } ZCursor.LockState = (CursorLockMode)1; ZCursor.Hide(); } private void LateUpdate() { if (!Active) { return; } if (PauseScene) { effects.Hold(); } else if (Frozen) { SetFrozen(value: false); } try { environment.Apply(PauseScene); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)ex); Exit(); return; } UpdateVisibility(force: false); if (Object.op_Implicit((Object)(object)strip)) { strip.SetActive(!capturing); } if (hints != null && Time.unscaledTime >= nextHintRefresh) { nextHintRefresh = Time.unscaledTime + 0.1f; hints.Begin(); hints.Add("Photo", Key("Capture")); hints.Add(orbit ? "Free camera" : "Orbit camera", Key("CameraMode")); hints.Add(orbit ? "Distance" : "Move", orbit ? (Key("Forward") + " / " + Key("Back")) : (Key("Forward") + " / " + Key("Left") + " / " + Key("Back") + " / " + Key("Right"))); if (orbit) { hints.Add("Circle", Key("Left") + " / " + Key("Right")); } hints.Add("Height", Key("Up") + " / " + Key("Down")); hints.Add("Fast", Key("Fast")); hints.Add("Slow", Key("Slow")); hints.Add(orbit ? "Orbit" : "Look", "Mouse"); hints.Add(orbit ? "Distance" : "Lens", "Wheel"); hints.Add(hidePlayer ? "Show character" : "Hide character", Key("Character")); hints.Add(hideHud ? "Show HUD" : "Hide HUD", Key("HUD")); if (Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.IsSinglePlayer) { hints.Add(PauseScene ? "Resume" : "Freeze", Key("Freeze")); } hints.Add("Tilt", Key("RollLeft") + " / " + Key("RollRight")); hints.Add("Lens " + Mathf.RoundToInt(fov) + "°", Key("WiderLens") + " / " + Key("NarrowerLens")); hints.Add("Reset", Key("Reset")); hints.Add("Exit", Key("Toggle") + " / Esc"); if (PhotoEnvironment.Allowed) { hints.Add("Time " + environment.Clock, Key("TimeEarlier") + " / " + Key("TimeLater")); hints.Add("Weather " + environment.Weather, Key("Weather")); hints.Add("Natural conditions", Key("NaturalConditions")); } string text = (PhotoEnvironment.Allowed ? "" : "Time & weather unavailable in multiplayer."); if (Time.unscaledTime < noticeUntil) { text = text + ((text.Length > 0) ? " " : "") + notice; } hints.Finish(text); } } private void EnsureStrip() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)strip)) { return; } strip = new GameObject("Photo controls", new Type[3] { typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler) }); Canvas component = strip.GetComponent<Canvas>(); component.renderMode = (RenderMode)0; component.sortingOrder = 32000; CanvasScaler component2 = strip.GetComponent<CanvasScaler>(); component2.uiScaleMode = (ScaleMode)1; component2.referenceResolution = new Vector2(1920f, 1080f); component2.matchWidthOrHeight = 0.5f; KeyHints instance = KeyHints.instance; TMP_Text val = (TMP_Text)(object)(Object.op_Implicit((Object)(object)instance) ? instance.m_buildMenuKey : null); TMP_Text val2 = null; if (Object.op_Implicit((Object)(object)instance) && Object.op_Implicit((Object)(object)instance.m_primaryAttackKB)) { val2 = ((IEnumerable<TMP_Text>)instance.m_primaryAttackKB.GetComponentsInChildren<TMP_Text>(true)).FirstOrDefault((Func<TMP_Text, bool>)((TMP_Text t) => !Object.op_Implicit((Object)(object)NativePhotoHints.FindKeyBackground(t)))); } if (!Object.op_Implicit((Object)(object)val2)) { val2 = val; } Image val3 = NativePhotoHints.FindKeyBackground(val); if (!Object.op_Implicit((Object)(object)val3)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Native keycap artwork was not available; photo hints will use text until the UI is recreated."); } hints = new NativePhotoHints(strip.transform, val, val2, val3); } private void UpdateVisibility(bool force) { if (hidePlayer) { if (force || Time.unscaledTime >= nextRenderScan) { nextRenderScan = Time.unscaledTime + 0.25f; Renderer[] componentsInChildren = ((Component)subject).GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if (!renderers.ContainsKey(val)) { renderers[val] = val.forceRenderingOff; } } } foreach (Renderer key in renderers.Keys) { if (Object.op_Implicit((Object)(object)key)) { key.forceRenderingOff = true; } } } else { foreach (KeyValuePair<Renderer, bool> renderer in renderers) { if (Object.op_Implicit((Object)(object)renderer.Key)) { renderer.Key.forceRenderingOff = renderer.Value; } } renderers.Clear(); } if (hideHud) { if (force || Time.unscaledTime >= nextCanvasScan) { nextCanvasScan = Time.unscaledTime + 0.25f; Canvas[] array = Object.FindObjectsByType<Canvas>((FindObjectsSortMode)0); foreach (Canvas val2 in array) { if (Object.op_Implicit((Object)(object)val2) && (Object)(object)((Component)val2).gameObject != (Object)(object)strip && !canvases.ContainsKey(val2)) { canvases[val2] = ((Behaviour)val2).enabled; } } } { foreach (Canvas key2 in canvases.Keys) { if (Object.op_Implicit((Object)(object)key2)) { ((Behaviour)key2).enabled = false; } } return; } } foreach (KeyValuePair<Canvas, bool> canvase in canvases) { if (Object.op_Implicit((Object)(object)canvase.Key)) { ((Behaviour)canvase.Key).enabled = canvase.Value; } } canvases.Clear(); } private IEnumerator Capture() { capturing = true; if (Object.op_Implicit((Object)(object)strip)) { strip.SetActive(false); } yield return (object)new WaitForEndOfFrame(); Texture2D image = null; try { if (Active && Object.op_Implicit((Object)(object)camera)) { image = ScreenCapture.CaptureScreenshotAsTexture(); if (!Object.op_Implicit((Object)(object)image)) { throw new InvalidOperationException("No rendered frame was available."); } string text = PhotoFiles.Save(PhotoFiles.DirectoryPath(output.Value), ScreenshotEncoding.EncodeOpaquePng(image)); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Screenshot saved: " + text)); Notify("Saved " + Path.GetFileName(text)); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)ex); Notify("Photo failed — see BepInEx log"); } finally { if (Object.op_Implicit((Object)(object)image)) { Object.Destroy((Object)(object)image); } capturing = false; if (Object.op_Implicit((Object)(object)strip) && Active) { strip.SetActive(true); } } } private void Notify(string message) { ((BaseUnityPlugin)this).Logger.LogInfo((object)message); notice = message; noticeUntil = Time.unscaledTime + 5f; } private void Exit() { //IL_0160: Unknown result type (might be due to invalid IL or missing references) Active = false; try { environment.Reset(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)ex); } SetFrozen(value: false); releaseAt = Time.unscaledTime + 0.2f; foreach (KeyValuePair<Renderer, bool> renderer in renderers) { if (Object.op_Implicit((Object)(object)renderer.Key)) { renderer.Key.forceRenderingOff = renderer.Value; } } renderers.Clear(); foreach (KeyValuePair<Canvas, bool> canvase in canvases) { if (Object.op_Implicit((Object)(object)canvase.Key)) { ((Behaviour)canvase.Key).enabled = canvase.Value; } } canvases.Clear(); if (Object.op_Implicit((Object)(object)camera)) { camera.fieldOfView = originalFov; camera.nearClipPlane = originalNear; } if (Object.op_Implicit((Object)(object)skyCamera)) { skyCamera.fieldOfView = originalSkyFov; } skyCamera = null; if (Object.op_Implicit((Object)(object)strip)) { strip.SetActive(false); } Cursor.lockState = originalLock; Cursor.visible = originalCursor; } private void OnDisable() { if (Active) { Exit(); } } private void OnDestroy() { if (Active) { Exit(); } if (Object.op_Implicit((Object)(object)strip)) { Object.Destroy((Object)(object)strip); } if (harmony != null) { harmony.UnpatchSelf(); } if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } } [HarmonyPatch(typeof(GameCamera), "UpdateCamera")] internal static class CameraPatch { private static bool Prefix(Camera ___m_skyCamera) { if (!Object.op_Implicit((Object)(object)Plugin.Instance) || !Plugin.Instance.Active) { return true; } Plugin.Instance.ApplyCamera(___m_skyCamera); return false; } } [HarmonyPatch(typeof(EventSystem), "Update")] internal static class UiInputPatch { private static bool Prefix() { return !Plugin.CapturingInput; } } [HarmonyPatch(typeof(GameCamera), "UpdateFOV")] internal static class FovPatch { private static bool Prefix() { if (Object.op_Implicit((Object)(object)Plugin.Instance)) { return !Plugin.Instance.Active; } return true; } } [HarmonyPatch(typeof(GameCamera), "ScreenShot")] internal static class NativeCapturePatch { private static bool Prefix() { return !Plugin.CapturingInput; } } [HarmonyPatch(typeof(GameCamera), "UpdateMouseCapture")] internal static class CursorPatch { private static bool Prefix() { if (Object.op_Implicit((Object)(object)Plugin.Instance)) { return !Plugin.Instance.Active; } return true; } } [HarmonyPatch(typeof(Game), "IsPaused")] internal static class PausePatch { private static void Postfix(ref bool __result) { if (Plugin.PauseScene) { __result = true; } } } [HarmonyPatch(typeof(Player), "TakeInput")] internal static class PlayerInputPatch { private static void Postfix(Player __instance, ref bool __result) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && Plugin.CapturingInput) { __result = false; } } } [HarmonyPatch(typeof(PlayerController), "TakeInput")] internal static class ControllerPatch { private static void Postfix(Player ___m_character, ref bool __result) { if ((Object)(object)___m_character == (Object)(object)Player.m_localPlayer && Plugin.CapturingInput) { __result = false; } } } [HarmonyPatch] internal static class ButtonsPatch { private static IEnumerable<MethodBase> TargetMethods() { try { string[] array = new string[3] { "GetButton", "GetButtonDown", "GetButtonUp" }; foreach (string name in array) { yield return AccessTools.Method(typeof(ZInput), name, new Type[1] { typeof(string) }, (Type[])null); } } finally { } try { string[] array2 = new string[3] { "GetKey", "GetKeyDown", "GetKeyUp" }; foreach (string name2 in array2) { yield return AccessTools.Method(typeof(ZInput), name2, new Type[2] { typeof(KeyCode), typeof(bool) }, (Type[])null); } } finally { } } private static bool Prefix(ref bool __result) { if (Plugin.ReadingInput || !Plugin.CapturingInput) { return true; } __result = false; return false; } } internal static class ScreenshotEncoding { internal static byte[] EncodeOpaquePng(Texture2D frame) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)frame)) { throw new ArgumentNullException("frame"); } Texture2D val = new Texture2D(((Texture)frame).width, ((Texture)frame).height, (TextureFormat)3, false); try { val.SetPixels32(frame.GetPixels32()); val.Apply(false, false); return ImageConversion.EncodeToPNG(val); } finally { if (Application.isPlaying) { Object.Destroy((Object)(object)val); } else { Object.DestroyImmediate((Object)(object)val); } } } }