Skip to content

Instantly share code, notes, and snippets.

@krzys-h
Last active February 16, 2019 13:32
Show Gist options
  • Save krzys-h/ce3f6e123058e9da9c46ac31e434a30a to your computer and use it in GitHub Desktop.
Save krzys-h/ce3f6e123058e9da9c46ac31e434a30a to your computer and use it in GitHub Desktop.
GameMaker: Studio 1.4 socket protocol
import socketserver
import struct
class GameMakerTCPHandler(socketserver.StreamRequestHandler):
def handle(self):
print("{} trying to connect".format(self.client_address[0]))
self.wfile.write(b"GM:Studio-Connect\0")
r = struct.unpack('IIII', self.rfile.read(16))
if r[0] != 0xcafebabe or r[1] != 0xdeadb00b or r[2] != 16:
raise Exception("Not a GameMaker client")
self.wfile.write(struct.pack('III', 0xdeafbead, 0xf00dbeeb, 12))
print("{} connected ({})".format(self.client_address[0], r[3]))
self.handle_gamemaker()
print("{} disconnected".format(self.client_address[0]))
def handle_gamemaker(self):
raise NotImplementedError("Override this method in your own class")
def send_packet(self, data):
self.wfile.write(struct.pack('III', 0xdeadc0de, 12, len(data)) + data)
def recv_packet(self):
hdrdata = self.rfile.read(12)
if not hdrdata:
return None
header = struct.unpack('III', hdrdata)
if header[0] != 0xdeadc0de or header[1] != 12:
raise Exception("Invalid packet")
return self.rfile.read(header[2])
class MyGameMakerServer(GameMakerTCPHandler):
def handle_gamemaker(self):
while True:
data = self.recv_packet()
if not data:
break
print("{} wrote: {}".format(self.client_address[0], data))
self.send_packet(data)
class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
pass
if __name__ == "__main__":
print("Server starting")
server = ThreadedTCPServer(("127.0.0.1", 6510), MyGameMakerServer)
server.serve_forever()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment