From: terencehill Date: Mon, 29 Jan 2018 17:59:41 +0000 (+0100) Subject: Delay forced auto join on connection, many things can go wrong if a client is spawned... X-Git-Tag: xonotic-v0.8.5~2067^2~5 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=351def9ce41e4761f1b7894b8fb5bcaa8cbec874;p=xonotic%2Fxonotic-data.pk3dir.git Delay forced auto join on connection, many things can go wrong if a client is spawned as player on connection; it fixes #1875 "Weapon position is forced to the right in LMS" --- diff --git a/qcsrc/server/client.qc b/qcsrc/server/client.qc index 3333c04e4..9c40f2dba 100644 --- a/qcsrc/server/client.qc +++ b/qcsrc/server/client.qc @@ -1196,16 +1196,7 @@ void ClientConnect(entity this) JoinBestTeam(this, false); // if the team number is valid, keep it this.playerid = playerid_save; - if (autocvar_sv_spectate || autocvar_g_campaign || this.team_forced < 0) { - TRANSMUTE(Observer, this); - } else { - if (!teamplay || autocvar_g_balance_teams) { - TRANSMUTE(Player, this); - campaign_bots_may_start = true; - } else { - TRANSMUTE(Observer, this); // do it anyway - } - } + TRANSMUTE(Observer, this); PlayerStats_GameReport_AddEvent(sprintf("kills-%d", this.playerid)); @@ -2604,7 +2595,10 @@ void PlayerPreThink (entity this) if (IS_REAL_CLIENT(this)) PrintWelcomeMessage(this); + #define MIN_SPEC_TIME 1 if (IS_PLAYER(this)) { + if (IS_REAL_CLIENT(this) && time < CS(this).jointime + MIN_SPEC_TIME) + error("Client can't be spawned as player on connection!"); if(!PlayerThink(this)) return; } @@ -2613,6 +2607,22 @@ void PlayerPreThink (entity this) IntermissionThink(this); return; } + else if (IS_REAL_CLIENT(this) && time < CS(this).jointime + MIN_SPEC_TIME + 1) + { + // don't do this in ClientConnect + // many things can go wrong if a client is spawned as player on connection + if (time > CS(this).jointime + MIN_SPEC_TIME) + { + if (MUTATOR_CALLHOOK(AutoJoinOnConnection, this) + || (!(autocvar_sv_spectate || autocvar_g_campaign || this.team_forced < 0) + && (!teamplay || autocvar_g_balance_teams))) + { + campaign_bots_may_start = true; + Join(this); + return; + } + } + } else if (IS_OBSERVER(this)) { ObserverThink(this); } diff --git a/qcsrc/server/mutators/events.qh b/qcsrc/server/mutators/events.qh index fb452c339..d1f33af10 100644 --- a/qcsrc/server/mutators/events.qh +++ b/qcsrc/server/mutators/events.qh @@ -24,6 +24,12 @@ MUTATOR_HOOKABLE(PutClientInServer, EV_PutClientInServer); /**/ MUTATOR_HOOKABLE(ForbidSpawn, EV_ForbidSpawn); +/** returns true if client should be put as player on connection */ +#define EV_AutoJoinOnConnection(i, o) \ + /** player */ i(entity, MUTATOR_ARGV_0_entity) \ + /**/ +MUTATOR_HOOKABLE(AutoJoinOnConnection, EV_AutoJoinOnConnection); + /** called when player spawns to determine whether to give them random start weapons. Return true to forbid giving them. */ #define EV_ForbidRandomStartWeapons(i, o) \ /** player */ i(entity, MUTATOR_ARGV_0_entity) \ diff --git a/qcsrc/server/mutators/mutator/gamemode_lms.qc b/qcsrc/server/mutators/mutator/gamemode_lms.qc index cd8fb390d..776484344 100644 --- a/qcsrc/server/mutators/mutator/gamemode_lms.qc +++ b/qcsrc/server/mutators/mutator/gamemode_lms.qc @@ -228,7 +228,10 @@ MUTATOR_HOOKFUNCTION(lms, ClientDisconnect) MUTATOR_HOOKFUNCTION(lms, MakePlayerObserver) { - entity player = M_ARGV(0, entity); + entity player = M_ARGV(0, entity); + + if (!IS_PLAYER(player)) + return true; lms_RemovePlayer(player); return true; // prevent team reset @@ -238,9 +241,6 @@ MUTATOR_HOOKFUNCTION(lms, ClientConnect) { entity player = M_ARGV(0, entity); - TRANSMUTE(Player, player); - campaign_bots_may_start = true; - if(GameRules_scoring_add(player, LMS_LIVES, LMS_NewPlayerLives()) <= 0) { GameRules_scoring_add(player, LMS_RANK, 666); // mark as forced spectator for the hud code @@ -248,6 +248,11 @@ MUTATOR_HOOKFUNCTION(lms, ClientConnect) } } +MUTATOR_HOOKFUNCTION(lms, AutoJoinOnConnection) +{ + return true; +} + MUTATOR_HOOKFUNCTION(lms, PlayerPreThink) { entity player = M_ARGV(0, entity); @@ -377,7 +382,7 @@ MUTATOR_HOOKFUNCTION(lms, Bot_FixCount, CBC_ORDER_EXCLUSIVE) MUTATOR_HOOKFUNCTION(lms, ClientCommand_Spectate) { - entity player = M_ARGV(0, entity); + entity player = M_ARGV(0, entity); if(warmup_stage || player.lms_spectate_warning) {