X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fsv_main.qc;h=68e7b375b507a09051f3607114f60d14cd9da0f2;hb=b8b9d9d6006669f36c9c9a7387506242a2955904;hp=87430a93eff4502037e10c52e8dd511f820e1852;hpb=f6ab993e30f72501c7c1dc8833b65cb93f3af1fc;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/sv_main.qc b/qcsrc/server/sv_main.qc index 87430a93e..68e7b375b 100644 --- a/qcsrc/server/sv_main.qc +++ b/qcsrc/server/sv_main.qc @@ -247,6 +247,77 @@ void StartFrame() .string gametypefilter; .string cvarfilter; bool DoesQ3ARemoveThisEntity(entity this); + +/** + * Evaluate an expression of the form: [+ | -]? [var[op]val | [op]var | val | var] ... + * +: all must match. this is the default + * -: one must NOT match + * + * var>x + * var=x + * var<=x + * var==x + * var!=x + * var===x + * var!==x + */ +bool expr_evaluate(string s) +{ + bool ret = false; + if (str2chr(s, 0) == '+') { + s = substring(s, 1, -1); + } else if (str2chr(s, 0) == '-') { + ret = true; + s = substring(s, 1, -1); + } + bool expr_fail = false; + for (int i = 0, n = tokenize_console(s); i < n; ++i) { + int o; + string k, v; + s = argv(i); + #define X(expr) \ + if (expr) { \ + continue; \ + } else { \ + expr_fail = true; \ + break; \ + } + #define BINOP(op, len, expr) \ + if ((o = strstrofs(s, op, 0)) >= 0) { \ + k = substring(s, 0, o); \ + v = substring(s, o + len, -1); \ + X(expr); \ + } + BINOP(">=", 2, cvar(k) >= stof(v)); + BINOP("<=", 2, cvar(k) <= stof(v)); + BINOP(">", 1, cvar(k) > stof(v)); + BINOP("<", 1, cvar(k) < stof(v)); + BINOP("==", 2, cvar(k) == stof(v)); + BINOP("!=", 2, cvar(k) != stof(v)); + BINOP("===", 3, cvar_string(k) == v); + BINOP("!==", 3, cvar_string(k) != v); + { + k = s; + bool b = true; + if (str2chr(k, 0) == '!') { + k = substring(s, 1, -1); + b = false; + } + float f = stof(k); + bool isnum = ftos(f) == k; + X(boolean(isnum ? f : cvar(k)) == b); + } + #undef BINOP + #undef X + } + if (!expr_fail) { + ret = !ret; + } + // now ret is true if we want to keep the item, and false if we want to get rid of it + return ret; +} + void SV_OnEntityPreSpawnFunction(entity this) { __spawnfunc_expecting = true; @@ -257,65 +328,8 @@ void SV_OnEntityPreSpawnFunction(entity this) { goto cleanup; } - if (this.cvarfilter != "") { - bool inv = false; - - string s = this.cvarfilter; - if (str2chr(s, 0) == '+') { - s = substring(s, 1, -1); - } else if(str2chr(s, 0) == '-') { - inv = true; - s = substring(s, 1, -1); - } - - bool cvar_fail = false; - for (int i = 0, n = tokenize_console(s); i < n; ++i) { - int o; - string k, v; - s = argv(i); - // syntax: - // var>x - // var=x - // var<=x - // var==x - // var!=x - // var===x - // var!==x - #define X(expr) \ - if (expr) { \ - continue; \ - } else { \ - cvar_fail = true; \ - break; \ - } - #define BINOP(op, len, expr) \ - if ((o = strstrofs(s, op, 0)) >= 0) { \ - k = substring(s, 0, o); \ - v = substring(s, o + len, -1); \ - X(expr); \ - } - BINOP(">=", 2, cvar(k) >= stof(v)); - BINOP("<=", 2, cvar(k) <= stof(v)); - BINOP(">", 1, cvar(k) > stof(v)); - BINOP("<", 1, cvar(k) < stof(v)); - BINOP("==", 2, cvar(k) == stof(v)); - BINOP("!=", 2, cvar(k) != stof(v)); - // fixme: did these two ever work? - BINOP("===", 2, cvar_string(k) == v); - BINOP("!==", 2, cvar_string(k) != v); - if (str2chr(s, 0) == '!') { k = substring(s, 1, -1); X(!cvar(k)); } - { k = s; X(cvar(k)); } - #undef BINOP - #undef X - } - if (!cvar_fail) { - inv = !inv; - } - // now inv is true if we want to keep the item, and false if we want to get rid of it - if (!inv) { - goto cleanup; - } + if (this.cvarfilter != "" && !expr_evaluate(this.cvarfilter)) { + goto cleanup; } if (DoesQ3ARemoveThisEntity(this)) {