Skip to content

Commit 88c74ac

Browse files
committed
Initial Commit
Proof of Concept, works, just not flawlessly.
1 parent 036e632 commit 88c74ac

File tree

4 files changed

+3210
-0
lines changed

4 files changed

+3210
-0
lines changed

DashPause.au3

Lines changed: 351 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,351 @@
1+
#include "WinHTTP.au3"
2+
3+
#include <WinAPI.au3> ; _WinAPI_GetLastError
4+
#include <String.au3> ; _HexToString
5+
#include <EditConstants.au3>
6+
#include <GUIConstantsEx.au3>
7+
#include <WindowsConstants.au3>
8+
9+
Main()
10+
11+
Func Main()
12+
13+
Local $bDev = False
14+
Local $sData = ""
15+
Local $hSocket = 0
16+
Local $iTimeout = 500
17+
Local $bRunning = False
18+
Local $bSuspended = False
19+
20+
Local $bInLevel = False
21+
Local $bLevelPaused = False
22+
23+
If $bDev Then
24+
Local $hGUI = GUICreate("Dash Pause", 640, 480, -1, -1, BitOr($WS_MINIMIZEBOX, $WS_CAPTION, $WS_SYSMENU))
25+
Local $hData = GUICtrlCreateEdit("", 0, 20, 640, 460, BitOR($ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL, $ES_READONLY))
26+
GUISetState(@SW_SHOW, $hGUI)
27+
EndIf
28+
29+
While 1
30+
31+
$hMsg = GUIGetMsg()
32+
33+
Select
34+
35+
Case $hMsg = $GUI_EVENT_CLOSE
36+
GUIDelete($hGUI)
37+
TCPShutdown()
38+
Exit
39+
40+
Case ProcessExists("Beat Saber.exe") and $hSocket = 0
41+
TraySetToolTip("Connecting...")
42+
$hSocket = _StartListener("127.0.0.1", 2946, "/BSDataPuller")
43+
TraySetToolTip("Connected")
44+
$bRunning = True
45+
46+
Case $hSocket <> 0 And Not ProcessExists("Beat Saber.exe")
47+
TraySetToolTip("Disconnecting...")
48+
_StopListener($hSocket)
49+
TraySetToolTip("Disconnected")
50+
$bRunning = False
51+
$hSocket = 0
52+
53+
Case $bRunning
54+
$sData = _GetData($hSocket, $iTimeout)
55+
If $bDev Then GUICtrlSetData($hData, $sData)
56+
$bInLevel = _StringBetween($sData, '"InLevel": ', ",")[0]
57+
$bLevelPaused = _StringBetween($sData, '"LevelPaused": ', ",")[0]
58+
If $bInLevel = "true" And $bLevelPaused = "false" Then
59+
If Not $bSuspended Then
60+
ConsoleWrite("Suspending" & @CRLF)
61+
_ProcessSuspend("OculusDash.exe")
62+
_ProcessSuspend("VRDashboard.exe")
63+
$bSuspended = True
64+
EndIf
65+
ElseIf $bInLevel = "false" Then
66+
If $bSuspended Then
67+
ConsoleWrite("Resuming" & @CRLF)
68+
_ProcessResume("OculusDash.exe")
69+
_ProcessResume("VRDashboard.exe")
70+
$bSuspended = False
71+
EndIf
72+
EndIf
73+
74+
Case Else
75+
;;;
76+
77+
EndSelect
78+
79+
WEnd
80+
81+
EndFunc
82+
83+
Func _GetData($hWebSocket, $iTimeout)
84+
85+
Local $hTimer = TimerInit()
86+
87+
Local Const $WINHTTP_WEB_SOCKET_BINARY_MESSAGE_BUFFER_TYPE = 0
88+
Local Const $WINHTTP_WEB_SOCKET_BINARY_FRAGMENT_BUFFER_TYPE = 1
89+
Local Const $WINHTTP_WEB_SOCKET_UTF8_MESSAGE_BUFFER_TYPE = 2
90+
Local Const $WINHTTP_WEB_SOCKET_UTF8_FRAGMENT_BUFFER_TYPE = 3
91+
92+
Local Const $ERROR_NOT_ENOUGH_MEMORY = 8
93+
Local Const $ERROR_INVALID_PARAMETER = 87
94+
95+
Local $iBufferLen = 1024
96+
Local $tBuffer = 0, $bRecv = Binary("")
97+
98+
Local $iBytesRead = 0, $iBufferType = 3
99+
Do
100+
If $iBufferLen = 0 Then
101+
$iError = $ERROR_NOT_ENOUGH_MEMORY
102+
Return False
103+
EndIf
104+
105+
$tBuffer = DllStructCreate("byte[" & $iBufferLen & "]")
106+
107+
$iError = _WinHttpWebSocketReceive($hWebSocket, _
108+
$tBuffer, _
109+
$iBytesRead, _
110+
$iBufferType)
111+
If @error Or $iError <> 0 Then
112+
ConsoleWrite("WebSocketReceive error" & @CRLF)
113+
Return False
114+
EndIf
115+
116+
; If we receive just part of the message restart the receive operation.
117+
118+
$bRecv &= BinaryMid(DllStructGetData($tBuffer, 1), 1, $iBytesRead)
119+
$tBuffer = 0
120+
121+
$iBufferLen -= $iBytesRead
122+
;If TimerDiff($hTimer) > $iTimeout Then Return False
123+
Until $iBufferType <> $WINHTTP_WEB_SOCKET_UTF8_FRAGMENT_BUFFER_TYPE
124+
125+
; We expected server just to echo single binary message.
126+
127+
If $iBufferType <> $WINHTTP_WEB_SOCKET_UTF8_MESSAGE_BUFFER_TYPE Then
128+
ConsoleWrite("Unexpected buffer type" & @CRLF)
129+
$iError = $ERROR_INVALID_PARAMETER
130+
Return False
131+
EndIf
132+
133+
Return _HexToString($bRecv)
134+
135+
EndFunc
136+
137+
Func _ProcessSuspend($sProcess)
138+
$iPID = ProcessExists($sProcess)
139+
If $iPID Then
140+
$ai_Handle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', 0x1f0fff, 'int', False, 'int', $iPID)
141+
$i_success = DllCall("ntdll.dll","int","NtSuspendProcess","int",$ai_Handle[0])
142+
DllCall('kernel32.dll', 'ptr', 'CloseHandle', 'ptr', $ai_Handle)
143+
If IsArray($i_success) Then
144+
Return 1
145+
Else
146+
SetError(1)
147+
Return 0
148+
Endif
149+
Else
150+
SetError(2)
151+
Return 0
152+
EndIf
153+
EndFunc
154+
155+
Func _ProcessResume($sProcess)
156+
$iPID = ProcessExists($sProcess)
157+
If $iPID Then
158+
$ai_Handle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', 0x1f0fff, 'int', False, 'int', $iPID)
159+
$i_success = DllCall("ntdll.dll","int","NtResumeProcess","int",$ai_Handle[0])
160+
DllCall('kernel32.dll', 'ptr', 'CloseHandle', 'ptr', $ai_Handle)
161+
If IsArray($i_success) Then
162+
Return 1
163+
Else
164+
SetError(1)
165+
Return 0
166+
Endif
167+
Else
168+
SetError(2)
169+
Return 0
170+
EndIf
171+
EndFunc
172+
173+
Func _SendData($hWebSocket, $sData) ; Why are you using this <_<
174+
175+
Local Const $WINHTTP_WEB_SOCKET_BINARY_MESSAGE_BUFFER_TYPE = 0
176+
177+
$iError = _WinHttpWebSocketSend($hWebSocket, _
178+
$WINHTTP_WEB_SOCKET_BINARY_MESSAGE_BUFFER_TYPE, _
179+
$sData)
180+
If @error Or $iError <> 0 Then
181+
ConsoleWrite("WebSocketSend error" & @CRLF)
182+
Return False
183+
EndIf
184+
Return True
185+
EndFunc
186+
187+
Func _StartListener($sIP = "127.0.0.1", $iPort = 1337, $sPath = "")
188+
189+
Local Const $WINHTTP_OPTION_UPGRADE_TO_WEB_SOCKET = 114
190+
191+
$hOpen = _WinHttpOpen("DashPause 0.1", $WINHTTP_ACCESS_TYPE_DEFAULT_PROXY)
192+
If $hOpen = 0 Then
193+
$iError = _WinAPI_GetLastError()
194+
ConsoleWrite("Open error" & @CRLF)
195+
Return False
196+
EndIf
197+
198+
$hConnect = _WinHttpConnect($hOpen, $sIP, $iPort)
199+
If $hConnect = 0 Then
200+
$iError = _WinAPI_GetLastError()
201+
ConsoleWrite("Connect error" & @CRLF)
202+
Return False
203+
EndIf
204+
205+
$hRequest = _WinHttpOpenRequest($hConnect, "GET", $sPath, "")
206+
If $hRequest = 0 Then
207+
$iError = _WinAPI_GetLastError()
208+
ConsoleWrite("OpenRequest error" & @CRLF)
209+
Return False
210+
EndIf
211+
212+
; Request protocol upgrade from http to websocket.
213+
214+
Local $fStatus = _WinHttpSetOptionNoParams($hRequest, $WINHTTP_OPTION_UPGRADE_TO_WEB_SOCKET)
215+
If Not $fStatus Then
216+
$iError = _WinAPI_GetLastError()
217+
ConsoleWrite("SetOption error" & @CRLF)
218+
Return False
219+
EndIf
220+
221+
; Perform websocket handshake by sending a request and receiving server's response.
222+
; Application may specify additional headers if needed.
223+
224+
$fStatus = _WinHttpSendRequest($hRequest)
225+
If Not $fStatus Then
226+
$iError = _WinAPI_GetLastError()
227+
ConsoleWrite("SendRequest error" & @CRLF)
228+
Return False
229+
EndIf
230+
231+
$fStatus = _WinHttpReceiveResponse($hRequest)
232+
If Not $fStatus Then
233+
$iError = _WinAPI_GetLastError()
234+
ConsoleWrite("SendRequest error" & @CRLF)
235+
Return False
236+
EndIf
237+
238+
; Application should check what is the HTTP status code returned by the server and behave accordingly.
239+
; WinHttpWebSocketCompleteUpgrade will fail if the HTTP status code is different than 101.
240+
241+
$hWebSocket = _WinHttpWebSocketCompleteUpgrade($hRequest, 0)
242+
If $hWebSocket = 0 Then
243+
$iError = _WinAPI_GetLastError()
244+
ConsoleWrite("WebSocketCompleteUpgrade error" & @CRLF)
245+
Return False
246+
EndIf
247+
248+
_WinHttpCloseHandle($hRequest)
249+
$hRequestHandle = 0
250+
251+
ConsoleWrite("Succesfully upgraded to websocket protocol" & @CRLF)
252+
Return $hWebSocket
253+
EndFunc
254+
255+
Func _StopListener($hWebSocket)
256+
257+
Local Const $WINHTTP_WEB_SOCKET_SUCCESS_CLOSE_STATUS = 1000
258+
259+
$iError = _WinHttpWebSocketClose($hWebSocket, _
260+
$WINHTTP_WEB_SOCKET_SUCCESS_CLOSE_STATUS)
261+
If @error Or $iError <> 0 Then
262+
ConsoleWrite("WebSocketClose error" & @CRLF)
263+
Return False
264+
EndIf
265+
266+
; Check close status returned by the server.
267+
268+
Local $iStatus = 0, $iReasonLengthConsumed = 0
269+
Local $tCloseReasonBuffer = DllStructCreate("byte[123]")
270+
271+
$iError = _WinHttpWebSocketQueryCloseStatus($hWebSocket, _
272+
$iStatus, _
273+
$iReasonLengthConsumed, _
274+
$tCloseReasonBuffer)
275+
If @error Or $iError <> 0 Then
276+
ConsoleWrite("QueryCloseStatus error" & @CRLF)
277+
Return False
278+
EndIf
279+
280+
ConsoleWrite("The server closed the connection with status code: '" & $iStatus & "' and reason: '" & _
281+
BinaryToString(BinaryMid(DllStructGetData($tCloseReasonBuffer, 1), 1, $iReasonLengthConsumed)) & "'" & @CRLF)
282+
EndFunc
283+
284+
Func _WinHttpSetOptionNoParams($hInternet, $iOption)
285+
Local $aCall = DllCall($hWINHTTPDLL__WINHTTP, "bool", "WinHttpSetOption", _
286+
"handle", $hInternet, "dword", $iOption, "ptr", 0, "dword", 0)
287+
If @error Or Not $aCall[0] Then Return SetError(4, 0, 0)
288+
Return 1
289+
EndFunc ;==>_WinHttpSetOptionNoParams
290+
291+
Func _WinHttpWebSocketCompleteUpgrade($hRequest, $pContext = 0)
292+
Local $aCall = DllCall($hWINHTTPDLL__WINHTTP, "handle", "WinHttpWebSocketCompleteUpgrade", _
293+
"handle", $hRequest, _
294+
"DWORD_PTR", $pContext)
295+
If @error Then Return SetError(@error, @extended, -1)
296+
Return $aCall[0]
297+
EndFunc ;==>_WinHttpWebSocketCompleteUpgrade
298+
299+
Func _WinHttpWebSocketSend($hWebSocket, $iBufferType, $vData)
300+
Local $tBuffer = 0, $iBufferLen = 0
301+
If IsBinary($vData) = 0 Then $vData = StringToBinary($vData)
302+
$iBufferLen = BinaryLen($vData)
303+
If $iBufferLen > 0 Then
304+
$tBuffer = DllStructCreate("byte[" & $iBufferLen & "]")
305+
DllStructSetData($tBuffer, 1, $vData)
306+
EndIf
307+
308+
Local $aCall = DllCall($hWINHTTPDLL__WINHTTP, "DWORD", "WinHttpWebSocketSend", _
309+
"handle", $hWebSocket, _
310+
"int", $iBufferType, _
311+
"ptr", DllStructGetPtr($tBuffer), _
312+
"DWORD", $iBufferLen)
313+
If @error Then Return SetError(@error, @extended, -1)
314+
Return $aCall[0]
315+
EndFunc ;==>_WinHttpWebSocketSend
316+
317+
Func _WinHttpWebSocketReceive($hWebSocket, $tBuffer, ByRef $iBytesRead, ByRef $iBufferType)
318+
Local $aCall = DllCall($hWINHTTPDLL__WINHTTP, "handle", "WinHttpWebSocketReceive", _
319+
"handle", $hWebSocket, _
320+
"ptr", DllStructGetPtr($tBuffer), _
321+
"DWORD", DllStructGetSize($tBuffer), _
322+
"DWORD*", $iBytesRead, _
323+
"int*", $iBufferType)
324+
If @error Then Return SetError(@error, @extended, -1)
325+
$iBytesRead = $aCall[4]
326+
$iBufferType = $aCall[5]
327+
Return $aCall[0]
328+
EndFunc ;==>_WinHttpWebSocketReceive
329+
330+
Func _WinHttpWebSocketClose($hWebSocket, $iStatus, $tReason = 0)
331+
Local $aCall = DllCall($hWINHTTPDLL__WINHTTP, "handle", "WinHttpWebSocketClose", _
332+
"handle", $hWebSocket, _
333+
"USHORT", $iStatus, _
334+
"ptr", DllStructGetPtr($tReason), _
335+
"DWORD", DllStructGetSize($tReason))
336+
If @error Then Return SetError(@error, @extended, -1)
337+
Return $aCall[0]
338+
EndFunc ;==>_WinHttpWebSocketClose
339+
340+
Func _WinHttpWebSocketQueryCloseStatus($hWebSocket, ByRef $iStatus, ByRef $iReasonLengthConsumed, $tCloseReasonBuffer = 0)
341+
Local $aCall = DllCall($hWINHTTPDLL__WINHTTP, "handle", "WinHttpWebSocketQueryCloseStatus", _
342+
"handle", $hWebSocket, _
343+
"USHORT*", $iStatus, _
344+
"ptr", DllStructGetPtr($tCloseReasonBuffer), _
345+
"DWORD", DllStructGetSize($tCloseReasonBuffer), _
346+
"DWORD*", $iReasonLengthConsumed)
347+
If @error Then Return SetError(@error, @extended, -1)
348+
$iStatus = $aCall[2]
349+
$iReasonLengthConsumed = $aCall[5]
350+
Return $aCall[0]
351+
EndFunc ;==>_WinHttpWebSocketQueryCloseStatus

Icon.png

27.8 KB
Loading

0 commit comments

Comments
 (0)