X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fcl_client.qc;h=2985b45b41262b4f9ac4ed51749d34323203a639;hb=e0aa374449ed8b7455450f339c9143854b073bb2;hp=5c980920b7228a5dcc37681bca3e7b3fa855afd1;hpb=06831b03595a3e450bf120d56d54f7e32c603cbe;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index 5c980920b..2985b45b4 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -6,15 +6,6 @@ void send_CSQC_teamnagger() { WriteByte(0, TE_CSQC_TEAMNAGGER); } -void send_CSQC_nexvelocity(entity e) { - msg_entity = e; - WriteByte(MSG_ONE, SVC_TEMPENTITY); - WriteByte(MSG_ONE, TE_CSQC_NEX_VELOCITY); - WriteShort(MSG_ONE, cvar("g_balance_nex_velocitydependent_minspeed")); - WriteShort(MSG_ONE, cvar("g_balance_nex_velocitydependent_maxspeed")); - WriteShort(MSG_ONE, cvar("g_balance_nex_velocitydependent_falloff_factor") * 10000); -} - void send_CSQC_cr_maxbullets(entity e) { msg_entity = e; WriteByte(MSG_ONE, SVC_TEMPENTITY); @@ -608,6 +599,7 @@ void PutObserverInServer (void) } DropAllRunes(self); + MUTATOR_CALLHOOK(MakePlayerObserver); Portal_ClearAll(self); @@ -639,6 +631,8 @@ void PutObserverInServer (void) PlayerScore_Clear(self); // clear scores when needed + accuracy_resend(self); + self.spectatortime = time; self.classname = "observer"; @@ -722,8 +716,6 @@ void PutObserverInServer (void) } else self.frags = FRAGS_SPECTATOR; - - MUTATOR_CALLHOOK(MakePlayerObserver); } float RestrictSkin(float s) @@ -863,6 +855,8 @@ void PutClientInServer (void) entity spot, oldself; float j; + accuracy_resend(self); + if(self.team < 0) JoinBestTeam(self, FALSE, TRUE); @@ -898,6 +892,12 @@ void PutClientInServer (void) self.effects = 0; self.air_finished = time + 12; self.dmg = 2; + if(cvar("g_balance_nex_charge")) + { + if(cvar("g_balance_nex_secondary_charge_pool")) + self.nex_charge_pool_ammo = 1; + self.nex_charge = cvar("g_balance_nex_charge_start"); + } if(inWarmupStage) { @@ -923,7 +923,13 @@ void PutClientInServer (void) } if(g_weaponarena_random) + { + if(g_weaponarena_random_with_laser) + self.weapons &~= WEPBIT_LASER; self.weapons = randombits(self.weapons, g_weaponarena_random, FALSE); + if(g_weaponarena_random_with_laser) + self.weapons |= WEPBIT_LASER; + } self.items = start_items; self.jump_interval = time; @@ -1076,6 +1082,9 @@ void PutClientInServer (void) // ctf_playerchanged(); } +.float ebouncefactor, ebouncestop; // electro's values +// TODO do we need all these fields, or should we stop autodetecting runtime +// changes and just have a console command to update this? float ClientInit_SendEntity(entity to, float sf) { WriteByte(MSG_ENTITY, ENT_CLIENT_INIT); @@ -1098,10 +1107,13 @@ float ClientInit_SendEntity(entity to, float sf) WriteString(MSG_ENTITY, ""); WriteByte(MSG_ENTITY, self.count * 255.0); // g_balance_armor_blockpercent WriteByte(MSG_ENTITY, self.cnt * 255.0); // g_balance_weaponswitchdelay - WriteCoord(MSG_ENTITY, self.bouncefactor); // g_balance_grenadelauncher_secondary_bouncefactor - WriteCoord(MSG_ENTITY, self.bouncestop); // g_balance_grenadelauncher_secondary_bouncestop + WriteCoord(MSG_ENTITY, self.bouncefactor); // g_balance_grenadelauncher_bouncefactor + WriteCoord(MSG_ENTITY, self.bouncestop); // g_balance_grenadelauncher_bouncestop + WriteCoord(MSG_ENTITY, self.ebouncefactor); // g_balance_grenadelauncher_bouncefactor + WriteCoord(MSG_ENTITY, self.ebouncestop); // g_balance_grenadelauncher_bouncestop WriteByte(MSG_ENTITY, cvar("g_balance_nex_secondary")); // client has to know if it should zoom or not WriteByte(MSG_ENTITY, cvar("g_balance_campingrifle_secondary")); // client has to know if it should zoom or not + WriteByte(MSG_ENTITY, serverflags); // client has to know if it should zoom or not return TRUE; } @@ -1118,14 +1130,24 @@ void ClientInit_CheckUpdate() self.cnt = cvar("g_balance_weaponswitchdelay"); self.SendFlags |= 1; } - if(self.bouncefactor != cvar("g_balance_grenadelauncher_secondary_bouncefactor")) + if(self.bouncefactor != cvar("g_balance_grenadelauncher_bouncefactor")) + { + self.bouncefactor = cvar("g_balance_grenadelauncher_bouncefactor"); + self.SendFlags |= 1; + } + if(self.bouncestop != cvar("g_balance_grenadelauncher_bouncestop")) + { + self.bouncestop = cvar("g_balance_grenadelauncher_bouncestop"); + self.SendFlags |= 1; + } + if(self.ebouncefactor != cvar("g_balance_electro_secondary_bouncefactor")) { - self.bouncefactor = cvar("g_balance_grenadelauncher_secondary_bouncefactor"); + self.ebouncefactor = cvar("g_balance_electro_secondary_bouncefactor"); self.SendFlags |= 1; } - if(self.bouncestop != cvar("g_balance_grenadelauncher_secondary_bouncestop")) + if(self.ebouncestop != cvar("g_balance_electro_secondary_bouncestop")) { - self.bouncestop = cvar("g_balance_grenadelauncher_secondary_bouncestop"); + self.ebouncestop = cvar("g_balance_electro_secondary_bouncestop"); self.SendFlags |= 1; } } @@ -1312,7 +1334,28 @@ void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto void ClientKill (void) { - ClientKill_TeamChange(0); + if((g_arena || g_ca) && ((champion && champion.classname == "player" && player_count > 1) || player_count == 1)) // don't allow a kill in this case either + { + // do nothing + } + else + ClientKill_TeamChange(0); +} + +void CTS_ClientKill_Think (void) +{ + self = self.owner; // set self to the player to be killed + sprint(self, "^1You were killed in order to prevent cheating!"); + ClientKill_Now(); +} + +void CTS_ClientKill (float t) // silent version of ClientKill +{ + entity e; + e = spawn(); + e.owner = self; + e.think = CTS_ClientKill_Think; + e.nextthink = t; } void DoTeamChange(float destteam) @@ -1393,6 +1436,27 @@ void FixClientCvars(entity e) */ } +float PlayerInIDList(entity p, string idlist) +{ + float n, i; + string s; + + // NOTE: we do NOT check crypto_keyfp here, an unsigned ID is fine too for this + if not(p.crypto_idfp) + return 0; + + // this function allows abbreviated player IDs too! + n = tokenize_console(idlist); + for(i = 0; i < n; ++i) + { + s = argv(i); + if(s == substring(p.crypto_idfp, 0, strlen(s))) + return 1; + } + + return 0; +} + /* ============= ClientConnect @@ -1404,10 +1468,6 @@ Called when a client connects to the server string ColoredTeamName(float t); void DecodeLevelParms (void); //void dom_player_join_team(entity pl); -#ifdef UID -.float uid_kicktime; -.string uid; -#endif void ClientConnect (void) { float t; @@ -1440,6 +1500,7 @@ void ClientConnect (void) PlayerScore_Attach(self); ClientData_Attach(); + accuracy_init(self); bot_clientconnect(); @@ -1452,9 +1513,37 @@ void ClientConnect (void) //if(g_domination) // dom_player_join_team(self); + // identify the right forced team + if(PlayerInIDList(self, cvar_string("g_forced_team_red"))) + self.team_forced = COLOR_TEAM1; + else if(PlayerInIDList(self, cvar_string("g_forced_team_blue"))) + self.team_forced = COLOR_TEAM2; + else if(PlayerInIDList(self, cvar_string("g_forced_team_yellow"))) + self.team_forced = COLOR_TEAM3; + else if(PlayerInIDList(self, cvar_string("g_forced_team_pink"))) + self.team_forced = COLOR_TEAM4; + else if(cvar_string("g_forced_team_otherwise") == "red") + self.team_forced = COLOR_TEAM1; + else if(cvar_string("g_forced_team_otherwise") == "blue") + self.team_forced = COLOR_TEAM2; + else if(cvar_string("g_forced_team_otherwise") == "yellow") + self.team_forced = COLOR_TEAM3; + else if(cvar_string("g_forced_team_otherwise") == "pink") + self.team_forced = COLOR_TEAM4; + else if(cvar_string("g_forced_team_otherwise") == "spectate") + self.team_forced = -1; + else if(cvar_string("g_forced_team_otherwise") == "spectator") + self.team_forced = -1; + else + self.team_forced = 0; + + if(!teams_matter) + if(self.team_forced > 0) + self.team_forced = 0; + JoinBestTeam(self, FALSE, FALSE); // if the team number is valid, keep it - if((cvar("sv_spectate") == 1 && !g_lms) || cvar("g_campaign")) { + if((cvar("sv_spectate") == 1 && !g_lms) || cvar("g_campaign") || self.team_forced < 0) { self.classname = "observer"; } else { if(teams_matter) @@ -1585,12 +1674,6 @@ void ClientConnect (void) else self.hitplotfh = -1; -#ifdef UID - if(clienttype(self) == CLIENTTYPE_REAL) - if not(self.uid) - self.uid_kicktime = time + 60; -#endif - if(g_race || g_cts) { string rr; if(g_cts) @@ -1599,11 +1682,12 @@ void ClientConnect (void) rr = RACE_RECORD; t = stof(db_get(ServerProgsDB, strcat(GetMapname(), rr, "time"))); + msg_entity = self; race_send_recordtime(MSG_ONE); race_send_speedaward(MSG_ONE); speedaward_alltimebest = stof(db_get(ServerProgsDB, strcat(GetMapname(), rr, "speed/speed"))); - speedaward_alltimebest_holder = db_get(ServerProgsDB, strcat(GetMapname(), rr, "speed/netname")); + speedaward_alltimebest_holder = uid2name(db_get(ServerProgsDB, strcat(GetMapname(), rr, "speed/crypto_idfp"))); race_send_speedaward_alltimebest(MSG_ONE); float i; @@ -1614,7 +1698,6 @@ void ClientConnect (void) else if(cvar("sv_teamnagger") && !(cvar("bot_vs_human") && (c3==-1 && c4==-1)) && !g_ca) // teamnagger is currently bad for ca send_CSQC_teamnagger(); - send_CSQC_nexvelocity(self); send_CSQC_cr_maxbullets(self); CheatInitClient(); @@ -1690,17 +1773,13 @@ void ClientDisconnect (void) bot_relinkplayerlist(); - // remove laserdot - if(self.weaponentity) - if(self.weaponentity.lasertarget) - remove(self.weaponentity.lasertarget); - if(g_arena) { Spawnqueue_Unmark(self); Spawnqueue_Remove(self); } + accuracy_free(self); ClientData_Detach(); PlayerScore_Detach(self); @@ -1708,6 +1787,8 @@ void ClientDisconnect (void) strunzone(self.netname_previous); if(self.clientstatus) strunzone(self.clientstatus); + if(self.weaponorder_byimpulse) + strunzone(self.weaponorder_byimpulse); ClearPlayerSounds(); @@ -2196,33 +2277,13 @@ void GetPressedKeys(void) { self.pressedkeys &~= KEY_CROUCH; } -void update_stats (float number, float hit, float fired) { -// self.stat_hit = number + ((number==0) ? 1 : 64) * hit * sv_accuracy_data_share; -// self.stat_fired = number + ((number==0) ? 1 : 64) * fired * sv_accuracy_data_share; - - if(number) { - self.stat_hit = number + 64 * hit * sv_accuracy_data_share; - self.stat_fired = number + 64 * fired * sv_accuracy_data_share; - } else { - self.stat_hit = hit * sv_accuracy_data_share; - self.stat_fired = fired * sv_accuracy_data_share; - } -} - /* ====================== spectate mode routines ====================== */ -.float weapon_count; void SpectateCopy(entity spectatee) { - if(spectatee.weapon_count < WEP_LAST) { - update_stats (spectatee.weapon_count, spectatee.cvar_cl_accuracy_data_share * floor(spectatee.stats_hit[spectatee.weapon_count - 1]), spectatee.cvar_cl_accuracy_data_share * floor(spectatee.stats_fired[spectatee.weapon_count - 1])); - spectatee.weapon_count ++; - } else - update_stats (0, spectatee.cvar_cl_accuracy_data_share * spectatee.stat_hit, spectatee.cvar_cl_accuracy_data_share * spectatee.stat_fired); - other = spectatee; MUTATOR_CALLHOOK(SpectateCopy); self.armortype = spectatee.armortype; @@ -2236,6 +2297,7 @@ void SpectateCopy(entity spectatee) { self.health = spectatee.health; self.impulse = 0; self.items = spectatee.items; + self.last_pickup = spectatee.last_pickup; self.metertime = spectatee.metertime; self.strength_finished = spectatee.strength_finished; self.invincible_finished = spectatee.invincible_finished; @@ -2289,8 +2351,7 @@ float SpectateNext() { WriteEntity(MSG_ONE, self.enemy); //stuffcmd(self, "set viewsize $tmpviewsize \n"); self.movetype = MOVETYPE_NONE; - - self.enemy.weapon_count = 0; + accuracy_resend(self); if(!SpectateUpdate()) PutObserverInServer(); @@ -2330,7 +2391,7 @@ void ShowRespawnCountdown() void LeaveSpectatorMode() { if(isJoinAllowed()) { - if(!teams_matter || cvar("g_campaign") || cvar("g_balance_teams") || (self.wasplayer && cvar("g_changeteam_banned"))) { + if(!teams_matter || cvar("g_campaign") || cvar("g_balance_teams") || (self.wasplayer && cvar("g_changeteam_banned")) || self.team_forced > 0) { self.classname = "player"; if(cvar("g_campaign") || cvar("g_balance_teams") || cvar("g_balance_teams_force")) @@ -2339,8 +2400,6 @@ void LeaveSpectatorMode() if(cvar("g_campaign")) campaign_bots_may_start = 1; - self.stat_count = WEP_LAST; - PutClientInServer(); if(self.classname == "player") @@ -2371,6 +2430,9 @@ void LeaveSpectatorMode() * @return bool TRUE if the player is allowed to join, false otherwise */ float isJoinAllowed() { + if(self.team_forced < 0) + return FALSE; // forced spectators can never join + if (!cvar("g_maxplayers")) return TRUE; @@ -2399,50 +2461,6 @@ void checkSpectatorBlock() { } } -float vercmp_recursive(string v1, string v2) -{ - float dot1, dot2; - string s1, s2; - float r; - - dot1 = strstrofs(v1, ".", 0); - dot2 = strstrofs(v2, ".", 0); - if(dot1 == -1) - s1 = v1; - else - s1 = substring(v1, 0, dot1); - if(dot2 == -1) - s2 = v2; - else - s2 = substring(v2, 0, dot2); - - r = stof(s1) - stof(s2); - if(r != 0) - return r; - - r = strcasecmp(s1, s2); - if(r != 0) - return r; - - if(dot1 == -1) - if(dot2 == -1) - return 0; - else - return -1; - else - if(dot2 == -1) - return 1; - else - return vercmp_recursive(substring(v1, dot1 + 1, 999), substring(v2, dot2 + 1, 999)); -} - -float vercmp(string v1, string v2) -{ - if(strcasecmp(v1, v2) == 0) // early out check - return 0; - return vercmp_recursive(v1, v2); -} - void ObserverThink() { if (self.flags & FL_JUMPRELEASED) { @@ -2485,14 +2503,12 @@ void SpectatorThink() self.classname = "spectator"; } else { self.classname = "observer"; - self.stat_count = WEP_LAST; PutClientInServer(); } } else if (self.BUTTON_ATCK2) { self.welcomemessage_time = 0; self.flags &~= FL_JUMPRELEASED; self.classname = "observer"; - self.stat_count = WEP_LAST; PutClientInServer(); } else { if(!SpectateUpdate()) @@ -2801,14 +2817,22 @@ void PlayerPreThink (void) } player_regen(); + + // rot nex charge to the charge limit + if(cvar("g_balance_nex_charge_rot_rate") && self.nex_charge > cvar("g_balance_nex_charge_limit") && self.nex_charge_rottime < time) + self.nex_charge = bound(cvar("g_balance_nex_charge_limit"), self.nex_charge - cvar("g_balance_nex_charge_rot_rate") * frametime / W_TICSPERFRAME, 1); + if(frametime) player_anim(); if (g_minstagib) minstagib_ammocheck(); - ctf_setstatus(); - nexball_setstatus(); + if(g_ctf) + ctf_setstatus(); + + if(g_nexball) + nexball_setstatus(); self.dmg_team = max(0, self.dmg_team - cvar("g_teamdamage_resetspeed") * frametime); @@ -2922,25 +2946,6 @@ void PlayerPostThink (void) stuffcmd(self, strcat("name ", self.netname, substring(ftos(random()), 2, -1), "\n")); } - // send the clients accuracy stats to the client - if(self.stat_count > 0) - if(frametime) - { - self.stat_hit = self.stat_count + 64 * floor(self.(stats_hit[self.stat_count - 1])); - self.stat_fired = self.stat_count + 64 * floor(self.(stats_fired[self.stat_count - 1])); - self.stat_count -= 1; - } - -#ifdef UID - if(self.uid_kicktime) - if(time > self.uid_kicktime) - { - bprint("^3", self.netname, "^3 was kicked for missing UID.\n"); - dropclient(self); - return; - } -#endif - if(sv_maxidle && frametime) { // WORKAROUND: only use dropclient in server frames (frametime set). Never use it in cl_movement frames (frametime zero). @@ -3037,6 +3042,18 @@ void PlayerPostThink (void) playerdemo_write(); + if((g_cts || g_race) && self.cvar_cl_allow_uid2name) + { + if(!self.stored_netname) + self.stored_netname = strzone(uid2name(self.crypto_idfp)); + if(self.stored_netname != self.netname) + { + db_put(ServerProgsDB, strcat("uid2name", self.crypto_idfp), self.netname); + strunzone(self.stored_netname); + self.stored_netname = strzone(self.netname); + } + } + /* if(g_race) dprint(sprintf("%f %.6f\n", time, race_GetFractionalLapCount(self)));