Minecraft Server List Ping

Ask gaming related questions (AHK v1.1 and older)
User avatar
elModo7
Posts: 217
Joined: 01 Sep 2017, 02:38
Location: Spain
Contact:

Minecraft Server List Ping

Post by elModo7 » 21 Jan 2024, 11:29

Hi there, I wanted to implement a minecraft server list ping message in AutoHotkey, I've never worked actively with buffers, numput, strput etc
This is what I have so far, I'm not sure if I'm way too off or I'm on track to achieving it:

I could use a few APIs for this, but I wanted to try to implement it directly in ahk.
For the connection I'm using GeekDude's socket library.

Edit: I didn't post this in the gaming help because I think it doesn't have to do with automating the game but rather how to create the packet and deal with the protocol itself and I thought it'd get better reception in the general ask for help forum.
image.png
image.png (15.11 KiB) Viewed 530 times

Code: Select all

#NoEnv
;#Warn
#SingleInstance Force
SetBatchLines, -1
;packet = b'\x00\x00' + bytes([len(host)]) + host.encode('utf-8') + bytes([port]) + b'\x01'
;sock.send(b'\x00' + bytes([len(packet)]) + packet)

;# Send handshake + status request
;self._send_data(connection, b'\x00\x00', self._host, self._port, b'\x01')
;self._send_data(connection, b'\x00')

global myTcp := new SocketTCP()
myTcp.connect(["mc.hypixel.net", 25565])
myTcp.onRecv := Func("OnTcpRecv")

; Define the packet structure (assuming the packet ID is 0x00)
packetID := 0x00
protocolVersion := 47 ; Replace with the desired protocol version
serverAddress := "mc.hypixel.net"
serverPort := 25565
nextState := 0x01

; Create a binary buffer to hold the packet
bufferSize := 1 + StrLen(serverAddress) + 2 + 4 + 2
bfr := BufferAlloc(bufferSize)

; Use NumPut to set values in the buffer
NumPut(packetID, bfr.ptr, 0, "UChar") ; Set packet ID

; Set protocol version
NumPut(protocolVersion, bfr.ptr, 1, "Int")

; Set server address
StrPut(serverAddress, bfr.ptr + 3, "UTF-8")
serverAddressLength := StrLen(serverAddress)
NumPut(serverAddressLength, bfr.ptr + 1, 1, "UShort")

; Set server port
NumPut(serverPort, bfr.ptr + 3 + serverAddressLength, "UShort")

; Set next state
NumPut(0x01, bfr.ptr, 1, "UShort") ; Should be 1 for status, but could also be 2 for login.

; Print the binary buffer
MsgBox % BinaryToString(bfr.ptr, bufferSize)

myTcp.Send(&bfr, bufferSize)

; Free the allocated buffer
BufferFree(bfr)

; Send Status Request
NumPut(packetID, bfr.ptr, 0, "UChar") ; Set packet ID
myTcp.Send(&bfr, 1)
Return

OnTcpRecv(this)
{
    MsgRecibido := this.RecvText()
    MsgBox, %MsgRecibido%
}

; BufferAlloc function to allocate memory for a buffer
BufferAlloc(size) {
    hGlobal := DllCall("GlobalAlloc", UInt, 0x40, UInt, size)
    if (hGlobal == 0)
        return 0
    
    return { ptr: DllCall("GlobalLock", UInt, hGlobal), size: size, hGlobal: hGlobal }
}

; BufferFree function to free the allocated memory for a buffer
BufferFree(buffer) {
    if (buffer.ptr != 0) {
        DllCall("GlobalUnlock", UInt, buffer.hGlobal)
        DllCall("GlobalFree", UInt, buffer.hGlobal)
    }
}

; BinaryToString function to convert a binary buffer to a string
BinaryToString(ptr, size) {
    VarSetCapacity(buffer, size)
    DllCall("RtlMoveMemory", "Str", &buffer, "Ptr", ptr, "UInt", size)
    return StrGet(&buffer, size, "UTF-8")
}

StrPutVar(string, ByRef var, encoding)
{
    ; Ensure capacity.
    VarSetCapacity( var, StrPut(string, encoding)
        ; StrPut returns char count, but VarSetCapacity needs bytes.
        * ((encoding="utf-16"||encoding="cp1200") ? 2 : 1) )
    ; Copy or convert the string.
    return StrPut(string, &var, encoding)
}

[Mod action: Topic moved to the "Gaming" section. Please post in the appropriate sub-forum.]

Return to “Gaming Help (v1)”