PDA

View Full Version : [Tutorial] DJSON uitleg


Kwarde
16/06/2011, 02:39 PM
Hoi.
In deze uitleg zal ik DJSON uitleggen en hoe die werkt.

Wat is DJSON?
DJSON is een bestand schrijver (filewriter), net zoals DINI. DJSON is gemaakt door Dracoblue.
DJSON werkt doormiddel van databases (SQLITE). Dit maakt het een stuk sneller. Bestanden van DJSON zien er anders uit dan die van Dini.
Hier is een voorbeeld van DINI:

Naam="Je_Naam"
Wachtwoord=Een_Wachtwoord
Score=55

DJSON werkt anders:

{"Naam":"Je_Naam","Wachtwoord":"Een_Wachtwoord","Score":55}

Dini wordt gesorteerd op de volgorde van hoe je ze toevoegd. DJSON werkt alfabetisch. DJSON heeft ook een 'styled' optie (djStyled). Als deze aanstaat zal het er zo uitzien:

{
"Naam":"Je_Naam",
"Wachtwoord":"Een_Wachtwoord",
"Score":55
}

Dit is handiger als je vaak bestanden wijzigd.

Hoe gebruik ik het?
Als eerst moet je (natuurlijk) DJSON downloaden. Dit kan op de site van dracoblue: http://dracoblue.net/download/djson-162/51/
Zet de djson.inc in je {pawno_dir}/include. In je filterscript of gamemode zet je neer: #include <djson>. (standaard allemaal).
Probeer nu eens voor de gein op F5 te drukken (compileren). Je zal twee warnings krijgen, dat twee 'symbols' nooit is gebruikt. Dat klopt! Je moet nl. de functies in On[GameMode/FilterScript]Init en On[GameMode/FilterScript]Exit die de waarschuwing aangeven neerzetten.
Deze zorgen ervoor dat DJSON werkt, en weer netjes afsluit. De funcites zijn djson_GameModeInit(); en djson_GameModeExit();.
Voordat je gaat denken: "Maar hoe zit het dan met filterscripts!!" - Deze functies werken ook gewoon in filterscripts. Sterker nog, als je in één script DJSON gebruikt, betekent het niet dat je DJSON ergens anders zomaar kan gebruiken. Je moet die functies ALTIJD gebruiken in ELK script.
Voorbeeld:

#include <a_samp>
#include <djson>

public OnFilterScriptInit()
{
djson_GameModeInit();
return 1;
}

public OnFilterScriptExit()
{
djson_GameModeExit();
return 1;
}

Nu zal ik uitleg geven over de functies. Deze zijn eigenlijk heel simpel. Ik zal niet alles uitleggen (djson kan ook op een andere manier gebruikt worden nl.), maar alleen de basis dingen, die het handigst zijn voor beginners.
Zoals je hoogstwaarschijnlijk weet zijn er verschillende soorten variabels, namelijk: Floats (vb. 5.5), Strings (vb. "Kwarde"), Booleans (true/false, hoort bij INT!) en Integers (vb. 5). DJSON heeft verschillende functies om die gegevens op te slaan. Het is niet mogelijk om met één functie (in DJson) verschillende types op te slaan.
Integers
Ik begin met integers (simpele getallen). Hiervoor heb je twee functies, nl. een functie om ze op te slaan, en eentje om ze te krijgen van het bestand zelf.
Deze functies heten djSetInt en djInt. Opzich is het niet moeilijk, want de functie naam zegt het al: "Set Int". De eerste heb je dus nodig om een getal op te slaan, en djInt om het getal weer op te roepen van het bestand (zoals ik hierboven al heb getyped).
De functies hebben natuurlijk ook parameters. voor djSetInt zijn deze:
file[], path[], new_value, use_cached_value=true
Je hebt alleen de eerste drie nodig, nl. file[], path[] en new_value. De 'file[]' is het bestandsnaam. Als je bijv. "test.ini" gebruikt, zal DJSON in '{samp_server_dir}/scriptfiles/test.ini' de gegevens opslaan. De 'path[]' is de key (sleutel). In een voorbeeldje hierboven zag je "score:55". De 'score' is de 'path[]'. De '55' is dus de 'new_value'.
Voorbeeld:

djSetInt("test.ini", "getal", 1337);

Nadat je deze hebt uitgevoerd, zal je 'test.ini' de volgende inhoud krijgen:
{"getal":1337}
djInt heeft dezelfde parameters, alleen zonder de 'new_value'. Voorbeeld:

printf("%d", djInt("test.ini", "getal"));

Als 'test.ini' bestaat, en de sleutel 'getal' is '1337', zal je console nu '1337' weergeven. Hier is een voorbeeld script:

#include <a_samp>
#include <djson>

public OnFilterScriptInit()
{
djson_GameModeInit();
if(!fexist("test.ini")) djCreateFile("test.ini");
djSetInt("test.ini", "getal", 1337);
return 1;
}

public OnFilterScriptExit()
{
printf("%d", djInt("test.ini", "getal"));
djson_GameModeExit();
return 1;
}

Als je de filterscript laad, zal het in de 'test.ini' de naam 'string' de inhoud '1337' geven. Als de filterscript stopt, zal die '1337' in de console weergeven.
En we zijn bij een andere functie aangekomen:

Bestanden maken
Ik was het bijna vergeten, maar met DJson moet je bestanden met een functie aanmaken. Deze doet dat (volgens mij ^^) niet automatisch.
Dit is heel simpel met de functie djCreateFile. De enige parameter is 'file[]'. Dit is de bestandsnaam. Vb.
djCreateFile("server.djson");
Deze zal een bestand genaamd 'server.djson' in je 'scriptfiles' folder aanmaken.

