NeotokyoRebuild / neo

NEOTOKYO Rebuild - Source SDK 2013 mod of NEOTOKYO
Other
11 stars 9 forks source link

Do not open class/loadout menu if you are spectating #397

Closed VantoNortim closed 5 days ago

VantoNortim commented 1 week ago

Description

Do not open the Class or Loadout menu while being in team Spectate/Unassigned

Toolchain

Linked Issues

nullsystem commented 1 week ago

@VantoNortim btw this branch is very behind the current master branch, suggest you rebase it

VantoNortim commented 6 days ago

This prevents the player from picking their class and loadout when they are first joining a playing team from spectator, because the associated jointeam command has not been processed yet.

The simplest solution is probably to just assign the client's team locally before these callbacks are invoked, for example:

diff --git a/mp/src/game/client/neo/game_controls/neo_teammenu.cpp b/mp/src/game/client/neo/game_controls/neo_teammenu.cpp
index 8658be7..1d095b0 100644
--- a/mp/src/game/client/neo/game_controls/neo_teammenu.cpp
+++ b/mp/src/game/client/neo/game_controls/neo_teammenu.cpp
@@ -177,6 +177,7 @@ void CNeoTeamMenu::OnCommand(const char *command)
      const int nsfNumPlayers = (pNsf != NULL ? pNsf->Get_Number_Players() : 0);
      int randomTeam = jinNumPlayers > nsfNumPlayers ? TEAM_NSF : (nsfNumPlayers > jinNumPlayers ? TEAM_JINRAI : RandomInt(TEAM_JINRAI, TEAM_NSF));
      V_sprintf_safe(commandBuffer, "jointeam %i", randomTeam);
+     C_NEO_Player::GetLocalNEOPlayer()->m_iTeamNum = randomTeam;
      ChangeMenu("classmenu");
      engine->ClientCmd(commandBuffer);
      return;
@@ -197,7 +198,25 @@ void CNeoTeamMenu::OnCommand(const char *command)
  }

  if (Q_stristr(commandBuffer, "jointeam") != 0) // Note using stristr, not strcmp. Equates to true when jointeam in commandBuffer
- { // joining jinrai or nsf
+ { // joining something other than TEAM_SPECTATOR or TEAM_NONE
+     CUtlStringList strs;
+     V_SplitString(commandBuffer, "jointeam ", strs);
+     if (strs.Count() != 0)
+     {
+         char* szNum = strs[0];
+         const int len = V_strlen(szNum);
+         for (int i = 0; i < len; ++i)
+         {
+             if (!V_isdigit(szNum[i]))
+             {
+                 szNum[i] = '\0';
+                 break;
+             }
+         }
+         const int team = V_atoi(szNum);
+         C_NEO_Player::GetLocalNEOPlayer()->m_iTeamNum = team;
+     }
+
      ChangeMenu("classmenu");
      engine->ClientCmd(commandBuffer);
      return;

But maybe double check that C string manipulation stuff 😄

The m_iTeamNum is networked, so any discrepancy should get overwritten by the server once it has processed the team request, so there's no need to do super strict validation here.

I found a better way to do this, by just forcing the team change to execute first. This way it just works.

Rainyan commented 6 days ago

I still can't see the class and loadout menus appear. Breakpointing on the engine->ExecuteClientCmd, and then continuing execution makes them appear, but by just running the game without breaking on the instruction I get:

I'm assuming there's some kind of data race happening.

Rainyan commented 6 days ago

class_loadout.webm

Well, it's still doing this thing for me where I can't choose a class or loadout. 🤷‍♂️ Perhaps someone else should test this on their machine to see if it's an issue on my end.

AdamTadeusz commented 6 days ago

class_loadout.webm

Well, it's still doing this thing for me where I can't choose a class or loadout. 🤷‍♂️ Perhaps someone else should test this on their machine to see if it's an issue on my end.

Is this on a dedicated server? Just tested on a listen server and having no trouble selecting team and loadout

(edit) ill test on dedicated in a sec

Rainyan commented 6 days ago

Is this on a dedicated server?

This is on a listen server. I've tried with a full rebuild and it still occurs. But I guess it's verified an issue on my end then, whatever it is.

AdamTadeusz commented 6 days ago

I noticed on dedicated the class selection menu doesn;t open up after pickign a team like on a listen server, but I can still use f2 to open it and select that way. Now I gotta check master to see whether the same behaviour is on there

AdamTadeusz commented 6 days ago

Is this on a dedicated server?

This is listen server. I've tried with a full rebuild and it still occurs. But I guess it's verified an issue on my end then, whatever it is.

So statistically speaking 33% of the playerbase will not be able to select their class after they join a server?

VantoNortim commented 6 days ago

I am going to need more time to look into this then, I would have thought there is an event client side when the player switches teams. Maybe I should clean up opening those elements in general there are so many bools in the player class related to them. But surely we could just check if any of them are visible and so on.

If it is a race condition it would still help to know what causes that.

AdamTadeusz commented 6 days ago

I noticed you were setting the value of m_iTeam locally before making a request to change the local player's team to that team via a command, so I changed how the function to open the class and loadout menus check what team the local player is on to this and now the problems I mentioned before are gone image

@Rainyan Could you do the same things I did in the two functions on line 216 and 293 and then see if the problem is resolved?

(edit) this is in c_neo_player

(edit 2) doing it this way isn't actually any different from the original, I have no clue why this fixed it for me, probably still a race condition thing

VantoNortim commented 6 days ago

I noticed you were setting the value of m_iTeam locally before making a request to change the local player's team to that team via a command, so I changed how the function to open the class and loadout menus check what team the local player is on to this and now the problems I mentioned before are gone image

@Rainyan Could you do the same things I did in the two functions on line 216 and 293 and then see if the problem is resolved?

(edit) this is in c_neo_player

(edit 2) doing it this way isn't actually any different from the original, I have no clue why this fixed it for me, probably still a race condition thing

Yeah I think I will have to hook on the team change event sent by server and once that is ran I will show the class menu.