PDA

View Full Version : Module: Vdf (key/value trees) - 1.07


commonbullet
02-22-2007, 00:19
This is a simple module to handle vdf (valve data files) trees. It makes very easy to read, create and write node structures.

A vdf tree is composed by nodes of key/value string pairs in quotation marks hierarchically disposed in braces.

Example:

"UserConfigData"
{
"Steam"
{
"Cached"
{
"SteamGamesDialog.res"
{
"xpos" "700"
"ypos" "112"
"wide" "204"
"tall" "332"
}
}
}
}

Big thanks to sawce for helping with linux.

Zenith77
02-22-2007, 09:58
So basically now instead of creating are own file formats, we can just use this for plugins that require loading things? In other words, we could create are own .vdf files then read from them (I'm guessing 90% yes)? If so, you've saved my life.

Twilight Suzuka
02-22-2007, 15:24
That is actually reasonably cool.

A little ineffecient though, as you could use casts to hand the user a direct pointer, thus improving speed by a large margin (due to cache misses).

But cool none the less.

commonbullet
02-22-2007, 16:18
Yep, Zenith that's what it's supposed to be ;).

Thanks Rukia.

EDIT: I am working on that.

sawce
02-23-2007, 00:49
Here's a Linux build (if you update and don't have a way to build Linux on your own PM me and I'll rebuild). I haven't tested this build's functionality beyond it loading properly.

I'd suggest 2 things:

1. Look at other module include files (.inc and the moduleconfig.h) (like fakemeta, engine) and see how they do module auto loading.

2. Update your amxxmodule.cpp/amxxmodule.h to whatever is in SVN, it doesn't export the amxx query functions properly in GCC4 with the version you have.

BAILOPAN
02-23-2007, 01:07
Shameless plug: If you're interested, I wrote an article on this file format using a different parsing technique: http://www.sourcemod.net/devlog/?p=96 (source code included)

Tree-based parsers are better for coders who like simplicity and don't like maintaining state, so I can certainly see this module being useful ;) good job.

commonbullet
02-23-2007, 11:51
Thank you sawce for that linux build, I'll check how to do the auto load thing and update my source files (I was using sdk from amxx 1.75).

Very cool reading - thanks Bail, maybe in future it could support both parsing methods (in separate modules or not), just like i.e. xml's sax & dom libraries.

I'm trying to work out Rukia's point (if I understand what she meant).
The way it works right now, nodes are exposed in pawn as indexes of a pointer 'list'. When a function is called it checks if node is in pointer array index bounds before picking up the pointer.

If these 'nodes' in script were directly nodes objects addresses, how could I safely cast them? (it could happen that a coder would pass a wrong argument or accidentally change the variable and hl would crash; I guess this would be hard to debug)

BAILOPAN
02-23-2007, 13:29
Using pointers directly is possible if you explicitly tell users not to pass wrong ones. For example, pcvars in AMX Mod X use direct pointers. Just tell users to be careful and not to assume that the return values are mutable or consistent in any way.

Zenith77
02-24-2007, 12:46
Already have some requests, as I plan on using this module in two of my major projects.
I would like these two natives:


vdf_is_first_node();
vdf_is_last_node();


or perhaps collapse them into one native:


vdf_is_node_number(myNode, 1);
vdf_is_node_number(myNode, vdf_num_nodes(myParentNode));


The latter one would require an additional native though, 'vdf_num_nodes()', which as you can tell returns the number of nodes in the current node.

Also, you should put everything in one big .zip file ^^..

commonbullet
02-24-2007, 15:17
Cool ideas.

You could check if it's the last or first node with "vdf_get_first_node" or vdf_get_last_node", but I see the advantages of using your model in a loop.

The new version is going to change functions arguments a bit, since nodes and trees will be pointers, functions like vdf_get_next_node won't need to pass the tree i.e.

And although this means performance enhancement you'll have to be very careful - I crashed hl a couple of times when I was writing the new example script carelessly... :)

For the same reason it's better to detach nodes concept from numbers. I'll include a function to count nodes in a branch though.

Finally I'm including important stuff I had forgotten like destroying trees and setting keys/values functions.

