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

Need a good array for this...


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
bally
Senior Member
Join Date: Aug 2015
Old 12-20-2015 , 19:41   Need a good array for this...
Reply With Quote #1

Code:
"Locations"
{
	"Arena"
  	{
       		"ammo" 		"1"
       		"ctlocx" 	"535"
        	"ctlocy"	 "5290"
        	"ctlocz" 	"1924"
        	"tlocx" 	"4467"
        	"tlocy" 	"45361"
        	"tlocz" 	"375"
    	}
	"TradeRooms"
  	{
       		"ammo" 		"0"
       		"ctlocx" 	"535"
        	"ctlocy"	 "5290"
        	"ctlocz" 	"1924"
        	"tlocx" 	"4467"
        	"tlocy" 	"45361"
        	"tlocz" 	"375"
    	}
	"Surf"
  	{
       		"ammo" 		"0"
       		"ctlocx" 	"535"
        	"ctlocy"	 "5290"
        	"ctlocz" 	"1924"
        	"tlocx" 	"4467"
        	"tlocy" 	"45361"
        	"tlocz" 	"375"
    	}
	"Bhop"
  	{
       		"ammo" 		"0"
       		"ctlocx" 	"535"
        	"ctlocy"	 "5290"
        	"ctlocz" 	"1924"
        	"tlocx" 	"4467"
        	"tlocy" 	"45361"
        	"tlocz" 	"375"
    	}
}
Q.1 - I have this KeyValue Config which I'll need to use it later in my plugin. I need to store every section data in an adt_array in such form as it can be used later given the section name... How can I do it? I was thinking something like:
PHP Code:
tpos_adtArray CreateArray(32)(3)(1); 
However, I'm not sure.

(32) = section Name
(3) = pos
(1) = 1/0

Q.2 - After creating the multi-dimensional array what would be the best form to either add/use data from it?

Q.3 - Should I keep the keyvalues Handle opened, so I don't need to over-stress server?

Thank you very much for reading my questions. Have a great time.
__________________
Perhaps my lack of faith was my undoing,
bally is offline
nosoop
Veteran Member
Join Date: Aug 2014
Old 12-20-2015 , 20:33   Re: Need a good array for this...
Reply With Quote #2

