need working script that acutally switches player for csgo

Please post any questions about developing your plugin here. Please use the search function before posting!
8guawong
Senior Member
Posts: 148
Joined: Sat Sep 20, 2014 3:06 am

need working script that acutally switches player for csgo

Postby 8guawong » Mon Oct 06, 2014 3:03 am

Hello I've given up on trying... so would some1 make a script for me... :tongue:

This script should keep 1 T and rest goes to CT
and at round end T will be switched to CT and a random CT will be switched to T
also prevent the map time from reseting!!

thanks!




------------------------------------------------------------ edit -----------------------------------------------------------------------


this is for csgo

Syntax: Select all

@Event
def round_end(game_event):
reason = game_event.get_int('reason')
t = random.sample(list(PlayerIter('t')), 1)
#if reason != 15:
ct = random.sample(list(PlayerIter('ct')), 1)
PlayerEntity(t[0]).team = 3
PlayerEntity(ct[0]).team = 2


ok the above switches the players at round_end.....
when i tested it 1 CT 1 T it'll go on endless round end if i don't use

Syntax: Select all

if reason != 15
keeps switching player

my explanination is b/c when round ends we switch the players but when round starts it view both team with 0 player with player joining hence firing the round_end with reason 15.....

now if i use

Syntax: Select all

if reason != 15
the scripts runs fine but the players don't get changed... the scoreboard still shows players pending team change... but when round starts you end up on the same team...can't test with more people since i only have 2 steam account with csgo :cool:
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Mon Oct 06, 2014 4:12 pm

You could always try with bots to get more players, however, that still won't fix your issue when there is 1v1.

Maybe try adding a global variable to know when you are attempting to change teams. Set it to True when you have a 1v1. Then, set it back to False and return from round_end when it is True.
Image
8guawong
Senior Member
Posts: 148
Joined: Sat Sep 20, 2014 3:06 am

Postby 8guawong » Mon Oct 06, 2014 4:45 pm

sigh~~ can we end the round ourselves?
i'm thinking maybe set mp_ignore_round_win_conditions 1
and just check number of players on each team then fire round_end by ourselves
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Mon Oct 06, 2014 5:45 pm

Actually, you might check the m_iPendingTeamNum for players, and if any are pending, just return.
Image
8guawong
Senior Member
Posts: 148
Joined: Sat Sep 20, 2014 3:06 am

Postby 8guawong » Mon Oct 06, 2014 5:55 pm

here is my full code
it limits 1 player to T and rest to CT and switched players at then end of the round picking a CT randomly
this will switch the players BUT map time WILL restart

Syntax: Select all

from commands.client import ClientCommandFilter
from players.helpers import edict_from_playerinfo
from players.helpers import userid_from_playerinfo
from players.helpers import userid_from_index
from players.helpers import edict_from_index
from players.helpers import index_from_edict
from filters.players import PlayerIter
from players.entity import PlayerEntity
from messages import SayText2
from events import Event
from engines.server import engine_server
import random

new_t = 0

@ClientCommandFilter
def client_command_filter(player, command):
edict = edict_from_playerinfo(player)
userid = userid_from_playerinfo(player)
if command[0] == 'jointeam' and command[1] == '0':
if len(PlayerIter('t')) > 1:
engine_server.client_command(edict, 'jointeam 3')
return False
else:
return True
if command[0] == 'jointeam' and command[1] == '2':
if userid != new_t:
if len(PlayerIter('t')) > 1:
engine_server.client_command(edict, 'jointeam 3')
return False
else:
return True
else:
return True

@Event
def round_end(game_event):
global new_t
reason = game_event.get_int('reason')
if reason != 15:
ct = random.sample(list(PlayerIter('ct')), 1)
t = random.sample(list(PlayerIter('t')), 1)
new_t = userid_from_index(ct[0])
engine_server.client_command(edict_from_index(ct[0]), 'jointeam 2')
engine_server.client_command(edict_from_index(t[0]), 'jointeam 3')


Ayuto please don't comment about my code looks ugly please :cool:
Hedgehog
Member
Posts: 62
Joined: Sun Nov 03, 2013 8:54 pm

Postby Hedgehog » Mon Oct 06, 2014 7:59 pm

Try to add 2 seconds delay for changing players teams and/or godmode for all alive players.

Also, PlayerEntity.switch_team function should not kill player on team change.
User avatar
Ayuto
Project Leader
Posts: 2195
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Postby Ayuto » Mon Oct 06, 2014 8:00 pm