Zenith77
02-24-2007, 18:02
Sounds cool ^^. But are you adding the natives or no (sounds like you are, but didn't get an answer :-))

commonbullet
02-24-2007, 18:51
I guess I'll include this form:
vdf_is_first_node(node);
vdf_is_last_node(node); actually, they could be easily replaced with these existent functions
!vdf_get_previous_node(node) // if true that's first node
!vdf_get_next_node(node) // if true that's the last node
but I guess the former sounds clearer.

And I'll include another one to way to count nodes in a branch. Maybe you can help me to find a better name to that.
vdf_count_branch_nodes(node)

Zenith77
02-25-2007, 10:13
vdf_num_branch_nodes() lol?

commonbullet
02-25-2007, 14:04
Update:

- updated sdk files and included auto load feature.
- nodes and trees are now pointers (thus should be used carefully)
- included the following natives.
vdf_set_node_key(node, const key[]);
vdf_set_node_value(node, const value[]);
native vdf_count_branch_nodes(node);
vdf_remove_tree(vdftree)
- included these stocks as suggested by Zenith vdf_is_last_node(node)
vdf_is_first_node(node)
- The number of arguments of many natives has changed.
- Included a more consistent example – it covers almost all features - creatings a trees, saving, reading from file, representing trees structures in a menu interface.
I’ve spammed this example with comments as so to make it clear for everyone (not only for more experienced coders).

Thanks to Bail, Rukia, sawce and Zenith for helping me to improve it.

Zenith77
02-25-2007, 14:44
Yay. I love all these modules coming out (this and MemoryX). They've been a great aid to me :-).

commonbullet
03-01-2007, 19:16
Update 1.02

- Included new search natives:

// creates a new search
vdf_create_search();

// sets up search
vdf_set_search(search, tree, const searchstr[], searchtype = 0, level =-1, ignorecase = 0);

// finds next node that matches search
vdf_find_next_match(search, startnode = 0);

// closes search
vdf_close_search(search);
- Included this native for fast checking node depth:native vdf_get_node_level(node);
- Detailed documentation in vdf.inc

- Included a plugin example for searching

- Fixed tree structure would be wrongly formed if vdf used k&r indentation style.

Zenith77
03-01-2007, 22:25
Yay.

commonbullet
04-07-2007, 15:09
1.03 Update

Lots of new stuff + fixes:

- It now requires tags for trees, nodes, and search. It tends to get safer from mistakes that could cause crashes, and it makes the source in pawn more clear (I think).
They are: VdfTree, VdfNode, VdfSearch; check the examples.

- Search may perform entire tree scanning by setting "*" as the look up string (this feature is useful to parse stuff).
- New find_in_branch native to look up a node in a branch
- New ‘shell’ sort nodes native, vdf_sort_branch. Sorts might be performed to nodes based on key/values (as strings or as numbers).
- New move nodes native (only moves nodes that are in the same tree): vdf_move_to_branch, vdf_move_as_child

- Included some ‘sugar’ to make it easier to lazy coders like me:
- vdf_get_node_value_num, vdf_get_node_value_float, vdf_get_node_value_vector – value string are converted to these ‘types’.
- vdf_set_node_value_num, vdf_set_node_value_float, vdf_set_node_value_vector – converts these ‘types’ to a string and stores in node value.

- Fixed append node bug, and some minor stuff.

Thanks to sawce for helping me with the code and for the Linux build.

commonbullet
04-16-2007, 00:30
Update 1.03a

- fixed find_in_branch - didn't work, I'd forgotten to include in table
- fixed vdf_save, vdf_create wouldn't get the correct path from mod directory

I saw a "daily mapcycle" request in forums suggestions and decided to include a vdf version of this in examples.

commonbullet
06-03-2007, 01:24
There's a bug in the linux version. Since I'm planning to release a new version soon, I'm posting a fix here.

Thanks to Zenith77 for reporting that and sawce for telling me how to debug it in Linux.

EDIT: Old attachment removed.

commonbullet
06-06-2007, 20:24
1.04 Update

- Implemented a simple event based parsing model – vdf_parse, to be used when no tree object creation is needed. It’s documented in inc file, see also vdf_parse.sma example.

- Added an optional event listener support for nodes added in vdf_open native. This can be particularly useful for updating data structures. Check sounds_scheme.sma example and vdf.inc.

commonbullet
07-10-2007, 14:53
1.05 Update

- Fixed parser forwards - sometimes the last node would be omitted
- Fixed root node removal would cause a tree to become unusable
- Fixed vdf_find_in_branch could cause crash
- vdf_get_node_value would ignore a node with a null value - this behavior could cause problems in a loop; now it returns an empty string
- Fixed a typo in vdf.inc that would prevent VDF_OPEN_CONTINUE to be used.

commonbullet
07-21-2007, 03:10
1.05a (small but important update)

- Fixed some mishandled destructors that could cause memory leaks

Big thanks to Bail for including it in the web compiler.

tomba2k
05-22-2009, 22:31
Does this module allow only using .vdf files on server side, or it can access clients .vdf files too?

Arkshine
05-23-2009, 02:34
Nothing to do with client files.

headboy
07-19-2010, 15:46
Hi

I have a problem with my plugin which uses this module. I just debugged once and I got this debug log. I checked my code and I think I didn't make mistake (checked example codes too, everything fine), but the server freeze always with segmentation fault. Please write some suggestion. Thx

(ip,port and folders are hidden: 'xxx')

[New Thread 22422]
[New Thread 13199]
[New Thread 13092]
[New Thread 13091]
Core was generated by `./hlds_i686 -debug -game cstrike -maxplayers 15 +ip xxx.xxx.xxx.xxx +port xxxxx +'.
Program terminated with signal 11, Segmentation fault.
#0 0xf3929210 in ?? () from cstrike/addons/amxmodx/modules/vdf_amxx_i386.so
#0 0xf3929210 in ?? () from cstrike/addons/amxmodx/modules/vdf_amxx_i386.so
#1 0xef4bf898 in ?? ()
#2 0x00042de4 in ?? ()
#3 0x0000001e in ?? ()
#4 0xef4bf898 in ?? ()
#5 0xf1b1dcc8 in ?? ()
#6 0xf1b2aabc in ?? ()
#7 0xef4bf898 in ?? ()
#8 0xf54889dd in ?? () from /home/xxx/cstrike/addons/amxmodx/dlls/amxmodx_mm_i386.so
#9 0xef4bf898 in ?? ()
#10 0xf1b6d890 in ?? ()
#11 0xf119ee5c in ?? ()
#12 0xff993f0e in ?? ()
#13 0xff994300 in ?? ()
#14 0xf54a9280 in amx_exec_asm () from /home/xxx/cstrike/addons/amxmodx/dlls/amxmodx_mm_i386.so
#15 0xf54a9068 in amx_exec_asm () from /home/xxx/cstrike/addons/amxmodx/dlls/amxmodx_mm_i386.so
#16 0x0000009a in ?? ()
#17 0xff993ee8 in ?? ()
#18 0xf1b6d890 in ?? ()
#19 0xf1b2aabc in ?? ()
#20 0xf1b1dcc8 in ?? ()
#21 0xef4bf898 in ?? ()
#22 0x00042f6c in ?? ()
#23 0x0001f164 in ?? ()
#24 0x00043160 in ?? ()
#25 0xff9940c0 in ?? ()
#26 0xef4bf898 in ?? ()
#27 0xf1b01f34 in ?? ()
#28 0xf1b2aabc in ?? ()
#29 0xf15c0fc8 in ?? ()
#30 0x00042ddc in ?? ()
#31 0x00042dd4 in ?? ()
#32 0xff9940c0 in ?? ()
#33 0xef4bf898 in ?? ()
#34 0x000430b4 in ?? ()
#35 0x00043160 in ?? ()
#36 0xf548a06f in ?? () from /home/xxx/cstrike/addons/amxmodx/dlls/amxmodx_mm_i386.so
#37 0xff993f50 in ?? ()
#38 0xff9940c0 in ?? ()
#39 0x00043160 in ?? ()
#40 0x0001f164 in ?? ()
#41 0xef4bf898 in ?? ()
#42 0x000430b4 in ?? ()
#43 0x00028b88 in ?? ()
#44 0x00001f1c in ?? ()
#45 0x00000038 in ?? ()
#46 0xf1b01f34 in ?? ()
#47 0x00000000 in ?? ()
No symbol table info available.
From To Syms Read Shared Object Library
0xf7f62a30 0xf7f639cc Yes (*) /lib32/libdl.so.2
0xf7f4d310 0xf7f59b40 Yes (*) /lib32/libpthread.so.0
0xf7e17990 0xf7f13748 Yes (*) /lib32/libc.so.6
0xf7f798d0 0xf7f9152f Yes (*) /lib/ld-linux.so.2
0xf78f0c30 0xf79712c4 Yes /home/xxx/engine_i686.so
0xf78b15f0 0xf78bfec4 Yes ./libsteam_api_c.so
0xf7889440 0xf78a3ce8 Yes (*) /lib32/libm.so.6
0xf786da60 0xf787bb4d Yes /home/xxx/filesystem_stdio_i386.so
0xf57af2a0 0xf5835ab7 Yes (*) ./cstrike/addons/metamod/dlls/metamod_i386.so
0xf555e09c 0xf5687668 Yes /home/xxx/cstrike/dlls/cs_i386.so
0xf54525e0 0xf54ac854 Yes (*) /home/xxx/cstrike/addons/amxmodx/dlls/amxmodx_mm_i386.so
0xf5408ac0 0xf5433b74 Yes (*) cstrike/addons/amxmodx/modules/fakemeta_amxx_i386.so
0xf53c4920 0xf53d5b28 Yes (*) cstrike/addons/amxmodx/modules/geoip_amxx_i386.so
0xf3ac2150 0xf3ac78f4 Yes (*) cstrike/addons/amxmodx/modules/cstrike_amxx_i386.so
0xf3a8f9f0 0xf3aba3a4 Yes (*) cstrike/addons/amxmodx/modules/hamsandwich_amxx_i386.so
0xf3a449b0 0xf3a4dd80 Yes (*) /home/xxx/cstrike/addons/w/dlls/w_mm_i386.so
0xf39c8f80 0xf3a20bc4 Yes (*) /usr/lib32/libstdc++.so.5
0xf3977c70 0xf39805cc Yes (*) /lib32/libgcc_s.so.1
0xf291b830 0xf2992924 Yes (*) cstrike/addons/amxmodx/modules/mysql_amxx_i386.so
0xf28410e0 0xf284b0b4 Yes (*) cstrike/addons/amxmodx/modules/engine_amxx_i386.so
0xf2835be0 0xf28386e4 Yes (*) cstrike/addons/amxmodx/modules/fun_amxx_i386.so
0xf3853a00 0xf385ac8c Yes (*) /lib32/libnss_files.so.2
0xf2052700 0xf2663684 Yes (*) ./steamclient.so
0xf381f400 0xf383ba40 Yes (*) ./libtier0_s.so
0xf37be070 0xf37f9fe0 Yes (*) ./libvstdlib_s.so
0xf2c054b0 0xf2ce6a04 Yes ./libsteamvalidateuseridtickets.so
0xf392cdd0 0xf392ddf4 Yes (*) cstrike/addons/amxmodx/modules/sockets_amxx_i386.so
0xf39062d0 0xf390ee84 Yes (*) cstrike/addons/amxmodx/modules/regex_amxx_i386.so
0xf3924d20 0xf392a190 Yes (*) cstrike/addons/amxmodx/modules/vdf_amxx_i386.so
0xf38ca400 0xf38d6318 Yes (*) /lib32/libz.so.1
(*): Shared library is missing debugging information.
Stack level 0, frame at 0xff993e74:
eip = 0xf3929210; saved eip 0xef4bf898
called by frame at 0xff993e78
Arglist at 0xff993e6c, args:
Locals at 0xff993e6c, Previous frame's sp is 0xff993e74
Saved registers:
eip at 0xff993e70
End of crash report

commonbullet
07-27-2010, 23:28
Sorry, I didn't read your post carefully before, it's about your plugin. Actually I can't tell you what's going on without reading the code - there are several ways you can cause a crash since functions handle pointers directly. You can send me your code through pm if you want.

Voi
10-26-2010, 19:10
This module crashes the server when im using content replacer plugin under a minute after a mapload

commonbullet
10-27-2010, 17:01
Linux or Windows?
Also it would be easier to track the problem if you could provide more details, files used by the plugin etc.

Voi
10-27-2010, 19:12
windows

Please take a look at my cfg file. Mb there's something wrong in there.

commonbullet
10-28-2010, 19:30
I found a bug in the node removal method. I believe it's fixed, I'm attaching the windows binary and I'll compile for linux and update pack when I get time.

commonbullet
10-28-2010, 23:00
Binary - linux/windows, source packages have been updated.

Voi
10-29-2010, 03:53
So far I can't get the server running. With this cfg it crashes on mapchange or when I join the team. If i remove the "Models" section it doesn't even start.

edit:

Hold on, I think I forgot to replace the old version, the new one seems to work. At least it doesn't crash for sure. Although I can't find the vdf in "meta list" command.

edit2:

Its in "amxx modules" :P.

commonbullet
11-27-2010, 16:59
This module needed an update, so here’s version 1.07; many parts have been rewritten from scratch. These are the most relevant changes:

Cleaner data structure, no more useless indexing and better memory handling
Faster parsing methods and simpler code
Much faster tree object creation (and also simpler code)
Included log messages for syntax error caught during parsing process
New native for traversing tree (check vdf.inc)

Arkshine
11-27-2010, 17:53
Glad to see you're still alive. Nice job !

amokossi
12-14-2010, 03:27
I put the .so file in plugins.ini of metamod but it doesn't start. Hm...

edmundobar
12-18-2012, 01:57
When a function is called it checks if node is in pointer array index bounds before picking up the pointer.