Verder is het eigenlijk hetzelfde, strings, floats, bools en integers. Toch nog iets meer informatie.
Float functies: djSetFloat en djFloat
String functies: djSet en dj
Bool functies: djSetInt en djInt.
Ho Kwarde, volgens mij maak je nu een fout! - Nee, dat doe ik niet. De boolean functies zijn wel gewoon djSetInt en djInt. Je moet het alleen iets anders gebruiken.
Hier is een voorbeeld omdat ik niet weet hoe ik het moet uitleggen:

new bool:Boolean;

//Boolean opslaan:
djSetInt("bestand.extensie", "boolean", Boolean);

//Boolean laden:
Boolean = djInt("bestand.extensie", "boolean") ? true : false;

Sluit de functie dus niet met een puntkomma (;) maar met ? true : false;.

Dit was het zo'n beetje. Als je toch nog meer wilt, wees niet bang om het te vragen.

Mvg,
Kevin

Danny
16/06/2011, 03:04 PM
Goede tut :)

Even een vraagje: Ik heb nooit geweten dat DJSON gebruik maakt van SQLLite, betekend dat dat het net zo snel is als MySQL?

Kwarde
16/06/2011, 03:12 PM
Dat weet ik niet, maar hij gebruikt idd SQLlite (en dan slaat het nog op in bestanden).
Hier zijn een paar stukjes van djson.inc:


new DB:DJSON_cache_db;

//---- Even later :P -----//
stock DJSON_cache_updateNode(file[],key[],type_id,value[]) {
new query[DJSON_MAX_STRING];
new DBResult:res;
format(query,DJSON_MAX_STRING,"SELECT `id` FROM `c` WHERE file = '%s' AND path = '%s' LIMIT 1",DJSON_sql_escape(file),DJSON_sql_escape(key));
res = db_query(DJSON_cache_db,query);
if (db_num_rows(res) != 0) {
// it exists
new the_id[DJSON_MAX_STRING]="-1";
db_get_field(res,0,the_id,DJSON_MAX_STRING);
db_free_result(res);

format(query,DJSON_MAX_STRING,"UPDATE `c` SET `value`='%s',type=%d WHERE file='%s' AND path='%s'",DJSON_sql_escape(value),type_id,DJSON_sql_escape( file),DJSON_sql_escape(key));
db_query(DJSON_cache_db,query);

return strval(the_id);
} else {
db_free_result(res);

return 0;
}
}

Maar ik DENK dat het dan wel ONGEVEER zo snel is ;)

Michael@Belgium
16/06/2011, 04:26 PM
hah :D Is DJSON één van de beste filewriters ? Ofniet ?

shadowdog
16/06/2011, 06:56 PM
Het valt me op dat er nergens wordt opgevraagd welke waarden je hebt bijv score(traditionele getPlayerScore)
maar alleen playerScore[playerid] overal. (wat ik zoal zag bij dat wat je had laten zijn in mijn topic. Hoe moet je de waarden dan opvragen?

Kwarde
16/06/2011, 07:59 PM
@Michael: Ja, één van de besten. Y_INI is nog altijd het best (snelst), maar die is irritant omdat die zoveel includes gebruikt.

@Shadowdog:


//Boolean laden:
Boolean = djInt("bestand.extensie", "boolean") ? true : false;


Dus:
Variabel = djInt("bestand.extensie", "sleutel");
Bijvoorbeeld:
playerScore[playerid] = djInt("Kevin_Warde.ini", "score");
Bedoel je dat? - En wil je dat ik dat toevoeg?

shadowdog
16/06/2011, 08:06 PM
Maar hoe weet playerscore wat je score is zonder getplayerscore?

mamorunl
16/06/2011, 08:10 PM
@Michael: Ja, één van de besten. Y_INI is nog altijd het best (snelst), maar die is irritant omdat die zoveel includes gebruikt.

@Shadowdog:

Dus:
Variabel = djInt("bestand.extensie", "sleutel");
Bijvoorbeeld:
playerScore[playerid] = djInt("Kevin_Warde.ini", "score");
Bedoel je dat? - En wil je dat ik dat toevoeg?

Naar mijns inziens bedoelt hij iets als:

djSetInt(getPlayerScore(playerid)); // note: rest van de parameters weggelaten
om de score op te slaan &
playerScore[playerid] = djInt("score"); // again, parameters weg
om de score op te slaan & te gebruiken in je script.

Kwarde
16/06/2011, 08:10 PM
Niet ;) - Tenzij het is opgeslagen in een bestand. Maar zoals er al stond, je kan een integer uit een bestand halen met djInt, dat is die functie. Maar je kan geen score krijgen (zover ik weet) zonder GetPlayerScore, tenzij je een custom score systeem gebruikt.
Ik kan nu niet verder helpen, want ik ga slapen. Cya

shadowdog
16/06/2011, 08:24 PM
Ja dat begrijp ik maar hoe pas ik doe toe XD heb al vanalles geprobeerd

mamorunl
16/06/2011, 09:17 PM
Je kan zo iets op meerdere manieren doen. Je kan de bestaande variabele playerScore[playerid] gebruiken:

Wanneer de speler registreert zet je de playerScore naar GetPlayerScore();
Sla daarna de score op met djIntSet (of djSetInt.. weet niet meer).

Je kan ook automatisch schrijven:
djSetInt("naam.ding", "score", getPlayerScore());
ophalen doe je dan: setPlayerScore(playerid, djInt("naam.ding", "score"));

ps: let niet op mijn notatie. Ik ben gewend om de eerste letter klein te schrijven.