using 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 UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("CompassVR")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("CompassVR")] [assembly: AssemblyTitle("CompassVR")] [assembly: AssemblyVersion("1.0.0.0")] namespace CompassVR; [BepInPlugin("geekstreet.compassvr", "CompassVR", "1.0.0")] public class CompassVR : BaseUnityPlugin { public static CompassVR Instance; public static ManualLogSource Log; private Harmony harmony; public static ConfigEntry Enabled; public static ConfigEntry DebugMode; public static ConfigEntry Scale; public static ConfigEntry Distance; public static ConfigEntry PositionY; public static ConfigEntry Opacity; public static ConfigEntry MaskWidth; public static ConfigEntry MaskHeight; public static ConfigEntry CenterScale; public static ConfigEntry PinMaxDistance; public static ConfigEntry PinMinScale; public static ConfigEntry SortClosestFirst; public static ConfigEntry ShowPinDistance; public static ConfigEntry DistanceTextRange; public static ConfigEntry CompassOffset; private void Awake() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; harmony = new Harmony("compassvr"); harmony.PatchAll(); InitConfig(); Log.LogInfo((object)"[CompassVR] Loaded"); } private void InitConfig() { Enabled = ((BaseUnityPlugin)this).Config.Bind("General", "Enabled", true, "Enable CompassVR"); DebugMode = ((BaseUnityPlugin)this).Config.Bind("Debug", "Enable Debug", false, "Enable debug visuals"); Scale = ((BaseUnityPlugin)this).Config.Bind("Transform", "Scale", 0.1f, "Compass scale"); Distance = ((BaseUnityPlugin)this).Config.Bind("Transform", "Distance", 1.5f, "Distance from camera"); PositionY = ((BaseUnityPlugin)this).Config.Bind("Transform", "Vertical Offset", 0.4f, "Vertical offset"); Opacity = ((BaseUnityPlugin)this).Config.Bind("Style", "Opacity", 1f, "Compass opacity"); MaskWidth = ((BaseUnityPlugin)this).Config.Bind("Mask", "Width", 1400f, "Width of the visible compass window"); MaskHeight = ((BaseUnityPlugin)this).Config.Bind("Mask", "Height", 120f, "Height of the visible compass window"); CenterScale = ((BaseUnityPlugin)this).Config.Bind("Center", "Scale", 1f, "Scale of center icon"); PinMaxDistance = ((BaseUnityPlugin)this).Config.Bind("Pins", "Max Distance", 350f, "Maximum distance to show pins"); PinMinScale = ((BaseUnityPlugin)this).Config.Bind("Pins", "Min Scale At Max Distance", 0.25f, "Scale of pins at max distance"); SortClosestFirst = ((BaseUnityPlugin)this).Config.Bind("Pins", "Sort Closest First", true, "Sort pins by distance"); ShowPinDistance = ((BaseUnityPlugin)this).Config.Bind("Pins", "Show Distance Text", true, "Show distance text near center"); DistanceTextRange = ((BaseUnityPlugin)this).Config.Bind("Pins", "Distance Text Range", 0.15f, "How close to center before distance text appears"); CompassOffset = ((BaseUnityPlugin)this).Config.Bind("Compass", "Rotation Offset", 0.125f, "Adjust cardinal alignment"); } private void Start() { if (Enabled.Value) { CreateController(); } } private void CreateController() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown if ((Object)(object)Object.FindObjectOfType() != (Object)null) { Log.LogInfo((object)"[CompassVR] Controller already exists"); return; } GameObject val = new GameObject("VRCompassController"); val.AddComponent(); Object.DontDestroyOnLoad((Object)(object)val); Log.LogInfo((object)"[CompassVR] Controller created"); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } } public static class EmbeddedAssets { public static byte[] GetFile(string filename) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string[] manifestResourceNames = executingAssembly.GetManifestResourceNames(); Debug.Log((object)("[CompassVR] Searching embedded for: " + filename)); string[] array = manifestResourceNames; foreach (string text in array) { Debug.Log((object)("[CompassVR] Found resource: " + text)); } string text2 = manifestResourceNames.FirstOrDefault((string x) => x.ToLower().EndsWith(filename.ToLower())); if (text2 == null) { Debug.LogError((object)("[CompassVR] Embedded resource NOT FOUND: " + filename)); return null; } Debug.Log((object)("[CompassVR] Using embedded resource: " + text2)); using Stream stream = executingAssembly.GetManifestResourceStream(text2); if (stream == null) { Debug.LogError((object)("[CompassVR] Stream null for: " + text2)); return null; } byte[] array2 = new byte[stream.Length]; stream.Read(array2, 0, array2.Length); return array2; } } public class ImageLoader { private string fileName; private Texture2D texture; private Sprite sprite; private GameObject target; public ImageLoader(string name) { fileName = name + ".png"; Load(); } public static ImageLoader Get(string name) { return new ImageLoader(name); } public ImageLoader SetTarget(GameObject go) { target = go; return this; } private void Load() { //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) string text = Path.Combine(Paths.ConfigPath, "CompassVR"); string path = Path.Combine(text, fileName); if (!Directory.Exists(text)) { Directory.CreateDirectory(text); } byte[] array = null; if (File.Exists(path)) { array = File.ReadAllBytes(path); Debug.Log((object)("[CompassVR] Loaded from config: " + fileName)); } else { array = EmbeddedAssets.GetFile(fileName); if (array != null) { File.WriteAllBytes(path, array); Debug.Log((object)("[CompassVR] Extracted embedded: " + fileName)); } else { Debug.LogError((object)("[CompassVR] Missing embedded: " + fileName)); string[] manifestResourceNames = typeof(EmbeddedAssets).Assembly.GetManifestResourceNames(); string[] array2 = manifestResourceNames; foreach (string text2 in array2) { Debug.Log((object)("[CompassVR] Embedded resource found: " + text2)); } } } texture = new Texture2D(2, 2, (TextureFormat)4, false); if (array != null && array.Length != 0) { if (!ImageConversion.LoadImage(texture, array)) { Debug.LogError((object)("[CompassVR] Failed to load PNG: " + fileName)); } } else { Debug.LogWarning((object)("[CompassVR] No data for texture: " + fileName)); } ((Texture)texture).wrapMode = (TextureWrapMode)1; ((Texture)texture).filterMode = (FilterMode)0; ((Texture)texture).anisoLevel = 0; texture.Apply(false, true); sprite = Sprite.Create(texture, new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0); } public void UpdateObject() { //IL_0046: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)target == (Object)null) && !((Object)(object)sprite == (Object)null)) { RectTransform val = target.GetComponent() ?? target.AddComponent(); Rect rect = sprite.rect; float width = ((Rect)(ref rect)).width; rect = sprite.rect; val.sizeDelta = new Vector2(width, ((Rect)(ref rect)).height); Image val2 = target.GetComponent() ?? target.AddComponent(); val2.sprite = sprite; val2.preserveAspect = true; } } } public class VRCompassController : MonoBehaviour { [CompilerGenerated] private sealed class d__5 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public VRCompassController <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__5(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)Minimap.instance == (Object)null) { <>2__current = null; <>1__state = 1; return true; } <>4__this.FindCamera(); <>4__this.CreateUI(); <>4__this.initialized = true; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private Canvas vrCanvas; private Camera vrCamera; private Transform cameraTransform; private bool initialized = false; private void Start() { ((MonoBehaviour)this).StartCoroutine(InitWhenReady()); } [IteratorStateMachine(typeof(d__5))] private IEnumerator InitWhenReady() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__5(0) { <>4__this = this }; } private void Update() { if (initialized && !((Object)(object)vrCanvas == (Object)null) && !((Object)(object)cameraTransform == (Object)null)) { UpdateTransform(); UpdateOpacity(); VRCompassUI.UpdateRotation(cameraTransform); } } private void FindCamera() { vrCamera = Camera.main; if ((Object)(object)vrCamera == (Object)null) { Camera[] array = Object.FindObjectsByType((FindObjectsSortMode)0); foreach (Camera val in array) { if (((Behaviour)val).isActiveAndEnabled) { vrCamera = val; break; } } } cameraTransform = ((Component)vrCamera).transform; } private void CreateUI() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("VRCompassCanvas"); vrCanvas = val.AddComponent(); vrCanvas.renderMode = (RenderMode)2; vrCanvas.worldCamera = vrCamera; val.AddComponent(); val.AddComponent(); val.transform.SetParent(cameraTransform, false); RectTransform component = val.GetComponent(); component.sizeDelta = new Vector2(800f, 150f); VRCompassUI.Create(val.transform); } private void UpdateTransform() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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_009e: Unknown result type (might be due to invalid IL or missing references) ((Component)vrCanvas).transform.localPosition = new Vector3(0f, CompassVR.PositionY.Value, CompassVR.Distance.Value); ((Component)vrCanvas).transform.localRotation = Quaternion.identity; Vector3 forward = cameraTransform.forward; forward.y = 0f; ((Component)vrCanvas).transform.rotation = Quaternion.LookRotation(forward, Vector3.up); ((Component)vrCanvas).transform.localScale = Vector3.one * CompassVR.Scale.Value * 0.01f; } private void UpdateOpacity() { //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_004b: Unknown result type (might be due to invalid IL or missing references) float value = CompassVR.Opacity.Value; Graphic[] componentsInChildren = ((Component)vrCanvas).GetComponentsInChildren(true); Graphic[] array = componentsInChildren; foreach (Graphic val in array) { if (Object.op_Implicit((Object)(object)val)) { Color color = val.color; color.a = value; val.color = color; } } } } public static class VRCompassPins { private class PinInstance { public RectTransform rect; public Image image; public Text text; } private static RectTransform root; private static FieldInfo pinsField; private static readonly List pool = new List(); private static int index = 0; private static readonly Material sharedMaterial = new Material(Shader.Find("UI/Default")); public static void Initialize(RectTransform parent) { root = parent; pinsField = typeof(Minimap).GetField("m_pins", BindingFlags.Instance | BindingFlags.NonPublic); } public static void UpdatePins(Transform head, float compassWidth) { //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Minimap.instance == (Object)null || pinsField == null || !(pinsField.GetValue(Minimap.instance) is List list)) { return; } index = 0; float value = CompassVR.PinMaxDistance.Value; float value2 = CompassVR.PinMinScale.Value; float num = compassWidth * 0.5f; for (int i = 0; i < list.Count; i++) { PinData val = list[i]; if (val == null || (Object)(object)val.m_icon == (Object)null) { continue; } float num2 = val.m_pos.x - head.position.x; float num3 = val.m_pos.z - head.position.z; float num4 = Mathf.Sqrt(num2 * num2 + num3 * num3); if (num4 > value) { continue; } PinInstance pinInstance = Get(); float angle = GetAngle(head, val.m_pos); float num5 = num * angle / (MathF.PI * 2f); float num6 = num4 / value; float num7 = Mathf.Lerp(1f, value2, num6); float num8 = 40f * num7; pinInstance.rect.sizeDelta = new Vector2(num8, num8); pinInstance.rect.anchoredPosition = new Vector2(num5, 0f); pinInstance.image.sprite = val.m_icon; ((Graphic)pinInstance.image).color = (val.m_checked ? Color.gray : Color.white); if (CompassVR.ShowPinDistance.Value) { float num9 = Mathf.Abs(num5) / num; if (num9 < CompassVR.DistanceTextRange.Value) { ((Component)pinInstance.text).gameObject.SetActive(true); pinInstance.text.text = (int)num4 + "m"; } else { ((Component)pinInstance.text).gameObject.SetActive(false); } } else { ((Component)pinInstance.text).gameObject.SetActive(false); } ((Component)pinInstance.rect).gameObject.SetActive(true); } for (int j = index; j < pool.Count; j++) { ((Component)pool[j].rect).gameObject.SetActive(false); } } private static PinInstance Get() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0069: 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_0092: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) PinInstance pinInstance; if (index < pool.Count) { pinInstance = pool[index]; } else { GameObject val = new GameObject("Pin"); val.transform.SetParent((Transform)(object)root, false); RectTransform rect = val.AddComponent(); Image val2 = val.AddComponent(); ((Graphic)val2).material = sharedMaterial; ((Graphic)val2).color = Color.white; val2.preserveAspect = true; val2.useSpriteMesh = false; GameObject val3 = new GameObject("Distance"); val3.transform.SetParent(val.transform, false); RectTransform val4 = val3.AddComponent(); val4.anchoredPosition = new Vector2(0f, -18f); Text val5 = val3.AddComponent(); val5.alignment = (TextAnchor)4; val5.fontSize = 14; ((Graphic)val5).color = Color.white; val5.font = Resources.GetBuiltinResource("Arial.ttf"); Outline val6 = val3.AddComponent(); ((Shadow)val6).effectColor = Color.black; ((Shadow)val6).effectDistance = new Vector2(1f, -1f); pinInstance = new PinInstance { rect = rect, image = val2, text = val5 }; pool.Add(pinInstance); } index++; return pinInstance; } private static float GetAngle(Transform head, Vector3 pos) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) float num = pos.x - head.position.x; float num2 = pos.z - head.position.z; Vector3 val = head.InverseTransformDirection(new Vector3(num, 0f, num2)); return Mathf.Atan2(val.x, val.z); } } public static class VRCompassUI { public static Transform Root; private static RectTransform compassTransform; private static RectTransform maskRect; private static RectTransform centerRect; private static float compassWidth; public static void Create(Transform parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_0066: 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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Expected O, but got Unknown //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Expected O, but got Unknown //IL_01a9: 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_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Expected O, but got Unknown //IL_020b: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("VRCompassUI"); val.transform.SetParent(parent, false); Root = val.transform; GameObject val2 = new GameObject("Mask"); val2.transform.SetParent(Root, false); maskRect = val2.AddComponent(); maskRect.sizeDelta = new Vector2(CompassVR.MaskWidth.Value, CompassVR.MaskHeight.Value); Image val3 = val2.AddComponent(); ((Graphic)val3).color = Color.white; Mask val4 = val2.AddComponent(); val4.showMaskGraphic = false; GameObject val5 = new GameObject("Compass"); val5.transform.SetParent(val2.transform, false); compassTransform = val5.AddComponent(); Image val6 = val5.AddComponent(); ((Graphic)val6).material = new Material(Shader.Find("UI/Default")); ((Graphic)val6).color = Color.white; ImageLoader.Get("compass").SetTarget(val5).UpdateObject(); if ((Object)(object)val6.sprite != (Object)null) { Rect rect = val6.sprite.rect; compassWidth = ((Rect)(ref rect)).width; } else { compassWidth = 2048f; } compassTransform.sizeDelta = new Vector2(compassWidth, CompassVR.MaskHeight.Value); GameObject val7 = new GameObject("Center"); val7.transform.SetParent(val2.transform, false); centerRect = val7.AddComponent(); Image val8 = val7.AddComponent(); ((Graphic)val8).material = new Material(Shader.Find("UI/Default")); ((Graphic)val8).color = Color.white; ImageLoader.Get("center").SetTarget(val7).UpdateObject(); centerRect.anchoredPosition = Vector2.zero; GameObject val9 = new GameObject("Pins"); val9.transform.SetParent(val2.transform, false); RectTransform val10 = val9.AddComponent(); val10.sizeDelta = maskRect.sizeDelta; VRCompassPins.Initialize(val10); } public static void UpdateRotation(Transform head) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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 (!((Object)(object)compassTransform == (Object)null) && !((Object)(object)head == (Object)null)) { if ((Object)(object)maskRect != (Object)null) { maskRect.sizeDelta = new Vector2(CompassVR.MaskWidth.Value, CompassVR.MaskHeight.Value); } float num = head.eulerAngles.y; if (num > 180f) { num -= 360f; } num *= -MathF.PI / 180f; float num2 = compassWidth / 2f * num / (MathF.PI * 2f) - compassWidth * CompassVR.CompassOffset.Value; compassTransform.anchoredPosition = new Vector2(num2, 0f); if ((Object)(object)centerRect != (Object)null) { ((Transform)centerRect).localScale = Vector3.one * CompassVR.CenterScale.Value; } VRCompassPins.UpdatePins(head, compassWidth); } } }