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

[ CS:GO ] Using the player_connect event


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
transeffect
New Member
Join Date: Feb 2015
Old 02-16-2015 , 18:16   [ CS:GO ] Using the player_connect event
Reply With Quote #1

I have a group of friends who hop on my server every Thursday night to play CSGO and talk smack to each other. We also have a GroupMe group we use to communicate during the rest of the week. My server is not popular, and I'm okay with that, because I really only keep it running for me and my friends to hop on occasionally and let off some steam (no pun intended).

I am not much of a programmer, but really wanted to write a plugin that would send a message to our GroupMe group any time someone joined the server, so if it happened at some random time, anyone else who had a few minutes to play could hop on, too.

I have a script that works, but it currently fires using OnClientPutInServer because I could not for the life of me get it to work with using the player_connect event. I finally realized that, when player_connect fires, it's so early that the client hasn't been authorized, so we're unable to get a name or auth string when using player_connect.

However, OnClientPutInServer fires every map change, so if there are ten of us playing, our GroupMe gets spammed every time the map switches.

Is there an effective way to use the player_connect event so that we can pull player names only when they connect to the server? Then we can use player_disconnect (which currently works fine) to notify us when players leave the server.

For some background info, here's the way the script is working, so if anyone else has a better way, they can make a suggestion:

Client connects to server, we get the client name (GetClientName), we check to make sure it's not a bot (IsFakeClient). If it's a real player, the script opens a text file and writes "<PlayerName> has just connected!"

Meanwhile, the server is using a script (When-Changed) to monitor the file that player names are written to, and every time the file gets modified, the message fires off a cURL directive that hits the GroupMe API and sends message that someone has connected.
transeffect is offline
TnTSCS
AlliedModders Donor
Join Date: Oct 2010
Location: Undisclosed...
Old 02-16-2015 , 18:24   Re: [ CS:GO ] Using the player_connect event
Reply With Quote #2

You could fire it off, use a client variable to tag that the client has already broadcasted to GroupMe that they joined and are in the game.

Then, every hour, as long as there is someone in the game, have a message sent to the GroupMe with a list of current players.

Tons of options here - just need to hammer out the method of notification without causing GroupMe spam (too much anyways)
__________________
View my Plugins | Donate
TnTSCS is offline
transeffect
New Member
Join Date: Feb 2015
Old 02-16-2015 , 18:45   Re: [ CS:GO ] Using the player_connect event
Reply With Quote #3

Thanks for your response, TnTSCS.

Quote:
Originally Posted by TnTSCS View Post
Then, every hour, as long as there is someone in the game, have a message sent to the GroupMe with a list of current players.
I specifically want to know if there's an effective way to utilize player_connect and still provide the information I'm looking for (player name). Like, is there a decent way to fire player_connect, pause to give steam time to auth the client, then process the connection with GetClientOfUserId(GetEventInt(event, "userid"))?

AFAIK player_connect and player_disconnect are the only events that fire just once (all the others are fired between every match/map-change).

I know there are a lot of ways to accomplish the overall objective, but that objective is being accomplished now - notifications in real-time that users are connecting and disconnecting. I want to maintain that functionality, but without the extra notifications when maps change.
transeffect is offline
TnTSCS
AlliedModders Donor
Join Date: Oct 2010
Location: Undisclosed...
Old 02-17-2015 , 09:33   Re: [ CS:GO ] Using the player_connect event
Reply With Quote #4

Use a timer in the player_connect and pass the userid, then in the timer execute your code - you should be able to get steamID and name then.
__________________
View my Plugins | Donate
TnTSCS is offline
transeffect
New Member
Join Date: Feb 2015
Old 02-19-2015 , 11:51   Re: [ CS:GO ] Using the player_connect event
Reply With Quote #5

Quote:
Originally Posted by TnTSCS View Post
Use a timer in the player_connect and pass the userid, then in the timer execute your code - you should be able to get steamID and name then.
Thanks for your advice. I spent hours trying to get it to work properly, and the way I'm doing is probably stupid, but I've never written a plugin before. Any advice on this? It seems to work really well at the moment.

PHP Code:
#include <sourcemod>

public Plugin:myinfo =
{
    
name "Player Connect Log",
    
author "PK and Mykie P",
    
description "This will log each connecting and disconnecting player and send a corresponding message to a GroupMe group",
    
version "1.0",
    
url "http://transeffect.com"
}

