X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;ds=sidebyside;f=qcsrc%2Fserver%2Fg_world.qc;h=001fbc5bb5d2d5dd718bbd188eddbf1a4dd5c307;hb=7072a9dc696dc5bd2a5a2c4c706c4a2f5c0a24c5;hp=c2f895c48243707e166dc4fa8b823f81499bff1a;hpb=c6466f683b8270a7a56305fbf0e8cc785df8356d;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/g_world.qc b/qcsrc/server/g_world.qc index c2f895c48..001fbc5bb 100644 --- a/qcsrc/server/g_world.qc +++ b/qcsrc/server/g_world.qc @@ -1,3 +1,7 @@ +#define LATENCY_THINKRATE 10 +.float latency_sum; +.float latency_cnt; +.float latency_time; entity pingplreport; void PingPLReport_Think() { @@ -18,6 +22,15 @@ void PingPLReport_Think() WriteShort(MSG_BROADCAST, max(1, e.ping)); WriteByte(MSG_BROADCAST, ceil(e.ping_packetloss * 255)); WriteByte(MSG_BROADCAST, ceil(e.ping_movementloss * 255)); + + // record latency times for clients throughout the match so we can report it to playerstats + if(time > (e.latency_time + LATENCY_THINKRATE)) + { + e.latency_sum += e.ping; + e.latency_cnt += 1; + e.latency_time = time; + //print("sum: ", ftos(e.latency_sum), ", cnt: ", ftos(e.latency_cnt), ", avg: ", ftos(e.latency_sum / e.latency_cnt), ".\n"); + } } else { @@ -45,7 +58,7 @@ float world_initialized; string GetMapname(); string GetGametype(); void GotoNextMap(float reinit); -void ShuffleMaplist() +void ShuffleMaplist(); float(float reinit) DoNextMapOverride; void SetDefaultAlpha() @@ -295,9 +308,8 @@ void cvar_changes_init() BADCVAR("g_balance_kill_delay"); BADCVAR("g_ca_point_leadlimit"); BADCVAR("g_ctf_captimerecord_always"); - BADCVAR("g_ctf_flag_capture_effects"); BADCVAR("g_ctf_flag_glowtrails"); - BADCVAR("g_ctf_flag_pickup_effects"); + BADCVAR("g_ctf_flag_pickup_verbosename"); BADCVAR("g_domination_point_leadlimit"); BADCVAR("g_forced_respawn"); BADCVAR("g_keyhunt_point_leadlimit"); @@ -348,7 +360,8 @@ void cvar_changes_init() BADCVAR("gametype"); BADCVAR("g_antilag"); BADCVAR("g_balance_teams"); - BADCVAR("g_balance_teams_force"); + BADCVAR("g_balance_teams_prevent_imbalance"); + BADCVAR("g_balance_teams_scorefactor"); BADCVAR("g_ban_sync_trusted_servers"); BADCVAR("g_ban_sync_uri"); BADCVAR("g_ctf_ignore_frags"); @@ -538,8 +551,10 @@ void spawnfunc___init_dedicated_server(void) self.classname = "worldspawn"; // safeguard against various stuff ;) // needs to be done so early because of the constants they create - RegisterWeapons(); - RegisterGametypes(); + CALL_ACCUMULATED_FUNCTION(RegisterWeapons); + CALL_ACCUMULATED_FUNCTION(RegisterGametypes); + CALL_ACCUMULATED_FUNCTION(RegisterNotifications); + CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes); MapInfo_Enumerate(); MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0); @@ -547,7 +562,6 @@ void spawnfunc___init_dedicated_server(void) void Map_MarkAsRecent(string m); float world_already_spawned; -void RegisterWeapons(); void Nagger_Init(); void ClientInit_Spawn(); void WeaponStats_Init(); @@ -585,8 +599,10 @@ void spawnfunc_worldspawn (void) } // needs to be done so early because of the constants they create - RegisterWeapons(); - RegisterGametypes(); + CALL_ACCUMULATED_FUNCTION(RegisterWeapons); + CALL_ACCUMULATED_FUNCTION(RegisterGametypes); + CALL_ACCUMULATED_FUNCTION(RegisterNotifications); + CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes); ServerProgsDB = db_load(strcat("server.db", autocvar_sessionid)); @@ -638,6 +654,8 @@ void spawnfunc_worldspawn (void) Map_MarkAsRecent(mapname); + PlayerStats_Init(); // we need this to be initiated before InitGameplayMode + precache_model ("null"); // we need this one before InitGameplayMode InitGameplayMode(); readlevelcvars(); @@ -812,15 +830,18 @@ void spawnfunc_worldspawn (void) addstat(STAT_MOVEVARS_MAXSPEED, AS_FLOAT, stat_sv_maxspeed); addstat(STAT_MOVEVARS_AIRACCEL_QW, AS_FLOAT, stat_sv_airaccel_qw); addstat(STAT_MOVEVARS_AIRSTRAFEACCEL_QW, AS_FLOAT, stat_sv_airstrafeaccel_qw); - + // secrets addstat(STAT_SECRETS_TOTAL, AS_FLOAT, stat_secrets_total); addstat(STAT_SECRETS_FOUND, AS_FLOAT, stat_secrets_found); - + + // misc + addstat(STAT_RESPAWN_TIME, AS_FLOAT, stat_respawn_time); + next_pingtime = time + 5; detect_maptype(); - + // set up information replies for clients and server to use lsmaps_reply = "^7Maps available: "; lsnewmaps_reply = "^7Maps without a record set: "; @@ -833,18 +854,18 @@ void spawnfunc_worldspawn (void) col = "^2"; else col = "^3"; - + ++j; - + lsmaps_reply = strcat(lsmaps_reply, col, MapInfo_Map_bspname, " "); - + if(g_race && !stof(db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, RACE_RECORD, "time")))) lsnewmaps_reply = strcat(lsnewmaps_reply, col, MapInfo_Map_bspname, " "); else if(g_cts && !stof(db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, CTS_RECORD, "time")))) lsnewmaps_reply = strcat(lsnewmaps_reply, col, MapInfo_Map_bspname, " "); } } - + lsmaps_reply = strzone(strcat(lsmaps_reply, "\n")); lsnewmaps_reply = strzone(strcat(((!g_race && !g_cts) ? "Need to be playing race or CTS for lsnewmaps to work." : lsnewmaps_reply), "\n")); @@ -867,9 +888,11 @@ void spawnfunc_worldspawn (void) for(i = 0; i < 10; ++i) { - records_reply[i] = strzone(getrecords(i)); + s = getrecords(i); + if (s) + records_reply[i] = strzone(s); } - + ladder_reply = strzone(getladder()); rankings_reply = strzone(getrankings()); @@ -911,8 +934,6 @@ void spawnfunc_worldspawn (void) cvar_set("sv_curl_serverpackages", substring(s, 1, -1)); } - PlayerStats_Init(); - // MOD AUTHORS: change this, and possibly remove a few of the blocks below to ignore certain changes modname = "Xonotic"; // physics/balance/config changes that count as mod @@ -1330,10 +1351,10 @@ float mapvote_initialized; void IntermissionThink() { FixIntermissionClient(self); - + float server_screenshot = (autocvar_sv_autoscreenshot && self.cvar_cl_autoscreenshot); float client_screenshot = (self.cvar_cl_autoscreenshot == 2); - + if( (server_screenshot || client_screenshot) && ((self.autoscreenshot > 0) && (time > self.autoscreenshot)) ) { @@ -1441,6 +1462,8 @@ void DumpStats(float final) print(s, "\n"); if(to_eventlog) GameLogEcho(s); + + file = -1; if(to_file) { file = fopen(autocvar_sv_logscores_filename, FILE_APPEND); @@ -1594,6 +1617,8 @@ void NextLevel() if(autocvar_g_campaign) CampaignPreIntermission(); + MUTATOR_CALLHOOK(MatchEnd); + localcmd("\nsv_hook_gameend\n"); } @@ -1740,10 +1765,10 @@ float WinningCondition_Onslaught() { if (head.health > 0) { - if (head.team == COLOR_TEAM1) t1 = 1; - if (head.team == COLOR_TEAM2) t2 = 1; - if (head.team == COLOR_TEAM3) t3 = 1; - if (head.team == COLOR_TEAM4) t4 = 1; + if (head.team == FL_TEAM_1) t1 = 1; + if (head.team == FL_TEAM_2) t2 = 1; + if (head.team == FL_TEAM_3) t3 = 1; + if (head.team == FL_TEAM_4) t4 = 1; } head = find(head, classname, "onslaught_generator"); } @@ -1751,10 +1776,10 @@ float WinningCondition_Onslaught() { // game over, only one team remains (or none) ClearWinners(); - if (t1) SetWinners(team, COLOR_TEAM1); - if (t2) SetWinners(team, COLOR_TEAM2); - if (t3) SetWinners(team, COLOR_TEAM3); - if (t4) SetWinners(team, COLOR_TEAM4); + if (t1) SetWinners(team, FL_TEAM_1); + if (t2) SetWinners(team, FL_TEAM_2); + if (t3) SetWinners(team, FL_TEAM_3); + if (t4) SetWinners(team, FL_TEAM_4); dprint("Have a winner, ending game.\n"); return WINNING_YES; } @@ -1792,13 +1817,13 @@ float WinningCondition_Assault() status = WINNING_NO; // as the timelimit has not yet passed just assume the defending team will win - if(assault_attacker_team == COLOR_TEAM1) + if(assault_attacker_team == FL_TEAM_1) { - SetWinners(team, COLOR_TEAM2); + SetWinners(team, FL_TEAM_2); } else { - SetWinners(team, COLOR_TEAM1); + SetWinners(team, FL_TEAM_1); } entity ent; @@ -1924,10 +1949,10 @@ float WinningCondition_Scores(float limit, float leadlimit) if(teamplay) { - team1_score = TeamScore_GetCompareValue(COLOR_TEAM1); - team2_score = TeamScore_GetCompareValue(COLOR_TEAM2); - team3_score = TeamScore_GetCompareValue(COLOR_TEAM3); - team4_score = TeamScore_GetCompareValue(COLOR_TEAM4); + team1_score = TeamScore_GetCompareValue(FL_TEAM_1); + team2_score = TeamScore_GetCompareValue(FL_TEAM_2); + team3_score = TeamScore_GetCompareValue(FL_TEAM_3); + team4_score = TeamScore_GetCompareValue(FL_TEAM_4); } ClearWinners(); @@ -1977,6 +2002,9 @@ float WinningCondition_Scores(float limit, float leadlimit) limitreached = (limitreached || leadlimitreached); } + if(limit) + game_completion_ratio = max(game_completion_ratio, bound(0, WinningConditionHelper_topscore / limit, 1)); + return GetWinningCode( WinningConditionHelper_topscore && limitreached, WinningConditionHelper_equality @@ -2007,7 +2035,6 @@ float WinningCondition_Race(float fraglimit) return WINNING_STARTSUDDENDEATHOVERTIME; else return WINNING_NEVER; - return wc; } float WinningCondition_QualifyingThenRace(float limit) @@ -2041,25 +2068,25 @@ float WinningCondition_RanOutOfSpawns() FOR_EACH_PLAYER(head) if(head.deadflag == DEAD_NO) { - if(head.team == COLOR_TEAM1) + if(head.team == FL_TEAM_1) team1_score = 1; - else if(head.team == COLOR_TEAM2) + else if(head.team == FL_TEAM_2) team2_score = 1; - else if(head.team == COLOR_TEAM3) + else if(head.team == FL_TEAM_3) team3_score = 1; - else if(head.team == COLOR_TEAM4) + else if(head.team == FL_TEAM_4) team4_score = 1; } for(head = world; (head = find(head, classname, "info_player_deathmatch")) != world; ) { - if(head.team == COLOR_TEAM1) + if(head.team == FL_TEAM_1) team1_score = 1; - else if(head.team == COLOR_TEAM2) + else if(head.team == FL_TEAM_2) team2_score = 1; - else if(head.team == COLOR_TEAM3) + else if(head.team == FL_TEAM_3) team3_score = 1; - else if(head.team == COLOR_TEAM4) + else if(head.team == FL_TEAM_4) team4_score = 1; } @@ -2072,17 +2099,21 @@ float WinningCondition_RanOutOfSpawns() else if(team1_score + team2_score + team3_score + team4_score == 1) { float t, i; - if(team1_score) t = COLOR_TEAM1; - if(team2_score) t = COLOR_TEAM2; - if(team3_score) t = COLOR_TEAM3; - if(team4_score) t = COLOR_TEAM4; + if(team1_score) + t = FL_TEAM_1; + else if(team2_score) + t = FL_TEAM_2; + else if(team3_score) + t = FL_TEAM_3; + else // if(team4_score) + t = FL_TEAM_4; CheckAllowedTeams(world); for(i = 0; i < MAX_TEAMSCORE; ++i) { - if(t != COLOR_TEAM1) if(c1 >= 0) TeamScore_AddToTeam(COLOR_TEAM1, i, -1000); - if(t != COLOR_TEAM2) if(c2 >= 0) TeamScore_AddToTeam(COLOR_TEAM2, i, -1000); - if(t != COLOR_TEAM3) if(c3 >= 0) TeamScore_AddToTeam(COLOR_TEAM3, i, -1000); - if(t != COLOR_TEAM4) if(c4 >= 0) TeamScore_AddToTeam(COLOR_TEAM4, i, -1000); + if(t != FL_TEAM_1) if(c1 >= 0) TeamScore_AddToTeam(FL_TEAM_1, i, -1000); + if(t != FL_TEAM_2) if(c2 >= 0) TeamScore_AddToTeam(FL_TEAM_2, i, -1000); + if(t != FL_TEAM_3) if(c3 >= 0) TeamScore_AddToTeam(FL_TEAM_3, i, -1000); + if(t != FL_TEAM_4) if(c4 >= 0) TeamScore_AddToTeam(FL_TEAM_4, i, -1000); } AddWinners(team, t); @@ -2161,6 +2192,11 @@ void CheckRules_World() float wantovertime; wantovertime = 0; + if(timelimit > game_starttime) + game_completion_ratio = (time - game_starttime) / (timelimit - game_starttime); + else + game_completion_ratio = 0; + if(checkrules_suddendeathend) { if(!checkrules_suddendeathwarning) @@ -2318,7 +2354,7 @@ string MapVote_Suggest(string m) if(mapvote_initialized) return "Can't suggest - voting is already in progress!"; m = MapInfo_FixName(m); - if(!m) + if not(m) return "The map you suggested is not available on this server."; if(!autocvar_g_maplist_votable_suggestions_override_mostrecent) if(Map_IsRecent(m)) @@ -2363,6 +2399,7 @@ void MapVote_AddVotable(string nextMap, float isSuggestion) mapvote_maps[mapvote_count] = strzone(nextMap); mapvote_maps_suggested[mapvote_count] = isSuggestion; + pakfile = string_null; for(i = 0; i < mapvote_screenshot_dirs_count; ++i) { mapfile = strcat(mapvote_screenshot_dirs[i], "/", mapvote_maps[i]);