SA-MP Speichergrenze geknackt?

Wichtiger Hinweis: Bitte ändert nicht manuell die Schriftfarbe auf schwarz sondern belasst es bei der Standardeinstellung. Somit tragt ihr dazu bei dass euer Text auch bei Verwendung unseren dunklen Forenstils noch lesbar ist!

Tipp: Ihr wollt längere Codeausschnitte oder Logfiles bereitstellen? Benutzt unseren eigenen PasteBin-Dienst Link
  • Hallo,
    ich habe eine riesige SQL-Query mit ca. 1300 Zeichen im String geschrieben, die es mir ermöglicht mittels LEFT JOIN's aus verschiedenen MySQL-Tabellen die Userdaten zu beziehen. Das klappt auch aber danach ist Ende. SAMP ist anscheinend vollgespeichert und führt nichts mehr aus, der Server bleibt zwar an aber z.B. einfache Commands wie:

    printf("GroupID: %d - GroupRankID: %d - GroupRank: %s", GroupInfo[playerid][groupID], GroupInfo[playerid][groupRankID], GroupInfo[playerid][groupRank]);

    werden einfach abgekürzt. Danach wird ein weiterer Befehl der unten drunter steht auch nicht mehr ausgeführt. Woran kann das liegen, dass der String wegen der großen Query evtl. so definiert wird:
    new sqlbig[1536];
    Ich weiß nicht woran es liegt und würde mich über eine Antwort freuen.


    Mfg

  • Naja, ich denke mal meine Query würde hier beim posten den Rahmen sprengen. Ach egal, ich poste es einfach mal rein, aufpassen :)

    new selectUserData[512], leftJoinData[512];
    format(selectUserData, sizeof(selectUserData), "userv.playedtimeH, userv.playedtimeM, userv.kills, userv.death, rllicense.id_card, rluserv.id_card_id, rllicense.car_license, rllicense.scooter_license, rllicense.bike_license, rllicense.boat_license, rllicense.heli_license, rllicense.plane_license, rluserv.wanted_level, rluserv.handy, rluserv.handyName, groupusers.groupID, groupusers.groupRankID, groupranks.groupRankName, jail.jailActive, jail.jailTime, jail.jailReason, jail.jailerID");
    format(leftJoinData, sizeof(leftJoinData), "LEFT JOIN rl_uservalues rluserv ON (rluserv.userID = user.id) LEFT JOIN rl_licenses rllicense ON (rllicense.userID = user.id) LEFT JOIN rl_group_users groupusers ON (groupusers.userID = user.id) LEFT JOIN rl_group_ranks groupranks ON (groupranks.groupRankID = groupusers.groupRankID AND groupranks.groupID = groupusers.groupID) LEFT JOIN rl_jail jail ON (jail.userID = user.id)");
    format(sqlbig, sizeof(sqlbig),
    "SELECT user.id, user.isAnAdmin, user.banned, user.banned_reason, user.password_md5, user.email, user.last_login_ip, language.languageid, %s FROM samp_user user LEFT JOIN samp_uservalues userv ON (userv.userID = user.id) LEFT JOIN samp_languages language ON (language.userID = user.id) %s WHERE user.playername = '%s'",
    selectUserData,
    leftJoinData,
    GetPlayerName(playerid));
    mysql_query(sqlbig);
    mysql_store_result();
    if(mysql_num_rows() == 1) {
    PlayerStatus[playerid][getAccount] = 1;
    PlayerStatus[playerid][ipAdress] = GetPlayerIp(playerid);
    while(mysql_fetch_row(sqlbig)) {
    sscanf(sqlbig, "p|dddssssdddddddddddddddsdddddsd",
    PlayerInfo[playerid][userID],
    AdminInfo[playerid][isAnAdmin],
    PlayerStatus[playerid][banned],
    PlayerStatus[playerid][bannedReason],
    PlayerInfo[playerid][password_md5],
    PlayerInfo[playerid][email],
    PlayerInfo[playerid][last_login_ip],
    PlayerInfo[playerid][playtimeH],
    PlayerInfo[playerid][playtimeM],
    PlayerInfo[playerid][kills],
    PlayerInfo[playerid][deaths],
    PlayerInfo[playerid][language],
    RlInfo[playerid][ID_card],
    RlInfo[playerid][ID_card_id],
    RlInfo[playerid][Car_license],
    RlInfo[playerid][Scooter_license],
    RlInfo[playerid][MBike_license],
    RlInfo[playerid][Boat_license],
    RlInfo[playerid][Heli_license],
    RlInfo[playerid][Plane_license],
    RlInfo[playerid][Wanted_level],
    RlInfo[playerid][Handy],
    RlInfo[playerid][HandyName],
    GroupInfo[playerid][groupID],
    GroupInfo[playerid][groupRankID],
    GroupInfo[playerid][groupRank],
    JailInfo[playerid][jailed],
    JailInfo[playerid][jailTime],
    JailInfo[playerid][jailReason],
    JailInfo[playerid][jailerID]);
    }
    print("");
    print("==== userConnectData erfolgreich ! ================");
    printf("...Spieler %s wurde in der Datenbank gefunden !");
    printf("...UserID: %d - Banned: %d - E-Mail: %s - Admin: %d", PlayerInfo[playerid][userID], PlayerStatus[playerid][banned], PlayerInfo[playerid][email], AdminInfo[playerid][isAnAdmin]);
    if(PlayerStatus[playerid][banned]) printf("Banreason: %s", PlayerStatus[playerid][bannedReason]);
    if(!PlayerStatus[playerid][banned]) printf("GroupID: %d - GroupRankID: %d - GroupRank: %s", GroupInfo[playerid][groupID], GroupInfo[playerid][groupRankID], GroupInfo[playerid][groupRank]);
    print("");
    mysql_free_result();
    userEditor("adminLogin", playerid);
    return 1;
    }
    mysql_free_result();

    Die hier auszuführende Query(Ja, ich musste sie leider aufteilen^^) lautet:

    SQL
    SELECT user.id, user.isAnAdmin, user.banned, user.banned_reason, user.password_md5, user.email, user.last_login_ip, language.languageid, userv.playedtimeH, userv.playedtimeM, userv.kills, userv.death, rllicense.id_card, rluserv.id_card_id, rllicense.car_license, rllicense.scooter_license, rllicense.bike_license, rllicense.boat_license, rllicense.heli_license, rllicense.plane_license, rluserv.wanted_level, rluserv.handy, rluserv.handyName, groupusers.groupID, groupusers.groupRankID, groupranks.groupRankName, jail.jailActive, jail.jailTime, jail.jailReason, jail.jailerID FROM samp_user user LEFT JOIN samp_uservalues userv ON (userv.userID = user.id) LEFT JOIN samp_languages language ON (language.userID = user.id) LEFT JOIN rl_uservalues rluserv ON (rluserv.userID = user.id) LEFT JOIN rl_licenses rllicense ON (rllicense.userID = user.id) LEFT JOIN rl_group_users groupusers ON (groupusers.userID = user.id) LEFT JOIN rl_group_ranks groupranks ON (groupranks.groupRankID = groupusers.groupRankID AND groupranks.groupID = groupusers.groupID) LEFT JOIN rl_jail jail ON (jail.userID = user.id) WHERE user.playername = 'HandsUpFreak'


    und das hochscrollen nicht vergesssen :)

  • Naja, der DB-Server liegt auf einem anderen als der Gameserver. Daher möchte ich nicht soviele ausführen da es auch irgendwo müll ist soviele Querys hintereinander auszuführen. Der Server ist zwar ordentlich eingestellt und auch leistungsstark aber wenn da in der Stunde (nehmen wir mal den extremfall)100 Leute connecten und disconnecten dann sind das schon 14 Querys(Connect+Disconnect)*100 das sind dann 1400 Querys in der Stunde, nicht gerade gesund.

  • Ich sehe da kein Problem, bei mir klappts auch wunderbar, und da merkt man davon nix. Nen externen MySQL Server zu verwenden ist schon bisschen blöd, Antwort senden = ca. 25 MS, Query bearbeiten ca. 5 MS (je nach Query), Antwort erhalten 25ms = 55 MS pro Query.

  • do.de - Domain-Offensive - Domains für alle und zu super Preisen
  • Ja, stimmt schon, ist aber weit aus sicherer falls mal ein Root-Absturz passiert.
    Mir ging es auch eigentlich einfach nur darum, zu wissen, ob SAMP mit zuvielen großen Strings nicht klarkommt. Ich habe nämlich auch mal ein Test gemacht und 8 Strings á 256 Länge befüllt und diese anschließend in einen großen String mit 2048 Länge per format reingequetscht. Danach hat der Server das gleiche Phänomen gezeigt und nichts mehr gemacht.

  • Ein String kann laut SA-MP Wiki doch nur 128 Zeichen (512 Byte) Lang sein oder?
    Wenn es mehr als 128 Zeichen sind wird einfach abgekürzt, das heißt wenn du in einem String 200 Zeichen hast, werden nur die ersten 128 angezeigt.
    Ich weiß nicht genau was jetzt die Frage war, aber ich glaube das könnte dein Problem Lösen.



    MfG

  • Hallo


    Nein, eine SendClientMessage kann nur 128 gross sein, aber zB ein String für einen Dialog kann grösser sein, oder ein Speicherquery



    Edit 1:
    Hinweis an den TS
    Wenn Du sscanf2 benutzt, musst Du bei Strings eine Grösse angeben, zB:


    fffs[20]iifs[30]


    Edit 2:
    Benutzt man den Trenner nicht so ?
    p<|>

  • Ein string kann noch weit aus mehr unterstützen. Das Problem ist hier(hab ich beobachtet), dass nach 2048 erstmal Sense ist, zumindest hab ich so dass Gefühl.
    Bei sscanf kann man auch mittels p| trennen, da das pX(p für Trenner und X für den Delimiter) anzeigt, wo getrennt werden soll.
    So kann man aus dem String
    1|0|abc|1|2
    mit sscanf auslesen:
    sscanf(string, "ddsdd", int1, int2, string1, int3, int4);

  • Hallo


    Ja, aber das geht nur wenn Du sscanf und nicht sscanf2 benutzt, bei sscanf 2 müsste es so heissen



    sscanf(string, "dds[STRINGGRÖSSE]dd", int1, int2, string1, int3, int4);


    Nichts für ungut aber mich würde es wundern, wenn Du noch sscanf anstatt sscanf2 benutzen würdest ;)

  • hallo


    Benutz auf jeden Fall sscanf2, denn alleine sscanf hat nach Aussagen von Y_Less Speicherprobleme. Zudem bietet sscanf2 dir die Möglichkeit, jeden Parameter optional zu stellen:


    s = String muss eingegeben werden /restart [REASON]
    S = optionaler String /restart [OptionaleREASON]


    Zudem bietet sscanf2 die Möglichkeit, Enums einzulesen, sprich zu bespeichern und auch (Bin mir aber nicht sicher), die Sache mit dem Delimiter.


    http://forum.sa-mp.com/showthr…p?t=120356&highlight=zcmd