Code:
; -------------------------------------------------
; ------------SERVERSCRIPT------------------
; -------------------------------------------------
; CONFIGURATION SECTION:
; Specify Your own Network's address and port.
;Network_Address = 127.0.0.1
Network_Address = 0.0.0.0
Network_Port = 8765
; ----------------------------
; END OF CONFIGURATION SECTION
; ----------------------------
killbroadcast = 0
KEY_0=0
KEY_1=1
KEY_2=2
KEY_3=3
KEY_4=4
KEY_5=5
KEY_6=6
KEY_7=7
KEY_8=8
KEY_9=9
KEY_A=10
KEY_B=11
KEY_C=12
KEY_D=13
KEY_E=14
KEY_F=15
KEY_G=16
KEY_H=17
KEY_I=18
KEY_J=19
KEY_K=20
KEY_L=21
KEY_M=22
KEY_N=23
KEY_O=24
KEY_P=25
KEY_Q=26
KEY_R=27
KEY_S=28
KEY_T=29
KEY_U=30
KEY_V=31
KEY_W=32
KEY_X=33
KEY_Y=34
KEY_Z=35
conectioncheck=0
;Gui, Add, Text,, Send:
;Gui, Add, Edit, w100 vSendText
;Gui, Add, Text,, Repeat:
;Gui, Add, Edit, w40 vRepeat, 5
;Gui, Add, Text,, Delay (ms):
;Gui, Add, Edit, w40 vDelay, 50
;Gui, Add, Button, gSendviaNet, Send
Gui, Add, Text,, Key sender server (transmits wow keystrokes to client):
Gui, Show
Gosub Connection_Init
return
Connection_Init:
OnExit, ExitSub ; For connection cleanup purposes.
; set up a very basic server:
socket := PrepareForIncomingConnection(Network_Address, Network_Port)
if socket = -1 ; Connection failed (it already displayed the reason).
ExitApp
; Find this script's main window:
Process, Exist ; This sets ErrorLevel to this script's PID (it's done this way to support compiled scripts).
DetectHiddenWindows On
ScriptMainWindowId := WinExist("ahk_class AutoHotkey ahk_pid " . ErrorLevel)
DetectHiddenWindows Off
; Set up the connection to notify this script via message whenever new data has arrived.
; This avoids the need to poll the connection and thus cuts down on resource usage.
FD_READ = 1 ; Received when data is available to be read.
;FD_WRITE =
FD_CLOSE = 32 ; Received when connection has been closed.
FD_CONNECT = 20 ; Received when connection has been made.
if DllCall("Ws2_32\WSAAsyncSelect", "UInt", socket, "UInt", ScriptMainWindowId, "UInt", NotificationMsg, "Int", FD_CLOSE|FD_CONNECT)
{
MsgBox % "WSAAsyncSelect() indicated Winsock error " . DllCall("Ws2_32\WSAGetLastError")
ExitApp
}
Loop ; Wait for incomming connections
{
; accept requests that are in the pipeline of the socket
conectioncheck := DllCall("Ws2_32\accept", "UInt", socket, "UInt", &SocketAddress, "Int", SizeOfSocketAddress)
; Ws2_22/accept returns the new Connection-Socket if a connection request was in the pipeline
; on failure it returns an negative value
if conectioncheck > 1
{
MsgBox Incoming connection accepted
break
}
sleep 500 ; wait half 1 second then accept again
}
return
;SendviaNet:
;Gui, Submit, NoHide
;SendData(conectioncheck,SendText,Repeat,Delay)
;SentText =
;return
PrepareForIncomingConnection(IPAddress, Port)
; This can connect to most types of TCP servers, not just Network.
; Returns -1 (INVALID_SOCKET) upon failure or the socket ID upon success.
{
VarSetCapacity(wsaData, 32) ; The struct is only about 14 in size, so 32 is conservative.
result := DllCall("Ws2_32\WSAStartup", "UShort", 0x0002, "UInt", &wsaData) ; Request Winsock 2.0 (0x0002)
; Since WSAStartup() will likely be the first Winsock function called by this script,
; check ErrorLevel to see if the OS has Winsock 2.0 available:
if ErrorLevel
{
MsgBox WSAStartup() could not be called due to error %ErrorLevel%. Winsock 2.0 or higher is required.
return -1
}
if result ; Non-zero, which means it failed (most Winsock functions return 0 upon success).
{
MsgBox % "WSAStartup() indicated Winsock error " . DllCall("Ws2_32\WSAGetLastError")
return -1
}
AF_INET = 2
SOCK_STREAM = 1
IPPROTO_TCP = 6
socket := DllCall("Ws2_32\socket", "Int", AF_INET, "Int", SOCK_STREAM, "Int", IPPROTO_TCP)
if socket = -1
{
MsgBox % "socket() indicated Winsock error " . DllCall("Ws2_32\WSAGetLastError")
return -1
}
; Prepare for connection:
SizeOfSocketAddress = 16
VarSetCapacity(SocketAddress, SizeOfSocketAddress)
InsertInteger(2, SocketAddress, 0, AF_INET) ; sin_family
InsertInteger(DllCall("Ws2_32\htons", "UShort", Port), SocketAddress, 2, 2) ; sin_port
InsertInteger(DllCall("Ws2_32\inet_addr", "Str", IPAddress), SocketAddress, 4, 4) ; sin_addr.s_addr
; Bind to socket:
if DllCall("Ws2_32\bind", "UInt", socket, "UInt", &SocketAddress, "Int", SizeOfSocketAddress)
{
MsgBox % "bind() indicated Winsock error " . DllCall("Ws2_32\WSAGetLastError") . "?"
return -1
}
if DllCall("Ws2_32\listen", "UInt", socket, "UInt", "SOMAXCONN")
{
MsgBox % "LISTEN() indicated Winsock error " . DllCall("Ws2_32\WSAGetLastError") . "?"
return -1
}
return socket ; Indicate success by returning a valid socket ID rather than -1.
}
SendData(wParam,SendData, Repeat, Delay)
{
socket := wParam
; SendDataSize := VarSetCapacity(SendData)
; SendDataSize += 1
Loop % Repeat
{
; SendIt := SendData . "(" . A_Index . ")"
; SendDataSize := VarSetCapacity(SendIt)
; SendDataSize += 1
; MsgBox sending %SendIt% to the socket
; sendret := DllCall("Ws2_32\send", "UInt", socket, "Str", SendIt, "Int", SendDatasize, "Int", 0)
; sendret := DllCall("Ws2_32\send", "UInt", socket, "Str", SendIt, "Int", strlen(SendIt), "Int", 0)
sendret := DllCall("Ws2_32\send", "UInt", socket, "Str", SendData, "Int", strlen(SendData), "Int", 0)
WinsockError := DllCall("Ws2_32\WSAGetLastError")
if WinsockError <> 0 ; WSAECONNRESET, which happens when Network closes via system shutdown/logoff.
; Since it's an unexpected error, report it. Also exit to avoid infinite loop.
MsgBox % "send() indicated Winsock error " . WinsockError
sleep,Delay
}
;send( sockConnected,> welcome, strlen(welcome) + 1, NULL);
}
InsertInteger(pInteger, ByRef pDest, pOffset = 0, pSize = 4)
; The caller must ensure that pDest has sufficient capacity. To preserve any existing contents in pDest,
; only pSize number of bytes starting at pOffset are altered in it.
{
Loop %pSize% ; Copy each byte in the integer into the structure as raw binary data.
DllCall("RtlFillMemory", "UInt", &pDest + pOffset + A_Index-1, "UInt", 1, "UChar", pInteger >> 8*(A_Index-1) & 0xFF)
}
~Pause::
KeyWait, Pause, D
If(%killbroadcast% = 0)
{
killbroadcast = 1
}
else
{
killbroadcast = 0
;WinGet, targetWindowIds, List, %windowTitle%
}
Return
~0::
KeyWait, 0
SendKey(KEY_0)
Return
~1::
KeyWait, 1
SendKey(KEY_1)
Return
~2::
KeyWait, 2
SendKey(KEY_2)
Return
~3::
KeyWait, 3
SendKey(KEY_3)
Return
~4::
KeyWait, 4
SendKey(KEY_4)
Return
~5::
KeyWait, 5
SendKey(KEY_5)
Return
~6::
KeyWait, 0
SendKey(KEY_6)
Return
~7::
KeyWait, 7
SendKey(KEY_7)
Return
~8::
KeyWait, 8
SendKey(KEY_8)
Return
~9::
KeyWait, 9
SendKey(KEY_9)
Return
~A::
KeyWait, A
SendKey(KEY_A)
Return
~B::
KeyWait, B
SendKey(KEY_B)
Return
~C::
KeyWait, C
SendKey(KEY_C)
Return
~D::
KeyWait, D
SendKey(KEY_D)
Return
~E::
KeyWait, E
SendKey(KEY_E)
Return
~F::
KeyWait, F
SendKey(KEY_F)
Return
~G::
KeyWait, G
SendKey(KEY_G)
Return
~H::
KeyWait, H
SendKey(KEY_H)
Return
~I::
KeyWait, I
SendKey(KEY_I)
Return
~J::
KeyWait, J
SendKey(KEY_J)
Return
~K::
KeyWait, K
SendKey(KEY_K)
Return
~L::
KeyWait, L
SendKey(KEY_L)
Return
~M::
KeyWait, M
SendKey(KEY_M)
Return
~N::
KeyWait, N
SendKey(KEY_N)
Return
~O::
KeyWait, O
SendKey(KEY_O)
Return
~P::
KeyWait, P
SendKey(KEY_P)
Return
~Q::
KeyWait, Q
SendKey(KEY_Q)
Return
~R::
KeyWait, R
SendKey(KEY_R)
Return
~S::
KeyWait, S
SendKey(KEY_S)
Return
~T::
KeyWait, T
SendKey(KEY_T)
Return
~U::
KeyWait, U
SendKey(KEY_U)
Return
~V::
KeyWait, V
SendKey(KEY_V)
Return
~W::
KeyWait, W
SendKey(KEY_W)
Return
~X::
KeyWait, X
SendKey(KEY_X)
Return
~Y::
KeyWait, Y
SendKey(KEY_Y)
Return
~Z::
KeyWait, Z
SendKey(KEY_Z)
Return
SendKey(key)
{
global killbroadcast
global conectioncheck
If(%killbroadcast% = 0)
{
killbroadcast = 1 ; stop other threads from sending right now!
if conectioncheck > 1 ; don't send before a client has connected.
{
SendData(conectioncheck,key,1,1)
}
killbroadcast = 0 ; Reactivate sending of keys.
}
}
guiclose:
ExitSub: ; This subroutine is called automatically when the script exits for any reason.
; MSDN: "Any sockets open when WSACleanup is called are reset and automatically
; deallocated as if closesocket was called."
DllCall("Ws2_32\WSACleanup")
ExitApp
Connect With Us