summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVon Random <von@mechanus.net>2021-02-07 05:40:59 +0300
committerVon Random <von@mechanus.net>2021-02-07 05:40:59 +0300
commit28b5bebc406f6f79ea0ff99f83d18b6ce14db8f2 (patch)
treed2fbc400d49c2e2835e873ede9e9f0a89078379b
parent62ff5d45c7159fa1daf670245970863874f6b3a9 (diff)
vq3srv: initial commit
-rw-r--r--LICENSE2
-rwxr-xr-xvq3srv111
2 files changed, 112 insertions, 1 deletions
diff --git a/LICENSE b/LICENSE
index 204b93d..57ce3a8 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-MIT License Copyright (c) <year> <copyright holders>
+MIT License Copyright (c) 2021 Von Random
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/vq3srv b/vq3srv
new file mode 100755
index 0000000..0b4f149
--- /dev/null
+++ b/vq3srv
@@ -0,0 +1,111 @@
+#!/usr/bin/env python3
+from argparse import ArgumentParser
+from os import system
+from random import shuffle
+from sys import exit
+
+# TODO: move this shit to a yaml config somewhere in /etc
+USER = 'quake3' # linux user, for sudo -u
+BIN = '/usr/bin/q3ded'
+CONF = '/srv/q3/.q3a/baseq3/autoexec.cfg'
+PARAM = '+exec autoexec.cfg'
+
+MAPLISTS = {
+ 'ffa': [
+ 'q3dm2', 'q3dm3', 'q3dm4', 'q3dm5', 'q3dm6',
+ 'q3dm7', 'q3dm8', 'q3dm9', 'q3dm10', 'q3dm11'
+ ],
+ 'duel': [
+ 'q3dm1', 'q3dm2', 'pro-q3dm6', 'pro-q3dm13',
+ 'q3tourney1', 'q3tourney3', 'q3tourney5', 'q3tourney6',
+ 'pro-q3tourney2', 'pro-q3tourney4'
+ ],
+ 'ctf': list()
+}
+BOTS = {
+ 'level': '3',
+ 'names': [
+ 'Anarki', 'Angel', 'Crash', 'Doom', 'Hunter',
+ 'Klesk', 'Major', 'Mynx', 'Orbb', 'Slash', 'Xaero'
+ ]
+}
+
+
+# these are saved to the q3config_server.cfg on the first run
+# no point in keeping them here afterwards
+BOOTSTRAP_OPTS = dict()
+# BOOTSTRAP_OPTS = {
+# 'sv_pure': '0', # enable client side mods, like better fonts or graphics
+# 'sv_maxclients': '8',
+# 'sv_hostname': 'myhost.tld'
+#
+# # this will let your server send maps to clients
+# # the downloads are attempted from http://%sv_dlURL%/baseq3/mapname.pk3
+# # note the protocol - no support for https,
+# # as well as the need to have baseq3 as a part of the path
+# # note that clients have to seta cl_allowDownload 1 for that to work
+# 'sv_dlURL': 'anyhost.tld/q3',
+# 'sv_allowDownloads': '1'
+# }
+
+
+def parse_arguments():
+ desc = 'host a q3 server'
+ parser = ArgumentParser(description=desc)
+ parser.add_argument('-m', '--gamemode', default='ffa')
+ parser.add_argument('-f', '--fraglimit', type=int, default=15)
+ parser.add_argument('-t', '--timelimit', type=int, default=10)
+ parser.add_argument('-b', '--bots', type=int, default=0)
+ return parser.parse_args()
+
+
+def gen_confline(param, value):
+ return 'seta {} "{}"\n'.format(param, value)
+
+
+def gen_maplist(maplist):
+ shuffle(maplist)
+ num = 1
+ stmpl = 'set d{} "map {} ; set nextmap vstr d{}"\n'
+ script = str()
+ while maplist:
+ nextnum = 1 if len(maplist) == 1 else num + 1
+ script += stmpl.format(num, maplist.pop(), nextnum)
+ num += 1
+ script += 'vstr d1\n'
+ return script
+
+
+def gen_addbots(count, level='3', names=list()):
+ shuffle(names)
+ btmpl = 'addbot {} {}\n'
+ script = str()
+ for bot in names[:count]:
+ script += btmpl.format(bot, level)
+ return script
+
+
+def main():
+ args = parse_arguments()
+ cfg_data = str()
+ try:
+ assert args.gamemode in MAPLISTS
+ except AssertionError:
+ exit('Wrong game mode specified!')
+
+ for param in BOOTSTRAP_OPTS:
+ cfg_data += gen_confline(param, BOOTSTRAP_OPTS[param])
+ cfg_data += gen_confline('fraglimit', args.fraglimit)
+ cfg_data += gen_confline('timelimit', args.timelimit)
+ # this should be last since it launches the actual maplist
+ cfg_data += gen_maplist(MAPLISTS[args.gamemode])
+ if args.bots:
+ cfg_data += gen_addbots(args.bots, **BOTS)
+
+ with open(CONF, 'w+') as config:
+ config.write(cfg_data)
+ system('sudo -u {} {} {}'.format(USER, BIN, PARAM))
+
+
+if __name__ == '__main__':
+ main()