Your declaration of CreateArray wouldn't work since the declaration's first argument determines the number of values it can hold in one array entry (and functions don't allow for arguments after the closing parenthesis). The size of the adt_array is dynamic and the initial size is the second argument. I wouldn't recommend using it for your particular use case.

You could do nested adt_trie so you could just read keys out, but you'd still have to deal with iterating through the KeyValues to put them into each trie.

Out of curiosity, why not just use the KeyValues directly? Since you know exactly what keys you're working with, you can use forward slashes to read a value from a subkey.

Assuming transitional syntax:
Code:
KeyValues kv = new KeyValues("Locations");
kv.ImportFromString(keyvalue_data_from_post);

// Read tlocx from Surf section
int tlocX = kv.GetNum("Surf/tlocx");
(Also, assuming the configuration file uses your own schema, you can also use kv.GetVector to read a float[3] instead of storing the individual (x, y, z) values.)
__________________
I do TF2, TF2 servers, and TF2 plugins.
I don't do DMs over Discord -- PM me on the forums regarding inquiries.
AlliedModders Releases / Github / TF2 Server / Donate (BTC / BCH / coffee)

Last edited by nosoop; 12-20-2015 at 20:47. Reason: updated reasoning for CreateArray
nosoop is offline
bally
Senior Member
Join Date: Aug 2015
Old 12-20-2015 , 21:31   Re: Need a good array for this...
Reply With Quote #3

Hi nosoop, thanks for replying me this fast, I did not understand what you meant with "adt_trie", would it be possible to add an example in? Also, I want to make this project extremely flexible and dynamic, therefore I can't just do what you told me.

The project objective is to build up a menu which it's contents will be the keyvalues section name... Done
Will retrieve data from the keyvalues and cache it
Will use this cached data when user inputs on the menu according to the specified option..

The dirty way would be accessing the keyvalues file everytime a user inputted data, however, I don't want it like that, so I need an array that could support all those 3 data ( name, ammo ? 1:0, pos[3] ) this way it wouldn't stress the server

Sorry for my bad english, looking forward for a reply.
Thanks.
__________________
Perhaps my lack of faith was my undoing,

Last edited by bally; 12-20-2015 at 21:32.
bally is offline
asherkin
SourceMod Developer
Join Date: Aug 2009
Location: OnGameFrame()
Old 12-20-2015 , 21:36   Re: Need a good array for this...
Reply With Quote #4

The KV file is already "cached" in memory, just don't continually close/re-open it.
__________________
asherkin is offline
bally
Senior Member
Join Date: Aug 2015
Old 12-21-2015 , 08:43   Re: Need a good array for this...
Reply With Quote #5

Quote:
Originally Posted by asherkin View Post
The KV file is already "cached" in memory, just don't continually close/re-open it.
So basically, what you're saying is, there's no need to store the values on a dynamic array, I can just access the keyvalues because they are already cached?
__________________
Perhaps my lack of faith was my undoing,
bally is offline
asherkin
SourceMod Developer
Join Date: Aug 2009
Location: OnGameFrame()
Old 12-21-2015 , 09:26   Re: Need a good array for this...
Reply With Quote #6

Quote:
Originally Posted by bally View Post
So basically, what you're saying is, there's no need to store the values on a dynamic array, I can just access the keyvalues because they are already cached?
Yes.
__________________
asherkin is offline
bally
Senior Member
Join Date: Aug 2015
Old 12-21-2015 , 09:36   Re: Need a good array for this...
Reply With Quote #7

Quote:
Originally Posted by asherkin View Post
Yes.
LOOL, you just saved me a bunch of time. cheers!
__________________
Perhaps my lack of faith was my undoing,
bally is offline
Dr. Greg House
Professional Troll,
Part-Time Asshole
Join Date: Jun 2010
Old 12-21-2015 , 12:39   Re: Need a good array for this...
Reply With Quote #8

Quote:
Originally Posted by bally View Post
So basically, what you're saying is, there's no need to store the values on a dynamic array, I can just access the keyvalues because they are already cached?
Well the kv tree is in memory, but that doesn't mean that lookup is particularly fast or equal compared to other storage techniques.
You still haven't said what you want to do, so everything from building a menu handle and caching that, using an adt-array, or using a tree might be better or not worth the effort.
I don't want this thread to be another example for "parse through huge kv-structures in game".
__________________
Santa or Satan?

Watch out when you're paying people for private requests! Most stuff already exists and you can hardly assess the quality of what you'll get, and if it's worth the money.
Dr. Greg House is offline
bally
Senior Member
Join Date: Aug 2015
Old 12-21-2015 , 13:18   Re: Need a good array for this...
Reply With Quote #9

Quote:
Originally Posted by Dr. Greg House View Post
Well the kv tree is in memory, but that doesn't mean that lookup is particularly fast or equal compared to other storage techniques.
You still haven't said what you want to do, so everything from building a menu handle and caching that, using an adt-array, or using a tree might be better or not worth the effort.
I don't want this thread to be another example for "parse through huge kv-structures in game".
Let me be more specific:

PHP Code:
#pragma semicolon 1

#define DEBUG

#define PLUGIN_AUTHOR ""
#define PLUGIN_VERSION "0.00"

#define Kv_Location "configs/loc/location.cfg"

#include <sourcemod>
#include <sdktools>
#include <cstrike> 


bool clwhitelisted[MAXPLAYERS 1];
KeyValues kv;

Handle g_adtArray;

public 
Plugin myinfo 
{
    
name ""
    
author PLUGIN_AUTHOR
    
description ""
    
version PLUGIN_VERSION
    
url ""
};

public 
void OnPluginStart()
{
    
RegConsoleCmd("sm_tpmenu"buildUI"builds UI");
    
CreateTimer(2.0loopremove_TIMER_REPEAT);
    
g_adtArray CreateArray(32);
}



public 
void OnMapStart()
{
    
CacheVl();
}

public 
bool CacheVl()
{
    
kv = new KeyValues("locations");

    
char buffer[256];
    
char dirLoc[PLATFORM_MAX_PATH];
    
BuildPath(Path_SMdirLocsizeof(dirLoc), Kv_Location);
    
    
    
FileToKeyValues(kvdirLoc);
    if (!
KvGotoFirstSubKey(kv))
    {
        
CloseHandle(kv);
        return 
false;
        
// cfg is broken...
    
}
    
    do {
        
        
KvGetSectionName(kvbuffersizeof(buffer));
        
PushArrayString(g_adtArraybuffer); 
        
// get section name, store into a dynamic array
        
    
} while (KvGotoNextKey(kv));
    
    return 
true;
}

public 
int handlerUI(Menu menuMenuAction actionint parameterCLint parameterARGS)
{
    
/* If an option was selected, tell the client about the item. */
    
    
if (action == MenuAction_Select)
    {
        
char selectedName[32];
        
menu.GetItem(parameterARGSselectedNamesizeof(selectedName)); 
        
retrieveCachedData(parameterCLselectedName);
            
            
/* Know which section we talkin' bout = selectedName = Section*/
            /* Compare data with the keyValues */
            /* Retrieve Info */
            /* Teleport */
            
    
}
    
/* If the menu was cancelled, print a message to the server about it. */
    
else if (action == MenuAction_Cancel)
    {
        
PrintToServer("Client %d's menu was cancelled.  Reason: %d"parameterCLparameterARGS);
    }
    
/* If the menu has ended, destroy it */
    
else if (action == MenuAction_End)
    {
        
delete menu;
    }
}


public 
Action buildUI(int clint args)
{
    
char buffer[32];
    
Menu menu = new Menu(handlerUI);
    
menu.SetTitle("Teleport to:");
    
    for (
int i 0GetArraySize(g_adtArray); i++)
    {
        
GetArrayString(g_adtArrayibuffersizeof(buffer));
        
menu.AddItem(buffer"location");
    }
    
menu.ExitButton true;
    
menu.Display(clMENU_TIME_FOREVER);
    
    return 
Plugin_Handled;
}

public 
bool retrieveCachedData(int clchar[] section)
{
    
float temploc[3];
    
bool whitelist;
    if (!
kv.JumpToKey(section))
    {
        return 
false;
        
// no setted section ??? 
    
}
    
    
int clteam GetClientTeam(cl);
    
    switch (
clteam)
    {
        case 
CS_TEAM_CT:
        {
            
kv.GetFloat("ctlocx"temploc[0]);
            
kv.GetFloat("ctlocy"temploc[1]);
            
kv.GetFloat("ctlocz"temploc[2]);
        }
        case 
CS_TEAM_T:
        {
            
kv.GetFloat("tlocx"temploc[0]);
            
kv.GetFloat("tlocy"temploc[1]);
            
kv.GetFloat("tlocz"temploc[2]);
        }
    }
    
//whitelist = kv.GetNum("tlocy", temploc[1]);                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
    
teleportcl(cltemploc);
    
delete kv;
    return 
true;
}

public 
teleportcl(int clfloat pos[3])
{
    
TeleportEntity(clposNULL_VECTORNULL_VECTOR);
}

public 
Action loopremove(Handle timer)
{
    
int ent;
    
    if (
GameRules_GetProp("m_bWarmupPeriod") == 0// it's not warm up
    
{
        for (
int i 1MaxClientsi++)
        {
            if (
IsClientInGame(i) && IsPlayerAlive(i))
            {
                for (
int wepwep 4wep++)
                {
                    if ((
ent GetPlayerWeaponSlot(iwep)) != -1)
                    {
                        
SetEntProp(entProp_Send"m_iPrimaryReserveAmmoCount"0);
                        
SetEntProp(entProp_Send"m_iClip1"0);
                    }
                }
                
            }
        }
    }

My KeyValue:
PHP Code:
"Locations"
{
    
"Arena"
      
{
               
"ammo"         "1"
               "ctlocx"     "535"
            "ctlocy"     "5290"
            "ctlocz"     "1924"
            "tlocx"     "4467"
            "tlocy"     "45361"
            "tlocz"     "375"
        
}
    
"TradeRooms"
      
{
               
"ammo"         "0"
               "ctlocx"     "535"
            "ctlocy"     "5290"
            "ctlocz"     "1924"
            "tlocx"     "4467"
            "tlocy"     "45361"
            "tlocz"     "375"
        
}
    
"Surf"
      
{
               
"ammo"         "0"
               "ctlocx"     "535"
            "ctlocy"     "5290"
            "ctlocz"     "1924"
            "tlocx"     "4467"
            "tlocy"     "45361"
            "tlocz"     "375"
        
}
    
"Bhop"
      
{
               
"ammo"         "0"
               "ctlocx"     "535"
            "ctlocy"     "5290"
            "ctlocz"     "1924"
            "tlocx"     "4467"
            "tlocy"     "45361"
            "tlocz"     "375"
        
}

This is my code & KeyValue, I want to access these values in such way that I won't stress my server, what would be the better way, keeping my KeyValue Handle open and search sections for a value each time a user inputs data, or cache all the data in an adt_array or an adt_trie?
__________________
Perhaps my lack of faith was my undoing,

Last edited by bally; 12-21-2015 at 14:07.
bally is offline
fakuivan
Senior Member
Join Date: Nov 2015
Old 12-22-2015 , 15:41   Re: Need a good array for this...
Reply With Quote #10

Don't worry about optimization unless is something more processing or io intese like writting to a databse. Finish the plugin first and see if it needs any optimization. If that is the case you can use a multidimensional array without leaving pawn, with static size as a gobal variable if the size is not a problem or an adt array if you need variable size. Take a look at this

Edit: Multidimensional Arrays in pawn:

new Float:g_flPositions[MAXPLAYERS+1][3];

for (new i=0; i<sizeof(g_flPositions); i++) {
g_flPositions[i][0] = -1.0;
g_flPositions[i][1] = -1.0;
g_flPositions[i][2] = -1.0;
}

Last edited by fakuivan; 12-22-2015 at 15:49.
fakuivan 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 09:43.


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