AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting Help (https://forums.alliedmods.net/forumdisplay.php?f=11)
-   -   [HELP] Save Model Permanent (https://forums.alliedmods.net/showthread.php?t=237153)

extream87 03-18-2014 19:32

[HELP] Save Model Permanent
 
I made a plugin in which players write /skins and you can buy your skins.

The problem is i dont know how can set this skin (forever). Maybe set skin by steam id no?

Example code:
Code:
case 15:     {     g_Hasawpflorest[id] = false     g_Hasawplight[id] = false     g_Hasawpmagma[id] = true     client_cmd(id,"slot3;slot1;drop")     set_task(0.1,"awp",id)     play     credits[id] -= 1     save_credits(id)     }
In this case i need to set g_Hasawpmagma to the player steam id and save it in a .txt or vault.

DavidJr 03-19-2014 06:40

Re: [HELP] Save Model Permanent
 
Just an example to save and load your weapon. I use fvault

PHP Code:

new const VAULT_NAME[] = "cs_weapon";

new 
gAwp[33];

public 
plugin_init()
{
    
register_plugin(PLUGINVERSIONAUTHOR);
}

public 
client_authorized(iIndex)
{
    if (!
is_user_hltv(iIndex) && !is_user_bot(iIndex)) LoadData(iIndex);
}

public 
client_disconnect(iIndex)
{
    
SaveData(iIndex);
}

LoadData(iIndex)
{
    new 
szAuthId[35];
    
get_user_authid(iIndexszAuthIdsizeof szAuthId);
    
    new 
szWpnKey[33];
    
format(szWpnKeysizeof szWpnKey"%s_Wpn"szAuthId);
    
    new 
szWpn[25];
    
fvault_get_data(VAULT_NAMEszWpnKeyszWpnsizeof szWpn);
    
    
gAwp[iIndex] = str_to_num(szWpn);
}

SaveData(iIndex)
{
    new 
szAuthId[35];
    
get_user_authid(iIndexszAuthIdsizeof(szAuthId));
    
    new 
szWpnKey[33];
    
format(szWpnKeysizeof szWpnKey"%s_Wpn"szAuthId);
    
    new 
szWpn[25];
    
num_to_str(gAwp[iIndex], szWpnsizeof szWpn);
    
    
fvault_set_data(VAULT_NAMEszWpnKeyszWpn);



extream87 03-19-2014 08:35

Re: [HELP] Save Model Permanent
 
DavidJr so i need to add more weapons here right?

Code:
LoadData(iIndex) {     new szAuthId[35];     get_user_authid(iIndex, szAuthId, sizeof szAuthId);         new szWpnKey[33];     format(szWpnKey, sizeof szWpnKey, "%s_Wpn", szAuthId);         new szWpn[25];     fvault_get_data(VAULT_NAME, szWpnKey, szWpn, sizeof szWpn);         gAwp[iIndex] = str_to_num(szWpn);     gAk47[iIndex] = str_to_num(szWpn);     gM4A1[iIndex] = str_to_num(szWpn);     //More... }

I'm getting tag mismatch error:
Code:
new bool:g_HasuspP[33] new purple_usp_vmodel[64] = "models/skinned/usp_purple/v_usp_purple.mdl" LoadData(iIndex) {     new szAuthId[35];     get_user_authid(iIndex, szAuthId, sizeof szAuthId);         new szWpnKey[33];     format(szWpnKey, sizeof szWpnKey, "%s_Wpn", szAuthId);         new szWpn[25];     fvault_get_data(VAULT_NAME, szWpnKey, szWpn, sizeof szWpn);       //here g_HasuspP[iIndex] = str_to_num(szWpn); }

Black Rose 03-19-2014 14:04

Re: [HELP] Save Model Permanent
 
Quote:

Originally Posted by extream87 (Post 2113416)
DavidJr so i need to add more weapons here right?

Code:
LoadData(iIndex) {     new szAuthId[35];     get_user_authid(iIndex, szAuthId, sizeof szAuthId);         new szWpnKey[33];     format(szWpnKey, sizeof szWpnKey, "%s_Wpn", szAuthId);         new szWpn[25];     fvault_get_data(VAULT_NAME, szWpnKey, szWpn, sizeof szWpn);         gAwp[iIndex] = str_to_num(szWpn);     gAk47[iIndex] = str_to_num(szWpn);     gM4A1[iIndex] = str_to_num(szWpn);     //More... }

You either need to separate the keys or the values.

Example 1:
STEAM_ID_BLAH_AWP 1
STEAM_ID_BLAH_M4A1 4
STEAM_ID_BLAH_AK47 2

Example 2:
STEAM_ID_BLAH 1,4,2

The first example will create a larger vault but it will be more efficient while saving/loading single values.
The second example will also be harder to edit if you start adding or removing weapons. You are locked to that structure and you can't remove values even if they're not being used anymore.
Not sure which one is more efficient while loading all values. Probably the second one.

"_Wpn" suffix is completely useless and will only add to the native calls.

If you're only using the vault for true/false values you can make it a bitsum for up to 31 (or 32, I'm not sure) weapons in one value. You also can make it a "binary" string for several values. "100101", much like the second example.

Quote:

Originally Posted by extream87 (Post 2113416)
I'm getting tag mismatch error:
Code:
new bool:g_HasuspP[33] new purple_usp_vmodel[64] = "models/skinned/usp_purple/v_usp_purple.mdl" LoadData(iIndex) {     new szAuthId[35];     get_user_authid(iIndex, szAuthId, sizeof szAuthId);         new szWpnKey[33];     format(szWpnKey, sizeof szWpnKey, "%s_Wpn", szAuthId);         new szWpn[25];     fvault_get_data(VAULT_NAME, szWpnKey, szWpn, sizeof szWpn);       //here g_HasuspP[iIndex] = str_to_num(szWpn); }

g_HasuspP is a boolean which only takes true/false.
Code:
g_HasuspP[iIndex] = str_to_num(szWpn) ? true : false;

extream87 03-19-2014 14:09

Re: [HELP] Save Model Permanent
 
Black Rose i want to use method 2.
The "binary" is too much to me :P

I've putted this(below) and works. How can i remove if the player change the usp model? (set g_HasuspP false again)
Code:
g_HasuspP[iIndex] = str_to_num(szWpn) ? true : false;


To save multiple guns how can i made?
Code:
SaveData(id) {     new szAuthId[35];     get_user_authid(id, szAuthId, sizeof(szAuthId));         new szWpnKey[33];     format(szWpnKey, sizeof szWpnKey, "%s", szAuthId);         new szWpn[25];     num_to_str(g_HasuspP[id], szWpn, sizeof szWpn);     num_to_str(g_Hasglockrdlam[id], szWpn, sizeof szWpn);     num_to_str(g_Hasuspchip[id], szWpn, sizeof szWpn);         fvault_set_data(VAULT_NAME, szWpnKey, szWpn); }

Black Rose 03-19-2014 15:27

Re: [HELP] Save Model Permanent
 
This will display the differences between loading and parsing data from various vault systems and methods.
Code:
    // nVault saved as array (really a string)     // Possible values -128 to 127 except 0.     nvault_set(hVault, "MyKey", {100, 50, 25});     // ---     new data1[4];     nvault_get(hVault, "MyKey", data1, charsmax(data1));     server_print("nVault: %d, %d, %d", data1[0], data1[1], data1[2]);         // fVault saved as string     // Possible values defined by string length     fvault_set_data("TestVault", "MyKey", "100, 50, 25");     // ---     new data2[12];     new subdata1[4], subdata2[4], subdata3[4];     fvault_get_data("TestVault", "MyKey", data2, charsmax(data2));     parse(data2, subdata1, charsmax(subdata1), subdata2, charsmax(subdata2), subdata3, charsmax(subdata3));     server_print("fVault String: %d, %d, %d", str_to_num(subdata1), str_to_num(subdata2), str_to_num(subdata3));         // fVault saved as array (really a string)     // Possible values -128 to 127 except 0.     fvault_set_data("TestVault", "MyKey", {100, 50, 25});     // ---     new data3[4];     fvault_get_data("TestVault", "MyKey", data3, charsmax(data3));     server_print("fVault Array: %d, %d, %d", data3[0], data3[1], data3[2]);
Why is this important? Well maybe it's not. But if you're gonna learn coding good you should know that there are different solutions to one problem depending on other circumstances. In this case, how many weapons are involved.

The first example looks good and is made for storing integers the way they were intended to.
The second example is not only horrible looking but it's wasteful of those precious resources. The more you add to it, the worse it will be.
The third example is basically like the first one.

So which one should we pick? It depends.
We could use example 1 with a bitsum and bitmasking to set 31 variables to true/false. But that would not look very good.
Code:
    #define DEAGLE_BITMASK  (1<<0)     #define M4A1_BITMASK    (1<<1)         new bool:GoldenDeagle[33], bool:CamoM4A1[33];         new bitsum = nvault_get(hVault, "MyKey");     GoldenDeagle[id] = bitsum & DEAGLE_BITMASK ? true : false;     CamoM4A1[id] = bitsum & M4A1_BITMASK ? true : false;
Another option is to save the bitsum directly inside a global array of players and use the bitmask instead of the booleans.
Both bitsum options are generally very bad as permanent storage. It will create a problem because you can not add more than 31 weapons. You also can't remove old ones to make room for new ones because that would corrupt the vault data.

Instead it would be better to use example 1 or 3 with an "array" and possibly an enumeration index for readability.
That way you have no limit on the vault size, minimizing native calls and also the code space, downside is higher memory usage.
Memory is cheap and won't affect the performance of the server as much as CPU hungry solutions.

So here's the save & load I would suggest.
Code:
#include <amxmodx> #include <fvault> enum {     GoldenDeagle,     CamoM4A1,         PLACEHOLDER_KEEP_AT_END } new gWeapons[33][PLACEHOLDER_KEEP_AT_END + 1]; new const VAULT_NAME[] = "cs_weapon"; public plugin_init() {     register_plugin("", "", ""); } public client_authorized(iIndex) {     if (!is_user_hltv(iIndex) && !is_user_bot(iIndex)) LoadData(iIndex); } public client_disconnect(iIndex) {     SaveData(iIndex); } LoadData(iIndex) {     new szAuthId[35];     get_user_authid(iIndex, szAuthId, sizeof szAuthId);         if ( ! fvault_get_data(VAULT_NAME, szAuthId, gWeapons[iIndex], sizeof gWeapons[] - 1) )         arrayset(gWeapons[iIndex], -1, sizeof gWeapons[] - 1); } SaveData(iIndex) {     new szAuthId[35];     get_user_authid(iIndex, szAuthId, sizeof(szAuthId));     fvault_set_data(VAULT_NAME, szAuthId, gWeapons[iIndex]); }

This however requires you to remake the weapon variables.
When you want to give someone a weapon you use the array + index.
Code:
gWeapons[id][GoldenDeagle] = 1
And when you want to remove it:
Code:
gWeapons[id][GoldenDeagle] = -1
When checking for a weapon:
Code:
if ( gWeapons[id][GoldenDeagle] == 1 )

There's a reason for using 1 and -1 instead of 1 and 0. Since the data is saved as a string 0 would terminate the string.

Here's an example with the code you supplied:
Code:
case 1: {     gWeapons[id][GoldenDeagle] = 1     client_cmd(id,"slot3;slot2;drop")     set_task(0.1,"deagle",id)     //play     credits[id] -= 1     save_credits(id) }

I'm sorry for complicating it further but in the end this would make the whole code easier to work with in general.
You still need to understand how it works so you can make changes yourself, so if you have any questions just ask.

extream87 03-19-2014 16:39

Re: [HELP] Save Model Permanent
 
Black Rose thank you very much :D

All works good.
In file_vault/skins.txt i have:

(XXXXX is to ommit my id)
"STEAM_0:0:XXXXX" "ÿÿÿÿÿÿÿÿÿÿÿÿ" 1395261491

Is not possible define GoldenDeagle to number 1 and GoldenAK to number 2?
"STEAM_0:0:XXXXX" "1, 2"

Black Rose 03-19-2014 17:53

Re: [HELP] Save Model Permanent
 
I avoided using commas, whitespace and ASCII encoding as that would require parse() and an edit of the save/load function every time you add or remove a weapon. It would also increase the filesize.
You could do this:
Code:
gWeapons[id][GoldenDeagle] = GoldenDeagle + 1;
Which would save the index in binary form. But I don't really understand why. The Vault is supposed to just keep in the background. This is one of the most efficient way to do it being almost no native calls at all.

If you could explain what you mean and why you want it I will try helping you.

extream87 03-19-2014 18:11

Re: [HELP] Save Model Permanent
 
Cause this is a mess :P But works and is the most important.

So what you recommend?
Code:
gWeapons[id][GoldenDeagle] = 1
or
Code:
gWeapons[id][GoldenDeagle] = GoldenDeagle + 1;

Black Rose 03-19-2014 18:21

Re: [HELP] Save Model Permanent
 
What's the mess? You're not supposed to read the vault as a book.

The first one is one less memory call for the variable value, so that would be more efficient. But that's really not a concern here so it really makes no difference whatsoever. I would consider the second one messier because you would have to make the if statements look the same.

In the end you are the author of your plugin and you decide which method you want to use. You are the one who are going to maintain it.
I'll show you a "cleaner" way tomorrow.


All times are GMT -4. The time now is 05:54.

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