@MiX(eP): Mir wären keine bekannt, sorry.
Mhh, dann lässt sich wohl nichts machen ich warte einfach auf die Antwort auf mein Support-Ticket bei Nitrado.
Trotzdem danke Jeffry!
@MiX(eP): Mir wären keine bekannt, sorry.
Mhh, dann lässt sich wohl nichts machen ich warte einfach auf die Antwort auf mein Support-Ticket bei Nitrado.
Trotzdem danke Jeffry!
Welche MySQL Version verwendest du denn?
Die neuste? https://github.com/pBlueG/SA-MP-MySQL/releases
Falls ja, dann solltest du dich mit dem Support von Nitrado in Verbindung setzen, damit die dir das installieren.
http://forum.sa-mp.com/showthread.php?t=570569
Am besten du gibst denen die Fehlermeldung, meistens wissen so Anbieter schon um was es da geht, die machen das ja normalerweise nicht zum ersten mal.
Ich nutze das MySQL-Plugin R39-3
Das dauert mir viel zu lange, bis man eine Antwort von Nitrado bekommt. Gibts da noch andere Lösungen?
Hat sich da jemand aus meinem Tutorial eine Idee geholt ?
Gutes Tutorial
mfg
Da war ich wohl ein bisschen Voreilig. Ja hab ans Scripten auch an dich gedacht, weil ich wusste das du so was auch machen wolltest / oder noch machst.
Oder auch besser? Wer weiß
Kann es sein das du 2 verschiedene Mysql Versionen ladest?
Fehlt dir eventuell das Whirpool.inc?
echo Executing Server Config...
lanmode 0
rcon_password Zensiert.
passwort Zensiert.
hostname SAMP-Server
gamemode0 Gamemode 1
filterscripts
announce 0
query 1
chatlogging 0
weburl
onfoot_rate 40
incar_rate 40
weapon_rate 40
stream_distance 300.0
stream_rate 1000
maxnpc 0
logtimeformat [%H:%M:%S]
language German | Deutsch
plugins mysql_static.so sscanf.so Whirlpool.so
maxplayers 40
bind Zensiert
bindip Zensiert
port 7777
Seit wann gibt es eine Whirlpool.inc? Ich hatte bisher nur eine .dll das außerdem wird die auch Geladen. hier der Log:
SA-MP Dedicated Server
----------------------
v0.3.7-RC6-3, (C)2005-2015 SA-MP Team
[20:29:20] filterscripts = "" (string)
[20:29:20] weburl = "www.sa-mp.com" (string)
[20:29:20]
[20:29:20] Server Plugins
[20:29:20] --------------
[20:29:20] Loading plugin: mysql_static.so
[20:29:20] Failed (/usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by plugins/mysql_static.so))
[20:29:20] Loading plugin: sscanf.so
[20:29:20]
[20:29:20] ===============================
[20:29:20] sscanf plugin loaded.
[20:29:20] Version: 2.8.1
[20:29:20] (c) 2012 Alex "Y_Less" Cole
[20:29:20] ===============================
[20:29:20] Loaded.
[20:29:20] Loading plugin: Whirlpool.so
[20:29:20]
[20:29:20] ==================
[20:29:20]
[20:29:20] Whirlpool loaded
[20:29:20]
[20:29:20] ==================
[20:29:20]
[20:29:20] Loaded.
[20:29:20] Loaded 2 plugins.
[20:29:20]
[20:29:20] Filterscripts
[20:29:20] ---------------
[20:29:20] Loaded 0 filterscripts.
[20:29:20] Script[gamemodes/M_Gamemode.amx]: Run time error 19: "File or function is not found"
[20:29:20] Number of vehicle models: 0
Hilfe wäre ganz Nützlich, bin am Verzweifeln.
Jeffry: | Jeffry
Nitrado macht mir das Leben mal wieder richtig Schwer. Ich hab die mysql_static.so genutzt, und nun kommt Folgendes:
Failed (/usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by plugins/mysql_static.so))
Bitte um Hilfe.
Teste dein Tutorial bitte zur Sicherheit. Ohne es zu testen habe ich schon zwei Fehler gefunden.
1.)
Zeile 18 in OnAccountCheck macht keinen Sinn:
(!strlen(IP[playerid]) || strcmp(IP[playerid], NewIP, true));
2.)
Das Query in SpielerSpeichern ist viel zu kurz. Schon ohne die ausgefüllten Platzhalter hat es 113 Zeichen, sprich die restlichen Zeichen werden abgeschnitten, somit kommt immer ein Syntax Error.
Ich habs getestet, bisher hatte ich keine Probleme. Mhh
Guten Abend.
Mein Name lautet MiX(eP).
Ich zeig euch wie man mit MySQL R39-3 ein Register/Login System baut!
Nun, fangen wir mal damit an.
Was benötigen wir? :
Ihr fügt alles in dem Script ordner Rein (Plugins, Includes.) und fügt dann auch die Namen der Plugins in die Server.cfg ein.
Der Scripting-Part:
Als erstes erstellen wir uns ein Static, das sollte so aussehen:
static
Handle,
Name[MAX_PLAYERS][24],
IP[MAX_PLAYERS][16]
;
Dann müssen wir ja noch unsere Daten angeben. Das machen wir so:
#define M_HOST "Host"
#define M_USER "Benutzer"
#define M_DATA "Datenbank"
#define M_PASS "Passwort"
Wie kann man nun sein Script mit der Datenbank verbinden? Dazu nutzen wir mysql_connect:
http://wiki.sa-mp.com/wiki/MySQL/R33#mysql_connect
Handle = mysql_connect(M_HOST, M_USER, M_DATA, M_PASS);
So aber am besten sollte man sich 2 Sachen vergewissern, 1. Das die Verbindung steht, 2. Das der Verlauf geloggt wird.
Um zu wissen, das die Verbindung steht müssen wir mit der Funktion mysql_errno Arbeiten.
http://wiki.sa-mp.com/wiki/MySQL/R33#mysql_errno
Beispiel:
if(mysql_errno(Handle) != 0)
{
print("[M_CONNECTION] >> Die Verbindung zur Datenbank ist Fehlgeschlagen! << [M_CONNECTION]");
}
else
{
printf("[M_CONNECTION] >> Die Verbindung zur Datenbank %s wurde Erfolgreich Hergestellt! << [M_CONNECTION]",M_DATA);
}
Jetzt gucken wir mal, wie wir die Datei "mysql_log" erstellen, dazu nutzen wir mysql_log :
http://wiki.sa-mp.com/wiki/MySQL/R33#mysql_log
mysql_log(LOG_ERROR | LOG_WARNING | LOG_DEBUG);
OnGamemodeInit sollte nun so aussehen:
public OnGameModeInit()
{
//===[ M_Connection ]===//
mysql_log(LOG_ERROR | LOG_WARNING | LOG_DEBUG);
Handle = mysql_connect(M_HOST, M_USER, M_DATA, M_PASS);
if(mysql_errno(Handle) != 0)
{
print("[M_CONNECTION] >> Die Verbindung zur Datenbank ist Fehlgeschlagen! << [M_CONNECTION]");
}
else
{
printf("[M_CONNECTION] >> Die Verbindung zur Datenbank %s wurde Erfolgreich Hergestellt! << [M_CONNECTION]",M_DATA);
}
return 1;
}
So nun gehen wir zu OnPlayerConnect, das haben wir nun auch, nun kommt der Richtige Scripting-Teil:
als erstes machen wir eine Schleife die, die Spieler durchgeht. Das sieht dann so aus:
for(new i; SpielerDaten:i < SpielerDaten; i++)
{
SpielerInfo[playerid][SpielerDaten:i] = 0;
}
Gut. nun setzen wir den Spieler auf Unregistriert, das machen wir so:
IstRegistriert[playerid] = 0;
Jetzt erstellen wir einen Query, der Abfragt ob ein Eintrag
in der Datenbank existiert, vorher Fragen wir aber noch den Namen und die IP des Spielers ab. Das geht so:
GetPlayerName(playerid, Name[playerid], 24);
GetPlayerIp(playerid, IP[playerid], 16);
Nun zu den Querys, erstellt eine Variable die so aussieht:
new Query[128];
nun Formatieren wir etwas das sieht dann so aus ( Beispiel! wird noch befüllt
format(query, sizeof(query), "..", ..);
nun der Format, wie er aussehen Sollte:
mysql_format(Handle, Query, sizeof(Query), "SELECT * FROM `Spieler` WHERE `Spielername` = '%e' LIMIT 1", Name[playerid]);
mysql_tquery(Handle, Query, "OnAccountCheck", "i", playerid);
Nun das ist fertig, jetzt gehen wir zu OnPlayerDisconnect und schreiben folgendes:
if(IstRegistriert[playerid] != 0)
{
SpielerSpeichern(playerid);
}
Nun erstellen wir unser Public "OnAccountCheck", dazu schreiben wir oben erst noch:
forward OnAccountCheck(playerid);
forward OnAccountLoad(playerid);
forward OnAccountRegister(playerid);
und:
#define D_REGISTER 1
#define D_LOGIN 2
Jetzt legen wir mit OnAccountCheck los. Wir arbeiten mit cache_get_data, das soll nun so aussehen:
http://wiki.sa-mp.com/wiki/MySQL/R33#cache_get_data
public OnAccountCheck(playerid)
{
new Rows, Fields;
cache_get_data(Rows, Fields, Handle);
if(Rows)
{
Jetzt arbeiten wir weiter mit cache_get_field_content:
http://wiki.sa-mp.com/wiki/MySQL/R33#cache_get_field_content
new oldIP[16];
cache_get_field_content(0, "IP", oldIP, Handle, 16);
GetPlayerIp(playerid, oldIP, 16);
IstRegistriert[playerid] = 1;
if(strlen(IP[playerid]) != 0 && !strcmp(IP[playerid], oldIP, true))
{
OnAccountLoad(playerid);
}
else
{
cache_get_field_content(0, "Passwort", SpielerInfo[playerid][Passwort], Handle, 129);
SpielerInfo[playerid][ID] = cache_get_field_content_int(0, "ID");
printf("%s", SpielerInfo[playerid][Passwort]);
ShowPlayerDialog(playerid, D_LOGIN, DIALOG_STYLE_INPUT, "Login", "Dein Account wurde gefunden. Bitte gib nun dein Passwort ein:","Einloggen","Abbrechen");
}
}
else
{
ShowPlayerDialog(playerid, D_REGISTER, DIALOG_STYLE_INPUT, "Registrieren","Dein Account wurde nicht gefunden! Bitte gib nun dein gewünschtes Passwort ein:","Registrieren","Abbrechen");
}
return 1;
}
Nun sollte unser Public so aussehen:
public OnAccountCheck(playerid)
{
new Rows, Fields;
cache_get_data(Rows, Fields, Handle);
if(Rows)
{
new oldIP[16];
cache_get_field_content(0, "IP", oldIP, Handle, 16);
GetPlayerIp(playerid, oldIP, 16);
IstRegistriert[playerid] = 1;
if(strlen(IP[playerid]) != 0 && !strcmp(IP[playerid], oldIP, true))
{
OnAccountLoad(playerid);
}
else
{
(!strlen(IP[playerid]) || strcmp(IP[playerid], NewIP, true));
cache_get_field_content(0, "Passwort", SpielerInfo[playerid][Passwort], Handle, 129);
SpielerInfo[playerid][ID] = cache_get_field_content_int(0, "ID");
printf("%s", SpielerInfo[playerid][Passwort]);
ShowPlayerDialog(playerid, D_LOGIN, DIALOG_STYLE_INPUT, "Login", "Dein Account wurde gefunden. Bitte gib nun dein Passwort ein:","Einloggen","Abbrechen");
}
}
else
{
ShowPlayerDialog(playerid, D_REGISTER, DIALOG_STYLE_INPUT, "Registrieren","Dein Account wurde nicht gefunden! Bitte gib nun dein gewünschtes Passwort ein:","Registrieren","Abbrechen");
}
return 1;
}
So nun müssen wir zum dem Callback was für die Antwort, es eines Buttons von einem Dialog ist. Eine sogenannte Response.
Das Callback nennt sich OnDialogResponse, Dazu fragen wir die jeweilige Dialog-ID ab, das erledigen wir so:
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
switch(dialogid)
{
case D_LOGIN:
{
if(!response) Kick(playerid);
new H_Pass[129];
new Query[100];
WP_Hash(H_Pass, 129, inputtext);
if(strlen(H_Pass) && !strcmp(H_Pass, SpielerInfo[playerid][Passwort]))
{
mysql_format(Handle, Query, sizeof(Query), "SELECT * FROM `Spieler` WHERE `Spielername` = '%e' LIMIT 1", Name[playerid]);
mysql_tquery(Handle, Query, "OnAccountLoad", "i", playerid);
}
else
{
ShowPlayerDialog(playerid, D_LOGIN, DIALOG_STYLE_INPUT, "Login", "Dein Account wurde gefunden. Bitte gib nun dein Passwort ein\nFalsches Passwort!", "Einloggen", "Abbrechen");
}
}
Nun fangen wir weiter an mit dem Dialog: D_REGISTER:
case D_REGISTER:
{
if(!response) return Kick(playerid);
if(strlen(inputtext) < 6) return ShowPlayerDialog(playerid, D_REGISTER, DIALOG_STYLE_INPUT, "Register", "Dein Account wurde nicht gefunden! Bitte gib nun dein gewünschtes Passwort ein.\nDein Passwort muss länger als 6 Zeichen sein!", "Registrieren", "Abbrechen");
new Query[300];
WP_Hash(SpielerInfo[playerid][Passwort], 129, inputtext);
mysql_format(Handle, Query, sizeof(Query), "INSERT INTO `Spieler` (`Spielername`, `Passwort`, `IP`, `Admin`, `VIP`,`Morde`,`Tode`,`Level`, `Geld`) VALUES ('%e', '%s', '%s', 0, 0, 0, 0, 0, 10000)", Name[playerid], SpielerInfo[playerid][Passwort], IP[playerid]);
mysql_tquery(Handle, Query, "OnAccountRegister", "i", playerid);
}
}
return 1;
}
Nun sollte auch dieses Public so aussehen:
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
switch(dialogid)
{
case D_LOGIN:
{
if(!response) Kick(playerid);
new H_Pass[129];
new Query[100];
WP_Hash(H_Pass, 129, inputtext);
if(!strcmp(H_Pass, SpielerInfo[playerid][Passwort]))
{
mysql_format(Handle, Query, sizeof(Query), "SELECT * FROM `Spieler` WHERE `Spielername` = '%e' LIMIT 1", Name[playerid]);
mysql_tquery(Handle, Query, "OnAccountLoad", "i", playerid);
}
else
{
ShowPlayerDialog(playerid, D_LOGIN, DIALOG_STYLE_INPUT, "Login", "Dein Account wurde gefunden. Bitte gib nun dein Passwort ein\nFalsches Passwort!", "Einloggen", "Abbrechen");
}
}
case D_REGISTER:
{
if(!response) return Kick(playerid);
if(strlen(inputtext) < 6) return ShowPlayerDialog(playerid, D_REGISTER, DIALOG_STYLE_INPUT, "Register", "Dein Account wurde nicht gefunden! Bitte gib nun dein gewünschtes Passwort ein.\nDein Passwort muss länger als 6 Zeichen sein!", "Registrieren", "Abbrechen");
new Query[300];
WP_Hash(SpielerInfo[playerid][Passwort], 129, inputtext);
mysql_format(Handle, Query, sizeof(Query), "INSERT INTO `Spieler` (`Spielername`, `Passwort`, `IP`, `Admin`, `VIP`,`Morde`,`Tode`,`Level`, `Geld`) VALUES ('%e', '%s', '%s', 0, 0, 0, 0, 0, 50000)", Name[playerid], SpielerInfo[playerid][Passwort], IP[playerid]);
mysql_tquery(Handle, Query, "OnAccountRegister", "i", playerid);
}
}
return 1;
}
So, nun braucht ihr noch ein Native, und zwar dieses:
native WP_Hash(buffer[], len, const str[]);
Nun brauchen wir noch das Public "OnAccountLoad" und "OnAccountRegister".
Die erstellen wir so:
OnAccountLoad:
public OnAccountLoad(playerid)
{
new Score;
SpielerInfo[playerid][Admin] = cache_get_field_content_int(0, "Admin");
SpielerInfo[playerid][VIP] = cache_get_field_content_int(0, "VIP");
SpielerInfo[playerid][Geld] = cache_get_field_content_int(0, "Geld");
SpielerInfo[playerid][Morde] = cache_get_field_content_int(0,"Morde");
SpielerInfo[playerid][Tode] = cache_get_field_content_int(0, "Tode");
Score = cache_get_field_content_int(0, "Level");
SetPlayerScore(playerid, Score);
GivePlayerMoney(playerid, SpielerInfo[playerid][Geld]);
SendClientMessage(playerid, -1, "Du hast dich Erfolgreich Eingeloggt!");
return 1;
}
OnAccountRegister:
public OnAccountRegister(playerid)
{
SpielerInfo[playerid][ID] = cache_insert_id();
printf("Neuer Account Registriert | ID: %d", SpielerInfo[playerid][ID]);
SpielerInfo[playerid][Geld] = 10000;
GivePlayerMoney(playerid, 10000);
IstRegistriert[playerid] = 1;
return 1;
}
Wie können wir nun den Spieler Speichern? Wir machen das per Stock! Hier ein Beispiel das funktionsfähig ist. :
stock SpielerSpeichern(playerid)
{
new Query[256];
mysql_format(Handle, Query, sizeof(Query), "UPDATE `Spieler` SET `IP`='%s', `Admin`=%d, `VIP`=%d, `Morde`=%d, `Tode`=%d, `Level`=%d, `Geld`=%d WHERE `ID`=%d",\
IP[playerid], SpielerInfo[playerid][Admin], SpielerInfo[playerid][VIP], SpielerInfo[playerid][Morde], SpielerInfo[playerid][Tode], GetPlayerScore(playerid), SpielerInfo[playerid][Geld], SpielerInfo[playerid][ID]);
mysql_tquery(Handle, Query, "", "");
}
Jetzt fehlen uns noch Folgende Sachen:
new IstRegistriert[MAX_PLAYERS];
enum SpielerDaten
{
ID,
Passwort[129],
Admin,
VIP,
Morde,
Tode,
Level,
Geld
}
new SpielerInfo[MAX_PLAYERS][SpielerDaten];
So das war es auch schon! Hoffe es hat euch gefallen
Hier ist die Datenbank fürs ganze!
Datenbank: http://www.file-upload.net/dow…10580092/Spieler.sql.html
Hinweis! : Durch kopieren lernt ihr kein Scripten, deswegen lest es euch durch! Und versucht es mal. Scripten kann Jeder wenn er es nur Möchte!
Jetzt kann ich das Endlich machen, was ich schon immer tuhen wollte.
Ich hab auch ein Numpad woaaaah.
PS: Coloreeee von LyD?
error 021: symbol already defined: "GivePlayerMoney"
Bedeutet:
error 021: Symbol bereits definiert: "GivePlayerMoney"
Hast du die Variable irgendwo definiert? such mal nach "GivePlayerMoney" und guck ob irgendwo ein #define davorsteht.
GivePlayerMoney hat nur 2 Reiter, das sind einmal "playerid"' und "money". ich weiß ja nicht was das soll:
GivePlayerMoney(playerid,killerid, -100,100);
Probiers mal so:
GivePlayerMoney(playerid,100);
Oder was willst du da probieren?
Wenn du es mit Stock hast, so siehts bei mir aus:
stock SpielerLaden(playerid)
{
new Spieler[64],Name[MAX_PLAYER_NAME];
GetPlayerName(playerid,Name,sizeof(Name));
format(Spieler,sizeof(Spieler),"/Spieler/%s.ini",Name);
if(dini_Exists(Spieler))
{
GivePlayerMoney(playerid,dini_Int(Spieler,"Geld"));
SetPlayerScore(playerid,dini_Int(Spieler,"Score"));
SpawnPlayer(playerid);
}
return 1;
}
Ich hab mit Bluetooth-Headset nur Schlechte Erfahrungen gemacht.
Eins zu Weihnachten gewünscht und nach dem 1 Tag von Weihnachten war das Headset defekt durch irgendeinen Kommunikations-Fehler, zwischen Stick und Headset.
Klappte auch ganz gut, aber nach dem 1x Tag wars dann vorbei.
Wow. einfach nur WOW! Ich find die map sehr gelungen.
10/10
Castle oder Monk?
Witzig und naja bissel Action ist dabei^^
Ich weiß nicht ob du sowas magst aber: Ich hab hier einen Indischen Film der mit Armee (Keine Dokumentation! ) zu tuhen hat. Für mich ist der Film einfach Prima.
( http://de.wikipedia.org/wiki/Ich_bin_immer_für_Dich_da! )
Firewall mal vielleicht Ausschalten?
Ich hab hier die ganzen .TXD - .DFF Dateien von allen Fahrzeugen - Download: http://www.file-upload.net/dow…562759/Fahrzeuge.rar.html
Die ersetzt du dann hier mit Spark: http://www.gtagarage.com/mods/show.php?id=1503
Hinweis das es kein Virus ist: https://www.virustotal.com/de/…a30b/analysis/1429877132/
(Aus Sicherheitsgründen)
Viel Spaß!
Hast du das Script? Wenn ja müsste die doch dabei sein. oder im Script per Query ausgeführt werden, oder in einem Kommentar sein.
Oder die Datenbank wurde nie Veröffentlicht....
Ich benutze:
http://www.chip.de/downloads/CamStudio_19900258.html
mit dem Codec: http://lags.leetcode.net/codec.html
PS: Ist eine Freeware *o*
Viel Spaß!