Python library, emulator of Quake 3 connection
Live demo: @qv3k_bot - q3 client with telegram bot interface
- Python 3.5+
- q3huff2 (clone of the q3huff library without the memory leak fix)
- Stable quake3 connection (vanilla, osp, e+, a bit of cpma)
- Connected and connection-less communication with a server
- Protocols 68 and 71
- Supports sv_pure 1
- Supports proxy connection (qwfwd)
- Player customization
- Other stuff
Q3net library is available in the PyPi repository
python -m pip install q3net
Then just include it into your project
import q3net
You can also copy q3net manually to your project or add it as a git submodule
cd <your project>
git submodule add https://github.com/JKornev/q3net.git q3net
git add .
git commit -m "q3net included to a project"
python -m pip install q3huff2
Query information from the server without opening a full game connection
import q3net
# query server info and status
connection = q3net.connection("localhost", 27960)
print(connection.request(q3net.get_info_request()).data)
print(connection.request(q3net.get_status_request()).data)
connection.terminate()
Open a connection with the server
import q3net
# open a connection with a server
connection = q3net.connection("localhost", 27960)
connection.connect()
# welcome other players
connection.request(q3net.say_request("hi!"))
connection.disconnect()
# gracefully destroy connection object
connection.terminate()
Keep in mind when you create a q3net.connection
object it internally creates a separated worker thread. Therefore to avoid app freezes and thread leaks you need to terminate each q3net.connection
object by calling method q3net.connection.terminate()
in the end.
Another example shows handling connection events
import q3net, time
class handler(q3net.events_handler):
def event_connected(self, gamestate, host, port, server_id):
print(f"Connected to {host}:{port} id:{srv_id}")
def event_disconnected(self, gamestate, reason):
print(f"Disconnected, reason : {reason}")
def event_packet(self, gamestate, packet):
pass # frequent event, no need spam
def event_command(self, gamestate, sequence, command):
print(f"Command {sequence} : {command}")
def event_configstring(self, gamestate, index, value):
print(f"ConfigString {index} : {value}")
connection = q3net.connection("localhost", 27960, handler=handler())
connection.connect()
time.sleep(5.0) # give it work a bit
connection.disconnect()
connection.terminate()
q3net.events_handler
class handles connection events from different thread (connection worker) therefore you have to worry about syncronization if you want to communicate with a main thread that opened a connection.
Other more detailed examples in \examples folder:
- client.py - simple command-line quake3 client
- master_server.py - query information from quake3 master-server
- proxy.py - an example of using QWFWD proxy
- server_info.py - get server info using connection-less requests