Skip to content
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Donate
Collapse

Plutonium

  1. Home
  2. General Discussion
  3. Scripts for automatic pause upon controller disconnect

Scripts for automatic pause upon controller disconnect

Scheduled Pinned Locked Moved General Discussion
2 Posts 1 Posters 126 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • PGarglerundefined Offline
    PGarglerundefined Offline
    PGargler
    wrote on last edited by
    #1

    (This may be helpful for PC players like me who use Bluetooth controllers that like to disconnect randomly, also looking for feedback from anyone who might know how to achieve this effect with lower latency)

    This should work with Windows 10 and 11.

    -Open config file for game of choice and set key P bind to "pause"
    -PowerShell code that achieves this effect:

    Add-Type -TypeDefinition @"
        using System;
        using System.Runtime.InteropServices;
    
        public class XInput {
            [DllImport("XInput1_4.dll", EntryPoint="XInputGetState")]
            public static extern int XInputGetState(int dwUserIndex, out XINPUT_STATE pState);
        }
    
        [StructLayout(LayoutKind.Sequential)]
        public struct XINPUT_STATE {
            public int dwPacketNumber;
            public XINPUT_GAMEPAD Gamepad;
        }
    
        [StructLayout(LayoutKind.Sequential)]
        public struct XINPUT_GAMEPAD {
            public short wButtons;
            public byte bLeftTrigger;
            public byte bRightTrigger;
            public short sThumbLX;
            public short sThumbLY;
            public short sThumbRX;
            public short sThumbRY;
        }
    "@
    
    function Send-KeyPress {
        param ($key)
        Add-Type -TypeDefinition @"
            using System;
            using System.Runtime.InteropServices;
    
            public class Keyboard {
                [DllImport("user32.dll")]
                public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo);
            }
    "@
        $VK_P = 0x50
        [Keyboard]::keybd_event($VK_P, 0, 0, 0)   # Press "P"
        Start-Sleep -Milliseconds 50  # Small delay before releasing
        [Keyboard]::keybd_event($VK_P, 0, 2, 0)   # Release "P"
    }
    
    $global:isConnected = $true
    Write-Host "Monitoring Xbox Controller... Press Ctrl+C to exit."
    
    try {
        while ($true) {
            $state = New-Object XINPUT_STATE
            $result = [XInput]::XInputGetState(0, [ref]$state)
    
            if ($result -eq 0) {
                if (-not $global:isConnected) {
                    $global:isConnected = $true
                }
            } else {
                if ($global:isConnected) {
                    $global:isConnected = $false
                    Send-KeyPress -key "P"
                    Write-Host "Controller disconnected - Sent 'P' key press!"
                }
            }
    
            Start-Sleep -Milliseconds 16  # Polls ~60 times per second
        }
    } catch {
        Write-Host "Script terminated."
    }
    

    -Ctrl+C to exit or kill shell

    Alternative using AutoHotKey 2.0.19 (runs in background):
    -Download AutoHotKey (dot com)
    -Create ControllerMonitor.ahk containing following text:

    #Requires AutoHotkey v2.0
    #SingleInstance Force
    
    ; Include the XInput library
    #include XInput.ahk
    
    global isConnected := false
    
    SetTimer(CheckController, 16)  ; 60 times per second (16ms interval)
    
    ; Define the hotkey to exit the script
    #!x:: 
        ExitApp  ; Terminates the script
    return
    
    CheckController() {
        global isConnected
    
        state := Buffer(16, 0)
        if (XInput_GetState(0, state) == 0) {  ; 0 means connected
            if (!isConnected) {
                isConnected := true
            }
        } else {
            if (isConnected) {
                isConnected := false
                Send("p")
            }
        }
    }
    
    

    -Win+Alt+X to terminate script when done playing
    -Of course you can change Send("p") or #!x:: to anything you like

    -Create in same folder XInput.ahk (save file type as "All Files") containing following text:

    ; XInput.ahk - XInput wrapper for AutoHotkey v2
    DllCall("LoadLibrary", "Str", "XInput1_4.dll")
    
    XInput_GetState(controllerIndex, state) {
        return DllCall("XInput1_4\XInputGetState", "UInt", controllerIndex, "Ptr", state.Ptr, "UInt")
    }
    
    

    -Run ControllerMonitor.ahk and terminate with Win+Alt+X when done playing

    Unfortunately, it takes roughly a second to register despite a high polling frequently. I tried looking for ways around this accessing log files from Event Viewer but had no success. Most of my issues doing it by other methods come from Windows 11 being so adamant that Bluetooth devices always appear connected.

    If anyone sees this who is part of the high round zombies community, I would love to know if this would be an accepted method of preventing losing a game by hardware issues, or if this would be considered cheating with a macro. Specifically considering first room games on BO1 personally (and yea I know not to use plutonium for BO1).

    Inb4 "just press ESC" igi

    1 Reply Last reply
    0
    • PGarglerundefined Offline
      PGarglerundefined Offline
      PGargler
      wrote on last edited by
      #2

      fixed ControllerMonitor.ahk:

      #Requires AutoHotkey v2.0
      #SingleInstance Force
      
      ; Include the XInput library
      #include XInput.ahk
      
      global isConnected := false
      
      SetTimer(CheckController, 16)  ; 60 times per second (16ms interval)
      
      ; Define the hotkey to exit the script
      #!x::ExitApp  ; Terminates the script
      
      CheckController() {
          global isConnected  ; Explicitly declare the global variable
      
          state := Buffer(16, 0)  ; Ensure the buffer is correctly allocated
          if (XInput_GetState(0, state) == 0) {  ; 0 means connected
              if (!isConnected) {
                  isConnected := true
              }
          } else {
              if (isConnected) {
                  isConnected := false
                  Send("p")  ; Send 'p' on disconnection
              }
          }
      }
      
      1 Reply Last reply
      1

      • Login

      • Don't have an account? Register

      • Login or register to search.
      • First post
        Last post
      0
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Donate