cvar_t prvm_garbagecollection_scan_limit = {CF_CLIENT | CF_SERVER, "prvm_garbagecollection_scan_limit", "50000", "scan this many fields or resources per second to free up unreferenced resources"};
cvar_t prvm_garbagecollection_strings = {CF_CLIENT | CF_SERVER, "prvm_garbagecollection_strings", "1", "automatically call strunzone() on strings that are not referenced"};
cvar_t prvm_stringdebug = {CF_CLIENT | CF_SERVER, "prvm_stringdebug", "0", "Print debug and warning messages related to strings"};
+cvar_t sv_entfields_noescapes = {CF_SERVER, "sv_entfields_noescapes", "wad", "Space-separated list of fields in which backslashes won't be parsed as escapes when loading entities from .bsp or .ent files. This is a workaround for buggy maps with unescaped backslashes used as path separators (only forward slashes are allowed in Quake VFS paths)."};
static double prvm_reuseedicts_always_allow = 0;
qbool prvm_runawaycheck = true;
{
mdef_t *key;
qbool anglehack;
- qbool init;
+ qbool init = false;
+ qbool parsebackslash = true;
char keyname[256];
size_t n;
- init = false;
-
// go through all the dictionary pairs
while (1)
{
if (!strcmp(com_token, "light"))
dp_strlcpy (com_token, "light_lev", sizeof(com_token)); // hack for single light def
- dp_strlcpy (keyname, com_token, sizeof(keyname));
+ n = dp_strlcpy (keyname, com_token, sizeof(keyname));
// another hack to fix keynames with trailing spaces
- n = strlen(keyname);
while (n && keyname[n-1] == ' ')
{
keyname[n-1] = 0;
n--;
}
+ // Check if escape parsing is disabled for this key (see cvar description).
+ // Escapes are always used in savegames and DP_QC_ENTITYSTRING for compatibility.
+ if (!saveload)
+ {
+ const char *cvarpos = sv_entfields_noescapes.string;
+
+ while (COM_ParseToken_Console(&cvarpos))
+ {
+ if (strcmp(com_token, keyname) == 0)
+ {
+ parsebackslash = false;
+ break;
+ }
+ }
+ }
+
// parse value
// If loading a save, unescape characters (they're escaped when saving).
// Otherwise, load them as they are (BSP compilers don't support escaping).
- if (!COM_ParseToken_Simple(&data, false, saveload, true))
+ if (!COM_ParseToken_Simple(&data, false, parsebackslash, true))
prog->error_cmd("PRVM_ED_ParseEdict: EOF without closing brace");
if (developer_entityparsing.integer)
Con_Printf(" \"%s\"\n", com_token);
prog->error_cmd("PRVM_ED_ParseEdict: parse error");
}
- if (!init) {
+ if (!init)
+ {
ent->free = true;
ent->freetime = host.realtime;
}
Cvar_RegisterVariable (&prvm_garbagecollection_scan_limit);
Cvar_RegisterVariable (&prvm_garbagecollection_strings);
Cvar_RegisterVariable (&prvm_stringdebug);
+ Cvar_RegisterVariable (&sv_entfields_noescapes);
// COMMANDLINEOPTION: PRVM: -norunaway disables the runaway loop check (it might be impossible to exit DarkPlaces if used!)
prvm_runawaycheck = !Sys_CheckParm("-norunaway");