From 6319f6166e35962763e377ced0bf9f5f35363fa0 Mon Sep 17 00:00:00 2001 From: Marco Cawthorne Date: Wed, 21 Feb 2024 21:08:57 -0800 Subject: [PATCH] Skill.qc: readcmd() builtin usage replaced with a tiny config parser. Context: localcmd/stuffcmd are delayed enough that we can't use it to load difficulty settings from skill.cfg before the game objects have spawned. readcmd worked around this, but its usage is buggy and discouraged. loading config files from the root game directory is forbidden by the engine for security reasons (being able to read passwords etc.) but we're allowed to do so from sub-directories. by emulating the source engine behaviour we become compatible with their convention, while also working around said incompatibility. --- src/server/skill.h | 3 +++ src/server/skill.qc | 41 ++++++++++++++++++++++++++++++++++------- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/server/skill.h b/src/server/skill.h index c8a450f0..5d6d8b46 100644 --- a/src/server/skill.h +++ b/src/server/skill.h @@ -16,4 +16,7 @@ */ void Skill_Init(void); + +/** Return a skill variable's value or return a defaultvalue if it's undefined. */ float Skill_GetValue(string, float); +bool Skill_ParseConfig(string fileName); \ No newline at end of file diff --git a/src/server/skill.qc b/src/server/skill.qc index ca2d66c3..8f05d784 100644 --- a/src/server/skill.qc +++ b/src/server/skill.qc @@ -27,21 +27,19 @@ This will almost always result in them using default values, or (worst case) 0. void Skill_Init(void) { - /* sometimes we have extra overrides that the original does not - provide. so we execute our mod-specific config here */ - readcmd(sprintf("exec skill_%s.cfg\n", cvar_string("game"))); - readcmd(sprintf("exec maps/%s_skl.cfg\n", mapname)); + Skill_ParseConfig("cfg/skill_manifest.cfg"); + Skill_ParseConfig(sprintf("maps/%s_skl.cfg", mapname)); } /* ================= Skill_GetValue -Return a skill variable's value or return a defaultvalue if it's undefined. +Return a skill variable's value or return a defaultValue if it's undefined. ================= */ float -Skill_GetValue(string variable, float defaultvalue) +Skill_GetValue(string variable, float defaultValue) { float skill = cvar("skill"); @@ -49,7 +47,7 @@ Skill_GetValue(string variable, float defaultvalue) skill = 2; /* default to medium */ float val = fabs(cvar(sprintf("sk_%s%d", variable, skill))); - return (val == 0) ? defaultvalue : val; + return (val == 0) ? defaultValue : val; } /* input string is potentially a skill variable */ @@ -61,4 +59,33 @@ Skill_GetDefValue(string variable) } return stof(variable); +} + +bool +Skill_ParseConfig(string fileName) +{ + string tempString; + filestream configFile = fopen(fileName, FILE_READ); + + if (configFile < 0) { + print(sprintf("^1Warning: Unable to exec %S for parsing.\n", fileName)); + return (false); + } + + while ((tempString = fgets(configFile))) { + int argCount = (int)tokenize_console(tempString); + string firstArg = argv(0); + + if (argCount == 2i) { + if (firstArg == "exec") { + Skill_ParseConfig(sprintf("cfg/%s", argv(1))); + } + } else if (argCount == 3i) { + if (firstArg == "set" || firstArg == "seta") + cvar_set(argv(1), argv(2)); + } + } + + fclose(configFile); + return (true); } \ No newline at end of file