Wieso wird der Code nicht ausgeführt ?
printe eventuell mal getAdmin() und schau, was für ein Wert daraus kommt
Wieso wird der Code nicht ausgeführt ?
printe eventuell mal getAdmin() und schau, was für ein Wert daraus kommt
Kann es evt. sein das mysql_static da Probleme macht ?
Unwahrscheinlich.
Wenn dann liegt es generell an MySQL, evtl mal den MySQL Debug aktivieren und schauen, was da so alles drinnen steht.
Aber wie gesagt, versuch es mal lokal laufen zu lassen oder auf einem anderen Host
Evt. zu früh gefreut.. Jetzt steht nichts mehr im Log, der Server macht jedoch trotzdem Probleme und Kickt mich wegen dem "Nickname" und die Bots leften alle..
Hier der Log:
Ja, so runtime Fehler haben nichts mit dem Restart an sich zu tun.
Wenn crashdetect nichts ausgibt, hast du eventuell irgendwo im Skript SendRconCommand("exit") oder SendRconCommand("gmx") stehen?
Eventuell wird das ja in einem Timer aufgerufen.
Andernfalls mal eventuell auf nem anderen Server (evtl lokal) oder so, den Server mal laufen lassen und schauen, ob dieser dann restartet.
Dann weißt du, ob der Fehler am Server oder am Skript liegt
Wie sieht denn deine Ordnerstruktur aus bei Pawno/Includes?
Bist du sicher, dass du das richtige Pawno öffnest und auch die Include abgespeichert hast?
Schreib es btw mal so:
#include <modules/login/main>
Dann solltest du unter Pawno/includes/modules/login/main.inc haben.
Was nun ?
Schreib es mal so:
Dann frage ich mich allerdings, wann genau man static benutzt. Aus dem Grund, dass es als Kernelement eher direkt ins Gamemode soll? Kannst du mir das bitte noch genauer erläutern?
Habe ich doch genau erklärt in meinen 3 Punkten.
Es ist quasi wie in der OOP als private zu verstehen.
Es ist nur im Include veränderbar und der Name hat keinen Einfluss auf andere Systeme.
Es ist quasi komplett isoliert und wenn etwas nicht funktioniert mit dem System, muss es an dem Include liegen.
Die Variante finde ich tatsächlich besser, aus deinen genannten Gründen. Werde ich dann so machen. Allerdings habe ich dazu noch eine Frage. Hat es einen speziellen Grund, dass du stock statt public im Include verwendest?
Dazu schau dir das hier mal an: Der Mythos "stock"
Also im Endeffekt ist sowohl "public", als auch "stock" egal, man hat eine Funktion.
Und in diesem Fall muss diese nicht public sein, da sie weder von einem Timer, noch "CallRemoteFunction" etc aufgerufen werden müsste.
wie genau hooked man nun die Callbacks von den Includes zum Gamemode? Wenn man nämlich nur die Includes zum Gamemode inkludiert, werden die Callbacks des Includes ja nicht aufgerufen(?).
Wie man richtig Hookt, wird hier gut erklärt:
Includes richtig erstellen | Hooking ganz einfach
Falls dir das zu umständlich ist, könntest du auch einfach eine Funktion in das Callback vom Gamemode packen und diese dann im Include aufrufen.
//Also z.B. im Gamemode
public OnPlayerConnect(playerid)
{
Spieler_OnPlayerConnect(playerid);
return 1;
}
//Und dann im Spieler Include
stock Spieler_OnPlayerConnect(playerid)
{
}
Alles anzeigen
Dann hätteste du auch immer eine chronologische Reihenfolge und eine direkte Übersicht über alle Includes im Gamemode.
Wie allerdings definiert man dann lokale Variablen, die nur eine Rolle im Include selbst spielen, einfach mit new?
Die Spieler Variable, ist ja quasi der Kern eines jeden Gamemodes.
Diese kannst du bei new belassen.
Und solltest du meiner Ansicht nach im Gamemode lassen und Include die darauf zugreifen, unter der Deklaration inkludieren, dann kannst du das dort überall verwenden.
Aber kannst natürlich auch das in eine Include packen.
Da hat jeder so seine Präferenzen.
So sieht mein Code aus in der Dashboard.php
Du setzt aber in der index Datei keine session, sondern einen cookie.
Deshalb springt er von da..wieder nach da usw.
Prüfe ob da der Cookie existiert oder setze noch eine Session...
Und was steht in der dashboard.php was ist denn welches Skript..
Bitte immer die Namen angeben, das ist sehr wichtig
warum ich soviel weitergeleitet werde
Zeig uns doch mal den Code, ohne den, können wir dir schlecht helfen.
Gibts eine einfache Möglichkeit wenn ich bspw pGeld = 20000 habe, dass ich es bei einer Übersicht für den Spieler mit einen Punkt anzeigen lassen (also ab den 1000er) also: 20.000 ohne das Geld System ändern zu müssen?
Hatte dafür mal eine Funktion geschrieben gehabt:
stock sMoney(geld)
{
new str[24],i;
valstr(str,geld),i=(geld > 0) ? strlen(str)-3 : strlen(str)-4;
for(; i>0; i-=3) strins(str,".",(geld > 0) ? i : i+1,24);
return str;
}
Nutzung einfach so:
format(string,sizeof(string),"Habe soviel Geld: %s$",sMoney(pGeld)); //Output: Habe soviel Geld: 20.000$
Hallo Brotfische,
oft sehe ich hier ein großes Missverständnis von Includes und Code-Trennungen.
Deshalb möchte ich hier noch einmal versuchen ein wenig mit diesen Fehlern aufzuräumen.
Was ist eigentlich ein Include?
Viele wissen dies nicht. Viele denken, das ist etwas ganz anderes als eine .pwn Datei, schließlich steht da ja .inc.
Allerdings ist das ein großes Missverständnis, denn im Endeffekt ist es identisch.
Die Endung soll nur symbolisieren, dass es sich um ein Include handelt und kein eigenständiges Skript.
Was ist der Unterschied?
Ein eigenständiges Skript wird kompiliert. Ein Include wird nicht kompiliert.
Wieso muss ein Include nicht kompiliert werden?
Ganz einfach, stellen wir uns mal folgende Situation vor:
//Im Gamemode
#include <a_samp>
#include <meinInclude>
main() {
print("%d",GetMyFunction());
}
//In der Datei - meinInclude.inc
stock GetMyFunction()
{
return 1;
}
Alles anzeigen
Kompilieren wir jetzt den Gamemode, sieht das nach dem pre-compile Prozess so aus:
//Hier würde alles stehen, was in a_samp steht.
stock GetMyFunction()
{
return 1;
}
main() {
print("%d",GetMyFunction());
}
Wir sehen also, es wird "einfach nur" (soo leicht ist das auch nicht, aber dazu später mehr) in die Datei kopiert.
Deshalb müssen wir Includes nicht kompilieren, da sie vom Gamemode kompiliert werden.
Und deshalb müssen wir in den Includes z.B. auch nicht mehr #include <a_samp> schreiben, da ja das schon im Gamemode steht und das somit auch für das Include gilt.
Was bringt das jetzt?
Das wurde ja schon oft gesagt, man kann nun viele Sachen auslagern.
Okay, aber was genau bedeutet das?
Logikfehler
Viele machen hier einen großen Logikfehler.
Da viele sich die Struktur ihres Gamemodes bei einem Godfather abschauen, verstehen sie oft nicht, wieso diese so schlecht ist.
Auf den Ersten Blick sieht das ja auch gut aus, ich meine, alle defines Oben, alle Variablen oben, alle Commands und publics in der Mitte und ganz unten alle "stock - Funktionen".
Ja cool, jetzt wo wir also Includes nutzen können, packen wir alle Variablen in ein Include, alle Commands, alle publics und alle "stock - Funktionen" und voila. Skript aufgeräumt xD
(No Joke, das machen sehr viele und sind fest von dieser Struktur überzeugt).
Wieso ist das aber schlecht?
Genau das versuche ich jetzt hiermit zu vermitteln, das ist NICHT der Sinn oder Vorteil eines Includes.
Da könnte man sich diesen ganzen Prozess gleich schenken.
Denn denken wir das weiter und es entsteht jetzt ein Fehler beim Haussystem.
Wie finden wir in so einem System den Fehler?
Ja Herzlichen Glückwunsch, jetzt sogar noch schlechter, da wir in 4 Dateien Suchen, alle Variablen dafür finden müssen, alle Funktionen, alle Befehle und überall in jedem public steht mal ein fitzelchen Code von dem System xD
Kein Wunder also, dass soviele Skripte verbuggt sind, wie will man da auch irgendwas finden.
Deshalb posten hier auch so viele Menschen 500 Zeilen Code und sagen, ja wo ist denn da der Fehler, bla bla funktioniert nicht.
Was wäre ein besserer Ansatz?
So, hier kommt jetzt das Wichtige.
Man packt ein einzelnes System in ein Include.
Und damit meine ich nicht nur den Hauptteil des Systems, sondern ALLES.
Und um noch einen drauf zu setzen, macht sowas:
//Include
static alleMeineVariablen;
static stock FunktionNurHier() { }
stock SetVar(x)
{
alleMeineVariablen = x;
}
CMD:fürDasInclude(playerid) {
}
Alles anzeigen
Hier sehen wir sehr viel static.
Das hat mehrere Gründe:
Denn wenn man dann einen Fehler hat, weiß man genau, wo man suchen muss.
Zusammenfassung
Weg von der Trennung von Bezeichnungen, wie new, public, stock...
Diese Trennung bringt rein gar nichts, man muss die LOGIK in einem Gamemode trennen.
Dafür eigenen sich Includes ideal.
Es sind im Endeffekt auch nur .pwn Dateien, die ihr mit Pawno schreiben könnt.
Und kompiliert, wird nur das Gamemode.
Zusätzliche Informationen:
Schneller & strukturierter skripten
Es ist auch nicht notwendig, dass ihr ein Selfmade anfangt und das dann konsequent macht (obwohl das ser sinnig wäre).
Ihr könnt auch anfangen neue Systeme, die ihr in ein GF implementiert, versucht so umzusetzen.
In diesem Sinne, ich hoffe ich sehe bald mehr Leute die das nutzen und schönere Fragen in der Scripting Base.
Mit freundlichen Grüßen
Euer Kalle
Ich hoffe mir kann jemand sagen wo das Problem ist, danke
Du erwartest jetzt, dass wir 525 Zeilen schlechten Code durcharbeiten, um dein Problem zu finden.
Wir wissen nicht, was für Werte die einzelnen Variablen haben, inwiefern OnPlayerDeath da eine entscheidende Rolle spielt etc pp.
Du solltest dir noch mal die Basics anschauen, wie du selbst print-Debugs machen kannst um eigenständig Fehler zu finden und eventuell crashdetect nutzen.
Zumal solltest du dir Tutorials anschauen, wie man Modular Skriptet bzw genrell mal schauen, wie man das in anderen Sprachen macht.
Den Code straight runter zu schreiben...sieht 1. Scheiße aus, 2. ist ineffizient und 3. Man findet nix mehr, genau deshalb stehst du jetzt vor deinem Problem.
Da sein?
Ja da hast du vollkommen recht, gar nicht auf den Code geachtet haha xD
Sinnvoller wäre eh sowas:
Wenn sie mit dem Thema zu tuen haben, einfach drunter.
Falls es sich um neue Themen handelt, eröffne einen neuen Thread.
Bitte nicht privat mit Problemen kommen, das ist nicht der Sinn eines Forums
Das unten schreib mal so:
stock const Float:Saveboxs[][3] = {
{-1834.7000000,327.5000000,16.7000000},
{-2932.1001000,453.8999900,3.6000000},
{-2942.3999000,1110.8000000,5.3000000},
{-1971.9000000,2601.7000000,48.8000000},
{-813.5999800,2345.8000000,119.8000000},
{-364.5000000,1593.4000000,76.5000000},
{-1356.4000000,2141.2000000,41.4000000},
{-792.0999800,2761.5000000,50.4000000},
{1564.4000000,2780.8999000,10.4000000},
{2627.0000000,2850.8999000,10.4000000},
{2613.2000000,718.5999800,10.4000000},
{2723.6001000,-1828.2000000,11.4000000},
{2471.6001000,-2697.7000000,2.6000000},
{1450.0000000,-2271.8999000,13.1000000},
{1120.4000000,-1886.5000000,36.3000000},
{707.7999900,-1472.7000000,5.0000000},
{1100.3000000,-665.4000200,109.7000000},
{1544.5000000,-1374.7000000,329.6000100},
{2112.2000000,-1500.5000000,10.0000000},
{2836.2000000,-1463.3000000,40.3000000},
{2840.1001000,-2395.8000000,20.0000000},
{2791.8999000,-2489.6001000,14.6000000},
{-1450.9000000,-217.8999900,13.7000000},
{-2508.0000000,-675.2000100,138.8999900},
{-2685.2000000,1428.9000000,6.6000000},
{-1688.6000000,1219.1000000,20.2000000},
{-1898.1000000,-127.0000000,22.8000000},
{-2229.3000000,138.8999900,34.9000000},
{-2053.7000000,309.7999900,41.5000000},
{-1724.2000000,543.7000100,33.5000000},
{-1797.7000000,372.5000000,0.1000000},
{1122.4000000,1463.7000000,5.4000000},
{1333.8000000,1250.2000000,10.4000000},
{1773.6000000,623.7000100,10.4000000},
{2439.3999000,-152.3999900,31.4000000},
{2114.2000000,-354.2999900,58.3000000},
{2243.6001000,1132.4000000,10.4000000},
{1990.1000000,1804.1000000,11.5000000},
{2561.5000000,2301.3999000,10.6000000},
{2119.7000000,1497.0000000,10.4000000}
};
ocmd:sb(playerid,params[])
{
ShowPlayerDialog(playerid,SBLISTE,DIALOG_STYLE_LIST,"Savebox - Liste","Box1,Box2,Box3,Box4,Box5,Box6,Box7,Box8,Box9,Box10,Box11,Box12,Box13,Box14,Box15,Box16,Box17,Box18,Box19,Box20,Box21,Box22,Box23,Box24,Box25,Box26,Box27,Box28,Box29,Box30,Box31,Box32,Box33,Box34,Box35,Box36,Box37,Box38,Box39,Box40","Wählen","");
return 1;
}
if(dialogid == SBLISTE)
{
if(!response) return 1;
GameTextForPlayer(playerid,"~w~ROUTE WIRD ~g~KALKULIERT",2000,4);
SetPlayerCheckpoint(playerid,Saveboxs[listitem][0],Saveboxs[listitem][1],Saveboxs[listitem][2], 5);
}
Alles anzeigen
Und das andere schreib so:
stock const Float:buddeln[][3] = {
{-152.4400,1846.9717,29.2687},//1
{-156.7346,1836.0719,35.8069},//2
{-159.3667,1819.4857,41.8780},//3
{-167.8414,1811.2115,47.8237},//4
{-170.0450,1801.4122,52.2505},//5
{-161.8423,1793.4242,53.3616},//6
{-158.1084,1784.1903,54.7704},//7
{-155.6175,1774.2726,55.9601},//8
{-161.5969,1759.1898,54.8455},//9
{-169.1723,1744.1102,54.3982},//10
{-179.5686,1728.7390,56.0567},//11
{-194.2571,1725.0474,57.2687},//12
{-211.9686,1723.6018,59.9577},//13
{-232.1001,1724.2982,65.5360},//14
{-249.9986,1729.4911,70.9397},//15
{-256.7750,1744.8335,79.7419},//16
{-263.5448,1757.6102,85.9440},//17
{-248.7828,1757.2014,91.1319},//18
{-236.3986,1762.3973,97.1517},//19
{-241.1614,1779.8954,98.7132},//20
{-158.1247,1657.6960,15.5781},//21
{-159.1710,1646.9923,17.1366},//22
{-161.2974,1631.9705,13.9626},//23
{-167.4120,1617.1793,16.0704},//24
{-179.3784,1609.5249,16.3702},//25
{-196.5753,1614.7747,18.1386},//26
{-208.7043,1622.6949,20.1674},//27
{-221.8707,1630.6270,23.0112},//28
{-224.7464,1643.3513,25.0204},//29
{-214.8419,1654.8787,24.1355},//30
{-217.1145,1666.9935,24.9542},//31
{-230.0202,1671.4265,28.5422},//32
{-240.1701,1680.7133,28.0925},//33
{-252.4414,1677.7377,27.4495},//34
{-264.8186,1666.5928,26.4511},//35
{-277.9287,1668.5056,27.4045},//36
{-287.5557,1678.8755,26.5148},//37
{-290.7267,1693.0597,28.3341},//38
{-300.0582,1705.0482,32.0989},//39
{-316.0493,1698.2067,34.0618}//40
};
stock GetPlayerCheckpoint(playerid)
{
for(new i; i<sizeof(buddeln); i++)
{
if(IsPlayerInRangeOfPoint(playerid,5.0,buddeln[i][0],buddeln[i][1],buddeln[i][2])) return i;
}
return -1;
}
ocmd:graben(playerid,params[])
{
if(sSpieler[playerid][Schaufel] < 1) return SendClientMessage(playerid,ROT,"Du hast keine Schaufeln mehr, kaufe dir neue im 24/7 Shop!");
if(IsPlayerInAnyVehicle(playerid)) return SendClientMessage(playerid,ROT,"Du sitz in/auf einem Fahrzeug!");
new cp = GetPlayerCheckpoint(playerid);
if(cp == -1) return SendClientMessage(playerid,GRAU,"Du bist nicht in der Nähe!");
switch(random(3))
{
case 0:
{
sSpieler[playerid][Schaufel] -= 1;
SendClientMessage(playerid,GOLD,"Du hast einen Goldbarren gefunden, du kannst ihn behalten, an andere Spieler verkaufen.");
SendClientMessage(playerid,GOLD,"oder auf dem Schwarzmarkt verkaufen.");
sSpieler[playerid][Goldbarre] += 1;
}
case 1:
{
sSpieler[playerid][Schaufel] -= 1;
SendClientMessage(playerid,HELLBLAU,"Leider hast du nichts gefunden, aber nicht aufgeben der Schatz wartet ;)");
}
case 2:
{
SendClientMessage(playerid,HELLBLAU,"Du hast eine Tasche gefunden, vielleicht ist was besonderes drin.");
SendClientMessage(playerid,HELLBLAU,"Mit /tasche kannst du sie öffnen.");
sSpieler[playerid][Schaufel] -= 1;
sSpieler[playerid][Tasche] += 1;
}
}
DisablePlayerCheckpoint(playerid);
return 1;
}
ocmd:bd(playerid,params[])
{
if(sSpieler[playerid][Schaufel] < 1) return SendClientMessage(playerid,ROT,"Du hast keine Schaufeln mehr, kaufe dir neue im 24/7 Shop!");
if(IsPlayerInAnyVehicle(playerid)) return SendClientMessage(playerid,ROT,"Du sitz in/auf einem Fahrzeug!");
new cp = random(40);
SetPlayerCheckpoint(playerid, buddeln[cp][0], buddeln[cp][1] ,buddeln[cp][2],5.0);
SendClientMessage(playerid,HELLBLAU,"Geh zum Checkpoint und tippe /graben ein. Viel Erfolg ;)");
return 1;
}
Alles anzeigen
Der Code ist ein richtig gutes Paradebeispiel dafür, wie man es nicht machen sollte haha xD
Das Problem ist, dass du alle 40 Safeboxen in eine Zeile schreibst und deswegen der crasht.
Nein, dann würde nur der Compiler crashen, er redet vom Server.
Crashdetect könnte hier definitiv helfen.
Deine Abfrage, ob er sich in einem Checkpoint befindet ist auch falsch, weil du nur prüfst ob er sich in einem zufälligen befindet.
Die Chance, dass der Befehl klappt steht damit bei 1/40 xD
Mit 2 einfachen Funktionen kannst du das realisieren:
stock CountCharsInString(const string[])
{
new c;
for(new i=strlen(string)-1; i!=-1; i--)
{
if((string[i] >= 'A' && string[i] <= 'Z') || (string[i] >= 'a' && string[i] <= 'z')) c++;
}
return c;
}
stock CountNumbersInString(const string[])
{
new c;
for(new i=strlen(string)-1; i!=-1; i--)
{
if(string[i] >= '0' && string[i] <= '9') c++;
}
return c;
}
Alles anzeigen
Und dann kannst du ja einfach abfragen:
Ich möchte gerne ein Filterscript erstellen, dass z.B. jeden Tag um 5 Uhr ein restart vom Server kommt
Also möglich ist das auch wirklich einfach durch ein Filterskript.
Falls du also noch irgendwas machen magst, bevor der Server Restartet, so könntest du das realisieren:
//Oben im Skript
new bool:variance;
//Unter OnFilterScriptInit
SetTimer("@restart", 1000*60, 1);
//Dann irgendwo
@restart();@restart()
{
new h,m,s;
gettime(h,m,s);
if(h == 5 && m <= 1 && !variance)
{
variance=true;
SendRconCommand("gmx");
}
else variance=false;
}
Alles anzeigen
Die variance Variable sorgt nur dafür, dass eine Timer Varianz miteinkalkuliert wird und so nicht 2x restartet.