Synopsis: AutoHotKey Server-script to relay a subset of keys from one computer where you play World of Warcraft (or other games with small changes) with your main, to another computer where the WoW-alt-sessions are running together with the Client-script.

Default a..z and 0..9 keys are relayed, but it's very easy to extend this for any possibly combination that suits your setup

I've submitted these two scrips before but i did it in the wrong area (beginners) and besides it wasn't even tagged up as code. This it the updated current version of this software that i use myself:

Usage instructions below the source.

Server script:
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