using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using FistVR; using HarmonyLib; using OtherLoader; using UnityEngine; [assembly: Debuggable(DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] namespace JerryAr.PC { [BepInPlugin("JerryAr.PC", "PC", "1.0.0")] [BepInProcess("h3vr.exe")] [Description("Built with MeatKit")] [BepInDependency("h3vr.otherloader", "1.3.0")] public class PCPlugin : BaseUnityPlugin { private static readonly string BasePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); internal static ManualLogSource Logger; private void Awake() { Logger = ((BaseUnityPlugin)this).Logger; LoadAssets(); } private void LoadAssets() { Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "JerryAr.PC"); OtherLoader.RegisterDirectLoad(BasePath, "JerryAr.PC", "", "", "pc_set", ""); } } } namespace JerryPC { [RequireComponent(typeof(Renderer))] public class DesktopCursorOverlay : MonoBehaviour { [SerializeField] private DesktopMirrorDisplay mirrorDisplay; [SerializeField] private int monitorIndex = 0; [SerializeField] private int maxCaptureWidth = 1280; [SerializeField] private int maxCaptureHeight = 720; [SerializeField] private float targetFrameRate = 60f; [SerializeField] private bool startOnAwake = true; [SerializeField] private bool syncTransformWithMirror = true; [SerializeField] private Shader cursorShader; private WindowsCursorCapture capture; private Material runtimeMaterial; private Renderer targetRenderer; private Coroutine captureRoutine; public Texture CursorTexture { get { if (capture == null) { return null; } return (Texture)(object)capture.Texture; } } private void Awake() { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown targetRenderer = ((Component)this).GetComponent(); if ((Object)(object)cursorShader == (Object)null) { cursorShader = Shader.Find("DesktopMirror/CursorOverlay"); if ((Object)(object)cursorShader == (Object)null) { cursorShader = Shader.Find("Transparent/Diffuse"); } } runtimeMaterial = new Material(cursorShader); runtimeMaterial.mainTexture = null; targetRenderer.material = runtimeMaterial; } private void Start() { if (startOnAwake) { StartOverlay(); } } private void LateUpdate() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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) if (syncTransformWithMirror && !((Object)(object)mirrorDisplay == (Object)null)) { Transform transform = ((Component)mirrorDisplay).transform; ((Component)this).transform.localPosition = transform.localPosition; ((Component)this).transform.localRotation = transform.localRotation; Vector3 localPosition = ((Component)this).transform.localPosition; localPosition.z -= 0.001f; ((Component)this).transform.localPosition = localPosition; } } private void OnDestroy() { StopOverlay(); } private void OnApplicationQuit() { StopOverlay(); } public void StartOverlay() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Invalid comparison between Unknown and I4 if (captureRoutine != null) { return; } if ((int)Application.platform != 2 && (int)Application.platform != 7) { Debug.LogWarning((object)"DesktopCursorOverlay requires a Windows build or the Windows Editor."); return; } ApplyMirrorSettings(); try { capture = new WindowsCursorCapture(monitorIndex, maxCaptureWidth, maxCaptureHeight); captureRoutine = ((MonoBehaviour)this).StartCoroutine(CaptureLoop()); } catch (Exception ex) { Debug.LogError((object)("DesktopCursorOverlay failed to start: " + ex.Message)); StopOverlay(); } } public void StopOverlay() { if (captureRoutine != null) { ((MonoBehaviour)this).StopCoroutine(captureRoutine); captureRoutine = null; } if (capture != null) { capture.Dispose(); capture = null; } if ((Object)(object)runtimeMaterial != (Object)null) { runtimeMaterial.mainTexture = null; } } private void ApplyMirrorSettings() { if (!((Object)(object)mirrorDisplay == (Object)null)) { monitorIndex = mirrorDisplay.GetMonitorIndex(); mirrorDisplay.GetCaptureSize(out maxCaptureWidth, out maxCaptureHeight); } } private IEnumerator CaptureLoop() { float interval = ((!(targetFrameRate > 0f)) ? 0f : (1f / targetFrameRate)); WaitForSeconds wait = ((!(interval > 0f)) ? ((WaitForSeconds)null) : new WaitForSeconds(interval)); while (capture != null) { if (capture.CaptureFrame()) { runtimeMaterial.mainTexture = (Texture)(object)capture.Texture; } if (wait != null) { yield return wait; } else { yield return null; } } } public void AssignMirrorDisplay(DesktopMirrorDisplay display) { mirrorDisplay = display; } } public class IgnoreCol : MonoBehaviour { public List col; private void Start() { for (int i = 0; i < col.Count; i++) { for (int j = 0; j < col.Count; j++) { Physics.IgnoreCollision(col[j], col[i]); } } } } internal static class MonitorLayoutUtility { internal static WindowsNative.RECT GetMonitorRect(int index) { List monitors = new List(); WindowsNative.MonitorEnumProc lpfnEnum = delegate(IntPtr hMonitor, IntPtr hdcMonitor, ref WindowsNative.RECT lprcMonitor, IntPtr dwData) { monitors.Add(lprcMonitor); return true; }; if (!WindowsNative.EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, lpfnEnum, IntPtr.Zero)) { throw new InvalidOperationException("EnumDisplayMonitors failed."); } if (monitors.Count == 0) { throw new InvalidOperationException("No monitors were found."); } if (index < 0 || index >= monitors.Count) { throw new ArgumentOutOfRangeException("monitorIndex", "Monitor index is out of range."); } return monitors[index]; } internal static int ScaleToMax(int sourceSize, int maxSize) { if (maxSize <= 0 || sourceSize <= maxSize) { return sourceSize; } return maxSize; } } public class PCKeyBoard : MonoBehaviour { public struct KeyboardInput { public ushort wVk; public ushort wScan; public uint dwFlags; public uint time; public IntPtr dwExtraInfo; } [StructLayout(LayoutKind.Explicit)] public struct InputUnion { [FieldOffset(0)] public KeyboardInput ki; } public struct Input { public int type; public InputUnion u; } [Flags] public enum InputType { Mouse = 0, Keyboard = 1, Hardware = 2 } [Flags] public enum KeyEventF { KeyDown = 0, ExtendedKey = 1, KeyUp = 2, Unicode = 4, Scancode = 8 } public Rigidbody rig; public GameObject PC_Core; public FVRPhysicalObject obj; public bool ispressingPhy; public KeyCode key; private const int KEYEVENTF_KEYDOWN = 0; private const int KEYEVENTF_KEYUP = 2; public AudioEvent keypress; public AudioEvent keyup; public float PressThreshoud; public bool pressing; public float cd = 1f; public bool presscontinue = false; [DllImport("user32.dll")] public static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo); [DllImport("user32.dll", SetLastError = true)] private static extern uint SendInput(uint nInputs, Input[] pInputs, int cbSize); [DllImport("user32.dll")] private static extern IntPtr GetMessageExtraInfo(); private void Start() { rig = ((Component)this).GetComponent(); } private void OnTriggerStay(Collider other) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)other == (Object)(object)GM.CurrentMovementManager.Hands[0].Collider_Fingers || (Object)(object)other == (Object)(object)GM.CurrentMovementManager.Hands[1].Collider_Fingers) { rig.AddRelativeForce(new Vector3(0f, 0.105f, 0f), (ForceMode)1); } } private void Update() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) rig.AddRelativeForce(new Vector3(0f, -0.1f, 0f), (ForceMode)1); if (((Component)this).gameObject.transform.localPosition.y >= PressThreshoud && !ispressingPhy) { SM.PlayCoreSound((FVRPooledAudioType)41, keypress, ((Component)this).transform.position); ispressingPhy = true; } if (((Component)this).gameObject.transform.localPosition.y < PressThreshoud && ispressingPhy) { SM.PlayCoreSound((FVRPooledAudioType)41, keyup, ((Component)this).transform.position); ispressingPhy = false; } } private void FixedUpdate() { //IL_00d6: 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_0092: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)PC_Core == (Object)null) { PC_Core = GameObject.Find("YES_Potato"); } if (!((FVRInteractiveObject)obj).m_isHeld && (Object)(object)PC_Core != (Object)null) { if (ispressingPhy) { if (!pressing) { KeyDown(key); pressing = true; } } else if (!ispressingPhy && pressing) { KeyUp(key); pressing = false; } } if ((((FVRInteractiveObject)obj).m_isHeld || (Object)(object)PC_Core == (Object)null) && pressing) { KeyUp(key); pressing = false; } } public static void KeyPress(KeyCode key) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) byte bVk = (byte)KeyCodeToVK(key); keybd_event(bVk, 0, 0, 0); keybd_event(bVk, 0, 2, 0); } public void KeyDown(KeyCode key) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (!presscontinue) { UnityKeyCodeWindowsOutput.Press(key); presscontinue = true; } if (presscontinue) { cd -= Time.deltaTime; if (cd < 0f) { cd = 0f; UnityKeyCodeWindowsOutput.Press(key); } } } private static int KeyCodeToVK(KeyCode kc) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Expected I4, but got Unknown return (int)kc; } public void KeyUp(KeyCode key) { presscontinue = false; cd = 1f; } } public class PCMonitor : MonoBehaviour { public AR15HandleSightFlipper trig; public GameObject PC_Core; public DesktopMirrorDisplay screen; public DesktopCursorOverlay cursor; public GameObject screenGeo; public bool switched; public bool captured; private void FixedUpdate() { if ((Object)(object)PC_Core != (Object)null) { if (!captured) { screen.StartCapture(); cursor.StartOverlay(); captured = true; } screenGeo.SetActive(true); if (trig.m_isLargeAperture) { if (!switched) { screen.StartCapture(); cursor.StartOverlay(); screen.SetMonitorIndex(0); switched = true; } } else if (!trig.m_isLargeAperture && switched) { screen.StartCapture(); cursor.StartOverlay(); screen.SetMonitorIndex(1); switched = false; } } if ((Object)(object)PC_Core == (Object)null) { captured = false; screenGeo.SetActive(false); PC_Core = GameObject.Find("YES_Potato"); } } } public class PCMouse : MonoBehaviour { public FVRPhysicalObject obj; public GameObject PC_Core; [Header("射线检测")] [Tooltip("射线向下检测的距离(从鼠标底部开始)")] public float rayDistance = 0.5f; [Tooltip("射线检测的层级掩码(哪些层被认为是平面)")] public LayerMask planeLayerMask = LayerMask.op_Implicit(-1); [Header("位置贴合")] [Tooltip("鼠标模型底部相对于物体中心点的局部偏移。例如鼠标模型中心在几何中心,底部向下偏移量为负Y值)")] public Vector3 bottomLocalOffset = new Vector3(0f, -0.1f, 0f); [Tooltip("是否自动将鼠标位置贴合到平面上")] public bool snapToPlane = true; [Header("光标控制")] [Tooltip("光标移动的灵敏度(屏幕像素 / 世界单位)")] public float sensitivity = 500f; public float Speed = 0.1f; [Tooltip("是否反转X轴")] public bool invertX = false; [Tooltip("是否反转Y轴")] public bool invertY = false; [Tooltip("是否实时更新系统光标位置")] public bool updateSystemCursor = true; private Vector3 lastWorldPosition; public Transform rayp; private bool isOnPlane = false; private Vector3 planeNormal; private Vector3 planePoint; public AudioEvent click; public bool leftc; public bool rightc; public bool middlec; public Vector3 velLinearWorldL; public Vector3 velLinearWorldR; public Transform slapdir; private const uint MOUSEEVENTF_LEFTDOWN = 2u; private const uint MOUSEEVENTF_LEFTUP = 4u; private const uint MOUSEEVENTF_RIGHTDOWN = 8u; private const uint MOUSEEVENTF_RIGHTUP = 16u; private const uint MOUSEEVENTF_MIDDLEDOWN = 32u; private const uint MOUSEEVENTF_MIDDLEUP = 64u; private const uint MOUSEEVENTF_WHEEL = 2048u; private const uint MOUSEEVENTF_HWHEEL = 4096u; public GameObject localpos; public GameObject worldpos; public GameObject localposH; public WindowsCursorController cursorC; [DllImport("user32.dll")] public static extern bool SetCursorPos(int X, int Y); [DllImport("user32.dll")] private static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, UIntPtr dwExtraInfo); public static void LeftClick() { mouse_event(2u, 0u, 0u, 0u, UIntPtr.Zero); mouse_event(4u, 0u, 0u, 0u, UIntPtr.Zero); } public static void LeftDown() { mouse_event(2u, 0u, 0u, 0u, UIntPtr.Zero); } public static void LeftUp() { mouse_event(4u, 0u, 0u, 0u, UIntPtr.Zero); } public static void RightClick() { mouse_event(8u, 0u, 0u, 0u, UIntPtr.Zero); mouse_event(16u, 0u, 0u, 0u, UIntPtr.Zero); } public static void RightDown() { mouse_event(8u, 0u, 0u, 0u, UIntPtr.Zero); } public static void RightUp() { mouse_event(16u, 0u, 0u, 0u, UIntPtr.Zero); } public static void MiddleClick() { mouse_event(32u, 0u, 0u, 0u, UIntPtr.Zero); mouse_event(64u, 0u, 0u, 0u, UIntPtr.Zero); } public static void MiddleDown() { mouse_event(32u, 0u, 0u, 0u, UIntPtr.Zero); } public static void MiddleUp() { mouse_event(64u, 0u, 0u, 0u, UIntPtr.Zero); } public static void ScrollWheel(int delta) { mouse_event(2048u, 0u, 0u, (uint)delta, UIntPtr.Zero); } public static void HorizontalScroll(int delta) { mouse_event(4096u, 0u, 0u, (uint)delta, UIntPtr.Zero); } private void Start() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) worldpos.transform.SetParent((Transform)null); lastWorldPosition = ((Component)this).transform.position; } private void FixedUpdate() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_04ed: Unknown result type (might be due to invalid IL or missing references) //IL_0524: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_055b: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_058a: Unknown result type (might be due to invalid IL or missing references) //IL_059a: 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_0197: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0607: Unknown result type (might be due to invalid IL or missing references) //IL_0617: Unknown result type (might be due to invalid IL or missing references) //IL_05af: 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_0409: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0684: Unknown result type (might be due to invalid IL or missing references) //IL_0694: Unknown result type (might be due to invalid IL or missing references) //IL_062c: Unknown result type (might be due to invalid IL or missing references) //IL_0637: Unknown result type (might be due to invalid IL or missing references) //IL_0485: Unknown result type (might be due to invalid IL or missing references) //IL_070d: Unknown result type (might be due to invalid IL or missing references) //IL_071d: Unknown result type (might be due to invalid IL or missing references) //IL_06a9: Unknown result type (might be due to invalid IL or missing references) //IL_06b4: Unknown result type (might be due to invalid IL or missing references) //IL_06be: Unknown result type (might be due to invalid IL or missing references) //IL_0732: Unknown result type (might be due to invalid IL or missing references) //IL_073d: Unknown result type (might be due to invalid IL or missing references) //IL_0747: Unknown result type (might be due to invalid IL or missing references) velLinearWorldL = GM.CurrentMovementManager.Hands[0].Input.VelLinearWorld; if (((FVRInteractiveObject)obj).m_isHeld) { if (((FVRInteractiveObject)obj).m_hand.Input.TriggerFloat > 0.5f) { if (((FVRInteractiveObject)obj).m_hand.IsInStreamlinedMode) { if (((FVRInteractiveObject)obj).m_hand.Input.BYButtonPressed && !rightc) { rightc = true; SM.PlayCoreSound((FVRPooledAudioType)41, click, ((Component)this).gameObject.transform.position); if ((Object)(object)PC_Core != (Object)null) { RightDown(); } } if (!((FVRInteractiveObject)obj).m_hand.Input.BYButtonPressed && !leftc) { leftc = true; SM.PlayCoreSound((FVRPooledAudioType)41, click, ((Component)this).gameObject.transform.position); if ((Object)(object)PC_Core != (Object)null) { LeftDown(); } } } else if (!((FVRInteractiveObject)obj).m_hand.IsInStreamlinedMode) { if (((FVRInteractiveObject)obj).m_hand.Input.Secondary2AxisInputAxes.y > 0.5f && !rightc) { rightc = true; SM.PlayCoreSound((FVRPooledAudioType)41, click, ((Component)this).gameObject.transform.position); if ((Object)(object)PC_Core != (Object)null) { RightDown(); } } if (((FVRInteractiveObject)obj).m_hand.Input.Secondary2AxisInputAxes.y <= 0.5f && !leftc) { leftc = true; SM.PlayCoreSound((FVRPooledAudioType)41, click, ((Component)this).gameObject.transform.position); if ((Object)(object)PC_Core != (Object)null) { LeftDown(); } } } } else if (((FVRInteractiveObject)obj).m_hand.Input.TriggerFloat <= 0.5f) { if (leftc) { SM.PlayCoreSound((FVRPooledAudioType)41, click, ((Component)this).gameObject.transform.position); LeftUp(); leftc = false; } if (rightc) { SM.PlayCoreSound((FVRPooledAudioType)41, click, ((Component)this).gameObject.transform.position); RightUp(); rightc = false; } } if (((FVRInteractiveObject)obj).m_hand.IsInStreamlinedMode) { if (((FVRInteractiveObject)obj).m_hand.Input.AXButtonPressed) { if (!middlec) { SM.PlayCoreSound((FVRPooledAudioType)41, click, ((Component)this).gameObject.transform.position); middlec = true; if ((Object)(object)PC_Core != (Object)null) { MiddleDown(); } } } else if (!((FVRInteractiveObject)obj).m_hand.Input.AXButtonPressed && middlec) { middlec = false; SM.PlayCoreSound((FVRPooledAudioType)41, click, ((Component)this).gameObject.transform.position); if ((Object)(object)PC_Core != (Object)null) { MiddleUp(); } } } else if (((FVRInteractiveObject)obj).m_hand.IsInStreamlinedMode) { if (((FVRInteractiveObject)obj).m_hand.Input.Secondary2AxisInputAxes.y < -0.5f) { if (!middlec) { SM.PlayCoreSound((FVRPooledAudioType)41, click, ((Component)this).gameObject.transform.position); middlec = true; if ((Object)(object)PC_Core != (Object)null) { MiddleDown(); } } } else if (((FVRInteractiveObject)obj).m_hand.Input.Secondary2AxisInputAxes.y >= -0.5f && middlec) { middlec = false; SM.PlayCoreSound((FVRPooledAudioType)41, click, ((Component)this).gameObject.transform.position); if ((Object)(object)PC_Core != (Object)null) { MiddleUp(); } } } } else if (!((FVRInteractiveObject)obj).m_isHeld) { if (leftc) { leftc = false; LeftUp(); SM.PlayCoreSound((FVRPooledAudioType)41, click, ((Component)this).gameObject.transform.position); } if (rightc) { rightc = false; RightUp(); SM.PlayCoreSound((FVRPooledAudioType)41, click, ((Component)this).gameObject.transform.position); } if (middlec) { middlec = false; MiddleUp(); SM.PlayCoreSound((FVRPooledAudioType)41, click, ((Component)this).gameObject.transform.position); } if ((Object)(object)PC_Core != (Object)null) { if (Vector3.Distance(GM.CurrentMovementManager.Hands[0].PointingTransform.position, ((FVRInteractiveObject)obj).PoseOverride.position) < 0.15f && Vector3.Angle(velLinearWorldL, slapdir.forward) < 45f && ((Vector3)(ref velLinearWorldL)).magnitude > 1f) { ScrollWheel((int)((Vector3)(ref velLinearWorldL)).magnitude); } if (Vector3.Distance(GM.CurrentMovementManager.Hands[1].PointingTransform.position, ((FVRInteractiveObject)obj).PoseOverride.position) < 0.15f && Vector3.Angle(velLinearWorldR, slapdir.forward) < 45f && ((Vector3)(ref velLinearWorldR)).magnitude > 1f) { ScrollWheel((int)((Vector3)(ref velLinearWorldR)).magnitude); } if (Vector3.Distance(GM.CurrentMovementManager.Hands[0].PointingTransform.position, ((FVRInteractiveObject)obj).PoseOverride.position) < 0.15f && Vector3.Angle(velLinearWorldL, slapdir.forward * -1f) < 45f && ((Vector3)(ref velLinearWorldL)).magnitude > 1f) { ScrollWheel(-1 * (int)((Vector3)(ref velLinearWorldL)).magnitude); } if (Vector3.Distance(GM.CurrentMovementManager.Hands[1].PointingTransform.position, ((FVRInteractiveObject)obj).PoseOverride.position) < 0.15f && Vector3.Angle(velLinearWorldR, slapdir.forward * -1f) < 45f && ((Vector3)(ref velLinearWorldR)).magnitude > 1f) { ScrollWheel(-1 * (int)((Vector3)(ref velLinearWorldR)).magnitude); } } } if ((Object)(object)PC_Core == (Object)null) { PC_Core = GameObject.Find("YES_Potato"); } } private void Update() { //IL_0009: 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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_019c: 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) Ray val = default(Ray); ((Ray)(ref val))..ctor(rayp.position, -((Component)this).transform.up); RaycastHit val2 = default(RaycastHit); isOnPlane = Physics.Raycast(val, ref val2, rayDistance, LayerMask.op_Implicit(planeLayerMask)); if (!isOnPlane) { worldpos.transform.position = localposH.transform.position; worldpos.transform.rotation = localposH.transform.rotation; localpos.transform.localPosition = new Vector3(0f, 0f, 0f); cursorC.X = 0f; cursorC.Y = 0f; } if (isOnPlane) { worldpos.transform.position = Vector3.Lerp(worldpos.transform.position, localposH.transform.position, Time.deltaTime * Speed); worldpos.transform.rotation = localposH.transform.rotation; localpos.transform.position = worldpos.transform.position; cursorC.X = (0f - localpos.transform.localPosition.x) * sensitivity; cursorC.Y = localpos.transform.localPosition.z * sensitivity; } } private void AlignToPlaneNormal() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (isOnPlane) { Vector3 val = planeNormal; Vector3 val2 = ((Component)this).transform.forward; if (Mathf.Abs(Vector3.Dot(val2, val)) > 0.9999f) { val2 = ((Component)this).transform.right; } Quaternion rotation = Quaternion.LookRotation(val2, val); ((Component)this).transform.rotation = rotation; } } public void MoveSystemCursorTo(int screenX, int screenY) { screenX = Mathf.Clamp(screenX, 0, Screen.width); screenY = Mathf.Clamp(screenY, 0, Screen.height); SetCursorPos(screenX, screenY); } public Vector2 ConvertUnityScreenCoordToSystemCoord(Vector2 unityScreenPos) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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) float x = unityScreenPos.x; float num = (float)Screen.height - unityScreenPos.y; return new Vector2(x, num); } } public static class PhysicalKeySimulator { public static bool SimulatePhysicalKeyPress(PhysicalScanCode scanCode) { return WindowsSystemKeyOutput.SendPhysicalKeyPress(scanCode); } public static bool SimulatePhysicalKeyPressToSystem(PhysicalScanCode scanCode, SystemKeyDeliveryMode deliveryMode, IntPtr targetWindow, bool restoreUnityFocus) { return WindowsSystemKeyOutput.SendPhysicalKeyPress(scanCode, deliveryMode, targetWindow, restoreUnityFocus); } public static bool SimulatePhysicalKeyPress(ushort scanCode, bool isExtendedKey) { if (!SendScanCode(scanCode, isExtendedKey, keyDown: true)) { return false; } return SendScanCode(scanCode, isExtendedKey, keyDown: false); } public static bool SimulatePhysicalKeyDown(PhysicalScanCode scanCode) { return SimulatePhysicalKeyDown((ushort)scanCode, IsExtendedScanCode(scanCode)); } public static bool SimulatePhysicalKeyDown(ushort scanCode, bool isExtendedKey) { return SendScanCode(scanCode, isExtendedKey, keyDown: true); } public static bool SimulatePhysicalKeyUp(PhysicalScanCode scanCode) { return SimulatePhysicalKeyUp((ushort)scanCode, IsExtendedScanCode(scanCode)); } public static bool SimulatePhysicalKeyUp(ushort scanCode, bool isExtendedKey) { return SendScanCode(scanCode, isExtendedKey, keyDown: false); } public static bool SimulateUnityKeyPress(KeyCode keyCode) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (!TryGetScanCodeFromUnityKeyCode(keyCode, out var scanCode, out var isExtended)) { Debug.LogWarning((object)("PhysicalKeySimulator: unsupported KeyCode " + keyCode)); return false; } return SimulatePhysicalKeyPress(scanCode, isExtended); } public static bool SimulateWindowsVirtualKeyPress(ushort virtualKey) { if (!TryGetScanCodeFromVirtualKey(virtualKey, out var scanCode, out var isExtended)) { Debug.LogWarning((object)("PhysicalKeySimulator: unsupported virtual key 0x" + virtualKey.ToString("X2"))); return false; } return SimulatePhysicalKeyPress(scanCode, isExtended); } public static bool TryGetScanCodeFromUnityKeyCode(KeyCode keyCode, out ushort scanCode, out bool isExtended) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) scanCode = 0; isExtended = false; if (!TryConvertUnityKeyCodeToVirtualKey(keyCode, out var virtualKey)) { return false; } return TryGetScanCodeFromVirtualKey(virtualKey, out scanCode, out isExtended); } public static bool TryGetScanCodeFromVirtualKey(ushort virtualKey, out ushort scanCode, out bool isExtended) { scanCode = 0; isExtended = IsExtendedVirtualKey(virtualKey); uint num = WindowsInputNative.MapVirtualKey(virtualKey, 0u); if (num == 0) { return false; } scanCode = (ushort)num; return true; } public static bool IsExtendedScanCodePublic(PhysicalScanCode scanCode) { return IsExtendedScanCode(scanCode); } private static bool SendScanCode(ushort scanCode, bool isExtendedKey, bool keyDown) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 if ((int)Application.platform != 2 && (int)Application.platform != 7) { Debug.LogWarning((object)"PhysicalKeySimulator only works on Windows."); return false; } return WindowsInputNative.SendKeyboardScanCode(scanCode, isExtendedKey, keyDown); } private static bool TryConvertUnityKeyCodeToVirtualKey(KeyCode keyCode, out ushort virtualKey) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected I4, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Expected I4, but got Unknown //IL_0121: 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_0172: Expected I4, but got Unknown //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Expected I4, but got Unknown //IL_0192: 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_01b3: Expected I4, but got Unknown //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Invalid comparison between Unknown and I4 //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Invalid comparison between Unknown and I4 //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Invalid comparison between Unknown and I4 //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Invalid comparison between Unknown and I4 //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Invalid comparison between Unknown and I4 virtualKey = 0; int num = (int)keyCode; if (num >= 97 && num <= 122) { virtualKey = (ushort)(num - 32); return true; } if (num >= 32 && num <= 126) { virtualKey = (ushort)num; return true; } switch (keyCode - 256) { default: switch (keyCode - 44) { case 4: virtualKey = 48; return true; case 5: virtualKey = 49; return true; case 6: virtualKey = 50; return true; case 7: virtualKey = 51; return true; case 8: virtualKey = 52; return true; case 9: virtualKey = 53; return true; case 10: virtualKey = 54; return true; case 11: virtualKey = 55; return true; case 12: virtualKey = 56; return true; case 13: virtualKey = 57; return true; case 15: virtualKey = 186; return true; case 17: virtualKey = 187; return true; case 0: virtualKey = 188; return true; case 1: virtualKey = 189; return true; case 2: virtualKey = 190; return true; case 3: virtualKey = 191; return true; } switch (keyCode - 8) { default: switch (keyCode - 91) { default: if ((int)keyCode != 19) { if ((int)keyCode != 27) { if ((int)keyCode != 32) { if ((int)keyCode != 39) { if ((int)keyCode == 127) { virtualKey = 46; return true; } return false; } virtualKey = 222; return true; } virtualKey = 32; return true; } virtualKey = 27; return true; } virtualKey = 19; return true; case 5: virtualKey = 192; return true; case 0: virtualKey = 219; return true; case 1: virtualKey = 220; return true; case 2: virtualKey = 221; return true; } case 0: virtualKey = 8; return true; case 1: virtualKey = 9; return true; case 4: virtualKey = 12; return true; case 5: break; } goto case 15; case 15: virtualKey = 13; return true; case 24: virtualKey = 33; return true; case 25: virtualKey = 34; return true; case 23: virtualKey = 35; return true; case 22: virtualKey = 36; return true; case 20: virtualKey = 37; return true; case 17: virtualKey = 38; return true; case 19: virtualKey = 39; return true; case 18: virtualKey = 40; return true; case 21: virtualKey = 45; return true; case 0: virtualKey = 96; return true; case 1: virtualKey = 97; return true; case 2: virtualKey = 98; return true; case 3: virtualKey = 99; return true; case 4: virtualKey = 100; return true; case 5: virtualKey = 101; return true; case 6: virtualKey = 102; return true; case 7: virtualKey = 103; return true; case 8: virtualKey = 104; return true; case 9: virtualKey = 105; return true; case 10: virtualKey = 110; return true; case 11: virtualKey = 111; return true; case 12: virtualKey = 106; return true; case 13: virtualKey = 109; return true; case 14: virtualKey = 107; return true; case 48: virtualKey = 160; return true; case 47: virtualKey = 161; return true; case 50: virtualKey = 162; return true; case 49: virtualKey = 163; return true; case 52: virtualKey = 164; return true; case 51: virtualKey = 165; return true; case 26: virtualKey = 112; return true; case 27: virtualKey = 113; return true; case 28: virtualKey = 114; return true; case 29: virtualKey = 115; return true; case 30: virtualKey = 116; return true; case 31: virtualKey = 117; return true; case 32: virtualKey = 118; return true; case 33: virtualKey = 119; return true; case 34: virtualKey = 120; return true; case 35: virtualKey = 121; return true; case 36: virtualKey = 122; return true; case 37: virtualKey = 123; return true; } } private static bool IsExtendedVirtualKey(ushort virtualKey) { switch (virtualKey) { case 33: case 34: case 35: case 36: case 37: case 38: case 39: case 40: case 45: case 46: case 111: case 163: case 165: return true; default: return false; } } private static bool IsExtendedScanCode(PhysicalScanCode scanCode) { switch (scanCode) { case PhysicalScanCode.Enter: case PhysicalScanCode.LeftControl: case PhysicalScanCode.Slash: case PhysicalScanCode.NumpadMultiply: case PhysicalScanCode.LeftAlt: case PhysicalScanCode.Numpad7: case PhysicalScanCode.Numpad8: case PhysicalScanCode.Numpad9: case PhysicalScanCode.Numpad4: case PhysicalScanCode.Numpad6: case PhysicalScanCode.Numpad1: case PhysicalScanCode.Numpad2: case PhysicalScanCode.Numpad3: case PhysicalScanCode.Numpad0: case PhysicalScanCode.NumpadDecimal: case PhysicalScanCode.LeftWindows: case PhysicalScanCode.RightWindows: case PhysicalScanCode.Menu: return true; default: return false; } } } public enum PhysicalScanCode : ushort { Escape = 1, Digit1 = 2, Digit2 = 3, Digit3 = 4, Digit4 = 5, Digit5 = 6, Digit6 = 7, Digit7 = 8, Digit8 = 9, Digit9 = 10, Digit0 = 11, Minus = 12, Equals = 13, Backspace = 14, Tab = 15, Q = 16, W = 17, E = 18, R = 19, T = 20, Y = 21, U = 22, I = 23, O = 24, P = 25, LeftBracket = 26, RightBracket = 27, Enter = 28, LeftControl = 29, A = 30, S = 31, D = 32, F = 33, G = 34, H = 35, J = 36, K = 37, L = 38, Semicolon = 39, Apostrophe = 40, Grave = 41, LeftShift = 42, Backslash = 43, Z = 44, X = 45, C = 46, V = 47, B = 48, N = 49, M = 50, Comma = 51, Period = 52, Slash = 53, RightShift = 54, NumpadMultiply = 55, LeftAlt = 56, Space = 57, CapsLock = 58, F1 = 59, F2 = 60, F3 = 61, F4 = 62, F5 = 63, F6 = 64, F7 = 65, F8 = 66, F9 = 67, F10 = 68, NumLock = 69, ScrollLock = 70, Numpad7 = 71, Numpad8 = 72, Numpad9 = 73, NumpadMinus = 74, Numpad4 = 75, Numpad5 = 76, Numpad6 = 77, NumpadPlus = 78, Numpad1 = 79, Numpad2 = 80, Numpad3 = 81, Numpad0 = 82, NumpadDecimal = 83, F11 = 87, F12 = 88, NumpadEnter = 28, RightControl = 29, NumpadDivide = 53, PrintScreen = 55, RightAlt = 56, Home = 71, ArrowUp = 72, PageUp = 73, ArrowLeft = 75, ArrowRight = 77, End = 79, ArrowDown = 80, PageDown = 81, Insert = 82, Delete = 83, LeftWindows = 91, RightWindows = 92, Menu = 93 } [RequireComponent(typeof(Renderer))] public class DesktopMirrorDisplay : MonoBehaviour { [SerializeField] private int monitorIndex = 0; [SerializeField] private int maxCaptureWidth = 1280; [SerializeField] private int maxCaptureHeight = 720; [SerializeField] private float targetFrameRate = 30f; [SerializeField] private bool startOnAwake = true; [SerializeField] private bool flipVertical = false; [SerializeField] private Shader mirrorShader; private WindowsDesktopCapture capture; private Material runtimeMaterial; private Renderer targetRenderer; private Coroutine captureRoutine; public Texture DesktopTexture { get { if (capture == null) { return null; } return (Texture)(object)capture.Texture; } } private void Awake() { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown targetRenderer = ((Component)this).GetComponent(); if ((Object)(object)mirrorShader == (Object)null) { mirrorShader = Shader.Find("DesktopMirror/Unlit"); if ((Object)(object)mirrorShader == (Object)null) { mirrorShader = Shader.Find("Unlit/Texture"); } } runtimeMaterial = new Material(mirrorShader); runtimeMaterial.mainTexture = null; targetRenderer.material = runtimeMaterial; } private void Start() { if (startOnAwake) { StartCapture(); } } private void OnDestroy() { StopCapture(); } private void OnApplicationQuit() { StopCapture(); } public void StartCapture() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Invalid comparison between Unknown and I4 if (captureRoutine != null) { return; } if ((int)Application.platform != 2 && (int)Application.platform != 7) { Debug.LogWarning((object)"DesktopMirrorDisplay requires a Windows build or the Windows Editor."); return; } try { capture = new WindowsDesktopCapture(monitorIndex, maxCaptureWidth, maxCaptureHeight); FitMeshAspect(capture.Width, capture.Height); captureRoutine = ((MonoBehaviour)this).StartCoroutine(CaptureLoop()); } catch (Exception ex) { Debug.LogError((object)("DesktopMirrorDisplay failed to start: " + ex.Message)); StopCapture(); } } public void StopCapture() { if (captureRoutine != null) { ((MonoBehaviour)this).StopCoroutine(captureRoutine); captureRoutine = null; } if (capture != null) { capture.Dispose(); capture = null; } if ((Object)(object)runtimeMaterial != (Object)null) { runtimeMaterial.mainTexture = null; } } private IEnumerator CaptureLoop() { float interval = ((!(targetFrameRate > 0f)) ? 0f : (1f / targetFrameRate)); WaitForSeconds wait = ((!(interval > 0f)) ? ((WaitForSeconds)null) : new WaitForSeconds(interval)); while (capture != null) { if (capture.CaptureFrame()) { runtimeMaterial.mainTexture = (Texture)(object)capture.Texture; } if (wait != null) { yield return wait; } else { yield return null; } } } private void FitMeshAspect(int textureWidth, int textureHeight) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) if (textureWidth > 0 && textureHeight > 0) { float num = (float)textureWidth / (float)textureHeight; Vector3 localScale = ((Component)this).transform.localScale; if (num >= 1f) { localScale.x = num; localScale.y = 1f; } else { localScale.x = 1f; localScale.y = 1f / num; } if (flipVertical) { Vector3 localEulerAngles = ((Component)this).transform.localEulerAngles; localEulerAngles.x = 180f; ((Component)this).transform.localEulerAngles = localEulerAngles; } } } public void SetMonitorIndex(int index) { monitorIndex = index; StopCapture(); StartCapture(); } public int GetMonitorIndex() { return monitorIndex; } public void GetCaptureSize(out int width, out int height) { width = maxCaptureWidth; height = maxCaptureHeight; } } public static class DesktopMirrorMenu { private static void CreateQuadDisplay() { GameObject val = GameObject.CreatePrimitive((PrimitiveType)5); ((Object)val).name = "DesktopMirror"; Object.DestroyImmediate((Object)(object)val.GetComponent()); val.AddComponent(); } } public class WindowsDesktopCapture : IDisposable { private readonly int monitorIndex; private readonly int captureWidth; private readonly int captureHeight; private IntPtr screenDc; private IntPtr memoryDc; private IntPtr bitmap; private IntPtr oldBitmap; private byte[] pixelBuffer; private WindowsNative.RECT monitorRect; public Texture2D Texture { get; private set; } public int Width => captureWidth; public int Height => captureHeight; public WindowsDesktopCapture(int monitorIndex, int maxWidth, int maxHeight) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 if ((int)Application.platform != 2 && (int)Application.platform != 7) { throw new PlatformNotSupportedException("WindowsDesktopCapture only works on Windows."); } this.monitorIndex = monitorIndex; monitorRect = GetMonitorRect(monitorIndex); captureWidth = ScaleToMax(monitorRect.Width, maxWidth); captureHeight = ScaleToMax(monitorRect.Height, maxHeight); CreateGpuTexture(); CreateGdiResources(); } private static int ScaleToMax(int sourceSize, int maxSize) { if (maxSize <= 0 || sourceSize <= maxSize) { return sourceSize; } return maxSize; } private static WindowsNative.RECT GetMonitorRect(int index) { List monitors = new List(); WindowsNative.MonitorEnumProc lpfnEnum = delegate(IntPtr hMonitor, IntPtr hdcMonitor, ref WindowsNative.RECT lprcMonitor, IntPtr dwData) { monitors.Add(lprcMonitor); return true; }; if (!WindowsNative.EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, lpfnEnum, IntPtr.Zero)) { throw new InvalidOperationException("EnumDisplayMonitors failed."); } if (monitors.Count == 0) { throw new InvalidOperationException("No monitors were found."); } if (index < 0 || index >= monitors.Count) { throw new ArgumentOutOfRangeException("monitorIndex", "Monitor index is out of range."); } return monitors[index]; } private void CreateGpuTexture() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown Texture = new Texture2D(captureWidth, captureHeight, (TextureFormat)14, false); ((Texture)Texture).wrapMode = (TextureWrapMode)1; ((Texture)Texture).filterMode = (FilterMode)1; pixelBuffer = new byte[captureWidth * captureHeight * 4]; } private void CreateGdiResources() { screenDc = WindowsNative.GetDC(IntPtr.Zero); if (screenDc == IntPtr.Zero) { throw new InvalidOperationException("GetDC failed."); } memoryDc = WindowsNative.CreateCompatibleDC(screenDc); if (memoryDc == IntPtr.Zero) { throw new InvalidOperationException("CreateCompatibleDC failed."); } bitmap = WindowsNative.CreateCompatibleBitmap(screenDc, monitorRect.Width, monitorRect.Height); if (bitmap == IntPtr.Zero) { throw new InvalidOperationException("CreateCompatibleBitmap failed."); } oldBitmap = WindowsNative.SelectObject(memoryDc, bitmap); } public bool CaptureFrame() { if (screenDc == IntPtr.Zero || memoryDc == IntPtr.Zero || bitmap == IntPtr.Zero) { return false; } if (!WindowsNative.BitBlt(memoryDc, 0, 0, monitorRect.Width, monitorRect.Height, screenDc, monitorRect.Left, monitorRect.Top, 13369376)) { return false; } WindowsNative.BITMAPINFO lpbi = default(WindowsNative.BITMAPINFO); lpbi.bmiHeader.biSize = MarshalSizeOf(typeof(WindowsNative.BITMAPINFOHEADER)); lpbi.bmiHeader.biWidth = monitorRect.Width; lpbi.bmiHeader.biHeight = -monitorRect.Height; lpbi.bmiHeader.biPlanes = 1; lpbi.bmiHeader.biBitCount = 32; lpbi.bmiHeader.biCompression = 0; byte[] array = new byte[monitorRect.Width * monitorRect.Height * 4]; if (WindowsNative.GetDIBits(memoryDc, bitmap, 0u, (uint)monitorRect.Height, array, ref lpbi, 0u) == 0) { return false; } CopyAndDownscale(array, monitorRect.Width, monitorRect.Height); Texture.LoadRawTextureData(pixelBuffer); Texture.Apply(false, false); return true; } private void CopyAndDownscale(byte[] source, int sourceWidth, int sourceHeight) { if (sourceWidth == captureWidth && sourceHeight == captureHeight) { Buffer.BlockCopy(source, 0, pixelBuffer, 0, pixelBuffer.Length); return; } float num = (float)sourceWidth / (float)captureWidth; float num2 = (float)sourceHeight / (float)captureHeight; int num3 = sourceWidth * 4; int num4 = captureWidth * 4; for (int i = 0; i < captureHeight; i++) { int num5 = Mathf.Min(sourceHeight - 1, (int)((float)i * num2)); int num6 = num5 * num3; int num7 = i * num4; for (int j = 0; j < captureWidth; j++) { int num8 = Mathf.Min(sourceWidth - 1, (int)((float)j * num)); int num9 = num6 + num8 * 4; int num10 = num7 + j * 4; pixelBuffer[num10] = source[num9]; pixelBuffer[num10 + 1] = source[num9 + 1]; pixelBuffer[num10 + 2] = source[num9 + 2]; pixelBuffer[num10 + 3] = source[num9 + 3]; } } } private static int MarshalSizeOf(Type type) { return Marshal.SizeOf(type); } public void Dispose() { if (memoryDc != IntPtr.Zero && oldBitmap != IntPtr.Zero) { WindowsNative.SelectObject(memoryDc, oldBitmap); oldBitmap = IntPtr.Zero; } if (bitmap != IntPtr.Zero) { WindowsNative.DeleteObject(bitmap); bitmap = IntPtr.Zero; } if (memoryDc != IntPtr.Zero) { WindowsNative.DeleteDC(memoryDc); memoryDc = IntPtr.Zero; } if (screenDc != IntPtr.Zero) { WindowsNative.ReleaseDC(IntPtr.Zero, screenDc); screenDc = IntPtr.Zero; } if ((Object)(object)Texture != (Object)null) { Object.Destroy((Object)(object)Texture); Texture = null; } } } internal static class WindowsNative { internal struct POINT { public int X; public int Y; } internal struct CURSORINFO { public int cbSize; public int flags; public IntPtr hCursor; public POINT ptScreenPos; } internal struct ICONINFO { [MarshalAs(UnmanagedType.Bool)] public bool fIcon; public int xHotspot; public int yHotspot; public IntPtr hbmMask; public IntPtr hbmColor; } internal struct RECT { public int Left; public int Top; public int Right; public int Bottom; public int Width => Right - Left; public int Height => Bottom - Top; } internal struct BITMAPINFOHEADER { public int biSize; public int biWidth; public int biHeight; public short biPlanes; public short biBitCount; public int biCompression; public int biSizeImage; public int biXPelsPerMeter; public int biYPelsPerMeter; public int biClrUsed; public int biClrImportant; } internal struct BITMAPINFO { public BITMAPINFOHEADER bmiHeader; } internal delegate bool MonitorEnumProc(IntPtr hMonitor, IntPtr hdcMonitor, ref RECT lprcMonitor, IntPtr dwData); internal const int SRCCOPY = 13369376; internal const int DIB_RGB_COLORS = 0; internal const int BI_RGB = 0; internal const int CURSOR_SHOWING = 1; internal const int DI_NORMAL = 3; [DllImport("user32.dll")] internal static extern IntPtr GetDesktopWindow(); [DllImport("user32.dll")] internal static extern IntPtr GetDC(IntPtr hWnd); [DllImport("user32.dll")] internal static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC); [DllImport("user32.dll")] internal static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip, MonitorEnumProc lpfnEnum, IntPtr dwData); [DllImport("gdi32.dll")] internal static extern bool BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, int dwRop); [DllImport("gdi32.dll")] internal static extern IntPtr CreateCompatibleDC(IntPtr hdc); [DllImport("gdi32.dll")] internal static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight); [DllImport("gdi32.dll")] internal static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj); [DllImport("gdi32.dll")] internal static extern bool DeleteDC(IntPtr hdc); [DllImport("gdi32.dll")] internal static extern bool DeleteObject(IntPtr hObject); [DllImport("gdi32.dll")] internal static extern int GetDIBits(IntPtr hdc, IntPtr hbmp, uint uStartScan, uint cScanLines, byte[] lpvBits, ref BITMAPINFO lpbi, uint uUsage); [DllImport("gdi32.dll")] internal static extern IntPtr CreateDIBSection(IntPtr hdc, ref BITMAPINFO pbmi, uint usage, out IntPtr ppvBits, IntPtr hSection, uint offset); [DllImport("user32.dll")] internal static extern bool GetCursorPos(out POINT lpPoint); [DllImport("user32.dll")] internal static extern bool SetCursorPos(int x, int y); [DllImport("user32.dll")] internal static extern IntPtr GetActiveWindow(); [DllImport("user32.dll")] internal static extern bool ClientToScreen(IntPtr hWnd, ref POINT lpPoint); [DllImport("user32.dll")] internal static extern bool GetCursorInfo(ref CURSORINFO pci); [DllImport("user32.dll")] internal static extern bool GetIconInfo(IntPtr hIcon, out ICONINFO piconinfo); [DllImport("user32.dll")] internal static extern bool DrawIconEx(IntPtr hdc, int xLeft, int yTop, IntPtr hIcon, int cxWidth, int cyWidth, uint istepIfAniCur, IntPtr hbrFlickerFreeDraw, uint diFlags); } } public class SnapToPoint : MonoBehaviour { public GameObject Obj; public GameObject Targ; private void Start() { } private void Update() { //IL_0017: 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) Obj.transform.position = Targ.transform.position; Obj.transform.rotation = Targ.transform.rotation; } } namespace JerryPC { public class SystemKeyboardOutputBridge : MonoBehaviour { [SerializeField] private bool sendOnStartTestKey = false; [SerializeField] private PhysicalScanCode testScanCode = PhysicalScanCode.W; [SerializeField] private SystemKeyDeliveryMode deliveryMode = SystemKeyDeliveryMode.DirectToWindow; [SerializeField] private string targetProcessName = "notepad"; [SerializeField] private string targetWindowTitle = string.Empty; [SerializeField] private bool restoreUnityFocus = true; [SerializeField] private float focusDelaySeconds = 0.05f; private IntPtr cachedTargetWindow; private void Start() { RefreshTargetWindow(); if (sendOnStartTestKey) { SendTestKey(); } } public void RefreshTargetWindow() { cachedTargetWindow = IntPtr.Zero; if (!string.IsNullOrEmpty(targetWindowTitle)) { cachedTargetWindow = WindowsSystemKeyOutput.FindWindowByTitle(targetWindowTitle); } if (cachedTargetWindow == IntPtr.Zero && !string.IsNullOrEmpty(targetProcessName)) { cachedTargetWindow = WindowsSystemKeyOutput.FindMainWindowForProcess(targetProcessName); } } public void SendTestKey() { SendPhysicalKey(testScanCode); } public void SendPhysicalKey(PhysicalScanCode scanCode) { if (deliveryMode == SystemKeyDeliveryMode.DirectToWindow || deliveryMode == SystemKeyDeliveryMode.FocusTargetThenSendInput) { if (cachedTargetWindow == IntPtr.Zero) { RefreshTargetWindow(); } if (cachedTargetWindow == IntPtr.Zero) { Debug.LogWarning((object)"SystemKeyboardOutputBridge: no target window configured."); return; } } if (deliveryMode == SystemKeyDeliveryMode.FocusTargetThenSendInput && focusDelaySeconds > 0f) { WindowsSystemKeyOutput.TryFocusWindow(cachedTargetWindow); } WindowsSystemKeyOutput.SendPhysicalKeyPress(scanCode, deliveryMode, cachedTargetWindow, restoreUnityFocus); } public void SendPhysicalKeyToForeground(PhysicalScanCode scanCode) { WindowsSystemKeyOutput.SendPhysicalKeyPress(scanCode, SystemKeyDeliveryMode.ForegroundWindow, IntPtr.Zero, restoreUnityFocus: false); } public void SendPhysicalKeyToTarget(PhysicalScanCode scanCode) { RefreshTargetWindow(); WindowsSystemKeyOutput.SendPhysicalKeyPress(scanCode, SystemKeyDeliveryMode.DirectToWindow, cachedTargetWindow, restoreUnityFocus); } public void SendPhysicalKeyDownToTarget(PhysicalScanCode scanCode) { SendPhysicalKeyStateToTarget(scanCode, keyDown: true); } public void SendPhysicalKeyUpToTarget(PhysicalScanCode scanCode) { SendPhysicalKeyStateToTarget(scanCode, keyDown: false); } private void SendPhysicalKeyStateToTarget(PhysicalScanCode scanCode, bool keyDown) { RefreshTargetWindow(); if (cachedTargetWindow == IntPtr.Zero) { Debug.LogWarning((object)"SystemKeyboardOutputBridge: no target window configured."); return; } ushort scanCode2 = (ushort)scanCode; bool isExtended = PhysicalKeySimulator.IsExtendedScanCodePublic(scanCode); if (TryScanCodeToVirtualKey(scanCode2, isExtended, out var virtualKey)) { uint msg = ((!keyDown) ? 257u : 256u); IntPtr lParam = BuildKeyLParam(scanCode2, isExtended, !keyDown); WindowsInputNative.PostMessage(cachedTargetWindow, msg, new IntPtr(virtualKey), lParam); } } private static bool TryScanCodeToVirtualKey(ushort scanCode, bool isExtended, out ushort virtualKey) { virtualKey = 0; uint num = WindowsInputNative.MapVirtualKey(scanCode, 1u); if (num == 0) { return false; } virtualKey = (ushort)num; return true; } private static IntPtr BuildKeyLParam(ushort scanCode, bool isExtended, bool keyUp) { int num = 1; num |= scanCode << 16; if (isExtended) { num |= 0x1000000; } if (keyUp) { num |= 0x40000000; num |= int.MinValue; } return new IntPtr(num); } } public static class UnityKeyCodeWindowsOutput { public static bool Press(KeyCode keyCode) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return WindowsSystemKeyOutput.SendKeyCodePress(keyCode); } public static bool Press(KeyCode keyCode, SystemKeyDeliveryMode deliveryMode, string targetProcessName, bool restoreUnityFocus) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(targetProcessName)) { return WindowsSystemKeyOutput.SendKeyCodePress(keyCode, deliveryMode, IntPtr.Zero, restoreUnityFocus); } return WindowsSystemKeyOutput.SendKeyCodePressToProcess(keyCode, targetProcessName, deliveryMode, restoreUnityFocus); } public static bool KeyDown(KeyCode keyCode) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return WindowsSystemKeyOutput.SendKeyCodeDown(keyCode); } public static bool KeyUp(KeyCode keyCode) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return WindowsSystemKeyOutput.SendKeyCodeUp(keyCode); } public static bool PressChord(params KeyCode[] keys) { if (keys == null || keys.Length == 0) { return false; } for (int i = 0; i < keys.Length - 1; i++) { if (!KeyDown(keys[i])) { return false; } } if (!Press(keys[^1])) { return false; } for (int num = keys.Length - 2; num >= 0; num--) { if (!KeyUp(keys[num])) { return false; } } return true; } } public class UnityKeyCodeWindowsSender : MonoBehaviour { [SerializeField] private KeyCode keyCode = (KeyCode)32; [SerializeField] private SystemKeyDeliveryMode deliveryMode = SystemKeyDeliveryMode.ForegroundWindow; [SerializeField] private string targetProcessName = string.Empty; [SerializeField] private bool restoreUnityFocus = true; [SerializeField] private bool sendOnStart = false; public KeyCode KeyCode { get { //IL_0002: 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_000d: Unknown result type (might be due to invalid IL or missing references) return keyCode; } set { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) keyCode = value; } } private void Start() { if (sendOnStart) { SendPress(); } } public void SendPress() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) UnityKeyCodeWindowsOutput.Press(keyCode, deliveryMode, targetProcessName, restoreUnityFocus); } public void SendKeyDown() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) UnityKeyCodeWindowsOutput.KeyDown(keyCode); } public void SendKeyUp() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) UnityKeyCodeWindowsOutput.KeyUp(keyCode); } public void SendPress(KeyCode code) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) keyCode = code; SendPress(); } } public class WindowsCursorCapture : IDisposable { private const int CursorDrawSize = 128; private readonly int captureWidth; private readonly int captureHeight; private readonly WindowsNative.RECT monitorRect; private IntPtr screenDc; private IntPtr overlayDc; private IntPtr overlayBitmap; private IntPtr overlayBits; private IntPtr cursorDc; private IntPtr cursorBitmap; private IntPtr cursorBits; private byte[] overlayPixels; private byte[] cursorPixels; public Texture2D Texture { get; private set; } public int Width => captureWidth; public int Height => captureHeight; public WindowsCursorCapture(int monitorIndex, int maxWidth, int maxHeight) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 if ((int)Application.platform != 2 && (int)Application.platform != 7) { throw new PlatformNotSupportedException("WindowsCursorCapture only works on Windows."); } monitorRect = MonitorLayoutUtility.GetMonitorRect(monitorIndex); captureWidth = MonitorLayoutUtility.ScaleToMax(monitorRect.Width, maxWidth); captureHeight = MonitorLayoutUtility.ScaleToMax(monitorRect.Height, maxHeight); overlayPixels = new byte[captureWidth * captureHeight * 4]; cursorPixels = new byte[65536]; CreateGpuTexture(); CreateGdiResources(); } private void CreateGpuTexture() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown Texture = new Texture2D(captureWidth, captureHeight, (TextureFormat)14, false); ((Texture)Texture).wrapMode = (TextureWrapMode)1; ((Texture)Texture).filterMode = (FilterMode)1; } private void CreateGdiResources() { screenDc = WindowsNative.GetDC(IntPtr.Zero); if (screenDc == IntPtr.Zero) { throw new InvalidOperationException("GetDC failed."); } overlayDc = WindowsNative.CreateCompatibleDC(screenDc); cursorDc = WindowsNative.CreateCompatibleDC(screenDc); if (overlayDc == IntPtr.Zero || cursorDc == IntPtr.Zero) { throw new InvalidOperationException("CreateCompatibleDC failed."); } overlayBitmap = CreateAlphaBitmap(overlayDc, captureWidth, captureHeight, out overlayBits); cursorBitmap = CreateAlphaBitmap(cursorDc, 128, 128, out cursorBits); } private static IntPtr CreateAlphaBitmap(IntPtr dc, int width, int height, out IntPtr bits) { WindowsNative.BITMAPINFO pbmi = default(WindowsNative.BITMAPINFO); pbmi.bmiHeader.biSize = MarshalSizeOf(typeof(WindowsNative.BITMAPINFOHEADER)); pbmi.bmiHeader.biWidth = width; pbmi.bmiHeader.biHeight = -height; pbmi.bmiHeader.biPlanes = 1; pbmi.bmiHeader.biBitCount = 32; pbmi.bmiHeader.biCompression = 0; IntPtr intPtr = WindowsNative.CreateDIBSection(dc, ref pbmi, 0u, out bits, IntPtr.Zero, 0u); if (intPtr == IntPtr.Zero) { throw new InvalidOperationException("CreateDIBSection failed."); } WindowsNative.SelectObject(dc, intPtr); ClearBits(bits, width * height * 4); return intPtr; } private static void ClearBits(IntPtr bits, int byteCount) { if (bits == IntPtr.Zero) { return; } int[] array = new int[256]; int num = byteCount; IntPtr destination = bits; while (num > 0) { int num2 = num; if (num2 > array.Length * 4) { num2 = array.Length * 4; } Marshal.Copy(array, 0, destination, num2 / 4); destination = new IntPtr(destination.ToInt64() + num2); num -= num2; } } public bool CaptureFrame() { ClearPixelBuffer(); if (!WindowsNative.GetCursorPos(out var lpPoint)) { UploadTexture(); return false; } if (!IsPointOnMonitor(lpPoint)) { UploadTexture(); return true; } WindowsNative.CURSORINFO pci = default(WindowsNative.CURSORINFO); pci.cbSize = MarshalSizeOf(typeof(WindowsNative.CURSORINFO)); if (!WindowsNative.GetCursorInfo(ref pci)) { UploadTexture(); return false; } if ((pci.flags & 1) == 0) { UploadTexture(); return true; } if (!WindowsNative.GetIconInfo(pci.hCursor, out var piconinfo)) { UploadTexture(); return false; } try { DrawCursorToOverlay(lpPoint, pci.hCursor, piconinfo); } finally { ReleaseIconInfo(piconinfo); } UploadTexture(); return true; } private void DrawCursorToOverlay(WindowsNative.POINT cursorPoint, IntPtr cursorHandle, WindowsNative.ICONINFO iconInfo) { ClearBits(cursorBits, cursorPixels.Length); WindowsNative.DrawIconEx(cursorDc, 0, 0, cursorHandle, 0, 0, 0u, IntPtr.Zero, 3u); Marshal.Copy(cursorBits, cursorPixels, 0, cursorPixels.Length); int x = cursorPoint.X; WindowsNative.RECT rECT = monitorRect; int num = x - rECT.Left; int y = cursorPoint.Y; WindowsNative.RECT rECT2 = monitorRect; int num2 = y - rECT2.Top; int drawX = ScaleToTexture(num - iconInfo.xHotspot, monitorRect.Width, captureWidth); int drawY = ScaleToTexture(num2 - iconInfo.yHotspot, monitorRect.Height, captureHeight); CompositeCursorPixels(drawX, drawY); } private static int ScaleToTexture(int monitorValue, int monitorSize, int textureSize) { if (monitorSize <= 0) { return 0; } return (int)((long)monitorValue * (long)textureSize / monitorSize); } private void CompositeCursorPixels(int drawX, int drawY) { int num = captureWidth * 4; int num2 = 512; for (int i = 0; i < 128; i++) { int num3 = drawY + i; if (num3 < 0 || num3 >= captureHeight) { continue; } int num4 = i * num2; int num5 = num3 * num; for (int j = 0; j < 128; j++) { int num6 = drawX + j; if (num6 >= 0 && num6 < captureWidth) { int num7 = num4 + j * 4; byte b = cursorPixels[num7 + 3]; if (b == 0) { b = GetCursorAlphaFromRgb(cursorPixels, num7); } if (b != 0) { int destIndex = num5 + num6 * 4; BlendPixel(destIndex, num7, b); } } } } } private static byte GetCursorAlphaFromRgb(byte[] pixels, int index) { byte b = pixels[index]; byte b2 = pixels[index + 1]; byte b3 = pixels[index + 2]; if (b3 > 0 || b2 > 0 || b > 0) { return byte.MaxValue; } return 0; } private void BlendPixel(int destIndex, int srcIndex, byte alpha) { float num = (float)(int)alpha / 255f; float num2 = 1f - num; overlayPixels[destIndex] = (byte)((float)(int)cursorPixels[srcIndex] * num + (float)(int)overlayPixels[destIndex] * num2); overlayPixels[destIndex + 1] = (byte)((float)(int)cursorPixels[srcIndex + 1] * num + (float)(int)overlayPixels[destIndex + 1] * num2); overlayPixels[destIndex + 2] = (byte)((float)(int)cursorPixels[srcIndex + 2] * num + (float)(int)overlayPixels[destIndex + 2] * num2); overlayPixels[destIndex + 3] = (byte)((float)(int)alpha + (float)(int)overlayPixels[destIndex + 3] * num2); } private bool IsPointOnMonitor(WindowsNative.POINT point) { int x = point.X; WindowsNative.RECT rECT = monitorRect; int result; if (x >= rECT.Left) { int x2 = point.X; WindowsNative.RECT rECT2 = monitorRect; if (x2 < rECT2.Right) { int y = point.Y; WindowsNative.RECT rECT3 = monitorRect; if (y >= rECT3.Top) { int y2 = point.Y; WindowsNative.RECT rECT4 = monitorRect; result = ((y2 < rECT4.Bottom) ? 1 : 0); goto IL_0069; } } } result = 0; goto IL_0069; IL_0069: return (byte)result != 0; } private void ClearPixelBuffer() { for (int i = 0; i < overlayPixels.Length; i++) { overlayPixels[i] = 0; } } private void UploadTexture() { Texture.LoadRawTextureData(overlayPixels); Texture.Apply(false, false); } private static void ReleaseIconInfo(WindowsNative.ICONINFO iconInfo) { if (iconInfo.hbmColor != IntPtr.Zero) { WindowsNative.DeleteObject(iconInfo.hbmColor); } if (iconInfo.hbmMask != IntPtr.Zero) { WindowsNative.DeleteObject(iconInfo.hbmMask); } } private static int MarshalSizeOf(Type type) { return Marshal.SizeOf(type); } public void Dispose() { if (overlayBitmap != IntPtr.Zero) { WindowsNative.DeleteObject(overlayBitmap); overlayBitmap = IntPtr.Zero; } if (cursorBitmap != IntPtr.Zero) { WindowsNative.DeleteObject(cursorBitmap); cursorBitmap = IntPtr.Zero; } if (overlayDc != IntPtr.Zero) { WindowsNative.DeleteDC(overlayDc); overlayDc = IntPtr.Zero; } if (cursorDc != IntPtr.Zero) { WindowsNative.DeleteDC(cursorDc); cursorDc = IntPtr.Zero; } if (screenDc != IntPtr.Zero) { WindowsNative.ReleaseDC(IntPtr.Zero, screenDc); screenDc = IntPtr.Zero; } if ((Object)(object)Texture != (Object)null) { Object.Destroy((Object)(object)Texture); Texture = null; } } } public enum WindowsCursorControlMode { Relative, Absolute } public class WindowsCursorController : MonoBehaviour { [SerializeField] private float x = 0f; [SerializeField] private float y = 0f; [SerializeField] private WindowsCursorControlMode controlMode = WindowsCursorControlMode.Relative; [SerializeField] private bool activeOnStart = true; private bool isActive; public float X { get { return x; } set { x = value; } } public float Y { get { return y; } set { y = value; } } private void Start() { isActive = activeOnStart; } private void Update() { if (isActive) { ApplyMovement(); } } public void ApplyMovement() { if (controlMode == WindowsCursorControlMode.Absolute) { WindowsCursorDriver.SetPosition(Mathf.RoundToInt(x), Mathf.RoundToInt(y)); } else { WindowsCursorDriver.MoveBy(x, y); } } public void SetActive(bool value) { isActive = value; } public void SetDelta(float newX, float newY) { x = newX; y = newY; } public void SetAbsolutePosition(float screenX, float screenY) { controlMode = WindowsCursorControlMode.Absolute; x = screenX; y = screenY; WindowsCursorDriver.SetPosition(Mathf.RoundToInt(x), Mathf.RoundToInt(y)); } } public static class WindowsCursorDriver { public static bool TryGetPosition(out int x, out int y) { x = 0; y = 0; if (!IsWindows()) { Debug.Log((object)"NotWindows"); return false; } if (!WindowsNative.GetCursorPos(out var lpPoint)) { Debug.Log((object)"Failed getting Windows cursor pos"); return false; } x = lpPoint.X; y = lpPoint.Y; return true; } public static bool SetPosition(int x, int y) { if (!IsWindows()) { return false; } return WindowsNative.SetCursorPos(x, y); } public static bool MoveBy(float deltaX, float deltaY) { if (!TryGetPosition(out var x, out var y)) { Debug.Log((object)"Failed getting cursor pos"); return false; } int x2 = x + Mathf.RoundToInt(deltaX); int y2 = y + Mathf.RoundToInt(deltaY); return SetPosition(x2, y2); } private static bool IsWindows() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 return (int)Application.platform == 2 || (int)Application.platform == 7; } } internal static class WindowsInputNative { [StructLayout(LayoutKind.Explicit, Size = 40)] internal struct INPUT { [FieldOffset(0)] public uint type; [FieldOffset(8)] public KEYBDINPUT ki; } internal struct KEYBDINPUT { public ushort wVk; public ushort wScan; public uint dwFlags; public uint time; public IntPtr dwExtraInfo; } internal const uint INPUT_KEYBOARD = 1u; internal const uint KEYEVENTF_EXTENDEDKEY = 1u; internal const uint KEYEVENTF_KEYUP = 2u; internal const uint KEYEVENTF_SCANCODE = 8u; internal const uint MAPVK_VK_TO_VSC = 0u; internal const uint MAPVK_VSC_TO_VK = 1u; internal const int SW_SHOW = 5; internal const uint WM_KEYDOWN = 256u; internal const uint WM_KEYUP = 257u; internal const uint WM_SYSKEYDOWN = 260u; internal const uint WM_SYSKEYUP = 261u; internal const int InputStructureSize = 40; [DllImport("user32.dll", SetLastError = true)] internal static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize); [DllImport("user32.dll")] internal static extern uint MapVirtualKey(uint uCode, uint uMapType); [DllImport("user32.dll")] internal static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] internal static extern bool SetForegroundWindow(IntPtr hWnd); [DllImport("user32.dll")] internal static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); [DllImport("user32.dll")] internal static extern bool IsWindow(IntPtr hWnd); [DllImport("user32.dll")] internal static extern bool IsIconic(IntPtr hWnd); [DllImport("user32.dll")] internal static extern bool AllowSetForegroundWindow(int dwProcessId); [DllImport("user32.dll")] internal static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); [DllImport("user32.dll")] internal static extern uint GetCurrentThreadId(); [DllImport("user32.dll", SetLastError = true)] internal static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach); [DllImport("user32.dll", CharSet = CharSet.Unicode)] internal static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll", CharSet = CharSet.Unicode)] internal static extern bool PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll", CharSet = CharSet.Unicode)] internal static extern IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); [DllImport("kernel32.dll")] internal static extern uint GetLastError(); internal static bool SendKeyboardScanCode(ushort scanCode, bool isExtendedKey, bool keyDown) { uint num = MapVirtualKey(scanCode, 1u); INPUT iNPUT = default(INPUT); iNPUT.type = 1u; iNPUT.ki.wVk = (ushort)((num != 0) ? ((ushort)num) : 0); iNPUT.ki.wScan = scanCode; iNPUT.ki.time = 0u; iNPUT.ki.dwExtraInfo = IntPtr.Zero; iNPUT.ki.dwFlags = 8u; if (isExtendedKey) { iNPUT.ki.dwFlags |= 1u; } if (!keyDown) { iNPUT.ki.dwFlags |= 2u; } uint num2 = SendInput(1u, new INPUT[1] { iNPUT }, 40); return num2 == 1; } } public enum SystemKeyDeliveryMode { ForegroundWindow, FocusTargetThenSendInput, DirectToWindow } public static class WindowsSystemKeyOutput { public static bool SendPhysicalKeyPress(PhysicalScanCode scanCode) { return SendPhysicalKeyPress(scanCode, SystemKeyDeliveryMode.ForegroundWindow, IntPtr.Zero, restoreUnityFocus: true); } public static bool SendPhysicalKeyPress(PhysicalScanCode scanCode, SystemKeyDeliveryMode deliveryMode, IntPtr targetWindow, bool restoreUnityFocus) { ushort scanCode2 = (ushort)scanCode; bool isExtended = PhysicalKeySimulator.IsExtendedScanCodePublic(scanCode); if (!TryScanCodeToVirtualKey(scanCode2, isExtended, out var virtualKey)) { Debug.LogWarning((object)("WindowsSystemKeyOutput: could not map scan code 0x" + scanCode2.ToString("X2"))); return false; } return SendVirtualKeyPress(virtualKey, scanCode2, isExtended, deliveryMode, targetWindow, restoreUnityFocus); } public static bool SendPhysicalKeyPressToProcess(string processName, PhysicalScanCode scanCode, SystemKeyDeliveryMode deliveryMode, bool restoreUnityFocus) { IntPtr intPtr = FindMainWindowForProcess(processName); if (intPtr == IntPtr.Zero) { Debug.LogWarning((object)("WindowsSystemKeyOutput: process window not found: " + processName)); return false; } return SendPhysicalKeyPress(scanCode, deliveryMode, intPtr, restoreUnityFocus); } public static bool SendPhysicalKeyPressToWindowTitle(string windowTitle, PhysicalScanCode scanCode, SystemKeyDeliveryMode deliveryMode, bool restoreUnityFocus) { IntPtr intPtr = WindowsInputNative.FindWindow(null, windowTitle); if (intPtr == IntPtr.Zero) { Debug.LogWarning((object)("WindowsSystemKeyOutput: window title not found: " + windowTitle)); return false; } return SendPhysicalKeyPress(scanCode, deliveryMode, intPtr, restoreUnityFocus); } public static bool SendKeyCodePress(KeyCode keyCode) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return SendKeyCodePress(keyCode, SystemKeyDeliveryMode.ForegroundWindow, IntPtr.Zero, restoreUnityFocus: true); } public static bool SendKeyCodePress(KeyCode keyCode, SystemKeyDeliveryMode deliveryMode, IntPtr targetWindow, bool restoreUnityFocus) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (!TryResolveKeyCode(keyCode, out var virtualKey, out var scanCode, out var isExtended)) { Debug.LogWarning((object)("WindowsSystemKeyOutput: unsupported KeyCode " + keyCode)); return false; } return SendVirtualKeyPress(virtualKey, scanCode, isExtended, deliveryMode, targetWindow, restoreUnityFocus); } public static bool SendKeyCodePressToProcess(KeyCode keyCode, string processName, SystemKeyDeliveryMode deliveryMode, bool restoreUnityFocus) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) IntPtr intPtr = FindMainWindowForProcess(processName); if (intPtr == IntPtr.Zero) { Debug.LogWarning((object)("WindowsSystemKeyOutput: process window not found: " + processName)); return false; } return SendKeyCodePress(keyCode, deliveryMode, intPtr, restoreUnityFocus); } public static bool SendKeyCodeDown(KeyCode keyCode) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (!PhysicalKeySimulator.TryGetScanCodeFromUnityKeyCode(keyCode, out var scanCode, out var isExtended)) { return false; } return SendInputScanCode(scanCode, isExtended, keyDown: true); } public static bool SendKeyCodeUp(KeyCode keyCode) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (!PhysicalKeySimulator.TryGetScanCodeFromUnityKeyCode(keyCode, out var scanCode, out var isExtended)) { return false; } return SendInputScanCode(scanCode, isExtended, keyDown: false); } public static bool TryResolveKeyCode(KeyCode keyCode, out ushort virtualKey, out ushort scanCode, out bool isExtended) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) virtualKey = 0; scanCode = 0; isExtended = false; if (!PhysicalKeySimulator.TryGetScanCodeFromUnityKeyCode(keyCode, out scanCode, out isExtended)) { return false; } return TryScanCodeToVirtualKey(scanCode, isExtended, out virtualKey); } public static bool SendVirtualKeyPress(ushort virtualKey, SystemKeyDeliveryMode deliveryMode, IntPtr targetWindow, bool restoreUnityFocus) { if (!PhysicalKeySimulator.TryGetScanCodeFromVirtualKey(virtualKey, out var scanCode, out var isExtended)) { return false; } return SendVirtualKeyPress(virtualKey, scanCode, isExtended, deliveryMode, targetWindow, restoreUnityFocus); } public static bool SendVirtualKeyPress(ushort virtualKey, ushort scanCode, bool isExtended, SystemKeyDeliveryMode deliveryMode, IntPtr targetWindow, bool restoreUnityFocus) { if (!IsWindowsPlatform()) { return false; } return deliveryMode switch { SystemKeyDeliveryMode.ForegroundWindow => SendInputKeyPress(scanCode, isExtended), SystemKeyDeliveryMode.FocusTargetThenSendInput => SendInputToTargetWindow(targetWindow, virtualKey, scanCode, isExtended, restoreUnityFocus), SystemKeyDeliveryMode.DirectToWindow => PostMessageKeyPress(targetWindow, virtualKey, scanCode, isExtended), _ => false, }; } public static IntPtr FindWindowByTitle(string windowTitle) { if (string.IsNullOrEmpty(windowTitle)) { return IntPtr.Zero; } return WindowsInputNative.FindWindow(null, windowTitle); } public static IntPtr FindMainWindowForProcess(string processName) { if (string.IsNullOrEmpty(processName)) { return IntPtr.Zero; } Process[] processesByName = Process.GetProcessesByName(processName); foreach (Process process in processesByName) { if (process != null) { IntPtr mainWindowHandle = process.MainWindowHandle; if (mainWindowHandle != IntPtr.Zero) { return mainWindowHandle; } } } return IntPtr.Zero; } public static bool TryFocusWindow(IntPtr windowHandle) { if (windowHandle == IntPtr.Zero || !WindowsInputNative.IsWindow(windowHandle)) { return false; } if (WindowsInputNative.IsIconic(windowHandle)) { WindowsInputNative.ShowWindow(windowHandle, 5); } uint lpdwProcessId; uint windowThreadProcessId = WindowsInputNative.GetWindowThreadProcessId(windowHandle, out lpdwProcessId); uint currentThreadId = WindowsInputNative.GetCurrentThreadId(); WindowsInputNative.AllowSetForegroundWindow((int)lpdwProcessId); bool flag = false; if (windowThreadProcessId != currentThreadId) { flag = WindowsInputNative.AttachThreadInput(currentThreadId, windowThreadProcessId, fAttach: true); } bool result = WindowsInputNative.SetForegroundWindow(windowHandle); if (flag) { WindowsInputNative.AttachThreadInput(currentThreadId, windowThreadProcessId, fAttach: false); } return result; } private static bool SendInputKeyPress(ushort scanCode, bool isExtended) { if (!SendInputScanCode(scanCode, isExtended, keyDown: true)) { return false; } return SendInputScanCode(scanCode, isExtended, keyDown: false); } private static bool SendInputToTargetWindow(IntPtr targetWindow, ushort virtualKey, ushort scanCode, bool isExtended, bool restoreUnityFocus) { if (targetWindow == IntPtr.Zero || !WindowsInputNative.IsWindow(targetWindow)) { Debug.LogWarning((object)"WindowsSystemKeyOutput: invalid target window handle."); return false; } IntPtr unityWindowHandle = GetUnityWindowHandle(); if (!TryFocusWindow(targetWindow)) { Debug.LogWarning((object)"WindowsSystemKeyOutput: failed to focus target window."); return false; } bool result = SendInputKeyPress(scanCode, isExtended); if (restoreUnityFocus && unityWindowHandle != IntPtr.Zero) { TryFocusWindow(unityWindowHandle); } return result; } private static bool PostMessageKeyPress(IntPtr targetWindow, ushort virtualKey, ushort scanCode, bool isExtended) { if (targetWindow == IntPtr.Zero || !WindowsInputNative.IsWindow(targetWindow)) { Debug.LogWarning((object)"WindowsSystemKeyOutput: invalid target window handle."); return false; } bool flag = virtualKey == 18 || virtualKey == 91 || virtualKey == 92; uint msg = ((!flag) ? 256u : 260u); uint msg2 = ((!flag) ? 257u : 261u); IntPtr lParam = BuildKeyLParam(scanCode, isExtended, keyUp: false); IntPtr lParam2 = BuildKeyLParam(scanCode, isExtended, keyUp: true); bool flag2 = WindowsInputNative.PostMessage(targetWindow, msg, new IntPtr(virtualKey), lParam); bool flag3 = WindowsInputNative.PostMessage(targetWindow, msg2, new IntPtr(virtualKey), lParam2); return flag2 && flag3; } private static IntPtr BuildKeyLParam(ushort scanCode, bool isExtended, bool keyUp) { int num = 1; num |= scanCode << 16; if (isExtended) { num |= 0x1000000; } if (keyUp) { num |= 0x40000000; num |= int.MinValue; } return new IntPtr(num); } private static bool SendInputScanCode(ushort scanCode, bool isExtendedKey, bool keyDown) { if (!WindowsInputNative.SendKeyboardScanCode(scanCode, isExtendedKey, keyDown)) { Debug.LogWarning((object)("WindowsSystemKeyOutput SendInput failed. Error=" + WindowsInputNative.GetLastError())); return false; } return true; } private static bool TryScanCodeToVirtualKey(ushort scanCode, bool isExtended, out ushort virtualKey) { virtualKey = 0; uint num = WindowsInputNative.MapVirtualKey(scanCode, 1u); if (num == 0) { return false; } virtualKey = (ushort)num; return true; } private static IntPtr GetUnityWindowHandle() { return WindowsInputNative.GetForegroundWindow(); } private static bool IsWindowsPlatform() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 if ((int)Application.platform != 2 && (int)Application.platform != 7) { Debug.LogWarning((object)"WindowsSystemKeyOutput only works on Windows."); return false; } return true; } } }