1 changed files with 111 additions and 0 deletions
@ -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() |
Loading…
Reference in new issue