Danke für den Hinweiß ist mir gar nicht aufgefallen ![]()
Ist aber bearbeitet^^
Gut ich pack in den 2. Beitrag noch eine weitere erklärung zu db_get_field(_assoc).
Aber nicht mehr heute ![]()
Eher morgen Mittag ![]()
Danke für den Hinweiß ist mir gar nicht aufgefallen ![]()
Ist aber bearbeitet^^
Gut ich pack in den 2. Beitrag noch eine weitere erklärung zu db_get_field(_assoc).
Aber nicht mehr heute ![]()
Eher morgen Mittag ![]()
Vielleicht weil ich nicht umbedingt soviel Wert darauf gelegt habe, dass das Betriebssystem zu 100% stabil ist, 99,99% reichen mir für die Vorzüge von MATE ![]()
Top, bis auf die kleinen Rechtschreibfehler, aber ich schätze bei soviel Text kommt man einfach durcheinander
Das stimmt, ich das ist auch sehr viel Arbeit gewesen, aber es fehlen nur kleine Wörter, das passiert auch mir ![]()
ich bewerte dich nicht, da du es nicht Wert bist von einem Punktesystem bewertet zu werden, welches eh nichts aussagekräftiges erläutert
Das ist nett ![]()
dass wenn man sich ein UCP basteln möchte, dass man da lieber MySQL benutzt
Ich habe nie behauptet das man lieber SQLite nutzen sollte. ![]()
Ich wüsste nicht warum das nicht funktionieren sollte.
MySQL ist nur eine mit ein paar Funktionen aufgepushte Version von SQLite,
von daher sollte das Problem los funktionieren.
Ich weiß aber nicht wie das bei SAMP mit den SQL Injections funktioniert,
es gibt keine real_escape_string funktion.
Es kann natürlich sein, das der Server das selbstständig schützt ![]()
Es gibt da aber auch noch nen Unterschied, Mint hat 2 Versionen.
Einmal Cinnamon und einmal MATE
Ich selber habe MATE aber man muss selber wissen was man will.
Einfach mal hier lesen
http://www.chip.de/artikel/Lin…riebssystem_53455677.html
ich wollte morgen mal auf meinem Laptop Ubuntu installieren
Es gibt ja nicht nur Ubuntu es gibt ja auch auf Ubuntu bassierende Betriebssysteme wie z.B. Linux Mint.
Ich selber nutze Mint und die Treiber wurden alle direkt installiert.
Sprich, probieren über studieren, eigentlich ist Ubuntu so schlau und hat die passenden Treiber irgendwo parat.
Sonst nutze einfach Mint ![]()
Da sollte das gehen
Veery Nice, werds von nun an nutzen
Freut mich, dass ich jemanden damit überzeugen konnte.
BTW:
Ihr könnte natürlich auch hier fragen dazu stellen wenn etwas nicht funktioniert ![]()
Es heißt dynamisch und nicht Dynamik.
Ich kann dir nicht sagen was es nicht nur ist.
Es ist nicht nur Ingame erstellen, verändern, löschen, laden, speichern.
Aber viele Glauben das.
Ich lass euch damit mal alleine ![]()
Warum sucht ihr euch nicht einfach einen Server der sich euch "unterwirft"?
Das wäre einfacher als sich ein Team zu suchen, das noch am Script arbeitet.
Du weißt aber schon das gpci nur einen verschlüsselten Code des Windowsbenutzers zurückgibt, oder?
Das hatten wir schonmal.
Nutzer wird gebannt auf dem Server holt sich eine neue IP legt einen neuen Benutzer an wählt einen anderen Nickname und kann wieder spielen.
Also so doll ist das nicht ![]()
Danke ist mir gar nicht aufgefallen ![]()
Ist geändert
Dein Problem ist beim texturennamen, der exestiert nicht ![]()
SetObjectMaterial(myobject1, 0, 6322, "law2_roadsb", "stormdrain3_nt",0); // stormdrain3_nt stimmt nicht
Probier mal
ws_nicepave
Das sollte dann richtig sein.
BTW: Die 0 kannst du weglassen ![]()
Wenn ihr immer noch wissens hungrig nach den Funktionsweisen der restlichen SQLite Funktionen seid,
dann gratuliere ich euch
Nicht jeder würde soweit lesen.
Gut als nächstes beschäftigen wir uns mit folgenden Funktionen:
| Funktionen | Kurz Beschreibung |
| db_num_rows(); | Gibt die Anzahl der ausgelesenen Zeilen zurück. |
| db_next_row(); | Springt in die nächste Zeile, sofern es mehr als eine ausgelesene Zeile gibt. |
| db_num_fields(); | Gibt die Anzahl der ausgelesenen Spalten zurück die in einer Zeile sind. |
| db_field_name(); | Gibt den Namen des Feldes zurück. |
Sie mögen nicht unbedingt immer so nützlich sein bzw. klingen,
aber man ist froh darüber wenn man sie braucht, vertraut mir ![]()
Ich werde im Verlauf nur noch auf die Funktionen eingehen mit denen wir uns noch nicht beschäftigt haben.
Das heißt ich werde z.B. die einzelnen Querys nicht mehr erklären oder die Funktionen die von mir schon einmal erklärt worden sind.
db_num_rows
Diese Funktion funktioniert wie mysql_num_rows.
Sie gibt die Anzahl der ausgelesen Spalten zurück.
Das wäre meist dann nützlich, wenn man z.B. feststellen möchte ob ein User regestiert ist.
Ein kleines Beispiel dazu:
public OnPlayerConnect(playerid)
{
new query[128];
GetPlayerName(playerid,query,MAX_PLAYER_NAME);
format(query,128,"SELECT * FROM `Accounts` WHERE `Name` = '%s'",query);
new DBResult:result = db_query(database,query);
new rows = db_num_rows(result); // Speichern der Reihen in der Variable Rows
db_free_result(result);
if(rows == 1) SendClientMessage(playerid,0xFFFFFFFF,"Registriert");
/*
Es gibt natürlich auch die Möglichkeit, ohne Zwischenspeicherung die Abfrage zu machen:
if(db_num_rows(result) == 1) SendClientMessage(playerid,0xFFFFFFFF,"Registriert"); // Achtung! - hier muss der Speicher trotzdem wieder freigegeben werden.
*/
else if(rows > 1) SendClientMessage(playerid,0xFFFFFFFF,"Es gibt mehrere Accounts mit diesem Namen");
else SendClientMessage(playerid,0xFFFFFFFF,"Du bist nicht Registriert");
return 1;
}
Alles anzeigen
db_next_row
Diese Funktion arbeitet wie mysql_retriew_row,
sie kann benutzt werden, wenn man mehrere Einträge hat.
z.B. wenn man 2x den gleichen Wert in einer Tabelle hat.
(Eine kleine Anspielung auf die Abfrage im Beispiel von db_num_rows)
Dieses Beispiel hat nur entfernt was mit dem vorherigen zu tun:
public OnPlayerConnect(playerid)
{
new store[5];
new DBResult:result = db_query(database,"SELECT `ID` FROM `Accounts`");// Auslesen aller ID Einträge die in der Tabelle Accounts sind.
new rows = db_num_rows(result); // Speichern der Reihen in der Variable Rows
if(rows == 1) SendClientMessage(playerid,0xFFFFFFFF,"Es ist nur ein Account in der Tabelle");
else if(rows > 1)
{
while(db_next_row(result)) // Die Schleife läuft solange, bis die letzte Zeile erreicht ist
{
db_get_field(result,0,store,5); // Auslesen des Feldes mit der ID 0 in der aktuellen Spalte
SendClientMessage(playerid,0xFFFFFFFF,store);
}
}
db_free_result(result);
return 1;
}
Alles anzeigen
db_num_fields
Diese Funktion ist vergleichbar mit der mysql Funktion mysql_num_fields und bewirkt exakt das gleiche.
Sie kann z.B. in Verbindung mit db_get_field genutzt werden.
Hier ein Beispiel zur Verdeutlichung in der Anwendung:
public OnPlayerConnect(playerid)
{
new store[50];
new DBResult:result = db_query(database,"SELECT * FROM `Accounts`");
new fields = db_num_fields(database);
for(new i;i!=fields;i++)
{
db_get_field(result,i,store,sizeof(store));
/*
i ist hier die Feld ID. Die FeldID wird hier durch die Schleife immer geändert.
Anstatt sizeof geht natürlich auch 50 bzw. die Größenangabe.
*/
SendClientMessage(playerid,0xFFFFFFFF,store); // Ausgabe des Inhaltes
}
}
Alles anzeigen
db_field_name
Diese Funktion hat in MySQL kein Gegenstück.
Sie speichert den Feldnamen in der angegebenen Variable und kann in Verbindung mit db_get_field_assoc genutzt werden.
Aber im folgenden Beispiel wäre das unpraktisch, aber es soll ja nur als Verdeutlichung dienen. ![]()
public OnPlayerConnect(playerid)
{
new store[50],fieldname[50];
new DBResult:result = db_query(database,"SELECT * FROM `Accounts`");
new fields = db_num_fields(database);
for(new i;i!=fields;i++)
{
db_field_name(result,i,fieldname,sizeof(fieldname));
/*
i ist hier die Feld ID. Die FeldID wird hier durch die Schleife immer geändert.
Der Name des Feldes wird hier in der Variable "fieldname" gespeichert
*/
db_get_field_assoc(result,fieldname,store,sizeof(store));
/*
Jetzt steht der Feldname in "fieldname" und wird als Parameter übergeben.
Das heißt steht in "fieldname" TestFeld wird so umgewandelt:
db_get_field_assoc(result,"TestFeld",store,sizeof(store));
*/
SendClientMessage(playerid,0xFFFFFFFF,fieldname); // Ausgabe des Feld Namens
SendClientMessage(playerid,0xFFFFFFFF,store); // Ausgabe des Inhaltes
}
}
Alles anzeigen
Gut das war es auch schon.
Vielen Dank fürs Lesen ![]()
Ich hoffe ich konnte euch die Welt von SQLite ein wenig näher bringen.
Falls Fragen - Fehler - Vorschläge zur Hand sind, postet sie doch bitte unten im Thread ![]()
Bewertungen sind natürlich nicht verboten ![]()
Hallo,
ich möchte euch einmal die Alternative zu MySQL vorstellen, nämlich SQLite.
Im Forum kusieren bisher 2 Werke damit einmal die DT_SaveBox und einmal gPM.
Ich finde es relativ traurig, das viele glauben man müsse unbedingt MySQL als Datenverwaltung haben, weil es mega super toll und total schnell sei, das ist aber nicht so.
SQLite weist gewisse Vorzüge in der Geschwindigkeit bei kleineren Datenbanken im gegen Satz zu MySQL auf.
Erst wenn die Datenbank, verdammt groß wird weist es Geschwindigtkeitseinbußen auf.
Viele von euch sind ja der Meinung das man UCPs nur mit Hilfe von MySQL erstellen kann,
dies stimmt aber nicht.
SQLite weist in PHP den gleichen Funktionsumfang wie wie MySQL auf.
Eine Übersicht über die Funktionen von PHP in Verbindung mit SQLite findet ihr hier
Für normale User gibt es keinen wirklichen Unterschied,
aber es gibt wesentliche Unterschiede zum Funktionsumfang, wie der Name "Lite" schon vermuten lässt.
Sie sind nicht für den normalen Gebrauch wirklich wichtig, also keine Sorge ![]()
Fangen wir mit dem wesentlichen an.
Warum SQLite?
Warum SQLite?
Die Frage ist nicht so schwer zu beantworten.
Wie oben schon beschrieben ist es in vielen Fällen überhaupt nicht nötig MySQL zu nutzen.
Es gibt natürlich einen Nachteil in punkto Sicherheit.
Die Datenbank liegt nur im Scriptfiles Ordner und kann von jedem der darauf Zugriff hat ausgelesen werden.
Es gibt natürlich auch gewisse Vorzüge von SQLite.
z.B. die Datenbank besteht nur aus einer Datei und ist nur einige (hundert) Kilobyte groß, also kein wirklicher Speicherplatzverlust.
Dazu passt sich die Datenbank während der Laufzeit immer auf das System an, das gerade die Datenbank benutzt.
Das vereinfacht den Austausch zwischen verschiedenen Systemen, sogar zwischen Systemen mit unterschiedlichen Byte-Reihenfolgen.
Jede Spalte kann also Daten beliebiger Typen enthalten, die erst zur Laufzeit wird nötigenfalls konvertiert werden.
Diese Vorzüge sind natürlich nicht für jeden relevant, deshalb muss jeder selbst entscheiden, ob er lieber SQLite, MySQL oder gleich beim klassischen Filesystem bleibt.
Also gut fangen wir mit dem eigentlichen Coding-/Scriptteil an.
Erstellen bzw. öffnen einer Datenbank:
Falls eine Datenbank noch nicht existiert, man sie aber trotzdem öffnen möchte,
ist es in SA:MP nicht relevant diese per Hand zu erstellen,
wenn man die Datenbank trotzdem per Hand erstellen möchte, kann dies gerne tun.
Anleitung dazu findet ihr weiter unten.
Damit müssen wir uns aber nicht abgeben, da dies der SA:MP Server für uns übernimmt. ![]()
Die Funktion dafür lautet db_open();
hier ein kleines Beispiel:
new DB:Database;
/*
Die "ID" zu Datenbank speichern wir in Database, der Tag "DB" sorgt,
einfach gesagt dafür, das nur bestimmte Funktionen die Variable "überschreiben"
Warum die "ID" Speicherung wichtig ist, folgt später.
*/
public OnGameModeInit()
{
Database = db_open("Stats.db"); // wir wollen hier die Datenbank Stats erstellen bzw. öffnen
return 1;
}
Alles anzeigen
OK, wir haben jetzt eine Datenbank erstellt, aber wir wollen jetzt ja damit arbeiten.
Erstellen von Tabellen in der SQLite Datenbank:
Das erstellen von Tabellen in der Datenbank, läuft nicht unbedingt so einfach ab, wie bei MySQL, sofern man immer mit PhpMyAdmin gearbeitet hat.
Ich nehme jetzt als Beispiel Navicat, weil es eigentlich dafür am einfachsten ist.
Sofern ihr Navicat noch nicht installiert habt, hier ein Downloadlink: http://www.computerbild.de/dow…Navicat-Lite-1298757.html
Zuerst müssen wir eine Verbindung zur Datenbank herstellen, das geht aber nur wenn sie auch existiert^^
Gut zum erstellen der Verbindung gehen wir zuerst auf den "Button" Connection und wählen SQLite aus

