X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Frace.qc;h=c940afb94dc4af026a48549bf321fb9d14c32744;hb=c0add59c57c00b31e0db86871ad776ffacc9165e;hp=4190c208ed273d8cc82dc1e32667685bd5a75301;hpb=258867c634125e1d048869b4a5d8ef279e8b8228;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/race.qc b/qcsrc/server/race.qc index 4190c208e..c940afb94 100644 --- a/qcsrc/server/race.qc +++ b/qcsrc/server/race.qc @@ -1,39 +1,72 @@ #include "race.qh" -#include -#include -#include -#include -#include -#include "client.qh" -#include "cheats.qh" -#include "portals.qh" -#include "scores.qh" -#include "spawnpoints.qh" -#include "bot/api.qh" -#include "command/getreplies.qh" -#include "../common/deathtypes/all.qh" -#include "../common/notifications/all.qh" +#include #include #include +#include +#include +#include #include +#include #include -#include -#include "../common/mapobjects/subs.qh" -#include -#include "../lib/warpzone/util_server.qh" -#include "../lib/warpzone/common.qh" +#include #include -#include "../common/mutators/mutator/waypoints/waypointsprites.qh" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -IntrusiveList g_race_targets; -IntrusiveList g_racecheckpoints; -STATIC_INIT(g_race) +.string stored_netname; // TODO: store this information independently of race-based gamemodes + +string uid2name(string myuid) +{ + string s = db_get(ServerProgsDB, strcat("/uid2name/", myuid)); + + // FIXME remove this later after 0.6 release + // convert old style broken records to correct style + if(s == "") + { + s = db_get(ServerProgsDB, strcat("uid2name", myuid)); + if(s != "") + { + db_put(ServerProgsDB, strcat("/uid2name/", myuid), s); + db_remove(ServerProgsDB, strcat("uid2name", myuid)); + } + } + + if(s == "") + s = "^1Unregistered Player"; + return s; +} + +void write_recordmarker(entity pl, float tstart, float dt) { - g_race_targets = IL_NEW(); - g_racecheckpoints = IL_NEW(); + GameLogEcho(strcat(":recordset:", ftos(pl.playerid), ":", ftos(dt))); + + // also write a marker into demo files for demotc-race-record-extractor to find + stuffcmd(pl, + strcat( + strcat("//", strconv(2, 0, 0, GetGametype()), " RECORD SET ", TIME_ENCODED_TOSTRING(TIME_ENCODE(dt))), + " ", ftos(tstart), " ", ftos(dt), "\n")); } +IntrusiveList g_race_targets; +IntrusiveList g_racecheckpoints; + void race_InitSpectator() { if(g_race_qualifying) @@ -43,16 +76,12 @@ void race_InitSpectator() float race_readTime(string map, float pos) { - string rr = ((g_cts) ? CTS_RECORD : ((g_ctf) ? CTF_RECORD : RACE_RECORD)); - - return stof(db_get(ServerProgsDB, strcat(map, rr, "time", ftos(pos)))); + return stof(db_get(ServerProgsDB, strcat(map, record_type, "time", ftos(pos)))); } string race_readUID(string map, float pos) { - string rr = ((g_cts) ? CTS_RECORD : ((g_ctf) ? CTF_RECORD : RACE_RECORD)); - - return db_get(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(pos))); + return db_get(ServerProgsDB, strcat(map, record_type, "crypto_idfp", ftos(pos))); } float race_readPos(string map, float t) @@ -69,8 +98,6 @@ float race_readPos(string map, float t) void race_writeTime(string map, float t, string myuid) { - string rr = ((g_cts) ? CTS_RECORD : ((g_ctf) ? CTF_RECORD : RACE_RECORD)); - float newpos; newpos = race_readPos(map, t); @@ -85,8 +112,8 @@ void race_writeTime(string map, float t, string myuid) // player improved his existing record, only have to iterate on ranks between new and old recs for (i = prevpos; i > newpos; --i) { - db_put(ServerProgsDB, strcat(map, rr, "time", ftos(i)), ftos(race_readTime(map, i - 1))); - db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(i)), race_readUID(map, i - 1)); + db_put(ServerProgsDB, strcat(map, record_type, "time", ftos(i)), ftos(race_readTime(map, i - 1))); + db_put(ServerProgsDB, strcat(map, record_type, "crypto_idfp", ftos(i)), race_readUID(map, i - 1)); } } else @@ -96,22 +123,34 @@ void race_writeTime(string map, float t, string myuid) { float other_time = race_readTime(map, i - 1); if (other_time) { - db_put(ServerProgsDB, strcat(map, rr, "time", ftos(i)), ftos(other_time)); - db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(i)), race_readUID(map, i - 1)); + db_put(ServerProgsDB, strcat(map, record_type, "time", ftos(i)), ftos(other_time)); + db_put(ServerProgsDB, strcat(map, record_type, "crypto_idfp", ftos(i)), race_readUID(map, i - 1)); } } } // store new time itself - db_put(ServerProgsDB, strcat(map, rr, "time", ftos(newpos)), ftos(t)); - db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(newpos)), myuid); + db_put(ServerProgsDB, strcat(map, record_type, "time", ftos(newpos)), ftos(t)); + db_put(ServerProgsDB, strcat(map, record_type, "crypto_idfp", ftos(newpos)), myuid); } string race_readName(string map, float pos) { - string rr = ((g_cts) ? CTS_RECORD : ((g_ctf) ? CTF_RECORD : RACE_RECORD)); + return uid2name(db_get(ServerProgsDB, strcat(map, record_type, "crypto_idfp", ftos(pos)))); +} - return uid2name(db_get(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(pos)))); +void race_checkAndWriteName(entity player) +{ + if(CS_CVAR(player).cvar_cl_allow_uidtracking == 1 && CS_CVAR(player).cvar_cl_allow_uid2name == 1) + { + if (!player.stored_netname) + player.stored_netname = strzone(uid2name(player.crypto_idfp)); + if(player.stored_netname != player.netname) + { + db_put(ServerProgsDB, strcat("/uid2name/", player.crypto_idfp), player.netname); + strcpy(player.stored_netname, player.netname); + } + } } @@ -216,7 +255,6 @@ void race_send_recordtime(float msg) WriteInt24_t(msg, race_readTime(GetMapname(), 1)); } - void race_send_speedaward(float msg) { // send the best speed of the round @@ -243,7 +281,7 @@ void race_send_rankings_cnt(float msg) WriteByte(msg, m); } -void race_SendRankings(float pos, float prevpos, float del, float msg) +void race_SendRanking(float pos, float prevpos, float del, float msg) { WriteHeader(msg, TE_CSQC_RACE); WriteByte(msg, RACE_NET_SERVER_RANKINGS); @@ -254,6 +292,56 @@ void race_SendRankings(float pos, float prevpos, float del, float msg) WriteInt24_t(msg, race_readTime(GetMapname(), pos)); } +void race_SpeedAwardFrame(entity player) +{ + if (IS_OBSERVER(player)) + return; + + if(vdist(player.velocity - player.velocity_z * '0 0 1', >, speedaward_speed)) + { + speedaward_speed = vlen(player.velocity - player.velocity_z * '0 0 1'); + speedaward_holder = player.netname; + speedaward_uid = player.crypto_idfp; + speedaward_lastupdate = time; + } + if (speedaward_speed > speedaward_lastsent && (time - speedaward_lastupdate > 1 || intermission_running)) + { + race_send_speedaward(MSG_ALL); + speedaward_lastsent = speedaward_speed; + if (speedaward_speed > speedaward_alltimebest && speedaward_uid != "") + { + speedaward_alltimebest = speedaward_speed; + speedaward_alltimebest_holder = speedaward_holder; + speedaward_alltimebest_uid = speedaward_uid; + db_put(ServerProgsDB, strcat(GetMapname(), record_type, "speed/speed"), ftos(speedaward_alltimebest)); + db_put(ServerProgsDB, strcat(GetMapname(), record_type, "speed/crypto_idfp"), speedaward_alltimebest_uid); + race_send_speedaward_alltimebest(MSG_ALL); + } + } +} + +void race_SendAll(entity player, bool only_rankings) +{ + if(!IS_REAL_CLIENT(player)) + return; + + msg_entity = player; + if (!only_rankings) + { + race_send_recordtime(MSG_ONE); + race_send_speedaward(MSG_ONE); + + speedaward_alltimebest = stof(db_get(ServerProgsDB, strcat(GetMapname(), record_type, "speed/speed"))); + speedaward_alltimebest_holder = uid2name(db_get(ServerProgsDB, strcat(GetMapname(), record_type, "speed/crypto_idfp"))); + race_send_speedaward_alltimebest(MSG_ONE); + } + + int m = min(RANKINGS_CNT, autocvar_g_cts_send_rankings_cnt); + race_send_rankings_cnt(MSG_ONE); + for (int i = 1; i <= m; ++i) + race_SendRanking(i, 0, 0, MSG_ONE); +} + void race_SendStatus(float id, entity e) { if(!IS_REAL_CLIENT(e)) @@ -334,7 +422,7 @@ void race_setTime(string map, float t, string myuid, string mynetname, entity e, race_send_recordtime(MSG_ALL); } - race_SendRankings(newpos, player_prevpos, 0, MSG_ALL); + race_SendRanking(newpos, player_prevpos, 0, MSG_ALL); strcpy(rankings_reply, getrankings()); if(newpos == player_prevpos) @@ -362,24 +450,22 @@ void race_setTime(string map, float t, string myuid, string mynetname, entity e, void race_deleteTime(string map, float pos) { - string rr = ((g_cts) ? CTS_RECORD : ((g_ctf) ? CTF_RECORD : RACE_RECORD)); - for(int i = pos; i <= RANKINGS_CNT; ++i) { string therank = ftos(i); if (i == RANKINGS_CNT) { - db_remove(ServerProgsDB, strcat(map, rr, "time", therank)); - db_remove(ServerProgsDB, strcat(map, rr, "crypto_idfp", therank)); + db_remove(ServerProgsDB, strcat(map, record_type, "time", therank)); + db_remove(ServerProgsDB, strcat(map, record_type, "crypto_idfp", therank)); } else { - db_put(ServerProgsDB, strcat(map, rr, "time", therank), ftos(race_readTime(GetMapname(), i+1))); - db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", therank), race_readUID(GetMapname(), i+1)); + db_put(ServerProgsDB, strcat(map, record_type, "time", therank), ftos(race_readTime(GetMapname(), i+1))); + db_put(ServerProgsDB, strcat(map, record_type, "crypto_idfp", therank), race_readUID(GetMapname(), i+1)); } } - race_SendRankings(pos, 0, 1, MSG_ALL); + race_SendRanking(pos, 0, 1, MSG_ALL); if(pos == 1) race_send_recordtime(MSG_ALL); @@ -1000,12 +1086,18 @@ spawnfunc(trigger_race_checkpoint) this.sprite.waypointsprite_visible_for_player = race_waypointsprite_visible_for_player; this.spawn_evalfunc = trigger_race_checkpoint_spawn_evalfunc; + if (!g_racecheckpoints) + g_racecheckpoints = IL_NEW(); IL_PUSH(g_racecheckpoints, this); + // trigger_race_checkpoint_verify checks this list too + if (!g_race_targets) + g_race_targets = IL_NEW(); + InitializeEntity(this, trigger_race_checkpoint_verify, INITPRIO_FINDTARGET); } -spawnfunc(target_checkpoint) // defrag entity +void target_checkpoint_setup(entity this) { if(!g_race && !g_cts) { delete(this); return; } defrag_ents = 1; @@ -1045,13 +1137,26 @@ spawnfunc(target_checkpoint) // defrag entity race_timed_checkpoint = 1; + if (!g_race_targets) + g_race_targets = IL_NEW(); IL_PUSH(g_race_targets, this); + // trigger_race_checkpoint_verify checks this list too + if (!g_racecheckpoints) + g_racecheckpoints = IL_NEW(); + InitializeEntity(this, trigger_race_checkpoint_verify, INITPRIO_FINDTARGET); } -spawnfunc(target_startTimer) { spawnfunc_target_checkpoint(this); } -spawnfunc(target_stopTimer) { spawnfunc_target_checkpoint(this); } +spawnfunc(target_checkpoint) +{ + // xonotic defrag entity + target_checkpoint_setup(this); +} + +// compatibility entity names +spawnfunc(target_startTimer) { target_checkpoint_setup(this); } +spawnfunc(target_stopTimer) { target_checkpoint_setup(this); } void race_AbandonRaceCheck(entity p) {