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.Bind(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
|