From 6abb0d521daf4d2739444500eea6d301d158ac29 Mon Sep 17 00:00:00 2001 From: terencehill Date: Tue, 11 May 2021 15:45:26 +0200 Subject: [PATCH] Fix kicked player not receiving the kick message (if sent with Send_Notification) --- .../kick_teamkiller/sv_kick_teamkiller.qc | 4 +-- qcsrc/server/client.qc | 9 +++-- qcsrc/server/main.qc | 34 +++++++++++++++++++ qcsrc/server/main.qh | 2 ++ 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/qcsrc/common/mutators/mutator/kick_teamkiller/sv_kick_teamkiller.qc b/qcsrc/common/mutators/mutator/kick_teamkiller/sv_kick_teamkiller.qc index d91546af5..f8e364fdd 100644 --- a/qcsrc/common/mutators/mutator/kick_teamkiller/sv_kick_teamkiller.qc +++ b/qcsrc/common/mutators/mutator/kick_teamkiller/sv_kick_teamkiller.qc @@ -28,7 +28,7 @@ MUTATOR_HOOKFUNCTION(kick_teamkiller, PlayerDies) if (teamkills >= autocvar_g_kick_teamkiller_lower_limit && teamkills >= autocvar_g_kick_teamkiller_rate*playtime/60.0) { - Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_QUIT_KICK_TEAMKILL, attacker.netname); - dropclient(attacker); + if (dropclient_schedule(attacker)) + Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_QUIT_KICK_TEAMKILL, attacker.netname); } } diff --git a/qcsrc/server/client.qc b/qcsrc/server/client.qc index 01426367a..7d3c1faca 100644 --- a/qcsrc/server/client.qc +++ b/qcsrc/server/client.qc @@ -2458,9 +2458,8 @@ void PlayerPreThink (entity this) && (IS_SPEC(this) || IS_OBSERVER(this)) && !this.caplayer && time > (CS(this).spectatortime + autocvar_g_maxplayers_spectator_blocktime)) { - Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_QUIT_KICK_SPECTATING); - dropclient(this); - return; + if (dropclient_schedule(this)) + Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_QUIT_KICK_SPECTATING); } } @@ -2747,8 +2746,8 @@ void PlayerPostThink (entity this) } else { - Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_QUIT_KICK_IDLING, this.netname, maxidle_time); - dropclient(this); + if (dropclient_schedule(this)) + Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_QUIT_KICK_IDLING, this.netname, maxidle_time); } return; } diff --git a/qcsrc/server/main.qc b/qcsrc/server/main.qc index 13574bf0e..73f473ae9 100644 --- a/qcsrc/server/main.qc +++ b/qcsrc/server/main.qc @@ -26,6 +26,40 @@ #include #include +void dropclient_do(entity this) +{ + if (this.owner) + dropclient(this.owner); + delete(this); +} +/** + * Schedules dropclient for a player and returns true; + * if dropclient is already scheduled (for that player) it does nothing and returns false. + * + * NOTE: this function exists only to allow sending a message to the kicked player with + * Send_Notification, which doesn't work if called together with dropclient + */ +bool dropclient_schedule(entity this) +{ + bool scheduled = false; + FOREACH_ENTITY_CLASS("dropclient_handler", true, + { + if(it.owner == this) + { + scheduled = true; + break; // can't use return here, compiler shows a warning + } + }); + if (scheduled) + return false; + + entity e = new_pure(dropclient_handler); + setthink(e, dropclient_do); + e.owner = this; + e.nextthink = time + 0.1; + return true; +} + void CreatureFrame_hotliquids(entity this) { if (this.contents_damagetime >= time) diff --git a/qcsrc/server/main.qh b/qcsrc/server/main.qh index 0685ca71f..e189601a7 100644 --- a/qcsrc/server/main.qh +++ b/qcsrc/server/main.qh @@ -16,6 +16,8 @@ bool autocvar_g_balance_falldamage_onlyvertical; #define autocvar_slowmo cvar("slowmo") float autocvar_sys_ticrate; +bool dropclient_schedule(entity this); + /** print(), but only print if the server is not local */ void dedicated_print(string input); -- 2.39.2