8guawong wrote:Ayuto please don't comment about my code looks ugly please :cool:

Okay... :(
8guawong
Senior Member
Posts: 148
Joined: Sat Sep 20, 2014 3:06 am

Postby 8guawong » Mon Oct 06, 2014 8:30 pm

Hedgehog wrote:Try to add 2 seconds delay for changing players teams and/or godmode for all alive players.

Also, PlayerEntity.switch_team function should not kill player on team change.


i tried respawning the player after they are switched but they respawn as their current team LOL .........
but if i use

PlayerEntity(ct[0]).team = 2

then respawn it'll work but round don't end anymore.... if one side dies.............
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Mon Oct 06, 2014 8:35 pm

A bit of advice. If you only need to concern yourself with the 'jointeam' client command, instead of using a filter, register the command:

Syntax: Select all

from commands.client import ClientCommand

@ClientCommand('jointeam')
def jointeam_filter(playerinfo, command):
# Do stuff...


Note that in this function, 'command' is the exact same instance as it would be if you used a client command filter. So, command[0] will always equal 'jointeam'.
Image
Hedgehog
Member
Posts: 62
Joined: Sun Nov 03, 2013 8:54 pm

Postby Hedgehog » Mon Oct 06, 2014 8:36 pm

8guawong wrote:
Hedgehog wrote:Try to add 2 seconds delay for changing players teams and/or godmode for all alive players.

Also, PlayerEntity.switch_team function should not kill player on team change.


i tried respawning the player after they are switched but they respawn as their current team LOL .........
but if i use

PlayerEntity(ct[0]).team = 2

then respawn it'll work but round don't end anymore.... if one side dies.............

But I didn't said anything about players respawning....
8guawong
Senior Member
Posts: 148
Joined: Sat Sep 20, 2014 3:06 am

Postby 8guawong » Mon Oct 06, 2014 8:42 pm

Hedgehog wrote:
8guawong wrote:
Hedgehog wrote:Try to add 2 seconds delay for changing players teams and/or godmode for all alive players.

Also, PlayerEntity.switch_team function should not kill player on team change.


i tried respawning the player after they are switched but they respawn as their current team LOL .........
but if i use

PlayerEntity(ct[0]).team = 2

then respawn it'll work but round don't end anymore.... if one side dies.............

But I didn't said anything about players respawning....


why would you want to put godmode on all alive players?? whats the reasoning for this??
i tried respawnining cuz i was thinking this would make the game think there is actually one person on another team...
also i know switch_team don't kill players but game is all weird after that.... round does not end if one side dies
8guawong
Senior Member
Posts: 148
Joined: Sat Sep 20, 2014 3:06 am

Postby 8guawong » Mon Oct 06, 2014 8:43 pm

satoon101 wrote:A bit of advice. If you only need to concern yourself with the 'jointeam' client command, instead of using a filter, register the command:

Syntax: Select all

from commands.client import ClientCommand

@ClientCommand('jointeam')
def jointeam_filter(playerinfo, command):
# Do stuff...


Note that in this function, 'command' is the exact same instance as it would be if you used a client command filter. So, command[0] will always equal 'jointeam'.


ok thanks and noted
8guawong
Senior Member
Posts: 148
Joined: Sat Sep 20, 2014 3:06 am

Postby 8guawong » Mon Oct 06, 2014 8:48 pm

ok i'm going to sleep (so tired from trying to figure this out) hopefully after i wake up some1 can figure out how to do it :cool:
User avatar
L'In20Cible
Project Leader
Posts: 1533
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Postby L'In20Cible » Mon Oct 06, 2014 11:51 pm

Well, I didn't test but, I could bet your issue is caused by your filter. You hook up "jointeam" and then force the player to execute that command again - this will call your filter over and over.
8guawong
Senior Member
Posts: 148
Joined: Sat Sep 20, 2014 3:06 am

Postby 8guawong » Tue Oct 07, 2014 12:31 am

L'In20Cible wrote:Well, I didn't test but, I could bet your issue is caused by your filter. You hook up "jointeam" and then force the player to execute that command again - this will call your filter over and over.


hi the issue right now is the map time will reset after switching team.............
User avatar
L'In20Cible
Project Leader
Posts: 1533
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Postby L'In20Cible » Tue Oct 07, 2014 4:13 am

Alright so I tested your code and it is not working. As soon as there is more than 1 player per team, the jointeam command is called twice (as expected by your code logic) and then, is not called again since the game itself is preventing the clients to spam that command. Anyways, forcing players to execute that command is probably the worst way to change their team. So yeah, I then tried the following code.

Syntax: Select all

from events import Event
from filters.players import PlayerIter
from players.entity import PlayerEntity
from players.helpers import index_from_playerinfo

@Event
def round_end(game_event):
for player in map(PlayerEntity, PlayerIter()):
if player.team not in (2, 3):
continue
player.switch_team(5 - player.team)
And faced ton of weird issues (player not respawning or spawning with no weapon in hand but still attacking, etc.) so indvestigated why and PlayerEntity.switch_team is not calling the function it should. Currently, it calls CBasePlayer::ChangeTeam.

Syntax: Select all

//================================================================================
// TEAM HANDLING
//================================================================================
//-----------------------------------------------------------------------------
// Purpose: Put the player in the specified team
//-----------------------------------------------------------------------------

void CBasePlayer::ChangeTeam( int iTeamNum, bool bAutoTeam, bool bSilent)
{
if ( !GetGlobalTeam( iTeamNum ) )
{
Warning( "CBasePlayer::ChangeTeam( %d ) - invalid team index.\n", iTeamNum );
return;
}

// if this is our current team, just abort
if ( iTeamNum == GetTeamNumber() )
{
return;
}

// Immediately tell all clients that he's changing team. This has to be done
// first, so that all user messages that follow as a result of the team change
// come after this one, allowing the client to be prepared for them.
IGameEvent * event = gameeventmanager->CreateEvent( "player_team" );
if ( event )
{
event->SetInt("userid", GetUserID() );
event->SetInt("team", iTeamNum );
event->SetInt("oldteam", GetTeamNumber() );
event->SetInt("disconnect", IsDisconnecting());
event->SetInt("autoteam", bAutoTeam );
event->SetInt("silent", bSilent );
if ( GetTeamNumber() == TEAM_UNASSIGNED )
{
event->SetString( "name", GetPlayerName() );
}
else
{
event->SetString( "name", "" ); // don't bother sending the name except on the first connect
}
event->SetBool("isbot", !IsNetClient());

gameeventmanager->FireEvent( event );
}

// Remove him from his current team
if ( GetTeam() )
{
GetTeam()->RemovePlayer( this );
}

// Are we being added to a team?
if ( iTeamNum )
{
GetGlobalTeam( iTeamNum )->AddPlayer( this );
}

BaseClass::ChangeTeam( iTeamNum );
}
As you can see, it does nothing else than, calling the player_team event with the given parameter, updating the cs_player_manager entities adding/removing the player and then setting m_iTeamNum by calling CBaseEntity::ChangeTeam. However, it requires more work than that to actually change a player team which is done by CCSPlayer::SwitchTeam. Once I updated the signature/symbol to the following:

Syntax: Select all

# CCSPlayer::SwitchTeam
[switch_team]
binary = csgo/bin/server
identifier_windows = " 55 8B EC 83 EC 10 53 56 8B 75 08 57 8B F9 85 F6 0F"
identifier_linux = _ZN9CCSPlayer10SwitchTeamEi
arguments = POINTER,INT
return_type = VOID
convention = THISCALL
srv_check = false
The code above worked just fine. All players are switched and the timeleft is never affected.
8guawong
Senior Member
Posts: 148
Joined: Sat Sep 20, 2014 3:06 am

Postby 8guawong » Tue Oct 07, 2014 4:32 am

L'In20Cible wrote:Alright so I tested your code and it is not working. As soon as there is more than 1 player per team, the jointeam command is called twice (as expected by your code logic) and then, is not called again since the game itself is preventing the clients to spam that command. Anyways, forcing players to execute that command is probably the worst way to change their team. So yeah, I then tried the following code.

Syntax: Select all

from events import Event
from filters.players import PlayerIter
from players.entity import PlayerEntity
from players.helpers import index_from_playerinfo

@Event
def round_end(game_event):
for player in map(PlayerEntity, PlayerIter()):
if player.team not in (2, 3):
continue
player.switch_team(5 - player.team)
And faced ton of weird issues (player not respawning or spawning with no weapon in hand but still attacking, etc.) so indvestigated why and PlayerEntity.switch_team is not calling the function it should. Currently, it calls CBasePlayer::ChangeTeam.

Syntax: Select all

//================================================================================
// TEAM HANDLING
//================================================================================
//-----------------------------------------------------------------------------
// Purpose: Put the player in the specified team
//-----------------------------------------------------------------------------

void CBasePlayer::ChangeTeam( int iTeamNum, bool bAutoTeam, bool bSilent)
{
if ( !GetGlobalTeam( iTeamNum ) )
{
Warning( "CBasePlayer::ChangeTeam( %d ) - invalid team index.\n", iTeamNum );
return;
}

// if this is our current team, just abort
if ( iTeamNum == GetTeamNumber() )
{
return;
}

// Immediately tell all clients that he's changing team. This has to be done
// first, so that all user messages that follow as a result of the team change
// come after this one, allowing the client to be prepared for them.
IGameEvent * event = gameeventmanager->CreateEvent( "player_team" );
if ( event )
{
event->SetInt("userid", GetUserID() );
event->SetInt("team", iTeamNum );
event->SetInt("oldteam", GetTeamNumber() );
event->SetInt("disconnect", IsDisconnecting());
event->SetInt("autoteam", bAutoTeam );
event->SetInt("silent", bSilent );
if ( GetTeamNumber() == TEAM_UNASSIGNED )
{
event->SetString( "name", GetPlayerName() );
}
else
{
event->SetString( "name", "" ); // don't bother sending the name except on the first connect
}
event->SetBool("isbot", !IsNetClient());

gameeventmanager->FireEvent( event );
}

// Remove him from his current team
if ( GetTeam() )
{
GetTeam()->RemovePlayer( this );
}

// Are we being added to a team?
if ( iTeamNum )
{
GetGlobalTeam( iTeamNum )->AddPlayer( this );
}

BaseClass::ChangeTeam( iTeamNum );
}
As you can see, it does nothing else than, calling the player_team event with the given parameter, updating the cs_player_manager entities adding/removing the player and then setting m_iTeamNum by calling CBaseEntity::ChangeTeam. However, it requires more work than that to actually change a player team which is done by CCSPlayer::SwitchTeam. Once I updated the signature/symbol to the following:

Syntax: Select all

# CCSPlayer::SwitchTeam
[switch_team]
binary = csgo/bin/server
identifier_windows = " 55 8B EC 83 EC 10 53 56 8B 75 08 57 8B F9 85 F6 0F"
identifier_linux = _ZN9CCSPlayer10SwitchTeamEi
arguments = POINTER,INT
return_type = VOID
convention = THISCALL
srv_check = false
The code above worked just fine. All players are switched and the timeleft is never affected.



so you are saying after i update the signature/symbole switch_team will work properly? :D

where can i find this so i can change it and test?? i'm so excited!!

nvm found it!

data\source-python\entities\functions\player
User avatar
L'In20Cible
Project Leader
Posts: 1533
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Postby L'In20Cible » Tue Oct 07, 2014 4:48 am

Sorry, I should have mentionned this signature is into ../csgo/addons/source-python/data/source-python/entities/functions/player/csgo.ini. All you have to do is replacing the following block:

Syntax: Select all

# CBasePlayer::ChangeTeam
[switch_team]
binary = csgo/bin/server
identifier_windows = " 55 8B EC 53 8B 5D 08 57 8B F9 85 DB 0F 88"
identifier_linux = _ZN11CBasePlayer10ChangeTeamEibb
arguments = POINTER,INT,BOOL,BOOL
return_type = VOID
convention = THISCALL
srv_check = false
With the following one:

Syntax: Select all

# CCSPlayer::SwitchTeam
[switch_team]
binary = csgo/bin/server
identifier_windows = " 55 8B EC 83 EC 10 53 56 8B 75 08 57 8B F9 85 F6 0F"
identifier_linux = _ZN9CCSPlayer10SwitchTeamEi
arguments = POINTER,INT
return_type = VOID
convention = THISCALL
srv_check = false
However, your actual code you posted still won't work.
8guawong
Senior Member
Posts: 148
Joined: Sat Sep 20, 2014 3:06 am

Postby 8guawong » Tue Oct 07, 2014 5:01 am

L'In20Cible wrote:However, your actual code you posted still won't work.


OMG finally switch team is working beautifully!!
at this point i don't really care if it works or not hahahah

thank you thank you thank you :cool:
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Tue Oct 07, 2014 12:28 pm

Hmm, that stinks. The reason I included CBasePlayer instead of CCSPlayer is because you can easily hide the chat message. Oh well.
Image

Return to “Plugin Development Support”

Who is online

Users browsing this forum: No registered users and 116 guests