AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Snippets and Tutorials (https://forums.alliedmods.net/forumdisplay.php?f=112)
-   -   [Tutorial] ClientPrefs (https://forums.alliedmods.net/showthread.php?t=228244)

KyleS 10-16-2013 13:20

[Tutorial] ClientPrefs
 
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 rukia


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));



TnTSCS 10-16-2013 16:50

Re: [Tutorial] ClientPrefs
 
Thank you... learned something new about SetCookiePrefabMenu

shavit 10-18-2013 15:08

Re: [Tutorial] ClientPrefs
 
Thanks :)
The way you loop through players is unique :O

Drixevel 10-19-2013 15:08

Re: [Tutorial] ClientPrefs
 
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.

KyleS 10-19-2013 15:24

Re: [Tutorial] ClientPrefs
 
Quote:

Originally Posted by r3dw3r3w0lf (Post 2050894)
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.

Bacardi 10-20-2013 14:59

Re: [Tutorial] ClientPrefs
 
Quote:

Originally Posted by KyleS (Post 2049566)
...
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 ?? :bee:
Spoiler

KyleS 10-20-2013 15:01

Re: [Tutorial] ClientPrefs
 
Quote:

Originally Posted by Bacardi (Post 2051248)
You mean command sm_cookies ?? :bee:

Correct!

Arkarr 11-26-2013 08:04

Re: [Tutorial] ClientPrefs
 
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

friagram 11-26-2013 08:28

Re: [Tutorial] ClientPrefs
 
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.

Arkarr 11-26-2013 08:41

Re: [Tutorial] ClientPrefs
 
Yep, I did, but cookies still lost.


All times are GMT -4. The time now is 15:30.

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