es geht immernoch nicht, etzt steht anstatt 1 eine 68
DU sollst auch den string zurück geben und keine Zahl.
heyhooo hat dir doch die lösung schon gepostet
es geht immernoch nicht, etzt steht anstatt 1 eine 68
DU sollst auch den string zurück geben und keine Zahl.
heyhooo hat dir doch die lösung schon gepostet
Alles anzeigenHi!
ich würde gerne wissen, wie man alle Befehle loggt, die man eingibt!
Ich habe im moment das:
public OnPlayerCommandText(playerid, cmdtext[])
{
return printf("Spieler %s [%d] => Command: %s", getName(playerid), playerid, cmdtext);
}
Doch in der Konsole steht nur etwas, wenn der Spieler einen Command eingibt, den es nicht gibt.
((Ich benutze OCMD))
Jeffry er benutzt ocmd daher, sollte er die Include etwas abändern oder er nutzt noch eine zusätzliche hooking Methode über state.
Nun gut zum eigentlichen Problem , füg einfach oben bevor du die Include einbindest
#define OCMD_COMMAND_LOG
ein.
Fall du ein anderes format haben willst musst du das define in der include ändern
#define OCMD_COMMAND_LOG_FORMAT "[cmd] [%s]: %s"
oder du definierst es neu Beispiel:
#undef OCMD_COMMAND_LOG_FORMAT
#define OCMD_COMMAND_LOG_FORMAT "[%s]: %s"
Als falls du das ganze nur umbennen möchtest das geht wie Jeffry schon gepostet hat auch via einem define
#define SCM(%0,%1,%2) SendClientMessage(%0,%1,%2)
hooken kannst du die Funktionen auch hier mal ein beispiel:
native __SetPlayerArmour(playerid, Float:armour) = SetPlayerArmour;
stock _SetPlayerArmour(playerid, Float:armour) {
AntiCheat[playerid][aArmour] = armour;
return __SetPlayerArmour(playerid,armour);
}
#if defined _ALS_SetPlayerArmour
#undef SetPlayerArmour
#else
#define _ALS_SetPlayerArmour
#endif
#define SetPlayerArmour _SetPlayerArmour
Das was du machen möchtest würde eigentlich nur mit dem Audioplugin funktionieren, jedoch weiß ich nicht ob er die Sequenz nochmal neu abspielt, falls du auch musik einbinden willst.
Bei PlayAudioStreamForPlayer brauchst du nur ein stream der keine werbung enthält
http://forum.sa-mp.com/showthread.php?t=82162
Jup, man kann jetzt Zellen verändern, wenn diese existieren. Sonst geben die Update-Funktionen "false" zurück.
Danke für die Anmerkung
Kein Problem, du hast in der tat recht das man damit viel kaputt machen kann, daher empfehle ich das memory access plugin und dazu die Link list include von BigETI
Plugin:
http://gta-sa-mp.de/forum/3-sa…393-memory-access-plugin/
Include:
http://gta-sa-mp.de/forum/3-sa…397-linked-lists-in-pawn/
Ebenso gibt es noch ein extra modus des Plugins , welche die sicherheit vor speicherlecks noch erhöht und die Performance ist auch besser als y_malloc.
Du kannst dir das ganze ja mal anschauen auch mein Ingameeditor arbeitet mit dem plugin und bisher hatte ich damit noch keine Probleme.
Ich glaube Y_LESS hat sowas schon mal veröffentlicht aber ohne Datenbank
Jo das war y_malloc, die Idee gab es schon öfters in deiner Ausführung noch nicht , jedoch würde ich eher zum memory access plugin tendieren.
was man bei dir jedoch nicht machen kann ist den inhalt einer "Zelle" zu bearbeiten, diesen müsste man momentan erstmal löschen und neu setzen,
daher würde ich noch abfragen ob der Inhalt schon existiert falls ja einfach Updaten, wenn nicht neu eintragen. Das kannst du ja noch ergänzen
Das Tutorial dazu ist auf der zweiten Seite
Ok pass mal auf , das Kommentar diebt dazu die alle objekte welche zur map gehören wiederzuerkennen.
Daher musat du deine map auch mit dem Kommentar LulzMap
über das tool hochladen , wenn du die map mit diesem namen über /convertmap dir ausgeben lassen möchtest.
Der name der zu konvertierenen map muss mit dem kommentar übereinstimmen
Dann schau mal ob der text bei der spalte kommentar dem mapname entspricht falls dem doch so sei und es immer noch nicht funktioniert kannst du mit mir heute abend in kontakt treten ab 23 Uhr, da ich noch im Geschäft bin.
Der editor bugt nichz du nutzt das ganze falsch um die map hochzuladen gibt es das tool den konverter und bevor man .
convertmap eingibt erstmal /saveobj eingeben da er die daten aus der datenbank nimmt
Genau solch ein System habe ich für einen Kunden geschrieben, welcher letztendlich nicht zahlen wollte.
Nutz doch das memory acess plugin und somit ein dynamisches array
Ja habe jetzt wieder 2-4monate nix mehr gemacht und muss wohl mich erstmal einarbeiten.
Werde mich bis heute abend nochmal dransitzen.
Habe total falsch angefangen.
Ich will ein job system mit bestimmten Aufträgen erstellen. Die man dann annimmt. Sollte ich dann Fragen , frag ich wieder :DD
1. z steht für packed strings, für integer musst du i oder d nutzen
2. Für statische Aufträge kannst du ja ein 2dimensionales Array erstellen mit folgender Struktur, dort kannst du deine Aufträge reinhauen, cTimestamp kann danachgenutzt werden
um zum einen abtufragen ob dieser auftrag schon gemacht wurde und um den Auftrag erst nach einer gewissen Zeit wieder frei zu geben
enum cContract {
cName[40],
Float:cX,
Float:cY,
Float:cZ,
cWage,
cTimestamp,
};
3. via einer for-schleife kannst du dir alles auflisten lassen entweder im Dialog (ShowPlayerDialog) oder im Chat (SendClientMessage).
4. Wenn du einen string als platzhalter verwenden möchtest benötigst du %s, nicht %z
ErikSon
deine aussage über die Funktion ist CreateClan mit den strings
ist totaler bullshit der einzige vorteil hierbei wäre das dabei
die strlen direkt angegeben werden kann.
Zum Problem es liegt an sscanf wenn dir Unknown Command
zurück gegeben wird sondern eher das was noch aufgerufen wird.
wie hier CreateClan bei deinem Befehl den du gepostet hast würden falls du das sscanf plugin verwendest nur die längenangabe der strings fehlen.
den obrigen code solltest du einfach nur debugen ich glaub eher das er wich bei CreateClan aufhängt.
SaveClan müsste nicht umbedungt ausgeführt werden wenn der clan direkt eingetragen wird in die datenbank
Ach was...auf die paar Bytes kommt es auf nem root auch nicht mehr drauf an
Aber danke für den Verbesserungs-Vorschlag bin aber zu faul das umzuändern und ich finde, es ist auch mal schön wenn man eine Datei öffnet wenigstens grob was lesen zu können
mfg.
Nun gut da hast du auch wiederrum Recht. Ich dachte nur als alter Optimierungsradikaler.
Jedoch ist das System auch wirklich gut für Neueinsteiger gemacht.
Übrigens funktioniert dein Anti-Cheat nicht, wenn du dem Spieler Waffen über AddPlayerClass gibst, wenn er/sie sich Waffen im Ammu-Nation kauft oder wenn er/sie die Waffen über statische Pickups aufnimmt.
deshalb ist es auch ein Codeschnipsel , also ein Schnipsel von einem ganzen Code, das wird man ja wohl noch selbst ergänzen können ^^.
Eine wirklich gute Idee aber an der performance da könntest du noch etwas schrauben :D.
Dazu hät ich nocheinmal eine Frage,
OnPlayerUpdate ist ja sehr recourcenaufwendig kann man das auch in einen sagen wir mal Sekunden Timer legen?
OnPlayerUpdate wie Raven^ bereits geschrieben hat kommt es letztendlich auf den Code an, OnPlayerUpdate wird ebenfalls nicht in der selben Zeit aufgerufen
wie es bei einem Timer der Fall ist, sondern nur wenn es etwas zu Synchronisieren gibt zwischen Client und dem Server.
So kommt es das OnPlayerUpdate sollte der Spieler auf dem Desktop ist nicht aufgerufen wird, falls sich der Spieler recht langsam oder garnicht bewegt reduziert sich auch der Aufruf von OnPlayerUpdate, besser gesagt OnPlayerUpdate wird nicht so oft aufgerufen.
Jeffry
Nun gut es war lediglich ein Hinweis, da ich selbst mal solch eine Funktion geschrieben habe, die läuft jedoch über getdate und getdate richtet sich nach der Serverzeit,
also auf das Datum , welches eingestellt wurde auf dem Server
stock const WeekDays[7][11] = {
"Sonntag",
"Monntag",
"Dienstag",
"Mittwoch",
"Donnerstag",
"Freitag",
"Samstag"
};
#define DATE_W(%0,%1,%2) WeekDays[(( %0 + _:DATE_Y(%1,%2) + _:DATE_Y(%1,%2)/4 - _:DATE_Y(%1,%2)/100 + _:DATE_Y(%1,%2)/400 + (31 * _:DATE_M(%1))/12 )% 7)]
#define DATE_M(%0) (%0 + 12 * _:DATE_A(%0) - 2)
#define DATE_Y(%0,%1) (%1 - _:DATE_A(%0))
#define DATE_A(%0) ((14 - %0) / 12)
kannst ja abfragen wenn sommerzeit ist die std drauf rechnen? oder abziehn ich nix wissen , und bei winterzeit die abziehen draufrechenn ?
ist halt jedes jahr anders
Auch der zeitlich Wechsel der Sommer und Winterzeit liegt einem Algorithmus zugrunde.
Ein Codeschnipsel für ein Anticheat gegen Waffenhacks.
#if !defined _ALS_
forward public _ALS_();
_ALS_()<_ALS_:unhooked>{}
_ALS_()<_ALS_:hooked>{}
_ALS_()<>{}
#endif
public OnPlayerUpdate(playerid) {
static Waffen[13][2];
for (new i=1; i != 13; ++i)
{
GetPlayerWeaponData(playerid, i, Waffen[i][0], Waffen[i][1]);
if (1 <= Waffen[i][0] <= 18){
if(!(AntiCheat[playerid][aWeapons1] & (1 << Waffen[i][0])))SendClientMessage(playerid,-1,"Du benutzt einen Waffencheat!");
}
else if (22 <= Waffen[i][0] <= 46){
if(!(AntiCheat[playerid][aWeapons2] & (1 << (Waffen[i][0]-22))))SendClientMessage(playerid,-1,"Du benutzt einen Waffencheat!");
}
}
return PH_OnPlayerUpdate(playerid);
}
forward PH_OnPlayerUpdate(playerid);
#if defined _ALS_OnPlayerUpdate
#undef OnPlayerUpdate
#else
#define _ALS_OnPlayerUpdate
#endif
public PH_OnPlayerUpdate(playerid)<_ALS_:unhooked> return 1;
public PH_OnPlayerUpdate(playerid) <> return 1;
#define OnPlayerUpdate(%0) PH_OnPlayerUpdate(%0)<_ALS_:hooked>
native __GivePlayerWeapon(playerid, weaponid, ammo) = GivePlayerWeapon;
stock _GivePlayerWeapon(playerid, weaponid, ammo) {
if (0 <= weaponid <= 18 || 22 <= weaponid <= 46){
if (0 <= weaponid <= 18)AntiCheat[playerid][aWeapons1] |= (1 << weaponid);
else if (22 <= weaponid <= 46)AntiCheat[playerid][aWeapons2] |= (1 << (weaponid-22));
}
return __GivePlayerWeapon(playerid, weaponid, ammo);
}
#if defined _ALS_GivePlayerWeapon
#undef GivePlayerWeapon
#else
#define _ALS_GivePlayerWeapon
#endif
#define GivePlayerWeapon _GivePlayerWeapon
enum aData {
aWeapons1,
aWeapons2,
};
new AntiCheat[MAX_PLAYERS][aData];
Keywords: HeutigerTag, WochenTag, WeekDay, GetToday, GetWeekDay, Welcher Tag ist heute?, Wochentag ausgeben.
Jeffry nix gegen deinen Codeschnipsel jedoch kommt dein Codeschnipsel nicht mit der Sommerzeit klar entweder ziehst du noch getdate dazu oder machst ein extra funktionsparameter
Alles anzeigen
Das ist aber nicht sehr schön
Schau mal:
Ganz schlechte Zeile. Hier fragt er immer wieder den Wert von GetMaxPlayers() ab...besser und schneller wäre deshalb:
for(new i,l=GetMaxPlayers();i<l;i++)
Desweiteren, wäre es so besser:
COMMAND:admins(playerid)
{
new string[(12+MAX_PLAYER_NAME) * 5]; //5 = Anzahl der Admins, wenn es mehr gibt, erhöhen
for(new i,l=GetMaxPlayers();i<l;i++) {
if(!IsPlayerConnected(i) || !User[i][Admin])continue;
format(string,sizeof string,"%s\n%s: %s",string,Adminrang[User[i][Admin]],PlayerName(i));
}
if(!string[0]) return SendClientMessage(playerid,GRAU,"Es sind keine Admins Online!");
SendClientMessage(playerid,GRAU,"Admins online:");
SendClientMessage(playerid,GRAU,string);
return 1;
}
mfg.
Alles anzeigen
Das ist aber nicht sehr schön
Schau mal:
Ganz schlechte Zeile. Hier fragt er immer wieder den Wert von GetMaxPlayers() ab...besser und schneller wäre deshalb:
for(new i,l=GetMaxPlayers();i<l;i++)
Desweiteren, wäre es so besser:
COMMAND:admins(playerid)
{
new string[(12+MAX_PLAYER_NAME) * 5]; //5 = Anzahl der Admins, wenn es mehr gibt, erhöhen
for(new i,l=GetMaxPlayers();i<l;i++) {
if(!IsPlayerConnected(i) || !User[i][Admin])continue;
format(string,sizeof string,"%s\n%s: %s",string,Adminrang[User[i][Admin]],PlayerName(i));
}
if(!string[0]) return SendClientMessage(playerid,GRAU,"Es sind keine Admins Online!");
SendClientMessage(playerid,GRAU,"Admins online:");
SendClientMessage(playerid,GRAU,string);
return 1;
}
mfg.
Ich hoffe du weißt das die ausgabe sich nicht auf einen dialog bezieht und SendClientMessage ein ausgaben limit von 168 oder mehr zeichen hat.
Daher versetze die erste ausgabe des strings vor die schleife
entferne den zeilenbruch in format und verschiebe SendClientMessage an diese Position, welches den formatierten String enthält.
(Mit dem Handy online)
Genau das ist korrekt
erweiter doch dein Array um eine 1 dimension
new Autospawns[7][3][spawnAH] = {
{
{-1641.0673,1211.3047,6.8848,225.4586}
},
{
{-1987.9824,294.5190,34.4335,88.9083}//Autohaus1
}
};