AlliedModders Donor
|
05-02-2015
, 22:08
Re: Add two KeyValue files together
|
#7
|
All right, so I've taken a little different approach than the one Exolent suggested.
I've created an enum with all the keys of the section including the section name itself and made it into two arrays:
Code:
enum _:KVKeys{
String:s_section[32],
i_score,
i_kills,
i_deaths,
};
new array_a[16][KVKeys];
new array_b[16][KVKeys];
Then cached key values from two files I wanted to merge in them:
Code:
static String:KVPathA[PLATFORM_MAX_PATH];
static String:KVPathB[PLATFORM_MAX_PATH];
static String:KVPathC[PLATFORM_MAX_PATH];
public OnPluginStart(){
BuildPath(Path_SM, KVPathA, sizeof(KVPathA), "data/[FILENAME]_a.txt");
BuildPath(Path_SM, KVPathB, sizeof(KVPathB), "data/[FILENAME]_b.txt");
BuildPath(Path_SM, KVPathC, sizeof(KVPathC), "data/[FILENAME]_c.txt"); //'C' will be A and B merged
CacheFileA(); //Caching the A file
CacheFileB(); //Caching the B file
CreateFileC(); //Create the merged file
}
CacheFileA()
Code:
CacheFileA(){
new Handle:dbA = CreateKeyValues("[ROOTNAME]");
FileToKeyValues(dbA, KVPathA);
if(KvGotoFirstSubKey(dbA, true)){
new i = 0;
do{
KvSavePosition(dbA);
//if(KvGetNum(dbA, "i_score", 0) < 3) continue; //A filter can be used, for example skip a section in which 'i_score' is less than 3
decl String:s_section_this[32];
KvGetSectionName(dbA, s_section_this, sizeof(s_section_this));
strcopy(array_a[i][s_section], 32, s_section_this);
array_a[i][i_score] = KvGetNum(dbA, "score", 0);
array_a[i][i_kills] = KvGetNum(dbA, "kills", 0);
array_a[i][i_deaths] = KvGetNum(dbA, "deaths", 0);
i++;
KvGoBack(dbA);
}while(KvGotoNextKey(dbA, true) && i < sizeof(array_a));
KvRewind(dbA);
}
CloseHandle(dbA);
}
CacheFileB()
Code:
CacheFileB(){
new Handle:dbB = CreateKeyValues("[ROOTNAME]");
FileToKeyValues(dbB, KVPathB);
if(KvGotoFirstSubKey(dbB, true)){
new i = 0;
do{
KvSavePosition(dbB);
//if(KvGetNum(dbB, "i_score", 0) < 3) continue;
decl String:s_section_this[32];
KvGetSectionName(dbA, s_section_this, sizeof(s_section_this));
strcopy(array_b[i][s_section], 32, s_section_this);
array_b[i][i_score] += KvGetNum(dbB, "score", 0);
array_b[i][i_kills] += KvGetNum(dbB, "kills", 0);
array_b[i][i_deaths] += KvGetNum(dbB, "deaths", 0);
i++;
KvGoBack(dbB);
}while(KvGotoNextKey(dbB, true) && i < sizeof(array_b));
KvRewind(dbB);
}
CloseHandle(dbB);
}
And then created the final file using the two arrays:
CreateFileC()
Code:
CreateFileC(){
new Handle:dbC = CreateKeyValues("[ROOTNAME]");
FileToKeyValues(dbC, KVPathC);
new a = 0;
while(a < 16){ //16 being the array lenght
KvJumpToKey(dbC, array_a[a][s_section], true);
KvSetNum(dbC, "score", array_a[a][i_score]);
KvSetNum(dbC, "kills", array_a[a][i_kills]);
KvSetNum(dbC, "deaths", array_a[a][i_deaths]);
KvGoBack(dbC);
a++;
}
new b = 0;
while(b < 16){ //With 'b' loop adding its keys
KvJumpToKey(dbC, array_b[b][s_auth], true);
new score = KvGetNum(dbC, "score", 0);
score += array_b[b][i_score];
KvSetNum(dbC, "score", score);
new kills = KvGetNum(dbC, "kills", 0);
kills += array_b[b][i_kills];
KvSetNum(dbC, "kills", kills);
new deaths = KvGetNum(dbC, "deaths", 0);
deaths += array_b[b][i_deaths];
KvSetNum(dbC, "deaths", deaths);
KvGoBack(dbC);
b++;
}
KeyValuesToFile(dbC, KVPathC);
CloseHandle(dbC);
}
NOTE: For some reason in the final file the root section is treated like a subsection. Meaning that at some point in the file there will something like:
I haven't looked into on how to fix it as the solution is to simply remove those lines and everything's good to go.
FINAL NOTE: Please don't hate on me for having player stats in a KV file, I'll port them to MySQL once I learn how everything works, I swear.. ;~;
Last edited by Phil25; 05-02-2015 at 22:12.
|
|