Browse Source

Refire team select panels if on cooldown

nosoop 2 years ago
parent
commit
fd0bda8a03
2 changed files with 44 additions and 3 deletions
  1. 4 2
      README.md
  2. 40 1
      scripting/csrd_jointeam_fix.sp

+ 4 - 2
README.md

@@ -7,8 +7,10 @@ select menu.
 
 The issue (as far as I'm personally aware) is described at [ValveSoftware/Source-1-Games#3651][].
 
-The fix involves a delayed resending of the team select panel if the player attempted to join a
-team while the command was on cooldown.
+The fix involves a delayed resending of the team select panel if:
+
+- the player attempted to join a team while the command was on cooldown, and
+- the server attempts to send one to a player while they are on cooldown
 
 [ValveSoftware/Source-1-Games#3651]: https://github.com/ValveSoftware/Source-1-Games/issues/3651
 

+ 40 - 1
scripting/csrd_jointeam_fix.sp

@@ -8,7 +8,7 @@
 
 #pragma newdecls required
 
-#define PLUGIN_VERSION "1.0.0"
+#define PLUGIN_VERSION "1.1.0"
 public Plugin myinfo = {
 	name = "[CSRD] `jointeam` Fix",
 	author = "nosoop",
@@ -30,6 +30,9 @@ public void OnPluginStart() {
 	tf_arena_use_queue = FindConVar("tf_arena_use_queue");
 	
 	AddCommandListener(OnClientJoinTeam, "jointeam");
+	
+	UserMsg vguiMessage = GetUserMessageId("VGUIMenu");
+	HookUserMessage(vguiMessage, OnVGUIMenuPreSent, true);
 }
 
 /**
@@ -53,6 +56,42 @@ Action OnClientJoinTeam(int client, const char[] command, int argc) {
 	return Plugin_Continue;
 }
 
+/**
+ * Intercepts attempts to transmit the team select panel to a client, delaying transmission if
+ * the player is unassigned and on cooldown.
+ */
+Action OnVGUIMenuPreSent(UserMsg vguiMessage, BfRead buffer, const int[] players,
+		int nPlayers, bool reliable, bool init) {
+	// vgui usermessages are expected to only have a single recipient
+	if (nPlayers != 1) {
+		return Plugin_Continue;
+	}
+	
+	char name[128];
+	buffer.ReadString(name, sizeof(name));
+	
+	if (!StrEqual(name, "arenateampanel") && !StrEqual(name, "team")) {
+		return Plugin_Continue;
+	}
+	
+	int client = players[0];
+	if (GetClientTeam(client)) {
+		return Plugin_Continue;
+	}
+	
+	float flNextAllowedTeamChange = GetEntDataFloat(client,
+			offs_CTFPlayer_flNextTimeAllowTeamChange);
+	if (flNextAllowedTeamChange > GetGameTime()) {
+		// we're not allowed to change teams right now --
+		// silently block the attempt then redisplay once the cooldown is over
+		CreateTimer(0.1 + flNextAllowedTeamChange - GetGameTime(), RedisplayTeamSelectMenu,
+				GetClientSerial(client), TIMER_FLAG_NO_MAPCHANGE);
+		return Plugin_Handled;
+	}
+	
+	return Plugin_Continue;
+}
+
 /**
  * Redisplay the team select panel.
  */