public 
OnPluginStart()
{
    
// Let's start a timer when players connect to the server. That will give the server time to get steam auth information for each player.
    // On disconnect, we'll call the playerDisconnectTE function, which will filter out bots and sent disconnect notifications for real players.
    
HookEvent("player_connect"startTimer);
    
HookEvent("player_disconnect"playerDisconnectTEEventHookMode_Pre);
}

public 
Action:startTimer(Handle:event, const String:name[], bool:dontBroadcast)
{
    
//const uid = GetEventInt(event, "userid");
    
CreateTimer(15.0playerConnectTEGetEventInt(event"userid"));
}

public 
Action:playerConnectTE(Handle:timerany:uid)
{
    
// A string buffer for our player name.
    
decl String:playerName[64];
    
    
// Let's figure out which player caused the event.
    // GetEventInt here retrieves value of event's "userid" field, which holds unique player identifier.
    // GetClientName retrieves client name into specified buffer, but it needs client entity id, not userid.
    // We will translate userid into entity id with GetClientOfUserId.

    
new clientIndex uid;
    new 
client GetClientOfUserId(uid);
    
GetClientName(clientplayerNamesizeof(playerName));

    
//GetClientName(GetClientOfUserId(GetEventInt(event, "userid")), playerName, sizeof(playerName));
    
    // if client has a valid ID, is in the game, and isn't a bot,
    // write debug info and write to the file that will send GroupMe message
    
if(((client && client <= MaxClients) && IsClientConnected(client)) && !IsFakeClient(client)) {
    
        
// ************** DEBUGGING *****************************
        
new Handle:writeDebugLog OpenFile("wtfdebug.txt""a");
        
WriteFileLine(writeDebugLog"CONNECT");
        
WriteFileLine(writeDebugLog"Player Index/Entity ID: %d",clientIndex);
        
WriteFileLine(writeDebugLog"Client: %d",client);
        
WriteFileLine(writeDebugLog"Player name holder 1: %s",playerName);
        
WriteFileLine(writeDebugLog"END CONNECT");
        
WriteFileLine(writeDebugLog"");
        
CloseHandle(writeDebugLog);
        
// ************** DEBUGGING *****************************
        
        // OpenFile returns a Handle which we can use in other functions to work with our file
        
new Handle:writePlayerLog OpenFile("playerName.txt""w");
        
// Writing a simple string of text into our file. This function adds newline automatically.
        
WriteFileLine(writePlayerLog"%s has just connected to the TE Server!"playerName);
        
// Close the file when it's not needed anymore.
        
CloseHandle(writePlayerLog);
        
// Finally, print contents of our string buffer. To print to specific player, use PrintCenterText function.
        
PrintCenterTextAll("Player %s has just connected!"playerName);
        
PrintToChatAll("Player %s has just connected!"playerName);
        return 
Plugin_Handled;
        }
        
        else
        {
            return 
Plugin_Stop;
        }
}

