splewis / get5

CS:GO Sourcemod plugin for competitive matches/scrims
GNU General Public License v3.0
556 stars 174 forks source link

Disable the teamjoin menu #2

Closed splewis closed 2 years ago

splewis commented 8 years ago

Hinges on #1's completion.

Two parts:

jfkz commented 8 years ago

We've tested most situation of your plugin. I totally prove: this code works as expected https://github.com/jfkz/get5/commit/921fbb940655e295a63b44ac2da98f4ae134fb76#diff-e8739654d1116a471bcf5b790538274eR8

splewis commented 8 years ago

The last time I worked on the team logic (which was 6 months ago when I made https://github.com/splewis/get5/issues/1), I could not get team placements during halftime periods to work consistently at all. I didn't know whether clients should be placed on their 1st half team or their 2nd half team if they connect during the halftime. I tried both, and always saw issues. I suspect the transition has to be done sometime during the middle of the halftime.

All that is to say, disabling the teamjoin menu isn't such a good idea since it will cause issues for clients if they join during a halftime period - they will be unable to get onto a team until they use a jointeam command in console once the halftime period is over.

jfkz commented 8 years ago

Ok. I just want to say that I uncomment your code and it works fine in any cases that I tested. And that's all =)

splewis commented 7 years ago

https://forums.alliedmods.net/showpost.php?p=2543217&postcount=38 might help

public void OnPluginStart()
{
    HookUserMessage(GetUserMessageId("VGUIMenu"), TeamMenuHook, true);
}

public Action TeamMenuHook(UserMsg msg_id, Protobuf msg, const int[] players, int playersNum, bool reliable, bool init)
{
    char buffermsg[64];

    PbReadString(msg, "name", buffermsg, sizeof(buffermsg));

    if (StrEqual(buffermsg, "team", true))
    {
        int client = players[0];

        //Do stuff here
        //You can acess the client's int as I defined it in "int client = players[0];"
    }

    return Plugin_Handled;
}  
rgoupil commented 5 years ago

~FYI, we had success making this work simply by changing this:~

EDIT: nevermind, while it is working, this change seem to randomly cause the server to reject player connections with the message You may only join this server from a lobby and then abort the match. I haven't been able to pinpoint why yet but I suspect a race condition while obtaining the team or the auth of the player followed by some critical failure, leading to the match being reset. This first match after starting the server is always fine, the issue only randomly trigger when reusing the server for other matches.

public Action Command_JoinGame(int client, const char[] command, int argc) {
  if (g_GameState == Get5State_None) {
    return Plugin_Continue;
  }

  // TODO: if we want to bypass the teammenu, this is probably the best
  // place to put the player onto a team.
  // if (IsPlayer(client)) {
  //     FakeClientCommand(client, "jointeam 2");
  // }

  return Plugin_Continue;
}

in this

public Action Command_JoinGame(int client, const char[] command, int argc) {
  if (g_GameState == Get5State_None) {
    return Plugin_Continue;
  }

  if (!g_CheckAuthsCvar.BoolValue) {
    return Plugin_Continue;
  }

  if (IsPlayer(client)) {
    CheckClientTeam(client);
  }

  return Plugin_Continue;
}

The player automatically join the right team upon connection (not tested with coach and casters yet). If that looks good to you @splewis we could make a PR after adding a cvar to enforce auto team join and thoroughly testing the behaviour.

fayeinmay commented 5 years ago

This is my current solution for my 5on5 plugin which I use for my upcoming website, feel free to use it:

OnPluginStart;

HookUserMessage(GetUserMessageId("VGUIMenu"), TeamMenuHook, true);

Actual logic: Note: Timer with at least 0.1 must be used, otherwise changing a players team in this function may cause a fatal error and a server crash.

public Action TeamMenuHook(UserMsg msg_id, Protobuf msg, const int[] players, int playersNum, bool reliable, bool init)
{
    char buffermsg[64];

    PbReadString(msg, "name", buffermsg, sizeof(buffermsg));

    if (StrEqual(buffermsg, "team", true)){
        int client = players[0];

        if (CurrentRound == KNIFE_ROUND || CurrentRound == MATCH) {
            CreateTimer(0.1, TeamSelectTimer, client);
        }
    }

    return Plugin_Continue;
}

public Action TeamSelectTimer(Handle timer, int data) {
    putPlayerInCorrectTeamAfterWarmup(data);

    return Plugin_Handled;
}
fayeinmay commented 5 years ago

Oh, I just saw that you already posted that solution. ;D My bad. (However, I can confirm that this solution works.)

splewis commented 5 years ago

Pull requests are welcome.