summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVon Random <von@mechanus.net>2021-02-07 18:37:53 +0300
committerVon Random <von@mechanus.net>2021-02-07 18:37:53 +0300
commit3e8932a4f2e9a243b45223581a3546625a27dd6d (patch)
treec49c42fc70e5aec9b355aa7525c10db9329cc8cd
parent28b5bebc406f6f79ea0ff99f83d18b6ce14db8f2 (diff)
vq3srv: remade to support a config; other: initial commt, some housekeeping
-rw-r--r--.gitignore3
-rw-r--r--bootstrap.example.yml14
-rw-r--r--config.example.yml31
-rwxr-xr-xvq3srv96
4 files changed, 83 insertions, 61 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1efc1fe
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+.vscode
+config.yml
+bootstrap.yml \ No newline at end of file
diff --git a/bootstrap.example.yml b/bootstrap.example.yml
new file mode 100644
index 0000000..5a87522
--- /dev/null
+++ b/bootstrap.example.yml
@@ -0,0 +1,14 @@
+# these are saved to the q3config_server.cfg, so -B should only be used once really
+# add any config variable with value here as needed,
+# defaults are mostly sensible, so here is a rather small list
+sv_pure: '0'
+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' \ No newline at end of file
diff --git a/config.example.yml b/config.example.yml
new file mode 100644
index 0000000..0b82330
--- /dev/null
+++ b/config.example.yml
@@ -0,0 +1,31 @@
+user: quake3
+cmd: /opt/ioquake3/ioq3ded.x86_64 +exec autoexec.cfg
+autoexec: /home/quake3/.q3a/baseq3/autoexec.cfg
+gamemodes:
+ any:
+ vars:
+ fraglimit: 100
+ timelimit: 10
+ ffa:
+ maps: [
+ q3dm2, q3dm3, q3dm4, q3dm5, q3dm6,
+ q3dm7, q3dm8, q3dm9, q3dm10, q3dm11
+ ]
+ vars:
+ fraglimit: 30
+ timelimit: 15
+ duel:
+ maps: [
+ q3dm1, q3dm2, pro-q3dm6, pro-q3dm13,
+ q3tourney1, q3tourney3, q3tourney5, q3tourney6,
+ pro-q3tourney2, pro-q3tourney4
+ ]
+ vars:
+ fraglimit: 15
+ timelimit: 5
+bots:
+ level: '3'
+ names: [
+ anarki, angel, crash, doom, hunter,
+ klesk, major, mynx, orbb, slash, xaero
+ ] \ No newline at end of file
diff --git a/vq3srv b/vq3srv
index 0b4f149..aea9a25 100755
--- a/vq3srv
+++ b/vq3srv
@@ -3,64 +3,24 @@ 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'
-# }
+from yaml import safe_load
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('-f', '--fraglimit', type=int)
+ parser.add_argument('-t', '--timelimit', type=int)
parser.add_argument('-b', '--bots', type=int, default=0)
+ parser.add_argument('-c', '--config', default='config.yml')
+ parser.add_argument('-B', '--bootstrap')
return parser.parse_args()
-def gen_confline(param, value):
- return 'seta {} "{}"\n'.format(param, value)
+def gen_confline(param, value, archive=False):
+ set_cmd = 'seta' if archive else 'set'
+ return '{} {} "{}"\n'.format(set_cmd, param, value)
def gen_maplist(maplist):
@@ -87,24 +47,38 @@ def gen_addbots(count, level='3', names=list()):
def main():
args = parse_arguments()
- cfg_data = str()
+ cfg_data, bvars, svars = str(), dict(), dict()
try:
- assert args.gamemode in MAPLISTS
+ with open(args.config, 'r') as config_file:
+ cfg = safe_load(config_file)
+ if args.bootstrap:
+ with open(args.bootstrap, 'r') as bootstrap_file:
+ bvars.update(safe_load(bootstrap_file))
+ assert args.gamemode != 'any' and args.gamemode in cfg['gamemodes']
+ except FileNotFoundError as error:
+ exit('Config `{}` not found!'.format(error.filename))
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])
+ exit('Wrong game mode `{}` specified!'.format(args.gamemode))
+
+ smaps = cfg['gamemodes'][args.gamemode]['maps']
+ svars.update(cfg['gamemodes']['any']['vars'])
+ svars.update(cfg['gamemodes'][args.gamemode]['vars'])
+ if args.fraglimit:
+ svars.update({'fraglimit': args.fraglimit})
+ if args.timelimit:
+ svars.update({'timelimit': args.timelimit})
+
+ for param in bvars:
+ cfg_data += gen_confline(param, bvars[param], archive=True)
+ for param in svars:
+ cfg_data += gen_confline(param, svars[param])
+ cfg_data += gen_maplist(smaps)
if args.bots:
- cfg_data += gen_addbots(args.bots, **BOTS)
+ cfg_data += gen_addbots(args.bots, **cfg['bots'])
- with open(CONF, 'w+') as config:
+ with open(cfg['autoexec'], 'w+') as config:
config.write(cfg_data)
- system('sudo -u {} {} {}'.format(USER, BIN, PARAM))
+ system('sudo -u {} {}'.format(cfg['user'], cfg['cmd']))
if __name__ == '__main__':