public 
Action:playerDisconnectTE(Handle:event, const String:name[], bool:dontBroadcast

    new 
String:userName[32], String:authid[32];
    new 
uid GetEventInt(event"userid");
    new 
client GetClientOfUserId(uid)
    
GetClientName(clientuserNamesizeof(userName));
    
GetClientAuthString(clientauthidsizeof(authid));
    
    if (((
client >= && client <= MaxClients) && IsClientConnected(client)) &&  !StrEqual(authid"BOT"))
    {
        
PrintToChatAll("%s has disconnected from the server."userName);
        
        
// ************** DEBUGGING *****************************
        
new Handle:writeDebugLog OpenFile("wtfdebug.txt""a");
        
WriteFileLine(writeDebugLog"DISCONNECT");
        
WriteFileLine(writeDebugLog"Player Index/Entity ID: %d",uid);
        
WriteFileLine(writeDebugLog"Client: %d",client);
        
WriteFileLine(writeDebugLog"Player name holder 1: %s",userName);
        
WriteFileLine(writeDebugLog"END DISCONNECT");
        
WriteFileLine(writeDebugLog"");
        
CloseHandle(writeDebugLog);
        
// ************** DEBUGGING *****************************
        
        
new Handle:writePlayerLog OpenFile("playerName.txt""w");
        
// Writing a simple string of text into our file. This function adds newline automatically.
        
WriteFileLine(writePlayerLog"%s has just disconnected from the TE Server."userName);
        
// Close the file when it's not needed anymore.
        
CloseHandle(writePlayerLog);
        return 
Plugin_Handled;
    }
    else
    {
        
PrintToChatAll("[BOT] %s has been disconnected from the server."userName);
        return 
Plugin_Stop;
    }


Last edited by transeffect; 02-19-2015 at 11:54. Reason: Making code more readable with PHP tag instead of CODE tag
transeffect is offline
andre2843
Member
Join Date: Apr 2011
Old 02-19-2015 , 13:13   Re: [ CS:GO ] Using the player_connect event
Reply With Quote #6

And example andre2843 has connect from brasil
__________________
.
andre2843 is offline
TnTSCS
AlliedModders Donor
Join Date: Oct 2010
Location: Undisclosed...
Old 03-09-2015 , 17:52   Re: [ CS:GO ] Using the player_connect event
Reply With Quote #7

I'm going to post a more robust version soon, but this very small and simple sample code that works with GroupMe - requires the cURL extension to work. I tested it and it works.

Text from bot in my GroupMe group chat looks like:
Tom<23><STEAM_ID><> just joined. There are N players on the server.

If you want to suggest things it should communicate, please let me know.

Just replace the xx's with your actual bot_id created from the GroupMe Developers page.

PHP Code:
#pragma semicolon 1

#include <sourcemod>
#include <cURL>

#define GM_BOT_ID "xxxxXXXXXxxxx"

public OnComplete(Handle:hndlCURLcodecode)
{
    
CloseHandle(hndl);
}

public 
OnClientConnected(client)
{
    new 
String:g_sMsg[255];
    
Format(g_sMsgsizeof(g_sMsg), "bot_id=%s&text=%L just joined.  There are %i players on the server"GM_BOT_IDclientGetClientCount());
    
ReplaceString(g_sMsgsizeof(g_sMsg), " ""+"false);
    
    new 
Handle:curl curl_easy_init();
    
    
curl_easy_setopt_string(curlCURLOPT_URL"https://api.groupme.com/v3/bots/post");
    
curl_easy_setopt_int(curlCURLOPT_SSL_VERIFYPEER0);
    
curl_easy_setopt_int(curlCURLOPT_SSL_VERIFYHOST2);
    
curl_easy_setopt_string(curlCURLOPT_POSTFIELDSg_sMsg);
    
curl_easy_perform_thread(curlOnComplete);

Above sample code taken from sample provided here

The above is just proof code. The features I'm going to include will be !calladmin <msg>, !reportplayer <player> (restricted to a flag), server shutdown message, banned player messages, echo chat (if allowed in the EULA for groupme), admin chat from groupme to game server, and a couple of others - all controlled by CVars to enable/disable them.
__________________
View my Plugins | Donate

Last edited by TnTSCS; 03-09-2015 at 17:56.
TnTSCS is offline
xf117
Senior Member
Join Date: Mar 2010
Location: Russia
Old 03-10-2015 , 04:46   Re: [ CS:GO ] Using the player_connect event
Reply With Quote #8

You could just use OnClientPostAdminCheck / OnClientAuth to save the steam id of the person who entered.
Using curl or socket lib is probably the better idea.
xf117 is offline
Send a message via ICQ to xf117
RedSword
SourceMod Plugin Approver
Join Date: Mar 2006
Location: Quebec, Canada
Old 03-11-2015 , 17:05   Re: [ CS:GO ] Using the player_connect event
Reply With Quote #9

As xf117 more or less indirectly said; rather than using the player_connect event and launching a timer to hope that the client is authorized during its callback, you could use the OnClientAuthorized forward.

You could also have a global array of MAXPLAYERS + 1 to stock the userid when a client is authorized for the first time. That way, you could know on subsequent call when a player is reconnecting due to a map change (GetClientUserId( clientBeingAuthed ) == theArray[ clientBeingAuthed ]) or simply connecting (==0/-1 instead). Also set your theArray[ clientBeingAuthed ] to 0/-1 on the EVENT when a player_disconnect, that way you detect furthuer first-client-connections.

I'm saying 0/-1 because I've no idea what the minimum UserId is (I just know it's on 2^16 values)

Also you should be careful when a client disconnect on map change, because player_disconnect event will gives you his real until-then userid; but doing GetClientOfUserId will return 0; so you'll have to loop through your array to detect if a client slot has that userId.

Also note that OnClientAuthorized is not 100% garanteed to launch (though I've never seen it not launch); therefore someone could connect and not be authorized yet and then disconnecting on map change which would be returning 0 when doing GetClientOfUserId on his player_disconnect event while his userId wouldn't be present in the array.

Red
__________________
My plugins :
Red Maze
Afk Bomb
RAWR (per player/rounds Awp Restrict.)
Kill Assist
Be Medic

You can also Donate if you appreciate my work

Last edited by RedSword; 03-11-2015 at 17:08.
RedSword 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 13:18.


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