Beiträge von Kasakow

    Guten Abend,


    Einleitung:


    Mein Name lautet MrPawn ( Michael ).
    Heute biete ich euch ein Simples Tutorial über ein Anmeldung´s System mit der Version R38.
    Aktuell gibt es auch die Version R39, aber das Prinzip wird sich nicht viel verändert haben.
    Bei dem Update von R38 - 39 wurden höchstens ein paar Korigierungen vorgenommen.
    So nun wollen wir aber mal anfangen mit der Anleitung für ein Simples Anmeldungs System.
    Ob es 100% Anfängertäuglich ist stellt sich zu einem späteren Zeitpunkt heraus.


    Voraussetzungen:


    Bevor wir mit diesem System anfangen wollen, müssen wir zuerst einmal wissen was ich alles dafür brauchen.
    Die Voraussetzungen werde ich nun auflisten.


    • Das MySQL Include in der Version r38/39.
    • Das jeweilige bereitgestellte MySQL Plugin in der Version R38.
    • Einen beliebigen Windows/Linux SA-MP Server.
    • Eine MySQL Datenbank, zur Testzwecken reicht eine ganz normale Lokale XAMPP Datenbank.
    • Leichte Grundkenntnisse.


    Installation:


    Was wir zuerst machen werden, ist folgendes: Da ich ja das ganze auf einen Windows Server laufen lasse, werde ich nun die libmysql.dll in die Hauptverzeichnis vom Server ziehen.

    Das gleiche machen wir mit der mysql.dll:
    Nur bei ihr sieht das ganze anders aus:
    Wir dürfen nähmlich das Plugin nicht in das Hauptverzeichnis klatschen.
    Sondern müssen die mysql.dll in den plugins Ordner verschieben.

    Dann muss die .inc Datei in /pawno/include/ verschoben werden.

    Zuletzt muss das ganze einfach nur bei der server.cfg unter "plugins" enzutragen.

    Wie man die XAMPP Datenbank Lokal hosten kann , werd ich allerdings nicht zeigen.


    Verbindungsaufbau zu der MySQL Datenbank:


    Da R38 immer nach einer ConnectingHandle fragen wird, werden wir uns eine Variable erstellen.
    Das sollte weiter oben im Script erfolgen.
    new Handle;
    Dann müssen wir überlegen , aber welchem Zeitpunkt soll eine Verbindung hergestellt werden.
    Das ist einfach zu beantworten.
    Wenn der Server startet, soll eine Verbindung aufgebaut werden.
    Wo kann man den Start sozusagen festlegen, das jeweilige Callback lautet: OnGameModeInit.
    Aber voher um es leichter zu machen, erstellen wir uns ganz normal definierungen für die Datenbank.
    Die können wir beliebig nennen, solange sie auf einen String zuweisen, sprich: ""


    #define MYSQL_HOST "127.0.0.1"
    #define MYSQL_USER "root"
    #define MYSQL_DATA "tutorialdb"
    #define MYSQL_PASS ""


    So nun können wir beim "Serverstart Callback" die Verbindung versuchen herzustellen.
    Dazu müssen wir die Funktion mysql_connect anwenden, auf diesen Connect müssen wir gleichzeitig unsere erstellte Variable "Handle" zuweisen.
    Wie das gehen würde sehr ihr hier:
    http://wiki.sa-mp.com/wiki/MySQL/R33#mysql_connect


    public OnGameModeInit()
    {
    Handle = mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_DATA, MYSQL_PASS);
    return 1;
    }


    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


    Verbindungstest:
    public OnGameModeInit()
    {
    Handle = mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_DATA, MYSQL_PASS);
    if(mysql_errno() < 1)print("MySQL: Die Verbindung wurde erfolgreich hergestellt."); else print("MySQL: Die Verbindung zur MySQL Datenbank konnte nicht hergestellt werden | Der Server wird nun heruntergefahren."), SendRconCommand("exit");
    return 1;
    }


    So sind wie auf der sicheren Seite.


    Jetzt müssen wir dafür sorgen das ganze auch geloggt wird, deswegen Arbeiten wir mit der Funktion mysql_log.
    http://wiki.sa-mp.com/wiki/MySQL/R33#mysql_log
    Es gibt 5 Verschiedene Arten von Logs.


    Typen:

    Code
    LOG_NONE	 Logs absolutely nothing.
    LOG_ERROR	 Logs errors.
    LOG_WARNING	 Logs warnings.
    LOG_DEBUG	 Logs debug messages.
    LOG_ALL	         Logs everything.


    Da wir nur die mal die ganze LOG im Blick haben, nehmen wir Type 5.
    Das ganze wenden wir nun so an:
    public OnGameModeInit()
    {
    Handle = mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_DATA, MYSQL_PASS);
    if(mysql_errno() < 1)print("MySQL: Die Verbindung wurde erfolgreich hergestellt."),mysql_log(LOG_ALL); else print("MySQL: Die Verbindung zur MySQL Datenbank konnte nicht hergestellt werden | Der Server wird nun heruntergefahren."), SendRconCommand("exit");
    return 1;
    }


    So, Leute somit währe der Verbindungsaufbau vollbracht.


    Query:


    Jetzt werden wir mal mit Querys Arbeiten.
    Ein Query ist sozusagen eine Abfrage, die aus der Datenbank erfolgt.
    Wir werden jetzt eine Abfrage starten, ob ein Eintrag mit unserem namen in der Datenbank existiert.
    Wir gehen also zum Callback was aufgerufen sobald ein Spieler auf den Server connected.
    Dieses Callback nennt sich: OnPlayerConnect


    public OnPlayerConnect(playerid)
    {
    return 1;
    }


    So nun erstellen wir uns einen neuen String, namens "query" ( muss nicht umbedingt sein, so mache ich das halt. )


    public OnPlayerConnect(playerid)
    {
    new query[256];
    return 1;
    }


    So nun müssen wir den Query/String befüllen lassen, sogesehen auch formatieren.
    Das machen wir mit der Funktion format


    format(query, sizeof(query), "..", ..);


    So nun müssen wir auch wissen welchen befehl wie der abfrage für die Datenbank zuweisen sollen.
    Aber was auch ganz wichtig ist, MySQL Befehle werden "IMMER!" Groß geschrieben.
    Mit dem Command SELECT können wir von einer Tabele eine jeweilge Spalte durchsuchen nach werten,strings.
    Wir müssen jeweils auch mit FROM & WHERE arbeiten , damit die DB auch weiß , was & wo sie suchen soll.


    Ich mache hiermal einen beispiel code:


    QUERY:


    format(query, sizeof(query), "SELECT * FROM user WHERE username='%s'", ..);


    So zuerst einmal muss das nicht user heißen sondern kann beliebig heißen, es muss halt nur in der Datenbank erstellen werden.
    Dann müssen wir eine Variable mit dem jeweiligen Spielernamen füllen lassen. Was auch gehen würde wäre man sich gleich dafür eine Funktion erstellen würde.
    Ich zeige mal beide beispiele:


    1. Variante:
    public OnPlayerConnect(playerid)
    {
    new query[256], name[24];
    GetPlayerName(playerid, name, 24);
    format(query, sizeof(query), "SELECT * FROM user WHERE username='%s'", name);
    return 1;
    }


    2. Variante:


    public OnPlayerConnect(playerid)
    {
    new query[256];
    format(query, sizeof(query), "SELECT * FROM user WHERE username='%s'", Spielername(playerid));
    return 1;
    }


    stock Spielername(playerid)
    {
    new name[24];
    GetPlayerName(playerid, name, 24);
    return name;
    }


    Aber wenn wir das so lassen würden, dann würde es nicht ganz gut Klappen.
    Aus dem einfachen Grund, das MySQL wenn es schon ein String ist, einen escaped.
    Deswegen arbeiten wir mit der Funktion mysql_escape_string.
    http://wiki.sa-mp.com/wiki/MySQL/R33#mysql_escape_string
    Dies ist nicht wirklich schwer.
    Ich zeigs wieder mit 2 Varianten:


    1. Variante:
    mysql_escape_string(name, name);


    2. Variante:
    mysql_escape_string(Spielername(playerid), Spielername(playerid));


    public OnPlayerConnect(playerid)
    {
    new query[256];
    mysql_escape_string(Spielername(playerid), Spielername(playerid));
    format(query, sizeof(query), "SELECT * FROM user WHERE username='%s'", Spielername(playerid));
    return 1;
    }


    So nun müssen wir den Query auch absenden, dass machen wir mit der Funktion mysql_tquery
    http://wiki.sa-mp.com/wiki/MySQL/R33#mysql_tquery


    public OnPlayerConnect(playerid)
    {
    new query[256];
    mysql_escape_string(Spielername(playerid), Spielername(playerid));
    format(query, sizeof(query), "SELECT * FROM user WHERE username='%s'", Spielername(playerid));
    mysql_tquery(Handle, query, "UserCheck", "i", playerid);
    return 1;
    }


    So ich denke, Handle & Query lassen sich von selbst erklären aber nicht "UserCheck, i & playerid".
    UserCheck wird als Callback verwendet (forward & public).
    Das ist i steht für Integer.
    Auf deutsch übersetzt ganzzahlige werte.
    Und i wird dann halt mit playerid gefüllt.


    So nun erstellen wir uns das Callback UserCheck, INFO: Kann wieder beliebig genannt werden.


    forward UserCheck(playerid);
    public UserCheck(playerid)
    {
    }


    So nun müssen wir wissen, wie wir die Ergebnisse fragen, das ist Einfach. Wir müssen mit der Funktion cache_get_data 2 Variablen füllen lassen, und die einfach er 'if' frage prüfen.
    Dazu erstellen wir auch noch weit oben im Script 2 Dialoge


    #define DIALOG_REGISTER 1
    #define DIALOG_LOGIN 2


    http://wiki.sa-mp.com/wiki/MySQL/R33#cache_get_data


    forward UserCheck(playerid);
    public UserCheck(playerid)
    {
    new num_rows, num_fields;
    cache_get_data(num_rows, num_fields, Handle);
    if(num_rows == 0)
    {
    //Register..
    ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_PASSWORD, "Anmeldung", "Es wurde kein Account unter diesem namen gefunden!", "Anmelden", "Abbrechen");
    }
    else
    {
    //Login..
    ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Anmeldung", "Es wurde ein Account unter diesem namen gefunden!", "Anmelden", "Abbrechen");
    }
    }


    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


    public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
    {
    return 1;
    }


    Da fragen wir erstmal die jeweilige DialogID ab.


    public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
    {
    new query[256], key[50];
    if(dialogid == DIALOG_REGISTER)
    {
    if(!response)
    {
    return Kick(playerid);
    }
    if(!strlen(inputtext) < 4)return ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_PASSWORD, "Anmeldung", "Es wurde kein Account unter diesem namen gefunden!", "Anmelden", "Abbrechen");
    format(key, 50, "%s", inputtext);
    mysql_escape_string(Spielername(playerid), Spielername(playerid)), mysql_escape_string(key, key);
    format(query, sizeof(query), "INSERT INTO (username, passwort) VALUES ('%s',MD5('%s')", Spielername(playerid), key);
    mysql_tquery(Handle, query);
    SendClientMessage(playerid, -1, "Dein Account wurde erstellt.");
    GivePlayerMoney(playerid, 50000), SetPlayerScore(playerid, 10);
    }
    return 1;
    }


    Jetzt fragen sich bestimmt die neulinge, wieso ich MD5('..') gemacht habe.
    MD5 ist eine Verschlüsseung für string. MySQL liefert die Funktion schon mit sich.


    So jetzt kümmern wir uns die Login Funktion:


    public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
    {
    if(dialogid == DIALOG_LOGIN)
    {
    if(!response)
    {
    return Kick(playerid);
    }
    format(key, 50, "%s", inputtext);
    mysql_escape_string(Spielername(playerid), Spielername(playerid)), mysql_escape_string(key, key);
    format(query, sizeof(query), "SELECT * FROM user WHERE username='%s' AND password='%s'", Spielername(playerid), key);
    mysql_tquery(Handle, query, "OnPasswordResponse", "i", playerid);
    }
    return 1;
    }


    forward OnPasswordResponse(playerid);
    public OnPasswordResponse(playerid)
    {
    new num_fields, num_rows;
    cache_get_data(num_rows, num_fields);
    if(num_rows == 0)
    {
    //Passwort falsch..
    SendClientMessage(playerid, -1, "Das Passwort ist inkorrekt.");
    ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Anmeldung", "Es wurde ein Account unter diesem namen gefunden!", "Anmelden", "Abbrechen");
    }
    else
    {
    //Passwort richtig..
    SendClientMessage(playerid, -1, "Erfolgreich eingeloggt.");
    SpielerInfo[playerid][pEingeloggt] = true;
    LoadAccount(playerid);
    SpawnPlayer(playerid);
    }
    return 1;
    }


    Wir erstellen nun wieder weiter oben im Script 1 Enum + 1 Variable


    enum PD {
    pEingeloggt,
    pGeld,
    pLevel,
    };


    new SpielerInfo[MAX_PLAYERS][PD];


    stock LoadAccount(playerid)
    {
    SpielerInfo[playerid][pEingeloggt] = true;
    SpielerInfo[playerid][pGeld] = cache_get_field_content_int(0, "Geld", Handle), GivePlayerMoney(playerid, SpielerInfo[playerid][pGeld]);
    SpielerInfo[playerid][pLevel] = cache_get_field_content_int(0, "Level", Handle), SetPlayerScore(playerid, SpielerInfo[playerid][pLevel]);
    return 1;
    }


    So, nun kommen wir fast zum Ende. Am Ende wirkt es vielleicht ein bisschen wie c & p aber wenn die Leute dieses Tutorial hier sehen und das wirklich lernen wollen, dann werden sie schon nicht nur c&p machen.


    Ab zur SpielerSpeichern Funktion.


    Nun müssen wir überlegen, wo soll die hin? Das ist Simpel, wie alles andere hier auch:


    public OnPlayerDisconnect(playerid)
    {
    SpielerSpeichern(playerid);
    return 1;
    }


    stock SpielerSpeichern(playerid)
    {
    if(SpielerInfo[playerid][pEingeloggt] == false)return 1;
    mysql_escape_string(Spielername(playerid), Spielername(playerid));
    format(query, sizeof(query), "UPDATE user SET Geld='%i',Level='%i' WHERE username='%s'", GetPlayerMoney(playerid), GetPlayerScore(playerid), Spielername(playerid));
    mysql_tquery(Handle, query);
    return 1;
    }


    So Leute das war es eigentlich im großen & ganzen.



    DOWNLOADS
    Komplettes MySQL Pack ( R38 ) Windows: ► Direkt Download
    Komplettes MySQL Pack ( R38 ) Windows: ► File Upload (Link Down, wird erneuert)
    Komplettes MySQL Pack ( R38 ) Windows: ► Dropbox


    Mit Freundlichen Grüßen,


    MrPawn

    Zum Event System kann man Vorschläge Skripten, die die User dann zum Beispiel Voten können.



    Aus der MySQL Datenbank, wird jeweils nach der eingestellten Uhrzeit ein Vote Modus gestartet.


    Das heißt, du gibt für den Tag, "Montag" die Uhrzeit 13.00 an, dann kommt für alle Spieler die online sind, eine Nachricht mit dem Beispiel Text: "Ihr könnt euch nun ein Event aussuchen. /vote [nummer]"


    Der Befehl würde ungefähr so aussehen:


    ocmd:vote(playerid, params[])
    {
    new votenumber;
    if(sscanf(params, "i", votenumber))
    {
    SendClientMessage(playerid, -1, "Benutze: /vote [Nummer]");
    SendClientMessage(playerid, -1, "OPTIONEN: Rennen(1), Team Deathmatch(2), Suchen & Verstecken(3) ,Raktenduell(4), Flugzeugsniper(5)");
    return 1;
    }
    switch(votenumber) {
    case 1: {
    //..
    }
    case 2: {
    //..
    }
    case 3: {
    //..
    }
    case 4: {
    //..
    }
    case 5: {
    //..
    }
    }
    return 1;
    }

    meins ist so



    if(newkeys & KEY_FIRE && (!noacheat)) { if(Spawned[playerid]) { static weapon; weapon = GetPlayerWeapon(playerid); if(!PlayerWeapons[playerid][weapon] && weapon != 40 && weapon != 0) { format(string, sizeof(string), "** Anti-Cheat: %s wurde vom Server gebannt. Grund: Waffen Cheat", GetName(playerid)); SendClientMessageToAll(Rot, string); TogglePlayerControllable(playerid, false); ResetPlayerWeapons(playerid); //Loggen format(string,sizeof(string),"(%d/%d/%d) [%d:%d:%d] %s wurde vom Anti-Cheat System gebannt. Grund: Waffenhack",day,month,year,hour,minute,second,GetName(playerid)); CheatLog(string); //Bannen SaveSpieler(playerid); BanEx(playerid, "Waffen Cheat"); } } }


    Das ist vom BSRP Script Kopiert. Das hatte ich auch damals

    Genau das weiß ich ja nicht.


    Ich möchte wissen wie ich am besten abfragen kann ob er eine Waffe hat die nicht in der Variable ist.
    Und wie man diese Waffe mit der Variable füllen kann, (Es sollen mehrere IDS in die Variable rein).
    Und wie man diese ID anschließend wieder aus der Variable holen kann. (Falls die Muniition leer geht, etc)


    Ich würde gerne wissen wie man das am besten Scripten könnte.


    Mit Freundlichen Grüßen,


    Michael ak MrPawn

    Hey,


    Eigentlich ist ein AntiMoneyhack unnötig da das Geld ja eh Serverseitig läuft.Sowie S0beit damals für den Singleplayer ausgelegt war,soweit ich weiß ändert so ein Money Hack nur deine Hud also du denkst es wäre mehr ist es aber nicht.Der Server zieht sich ja alle Infos aus der Datenbank und der Hack kann diese nicht beeinflussen


    Falls du es doch willst empfehle ich dir einfach dass GivePlayerMoney in GivePlayerCash oder so umzuändern.Wenn jmd. Dann Money bekommt lässt du ihn bannen :p


    Ist es ja eigentlich nicht ;)
    Wenn er das normale GTA San Andreas Geld System benutzen würde, dann würde er die Speicherung warscheinlich mit GetPlayerMoney machen.
    Und was würde heißen man geht in ein beliebiges Programm z.B Cheat Engine, S0beit, Trollbeit etc.
    Dann würde Funktion SetPlayerMoney zum Einsatz kommen, da ja das normale System verwenden wird.
    Also kann man sich extra Funktionen erstellen, die zur Erleichterung dienen.


    Beispiel Code:


    stock SetPlayerMoney(playerid, amount) {
    SetPVarInt(playerid, "Money", 0);
    return GivePlayerMoneyEx(playerid, amount);
    }


    stock GivePlayerMoneyEx(playerid, amount) {
    SetPVarInt(playerid, "Money", GetPlayerMoneyEx(playerid) + amount );
    return GivePlayerMoney(playerid, amount);
    }


    stock GetPlayerMoneyEx(playerid) {
    return GetPVarInt(playerid, "Money");
    }


    Mit Freundlichen Grüßen,


    Michael aka MrPawn

    Achso, darauf habe ich ja garnicht geschaut.
    Natürlich ergibt playerid != 0 keinen sinn ^^
    Und bitte frag mich nicht warum ich so spät geantwortet habe.

    Guten Tag,


    Ich arbeite mal wieder am meinem Selfmade, und habe ein Anti - Cheat System angefangen.
    Bis jetzt enthalten:


    • Anti - GeldCheat


    Was ich nun mache:


    • Anti Waffencheat


    Ich würde es gerne so machen, das man alle Waffen besitzen kann sobald die in einer Player Variable enthalten sind.
    Sprich z.B


    new pWaffen[MAX_PLAYERS][13][50];


    Dann wird in einem Timer mit einer Schleife gearbeitet.


    new Waffen[13][2];
    for(new i; i < 13; i++)
    {
    GetPlayerWeaponData(playerid, Waffen[i][0], Waffen[i][1]);
    if(Waffen[i][0] != pWaffen[playerid][i][Waffen[i][0]];
    }


    Aber ich denke, das wird so nicht ganz so viel sinn machen.
    Deswegen würde ich euch mal fragen wie man sowas am besten machen könnte.


    INFO: Jeder Spieler kann jede Waffe besitzen , vorrausgesetzt, er hat sie von einer Funktion bekommen, z.B GivePlayerWeaponEx(playerid, wid, ammo)
    In der Funktion wird dann die Variable befüllt/updated


    Mit Freundlichen Grüßen,


    Michael aka MrPawn

    Wenn du nur die Spieler anzeigen lässt, die ein "[pWanteds]" haben welches nicht 0 ist, dann ja.


    Es gibt dabei einen Kleinen Fehler Jeffry.
    Und zwar ich kann jeden anderen anklicken aber keiner kann auf meinen Namen klicken.


    Aktueller Quellcode:


    for( new i; i < MAX_PLAYERS; i++)
    {
    if(i == INVALID_PLAYER_ID || uInfo[i][pEingeloggt] != 1)continue;
    if(uInfo[i][pWanteds] == 0)continue;
    format(string, sizeof(string), "Spieler: %s | %i Wanteds\n%s", Spielername(i), uInfo[i][pWanteds], string);
    ShowPlayerDialog(playerid, DIALOG_FRAKTIONS_SAPD_AKTENx, DIALOG_STYLE_LIST, "Akten", string, "Weiter", "Abbrechen");
    }


    new count;
    if(response)
    {
    for(new i = 0; i < MAX_PLAYERS; i++)
    {
    if(i == INVALID_PLAYER_ID || uInfo[i][pEingeloggt] != 1)continue;
    if(uInfo[i][pWanteds] != 0) count ++;
    if(count != listitem)continue;
    SetPVarInt(playerid, "CID", i);
    format(string, sizeof(string), "{FFFFFF}Möchtest du dir wirklich die Akte von %s krallen?", Spielername(i));
    ShowPlayerDialog(playerid, DIALOG_FRAKTIONS_SAPD_AKTEN, DIALOG_STYLE_MSGBOX, "Akte", string, "Ja", "Nein");
    }
    }


    Hoffe ihr könnt mir helfen!


    Erstmal danke, für eine erneute & schnelle Antwort.
    Dieser Quelltext ist schon verständlicher für mich.


    Aktuell habe ich es so:


    for(new i = 0; i < MAX_PLAYERS; i++)
    {
    if(i == INVALID_PLAYER_ID || uInfo[i][pEingeloggt] != 1)continue;
    if(uInfo[i][pWanteds] != 0) count ++;
    if(count != listitem)continue;
    SetPVarInt(playerid, "CID", i);
    format(string, sizeof(string), "{FFFFFF}Möchtest du dir wirklich die Akte von %s krallen?", Spielername(i));
    ShowPlayerDialog(playerid, DIALOG_FRAKTIONS_SAPD_AKTEN, DIALOG_STYLE_MSGBOX, "Akte", string, "Ja", "Nein");
    }


    Wäre das soweit richtig ?

    Ich würde dir mein Tutorial empfehlen.
    [ SCRIPTING ] [jTuT] Interaktive Dialoge


    Damit kannst du den Inhalt der Zeile des listitems abfragen, und an Hand dessen dann deine Bedingung einfach mit strcmp prüfen.


    Das ist alles schön & Gut Jeffry, aber ich möchte es so machen wie es alle machen.
    Nochmal eine genauere Erklärung: z.B /accept oamt


    Der OÄmtler sieht wer alles einen Auftrag hat, z.B auftrag[i] == true)
    Dann drückt der oämtler die pos, das heißt die id.
    Ganz einfach erklärt ;)
    Aber schon mal danke für die Empfehlung

    Guten Mittag,


    Ich möchte mal etwas fragen.
    Ich versuche ein Dialogen Listen System zu machen:


    for ( new i; i < MAX_PLAYERS; i++ )
    {
    if(i == INVALID_PLAYER_ID)continue;
    if(var[i] != bedingung)continue;
    format(string, sizeof(string), "Spieler: %s\n%s", Spielername(i), string);
    ShowPlayerDialog(playerid, id, DIALOG_STYLE_LIST, "..", string, "Wählen", "");
    }


    Wenn es zum Beispiel mir der Fall ist, das die Bedingung erfüllt wurde, dann soll ich angezeigt werden, nach dem jetzigen Code würde das auch Klappen.
    Nur ich möchte auch das man auf mich draufklicken kann, und das dann z.B meine ID für weitere funktionen in eine zwischenvariable speichert.
    Sprich, mann soll auf mich draufklicken können oder bei den anderen Usern bei denen die Bedingung erfüllt wurde.
    Mich würde mal interessieren wie sowas funktonieren würde,


    Mit Freundlichen Grüßen


    Michael aka MrPawn

    Wieso sollte man in einem Anti - Cheat Client eine Spieler Statistik vorhanden sein, dafür könnte man sich doch ein User Control Panel programmieren!

    Das ergibt gar keinen sin ;)


    new lastkillid[MAX_PLAYER_NAME];


    Du hast daraus einen string gemacht!


    format(lastkillid[playerid],MAX_PLAYER_NAME,"%s",PlayerName(playerid));


    Und dann verwendest du es als normale MAX_PLAYER Variable, sinnlos :love:

    Dann musst du auch z.B [playerid] reinschreiben!


    format(string,sizeof(string),"%s wurde zuletzt von %s gekillt.", PlayerName(giveplayerid), PlayerName(lastkillid)); //Zeile 22688


    zu:


    format(string,sizeof(string),"%s wurde zuletzt von %s gekillt.", PlayerName(giveplayerid), PlayerName(lastkillid[giveplayerid])); //Zeile 22688

    Ich möchte abfragen ob ein Eintrag in der Datenbank vorhanden ist. (z.B für ein Anmelde System)
    Wie man den Query benutzt weiß ich bereits. (Müsste so stimmen)
    Und möchte ich abfragen ob was gefunden wurde.
    Den Eintrag den ich angegeben habe.
    Ich lasse den Query so ausführen:


    format(query, sizeof(query), "SELECT * FROM acc WHERE Name='%s'", tmp_name);
    mysql_tquery(MySQL_Connect, query);


    Und möchte ich abfragen, ob der Eintrag mit dem Namen = '%s' in der Datenbank gefunden wurde.


    Ich überlege die 2 Funktionen in betracht zu ziehen:


    Funktionen:

    • cache_get_field_name
    • cache_get_field_count


    Welche Funktion muss ich verwenden, und wie setze ich sie genausten ein. (Bitte einen Codeschnipsel)


    Vielen Dank im Voraus !

    Jap, musste Pawno neustarten und mysql_ping rausnehmen, aber wie kann ich nun dafür sorgen wenn die verbindung steht, das es geprintet wird und wenn sie erfolglos war das der server beendet wird ?


    EDIT:
    Habe es hinbekommen:
    if(mysql_errno() != 0){print("Die Verbindung war erfolglos!"),SendRconCommand("exit");}else print("Die Verbindung war erfolgreich!");


    Danke :)



    Ich habe nun R38 angeschmissen, und muss ehrlich sagen nun möchte der Server nicht mehr mitmachen ;)



    In die MySQL wird nichts geprintet ;)