98 lines
2.7 KiB
Python
98 lines
2.7 KiB
Python
"""Verify all the things that could go wrong."""
|
|
from copy import deepcopy
|
|
from tfscript import tftypes
|
|
|
|
def verifyConfig(cfg: dict) -> (dict, dict):
|
|
verifiedConfig = {}
|
|
|
|
# Do defaults first
|
|
errors = {}
|
|
|
|
defaults = []
|
|
|
|
classList = [
|
|
'default',
|
|
'scout',
|
|
'soldier',
|
|
'pyro',
|
|
('demo','demoman'),
|
|
('engi','engineer'),
|
|
('heavy','heavyweapons'),
|
|
'medic',
|
|
'sniper',
|
|
'spy'
|
|
]
|
|
|
|
for isclass, cclass in enumerate(classList):
|
|
|
|
classCFG = None
|
|
classBinds = []
|
|
className = cclass
|
|
|
|
if isinstance(cclass, str) and cclass in cfg:
|
|
classCFG = cfg.pop(cclass)
|
|
elif isinstance(cclass, tuple):
|
|
for tupClass in cclass:
|
|
if tupClass in cfg:
|
|
classCFG = cfg.pop(tupClass)
|
|
className = cclass[0]
|
|
break
|
|
if classCFG is None:
|
|
# Invalid class, this gets caught later.
|
|
# It may be less efficient this way, but
|
|
# it makes for more descriptive error messages
|
|
continue
|
|
|
|
errMessages = []
|
|
for key, data in classCFG.items():
|
|
bind = tftypes.bind(key, data)
|
|
|
|
bind = bind.toTargetType()
|
|
if isclass:
|
|
classBinds.append(bind)
|
|
else:
|
|
defaults.append(bind)
|
|
|
|
errMessages.extend(bind.errors)
|
|
|
|
if len(errMessages) > 0:
|
|
errors.update( {className: errMessages} )
|
|
|
|
verifiedConfig.update({className: classBinds})
|
|
|
|
# Turn list into only strings by expanding tuples
|
|
for i, cclass in enumerate(classList):
|
|
if isinstance(cclass, tuple):
|
|
classList.insert(i+1, cclass[1])
|
|
classList.insert(i+1, cclass[0])
|
|
classList.pop(i)
|
|
|
|
globalErrors = []
|
|
for remainingClass in cfg:
|
|
if remainingClass not in classList:
|
|
globalErrors.append(f'"{remainingClass}" is not a valid class')
|
|
else:
|
|
otherName = findTwin(remainingClass)
|
|
globalErrors.append(f'Conflicting names for section: "{remainingClass}" and "{otherName}"')
|
|
|
|
if len(globalErrors) > 0:
|
|
errors.update({'file': globalErrors})
|
|
|
|
if len(errors) > 0:
|
|
verifiedConfig.update({'errors': errors})
|
|
|
|
return verifiedConfig, defaults
|
|
|
|
def findTwin(className):
|
|
classDict = {
|
|
"demo": "demoman",
|
|
"engi": "engineer",
|
|
"heavy": "heavyweapons"
|
|
}
|
|
for className1, className2 in classDict.items():
|
|
if className == className1:
|
|
return className2
|
|
elif className == className2:
|
|
return className1
|
|
|
|
return None |