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 Valheim Portal View v1.0.0
Valheim_PortalView.dll
Decompiled a day agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.PostProcessing; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Valheim_PortalView { public static class PortalCamera { private const int Supersample = 2; private const float NearClip = 0.1f; private static bool s_described; private static readonly FieldRef<Player, GameObject> s_placementGhost = AccessTools.FieldRefAccess<Player, GameObject>("m_placementGhost"); private static readonly FieldRef<GameCamera, Camera> s_mainCamera = AccessTools.FieldRefAccess<GameCamera, Camera>("m_camera"); public static Texture2D Render(Transform portal, PortalShape shape, Vector3 look, int size) { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0162: 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) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0195: 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_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: 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_0298: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Expected O, but got Unknown GameCamera instance = GameCamera.instance; Camera val = (((Object)(object)instance != (Object)null) ? s_mainCamera.Invoke(instance) : null); if ((Object)(object)val == (Object)null) { PortalViewPlugin.Log.LogWarning((object)"No game camera to copy, no picture."); return null; } Camera skyCamera = instance.m_skyCamera; if (!s_described) { s_described = true; PortalViewPlugin.Log.LogInfo((object)($"Copying main camera (clear {val.clearFlags}, hdr {val.allowHDR}, " + $"post-processing {(Object)(object)((Component)val).GetComponent<PostProcessingBehaviour>() != (Object)null}) and " + (((Object)(object)skyCamera != (Object)null) ? $"sky camera (clear {skyCamera.clearFlags}, depth {skyCamera.depth} vs {val.depth})." : "no sky camera."))); } Vector3 val2 = portal.TransformPoint(shape.Center); Quaternion val3 = Quaternion.LookRotation(look, Vector3.up); int num = size * 2; List<GameObject> list = new List<GameObject>(); List<Renderer> list2 = new List<Renderer>(); PostProcessingProfile val4 = null; RenderTexture temporary = RenderTexture.GetTemporary(num, num, 24, (RenderTextureFormat)0, (RenderTextureReadWrite)0); RenderTexture active = RenderTexture.active; try { RenderTexture.active = temporary; GL.Clear(true, true, Color.black); RenderTexture.active = active; if ((Object)(object)skyCamera != (Object)null) { Camera camera = Copy(skyCamera, "pv_sky", list); Quaternion val5 = Quaternion.Inverse(((Component)val).transform.rotation); Vector3 val6 = val5 * (((Component)skyCamera).transform.position - ((Component)val).transform.position); Aim(rotation: val3 * (val5 * ((Component)skyCamera).transform.rotation), camera: camera, position: val2 + val3 * val6, target: temporary); } Camera val7 = Copy(val, "pv_view", list); Aim(val7, val2, val3, temporary); if (PortalViewConfig.PostProcessing.Value) { val4 = AddPostProcessing(val, ((Component)val7).gameObject); } foreach (GameObject item in list) { item.SetActive(true); } Hide(((Component)portal).gameObject, list2); Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { Hide(((Component)localPlayer).gameObject, list2); Hide(s_placementGhost.Invoke(localPlayer), list2); } foreach (GameObject item2 in list) { item2.GetComponent<Camera>().Render(); } RenderTexture.active = temporary; Texture2D val8 = new Texture2D(num, num, (TextureFormat)3, false); val8.ReadPixels(new Rect(0f, 0f, (float)num, (float)num), 0, 0, false); val8.Apply(); return val8; } catch (Exception ex) { PortalViewPlugin.Log.LogError((object)("Portal picture failed: " + ex)); return null; } finally { RenderTexture.active = active; foreach (Renderer item3 in list2) { if ((Object)(object)item3 != (Object)null) { item3.enabled = true; } } foreach (GameObject item4 in list) { Camera component = item4.GetComponent<Camera>(); if ((Object)(object)component != (Object)null) { component.targetTexture = null; } Object.Destroy((Object)(object)item4); } if ((Object)(object)val4 != (Object)null) { Object.Destroy((Object)(object)val4); } RenderTexture.ReleaseTemporary(temporary); } } private static Camera Copy(Camera source, string name, List<GameObject> rig) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown GameObject val = new GameObject(name); val.SetActive(false); Object.DontDestroyOnLoad((Object)(object)val); rig.Add(val); Camera obj = val.AddComponent<Camera>(); obj.CopyFrom(source); ((Behaviour)obj).enabled = false; return obj; } private static void Aim(Camera camera, Vector3 position, Quaternion rotation, RenderTexture target) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) ((Component)camera).transform.SetPositionAndRotation(position, rotation); camera.targetTexture = target; camera.aspect = 1f; camera.fieldOfView = PortalViewConfig.FieldOfView.Value; camera.nearClipPlane = 0.1f; camera.rect = new Rect(0f, 0f, 1f, 1f); } private static PostProcessingProfile AddPostProcessing(Camera main, GameObject view) { PostProcessingBehaviour component = ((Component)main).GetComponent<PostProcessingBehaviour>(); if ((Object)(object)component == (Object)null || (Object)(object)component.profile == (Object)null) { return null; } PostProcessingProfile val = Object.Instantiate<PostProcessingProfile>(component.profile); ((Object)val).name = "pv_profile"; ((PostProcessingModel)val.motionBlur).enabled = false; ((PostProcessingModel)val.antialiasing).enabled = false; ((PostProcessingModel)val.eyeAdaptation).enabled = false; ((PostProcessingModel)val.depthOfField).enabled = false; ((PostProcessingModel)val.chromaticAberration).enabled = false; ((PostProcessingModel)val.grain).enabled = false; ((PostProcessingModel)val.vignette).enabled = false; ((PostProcessingModel)val.dithering).enabled = false; ((PostProcessingModel)val.debugViews).enabled = false; view.AddComponent<PostProcessingBehaviour>().profile = val; return val; } private static void Hide(GameObject root, List<Renderer> hidden) { if ((Object)(object)root == (Object)null) { return; } Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(); foreach (Renderer val in componentsInChildren) { if (val.enabled) { val.enabled = false; hidden.Add(val); } } } public static Texture2D Downscale(Texture2D source, int size) { //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) int num = ((Texture)source).width / size; Color32[] pixels = source.GetPixels32(); Color32[] array = (Color32[])(object)new Color32[size * size]; int num2 = num * num; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { int num3 = 0; int num4 = 0; int num5 = 0; for (int k = 0; k < num; k++) { int num6 = (i * num + k) * ((Texture)source).width + j * num; for (int l = 0; l < num; l++) { Color32 val = pixels[num6 + l]; num3 += val.r; num4 += val.g; num5 += val.b; } } array[i * size + j] = new Color32((byte)(num3 / num2), (byte)(num4 / num2), (byte)(num5 / num2), byte.MaxValue); } } Texture2D val2 = new Texture2D(size, size, (TextureFormat)3, false); val2.SetPixels32(array); val2.Apply(); return val2; } } public static class PortalImages { public const string IdKey = "pv_id"; public const string ImageKey = "pv_img"; private static readonly Dictionary<string, Material> s_materials = new Dictionary<string, Material>(); private static Shader s_shader; private static readonly string[] ShaderNames = new string[3] { "Particles/Standard Unlit", "Unlit/Texture", "Legacy Shaders/Diffuse" }; private static bool s_shaderMissing; public static string NewId() { return DateTime.Now.ToString("yyyy-MM-dd_HHmmss") + "_" + Random.Range(4096, 65535).ToString("x4"); } public static Material MaterialFor(string id, byte[] jpeg) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_009d: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(id)) { return null; } if (s_materials.TryGetValue(id, out var value) && (Object)(object)value != (Object)null) { return value; } Shader val = Shader(); if ((Object)(object)val == (Object)null) { return null; } Texture2D val2 = Decode(jpeg); if ((Object)(object)val2 == (Object)null) { PortalViewPlugin.Log.LogWarning((object)("Picture " + id + " does not decode.")); return null; } ((Object)val2).name = "pv_" + id; Material val3 = new Material(val) { name = "pv_" + id, mainTexture = (Texture)(object)val2, renderQueue = 2000 }; val3.color = Color.white; if (val3.HasProperty("_Cull")) { val3.SetFloat("_Cull", 2f); } s_materials[id] = val3; return val3; } private static Shader Shader() { if ((Object)(object)s_shader != (Object)null || s_shaderMissing) { return s_shader; } string[] shaderNames = ShaderNames; foreach (string text in shaderNames) { s_shader = Shader.Find(text) ?? Loaded(text); if ((Object)(object)s_shader != (Object)null && s_shader.isSupported) { PortalViewPlugin.Log.LogInfo((object)("Portal views drawn with shader " + text + ".")); return s_shader; } } s_shader = null; s_shaderMissing = true; PortalViewPlugin.Log.LogError((object)("None of " + string.Join(", ", ShaderNames) + " is available, portal views cannot be shown.")); return null; } private static Shader Loaded(string name) { Shader[] array = Resources.FindObjectsOfTypeAll<Shader>(); foreach (Shader val in array) { if (((Object)val).name == name) { return val; } } return null; } private static Texture2D Decode(byte[] bytes) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_0082: 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) if (bytes == null || bytes.Length == 0) { return null; } Texture2D val = new Texture2D(2, 2, (TextureFormat)3, true); if (!ImageConversion.LoadImage(val, bytes, false)) { Object.Destroy((Object)(object)val); return null; } float value = PortalViewConfig.Brightness.Value; if (!Mathf.Approximately(value, 1f)) { Color32[] pixels = val.GetPixels32(); for (int i = 0; i < pixels.Length; i++) { Color32 val2 = pixels[i]; pixels[i] = new Color32((byte)Mathf.Min(255f, (float)(int)val2.r * value), (byte)Mathf.Min(255f, (float)(int)val2.g * value), (byte)Mathf.Min(255f, (float)(int)val2.b * value), byte.MaxValue); } val.SetPixels32(pixels); } ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)2; ((Texture)val).anisoLevel = 4; val.Apply(true, true); return val; } public static byte[] EncodeJpeg(Texture2D texture, int quality, int maxBytes, out int usedQuality) { usedQuality = Mathf.Clamp(quality, 20, 100); byte[] array = ImageConversion.EncodeToJPG(texture, usedQuality); while (array.Length > maxBytes && usedQuality > 20) { usedQuality = Mathf.Max(20, usedQuality - 10); array = ImageConversion.EncodeToJPG(texture, usedQuality); } return array; } public static string WritePng(string id, byte[] png) { try { string value = PortalViewConfig.ExportFolder.Value; string text = Path.Combine(string.IsNullOrEmpty(value) ? Path.Combine(Paths.ConfigPath, "Valheim_PortalView") : value, SafeWorldName()); Directory.CreateDirectory(text); string text2 = Path.Combine(text, id + ".png"); File.WriteAllBytes(text2, png); return text2; } catch (Exception ex) { PortalViewPlugin.Log.LogWarning((object)("Could not export the png: " + ex.Message)); return null; } } private static string SafeWorldName() { string text = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetWorldName() : null); if (string.IsNullOrEmpty(text)) { return "unknown"; } char[] invalidFileNameChars = Path.GetInvalidFileNameChars(); foreach (char oldChar in invalidFileNameChars) { text = text.Replace(oldChar, '_'); } return text; } } public sealed class PortalShape { public float CenterY; public float[] Radii; public const float Step = 5f; public const float Overlap = 0.04f; public Vector3 Center => new Vector3(0f, CenterY, 0f); public float Extent { get { float num = 0f; float[] radii = Radii; foreach (float num2 in radii) { num = Mathf.Max(num, num2); } return num + 0.04f; } } } public static class PortalShapes { private static readonly Dictionary<string, PortalShape> s_shapes = new Dictionary<string, PortalShape> { ["portal_wood"] = new PortalShape { CenterY = 1.37f, Radii = new float[72] { 1.22f, 1.22f, 1.22f, 1.23f, 1.21f, 1.2f, 1.19f, 1.2f, 1.21f, 1.2f, 1.2f, 1.2f, 1.21f, 1.22f, 1.25f, 1.28f, 1.33f, 1.33f, 1.19f, 1.16f, 1.16f, 1.16f, 1.16f, 1.18f, 1.18f, 1.18f, 1.18f, 1.18f, 1.17f, 1.16f, 1.16f, 1.13f, 1.1f, 1.09f, 1.09f, 1.09f, 1.09f, 1.08f, 1.09f, 1.1f, 1.12f, 1.15f, 1.19f, 1.21f, 1.21f, 1.22f, 1.24f, 1.27f, 1.31f, 1.35f, 1.32f, 1.3f, 1.29f, 1.28f, 1.29f, 1.29f, 1.31f, 1.34f, 1.38f, 1.41f, 1.4f, 1.37f, 1.36f, 1.35f, 1.35f, 1.35f, 1.31f, 1.29f, 1.27f, 1.26f, 1.24f, 1.22f } }, ["portal_stone"] = new PortalShape { CenterY = 2.4f, Radii = new float[72] { 1.89f, 1.89f, 1.89f, 1.9f, 1.92f, 1.9f, 1.9f, 1.9f, 1.91f, 1.92f, 1.91f, 1.91f, 1.92f, 1.93f, 1.9f, 1.88f, 1.88f, 1.88f, 1.88f, 1.88f, 1.88f, 1.9f, 1.93f, 1.92f, 1.91f, 1.91f, 1.92f, 1.91f, 1.9f, 1.9f, 1.9f, 1.92f, 1.9f, 1.89f, 1.89f, 1.89f, 1.85f, 1.82f, 1.81f, 1.78f, 1.76f, 1.76f, 1.76f, 1.76f, 1.78f, 1.82f, 1.87f, 1.92f, 2.03f, 2.21f, 2.15f, 2.11f, 2.09f, 2.08f, 2.08f, 2.08f, 2.11f, 2.16f, 2.21f, 2.03f, 1.92f, 1.87f, 1.82f, 1.78f, 1.76f, 1.76f, 1.76f, 1.76f, 1.78f, 1.81f, 1.82f, 1.85f } } }; private static readonly Dictionary<string, Mesh> s_meshes = new Dictionary<string, Mesh>(); public static IEnumerable<string> PrefabNames => s_shapes.Keys; public static PortalShape For(string prefabName) { if (prefabName == null || !s_shapes.TryGetValue(prefabName, out var value)) { return null; } return value; } public static Mesh MeshFor(string prefabName) { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0208: 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_0225: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Expected O, but got Unknown //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_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: 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_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) if (s_meshes.TryGetValue(prefabName, out var value) && (Object)(object)value != (Object)null) { return value; } PortalShape portalShape = For(prefabName); if (portalShape == null) { return null; } int num = portalShape.Radii.Length; float extent = portalShape.Extent; Vector3[] array = (Vector3[])(object)new Vector3[num]; for (int i = 0; i < num; i++) { float num2 = ((float)i + 0.5f) * 5f * ((float)Math.PI / 180f); float num3 = portalShape.Radii[i] + 0.04f; array[i] = new Vector3(Mathf.Cos(num2) * num3, Mathf.Sin(num2) * num3, 0f); } int num4 = num + 1; Vector3[] array2 = (Vector3[])(object)new Vector3[num4 * 2]; Vector2[] array3 = (Vector2[])(object)new Vector2[num4 * 2]; int[] array4 = new int[num * 3 * 2]; for (int j = 0; j < 2; j++) { float num5 = ((j == 0) ? 1f : (-1f)); int num6 = j * num4; array2[num6] = portalShape.Center; array3[num6] = new Vector2(0.5f, 0.5f); for (int k = 0; k < num; k++) { Vector3 val = array[k]; array2[num6 + 1 + k] = portalShape.Center + val; array3[num6 + 1 + k] = new Vector2(0.5f + num5 * val.x / (2f * extent), 0.5f + val.y / (2f * extent)); } for (int l = 0; l < num; l++) { int num7 = num6 + 1 + l; int num8 = num6 + 1 + (l + 1) % num; int num9 = (j * num + l) * 3; array4[num9] = num6; array4[num9 + 1] = ((j == 0) ? num8 : num7); array4[num9 + 2] = ((j == 0) ? num7 : num8); } } Mesh val2 = new Mesh { name = "pv_opening_" + prefabName, vertices = array2, uv = array3, colors32 = Enumerable.Repeat<Color32>(new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue), array2.Length).ToArray(), triangles = array4 }; val2.RecalculateNormals(); val2.RecalculateBounds(); s_meshes[prefabName] = val2; return val2; } } public static class PortalViewConfig { public static ConfigEntry<bool> Enabled; public static ConfigEntry<float> CaptureDelay; public static ConfigEntry<float> FieldOfView; public static ConfigEntry<bool> ReverseView; public static ConfigEntry<bool> PostProcessing; public static ConfigEntry<int> TextureSize; public static ConfigEntry<int> JpegQuality; public static ConfigEntry<int> MaxBytes; public static ConfigEntry<float> Brightness; public static ConfigEntry<bool> ExportPng; public static ConfigEntry<string> ExportFolder; public static void Bind(ConfigFile config) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Expected O, but got Unknown //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Expected O, but got Unknown //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Expected O, but got Unknown //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Expected O, but got Unknown Enabled = config.Bind<bool>("General", "Enabled", true, "Master switch. Turn off to disable the mod without uninstalling it."); CaptureDelay = config.Bind<float>("Capture", "CaptureDelay", 1.5f, new ConfigDescription("Seconds between placing a portal and taking its picture. Long enough for the dust of the placement to settle, which would otherwise be in it.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>())); FieldOfView = config.Bind<float>("Capture", "FieldOfView", 60f, new ConfigDescription("Vertical field of view of the picture, in degrees. Lower zooms on what lies straight ahead of the portal, higher takes in more of the landscape.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(20f, 110f), Array.Empty<object>())); ReverseView = config.Bind<bool>("Capture", "ReverseView", true, "Take the picture the other way round: from the portal towards the side you built it from, instead of through the portal and away from you. You are left out of the picture either way. Only portals placed afterwards are affected, a picture already taken stays as it is."); PostProcessing = config.Bind<bool>("Capture", "PostProcessing", true, "Give the picture the game's colour grading and bloom, like the view on screen. Turn off if pictures come out black or broken."); TextureSize = config.Bind<int>("Capture", "TextureSize", 384, new ConfigDescription("Side of the picture, in pixels. Every picture lives in the portal's world data and travels to every player who sees the linked portal.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(64, 1024), Array.Empty<object>())); JpegQuality = config.Bind<int>("Capture", "JpegQuality", 80, new ConfigDescription("JPEG quality of the picture. Lowered automatically when the result does not fit under MaxBytes.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(20, 100), Array.Empty<object>())); MaxBytes = config.Bind<int>("Capture", "MaxBytes", 40960, new ConfigDescription("Hard ceiling for one picture, in bytes.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(4096, 262144), Array.Empty<object>())); Brightness = config.Bind<float>("Appearance", "Brightness", 0.9f, new ConfigDescription("How bright the view shows in the portal. The picture ignores the light around the portal, a view of a sunny meadow stays sunny at midnight. Read when a picture is first shown, so a change needs a restart.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 1.5f), Array.Empty<object>())); ExportPng = config.Bind<bool>("Export", "ExportPng", false, "Also write each picture taken to disk as a png. Never read back by the mod."); ExportFolder = config.Bind<string>("Export", "ExportFolder", "", "Absolute path for those png files. Leave empty to write under BepInEx/config/Valheim_PortalView/<world name>."); } } [BepInPlugin("Tchernobill.Valheim_PortalView", "Valheim Portal View", "1.0.0")] public class PortalViewPlugin : BaseUnityPlugin { public const string GUID = "Tchernobill.Valheim_PortalView"; public const string NAME = "Valheim Portal View"; public const string VERSION = "1.0.0"; public static ManualLogSource Log { get; private set; } private void Awake() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; PortalViewConfig.Bind(((BaseUnityPlugin)this).Config); if (!PortalViewConfig.Enabled.Value) { Log.LogInfo((object)"Disabled by configuration, nothing is hooked."); return; } new Harmony("Tchernobill.Valheim_PortalView").PatchAll(); Log.LogInfo((object)"Valheim Portal View 1.0.0 ready."); } } [HarmonyPatch(typeof(ZNetScene), "Awake")] internal static class ZNetSceneAwakePatch { private static void Postfix(ZNetScene __instance) { foreach (string prefabName in PortalShapes.PrefabNames) { GameObject prefab = __instance.GetPrefab(prefabName); if ((Object)(object)prefab == (Object)null) { PortalViewPlugin.Log.LogWarning((object)("Prefab " + prefabName + " not found, it gets no view.")); } else if ((Object)(object)prefab.GetComponent<PortalWindow>() == (Object)null) { prefab.AddComponent<PortalWindow>(); } } } } public class PortalWindow : MonoBehaviour, IPlaced { private const float RequestRange = 40f; private const float RequestInterval = 5f; private ZNetView m_nview; private PortalShape m_shape; private string m_prefabName; private GameObject m_opening; private MeshRenderer m_renderer; private string m_shownId; private ZDOID m_shownFrom = ZDOID.None; private float m_lastRequest = -5f; private bool IsGhost { get { if (!((Object)(object)m_nview == (Object)null)) { return m_nview.GetZDO() == null; } return true; } } private void Awake() { m_nview = ((Component)this).GetComponent<ZNetView>(); m_prefabName = Utils.GetPrefabName(((Component)this).gameObject); m_shape = PortalShapes.For(m_prefabName); } private void Start() { if (IsGhost || m_shape == null) { ((Behaviour)this).enabled = false; } else { ((MonoBehaviour)this).InvokeRepeating("Refresh", Random.Range(0.2f, 1f), 1f); } } public void OnPlaced() { //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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) if (PortalViewConfig.Enabled.Value && m_shape != null) { Vector3 forward = ((Component)this).transform.forward; Vector3 val = ((Component)this).transform.TransformPoint(m_shape.Center); Vector3 val2 = (((Object)(object)GameCamera.instance != (Object)null) ? ((Component)GameCamera.instance).transform.position : (((Object)(object)Player.m_localPlayer != (Object)null) ? ((Character)Player.m_localPlayer).GetEyePoint() : (val - forward))); Vector3 val3 = ((Vector3.Dot(val - val2, forward) >= 0f) ? forward : (-forward)); if (PortalViewConfig.ReverseView.Value) { val3 = -val3; } ((MonoBehaviour)this).StartCoroutine(Capture(val3)); } } private IEnumerator Capture(Vector3 look) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return (object)new WaitForSeconds(PortalViewConfig.CaptureDelay.Value); if ((Object)(object)m_nview == (Object)null || !m_nview.IsValid()) { yield break; } int value = PortalViewConfig.TextureSize.Value; Texture2D val = PortalCamera.Render(((Component)this).transform, m_shape, look, value); if (!((Object)(object)val == (Object)null)) { Texture2D val2 = PortalCamera.Downscale(val, value); Object.Destroy((Object)(object)val); string text = PortalImages.NewId(); int usedQuality; byte[] array = PortalImages.EncodeJpeg(val2, PortalViewConfig.JpegQuality.Value, PortalViewConfig.MaxBytes.Value, out usedQuality); string text2 = (PortalViewConfig.ExportPng.Value ? PortalImages.WritePng(text, ImageConversion.EncodeToPNG(val2)) : null); Object.Destroy((Object)(object)val2); if (!m_nview.IsOwner()) { m_nview.ClaimOwnership(); } ZDO zDO = m_nview.GetZDO(); zDO.Set("pv_id", text); zDO.Set("pv_img", array); PortalViewPlugin.Log.LogInfo((object)($"Portal picture {text}: {value}px, {(float)array.Length / 1024f:0.0} KB jpeg at quality {usedQuality}" + ((text2 != null) ? (", exported to " + text2) : string.Empty))); } } private void Refresh() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) ZDO val = (((Object)(object)m_nview != (Object)null) ? m_nview.GetZDO() : null); if (val == null) { return; } ZDOID connectionZDOID = val.GetConnectionZDOID((ConnectionType)1); if (connectionZDOID == ZDOID.None) { Hide(); return; } ZDO zDO = ZDOMan.instance.GetZDO(connectionZDOID); if (zDO == null) { if (connectionZDOID != m_shownFrom) { Hide(); Request(connectionZDOID); } return; } string text = zDO.GetString("pv_id", ""); if (string.IsNullOrEmpty(text)) { Hide(); } else if (!(text == m_shownId)) { Material val2 = PortalImages.MaterialFor(text, zDO.GetByteArray("pv_img", (byte[])null)); if ((Object)(object)val2 == (Object)null) { Hide(); } else { Show(val2, text, connectionZDOID); } } } private void Request(ZDOID target) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !(Time.time - m_lastRequest < 5f) && !(Vector3.Distance(((Component)localPlayer).transform.position, ((Component)this).transform.position) > 40f)) { m_lastRequest = Time.time; ZDOMan.instance.RequestZDO(target); } } private void Show(Material material, string id, ZDOID from) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)m_opening == (Object)null) { Build(); } ((Renderer)m_renderer).sharedMaterial = material; m_opening.SetActive(true); m_shownId = id; m_shownFrom = from; } private void Hide() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)m_opening != (Object)null) { m_opening.SetActive(false); } m_shownId = null; m_shownFrom = ZDOID.None; } private void Build() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown m_opening = new GameObject("pv_opening"); m_opening.layer = 0; m_opening.transform.SetParent(((Component)this).transform, false); m_opening.AddComponent<MeshFilter>().sharedMesh = PortalShapes.MeshFor(m_prefabName); m_renderer = m_opening.AddComponent<MeshRenderer>(); ((Renderer)m_renderer).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)m_renderer).receiveShadows = false; ((Renderer)m_renderer).lightProbeUsage = (LightProbeUsage)0; ((Renderer)m_renderer).reflectionProbeUsage = (ReflectionProbeUsage)0; } } }