105 lines
2.9 KiB
Python
105 lines
2.9 KiB
Python
"""Verify all the things that could go wrong."""
|
|
|
|
from tfscript import tftypes
|
|
|
|
def verifyConfig(cfg: dict) -> (dict, dict):
|
|
verifiedConfig = {}
|
|
|
|
errors = {}
|
|
warnings = {}
|
|
|
|
# Do defaults first
|
|
defaults = []
|
|
|
|
classList = [
|
|
'default',
|
|
'scout',
|
|
'soldier',
|
|
'pyro',
|
|
('demo','demoman'),
|
|
('engi','engineer'),
|
|
('heavy','heavyweapons'),
|
|
'medic',
|
|
'sniper',
|
|
'spy'
|
|
]
|
|
|
|
for isclass, class_ in enumerate(classList):
|
|
|
|
classCFG = None
|
|
className = class_
|
|
|
|
if isinstance(class_, str) and class_ in cfg:
|
|
classCFG = cfg.pop(class_)
|
|
elif isinstance(class_, tuple):
|
|
for tupClass in class_:
|
|
if tupClass in cfg:
|
|
classCFG = cfg.pop(tupClass)
|
|
className = class_[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
|
|
|
|
classBinds = []
|
|
errMessages = []
|
|
warnMessages = []
|
|
for key, data in classCFG.items():
|
|
bind = tftypes.ScriptBind(key, data)
|
|
|
|
bind = bind.toTargetType()
|
|
if isclass:
|
|
classBinds.append(bind)
|
|
else:
|
|
defaults.append(bind)
|
|
|
|
errMessages.extend(bind.errors)
|
|
warnMessages.extend(bind.warnings)
|
|
|
|
if len(errMessages) > 0:
|
|
errors.update( {className: errMessages} )
|
|
if len(warnMessages) > 0:
|
|
warnings.update( {className: warnMessages} )
|
|
|
|
verifiedConfig.update({className: classBinds})
|
|
|
|
# Turn list into only strings by expanding tuples
|
|
for i, class_ in enumerate(classList):
|
|
if isinstance(class_, tuple):
|
|
classList.insert(i+1, class_[1])
|
|
classList.insert(i+1, class_[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})
|
|
if len(warnings) > 0:
|
|
verifiedConfig.update({'warnings': warnings})
|
|
|
|
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 |