vq3srv, config.example.yml: massive refactor, better defaults handling
This commit is contained in:
parent
582dc79ac7
commit
168011bd5a
2 changed files with 90 additions and 49 deletions
|
@ -2,14 +2,20 @@ user: quake3
|
||||||
cmd: /opt/ioquake3/ioq3ded.x86_64
|
cmd: /opt/ioquake3/ioq3ded.x86_64
|
||||||
exec: /home/quake3/.q3a/baseq3/autoexec.cfg
|
exec: /home/quake3/.q3a/baseq3/autoexec.cfg
|
||||||
gamemodes:
|
gamemodes:
|
||||||
ffa:
|
# names just identifiers, feel free to mix
|
||||||
|
# map types as you see fit
|
||||||
|
default:
|
||||||
|
# the only required option here is maps,
|
||||||
|
# everything else is optional
|
||||||
maps: [
|
maps: [
|
||||||
q3dm2, q3dm3, q3dm4, q3dm5, q3dm6,
|
q3dm2, q3dm3, q3dm4, q3dm5, q3dm6,
|
||||||
q3dm7, q3dm8, q3dm9, q3dm10, q3dm11
|
q3dm7, q3dm8, q3dm9, q3dm10, q3dm11
|
||||||
]
|
]
|
||||||
|
# any supported var can be set from here
|
||||||
|
# vars is optional, defaults to these:
|
||||||
vars:
|
vars:
|
||||||
fraglimit: 30
|
fraglimit: 15
|
||||||
timelimit: 15
|
timelimit: 5
|
||||||
duel:
|
duel:
|
||||||
maps: [
|
maps: [
|
||||||
q3dm1, q3dm2, pro-q3dm6, pro-q3dm13,
|
q3dm1, q3dm2, pro-q3dm6, pro-q3dm13,
|
||||||
|
@ -22,12 +28,14 @@ gamemodes:
|
||||||
cpma_duel:
|
cpma_duel:
|
||||||
maps: [ q3dm6 ]
|
maps: [ q3dm6 ]
|
||||||
vars:
|
vars:
|
||||||
sv_game: cpma
|
# mods can be used as well
|
||||||
|
fs_game: cpma
|
||||||
fraglimit: 15
|
fraglimit: 15
|
||||||
timelimit: 15
|
timelimit: 15
|
||||||
bots:
|
# defining bots here is optional, defaults
|
||||||
level: '3'
|
# are already defined in the script
|
||||||
names: [
|
bot_level: 3
|
||||||
|
bot_names: [
|
||||||
anarki, angel, crash, doom, hunter,
|
anarki, angel, crash, doom, hunter,
|
||||||
klesk, major, mynx, orbb, slash, xaero
|
klesk, major, mynx, orbb, slash, xaero
|
||||||
]
|
]
|
||||||
|
|
111
vq3srv
111
vq3srv
|
@ -7,15 +7,30 @@ from sys import exit
|
||||||
from yaml import safe_load
|
from yaml import safe_load
|
||||||
|
|
||||||
|
|
||||||
|
GDEFAULTS = {
|
||||||
|
'bots': {
|
||||||
|
'level': 3,
|
||||||
|
'names': ['anarki', 'angel', 'crash', 'doom', 'hunter',
|
||||||
|
'klesk', 'major', 'mynx', 'orbb', 'slash', 'xaero']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MDEFAULTS = {
|
||||||
|
'randomize': True,
|
||||||
|
'vars': {
|
||||||
|
'fraglimit': 30,
|
||||||
|
'timelimit': 15
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def parse_arguments():
|
def parse_arguments():
|
||||||
desc = 'host a q3 server'
|
desc = 'host a q3 server'
|
||||||
parser = ArgumentParser(description=desc)
|
parser = ArgumentParser(description=desc)
|
||||||
parser.add_argument('-m', '--gamemode', default='ffa')
|
parser.add_argument('-m', '--gamemode', default='default')
|
||||||
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('-b', '--bots', type=int, default=0)
|
||||||
parser.add_argument('-c', '--config', default='config.yml')
|
parser.add_argument('-c', '--config', default='config.yml')
|
||||||
parser.add_argument('-B', '--bootstrap')
|
parser.add_argument('-B', '--bootstrap')
|
||||||
|
parser.add_argument('-d', '--debug', action="store_true")
|
||||||
return parser.parse_args()
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,11 +39,12 @@ def gen_confline(param, value, archive=False):
|
||||||
return '{} {} "{}"\n'.format(set_cmd, param, value)
|
return '{} {} "{}"\n'.format(set_cmd, param, value)
|
||||||
|
|
||||||
|
|
||||||
def gen_maplist(maplist):
|
def gen_maplist(maplist, randomize=True):
|
||||||
shuffle(maplist)
|
|
||||||
num = 1
|
num = 1
|
||||||
stmpl = 'set d{} "map {} ; set nextmap vstr d{}"\n'
|
stmpl = 'set d{} "map {} ; set nextmap vstr d{}"\n'
|
||||||
script = str()
|
script = str()
|
||||||
|
if randomize:
|
||||||
|
shuffle(maplist)
|
||||||
while maplist:
|
while maplist:
|
||||||
nextnum = 1 if len(maplist) == 1 else num + 1
|
nextnum = 1 if len(maplist) == 1 else num + 1
|
||||||
script += stmpl.format(num, maplist.pop(), nextnum)
|
script += stmpl.format(num, maplist.pop(), nextnum)
|
||||||
|
@ -37,50 +53,67 @@ def gen_maplist(maplist):
|
||||||
return script
|
return script
|
||||||
|
|
||||||
|
|
||||||
def gen_addbots(count, level='3', names=list()):
|
def gen_addbots(count, level, names):
|
||||||
shuffle(names)
|
|
||||||
btmpl = 'addbot {} {}\n'
|
btmpl = 'addbot {} {}\n'
|
||||||
script = str()
|
script = str()
|
||||||
|
shuffle(names)
|
||||||
for bot in names[:count]:
|
for bot in names[:count]:
|
||||||
script += btmpl.format(bot, level)
|
script += btmpl.format(bot, level)
|
||||||
return script
|
return script
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def gen_exec(gcfg, mcfg, bvars=dict(), bot_count=0, debug=False):
|
||||||
args = parse_arguments()
|
cfg_data = str()
|
||||||
cfg_data, cmd_vars, bvars, svars = str(), list(), dict(), dict()
|
|
||||||
try:
|
|
||||||
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 in cfg['gamemodes']
|
|
||||||
exec_filename = basename(cfg['exec'])
|
|
||||||
except FileNotFoundError as error:
|
|
||||||
exit('Config `{}` not found!'.format(error.filename))
|
|
||||||
except AssertionError:
|
|
||||||
exit('Wrong game mode `{}` specified!'.format(args.gamemode))
|
|
||||||
|
|
||||||
smaps = cfg['gamemodes'][args.gamemode]['maps']
|
|
||||||
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:
|
for param in bvars:
|
||||||
cfg_data += gen_confline(param, bvars[param], archive=True)
|
cfg_data += gen_confline(param, bvars[param], archive=True)
|
||||||
for param in svars:
|
cfg_data += gen_maplist(mcfg['maps'],
|
||||||
cmd_vars.append('+set {} {}'.format(param, svars[param]))
|
mcfg.get('randomize', MDEFAULTS['randomize']))
|
||||||
cmd_vars.append('+exec {}'.format(exec_filename))
|
if bot_count:
|
||||||
cmd_opts = ' '.join(cmd_vars)
|
bot_level = gcfg.\
|
||||||
cfg_data += gen_maplist(smaps)
|
get('bots', GDEFAULTS['bots']).\
|
||||||
if args.bots:
|
get('level', GDEFAULTS['bots']['level'])
|
||||||
cfg_data += gen_addbots(args.bots, **cfg['bots'])
|
bot_names = gcfg.\
|
||||||
|
get('bots', GDEFAULTS['bots']).\
|
||||||
with open(cfg['exec'], 'w+') as config:
|
get('names', GDEFAULTS['bots']['names'])
|
||||||
|
cfg_data += gen_addbots(bot_count, bot_level, bot_names)
|
||||||
|
if debug:
|
||||||
|
print('Debug {} contents:\n{}'.format(gcfg['exec'], cfg_data))
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
with open(gcfg['exec'], 'w+') as config:
|
||||||
config.write(cfg_data)
|
config.write(cfg_data)
|
||||||
system('sudo -u {} {} {}'.format(cfg['user'], cfg['cmd'], cmd_opts))
|
except FileNotFoundError as error:
|
||||||
|
exit('Config `{}` not found!'.format(error.filename))
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
args = parse_arguments()
|
||||||
|
cfg_data, cmd_list, bvars = str(), list(), dict()
|
||||||
|
try:
|
||||||
|
with open(args.config, 'r') as config_file:
|
||||||
|
gcfg = safe_load(config_file)
|
||||||
|
assert {'user', 'exec', 'cmd'} <= gcfg.keys()
|
||||||
|
mcfg = gcfg['gamemodes'][args.gamemode]
|
||||||
|
assert 'maps' in mcfg
|
||||||
|
if args.bootstrap:
|
||||||
|
with open(args.bootstrap, 'r') as bootstrap_file:
|
||||||
|
bvars = safe_load(bootstrap_file)
|
||||||
|
except FileNotFoundError as error:
|
||||||
|
exit('Config `{}` not found!'.format(error.filename))
|
||||||
|
except (AssertionError, KeyError):
|
||||||
|
exit('Missing required settings in {}!'.format(args.config))
|
||||||
|
|
||||||
|
svars = mcfg.get('vars', MDEFAULTS['vars'])
|
||||||
|
exec_filename = basename(gcfg['exec'])
|
||||||
|
|
||||||
|
for param in svars:
|
||||||
|
cmd_list.append('+set {} {}'.format(param, svars[param]))
|
||||||
|
cmd_list.append('+exec {}'.format(exec_filename))
|
||||||
|
cmd_opts = ' '.join(cmd_list)
|
||||||
|
|
||||||
|
action = print if args.debug else system
|
||||||
|
gen_exec(gcfg, mcfg, bvars, args.bots, args.debug)
|
||||||
|
action('sudo -u {} {} {}'.format(gcfg['user'], gcfg['cmd'], cmd_opts))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
Loading…
Reference in a new issue