Dann legen wir den Verbindungsnamen und die Datenbank Datei fest.
Dabei ist zu beachten das "Existierende Datenbank Datei" ausgewählt ist.

Als nächstes gilt es die Tabelle zu erstellen, dies geht über "New Table",
dort ist alles wie gehabt.
Felder erstellen und den Feldtypen festlegen.
Meistens braucht man hier allerdings nur Integer und Text.
Bei Text ist grundsätzlich die Länge anzugeben und bei den Integer nicht, diese passen sich selbstständig an.
Als nächstes wenn die Tabelle erstellt ist, speichern wir sie und geben ihr einen Namen.
Die Tabelle mit der wir arbeiten werden ist unten.

Nach dem wir die Tabelle erstellt haben, schließen wir Navicat und kümmern und uns wieder um den Scriptteil.
Einfügen von Daten in die Datenbank:
Das einfügen von Daten ist eigentlich das einfachste,
ich vollführe das einmal an einem Beispiel, da dies eigentlich selbsterklärend ist,
wenn man schon mal mit MySQL bzw. SQL gearbeitet hat.
public OnPlayerConnect(playerid)
{
new query[128];
GetPlayerName(playerid, query, MAX_PLAYER_NAME); // speichern der Spielernamens in query
format(query, 128, "INSERT INTO `Accounts` (`ID`, `Name`) VALUES (7, '%s')",query); // Formatierung des Strings bzw. des Querys und einfügen
/*
INSERT INTO | Suggeriert der Datenbank das nun etwas in eine Tabelle (Accounts) eingefügt wird
`Accounts` | Die Tabelle
(`ID`,`Name`) | Die einzelnen Felder
VALUES | Suggeriert der Datenbank, das nun die Werte folgen, die zu den Felder gehören
('%s','7') | Die Werte die in die Felder eingetragen werden
*/
db_query(Database, query); // Ausführen des Querys
/*
Hier kommt die variable Database zum Tragen.
Database bzw. die ID ist hier wichtig, falls man mehrere Datenbanken gleichzeitig offen hat.
Ein weiter Vorteil.
Man kann mehr als 4, wie bei den MySQL Plugins, Connections gleichzeitig haben.
*/
return 1;
}
Alles anzeigen
Die Tabelle sollte danach so aussehen.
Wenn nicht, beginnt von vorne oder lasst es,
wer es bis hier hin zum 2. mal nicht geschafft hat, sollte es lassen ![]()
Updaten von Werten:
Nun zum 2. einfachsten, das Updaten von Werten.
Es ist nicht viel anders als das einfügen, der Aufbau des Querys sind nur komplett anders.
public OnPlayerDisconnect(playerid,reason)
{
new query[128];
GetPlayerName(playerid, query, MAX_PLAYER_NAME); // speichern der Spielernamens in query
format(query, 128, "UPDATE `Accounts` SET `ID` = '77' WHERE `Name` = '%s'", query); // Formatierung des Strings bzw. des Querys und einfügen
/*
UPDATE | Suggeriert der Datenbank das nun etwas in der Tabelle (Accounts) geupdatet wird
`Accounts` | Die Tabelle
SET | Suggeriert der Datenbank das nun alle Felder mit ihren Werten folgen
`ID` = '77' | Setzt das Feld ID auf 77
WHERE `Name` = '%s' | Suggeriert der Datenbank in welcher Spalte etwas geändert bzw. geupdatet werden soll.
*/
db_query(Database, query); // Ausführen des Querys
return 1;
}
Alles anzeigen
Wenn der Code ausgeführt wurde sollte eure Tabelle wie folgt aussehen
Bild 4:
Wenn nicht, alles auf Anfang oder lasst es ![]()
Auslesen von Daten:
Nun zum schwierigsten Teil, das Auslesen von Daten.
Eigentlich ist es ganz einfach, wenn man es verstanden hat.
Problem hier allerdings, es gibt hier zwei verschiedene Möglichkeiten an die Daten zu kommen.
Ich arbeite sie von oben bis unten einmal ab.
Möglichkeit 1:
Das ist die schwierigste Möglichkeit.
Hier arbeiten wir direkt mit mehreren Feldern,
da es ziemlich blöd und umständlich ist alle Felder die man braucht einzeln aus zu lesen.
public OnPlayerSpawn(playerid)
{
new query[128];
GetPlayerName(playerid, query, MAX_PLAYER_NAME); // Speichern der Spielernamens in query
format(query,128,"SELECT * FROM `Accounts` WHERE `Name` = '%s'",query); // Formatierung des Strings bzw. des Querys und einfügen
/*
SELECT | Suggeriert der Datenbank das nun etwas "entnommen" wird
* | bedeutet nur das alles entnommen wird, macht nur dann Sinn, wenn man mehr als eine Sache aus der Tabelle laden möchte
FROM | Suggeriert von welcher Tabelle entnommen wird
`Accounts` | Die Tabelle
WHERE `Name` = '%s' | Die zu entnehmende Zeile
*/
new DBResult:result = db_query(Database, query); // Den Rückgabewert also das Ergebnis in der Variable result speichern | Achtung, das ist nicht das was wir wollen - ist später aber wichtig
db_get_field_assoc(result, "ID", query, 5); // Wir speichern den Wert aus der Tabelle im Feld ID im String query | 5 ist hier die Länge die der Wert maximal haben darf.
// Das heißt, wenn im Feld 123457 steht wird nur 12345 gespeichert. Da 123457 6 Zeichen enthält und nur 5 maximal enthalten sein dürfen, wird es auf 12345 gekürzt.
/*
Da der Wert nun in einem String ist und wir den so überhaupt nicht gebrauchen können, da es ja ein Integer bzw. eine Zahl ist müssen wir das umwandeln
und das geht mit strval();
*/
new ID = strval(query); // Umwandeln in ein Integer
/*
in einen Float würde das mit floatstr(); funktionieren
new Float:ID = floatstr(query),
*/
printf("ID: %d", ID); // Hier lassen wir uns das Ergebnis ausgeben
db_get_field_assoc(result, "Name", query, MAX_PLAYER_NAME);
print("Name");
print(query); // Wir können direkt damit arbeiten, da wir hier einen String brauchen
db_free_result(result); // Freigeben des Speichers, der durch das Auslesen belegt war
return 1;
}
Alles anzeigen
Wenn alles richtig gemacht wurde steht nun 7 und eure Namen in der Serverlog bzw. in der Serverkonsole.
Herzlichen Glückwunsch ihr könnt nun mehrere Daten auf einmal auslesen ![]()
Möglichkeit 2:
Nun zu der einfachsten Methode, das Auslesen von nur einem Feld.
Zur Verdeutlichung nutze ich hier das vorherige Beispiel ein abgeänderter Form.
public OnPlayerSpawn(playerid)
{
new query[128];
GetPlayerName(playerid, query, MAX_PLAYER_NAME); // Speichern der Spielernamens in query
format(query, 128, "SELECT `ID` FROM `Accounts` WHERE `Name` = '%s'", query); // Formatierung des Strings bzw. des Querys und einfügen
/*
SELECT | Suggeriert der Datenbank das nun etwas "entnommen" wird
`ID` | Das ist das Feld das wir auslesen wollen.
FROM | Suggeriert von welcher Tabelle entnommen wird
`Accounts` | Die Tabelle
WHERE `Name` = '%s' | Die zu entnehmende Zeile
*/
new DBResult:result = db_query(Database, query); // Den Rückgabewert also das Ergebnis in der Variable result speichern | Achtung, das ist nicht das was wir wollen - ist später aber wichtig
db_get_field(result, 0, query, 5);
/*
0 ist hier die Feld ID | Da nur das Feld ID ausgegeben werden kann ist die FeldID 0 | Der Rest ist wie gehabt.
Man kann mit dieser Funktion auch wie oben beschrieben, die Felder auslesen, dann muss man aber wissen welche ID die einzelnen Felder haben.
*/
new ID = strval(query); // Umwandeln in ein Integer
printf("ID: %d", ID); // Hier lassen wir uns das Ergebnis ausgeben
db_free_result(result); // Freigeben des Speichers, der durch das Auslesen belegt war
return 1;
}
Alles anzeigen
So nun habt ihr es fast überstanden.
Im 2. Post Folgen ein paar weitere Funktionen mit Anwendungsbeispielen.
Viel Spaß beim Lesen ![]()
Was für einen Sinn hat es für ein Spiel ein Forum zu erstellen das es noch gar nicht gibt?
bei SendClientMessage wird gespeichert, was gesendet wurde. Das gleiche bei den nachfolgenden. Und beim PlayAudiostreamForPlayer wird der Chat gecleared und die alten Nachrichten gesendet...
Ich weiß ja nicht was du dir angeguckt hast,
aber das System funktioniert nach diesem Prinzip
Nein hat man nicht,
Kye hat selbergesagt, der Spieler MUSS die Möglichkeit haben, nachzuvollziehen mit was er sich da gerade verbunden hat.
Deswegen habe ich dieses System entwickelt und ich wage auch nicht zu bezweifeln, das Kye mich deswegen aus dem englischen Forum bannen würde
Wie wäre es mit dem einfachen Text(draw) Tag,
aber es ist natürlich jedem selbst überlassen was er nutzen möchte
Nicht umbedingt, aber dies ist jedem selbst überlassen.
Nur weil es von etwas "Playermäßiges" gibt, heißt es nicht das es besser ist,
prinzipiell ist es sogar schlechter, weil der Server und der Client mehr arbeiten müssen
@ Sonic
Da fehlt der Text(draw) Tag ![]()