Raised This Month: $170 Target: $400
 42% 

[Tutorial] ClientPrefs


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
KyleS
SourceMod Plugin Approver
Join Date: Jul 2009
Location: Segmentation Fault.
Old 10-16-2013 , 13:20   [Tutorial] ClientPrefs
Reply With Quote #1

Alrighty, so using ClientPrefs is pretty straight forward. However, not a lot of plugins include support for it. Hopefully this helps someone.

The first thing you need to determine is what you need to store. Is it just a simple on off value? A name? In this case, let's store a simple bool.

PHP Code:
new bool:g_bClientPreference[MAXPLAYERS+1]; 
The next thing you need to do is RegClientCookie. This is where you determine the internal (32 character) name of your cookie, a subsequently a description. This is also where you determine the CookieAccess of a cookie. This can make or break you quite easily. If you make your cookie public, clients can raw set values using sm_cookies. This can provoke undefined behaviour, which can wreck you depending on your sanitation. In our case, we're making our cookie Private.

PHP Code:
new Handle:g_hClientCookie INVALID_HANDLE;

public 
OnPluginStart()
{
    
g_hClientCookie RegClientCookie("OurTestCookie""A Test Cookie for use in our Tutorial"CookieAccess_Private);

In our case, we're going to add our Cookie to the sm_settings menu. Because we're using a simple on and off switch, we can easily use SetCookiePrefabMenu. We're going to use CookieMenu_OnOff_Int, because in our case we only want to store 1 or 0.

PHP Code:
public OnPluginStart()
{
    
g_hClientCookie RegClientCookie("OurTestCookie""A Test Cookie for use in our Tutorial"CookieAccess_Private);
    
SetCookiePrefabMenu(g_hClientCookieCookieMenu_OnOff_Int"TestCookie"TestCookieHandler);

Just with that one line, you have sm_settings support.

We now need to define our CookieMenuHandler. The handler is pretty straight forward if you've used the menu API. If not, you may need to brush up on Menus. In this specific case, we only need to worry about the CookieMenuAction_SelectOption. We need to simply cover setting the boolean so our internal state holds consistent. The major failure of the API is when the setting changes, buffer is always "", which makes me sad, but oh well.
PHP Code:
public TestCookieHandler(clientCookieMenuAction:actionany:infoString:buffer[], maxlen)
{
    switch (
action)
    {
        case 
CookieMenuAction_DisplayOption:
        {
        }
        
        case 
CookieMenuAction_SelectOption:
        {
            
OnClientCookiesCached(client);
        }
    }

The next gotcha with ClientPrefs (and SourceMod in general) is late-load support for plugins. You should probably support late-loading, because you can get into a weird state if you don't. It's pretty easy to do so with ClientPrefs.

PHP Code:
public OnPluginStart()
{
    for (new 
MaxClients0; --i)
    {
        if (!
AreClientCookiesCached(i))
        {
            continue;
        }
        
        
OnClientCookiesCached(i);
    }

Don't worry about bots/fake clients, they too have cookies.

Last but not least, the magical OnClientCookiesCached forward. Here you're just reading a value out of a cookie. You can definitely register multiple cookies, or no cookies. OnClientCookiesCached has no defined order, and can happen before or after OnClientPostAdminCheck. If you have a protected admin cookie, you're going to need to have your own custom handler, which is beyond the scope of this tutorial (at the moment). In our case, we're reading a simple one byte value from a String. In our case, we're going to use 8 bytes.

PHP Code:
public OnClientCookiesCached(client)
{
    
decl String:sValue[8];
    
GetClientCookie(clientg_hClientCookiesValuesizeof(sValue));
    
    
g_bClientPreference[client] = (sValue[0] != '\0' && StringToInt(sValue));

Hopefully this helped. There are more, customized ways to handle Cookies. I tried to cover the basics, if you'd like me to go further into depth, just say so


EDIT: The final Plugin Looks Like:
PHP Code:
#pragma semicolon 1
#include <sourcemod>
#include <clientprefs>

new Handle:g_hClientCookie INVALID_HANDLE;
new 
bool:g_bClientPreference[MAXPLAYERS+1];

public 
OnPluginStart()
{
    
g_hClientCookie RegClientCookie("OurTestCookie""A Test Cookie for use in our Tutorial"CookieAccess_Private);
    
SetCookiePrefabMenu(g_hClientCookieCookieMenu_OnOff_Int"TestCookie"TestCookieHandler);
    for (new 
MaxClients0; --i)
    {
        if (!
AreClientCookiesCached(i))
        {
            continue;
        }
        
        
OnClientCookiesCached(i);
    }
}

public 
TestCookieHandler(clientCookieMenuAction:actionany:infoString:buffer[], maxlen)
{
    switch (
action)
    {
        case 
CookieMenuAction_DisplayOption:
        {
        }
        
        case 
CookieMenuAction_SelectOption:
        {
            
OnClientCookiesCached(client);
        }
    }
}

public 
OnClientCookiesCached(client)
{
    
decl String:sValue[8];
    
GetClientCookie(clientg_hClientCookiesValuesizeof(sValue));
    
    
g_bClientPreference[client] = (sValue[0] != '\0' && StringToInt(sValue));


Last edited by KyleS; 10-20-2013 at 15:01. Reason: Bacardi is correct.
KyleS is offline
TnTSCS
AlliedModders Donor
Join Date: Oct 2010
Location: Undisclosed...
Old 10-16-2013 , 16:50   Re: [Tutorial] ClientPrefs
Reply With Quote #2

Thank you... learned something new about SetCookiePrefabMenu
__________________
View my Plugins | Donate
TnTSCS is offline
shavit
AlliedModders Donor
Join Date: Dec 2011
Location: Israel
Old 10-18-2013 , 15:08   Re: [Tutorial] ClientPrefs
Reply With Quote #3

Thanks
The way you loop through players is unique :O
__________________
My Plugins
Not taking private requests, too busy.
shavit is offline
Drixevel
AlliedModders Donor
Join Date: Sep 2009
Location: Lazytown
Old 10-19-2013 , 15:08   Re: [Tutorial] ClientPrefs
Reply With Quote #4

Appreciate the example! Any quick leads on how to have a specific message pop up when the client select on or off in the menu? Can't seem to find much after searching a bit.
__________________
I sometimes do commissions.
Drixevel is offline
KyleS
SourceMod Plugin Approver
Join Date: Jul 2009
Location: Segmentation Fault.
Old 10-19-2013 , 15:24   Re: [Tutorial] ClientPrefs
Reply With Quote #5

Quote:
Originally Posted by r3dw3r3w0lf View Post
Appreciate the example! Any quick leads on how to have a specific message pop up when the client select on or off in the menu? Can't seem to find much after searching a bit.
In MenuSelect you can print a message, or do whatever you want.
KyleS is offline
Bacardi
Veteran Member
Join Date: Jan 2010
Location: mom's basement
Old 10-20-2013 , 14:59   Re: [Tutorial] ClientPrefs
Reply With Quote #6

Quote:
Originally Posted by KyleS View Post
...
This is also where you determine the CookieAccess of a cookie. This can make or break you quite easily. If you make your cookie public, clients can raw set values using sm_settings. This can provoke undefined behaviour, which can wreck you depending on your sanitation. In our case, we're making our cookie Private.
...
You mean command sm_cookies ??
Spoiler
__________________
Bacardi is offline
KyleS
SourceMod Plugin Approver
Join Date: Jul 2009
Location: Segmentation Fault.
Old 10-20-2013 , 15:01   Re: [Tutorial] ClientPrefs
Reply With Quote #7

Quote:
Originally Posted by Bacardi View Post
You mean command sm_cookies ??
Correct!
KyleS is offline
Arkarr
Veteran Member
Join Date: Sep 2012
Location: Just behind my PC screen
Old 11-26-2013 , 08:04   Re: [Tutorial] ClientPrefs
Reply With Quote #8

I don't get it... Why my cookie are always lost when I reload my plugin and players are in game ?

I can restart my server and player have their correct cookie [OK]
I can restart map and player have their correct cookie [OK]
I reload my plugin and players are in game, they lost their cookies !!! [X]

NOTE:
I didn't understand everything you wrote, so I'm not sure if you speak about this...

Original thread
__________________
Arkarr is offline
friagram
Veteran Member
Join Date: Sep 2012
Location: Silicon Valley
Old 11-26-2013 , 08:28   Re: [Tutorial] ClientPrefs
Reply With Quote #9

OnClientCookiesCached will only fire when they connect. If you yeload the plugin, you need to loop over the players and do AreClientCookiesCached in OnPluginStart... Look at the example.
__________________
Profile - Steam Group - Plugins - Blog - Donate
Add me on steam if you are seeking sp/map/model commissions.
friagram is offline
Arkarr
Veteran Member
Join Date: Sep 2012
Location: Just behind my PC screen
Old 11-26-2013 , 08:41   Re: [Tutorial] ClientPrefs
Reply With Quote #10

Yep, I did, but cookies still lost.
__________________
Arkarr is offline
Reply


Thread Tools
Display Modes

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 09:17.


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