Raised This Month: $51 Target: $400
 12% 

Solved [CSGO] Plugin spawns a client with opposite team [solved 6/14/20]


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Effeff
AlliedModders Donor
Join Date: Jan 2019
Location: discord: ff#0533
Old 04-07-2020 , 03:31   [CSGO] Plugin spawns a client with opposite team [solved 6/14/20]
Reply With Quote #1

Solution in quote below
(Thanks to MAMAC for explaining and showing me the plugin that solved the issue here https://github.com/NotJustin/SkillAutoBalance/issues/7)

Quote:
Originally Posted by Effeff View Post
Solved. The problem was specifically with forcing clients to join a team when they connect to the server. This plugin [CSGO] Auto Assign Team by SM9 fixes the problem. Here is what they do differently from what I was doing:
  • Force a client on a team inside the event hook for "player_connect_full"
  • Force a client to join a team using the ClientCommand "jointeam".
I am unsure of which of these in particular fixes the issue. My assumption is using the ClientCommand directly instead of ChangeClientTeam.
Using this plugin, when a new client joins my server they spawn with the other team (rarely).

PHP Code:
#include <sourcemod>
#include <sdktools_functions>
#include <sdktools_gamerules>

#define TEAM_SPEC 1
#define TEAM_T 2
#define TEAM_CT 3

// List of clients (in a separate array because I want to re-arrange the order later)
ArrayList g_iClients;

// The team that client i "belongs" on (the team they were on before switching to spectate, so they must only join that same team)
int g_iClientTeam[MAXPLAYERS 1];

public 
Plugin myinfo =
{
    
name "debug",
    
author "Justin (ff)",
    
description "Balance teams when one side is stacked",
    
version "2.1.4",
    
url "https://steamcommunity.com/id/NameNotJustin/"
}

public 
void OnPluginStart()
{
    
// Initialize the client array
    
g_iClients = new ArrayList();

    
// Create the jointeam listener
    
AddCommandListener(CommandList_JoinTeam"jointeam");
}

// Jointeam listener
Action CommandList_JoinTeam(int client, const char[] commandint argc)
{
    
// Get team client is trying to join
    
char arg[5];
    
GetCmdArg(1argsizeof(arg));
    
int newTeam StringToInt(arg);

    
// If they are trying to join spectate, let them without changing what their team is in g_iClientTeam
    // Otherwise, check if they can join the specific team (it will always either be TEAM_T or TEAM_CT)
    
if (newTeam == TEAM_SPEC)
    {
        return 
Plugin_Continue;
    }
    else if (!
CanJoin(clientnewTeam))
    {
        
// If they can't join, don't let them switch team
        
return Plugin_Handled;
    }
    
// Otherwise, let them switch team and update what team they "belong" on in g_iClientTeam
    
g_iClientTeam[client] = newTeam;
    return 
Plugin_Continue;
}

// Logic for whether or not a client can join a team
bool CanJoin(int clientint team)
{
    
// Abstract way to check if the team the client is trying to join has more players than the opposite team
    
int count[2];
    
count[0] = GetTeamClientCount(TEAM_T);
    
count[1] = GetTeamClientCount(TEAM_CT);
    
int newTeamCount count[team 2];
    
int otherTeamCount count[(team 1) % 2];

    
// If the new team has more players, never let them join
    // If both teams have the same amount of players, do not let them join unless they "belong" on that team
    // If the team the client wants to join has LESS players, do not let them join unless the client is currently in spectate (this is necessary because it allows a person to join a team they don't belong in only if it is impossible for them to join the team they do belong in due to the team having more players)
    
if (newTeamCount otherTeamCount)
    {
        return 
false;
    }
    else if (
newTeamCount == otherTeamCount && g_iClientTeam[client] == team)
    {
        return 
true;
    }
    else if (
newTeamCount otherTeamCount && GetClientTeam(client) == TEAM_SPEC)
    {
        return 
true;
    }
    return 
false;
}

// custom stock for checking if client is valid
stock bool IsClientValid(int client)
{
    return (
client >= && client <= MaxClients && IsClientInGame(client) && !IsFakeClient(client));
}

// When a client loads into the map, disable the team menu so that they cannot manually choose a team
public void OnClientPutInServer(int client)
{
    
GameRules_SetProp("m_bIsQueuedMatchmaking"1);
    
//Re-enable the team menu after 5 seconds, in case somehow they disconnect here before OnClientPostAdminCheck occurs
    
CreateTimer(5.0EnableTeamMenu);
}

// Re-enable the team menu after 5 seconds
Action EnableTeamMenu(Handle timer)
{
    
GameRules_SetProp("m_bIsQueuedMatchmaking"0);
    return 
Plugin_Handled;
}

//After 1 second, force the client to join a team
public void OnClientPostAdminCheck(int client)
{
    
int userId GetClientUserId(client);
    
CreateTimer(1.0ForceJoinuserId);
}

// Force the client to join a team
Action ForceJoin(Handle timerint userId)
{
    
int client GetClientOfUserId(userId);
    
// If the client is valid
    
if (IsClientValid(client))
    {
        
// Get the smallest team
        
int team GetSmallestTeam();
        
// Change the client's team to the smallest team
        
ChangeClientTeam(clientteam);
        
// Update the team that the client "belongs" on
        
g_iClientTeam[client] = team;
        
// Re-enable the team menu (I still want players to be able to switch to spectate)
        
GameRules_SetProp("m_bIsQueuedMatchmaking"0);
    }
}

// Get the smallest team
int GetSmallestTeam()
{
    
// Compare the sizes of the two teams. If they're the same, return either, otherwise, return the smallest.
    
int tSize GetTeamClientCount(TEAM_T);
    
int ctSize GetTeamClientCount(TEAM_CT);
    if(
tSize == ctSize)
    {
        return 
GetRandomInt(TEAM_TTEAM_CT);
    }
    return 
tSize ctSize TEAM_T TEAM_CT;
}

// When a client disconnects, erase them from the client array and "reset" the team that the client index belongs in to be neither TEAM_T nor TEAM_CT
public void OnClientDisconnect(int client)
{
    
int index g_iClients.FindValue(client);
    if (
index != -1)
    {
        
g_iClients.Erase(index);
    }
    
g_iClientTeam[client] = TEAM_SPEC;

Can anyone find some kind of flaw in the logic with this plugin or something?
Attached Files
File Type: sp Get Plugin or Get Source (skillautobalance_remake.sp - 198 views - 4.8 KB)

Last edited by Effeff; 06-14-2020 at 15:19. Reason: Solved
Effeff is offline
Effeff
AlliedModders Donor
Join Date: Jan 2019
Location: discord: ff#0533
Old 04-10-2020 , 00:52   Re: [CSGO] Bug w/ my plugin spawns a client with opposite team
Reply With Quote #2

Hiding old/irrelevant info, just see OP
Spoiler

Last edited by Effeff; 05-21-2020 at 15:32.
Effeff is offline
Bacardi
Veteran Member
Join Date: Jan 2010
Location: mom's basement
Old 04-10-2020 , 02:17   Re: [CSGO] Bug w/ my plugin spawns a client with opposite team
Reply With Quote #3

You get this problem on warmups or anytime?
What is your game mode ? Have you fast respawn enabled?
__________________
Do not Private Message @me
Bacardi is offline
Effeff
AlliedModders Donor
Join Date: Jan 2019
Location: discord: ff#0533
Old 04-10-2020 , 03:04   Re: [CSGO] Bug w/ my plugin spawns a client with opposite team
Reply With Quote #4

Quote:
Originally Posted by Bacardi View Post
You get this problem on warmups or anytime?
What is your game mode ? Have you fast respawn enabled?
Casual, round based, no warmup, no respawn until next round.

gamemode is just this:
Code:
"Gamemodes_Server.txt"
{
	"gameTypes"
	{
		"classic"
		{
			"gameModes"
			{
				"casual"
				{
					"exec"
					{
						"exec"	"server.cfg"
					}
				}
			}
		}
	}
}
Here is config minus stuff i shouldn't share:

Code:
sv_prime_accounts_only 0 //allow non-prime users to join

host_name_store 1
host_info_show 2
host_players_show 2
sv_holiday_mode 0

//stuff related to downloading workshop maps
ds_get_newest_subscribed_files
sv_broadcast_ugc_downloads 1
sv_debug_ugc_downloads 1
sv_broadcast_ugc_download_progress_interval 8

sv_disable_radar 1	//disable radar

// Voice
sv_voiceenable 1
sv_voicecodec vaudio_celt
sv_alltalk 1					// Players can hear all other players' voice communication, no team restrictions
sv_deadtalk 1					// Dead players can speak (voice, text) to the living
sv_full_alltalk 1				// Any player (including Spectator team) can speak to any other player
sv_talk_enemy_living 1
sv_talk_enemy_dead 1

// Team balance
mp_autoteambalance 1
mp_limitteams 1

// Time limits
mp_freezetime 0
mp_buytime 0
mp_warmuptime 0
mp_halftime 0
mp_roundtime 1
mp_timelimit 20
mp_round_restart_delay 3

// Bots
bot_difficulty 3
bot_join_after_player 1
bot_quota_mode fill
bot_quota 0
bot_auto_vacate 1

// Match & map end
mp_win_panel_display_time 0
mp_endmatch_votenextmap 0
mp_endmatch_votenextmap_keepcurrent 0
mp_match_end_restart 0
mp_match_restart_delay 0 
mp_match_end_changelevel 1
mp_match_can_clinch 0
mp_halftime 0
mp_halftime_duration 0

// Misc. sv_
sv_allow_wait_command 0			// Allow or disallow the wait command on clients connected to this server.
sv_cheats 0
sv_consistency 0				// Whether the server enforces file consistency for critical files
sv_contact 0					// Contact email for server sysop
sv_dc_friends_reqd 0
sv_gameinstructor_disable 0		// Force all clients to disable their game instructors.
sv_lan 0
sv_pausable 0
sv_pure_kick_clients 1
sv_pure_trace 0					// If set to 1, the server will print a message whenever a client is verifying a CR

// Misc. mp_
mp_autokick 0					// Kick idle/team-killing players
mp_maxmoney 0					// maximum amount of money allowed in a player's account
mp_playercashawards 0			// Players can earn money by performing in-game actions
mp_do_warmup_period 0			// Whether or not to do a warmup period at the start of a match.
mp_force_pick_time 3600			// High number so it doesn't mess with auto-balance 
mp_force_assign_teams 0			// Do not force players onto teams (i would like to see how this command works later)
mp_startmoney 0
mp_teamcashawards 0				// Teams can earn money by performing in-game actions
mp_solid_teammates 2 		//Determines whether teammates are solid or not.
mp_free_armor 0				//Determines whether armor and helmet are given automatically.
mp_drop_knife_enable 1
mp_friendlyfire 0
mp_forcecamera 0
mp_fraglimit 0
mp_winlimit 0
mp_maxrounds 0
mp_weapons_allow_map_placed 0
mp_spectators_max 10

// Misc. commands
spec_freeze_time 0
spec_freeze_panel_extended_time 0

// Voting
sv_allow_votes 0
sv_vote_allow_in_warmup 0
mp_endmatch_votenextmap 0
mp_endmatch_votenextleveltime 0
mp_endmatch_votenextmap_keepcurrent 0

// Spawn with AWP
mp_t_default_primary weapon_awp
mp_t_default_secondary ""
mp_t_default_melee "weapon_knife"
mp_ct_default_primary weapon_awp
mp_ct_default_secondary ""
mp_ct_default_melee "weapon_knife"

// Deal damage through teammates
ff_damage_bullet_penetration 1

// Spec replay
tv_enable 1
tv_delay 30
tv_advertise_watchable 1
spec_replay_enable 1
spec_replay_leadup_time 2.5

//testing 128 tickrate demo recording (instead of 32 tick)
sv_maxupdaterate 128
sv_minupdaterate 128
tv_snapshotrate 128
tv_maxclients 10
tv_maxrate 196608
tv_snapshotrate 128
tv_timeout 60
sv_hibernate_postgame_delay 180

sm_cvar sv_full_alltalk 1
sv_competitive_official_5v5 1	// Enable XRay in spectator
Effeff is offline
Notifications
AlliedModders Donor
Join Date: Oct 2015
Old 04-12-2020 , 13:28   Re: [CSGO] Bug w/ my plugin spawns a client with opposite team
Reply With Quote #5

That's a bug with the game itself, not your plugin. If you spam a team when joining (1 or 2) using the numbers - you sometimes spawn either outside the map or in some dumb spot.
Notifications is offline
Bacardi
Veteran Member
Join Date: Jan 2010
Location: mom's basement
Old 04-12-2020 , 13:47   Re: [CSGO] Bug w/ my plugin spawns a client with opposite team
Reply With Quote #6

Quote:
Originally Posted by Notifications View Post
That's a bug with the game itself, not your plugin. If you spam a team when joining (1 or 2) using the numbers - you sometimes spawn either outside the map or in some dumb spot.
This could lead to that "blocking" spectator bug, player have re-spawn in spectators team (1).
I blame CSGO fast respawn system. It also add extra bots on server even you don't want to.
__________________
Do not Private Message @me
Bacardi is offline
Effeff
AlliedModders Donor
Join Date: Jan 2019
Location: discord: ff#0533
Old 04-12-2020 , 21:00   Re: [CSGO] Bug w/ my plugin spawns a client with opposite team
Reply With Quote #7

Quote:
Originally Posted by Notifications View Post
That's a bug with the game itself, not your plugin. If you spam a team when joining (1 or 2) using the numbers - you sometimes spawn either outside the map or in some dumb spot.
edit: I wrote before, it is caused by my plugin.

However.

I have disabled the thing that freezes players, so now when they are swapped it just switches their team and player model.

The bug still occurs where they freeze in either their spawn or their opponent's spawn somehow.

Now I'm just more confused.

Last edited by Effeff; 04-13-2020 at 00:52.
Effeff is offline
Effeff
AlliedModders Donor
Join Date: Jan 2019
Location: discord: ff#0533
Old 05-21-2020 , 15:21   Re: [CSGO] Plugin spawns a client with opposite team [updated 5/21/20]
Reply With Quote #8

Bump, see OP (ignore everything else I've posted as replies because it's all speculation). Still unresolved.

As for what Notifications said here, https://forums.alliedmods.net/showpo...46&postcount=5
I have ruled this out by disabling the team menu when clients join, so spamming 1 or 2 does nothing.

If it is truly a fault of CSGO and not a fault of the plugin, is there a way to get around this? Should I force clients to go to spectator when they connect, and wait a longer period of time before putting them on a team?
Effeff is offline
Effeff
AlliedModders Donor
Join Date: Jan 2019
Location: discord: ff#0533
Old 06-14-2020 , 15:13   Re: [CSGO] Plugin spawns a client with opposite team [updated 5/21/20]
Reply With Quote #9

Solved. The problem was specifically with forcing clients to join a team when they connect to the server. This plugin [CSGO] Auto Assign Team by SM9 fixes the problem. Here is what they do differently from what I was doing:
  • Force a client on a team inside the event hook for "player_connect_full"
  • Force a client to join a team using the ClientCommand "jointeam".
I am unsure of which of these in particular fixes the issue. My assumption is using the ClientCommand directly instead of ChangeClientTeam.
Effeff is offline
mrtn
Junior Member
Join Date: May 2020
Old 06-18-2020 , 11:44   Re: [CSGO] Plugin spawns a client with opposite team [solved 6/14/20]
Reply With Quote #10

Hey Effeff, I see you've found a solution already, but I previously spent longer than I'd like to admit on the same issue (and the incredibly frustrating bot side effect behaviour mentioned by Barcardi https://forums.alliedmods.net/showpo...53&postcount=6), and came up with a slightly different solution that may be of use to you or others:

Like you, I hook `player_connect_full` (using the default post hook mode) and perform the following actions:

PHP Code:
// Set the Client's m_fForceTeam entity prop value to 0.0, which bypasses the selection screen
SetEntPropFloat(iClientIdProp_Send"m_fForceTeam"0.0);

// Move the player to the desired team on the next game frame
RequestFrame(Utils_MoveClientToCsTeamiClientId); 
PHP Code:
stock void Utils_MoveClientToCsTeam(int iClientId)
{
    
// Determine which team the client belongs to (hard-coded in this example)
    
int iCsTeam CS_TEAM_T;
    
    
// Note this will only move to CT or T; To move to spectator use ChangeClientTeam()
    
CS_SwitchTeam(iClientIdiCsTeam);

The above also works for bots, but one must hook earlier in the chain, either player_connect or OnClientConnect forward.

I abandoned other methods such as using convars (mp_force_pick_time, mp_force_assign_teams), setting an extremely high m_fForceTeam value (to prevent automatic selection), and trying to manipulate m_iTeamNum, as these yielded mixed results (often resulting in UI issues on the team select interface).

Reading over your solution, I wonder if the key was using ClientCommand to send jointeam, which may execute on the following frame (similar to my solution)?



Re The fast respawn process causing unnecessary bots to join: To resolve (read: workaround ) I created a listener on `jointeam`, which blocks `bot_add_ct, bot_add_t` commands sent on the subsequent game tick. Hacky, but c'est la vie
mrtn is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 17:04.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode