Scripting

8  Scripting

Das Scripting-Kapitel ist in Form eines Tutoriums gefasst, bei dem nicht bei Adam und Eva angefangen wird. Auch wird das Thema nicht in allen Feinheiten vorgestellt. Das würde den Sinn eines Tutoriums verfehlen. Ich bin leider nur Autodidakt und daher im Fachvokabular eines Informatikers nicht firm. Letztendlich sollte mein Wissen jedoch ausreichen, Laien das Admin Mod Scripting näher zu bringen.

Für das Schreiben von Plugins (oder Skripts) unter Admin Mod empfiehlt es sich, bereits Grundkenntnisse in einer Programmiersprache zu besitzen. Dabei genügen bereits Kenntnisse in Basic oder PHP, C++ Kenntnisse wären ideal. Das Wissen, wie ein HL-Server funktioniert, ist jedoch die wichtigste Voraussetzung!

Die verwendete Skriptsprache heißt Small (inzwischen Pawn genannt)1 und bietet gegenüber C++ nur eingeschränkte Möglichkeiten der Programmierung. Gerade deshalb wurde sie gewählt, da der Anwender maximal in der Lage ist, den HL-Server abstürzen zu lassen, nicht aber das gesamte Betriebssystem.

Zunächst sollen die Konventionen und der Syntax von Small vorgestellt werden. C++ Anhänger werden sich vermutlich wie zu Hause fühlen.

 8.1  Syntax
 8.2  Datentypen, Variablen und Konstanten
 8.3  Operatoren
 8.4  Verzweigungen
 8.5  Schleifen
 8.6  Direktiven
  8.6.1  include
  8.6.2  define
  8.6.3  if, elseif, else und endif
 8.7  Funktionen und Events
  8.7.1  Beispiele für Events von Admin Mod
 8.8  Tutorial
  8.8.1  Basis
  8.8.2  Befehle registrieren
  8.8.3  Auf say reagieren
  8.8.4  Spielerconnect abfangen
  8.8.5  Timer verwenden
  8.8.6  Vote ausführen
  8.8.7  Vault-File nutzen
  8.8.8  LogD verwenden
  8.8.9  Menüs nutzen
 8.9  Includes
  8.9.1  admin.inc
  8.9.2  adminlib.inc
  8.9.3  console.inc
  8.9.4  core.inc
  8.9.5  fixed.inc
  8.9.6  math.inc
  8.9.7  plugin.inc
  8.9.8  string.inc
 8.10  Funktionsreferenz
  8.10.1  access
  8.10.2  auth
  8.10.3  ban
  8.10.4  censor_words
  8.10.5  centersay
  8.10.6  centersayex
  8.10.7  changelevel
  8.10.8  ChangeMap
  8.10.9  check_auth
  8.10.10  check_immunity
  8.10.11  check_param
  8.10.12  check_user
  8.10.13  check_words
  8.10.14  clamp
  8.10.15  consgreet
  8.10.16  convert_string
  8.10.17  currentmap
  8.10.18  cvar_exists
  8.10.19  deletefile
  8.10.20  deleteproperty
  8.10.21  directmessage
  8.10.22  distance
  8.10.23  exec
  8.10.24  execclient
  8.10.25  execclient_all
  8.10.26  execute_command
  8.10.27  existproperty
  8.10.28  fileexists
  8.10.29  filesize
  8.10.30  fixed:f_abs
  8.10.31  fixed:f_arccos
  8.10.32  fixed:f_arccot
  8.10.33  fixed:f_arcosh
  8.10.34  fixed:f_arcoth
  8.10.35  fixed:f_arcsin
  8.10.36  fixed:f_arctan
  8.10.37  fixed:f_arctan_help
  8.10.38  fixed:f_arsinh
  8.10.39  fixed:f_artanh
  8.10.40  fixed:f_cos
  8.10.41  fixed:f_cosh
  8.10.42  fixed:f_cot
  8.10.43  fixed:f_coth
  8.10.44  fixed:f_degtorad
  8.10.45  fixed:f_euler
  8.10.46  fixed:f_faculty
  8.10.47  fixed:f_ln
  8.10.48  fixed:f_log10
  8.10.49  fixed:f_logab
  8.10.50  fixed:f_max
  8.10.51  fixed:f_min
  8.10.52  fixed:f_pi
  8.10.53  fixed:f_power
  8.10.54  fixed:f_powere
  8.10.55  fixed:f_radtodeg
  8.10.56  fixed:f_sin
  8.10.57  fixed:f_sinh
  8.10.58  fixed:f_sqrt
  8.10.59  fixed:f_tan
  8.10.60  fixed:f_tanh
  8.10.61  fixed:fdiv
  8.10.62  fixed:ffract
  8.10.63  fixed:fixed
  8.10.64  fixed:fixedstr
  8.10.65  fixed:fmul
  8.10.66  fixed:strtofix
  8.10.67  fixtostr
  8.10.68  format_command
  8.10.69  fround
  8.10.70  funcidx
  8.10.71  get_serverinfo
  8.10.72  get_timer
  8.10.73  get_userArmor
  8.10.74  get_userAuthID
  8.10.75  get_userFrags
  8.10.76  get_userHealth
  8.10.77  get_userindex
  8.10.78  get_userinfo
  8.10.79  get_userIP
  8.10.80  get_username
  8.10.81  get_userorigin
  8.10.82  get_userSessionID
  8.10.83  get_userTeam
  8.10.84  get_userWONID
  8.10.85  get_vaultdata
  8.10.86  get_vaultnumdata
  8.10.87  getarg
  8.10.88  getchar
  8.10.89  getproperty
  8.10.90  getstring
  8.10.91  getstrvar
  8.10.92  gettarget
  8.10.93  getteamcount
  8.10.94  getvalue
  8.10.95  getvar
  8.10.96  glow
  8.10.97  godmode
  8.10.98  heapspace
  8.10.99  help
  8.10.100  index
  8.10.101  kick
  8.10.102  kill_timer
  8.10.103  list_maps
  8.10.104  listspawn
  8.10.105  log
  8.10.106  log_command
  8.10.107  look_in_dir
  8.10.108  maptime
  8.10.109  matherror
  8.10.110  max
  8.10.111  maxplayercount
  8.10.112  menu
  8.10.113  message
  8.10.114  messageex
  8.10.115  min
  8.10.116  motd
  8.10.117  movespawn
  8.10.118  nextmap
  8.10.119  noclip
  8.10.120  numargs
  8.10.121  numtostr
  8.10.122  playercount
  8.10.123  playerinfo
  8.10.124  playsound
  8.10.125  plugin_checkcommand
  8.10.126  plugin_command
  8.10.127  plugin_connect
  8.10.128  plugin_disconnect
  8.10.129  plugin_exec
  8.10.130  plugin_info
  8.10.131  plugin_init
  8.10.132  plugin_message
  8.10.133  plugin_registercmd
  8.10.134  plugin_registerhelp
  8.10.135  plugin_registerinfo
  8.10.136  pointto
  8.10.137  print
  8.10.138  printf
  8.10.139  rainbow
  8.10.140  random
  8.10.141  readfile
  8.10.142  reject_message
  8.10.143  reload
  8.10.144  removespawn
  8.10.145  resetfile
  8.10.146  rindex
  8.10.147  say
  8.10.148  say_command
  8.10.149  selfmessage
  8.10.150  servertime
  8.10.151  set_serverinfo
  8.10.152  set_timer
  8.10.153  set_vaultdata
  8.10.154  set_vaultnumdata
  8.10.155  setarg
  8.10.156  setproperty
  8.10.157  setstrvar
  8.10.158  slap
  8.10.159  slay
  8.10.160  snprintf
  8.10.161  spawn
  8.10.162  speakto
  8.10.163  strbreak
  8.10.164  strcasecmp
  8.10.165  strcasestr
  8.10.166  strcasestrx
  8.10.167  strcat
  8.10.168  strchr
  8.10.169  strcmp
  8.10.170  strcount
  8.10.171  strcpy
  8.10.172  strcspn
  8.10.173  streq
  8.10.174  strgsep
  8.10.175  strgsplit
  8.10.176  strgtok
  8.10.177  strgtokrest
  8.10.178  strinit
  8.10.179  strlen
  8.10.180  strmatch
  8.10.181  strncasecmp
  8.10.182  strncat
  8.10.183  strncmp
  8.10.184  strncpy
  8.10.185  strpack
  8.10.186  strrchr
  8.10.187  strsep
  8.10.188  strsplit
  8.10.189  strspn
  8.10.190  strstr
  8.10.191  strstripquotes
  8.10.192  strstrx
  8.10.193  strsubst
  8.10.194  strtok
  8.10.195  strtokrest
  8.10.196  strtonum
  8.10.197  strtrim
  8.10.198  strunpack
  8.10.199  swapchars
  8.10.200  systemtime
  8.10.201  teleport
  8.10.202  timeleft
  8.10.203  tolower
  8.10.204  toupper
  8.10.205  typesay
  8.10.206  unban
  8.10.207  userlist
  8.10.208  valid_map
  8.10.209  valid_mapex
  8.10.210  version
  8.10.211  vote
  8.10.212  vote_allowed
  8.10.213  writefile
 8.11  Compiler Fehler und Warnungen
 8.12  Runtime Fehler
 8.13  LogD Events
 8.14  Properties in Small

8.1  Syntax

Die Syntax Smalls lässt sich am Besten anhand eines „Hallo Welt“ Codes erklären:
1 #include <core>  
2 #include <string>  
3 #include <admin>  
4 #include <adminlib>  
5  
6 new VERSION[]= "1.0";  
7  
8 public plugin_init() {  
9    plugin_registerinfo("Hallo Welt Plugin","Hallo Welt!",VERSION);  
10    say("Hallo Welt!");  
11  
12    return PLUGIN_CONTINUE;  
13 }

Die Funktion plugin_init wird beim Starten des Plugins ausgeführt (entspricht der main() Funktion von C++). Die Funktion muss öffentlich bekannt sein (public) und sollte PLUGIN_CONTINUE zurückgeben. Der Beginn und das Ende von Verzweigungen, Schleifen, usw. wird durch geschweifte Klammern kenntlich gemacht. Funktionen müssen durch ein Semikolon abgeschlossen werden. Includes und Deklarationen werden mittels Hashes (#) kenntlich gemacht. Außerdem ist zu beachten, dass Small Groß- und Kleinschreibung unterscheidet.

8.2  Datentypen, Variablen und Konstanten

Small wird als „typenlose“ Programmiersprache bezeichnet. Der einzige, direkt unterstützte Datentyp ist 32-bit signed Integer (-2147483648 bis +2147483647).

Variablen werden in der Regel über die „new“-Anweisung deklariert. Man kann sie „global“ definieren, wenn sie im Skript außerhalb der Funktionen deklariert werden oder „lokal“ innerhalb ein Funktion.

new iZahl1;
new iZahl2 = 1;

Man kann die Variable ohne Zuweisung erstellen und diese im Code nachholen oder, wie im zweiten Beispiel gezeigt, direkt zuweisen.

Lokale Variablen gelten nur für die Funktion, in der sie erstellt wurden und werden nach Abschluss der Ausführung selbiger wieder gelöscht. Daher findet man hin und wieder auch statt „new“ „static“ bei der Deklarierung, da hier der Variableninhalt erhalten bleibt. Eine andere Möglichkeit den Variableninhalt zu behalten und ihn zudem allen Funktionen gleichzeitig zur Verfügung zu stellen, besteht in der Definition globaler Variablen. Dabei muss die Variable außerhalb der Funktionen definiert werden. Meist findet man diese am Kopf des Plugins wieder, damit sie den nachfolgenden Funktionen bekannt sind.

Zahlen können auch in bis zu zweidimensionalen Feldern verwendet werden.

new aFeld[2][2];
aFeld[1][0] = 5;
aFeld[1][1] = 3;

Eine einmal festgelegte Feldgröße kann während der Laufzeit nicht geändert werden. Man sollte vorausschauend programmieren und die Feldgröße ausreichend dimensionieren.

Die 1 und die 0 sieht Small neben den üblichen Rechnungen insbesondere in Vergleichen auch als Boolean-Wert „Wahr“ bzw. „Falsch“ an.

Konstanten werden stets am Kopf des Plugins definiert. Die Definition sieht etwa folgendermaßen aus:

#define MAX_TEST_LENGTH 100

Dies ist eine compilerspezifische Anweisung und muss damit nicht mit einem Semikolon abgeschlossen werden. Der Compiler ersetzt im Beispiel alle MAX_TEST_LENGTH beim Compilieren durch 100. Eine Feldvariable kann also auch so definiert werden:

new Variable[MAX_TEST_LENGTH];

Das mag auf den ersten Blick etwas umständlich erscheinen. Hat man jedoch mehrere dieser Felder, kann man die Größe aller bequem über die Konstantendefinition ändern. Darüber hinaus erhöht es die Lesbarkeit des Programmcodes.

Alternativ kann man Konstanten auch mit einem vorangestellten „const“ definieren:

const cVariable = 1

Strings werden in Feldern abgespeichert, wobei jeder Buchstabe eine Zahl in einer Zelle des Arrays ist. Das Feld zum zugehörigen Text muss immer um eine Zelle größer als die Länge des Texts angesetzt werden, da Small in die letzte Zelle ein „^0“ setzt, um das Ende des Strings festzulegen.

new Text[200]=“Hallo Welt!”;
new Text[]=“Hallo Welt!”;

Man kann wie gezeigt auch auf die Deklaration einer Feldgröße verzichten. Die Feldgröße beträgt in diesem Fall jedoch nur die Länge von „Hallo Welt!“ + 1 (12) und kann auch nicht während der Laufzeit vergrößert werden.

Neben dem Pseudo-Datentyp String gibt es den Typ der Festkommazahlen (Fixed). Die Festkommazahlen haben in Admin Mod einen Zahlenbereich von -2147482 bis +2147482 mit 3 Nachkommastellen. Festkommazahlen werden folgendermaßen deklariert:

new fixed:fPI = 3.142;

Die Information „fixed:“ weist den Compiler an, die Zahl als Festkommazahl zu betrachten.

Zu guter Letzt kann man auch Enums definieren. Dabei werden Begriffe einer aufsteigenden Zahlenreihe zugeordnet. Man kann sie zur besseren Lesbarkeit des Codes einsetzen.

enum tks{tk=0,victim};

Das „=0“ bedeutet, dass bei Null angefangen wird zu zählen. Jeder weitere Option bekommt einen um eins erhöhten Wert.

8.3  Operatoren

Es stehen folgende Rechenoperatoren zur Verfügung:

+ Addieren
- Subtrahieren
* Multiplizieren
/ Dividieren
& Bit-Shift-Aktionen

Auch existieren die üblichen Vereinfachungen aus anderen Sprachen.

i++; entspricht i=i+1;
i+=j; entspricht i=i+j;

Vorsicht! Nicht auf Zellen von Feldern anwenden. a[1]++; z.B. führt auf Grund eines Compilerbugs im schlimmsten Fall zum Absturz des HL-Servers!

Eine Besonderheit sind die Festkommazahlen. Während das Addieren und Subtrahieren noch identisch ausgeführt wird, gibt es für das Multiplizieren und Dividieren spezielle Funktionen (fmul und fdiv). Über die Grundrechenarten hinausgehende Rechenfunktionen bzw. -operatoren zu Festkommazahlen sind der math.inc zu entnehmen.

Es gibt darüber hinaus auch logische Operatoren, die insbesondere in Verzweigungen eingesetzt werden:

! Nicht
&& Und
|| Oder

8.4  Verzweigungen

Es gibt in Small zwei Verzweigungen, „if“ und „switch“. Die If-Verzweigung kann durch „else if“ und/oder „else“ erweitert werden.
1 vergleich(i){  
2    new j=0;  
3  
4    if (i = 1){  
5       j = 2;  
6    }  
7    else if (i = 2 || i = 3) {  
8       j = 5;  
9    }  
10    else {  
11       j = 1;  
12    }  
13  
14    return j;  
15 }

Die Vergleiche wurde zur besseren Lesbarkeit in runde Klammern gesetzt. Dies ist nicht notwendig, aber zu empfehlen. Für Konstrukte dieser Art sollte man aus Übersichtlichkeitsgründen aber eher auf die Switch-Verzweigung ausweichen. Das obige Beispiel sieht dann folgendermaßen aus:
1 vergleich(i){  
2    new j = 0;  
3  
4    switch(i){  
5       case 1:{  
6          j = 2;  
7       }  
8       case 2,3:{  
9          j = 5;  
10       }  
11       default:{  
12          j = 1;  
13       }  
14    }  
15  
16    return j;  
17 }

Switch-Verzweigungen können nur Zahlen jedoch keine Strings vergleichen.

8.5  Schleifen

Small hat 3 verschiedene Schleifen implementiert, „for“, „while“ und „do ... while“. In Admin Mod werden vorzugsweise For-Schleifen eingesetzt, da auf Grund der festgelegten Feldgröße auch die Schleifenlänge bereits vorab festgelegt werden kann.
1 schleife(){  
2    new j = 0;  
3  
4    for (i=0;i<=5;i++){  
5       j = j + i;  
6    }  
7  
8    return j  
9 }

In diesem Fall läuft die Schleife von 0 bis 5, wobei i um eins bei jedem Schritt erhöht wird. Will man die Schleife abbrechen, z.B. wenn j 10 überschreitet, muss man mit der break-Anweisung arbeiten.
1 schleife(){  
2    new j = 0;  
3  
4    for (i=0;i<=5;i++){  
5       if (j >= 10){  
6          break;  
7       }  
8       j = j + i;  
9    }  
10  
11    return j  
12 }

In diesem Fall bricht die For-Schleife komplett ab, und der Wert j wird zurückgegeben. Statt „break“ kann auch „continue“ verwendet werden.
6          continue;

Mit „continue“ wird direkt der nächste Durchlauf der Schleife initiiert, ohne dass die noch ausstehenden Rechnungen (hier: j = j + i;) durchgeführt werden.

Die gleiche Schleife kann auch mit „while“ und „do ... while“ durchgeführt werden, wobei beachtet werden muss, dass „do ... while“ mindestens einmal ausgeführt wird, da der Vergleich erst am Ende der Schleife durchgeführt wird.
1 schleife(){  
2    new j = 0;  
3  
4    do i++ while (j >= 10){  
5       j = j + i;  
6    }  
7  
8    return j  
9 }

Und hier auch ein Beispiel mit while:
1 schleife(){  
2    new j = 0;  
3  
4    while (j >= 10) i++{  
5       j = j + i;  
6    }  
7  
8    return j  
9 }

8.6  Direktiven

Direktiven sind Anweisungen an den Compiler, die nur zur Laufzeit des Compilers und nicht während der Laufzeit des Plugins berücksichtigt werden. Es sollen an dieser Stelle nur die gebräuchlisten Direktiven in Admin Mod beschrieben werden.

8.6.1  include

#include Include-Datei oder <Include-Datei>

Mit der Include-Direktive wird eine Include-Datei mit seinen Funktionen in den Quellcode eingebunden. Der Dateiname muss mit „.inc“ enden. Diese Endung darf jedoch nicht in der Direktive auftauchen. Ist der Dateiname in Klammern, wird die Include-Datei im Includes-Verzeichnis gesucht, während sie ohne die Klammern im gleichen Verzeichnis wie die Quelldatei erwartet wird.

8.6.2  define

#define KONSTANTENNAME Zahl

Mit dieser Direktive werden, wie bereits im Kapitel „Datentypen, Variablen und Konstanten“ beschrieben, Konstanten festgelegt.

8.6.3  if, elseif, else und endif

1 #define TEST 1  
2 #if Test == 1  
3    Small-Code 1  
4 #elseif Test == 2  
5    Small-Code 2  
6 #else  
7    Small-Code 3  
8 #endif

Man kann damit über eine Konstante definieren, welchen Code der Compiler für das Plugin nutzen soll. Ich würde das als Poor-Man’s-Option bezeichnen. Für den Enduser sollte man die Option üblicherweise zur Laufzeit änderbar machen (z.B. mit einem Admin Mod Befehl).

8.7  Funktionen und Events

Funktionen sind ein wesentlicher Bestandteil Admin Mods. Funktionen können aus anderen (einfacheren) Funktionen erstellt werden. Viele Funktionen werden jedoch auch von Admin Mod zur Verfügung gestellt. Sie werden in den sogenannten Includes vermerkt und stehen nach Einbindung selbiger für die Programmierung zur Verfügung.

Es gibt aber auch Funktionen, die bei bestimmten Events (z.B. Serverbefehl oder Spielerconnect) automatisch ausgeführt werden. Dabei kann die zugehörige Reaktion programmiert werden. Dies sind:

Auf die Anwendung von Events wird im Tutorial näher eingegangen.

Vorgegebenen Funktionen ist ein „stock“ (in Small erstellte Funktion) bzw. „native“ (von Admin Mod zur Verfügung gestellte Funktion) vorangestellt. Sie werden nur vom Compiler eingebunden, wenn sie auch benötigt werden. Beide Schlüsselwörter sind nur von Interesse, wenn man eigene Includes erstellen möchte. Funktionen, die auf Events reagieren, muss ein „public“ vorangestellt werden, da anderenfalls die Funktion zur Laufzeit nicht gefunden wird. Alle weiteren Funktionen benötigen keine besondere Kennzeichnung.

8.7.1  Beispiele für Events von Admin Mod

Zunächst startet Metamod Admin Mod. Admin Mod lädt seine Plugins in der Reihenfolge, wie sie in der plugin.ini stehen und führt jeweils die plugin_init Funktion aus. Die plugin_init sollte so programmiert sein, dass Pluginname, Beschreibung, Version und ggf. zu registrierende Befehle an Admin Mod zurückgegeben werden. Admin Mod weiß nun, welche Befehle es an das Plugin weiterleiten soll.

Kommt ein Spieler auf den Server, ruft Admin Mod die Funktion plugin_connect auf (sofern im Plugin definiert) und führt die angegebenen Aktionen durch.

Wird ein im Plugin definierter Befehl aufgerufen, wird die zugehörige Funktion aufgerufen, die (sofern der Accesslevel des Spielers ausreicht) ausgeführt wird. Das Plugin meldet zurück, ob Admin Mod noch andere Plugins abfragen soll (return PLUGIN_CONTINUE), oder ob Admin Mod die weiteren Plugins übergehen soll (return PLUGIN_HANDLED).

8.8  Tutorial

In diesem Tutorial wird auf das Grundgerüst aufgebaut und die wichtigsten Funktionen und Events sowie deren Anwendung vorgestellt.

8.8.1  Basis

Small bzw. Admin Mod erwarten ein gewisses Grundgerüst, damit sie das compilierte Plugin akzeptieren.
1 #include <core>  
2 #include <string>  
3 #include <admin>  
4 #include <adminlib>  
5  
6 public plugin_init() {  
7    plugin_registerinfo("Testplugin","Ein Testplugin!","1.0");  
8    return PLUGIN_CONTINUE;  
9 }

Zunächst werden die Includes eingebunden.
1 #include <core>  
2 #include <string>  
3 #include <admin>  
4 #include <adminlib>

Man sollte nie zu sparsam bei den Includes sein. Theoretisch kann man alle vorhandenen Includes einbinden, da nur das vom Compiler berücksichtigt wird, was er auch benötigt. Das Plugin wird durch mehr Includes nicht größer.

Damit das Plugin überhaupt etwas tut, wird das Event plugin_init eingebunden. Überlicherweise geschieht dies am Ende des Quellcodes.
6 public plugin_init() {  
7    plugin_registerinfo("Testplugin","Das Plugin macht noch nichts!","1.0");  
8    return PLUGIN_CONTINUE;  
9 }

Das Event plugin_init wird nach dem HL-Serverstart bzw. nach jedem Mapwechsel von Admin Mod aufgerufen. Damit Admin Mod erkennt, dass das Plugin plugin_init implementiert hat, muss das Event mit „public“ bekanntgegeben werden. In Zeile 8 wird Admin Mod zurückgemeldet, dass die Abarbeitung des Events erfolgreich beendet ist.

In Zeile 7 wird Admin Mod mitgeteilt (plugin_registerinfo), wie das Plugin heißt, was das Plugin macht, und um welche Version des Plugins es sich handelt.
7    plugin_registerinfo("Testplugin","Das Plugin macht noch nichts!","1.0");

Die angebenen Informationen haben keine Funktion in Admin Mod, sondern dienen nur zur späteren Darstellung in der Console, wenn man sich alle geladenen Plugins auflisten lässt.

Dieses Plugin registriert sich also lediglich bei Admin Mod. Weitergehende Aktionen werden nicht ausgeführt.

8.8.2  Befehle registrieren

Meist möchte man, dass Admin Mod auf einen bestimmten Befehl eine Aktion ausführt. Dafür muss zunächst bei Admin Mod ein Befehl registriert werden. Üblicherweise macht man dies im Event plugin_init. Zum einfacheren Verständnis erweitern wir das Grundplugin.
1 #include <core>  
2 #include <string>  
3 #include <admin>  
4 #include <adminlib>  
5  
6 public test(HLCommand,HLData,HLUserName,UserIndex) {  
7    new sData[MAX_DATA_LENGTH];  
8  
9    convert_string(HLData,sData,MAX_DATA_LENGTH);  
10    userlist(sData);  
11  
12    return PLUGIN_HANDLED;  
13 }  
14  
15 public plugin_init() {  
16    plugin_registerinfo("Testplugin","Ein Testplugin!","1.0");  
17    plugin_registercmd("admin_test","test",ACCESS_ALL,"Userlist anzeigen");  
18  
19    return PLUGIN_CONTINUE;  
20 }

Das Plugin wurde um einen Befehl „plugin_registercmd„ erweitert, der einen Befehl bei Admin Mod registriert.
17    plugin_registercmd("admin_test","test",ACCESS_ALL,"Userlist anzeigen");

Dabei ist admin_test der Befehl, auf den Admin Mod später reagiert und die Funktion „test“ ausführt, die ebenfalls hinzugefügt wurde. Zugriff auf den Befehl haben alle Spieler (ACCESS_ALL). Die vordefinierten Accesslevel sind der admin.inc zu entnehmen oder selbst zu definieren. Zu letzt gibt man einen Hilfetext an, der bei der Ausführung von „admin_help“ ausgegeben wird.

Damit Admin Mod auch eine Aktion ausführen kann, wenn das Event „admin_test“ ausgeführt wird, muss auch die Funktion „test“ definiert werden.
6 public test(HLCommand,HLData,HLUserName,UserIndex) {  
7    new sData[MAX_DATA_LENGTH];  
8  
9    convert_string(HLData,sData,MAX_DATA_LENGTH);  
10    userlist(sData);  
11  
12    return PLUGIN_HANDLED;  
13 }

Damit Admin Mod die Funktion auch aufrufen kann, muss ein „public“ vorangestellt werden. Die übergebenen Variablen bei einem Befehlsevent sind vorgegeben. „HLCommand“ bringt den die Funktion aufrufenden Befehl (hier: „admin_test“). Es können aber auch verschiedene Befehle die gleiche Funktion aufrufen. Dann kann man mit Verzweigungen unterschiedlichen Code ausführen lassen. In „HLData“ stehen die Befehlsoptionen und in „HLUserName“ der Spielername, der den Befehl aufgerufen hat. „UserIndex“ wiederum gibt an, in welchem Slot der aufrufenden Spieler auf dem Server ist.

Die HL-Variablen müssen, sofern sie genutzt werden sollen, erst in Small-Strings konvertiert werden. Nur der UserIndex liegt bereits als Zahl vor.
9    convert_string(HLData,sData,MAX_DATA_LENGTH);

Nach Ausführung der convert_string Funktion liegt alles, was nach „admin_test“ eingegeben wurde, in der Variable sData vor. Nun wird die Funktion „userlist“ ausgeführt.
10    userlist(sData);

Ist sData leer, werden alle Spieler auf dem Server mit einigen Zusatzinformationen in der Console ausgegeben. Ist z.B. „admin_test a“ eingegeben worden, ist sData = „a“. Es werden dann alle Spieler ausgegeben, deren Name ein „a“ enthält.

Die Funktion wird nicht wie bei der plugin_init durch PLUGIN_CONTINUE beendet.
13    return PLUGIN_HANDLED;

Admin Mod geht der Reihe nach durch die Plugins und überprüft, ob der gesuchte Befehl einem Plugin gehört. Erst wenn es kein passendes Plugin findet, gibt es den Befehl an den Server weiter. Würde man hier PLUGIN_CONTINUE angeben, so würde Admin Mod in den nachfolgenden Plugins weitersuchen und den Befehl anschließend an den Server weitergeben. Der Server kennt den Befehl aber nicht und würde mit „Unknown command“ antworten, obwohl die Admin Mod Aktion durchgeführt wurde.

Mit PLUGIN_HANDLED verhindert man, dass Admin Mod weitersucht bzw. den Befehl an den Server weitergibt.

8.8.3  Auf say reagieren

Die gleiche Funktionalität kann man auch über den Chat erreichen, wenngleich die Ausgabe weiterhin in der Console stattfindet. Es soll also bei der Eingabe von „userlist“ im Chat, die Spielerliste in der Console ausgegeben werden.
1 #include <core>  
2 #include <string>  
3 #include <admin>  
4 #include <adminlib>  
5  
6 public test(HLCommand,HLData,HLUserName,UserIndex) {  
7    new sData[MAX_DATA_LENGTH];  
8    new sCommand[MAX_COMMAND_LENGTH];  
9  
10    convert_string(HLData,sData,MAX_DATA_LENGTH);  
11    strsep(sData," ",sCommand,MAX_COMMAND_LENGTH,sData,MAX_DATA_LENGTH);  
12  
13    if (streq(sCommand, "userlist") == 1) {  
14       userlist(sData);  
15       return PLUGIN_HANDLED;  
16    }  
17  
18    return PLUGIN_CONTINUE;  
19 }  
20  
21 public plugin_init() {  
22    plugin_registerinfo("Testplugin","Ein Testplugin!","1.0");  
23    plugin_registercmd("say","test",ACCESS_ALL);  
24    plugin_registercmd("say_team","test",ACCESS_ALL);  
25    plugin_registerhelp("say",ACCESS_ALL,"userlist <Muster>: Userlist anzeigen");  
26  
27    return PLUGIN_CONTINUE;  
28 }

Es wurde „admin_test“ durch „say“ (freier Chat) und „say_team“ (Teamchat) ersetzt.
23    plugin_registercmd("say","test",ACCESS_ALL);  
24    plugin_registercmd("say_team","test",ACCESS_ALL);  
25    plugin_registerhelp("say",ACCESS_ALL,"userlist <Muster>: Userlist anzeigen");

Da auch andere Plugins „say“ und „say_team“ reagieren können, verzichtet man beim Registrieren auf einen Hilfetext. Stattdessen legt man mit plugin_registerhelp einen Hilfetext fest. Auf diese Weise können auch Unteroptionen genauer beschrieben werden. Eine Funktion muss nicht angegeben werden, da der Befehl nur den Hilfetext festlegt.

Auch die Funktion „test“ hat sich verändert.
6 public test(HLCommand,HLData,HLUserName,UserIndex) {  
7    new sData[MAX_DATA_LENGTH];  
8    new sCommand[MAX_COMMAND_LENGTH];  
9  
10    convert_string(HLData,sData,MAX_DATA_LENGTH);  
11    strsep(sData," ",sCommand,MAX_COMMAND_LENGTH,sData,MAX_DATA_LENGTH);  
12  
13    if (streq(sCommand, "userlist") == 1) {  
14       userlist(sData);  
15       return PLUGIN_HANDLED;  
16    }  
17  
18    return PLUGIN_CONTINUE;  
19 }

Da der Befehl immer „say“ oder „say_team“ lautet, muss man erst sData trennen, um an den eigentlichen Befehl heranzukommen.
11    strsep(sData," ",sCommand,MAX_COMMAND_LENGTH,sData,MAX_DATA_LENGTH);

Mit „strsep“ wird der String sData am ersten Leerzeichen in sCommand und sData getrennt (sData wird dabei überschrieben). Man muss jeweils auch die maximale Länge des Strings angeben.

Anschließend wird der Befehl in sCommand überprüft, ob er mit „userlist“ identisch ist (streq). Wenn dies der Fall ist, wird die Spielerliste ausgegeben und nicht weitergesucht (PLUGIN_HANDLED). Das bedeutet auch, dass die Nachricht nicht im Chat ankommt. Admin Mod gibt die Nachricht nicht an den Server weiter. Ist sCommand nicht mit „userlist“ identisch, gibt Admin Mod die Nachricht an das nächste Plugin oder an den Server weiter. Sofern also kein anderes Plugin die Weiterleitung blockiert, landet sie beim Serverchat.

8.8.4  Spielerconnect abfangen

Es könnte von Interesse sein, eine Aktion durchzuführen, wenn ein Spieler den Server betritt. Im folgenden Plugin soll in den Logfiles gespeichert werden, welcher Slot beim Connect besetzt wird.
1 #include <core>  
2 #include <string>  
3 #include <admin>  
4 #include <adminlib>  
5  
6 public plugin_connect(HLUserName, HLIP, UserIndex) {  
7    new sText[MAX_TEXT_LENGTH];  
8  
9    snprintf(sText,MAX_TEXT_LENGTH,"Slot %d ist besetzt",UserIndex);  
10    log(sText);  
11  
12    return PLUGIN_CONTINUE;  
13 }  
14  
15 public plugin_init() {  
16    plugin_registerinfo("Testplugin","Ein Testplugin!","1.0");  
17    return PLUGIN_CONTINUE;  
18 }

Der Event „plugin_connect“ muss wie alle Events mit „public“ öffentlich gemacht werden.
6 public plugin_connect(HLUserName, HLIP, UserIndex) {

Wie beim Serverbefehl-Event gibt es auch für den Spielerbeitritt festgelegte Variablen, die ausgewertet werden können. Leider ist der Event in der Regel zu früh, so dass weder Spielername noch seine IP zurückgegeben werden. Nur der Slot (UserIndex) lässt sich zuverlässig nutzen.

Aus dem „UserIndex“ soll ein ausagekräfter Text für die Logdateien gemacht werden.
9    snprintf(sText,MAX_TEXT_LENGTH,"Slot %d ist besetzt",UserIndex);  
10    log(sText);

Mit der Funktion „snprintf“ lassen sich einfach Strings und Zahlen in einen bestehenden String implementieren. Neben dem String, in den der Text gespeichert werden soll, muss auch die maximale Länge des Strings angegeben werden. Der folgende String beinhaltet neben dem eigentlichen Text auch einen Platzhalter für den Slot (%d steht für eine Zahl, %s steht für einen String). Abschließend müssen in der Reihenfolge des Auftauchens im Text die Variablen angegeben werden. Das Ergebnis sieht dann z.B. folgendermaßen aus:

Slot 9 ist besetzt

Als letztes wird der Text mittels der Funktion „log“ in die Logdatei eingetragen. Dies passiert bei jedem Spieler, der auf den Server kommt.

8.8.5  Timer verwenden

Oftmals möchte man bestimmte Aktionen in regelmäßigen Abständen wiederholen lassen. Admin Mod bietet dafür Timer an, die eine Aktion ein- oder mehrmals durchführen können. Es wird damit bei jedem Auslösen des Timers ein Event erzeugt, das mit einer vordefinierten Funktion (wie bei einem Serverbefehl) verarbeitet werden kann.

Das folgende Plugin zeigt in roter, zentrierter Schrift alle 60 Sekunden den Begriff „Admin Mod“ an.
1 #include <core>  
2 #include <string>  
3 #include <admin>  
4 #include <adminlib>  
5  
6 public say_stuff(Timer,Repeat,HLName,HLParam) {  
7    centersay("Admin Mod",10,255,0,0);  
8 }  
9  
10 public plugin_init() {  
11    plugin_registerinfo("Testplugin","Ein Testplugin!","1.0");  
12    set_timer("say_stuff", 60, 99999,"");  
13    return PLUGIN_CONTINUE;  
14 }

In plugin_init wird zunächst mittels set_timer ein Timer gestartet. 12    set_timer("say_stuff", 60, 99999,"");

Es muss angegeben werden, welche Funktion („say_stuff“) beim Ablauf des Timers aufgerufen werden soll, wie lang der Timer jeweils laufen soll (60 Sekunden), wie lang er wiederholt werden soll. Die 99999 hat eine Sonderstellung und steht für unendlich viele Wiederholungen. Admin Mod wird nun versuchen alle 60 Sekunden die Funktion „say_stuff“ auszuführen.

Diese Funktion muss wiederum öffentlich (public) gemacht werden.
6 public say_stuff(Timer,Repeat,HLName,HLParam) {  
7    centersay("Admin Mod",10,255,0,0);  
8 }

Da es sich um eine Funktion handelt, die von einem Timer aufgerufen wurde, gibt es wieder festgelegte Variable. Zunächst wird die Nummer des Timers zurückgegeben. Diese erhält man auch als Rückgabe von set_timer. Weiterhin wird übergeben, um die wievielte Wiederholung es sich handelt. „HLName“ gibt den Spieler zurück, der den Timer ausgelöst hat. Hier ist der Timer automatisch ausgelöst worden, es wird kein Name zurückgegeben. Wird der Timer aus einem Serverbefehlevent ausgeführt, wird der Spieler zurückgegeben, der den Befehl aufgerufen hat. Zuletzt wird ein beliebiger String „HLParam“ übergeben, der in set_timer festgelegt wurde. Im Beispiel wurde nichts angegeben. „HLName“ und „HLParam“ müssen mit convert_string konvertiert werden.

Die centersay Funktion sorgt für die eigentlich Darstellung des Texts „Admin Mod“. Dieser muss natürlich angegeben werden. Weiterhin benötigt die Funktion die Dauer der Darstellung (10 Sekunden) und die Farbe in RGB-Farben (jede Farbe 0 bis 255).

8.8.6  Vote ausführen

Das nächste Beispiel soll zeigen, wie man einen Vote mit Admin Mod durchführt. In diesem Plugin soll die Mehrheit der Spieler entscheiden, ob in einem Counter-Strike Spiel die Map neu gestartet werden soll.
1 #include <core>  
2 #include <string>  
3 #include <admin>  
4 #include <adminlib>  
5  
6 public test(HLCommand,HLData,HLUserName,UserIndex) {  
7    if (vote_allowed()!=1) {  
8       selfmessage( "Vote noch nicht erlaubt.");  
9       return PLUGIN_HANDLED;  
10    }  
11  
12    vote("Restart?","Ja","Nein","HandleVsay","");  
13    return PLUGIN_HANDLED;  
14 }  
15  
16 public HandleVsay(WinningOption,HLData,VoteCount,UserCount) {  
17    if (WinningOption == 1) {  
18       say("Mehrheit wollte Restart");  
19       setstrvar("sv_restart","1");  
20    }  
21    else {  
22       say("Mehrheit wollte keinen Restart");  
23    }  
24 }  
25  
26 public plugin_init() {  
27    plugin_registerinfo("Testplugin","Ein Testplugin!","1.0");  
28    plugin_registercmd("admin_test","test",ACCESS_ALL,"Restartvote");  
29    return PLUGIN_CONTINUE;  
30 }

Um den Vote ausführen zu können, braucht man ein Event. Es wurde zu diesem Zweck ein Befehl eingefügt (Zeile 28), der auf die „test“ Funktion verweist. Natürlich lässt sich der Vote auch mit anderen Events koppeln.

Zunächst muss überprüft werden, ob ein Vote überhaupt erlaubt ist.
7    if (vote_allowed()!=1) {  
8       selfmessage( "Vote noch nicht erlaubt.");  
9       return PLUGIN_HANDLED;  
10    }

Die Funktion vote_allowed überprüft, ob die in der Variablen vote_freq festgelegte Zeit seit dem letzten Vote bzw. des Mapchanges abgelaufen ist. Ist dies nicht der Fall, wird dem Aufrufenden ein Nachricht in die Console gesendet (selfmessage) und anschließend die Ausführung mit „return“ abgebrochen. Diese Routine verhindert, dass der unzulässige Aufruf von vote zu einer Fehlermeldung führt.

Anschließend wird der Vote mit der Funktion vote gestartet. Vote benötigt eine Frage, bis zu neun Optionen, die aufzurufende Funktion und Zusatzdaten.
12    vote("Restart?","Ja","Nein","HandleVsay","");

Hier wird gefragt, ob ein Restart durchgeführt werden soll, es gibt zwei Optionen (Ja oder Nein), die aufzurufende Funktion heißt „HandleVsay“ und es werden keine Zusatzdaten übertragen. Es ist zu beachten, dass keine Vote-Dauer festgelegt werden kann. Hierzu zieht Admin Mod die Variable amv_vote_duration heran. Auch die Schriftfarbe kann nicht verändert werden (weiß).

Der Vote-Event wird mit Ablauf des Vote-Timers ausgelöst.
16 public HandleVsay(WinningOption,HLData,VoteCount,UserCount) {  
17    if (WinningOption == 1) {  
18       say("Mehrheit wollte Restart");  
19       setstrvar("sv_restart","1");  
20    }  
21    else {  
22       say("Mehrheit wollte keinen Restart");  
23    }  
24 }

Einige Variablen werden bei diesem Event mitgeliefert. „WinningOption“ gibt die Nummer der Option an, die gewonnen hat. Dies wird über die Variable admin_vote_ratio vorab festgelegt. „HLData“ gibt die Zusatzoptionen zurück, die hier nicht genutzt wurden (muss konvertiert werden). Außerdem bekommt man die Anzahl der Stimmen, die auf die Option gefallen sind (VoteCount) sowie die Gesamtzahl der Stimmen (UserCount).

Die erste Option „Ja“ ist die „1“. Wenn Option 1 gewonnen hat, gibt Admin Mod im Chat aus (say), dass sich die Mehrheit für einen Restart entschieden hat. Anschließend wird die Variable „sv_restart“ auf 1 gesetzt (setstrvar), was mit einem Restart nach einer Sekunde gleichzusetzen ist. Gewinnt Option 2 wird dies ebenfalls den Spielern mitgeteilt, aber keine weitere Aktion ausgeführt. Ein „return“ ist hier nicht notwendig, da Admin Mod beim Vote-Event keine Rückgabe benötigt.

8.8.7  Vault-File nutzen

Variablen lassen sich bequem in Plugins speichern. Die Inhalte gehen jedoch beim Mapwechsel oder beim Abschalten des Servers verloren. Einige der Standardplugins dürfen sich über Servervariablen glücklich schätzen, die für sie von Admin Mod erstellt wurden. Um auch anderen Programmierern die Möglichkeit zu geben, Einstellungen dauerhaft zu speichern, wurde die vault.ini geschaffen. Mit einigen wenigen Befehlen lassen sich bequem Zahlen und Strings abspeichern. Man sollte diese Funktionen allen Textdateispielereien vorziehen. Sie sind wesentlich schneller als die zum Lesen und Schreiben von Textdateien.

Das folgende Beispiel schreibt einen zufälligen Wert zwischen 0 und 9 in einen Vault-Eintrag. Es wird dabei die Funktion set_vaultnumdata nachgebaut.
1 #include <core>  
2 #include <string>  
3 #include <admin>  
4 #include <adminlib>  
5  
6 public write_entry(HLCommand,HLData,HLUserName,UserIndex) {  
7    new_set_vaultnumdata("TEST_ENTRY",random(9));  
8    return PLUGIN_HANDLED;  
9 }  
10  
11 new_set_vaultnumdata(sEntry[],iContent){  
12    new sContent[MAX_DATA_LENGTH];  
13    snprintf(sContent,MAX_DATA_LENGTH,"%d",iContent);  
14    set_vaultdata(sEntry,sContent);  
15    return PLUGIN_CONTINUE;  
16 }  
17  
18 public plugin_init() {  
19    plugin_registerinfo("Testplugin","Ein Testplugin!","1.0");  
20    plugin_registercmd("admin_write","write_entry",ACCESS_ALL,"Schreibe Eintrag");  
21    return PLUGIN_CONTINUE;  
22 }

Auch in diesem Beispiel muss wieder ein Befehl registriert werden (Zeile 20). Um den Quellcode transparenter zu machen, wurde der Nachbau der Funktion set_vaultnumdata in eine interne Funktion ausgelagert.
11 new_set_vaultnumdata(sEntry[],iContent){  
12    new sContent[MAX_DATA_LENGTH];  
13    snprintf(sContent,MAX_DATA_LENGTH,"%d",iContent);  
14    set_vaultdata(sEntry,sContent);  
15    return PLUGIN_CONTINUE;  
16 }

Die neue Funktion erwartet einen String (sEntry) und eine Zahl (iContent) als Eingabe. Die Zahl iContent wird über die Funktion „snprintf“ in einen String umgewandelt. Man kann selbstverständlich auch numtostr verwenden. Anschließend wird mit set_vaultdata der Variablenname (sEntry) und sein Wert (sContent) in die vault.ini geschrieben. Pro forma wurde ein PLUGIN_CONTINUE als Rückgabewert angegeben.

Es ist zu beachten, dass die Funktion nicht öffentlich ist. Sie hat kein „public“ vorangestellt. Dies ist nicht notwendig, da sie ein integraler Bestandteil des Plugins ist, und nur von diesem selbst aufgerufen wird.

Die neue Funktion „new_set_vaultnumdata“ wird aus „write_entry“ aufgerufen.
6 public write_entry(HLCommand,HLData,HLUserName,UserIndex) {  
7    new_set_vaultnumdata("TEST_ENTRY",random(9));  
8    return PLUGIN_HANDLED;  
9 }

Als Eintrag wurde „TEST_ENTRY“ verwendet und eine weitere Funktion (random) direkt eingebunden, die eine Zahl zwischen 0 und 9 ausgibt. Die direkte Einbindung funktioniert bei allen Funktionen. Da Small aber nur Zahlen als direkten Rückgabewert verwendet, können auf diese Art keine Strings eingebunden werden. Strings die übergeben wurden, sind jedoch automatisch referenziert, d.h. Änderungen in der Child-Funktion werden automatisch an die Parent-Funktion weitergeleitet. Bei Zahlen muss ein kaufmännisches Und voranstellt werden.

new_set_vaultnumdata(sEntry[],&iContent){

8.8.8  LogD verwenden

In diesem Abschnitt soll beschrieben werden, wie die Admin Mod Events durch weitere ergänzt werden können. Dazu ist das Metamod-Plugin LogD notwendig. Dieses Plugin erkennt Damages in Counter-Strike und schreibt sie in den Chat.
1 #include <core>  
2 #include <string>  
3 #include <admin>  
4 #include <adminlib>  
5  
6 #define ACCESS_CONSOLE 131072  
7 #define MNL 33  
8  
9 public damages(HLCommand,HLData,HLUserName,UserIndex) {  
10    new sData[MAX_DATA_LENGTH];  
11    new sA[MNL];  
12    new sV[MNL];  
13    new sW[MNL];  
14    new sD[MNL];  
15  
16    convert_string(HLData,sData,MAX_DATA_LENGTH);  
17    strsep(sData," ",sA,MNL,sV,MNL,sW,MNL,sD,MNL,sData,MAX_DATA_LENGTH);  
18    strsep(sData,"#",sData,MAX_DATA_LENGTH,sD,MNL);  
19  
20    playerinfo(strtonum(sA),sA,MNL);  
21    playerinfo(strtonum(sV),sV,MNL);  
22  
23    snprintf(sData,MAX_DATA_LENGTH,"%s traf %s mit %s (-%s hp)",sA,sV,sW,sD);  
24    say(sData);  
25  
26    return PLUGIN_HANDLED;  
27 }  
28  
29 public plugin_init() {  
30    plugin_registerinfo("Testplugin","Ein Testplugin!","1.0");  
31    plugin_registercmd("test_damages","damages",ACCESS_CONSOLE);  
32  
33    exec("logd_reg 58 admin_command test_damages",1);  
34    return PLUGIN_CONTINUE;  
35 }

Das sieht im ersten Moment etwas komplexer aus. Die eigentliche Funktionsweise lässt sich aber schon mittels der plugin_init erklären.
29 public plugin_init() {  
30    plugin_registerinfo("Testplugin","Ein Testplugin!","1.0");  
31    plugin_registercmd("test_damages","damages",ACCESS_CONSOLE);  
32  
33    exec("logd_reg 58 admin_command test_damages",1);  
34    return PLUGIN_CONTINUE;  
35 }

In Zeile 33 wird ein Serverbefehl abgesetzt. LogD wird mitgeteilt, dass es bei Event 58 (Damages) den Befehl „admin_command test_damages“ ausführen soll. Die „1“ bei der exec sagt lediglich aus, dass die Ausführung der Eventregistrierung mitgelogged wird. Weitere LogD-Events werden im Abschnitt 8.13 vorgestellt.

Damit Admin Mod auch auf den Serverbefehl reagiert, muss der Befehl „test_damages“ bei Admin Mod registriert werden. Der Access Level „ACCESS_CONSOLE“ wurde bewusst über die üblichen Access Level gesetzt (Zeile 6), da kein User diesen Befehl manuell ausführen können darf. Aus dem gleichen Grund wurde auch der Hilfetext weggelassen.

Zusammengefasst wird auf diese Art beim Zufügen von Schaden automatisch die Funktion „damages“ ausgeführt.

Zwei Besonderheiten sind noch in diesem Plugin zu finden.
6 #define ACCESS_CONSOLE 131072  
7 #define MNL 33

Es wird wie beschrieben ein neuer Access Level definiert. Alle Befehle, die von der Serverconsole ausgeführt werden (z.B. über RCon oder anderen Plugins), haben alle theoretischen Rechte. Normalerweise hat kein User den Access Level 131072. Damit wird sichergestellt, dass kein User einen Pseudoevent absetzen kann. Allerdings ist ein solcher Access Level nicht in der admin.inc definiert, so dass man dies selbst durchführen muss.

Der zweite Eintrag ist ein Alias für MAX_NAME_LENGTH, der wegen Darstellungsgründen für dieses Tutorial eingesetzt werden musste. Anderenfalls wäre die Zeile 17 zu lang geraten. Das ist also normalerweise nicht notwendig.

Die Funktion „damages“ nimmt letztlich den von LogD gelieferten String auseinander und setzt ihn neu zusammen.
9 public damages(HLCommand,HLData,HLUserName,UserIndex) {  
10    new sData[MAX_DATA_LENGTH];  
11    new sA[MNL];  
12    new sV[MNL];  
13    new sW[MNL];  
14    new sD[MNL];  
15  
16    convert_string(HLData,sData,MAX_DATA_LENGTH);  
17    strsep(sData," ",sA,MNL,sV,MNL,sW,MNL,sD,MNL,sData,MAX_DATA_LENGTH);  
18    strsep(sD,"#",sData,MAX_DATA_LENGTH,sD,MNL);  
19  
20    playerinfo(strtonum(sA),sA,MNL);  
21    playerinfo(strtonum(sV),sV,MNL);  
22  
23    snprintf(sData,MAX_DATA_LENGTH,"%s traf %s mit %s (-%s hp)",sA,sV,sW,sD);  
24    say(sData);  
25  
26    return PLUGIN_HANDLED;  
27 }

Für Damages sieht der String beispielhaft so aus:

3 1 p228 damage#28 damage_armor#12 health#72 armor#34.

Der String beginnt mit dem Userindex des Angreifers, gefolgt von dem des Opfers und der genutzten Waffe. Anschließend kommt der Lebensschaden, der Rüstungsschaden, die verbleibenden Lebenspunkte und die verbleibenden Rüstungspunkte des Opfers. Option und Wert sind hier durch Hashes (#) getrennt. Für die Ausgabe werden in diesem Fall nur die ersten vier Werte benötigt.

Zunächst wird der String an den ersten 4 Leerzeichen getrennt (Zeile 17). sData wird hier als Abfalleimer wiederverwendet (der Restsring wird nicht benötigt). Anschließend wird sD am Hash getrennt (Zeile 18). Auch hier ist sData wieder Abfalleimer verwendet. Auf diese Weise spart man sich Speicher, da keine zusätzlichen Variablen definiert werden müssen.

Aus den Userindizes sollen nun Namen ermittelt werden (playerinfo). Dazu müssen die Strings aber zuvor in Zahlen umgewandelt werden strtonum.

Der String wird dann in Zeile 23 neu zusammengesetzt und könnte dann mit obigen LogD String folgendermaßen aussehen:

Player(2) traf Player mit p228 (-28 hp)

Dieser Text wird abschließend in den Chat geschrieben.

8.8.9  Menüs nutzen

Die Verwendung von Menüs muss unter Admin Mod als höhere Programmierkunst bezeichnet werden. Es gibt diverse Fallstricke, die zu beachten sind. Gerade komplexe Menüstrukturen bedingen ein hohes Abstraktionsvermögen. Auch kann man mit anderen Menüs kollidieren (auch die von Half-Life; z.B. Teamauswahl oder Waffenkauf). Nicht jedes Plugin benötigt ein Menü. Man sollte sich genau überlegen, ob man eines verwenden möchte. Üblicherweise verdoppelt sich der Code. Außerdem muss der Serveradmin die Variable amv_enable_beta um „menu1“ ergänzt haben.

Nachdem genügend Angst gesäht wurde, soll nun ein Beispiel folgen, dass eine simple Verwendung des Menüs demonstrieren soll. Dem Spieler soll nach Eingabe von „admin_test“ in der Console ein Menü präsentiert werden, das ihn auswählen lässt, ob er einen Maprestart nach 10, 5 oder 2 Sekunden durchführen möchte. Als letzte Auswahlmöglichkeit kann er das Menü auch einfach schließen.

1 #include <core>  
2 #include <console>  
3 #include <string>  
4 #include <plugin>  
5 #include <admin>  
6 #include <adminlib>  
7  
8 new giMenu[MAX_PLAYERS];  
9  
10 public test(HLCommand,HLData,HLUsername,UserIndex) {  
11    new sUser[MAX_NAME_LENGTH];  
12    convert_string(HLUsername,sUser,MAX_NAME_LENGTH);  
13    new sMenu[MAX_DATA_LENGTH]="sv_restart?:^n1. 10s^n2. 5s^n3. 2s^n8. Close";  
14    giMenu[UserIndex]=1;  
15    menu(sUser,sMenu,135);  
16    return PLUGIN_HANDLED;  
17 }  
18  
19 public menuselect(HLCommand,HLData,HLUserName,UserIndex){  
20    new sOption[MAX_DATA_LENGTH];  
21    new iOption;  
22    if(giMenu[UserIndex]){  
23       convert_string(HLData,sOption,MAX_DATA_LENGTH);  
24       iOption=strtonum(sOption);  
25       switch(iOption){  
26          case 1:{  
27             setstrvar("sv_restart","10");  
28          }  
29          case 2:{  
30             setstrvar("sv_restart","5");  
31          }  
32          case 3:{  
33             setstrvar("sv_restart","2");  
34          }  
35       }  
36       giMenu[UserIndex]=0;  
37       return PLUGIN_HANDLED;  
38    }  
39    return PLUGIN_CONTINUE;  
40 }  
41  
42 public plugin_disconnect(HLUserName,UserIndex){  
43    giMenu[UserIndex]=0;  
44    return PLUGIN_CONTINUE;  
45 }  
46  
47 public plugin_connect(HLUserName,HLIP, UserIndex) {  
48    giMenu[UserIndex]=0;  
49    return PLUGIN_CONTINUE;  
50 }  
51  
52 public plugin_init() {  
53    plugin_registerinfo("Test","Testplugin","1.0");  
54    plugin_registercmd("admin_test","test",ACCESS_CONFIG,"Ein Menue");  
55    plugin_registercmd("menuselect","menuselect",ACCESS_ALL);  
56  
57    return PLUGIN_CONTINUE;  
58 }

Zunächst soll wieder mit der plugin_init begonnen werden:
52 public plugin_init() {  
53    plugin_registerinfo("Test","Testplugin","1.0");  
54    plugin_registercmd("admin_test","test",ACCESS_CONFIG,"Ein Menue");  
55    plugin_registercmd("menuselect","menuselect",ACCESS_ALL);  
56  
57    return PLUGIN_CONTINUE;  
58 }

Es werden zwei Befehle registriert. Zum einen ist das der Befehl „admin_test“, der die Menüauswahl öffnet. Damit nicht jeder ihn ausführen kann, wurde er nur demjenigen zugreifbar gemacht, der Accesslevel 512 hat. Zum anderen wird der Befehl „menuselect“ registriert, der für alle Menüauswahlen in Half-Life verwendet wird. Er darf nicht eingeschränkt werden (ACCESS_ALL), da ansonsten selbst das Team nicht auswählbar ist. Beide Registrierungen verweisen auf entsprechende Funktionen (test und menuselect).
10 public test(HLCommand,HLData,HLUsername,UserIndex) {  
11    new sUser[MAX_NAME_LENGTH];  
12    convert_string(HLUsername,sUser,MAX_NAME_LENGTH);  
13    new sMenu[MAX_DATA_LENGTH]="sv_restart?:^n1. 10s^n2. 5s^n3. 2s^n8. Close";  
14    giMenu[UserIndex]=1;  
15    menu(sUser,sMenu,135);  
16    return PLUGIN_HANDLED;  
17 }

Es wird der Username vom HL Format ins Small Format konvertiert. Anschließend wird der Menütext mit einigen Umbrüchen erstellt, damit die Frage und die Optionen jeweils in einer eigenen Zeile stehen. In Zeile 14 wird eine Zelle des globalen Feldes giMenu auf 1 gesetzt. Der Zellenindex wird durch den Userindex definiert. Auf diese Weise kann festgehalten werden, ob sich der jeweilige Spieler gerade in einem Menü befindet. Das Feld giMenu wurde in Zeile 8 definiert und ist in allen Funktionen gültig.
8 new giMenu[MAX_PLAYERS];

Schlussendlich wird nun beim aufrufenden Spieler ein Menü mit dem angegebenen Text ausgegeben (Zeile 15, menu). Es wird dabei auch festgelegt, welche Menüauswahlen erlaubt sind. Bei den Optionen 1, 2, 3 und 8 ergibt sich:

21-1 + 22-1 + 23-1 + 28-1 = 1 + 2 + 4 + 128 = 135

Genaueres darüber ist der Funktionsbeschreibung von menu zu entnehmen. Andere Auswahlmöglichkeiten sind geblockt, während das Menü geöffnet ist.

Um die Menüauswahl auszuwerten, wird die Funktion menuselect benötigt.
19 public menuselect(HLCommand,HLData,HLUserName,UserIndex){  
20    new sOption[MAX_DATA_LENGTH];  
21    new iOption;  
22    if(giMenu[UserIndex]){  
23       convert_string(HLData,sOption,MAX_DATA_LENGTH);  
24       iOption=strtonum(sOption);  
25       switch(iOption){  
26          case 1:{  
27             setstrvar("sv_restart","10");  
28          }  
29          case 2:{  
30             setstrvar("sv_restart","5");  
31          }  
32          case 3:{  
33             setstrvar("sv_restart","2");  
34          }  
35       }  
36       giMenu[UserIndex]=0;  
37       return PLUGIN_HANDLED;  
38    }  
39    return PLUGIN_CONTINUE;  
40 }

Wichtig zu beachten ist, dass diese Funktion durch alle Auswahlen ausgeführt wird. Daher sollte der Code minimiert werden, der ausgeführt wird, wenn das eigene Plugin nicht gemeint ist. Daher wird zunächst überprüft, ob die die Zelle des Feldes giMenu auf 1 gesetzt ist (Zeile 22), der Spieler sich also im eigenen Menü befindet. Anderenfalls wird der menuselect Befehl durchgelassen. Hier ist auch das PLUGIN_CONTINUE am Ende der Funktion wichtig. Ein PLUGIN_HANDLED würde die weitere Ausführung des menuselect Befehls unterbinden.

Nachdem die Überprüfung positiv verlaufen ist, wird die übergebene Option HLData in sOption konvertiert und anschließend in eine Ganzzahl umgewandelt. Die Switch-Verzweigung verweist auf setstrvar Funktionen mit unterschiedlichen Werten für die Servervariable sv_restart wie sie im Menütext angegeben waren. Wenn diese gesetzt werden, erfolgt ein Restart nach der angegeben Anzahl an Sekunden. Entspricht iOption keiner Option, wird dafür kein Code ausgeführt. Das Menü wird aber nach jedem menuselect automatisch geschlossen. Die Angabe von der Option 8 schließt also nur das Menü.

Dem Feld giMenu muss noch mitgeteilt werden, dass der Spieler das Menü verlassen hat. Daher wird die dem Spieler zugewiesene Zelle auf 0 gesetzt (Zeile 36). Die weitere Ausführung von menuselect wird mit PLUGIN_HANDLED unterbunden, da das Menü abgearbeitet wurde.

Es gibt Fälle, wo der Spieler das Spiel bei offenem Menü beendet. Es verbleibt eine 1 im Feld, die derjenige erbt, der in den gleichen Slot kommt.
42 public plugin_disconnect(HLUserName,UserIndex){  
43    giMenu[UserIndex]=0;  
44    return PLUGIN_CONTINUE;  
45 }  
46  
47 public plugin_connect(HLUserName,HLIP, UserIndex) {  
48    giMenu[UserIndex]=0;  
49    return PLUGIN_CONTINUE;  
50 }

Aus diesem Grunde ist es notwendig, plugin_disconnect zu definieren, damit bei jedem Disconnect die Zelle auf 0 gesetzt wird. Zur Sicherheit wird dies auch überlicherweise für plugin_connect wiederholt.

Damit erhält man ein funktionsfähiges Menü. Es lässt sich das Prinzip aber auch beliebig verkomplizieren. Untermenüs, zweite Seiten, Eingaben im Chat als Optionsparameter sind nur einige wenige Beispiele, wie das Menüprinzip schnell große Ausmaße annimmt. Menüs sind aber ein i-Tüpfelchen auf jedem Plugin, das viel Spielerbeteiligung benötigt.

8.9  Includes

Die Includes beinhalten alle von Admin Mod zur Verfügung gestellten Funktion, aber auch solche, die erst aus anderen Funktion gebildet werden (z.B. in adminlib.inc oder math.inc. Die Includes befinden sich im Verzeichnis „scripting/include“. Man kann sie wie auch schon den Quellcode der Admin Mod Plugins mit jedem handelsüblichen Editor öffnen.

Um Includes zu nutzen, müssen sie mit der include-Direktive in das Plugin eingebunden werden.

Eine kurze Beschreibung zu den einzelnen Funktionen eines Includes kann manchmal auch als Kommentar dem Quellcode der Includes selber entnommen werden. Die Beschreibung ist jedoch relativ kurz.

Im Weiteren werden die einzelnen Includes kurz vorgestellt und die zugehörigen Funktionen aufgelistet. Die Beschreibung und Beispiele zu einzelnen Funktionen sind der Funktionsreferenz zu entnehmen.

8.9.1  admin.inc

Die admin.inc ist das Basis-Include, welches für alle Plugins benötigt wird. Dies liegt schon allein daran, dass sie das Event plugin_init zur Verfügung stellt. Aber auch andere essentielle Events und Funktionen werden hier definiert.

Weiterhin sind diverse Konstanten an dieser Stelle definiert (z.B. Access Level). Auch augewählte Enums sind dort zu finden.

Es ist daher notwendig das Include in das eigene Plugin einzubinden. Eine Liste der zur Verfügung gestellten Events und Funktionen ist der anschließenden Tabelle zu entnehmen.

8.9.2  adminlib.inc

Das adminlib Include beinhaltet Funktionen, die nicht von Admin Mod selber zur Verfügung gestellt werden. Vielmehr liegen diese Funktionen als Small-Code vor, der wiederum auf den Basisfunktionen und -operatoren aufbaut. Die Admin Mod Programmierer banden diese Funktionen ein, da sie häufig benötigt wurden jedoch nicht nativ über Admin Mod zur Verfügung standen. Sie sind im Laufe der Zeit auch nicht in Admin Mod übernommen worden.

Man wird dieses Include nicht immer benötigen, aber es ist zu empfehlen das Include stets einzubinden. Funktionen wie numtostr oder max werden sehr häufig verwendet.

8.9.3  console.inc

Das Include console ist in Admin Mod mehr oder weniger nutzlos. Die zugehörigen Funktionen interagieren mit Betriebsystemconsole. Es werden Keyboard-Eingaben gelesen und Text ausgegeben. Unter Umständen lassen sich diese Funktionen zu Debuggingzwecken nutzen.

Es ist nicht nötig dieses Include einzubinden.

8.9.4  core.inc

Das core Include beinhaltet Funktionen, die direkt (also nicht von Admin Mod) von Small zur Verfügung gestellt werden.

Genutzt werden die Funktionen nur selten (z.B. clamp oder random), aber zur Sicherheit sollte man auch dieses Include einbinden.

8.9.5  fixed.inc

Das Include fixed stellt die Grundrechenarten für Festkommazahlen und einige Konvertierungsfunktionen zur Verfügung.

Das Include wird nur dann benötigt, wenn man mit Festkommazahlen arbeiten oder Funktionen aus dem math Include nutzen möchte.

8.9.6  math.inc

Die Nutzung von Festkommazahlen ist eigentlich nur sinnvoll, wenn man auf Funktionen zurückgreifen will, die über die einfachen Grundrechenarten hinausgehen. Mit Ganzzahlen (Integer) ist man auf die Grundrechenarten beschränkt.

Da eine native Implementierung der Funktionen höherer Mathematik in Admin Mod nicht in Aussicht gestellt wurde, entstand dieses Include, welches die Funktionen aus den Grundrechenarten nachbildet. Das Include ist mehr oder weniger ein Proof of Concept, hatte aber auch das Ziel z.B. Statistiken oder Distanzrechnungen in Admin Mod zu ermöglichen. Bis dato ist kein Plugin bekannt, das dieses Include nutzt. Die Genauigkeit der Berechnungen ist ausreichend genau bis mindestens zur zweiten Nachkommastelle (je nach Funktion).

Wenn mit Festkommazahlen gerechnet werden soll, ist dieses Include wahrscheinlich notwendig. Dann muss aber auch das fixed Include eingebunden werden.

8.9.7  plugin.inc

Das Include plugin hat nur zwei selten verwendete Funktionen.

In der Regel muss dieses Include nicht eingebunden werden.

8.9.8  string.inc

Das string Include beschäftigt sich mit Stringauswertungen und -manipulationen. Besonders Funktionen wie snprintf machen das Include fast unentbehrlich.

Es ist sinnvoll dieses Include standardmäßig in das eigene Plugin aufzunehmen.

8.10  Funktionsreferenz

8.10.1  access

access( iAccess, sName[]= “” );

iAccess
Typ: Integer (0 - 2147483647)

sName[]= “”
Typ: String (33)

Mit der Funktion kann man den Accesslevel der Person abfragen, die entweder direkt die Funktion im Plugin aufgerufen hat (sName braucht dann nicht angegegeben werden) oder der Person, die man mit sName angibt. Man erhält einen Integer mit Wert 1 zurück, wenn die Person den Rechtelevel iAccess besitzt und eine 0, wenn die Person diesen Rechtelevel nicht besitzt.

 
Beispiel aus plugin_base (Funktion: admin_chat):
110    for(i=1; i<=maxplayers; i++) {  
111       strinit(Name);  
112       if(playerinfo(i,Name,MAX_NAME_LENGTH)==1) {  
113          if(access(ACCESS_CHAT,Name)!=0) {  
114             messageex(Name, Text, print_chat);  
115          }  
116       }  
117    }

Es werden alle Playerslots abgefragt, ob ein Spieler vorhanden ist. Wenn ja, wird überprüft, ob er den Rechtelevel (ACCESS_CHAT = 64) hat, um Nachrichten, die über admin_chat abgesetzt wurden, lesen zu dürfen. Erst wenn Admin Mod dies auch bestätigt, wird die Nachricht an den Spieler ausgegeben.

Gehört zu: admin.inc

Siehe auch: auth, check_auth

8.10.2  auth

auth( sName[]= “” );

sName[]= “”
Typ: String (33)

Mit der Funktion auth kann man abfragen, ob eine Person (sName) als Admin authentifiziert wurde (d.h. in der users.ini steht und sich angemeldet hat). Es spielt dabei keine Rolle, welchen Access Level die Person hat. Die Funktion wird selten für eine vereinfachte Administratorüberprüfung genutzt.

Liefert als Integerwert 1 zurück, wenn die Personen authentifiziert wurde. Andernfalls wird eine 0 zurückgeliefert.

 
Beispiel aus plugin_bk_hltvannounce2 (Funktion: admin_hltv_connect):
185       if(auth(User)){  
186          hltvconnect(Data);  
187       }

Erst wenn der Spieler (User), der den Befehl zum Umleiten eines anderen Spielers (Data) abgesetzt hat, nachweisen kann, dass er in der plugin.ini steht, d.h. authentifiziert ist, wird dieser Spieler auch auf den HLTV umgeleitet.

Gehört zu: admin.inc

Siehe auch: access, check_auth

8.10.3  ban

ban( sPlayer[], iTime, bBanBy = bBanByID );

sPlayer[]
Typ: String (33)

iTime
Typ: Integer (0 - 2147483647)

bBanBy = bBanByID
Typ: Enum (0=bBanByID; bBanByIP, bBanBoth)

Die Funktion bannt eine Person unter sPlayer angegebene Person. sPlayer kann der Spielername, die SessionID oder die Steam ID sein. iTime ist der Integerwert in Minuten, wie lange der Spieler gebannt werden soll. Der Wert 0 bedeutet, dass die Person permanent vom Server verbannt wird. Wenn als bBanBy die bBanByID angegeben wird, wird die Steam ID gebannt. Bei LAN-Servern, wo es keine eindeutige Steam ID gibt, muss man bBanByIP verwenden. Dies bestimmt auch, in welche Banliste der Eintrag eingefügt wird. Entweder banned.cfg oder listip.cfg. Der Spieler wird zusätzlich sofort vom Server gekickt.

 
Beispiel aus plugin_base (Funktion: admin_ban):
71       if(check_immunity(ban_user)==1) {  
72          snprintf(Text, MAX_TEXT_LENGTH, "You can’t ban ’%s’.", TargetName);  
73          messageex(User,Text,print_chat);  
74       } else {  
75          ban(ban_user,BanTime,iBanType);  
76       }

Zunächst wird überprüft, ob der zu bannende Spieler evtl. immun gegen Aktionen ihn betreffend ist. Wenn dies der Fall ist, weist eine mehr oder weniger freundliche Meldung den aufrufenden Spieler auf seine nutzlose Aktion hin. Anderenfalls wird der Bann anhand der ID/IP für die angegebene Zeit ausgeführt und der Spieler vom Server geworfen.

Gehört zu: admin.inc

8.10.4  censor_words

censor_words( sString[] );

sString[]
Typ: String (100)

Die zensierten Wörter werden in der Datei angegeben, die in der adminmod.cfg mittels words_file definiert wird. Man kann mit censor_words einen Text untersuchen, ob sich darin ein zensiertes Wort befindet. Ist eines vorhanden, werden die Buchstaben durch „*“ ersetzt.

 
Beispiel aus plugin_retribution (Funktion: Handle_say):
643       if (check_immunity(User)==0) {  
644          messageex(User, "Swearing not allowed on this server", print_center);  
645  
646          new SwearMsg[MAX_TEXT_LENGTH];  
647          censor_words(Data);  
648       new i;  
649       new c=strlen(Data);  
650       for (i=0;i<c;i++) {  
651         if (Data[i] == ’"’) {  
652           Data[i]=’^’’;  
653         }  
654       }  
655  
656       snprintf(SwearMsg, MAX_TEXT_LENGTH, "%s ^"%s^"", Command, Data);  
657       execclient(User, SwearMsg);  
658       return PLUGIN_HANDLED;  
659     }

Nach dem Check, dass der schreibende Spieler keine Immunitität besitzt, gibt es einen Hinweis in der Mitte des Bildschirms, dass Fluchen auf dem Server nicht erlaubt ist. Danach wird das Geschriebene zensiert, die Anführungszeichen ausgetauscht und die bereinigte Chat-Nachricht nochmals vom Spieler abgeschickt (execclient). Um zu verhindern, dass die unzensierte Nachricht versandt wird, muss die weitere Abarbeitung der Nachricht mittels PLUGIN_HANDLED unterbunden werden.

Gehört zu: admin.inc

Siehe auch: check_words

8.10.5  centersay

centersay( sText[], iTime, iRed, iGreen, iBlue );

sText[]
Typ: String (500) (max. Zeilenlänge: 80)

iTime
Typ: Integer (0 - 2147483647)

iRed
Typ: Integer (0 - 255)

iGreen
Typ: Integer (0 - 255)

iBlue
Typ: Integer (0 - 255)

Mit dieser Funktion kann man eine bunte Nachricht (sText) für alle Spieler in der Mitte des Bildschirms produzieren. iTime ist die Einblendzeit in Sekunden. iRed ist der Rotanteil, iGreen der Grünanteil und iBlue der Blauanteil in der Nachricht. Die Funktion centersayex ermöglicht die gleiche Funktionalität für einzelne Spieler.

 
Beispiel aus plugin_base (Funktion: admin_csay):
136    if (streq(Color,"red")==1) {  
137       centersay(Message,10,250,10,10);

Wenn der Text Color gleich „red“ ist, wird die Nachricht in Message für 10 Sekunden in einen hellem Rot dargestellt. Es ist zu beachten, dass eine Zeile maximal 80 Zeichen lang sein darf. Mit Zeilenumbrüchen sind bis zu 500 Zeichen möglich.

Gehört zu: admin.inc

Siehe auch: centersayex, messageex, rainbow, typesay

8.10.6  centersayex

centersayex( sUser[], sText[], iTime, iRed, iGreen, iBlue );

sUser[]
Typ: String (33)

sText[]
Typ: String (500) (max. Zeilenlänge: 80)

iTime
Typ: Integer (0 - 2147483647)

iRed
Typ: Integer (0 - 255)

iGreen
Typ: Integer (0 - 255)

iBlue
Typ: Integer (0 - 255)

Mit dieser Funktion kann man eine bunte Nachricht (sText) für einzelne Spieler in der Mitte des Bildschirms produzieren. iTime ist die Einblendzeit in Sekunden. iRed ist der Rotanteil, iGreen der Grünanteil und iBlue der Blauanteil in der Nachricht. Die Funktion centersay ermöglicht die gleiche Funktionalität für alle Spieler.

 
Beispiel aus plugin_cw_creator33 (Funktion: kickplayers):
256             if(Team!=TEAM_PROXY){  
257                get_vaultdata("CWC_PASS",Text,MAX_TEXT_LENGTH);  
258                snprintf(Text,MAX_TEXT_LENGTH,"password %s",Text);  
259                execclient(Target,Text);  
260                centersayex(Target,sMessage,10,68,255,125);  
261             }

Der Auszug stammt aus einer For-Schleife über alle Spieler. Der Server soll für einen Clanwar geschlossen werden. Um Spielern auf einem HLTV nicht das Passwort zu präsentieren, wird das Passwort nur echten Spielern als Centersay gezeigt. Vorab wurde das neue Passwort aus der vault.ini geladen und bei den Spielern gesetzt.

Gehört zu: admin.inc

Siehe auch: centersay, messageex

8.10.7  changelevel

changelevel( sMap[], iIntermissionPause = 0 );

sMap[]
Typ: String (100)

iIntermissionPause = 0
Typ: Integer (0 - 2147483647)

Die Funktion lässt den Server zur angegebenen Map (sMap) wechseln. iIntermissionPause ist ein Integerwert in Sekunden, wie lange gewartet werden soll, bis die Map gewechselt wird.

 
Beispiel aus plugin_base (Funktion: admin_map):
307    if (valid_map(Data)==1) {  
308       say_command(User,Command,Data);  
309       changelevel(Data, 4);

Wenn es sich bei Data um eine gültige Map handelt, wird dies öffentlich gemacht und nach 4 Sekunden ein Mapwechsel durchgeführt.

Gehört zu: admin.inc

Siehe auch: ChangeMap

8.10.8  ChangeMap

ChangeMap( Timer, Repeat, HLUser, HLParam );

Bei dieser Funktion handelt es sich ein Timer-Event, das früher statt der direkten Verwendung von changelevel genutzt wurde. Inzwischen ist sie nur noch aus Kompatibilitätsgründen vorhanden.

Gehört zu: adminlib.inc

Siehe auch: changelevel

8.10.9  check_auth

check_auth( iAuthLevel );

iAuthLevel
Typ: Integer (0 - 2147483647)

Die Funktion liefert eine 1 zurück, wenn die Person, die diese Funktion aufgerufen hat, den Accesslevel iAuthlevel besitzt, andernfalls eine 0. Mit der Funktion access können auch die Rechte anderer ermittelt werden.

 
Beispiel aus plugin_base (Funktion: admin_rcon):
435    if (check_auth(ACCESS_RCON)==0) {  
436       selfmessage("Laf. Silly bear.");  
437       return PLUGIN_HANDLED;  
438    }

Um zu verhindern, dass jemand auf die Idee kommt aus der Serverconsole den Befehl admin_rcon aufzurufen, was möglich aber unsinnig ist, wurde eine Abfangroutine implementiert. Nur wenn der User den Access Level 65536 (ACCESS_RCON) besitzt, wird der RCon-Befehl über Admin Mod abgesetzt. Anderenfalls wird man etwas unhöflich auf das unsinnige Ansinnen hingewiesen.

Gehört zu: adminlib.inc

Siehe auch: access, auth, check_immunity

8.10.10  check_immunity

check_immunity( sTarget[] );

sTarget[]
Typ: String (33)

Die Funktion überprüft, ob der Spieler (sTarget) den Rechtelevel für Immunität (4096) besitzt. Dieses und andere Rechtelevel lassen sich auch mit der Funktion access überprüfen.

 
Beispiel aus plugin_base (Funktion: admin_ban):
71       if(check_immunity(ban_user)==1) {  
72          snprintf(Text, MAX_TEXT_LENGTH, "Laf. You can’t ban ’%s’.", TargetName);  
73          messageex(User,Text,print_chat);  
74       } else {  
75          ban(ban_user,BanTime,iBanType);  
76       }

Zunächst wird überprüft, ob der zu bannende Spieler immun gegen Aktionen ihn betreffend ist. Je nach Ausfallen der Überprüfung wird entweder eine Meldung über den Fehlschlag des Banns oder der Bann selbst abgesetzt.

Gehört zu: adminlib.inc

Siehe auch: access, auth, check_auth

8.10.11  check_param

check_param( sParam[] );

sParam[]
Typ: String (100)

Die Funktion überprüft, ob der String sParam gleich dem String „on“ ist. Bei „on“ gibt die Funktion 1 anderenfalls 0 zurück.

 
Beispiel aus plugin_fun (Funktion: admin_fun):
203    if(check_param(Data)==1) {  
204       execute_command(User,Command,"admin_fun_mode","1");  
205    } else {  
206       execute_command(User,Command,"admin_fun_mode","0");  
207       KillGlow();  
208    }

Wenn der Befehl admin_fun abgesetzt wurde, wird überprüft, ob als Option „on“ übergeben wurde. Wenn dies der Fall ist, wird der Fun Mode aktiviert, anderenfalls deaktiviert und alle aktiven Glows abgeschaltet.

Gehört zu: adminlib.inc

8.10.12  check_user

check_user( sPlayer[] );

sPlayer[]
Typ: String (33)

Überprüft, ob sich ein Spieler mit dem Namen (auch Teil), ID oder IP (sPlayer) auf dem Server befindet. Ein positive Überprüfung gibt eine 1 eine negative eine 0 zurück. Die Funktion wird gern für die Bot oder HLTV-Erkennung eingesetzt.

 
Beispiel aus plugin_base (Funktion: admin_ban):
68    if (check_user(ban_user)==1) {  
69       get_username(ban_user,TargetName,MAX_NAME_LENGTH);

Es wird überprüft, ob ein entsprechender Spieler auf dem Server existiert. In dem Fall wird über die Funktion get_username aus der ID oder IP ein Name gemacht oder zu einem Namen ergänzt.

Gehört zu: admin.inc

8.10.13  check_words

check_words( sData[] );

sData[]
Typ: String (100)

Die zensierten Wörter werden in der Datei angegeben, die in der adminmod.cfg mittels words_file definiert wird. Man kann mit check_words einen Text untersuchen, ob sich darin ein zensiertes Wort befindet. Ist eines vorhanden, wird eine 0 zurückgegeben.

 
Beispiel aus plugin_retribution (Funktion: Handle_say):
726    if(check_words(NewName)==0) {  
727       execclient(OldName,"name OldName");  
728       return PLUGIN_HANDLED;  
729    }

Wenn der neue Spielername ein verbotenes Wort enthält, wird veranlasst, dass er seinen Namen wieder zurücksetzt.

Gehört zu: admin.inc

Siehe auch: censor_words

8.10.14  clamp

clamp( value, min=cellmin, max=cellmax );

value
Typ: Integer (-2147483648 - 2147483647)

min=cellmin
Typ: Integer (-2147483648 - 2147483647)

max=cellmax
Typ: Integer (-2147483648 - 2147483647)

Manchmal ist es gewünscht, dass sich ein Zahl (value) innerhalb eines bestimmten Bereichs befindet. Liegt sie oberhalb des Bereichs wird sie durch die obere Bereichsgrenze (max) bzw. unterhalb durch die untere Bereichsgrenze (min) ersetzt.

 
Beispiel aus plugin_CS (Funktion: menuselect):
1512                     new Team;  
1513                     get_userTeam(UserName,Team);  
1514                     Team = clamp(Team,1,2) - 1;

Zunächst wird das Team des Spielers ermittelt. Anschließend wird zur Vermeidung einer Feldadressierung außerhalb des gültigen Bereichs (4 - AMX_ERR_BOUNDS) die möglichen Teams auf 1 und 2 begrenzt. Zur weiteren Bearbeitung werden die Teamnummern dekrementiert.

Gehört zu: core.inc

Sieh auch: f_max, f_min, max, min

8.10.15  consgreet

consgreet( sMessage[] );

sMessage[]
Typ: String (256)

Mit der consgreet Funktion kann man Nachrichten (sMessage) in der Konsole des Spielers anzeigen, der sich gerade mit dem Server verbindet (zum Lesen der Serverregeln etc.). Man kann mit der Funktion auch ein Textfile anzeigen lassen. Dann muss sMessage den Pfad und die Textdatei mit Endung txt enthalten.

Inzwischen wird die Console beim Connect nicht mehr angezeigt. Die Funktion ist daher als obsolet anzusehen.

 
Beispiel aus plugin_dale_consgreet4 (Funktion: plugin_connect):
186    if(fileexists("consgreet.txt")==1) {  
187    consgreet("================================================================");  
188    consgreet("------------------------Server Stuff--------------------------");  
189    consgreet("consgreet.txt");  
190    consgreet("");  
191    }

Zunächst wird überprüft, ob die Datei consgreet.txt existiert. Anschließend wird eine Überschrift generiert und der Inhalt der Datei consgreet.txt in die Console geschrieben. Eine Leerzeile schließt den Code ab.

Gehört zu: admin.inc

Siehe auch: messageex, selfmessage

8.10.16  convert_string

convert_string( HLString, sSmallString[], iMaxLength );

iHLString
Typ: String (variabel, theoretisch: 2147483647)

sSmallString[]
Typ: String (iMaxLength)

iMaxLength
Typ: Integer (variabel, theoretisch: 1 - 2147483647)

Admin Mod erhält von der Engine den HLString, der nicht direkt nutzbar ist. Daher muss der Inhalt mit convert_string in einen SmallString umgewandelt werden.

 
Beispiel aus plugin_base (Funktion: admin_ban):
45 public admin_ban(HLCommand,HLData,HLUserName,UserIndex) {  
46    new ban_user[MAX_DATA_LENGTH];  
47    new BanTime = 0;  
48    new iBanType = bBanByID;  
49    new Command[MAX_COMMAND_LENGTH];  
50    new Data[MAX_DATA_LENGTH];  
51    new strTime[MAX_NUMBER_LENGTH];  
52    new strType[MAX_NAME_LENGTH];  
53    new Text[MAX_TEXT_LENGTH];  
54    new TargetName[MAX_NAME_LENGTH];  
55    new User[MAX_NAME_LENGTH];  
56  
57    convert_string(HLCommand,Command,MAX_COMMAND_LENGTH);  
58    convert_string(HLData,Data,MAX_DATA_LENGTH);  
59    convert_string(HLUserName,User,MAX_NAME_LENGTH);

Nach einigen Variablendeklaration werden die übergebenen HL-Strings (HLCommand, HLData, HLUserName) zur weiteren Bearbeitung in einen Small-String umgewandelt. Dabei wird auf die maximale Stringlänge aus den Deklarationen Rücksicht genommen.

Gehört zu: admin.inc

8.10.17  currentmap

currentmap( sMap[], iMaxLength );

sMap[]
Typ: String (iMaxLength)

iMaxLength
Typ: Integer (variabel, theoretisch: 1 - 2147483647), praktisch: 33)

Mit der Funktion currentmap wird die aktuell laufende Map (sMap) zurückgegeben.

 
Beispiel aus plugin_chat (Funktion: SayCurrentMap):
43 SayCurrentMap() {  
44    new Text[MAX_TEXT_LENGTH];  
45    new CurrentMap[MAX_NAME_LENGTH];  
46  
47    currentmap(CurrentMap,MAX_NAME_LENGTH);  
48    snprintf(Text, MAX_TEXT_LENGTH, "The current map is: %s", CurrentMap);  
49    say(Text);  
50 }

Die derzeit auf dem Server gespielte Map wird ermittelt. Die maximale Stringlänge von 33 (MAX_NAME_LENGTH) sollte völlig ausreichend sein. Anschließend wird allen Spielern mitgeteilt, auf welcher Map sie gerade spielen.

Gehört zu: admin.inc

Siehe auch: nextmap

8.10.18  cvar_exists

cvar_exists( sCvar[] );

sMap[]
Typ: String (variabel, theoretisch: 1 - 2147483647, praktisch: 33)

Die Funktion dient der Überprüfung, ob eine bestimmte Servervariable existiert. U.U. kann man durch diese Funktion herausbekommen, welche HL-Modifikation läuft.

 
Beispiel aus plugin_CS (Funktion: GetVersion):
1550 GetVersion() {  
1551     if( cvar_exists("sv_region") ) {  
1552         return V15 + 1;  
1553     }  
1554     return V15;  
1555 }

In diesem Fall wird überprüft, ob die Variable „sv_region“ existiert. Diese wurde erst in der Counter-Strike Version 1.6 eingeführt. Da sich einiges im Handling zwischen CS 1.5 und CS 1.6 unterscheidet, müssen einige Funktionen für beide Versionen funktional bleiben. Mittels Verzweigungen auf Basis des Versionschecks kann diese Problematik bequem umschifft werden.

Gehört zu: admin.inc

Siehe auch: nextmap

8.10.19  deletefile

deletefile( sFilename[] );

sFilename[]
Typ: String (200)

Löscht die Datei (sFilename), wenn sie existiert. Relative Pfade vom Modverzeichnis aus sind erlaubt. Es muss file_access_write auf 1 gesetzt sein, damit die Funktion wirksam wird. Es ist nur möglich Dateien im Modverzeichnis oder darunter zu schreiben und zu löschen.

 
Beispiel aus plugin_bk_res5 (Funktion: admin_res_refresh):
184          if(fileexists(sMap)){  
185             deletefile(sMap);  
186          }

Zunächst wird überprüft, ob die Datei (sMap) überhaupt existiert. Erst bei einer positiven Überprüfung wird sie gelöscht.

8.10.20  deleteproperty

deleteproperty( id=0, const name[]=“”, value=cellmin );

id=0
Typ: Integer (-2147483648 - 2147483647)

const name[]=“”
Typ: String (variabel)

value=cellmin
Typ: Integer (-2147483648 - 2147483647)

Mit dieser Funktion kann eine so genannte Property bei gegebenem Schlüssel gelöscht werden. Es handelt sich dabei um eine Funktion, deren Benutzung unter Admin Mod vermieden werden sollte. Stattdessen wird empfohlen z.B. die Funktionen get_vaultdata oder set_vaultdata zurückzugreifen.

Mehr Informationen zum Thema sind im Abschnitt 8.14 nachzulesen.

 
Beispiel:
deleteproperty(2,“test_prop”);
deleteproperty(3,15);

Das erste Beispiel löscht die in ID 2 befindliche Property „test_prop“, während das zweite Beispiel die in ID 3 befindliche Property 15 löscht.

Gehört zu: core.inc

Siehe auch: existproperty, getproperty, setproperty

8.10.21  directmessage

directmessage( sMessage[], iUserID = -1, uid:tUidType =
uid:uid_SessionID );

sMessage[]
Typ: String (100)

iUserID = -1
Typ: Integer (-1 - 2147483647)

uid:tUidType = uid:uid_SessionID
Typ: Enum (0=uid_none, uid_invalid, uid_index, uid_SessionID, uid_wonID)

Die Nachricht sMessage kann direkt an den Spieler mit dem angegebenen Userindex bzw. der Session ID geschickt werden. Ob es sich um den Userindex oder um die Session ID handelt, muss mit „uid_index“ bzw. „uid_SessionID“ angegeben werden. Die weiteren Optionen „uid_none“, „uid_invalid“, „uid_wonID“ werden nicht (mehr) genutzt.

 
Beispiel aus plugin_base (Funktion: admin_dmsg):
179    switch( sType[0] ) {  
180    case ’i’:  
181       tType = uid_index;  
182    case ’s’:  
183       tType = uid_SessionID;  
184    case ’w’:  
185       tType = uid_wonID;  
186    default:  
187       tType = uid_invalid;  
188    }  // switch()  
189  
190  
191    strstripquotes(sMessage);  
192    directmessage( sMessage, iUid, tType );

Abhängig vom Buchstaben, der sich in der ersten Zelle von sType befindet, wird der UID Typ festgelegt. Die um Anführungszeichen befreite Nachricht (Zeile 191: strstripquotes) wird der ID (Session ID oder Userindex) geschickt.

Gehört zu: admin.inc

Siehe auch: centersayex, message, messageex, selfmessage

8.10.22  distance

distance( x1, x2, y1=0, y2=0, z1=0, z2=0 );

x1
Typ: Integer (-2147483648 - 2147483647)

x2
Typ: Integer (-2147483648 - 2147483647)

y1=0
Typ: Integer (-2147483648 - 2147483647)

y2=0
Typ: Integer (-2147483648 - 2147483647)

z1=0
Typ: Integer (-2147483648 - 2147483647)

z2=0
Typ: Integer (-2147483648 - 2147483647)

Die Funktion „distance“ berechnet die Entfernung zwischen zwei Punkten auf der Map.

Bei großen Entfernungen zwischen zwei Punkten, kann es zu Problemen kommen. Die Berechnung ermittelt die Summe der Quadrate der Abstände in x-, y- und z-Richtung. Sollte diese Summe größer als 2147483647 sein, kommt es zu einem Overflow, der zwar das Plugin nicht abstürzen lässt, aber falsche Ergebnisse liefert. Es wird daher empfohlen die Summe vorab abzuschätzen (z.B. sollte die Summe der Abstände 46340 nicht überschreiten). Man kann dann die Punkte durch einen festen Faktor teilen und ihn nach der Berechnung wieder aufschlagen.

 
Beispiel aus plugin_sdal_logd_hp506 (Funktion: get_user_distance):
487    get_userorigin(Attacker,ax,ay,az);  
488    get_userorigin(Victim,vx,vy,vz);  
489    g_PlayerEnemyDistance[iVID]= distance(ax,vx,ay,vy,az,vz);

Der Funktion „get_user_distance“ wird der Name des Siegers und des Verlierers des Duells und der Userindex des Verlierers übergeben. Mittels get_userorigin werden die Positionen der Spieler auf der Map ermittelt und der Abstand zwischen den Spielern in einer Zelle eines Feldes gespeichert.

Gehört zu: math.inc

Siehe auch: get_userorigin

8.10.23  exec

exec( sCommand[], bWriteLogEntry = 1 );

sCommand[]
Typ: String (256)

bWriteLogEntry = 1
Typ: Integer (0 - 1)

Führt einen beliebigen Serverbefehl aus, kann aber auch Variablen setzen. Ausgenommen sind Admin Mod Befehle. Diese müssen mit plugin_exec ausgeführt werden, damit das Rechtesystem nicht über Plugins ausgehebelt werden kann.

Mit bWriteLogEntry = 0 kann man bewirken, dass keine Logzeile, beginnend mit „[ADMIN]Executing command:“ in die Logs eingetragen wird.

 
Beispiel aus plugin_base (Funktion: admin_pass):
359    snprintf(Msg, MAX_DATA_LENGTH, "sv_password %s", Data);  
360    exec(Msg);

Der Inhalt aus „Data“ wird „sv_password“ angehängt und ausgeführt, so dass nun das Passwort gilt, das in „Data“ steht. Auf die Logentry Einstellung wurde verzichtet, so dass die Ausführung geloggt wird.

Gehört zu: admin.inc

Siehe auch: execute_command, plugin_exec, setstrvar

8.10.24  execclient

execclient( sPlayer[], sCommand[] );

sPlayer[]
Typ: String (100)

sCommand[]
Typ: String (100)

Führt einen Befehl beim Spieler aus. Dabei muss der Spielername und der auszuführende Befehl angegeben werden. In der adminmod.cfg muss allow_client_exec auf 1 gesetzt sein.

 
Beispiel aus plugin_retribution (Funktion: admin_bury):
510          snprintf(Text, MAX_TEXT_LENGTH, "%s has broke the rules!", TargetName);  
511          say(Text);  
512  
513          messageex(TargetName, "Please obey our rules!", print_chat);  
514          execclient(TargetName, "say Help! I’m stuck!");

Allen Spielern wird im Chat mitgeteilt, dass der eingegrabene Spieler gegen die Regeln verstoßen hat. Dieses wird ihm ebenfalls im Chat gesagt. Zusätzlich lässt man den Spieler mittels execclient „Help! I’m stuck!“ sagen.

Gehört zu: admin.inc

Siehe auch: execclient_all

8.10.25  execclient_all

execclient_all( sCommand[] );

sCommand[]
Typ: String (100)

Führt bei allen Spielern den selben Befehl aus. allow_client_exec 1 muss dazu in der adminmod.cfg gesetzt sein.

 
Beispiel aus plugin_cw_creator/plugin_logd_cwcaddon7 (Funktion: logd_cwc_score):
305       if(maxrounds==0){  
306          execclient_all("timeleft");  
307       }

Falls die Variable „maxrounds“ auf 0 gesetzt ist, wird bei allen Spielern der Befehl „timeleft“ ausgeführt, der die verbleibende Restzeit auf der Map beim Spieler anzeigt.

Gehört zu: adminlib.inc

Siehe auch: execclient

8.10.26  execute_command

execute_command( sUser[], sCommand[], sHalfLifeCmd[], sData[] );

sUser[]
Typ: String (33)

sCommand[]
Typ: String (30)

sHalfLifeCmd[]
Typ: String (30)

sData[]
Typ: String (200)

Führt einen Befehl auf dem Server aus und gibt zusätzlich eine formatierte Nachricht am Bildschirm oder in den Logdateien aus, wenn admin_quiet entsprechend in der adminmod.cfg gesetzt ist.

Zum Ausführen wird der Adminname (sUser), der Admin Mod Befehl (sCommand), den er ausgeführt hat, der zu setzende Serverbefehl bzw. die Servervariable (sHalfLifeCmd) und die Option (sData) benötigt.

 
Beispiel aus plugin_base (Funktion: admin_hostname):
243    convert_string(HLCommand,Command,MAX_COMMAND_LENGTH);  
244    convert_string(HLData,Data,MAX_DATA_LENGTH);  
245    convert_string(HLUserName,User,MAX_NAME_LENGTH);  
246    snprintf(sHostName, MAX_DATA_LENGTH, "^"%s^"", Data);  
247    execute_command(User,Command,"hostname",sHostName);

Zunächst werden die Half-Life Strings konvertiert. „Data“ sollte dabei den neuen Servernamen beinhalten und wird wegen möglicher Leerzeichen in Anführungszeichen gesetzt (Zeile: 246). Anschließend werden die Daten „execute_command“ übergeben. „User“ und „Command“ geben ausführlich Auskunft darüber, wer welchen Befehl ausgeführt hat.

Gehört zu: adminlib.inc

Siehe auch: exec, setstrvar

8.10.27  existproperty

existproperty( id=0, const name[]=“”, value=cellmin );

id=0
Typ: Integer (-2147483648 - 2147483647)

const name[]=“”
Typ: String (variabel)

value=cellmin
Typ: Integer (-2147483648 - 2147483647)

Mit dieser Funktion kann die Existenz einer so genannten Property bei gegebenem Schlüssel überprüft werden. Es handelt sich dabei um eine Funktion, deren Benutzung unter Admin Mod vermieden werden sollte. Stattdessen wird empfohlen z.B. die Funktionen get_vaultdata oder set_vaultdata zurückzugreifen.

Mehr Informationen zum Thema sind im Abschnitt 8.14 nachzulesen.

 
Beispiel:
bBoolean = existproperty(2,“test_prop”);
bBoolean = existproperty(3,15);

Das erste Beispiel überprüft, ob die in ID 2 befindliche Property „test_prop“ existiert, während das zweite Beispiel überprüft, ob die in ID 3 befindliche Property 15 gesetzt wurde.

Gehört zu: core.inc

Siehe auch: deleteproperty, getproperty, setproperty

8.10.28  fileexists

fileexists( sFilename[] );

sFilename[]
Typ: String (100)

Überprüft unter Angabe von „sFilename“, ob die Datei vorhanden ist. Dazu muss die Variable file_access_read auf 1 in der adminmod.cfg gesetzt sein. Als Rückgabewert erhält man eine 1, wenn die Datei vorhanden, anderenfalls bekommt man eine 0 zurück.

 
Beispiel aus plugin_base (Funktion: plugin_init):
870    currentmap(strMap, MAX_DATA_LENGTH);  
871    snprintf(ExecCommand, MAX_DATA_LENGTH, "%s.cfg", strMap);  
872    if ( fileexists(ExecCommand) ) {  
873       snprintf(ExecCommand, MAX_DATA_LENGTH, "exec %s.cfg", strMap);  
874       log(ExecCommand);  
875       exec(ExecCommand);  
876    }

Es wird die aktuelle Map ermittelt und überprüft, ob sich im Modverzeichnis eine Konfiguartionsdatei für diese spezielle Map befindet. Existiert die Datei, wird sie ausgeführt. Dies ist eine oftmals übersehene Funktion Admin Mods, die der Basisfunktionalität des HL-Servers zugeschlagen wird.

8.10.29  filesize

filesize( sFilename[], fsize_unit:Unit = 1 );

sFilename[]
Typ: String (100)

fsize_unit:Unit = 1
Typ: Enum (0=bytes, lines)

Man erhält die Anzahl der Zeilen oder die Größe in Byte der unter sFilename angegebenen Datei. Wird „fsize_unit“ nicht angegeben, wird die Anzahl der Zeilen bei „bytes“ hingegen die Dateigröße in Bytes zurückgegeben.

Zum Ausführen der Funktion muss file_access_read auf 1 in der adminmod.cfg gesetzt sein.

 
Beispiel aus plugin_bk_cron8 (Funktion: admin_cron_refresh):
187    if(fileexists(filename)==0){  
188       /* log("plugin_bk_cron found no schedule.ini."); */  
189       log(cron_nosched);  
190       return PLUGIN_CONTINUE;  
191    }  
192    sizeoffile=filesize(filename,lines);

Ist die unter „filename“ angegebene Datei nicht existent, wird eine Fehlermeldung in den Logdateien ausgegeben und die weitere Ausführung des Befehls abgebrochen. Wird die Datei hingegen gefunden, wird die Anzahl der Zeilen ausgelesen und in die Variable „sizeoffile“ geschrieben.

8.10.30  fixed:f_abs

f_abs( fixed:fNum );

fixed:fNum
Typ: Fixed (-2147482 - 2147482)

Die Funktion f_abs gibt den Absolutwert einer Festkommazahl aus.

 
Beispiel aus math.inc (Funktion: f_sqrt):
296    if(f_abs(fNum)!=fNum){  
297       iError=1;  
298       return -1.000;  
299    }

Hier wird die Funktion f_abs benutzt, um zu überprüfen, ob der Wert fNum negativ ist. Ist er negativ, wird die Funktion abgebrochen und -1 zurückgegeben, um zu verhindern, dass die Wurzel aus einer negativen Zahl gezogen wird.

Gehört zu: math.inc

8.10.31  fixed:f_arccos

f_arccos( fixed:fNum, &iError=0 );

fixed:fNum
Typ: Fixed (-2147482 - 2147482)

iError=0
Typ: Integer (0 - 3)

Die Funktion f_arccos gibt den Arkuskosinus Wert als eine Festkommazahl zurück. Darüber hinaus wird bei einer fehlgeschlagenen Berechnung ein Fehlerwert iError zurückgegeben.

 
Beispiel:
fNum = f_arccos(fNum,iError);
matherror(iError);

Aus fNum wird der Arkuskosinus gebildet und anschließend eine mögliche Fehlermeldung mit matherror in die Logdateien geschrieben.

Gehört zu: math.inc

Siehe auch: f_arccot, f_arcsin, f_arctan

8.10.32  fixed:f_arccot

f_arccot( fixed:fNum );

fixed:fNum
Typ: Fixed (-2147482 - 2147482)

Die Funktion f_arccot gibt den Arkuskotangens Wert als eine Festkommazahl zurück.

 
Beispiel:
fNum = f_arccot(fNum);

Aus fNum wird der Arkuskotangens gebildet.

Gehört zu: math.inc

Siehe auch: f_arccos, f_arcsin, f_arctan

8.10.33  fixed:f_arcosh

f_arcosh( fixed:fNum, &iError=0 );

fixed:fNum
Typ: Fixed (-2147482 - 2147482)

iError=0
Typ: Integer (0 - 3)

Die Funktion f_arcosh gibt den Areakosinus Hyperbolicus Wert als eine Festkommazahl zurück. Darüber hinaus wird bei einer fehlgeschlagenen Berechnung ein Fehlerwert iError zurückgegeben.

 
Beispiel:
fNum = f_arcosh(fNum,iError);
matherror(iError);

Aus fNum wird der Areakosinus Hyperbolicus gebildet und anschließend eine mögliche Fehlermeldung mit matherror in die Logdateien geschrieben.

Gehört zu: math.inc

Siehe auch: f_arcoth, f_arsinh, f_artanh

8.10.34  fixed:f_arcoth

f_arcoth( fixed:fNum, &iError=0 );

fixed:fNum
Typ: Fixed (-2147482 - 2147482)

iError=0
Typ: Integer (0 - 3)

Die Funktion f_arcoth gibt den Areatangens Hyperbolicus Wert als eine Festkommazahl zurück. Darüber hinaus wird bei einer fehlgeschlagenen Berechnung ein Fehlerwert iError zurückgegeben.

 
Beispiel:
fNum = f_arcoth(fNum,iError);
matherror(iError);

Aus fNum wird der Areatangens Hyperbolicus gebildet und anschließend eine mögliche Fehlermeldung mit matherror in die Logdateien geschrieben.

Gehört zu: math.inc

Siehe auch: f_arcosh, f_arsinh, f_artanh

8.10.35  fixed:f_arcsin

f_arcsin( fixed:fNum, &iError=0 );

fixed:fNum
Typ: Fixed (-2147482 - 2147482)

iError=0
Typ: Integer (0 - 3)

Die Funktion f_arcsin gibt den Arkussinus Wert als eine Festkommazahl zurück. Darüber hinaus wird bei einer fehlgeschlagenen Berechnung ein Fehlerwert iError zurückgegeben.

 
Beispiel aus math.inc (Funktion: f_arccos):
478    return fdiv(f_pi(),2.000)-f_arcsin(fNum);

Der Arkuskosinus wird aus der Berechnung arccos x = π2 - arcsin x gebildet.

Gehört zu: math.inc

Siehe auch: f_arccos, f_arccot, f_arctan

8.10.36  fixed:f_arctan

f_arctan( fixed:fNum, &iError=0 );

fixed:fNum
Typ: Fixed (-2147482 - 2147482)

iError=0
Typ: Integer (0 - 3)

Die Funktion f_arctan gibt den Arkustangens Wert als eine Festkommazahl zurück. Darüber hinaus wird bei einer fehlgeschlagenen Berechnung ein Fehlerwert iError zurückgegeben.

 
Beispiel aus math.inc (Funktion: f_arccot):
481 stock fixed:f_arccot(fixed:fNum){  
482    return fdiv(f_pi(),2.000)-f_arctan(fNum);  
483 }

Der Arkuskotangens wird aus der Berechnung arccot x = π2 - arctan x gebildet.

Gehört zu: math.inc

Siehe auch: f_arccos, f_arccot, f_arcsin

8.10.37  fixed:f_arctan_help

f_arctan_help( fixed:fNum );

fixed:fNum
Typ: Fixed (-2147482 - 2147482)

Die Funktion f_arctan_help ist lediglich eine Unterfunktion von f_arctan und ist für eine Verwendung in einem Plugin nicht sinnvoll.

Gehört zu: math.inc

Siehe auch: f_arctan

8.10.38  fixed:f_arsinh

f_arsinh( fixed:fNum, &iError=0 );

fixed:fNum
Typ: Fixed (-2147482 - 2147482)

iError=0
Typ: Integer (0 - 3)

Die Funktion f_arsinh gibt den Areasinus Hyperbolicus Wert als eine Festkommazahl zurück. Darüber hinaus wird bei einer fehlgeschlagenen Berechnung ein Fehlerwert iError zurückgegeben.

 
Beispiel:
fNum = f_arsinh(fNum,iError);
matherror(iError);

Aus fNum wird der Areasinus Hyperbolicus gebildet und anschließend eine mögliche Fehlermeldung mit matherror in die Logdateien geschrieben.

Gehört zu: math.inc

Siehe auch: f_arcosh, f_arcoth, f_artanh

8.10.39  fixed:f_artanh

f_artanh( fixed:fNum, &iError=0 );

fixed:fNum
Typ: Fixed (-2147482 - 2147482)

iError=0
Typ: Integer (0 - 3)

Die Funktion f_artanh gibt den Areatangens Hyperbolicus Wert als eine Festkommazahl zurück. Darüber hinaus wird bei einer fehlgeschlagenen Berechnung ein Fehlerwert iError zurückgegeben.

 
Beispiel:
fNum = f_artanh(fNum,iError);
matherror(iError);

Aus fNum wird der Areatangens Hyperbolicus gebildet und anschließend eine mögliche Fehlermeldung mit matherror in die Logdateien geschrieben.

Gehört zu: math.inc

Siehe auch: f_arcosh, f_arcoth, f_arsinh

8.10.40  fixed:f_cos

f_cos( fixed:fNum );

fixed:fNum
Typ: Fixed (-2147482 - 2147482)

Die Funktion f_cos gibt den Kosinus Wert als eine Festkommazahl zurück.

 
Beispiel aus math.inc (Funktion: f_tan):
398 stock fixed:f_tan(fixed:fNum){  
399    return fdiv(f_sin(fNum),f_cos(fNum));  
400 }

Der Tangens wird aus der Berechnung tan x = sinx-
cosx gebildet.

Gehört zu: math.inc

Siehe auch: f_cot, f_sin, f_tan

8.10.41  fixed:f_cosh

f_cosh( fixed:fNum );

fixed:fNum
Typ: Fixed (-2147482 - 2147482)

Die Funktion f_cosh gibt den Kosinus Hyperbolicus Wert als eine Festkommazahl zurück.

 
Beispiel aus math.inc (Funktion: f_tanh):
493 stock fixed:f_tanh(fixed:fNum){  
494    return fdiv(f_sinh(fNum),f_cosh(fNum));  
495 }

Der Tangens Hyperbolicus wird aus der Berechnung tanh x = sinh x
coshx gebildet.

Gehört zu: math.inc

Siehe auch: f_coth, f_sinh, f_tanh

8.10.42  fixed:f_cot

f_cot( fixed:fNum );

fixed:fNum
Typ: Fixed (-2147482 - 2147482)

Die Funktion f_cot gibt den Kotangens Wert als eine Festkommazahl zurück.

 
Beispiel:
fNum = f_cot(fNum);

Aus fNum wird der Kotangens gebildet.

Gehört zu: math.inc

Siehe auch: f_cos, f_sin, f_tan

8.10.43  fixed:f_coth

f_coth( fixed:fNum, &iError=0 );

fixed:fNum
Typ: Fixed (-2147482 - 2147482)

iError=0
Typ: Integer (0 - 3)

Die Funktion f_coth gibt den Kotangens Hyperbolicus Wert als eine Festkommazahl zurück. Darüber hinaus wird bei einer fehlgeschlagenen Berechnung ein Fehlerwert iError zurückgegeben.

 
Beispiel:
fNum = f_coth(fNum,iError);
matherror(iError);

Aus fNum wird der Kotangens Hyperbolicus gebildet und anschließend eine mögliche Fehlermeldung mit matherror in die Logdateien geschrieben.

Gehört zu: math.inc

Siehe auch: f_cosh, f_sinh, f_tanh

8.10.44  fixed:f_degtorad

f_degtorad( fixed:fNum );

fixed:fNum
Typ: Fixed (-2147482 - 2147482)

Die Funktion f_degtorad rechnet einen Winkel von Grad in Radiant um.

 
Beispiel:
fNum = f_degtorad(fNum);

Der Winkel fNum wird in Radiant umgerechnet.

Gehört zu: math.inc

Siehe auch: f_radtodeg

8.10.45  fixed:f_euler

f_euler( );

Die Funktion f_euler gibt die Eulersche Zahl (2,718) zurück.

 
Beispiel:
fEuler = f_euler();

In die Variable fEuler wird die Eulersche Zahl geschrieben.

Gehört zu: math.inc

Siehe auch: f_pi

8.10.46  fixed:f_faculty

f_faculty( fixed:fValue, &iError=0 );

fixed:fValue
Typ: Fixed (-2147482 - 2147482)

iError=0
Typ: Integer (0 - 3)

Die Funktion f_faculty gibt die Fakultät einer Zahl als eine Festkommazahl zurück. Darüber hinaus wird bei einer fehlgeschlagenen Berechnung ein Fehlerwert iError zurückgegeben.

 
Beispiel:
fNum = f_faculty(fNum,iError);
matherror(iError);

Aus fNum wird die Fakultät ermittelt und anschließend eine mögliche Fehlermeldung mit matherror in die Logdateien geschrieben.

Gehört zu: math.inc

8.10.47  fixed:f_ln

f_ln( fixed:fValue, &iError=0 );

fixed:fValue
Typ: Fixed (-2147482 - 2147482)

iError=0
Typ: Integer (0 - 3)

Die Funktion f_ln ermittelt den natürlichen Logarithmus einer Zahl und gibt diesen als eine Festkommazahl zurück. Darüber hinaus wird bei einer fehlgeschlagenen Berechnung ein Fehlerwert iError zurückgegeben.

 
Beispiel aus math.inc (Funktion: f_arsinh):
510    return f_ln(fNum+f_sqrt(fmul(fNum,fNum)+1.000));

Der Areasinus Hyperbolicus wird aus der Berechnung arsinh x = ln(x + √ -----------
  x2 + 1.000) gebildet.

Gehört zu: math.inc

Siehe auch: f_log10, f_logab

8.10.48  fixed:f_log10

f_log10( fixed:fValue, &iError=0 );

fixed:fValue
Typ: Fixed (-2147482 - 2147482)

iError=0
Typ: Integer (0 - 3)

Die Funktion f_log10 ermittelt den Zehner-Logarithmus einer Zahl und gibt diesen als eine Festkommazahl zurück. Darüber hinaus wird bei einer fehlgeschlagenen Berechnung ein Fehlerwert iError zurückgegeben.

 
Beispiel aus math.inc (Funktion: f_logab):
163    fBase=f_log10(fBase,iError);  
164    if(iError>0){  
165       return fBase;  
166    }

Die Basis für den beliebigen Logarithmus wird mit dem Zehnerlogarithmus vorbereitet. Ist ein Fehler aufgetreten, wird die Ausführung abgebrochen.

Gehört zu: math.inc

Siehe auch: f_ln, f_logab

8.10.49  fixed:f_logab

f_log10( fixed:fBase, fixed:fValue, &iError=0 );

fixed:fBase
Typ: Fixed (-2147482 - 2147482)

fixed:fValue
Typ: Fixed (-2147482 - 2147482)

iError=0
Typ: Integer (0 - 3)

Die Funktion f_logab ermittelt den Logarithmus einer Zahl auf einer beliebigen Basis und gibt diesen als eine Festkommazahl zurück. Darüber hinaus wird bei einer fehlgeschlagenen Berechnung ein Fehlerwert iError zurückgegeben. Benötigt man den natürlichen oder den Zehnerlogarithmus, sollte man auf die Funktionen f_ln und f_log10 zurückgreifen.

 
Beispiel:
fNum = f_logab(fBasis,fNum,iError);
matherror(iError);

Aus fNum wird der Logarithmus auf der Basis fBasis gebildet und anschließend eine mögliche Fehlermeldung mit matherror in die Logdateien geschrieben.

Gehört zu: math.inc

Siehe auch: f_ln, f_log10

8.10.50  fixed:f_max

f_max( fixed:fNum, fixed:fNum2 );

fixed:fNum
Typ: Fixed (-2147482 - 2147482)

fixed:fNum2
Typ: Fixed (-2147482 - 2147482)

Die Funktion f_max gibt aus zwei Festkommazahlen die größte aus. Für Ganzzahlen kann man max nutzen.

 
Beispiel aus math.inc (Funktion: f_arctan):
424    fRange=f_max(fNum,0.000);

Es wird sichergestellt, dass keine negativen Werte auftreten können. Negative Werte werden auf 0 gesetzt.

Gehört zu: math.inc

Siehe auch: clamp, f_min, max, min

8.10.51  fixed:f_min

f_min( fixed:fNum, fixed:fNum2 );

fixed:fNum
Typ: Fixed (-2147482 - 2147482)

fixed:fNum2
Typ: Fixed (-2147482 - 2147482)

Die Funktion f_min gibt aus zwei Festkommazahlen die kleinste aus. Für Ganzzahlen kann man min nutzen.

 
Beispiel:
fMin = f_min(fNum1,fNum2);

Der kleinste Wert aus fNum1 und fNum2 wird an fMin übergeben.

Gehört zu: math.inc

Siehe auch: clamp, f_max, max, min

8.10.52  fixed:f_pi

f_pi( );

Die Funktion f_pi gibt die Zahl Pi (3,142) zurück.

 
Beispiel:
fPi = f_pi();

In die Variable fPi wird die Zahl Pi geschrieben.

Gehört zu: math.inc

Siehe auch: f_euler

8.10.53  fixed:f_power

f_power( fixed:fBasis, fixed:fExponent, &iError=0 );

fixed:fBasis
Typ: Fixed (-2147482 - 2147482)

fixed:fExponent
Typ: Fixed (-2147482 - 2147482)

iError=0
Typ: Integer (0 - 3)

Die Funktion f_power exponiert (fExponent) den in fBasis gegebenen Wert. Will man nur die Eulerzahl exponieren, sollte man auf f_powere zurückgreifen.

 
Beispiel:
fNum = f_power(fBasis,fExponent,iError);
matherror(iError);

Die Basis (fBasis) wird mit fExponent exponiert und das Ergebnis in fNum geschrieben. Eine mögliche Fehlermeldung wird mit matherror in die Logdateien geschrieben.

Gehört zu: math.inc

Siehe auch: f_powere

8.10.54  fixed:f_powere

f_powere( fixed:fExponent, &iError=0 );

fixed:fExponent
Typ: Fixed (-2147482 - 2147482)

iError=0
Typ: Integer (0 - 3)

Die Funktion f_power exponiert (fExponent) den die Eulersche Zahl. Will man eine beliebige Zahl exponieren, sollte man auf f_power zurückgreifen.

 
Beispiel aus math.inc (Funktion: f_sinh):
424 stock fixed:f_sinh(fixed:fNum){  
425    return fdiv(f_powere(fNum)-f_powere(fmul(fNum,-1.000)),2.000);  
426 }

Der Sinus Hyperbolicus wird aus der Berechnung sinh x = ex--e--x
  2 gebildet.

Gehört zu: math.inc

Siehe auch: f_power

8.10.55  fixed:f_radtodeg

f_radtodeg( fixed:fNum );

fixed:fNum
Typ: Fixed (-2147482 - 2147482)

Die Funktion f_radtodeg rechnet einen Winkel von Radiant in Grad um.

 
Beispiel:
fNum = f_radtodeg(fNum);

Der Winkel fNum wird in Grad umgerechnet.

Gehört zu: math.inc

Siehe auch: f_degtorad

8.10.56  fixed:f_sin

f_sin( fixed:fNum );

fixed:fNum
Typ: Fixed (-2147482 - 2147482)

Die Funktion f_sin gibt den Sinus Wert als eine Festkommazahl zurück.

 
Beispiel aus math.inc (Funktion: f_cos):
394 stock fixed:f_cos(fixed:fNum){  
395    return f_sin(fNum+fdiv(f_pi(),2.000));  
396 }

Der Kosinus wird aus der Berechnung cos x = sin(x + π
2) gebildet.

Gehört zu: math.inc

Siehe auch: f_cos, f_cot, f_tan

8.10.57  fixed:f_sinh

f_sinh( fixed:fNum );

fixed:fNum
Typ: Fixed (-2147482 - 2147482)

Die Funktion f_sinh gibt den Sinus Hyperbolicus Wert als eine Festkommazahl zurück.

 
Beispiel aus math.inc (Funktion: f_tanh):
493 stock fixed:f_tanh(fixed:fNum){  
494    return fdiv(f_sinh(fNum),f_cosh(fNum));  
495 }

Der Tangens Hyperbolicus wird aus der Berechnung tanh x = sinh x
coshx gebildet.

Gehört zu: math.inc

Siehe auch: f_cosh, f_coth, f_tanh

8.10.58  fixed:f_sqrt

f_sqrt( fixed:fNum, &iError=0, fixed:fNumStart=1.000 );

fixed:fNum
Typ: Fixed (-2147482 - 2147482)

iError=0
Typ: Integer (0 - 3)

fixed:fNumStart
Typ: Fixed (-2147482 - 2147482)

Die Funktion f_sqrt zieht aus einer gegebenen Zahl fNum die Quadratwurzel. Da die Ermittlung der Quadratwurzel eine iterative Berechnung ist, kann die Berechnung beschleunigt werden, in dem ein sinnvoller Startwert für fNumStart angegeben wird (Standard: 1.000). Außerdem wird über iError ein Fehlerwert zurückgegeben.

 
Beispiel aus math.inc (Funktion: f_arsinh):
510    return f_ln(fNum+f_sqrt(fmul(fNum,fNum)+1.000));

Der Areasinus Hyperbolicus wird aus der Berechnung arsinh x = ln(x + √ -----------
  x2 + 1.000) gebildet.

Gehört zu: math.inc

8.10.59  fixed:f_tan

f_tan( fixed:fNum );

fixed:fNum
Typ: Fixed (-2147482 - 2147482)

Die Funktion f_tan gibt den Tangens Wert als eine Festkommazahl zurück.

 
Beispiel:
fNum = f_tan(fNum);

Aus fNum wird der Tangens gebildet.

Gehört zu: math.inc

Siehe auch: f_cos, f_cot, f_sin

8.10.60  fixed:f_tanh

f_tanh( fixed:fNum );

fixed:fNum
Typ: Fixed (-2147482 - 2147482)

Die Funktion f_tanh gibt den Tangens Hyperbolicus Wert als eine Festkommazahl zurück.

 
Beispiel:
fNum = f_tanh(fNum);

Aus fNum wird der Tangens Hyperbolicus gebildet.

Gehört zu: math.inc

Siehe auch: f_cosh, f_coth, f_sinh

8.10.61  fixed:fdiv

fixed:fdiv( fixed:dividend, fixed:divisor );

fixed:dividend
Typ: Fixed (-2147482 - 2147482)

fixed:divisor
Typ: Fixed (-2147482 - 2147482)

Die Funktion fdiv führt eine Divison zweier Zahlen durch. Theoretisch steht auch „/“ als Operatorzeichen zur Verfügung. Die Erkennung durch den Compiler ist leider nicht zuverlässig, so dass die Funktion fdiv empfohlen wird.

 
Beispiel aus math.inc (Funktion: f_cos):
394 stock fixed:f_cos(fixed:fNum){  
395    return f_sin(fNum+fdiv(f_pi(),2.000));  
396 }

Hier wird der Kosinus durch die Berechnung cos x = sin(x + π
2) ermittelt.

Gehört zu: fixed.inc

Siehe auch: fmul

8.10.62  fixed:ffract

fixed:ffract( fixed:value );

fixed:value
Typ: Fixed (-2147482 - 2147482)

Mit ffract werden die drei Nachkommastellen als Zahl ermittelt. Dabei wird auch das Vorzeichen des Gesamtwertes übertragen.

 
Beispiel aus math.inc (Funktion: fixtorstr):
26    iFrac=ffract(fNumber);  
27    if(iFrac<0){  
28       iFrac*=-1;  
29       iSign=-1;  
30    }

Im Beispiel werden die Nachkommastellen als Zahl ermittelt. Ist die Zahl negativ wird sie negiert und das Vorzeichen in iSign gespeichert.

Gehört zu: fixed.inc

8.10.63  fixed:fixed

fixed:fixed( value );

value
Typ: Integer (-2147482 - 2147482)

Die Funktion fixed wandelt eine Ganzzahl in eine Festkommazahl um.

 
Beispiel aus math.inc (Funktion: f_faculty):
181             iValue=fround(fValue);  
182             fValue=1.000;  
183             for(new i=2;i<=iValue;i++){  
184                fValue=fmul(fValue,fixed(i));  
185             }

Zunächst wird zur Ermittlung der Fakultät der Wert auf eine Ganzzahl gerundet. Der Ausgangswert wird auf 1 gesetzt. Die Fakultät wird durch eine For Schleife durch Multiplikation ermittelt. Dabei muss das aktuelle Inkrement bei jedem Durchlauf in eine Festkommazahl mittels der Funktion fixed umgewandelt werden.

Gehört zu: fixed.inc

8.10.64  fixed:fixedstr

fixed:fixedstr( const string[] );

string
Typ: String (20)

Die Funktion fixedstr wandelt einen String in eine Festkommazahl um. Dabei geht aber ein mögliches Vorzeichen verloren. Das Ergebnis ist immer positiv. Daher wird empfohlen statt fixedstr die Funktion strtofix zu verwenden, die auch das Vorzeichen berücksichtigt.

 
Beispiel aus math.inc (Funktion: strtofix):
49    if(strtrim(sNumber,"-",0)>0){  
50       fNumber=fmul(fixedstr(sNumber),-1.000);  
51    }  
52    else{  
53       fNumber=fixedstr(sNumber);  
54    }

Wenn ein negatives Vorzeichen existiert, wird die aus dem String umgewandelte Zahl negiert. Anderenfalls wird nur der String in eine Festkommazahl umgewandelt.

Gehört zu: fixed.inc

Siehe auch: strtofix

8.10.65  fixed:fmul

fixed:fmul( fixed:oper1, fixed:oper2 );

fixed:oper1
Typ: Fixed (-2147482 - 2147482)

fixed:oper2
Typ: Fixed (-2147482 - 2147482)

Die Funktion fmul führt eine Multiplikation zweier Zahlen durch. Theoretisch steht auch „*“ als Operatorzeichen zur Verfügung. Die Erkennung durch den Compiler ist leider nicht zuverlässig, so dass die Funktion fmul empfohlen wird.

 
Beispiel aus math.inc (Funktion: f_abs):
320 stock fixed:f_abs(fixed:fNum) {  
321    if(fNum >= 0.000) {  
322       return fNum;  
323    }  
324    return fmul(fNum,-1.000);  
325 }

Ist die Zahl positiv, wird sie unbearbeitet zurückgegeben. Anderenfalls wird sie mit -1 multipliziert (also negiert), so dass stets der Absolutwert zurückgegeben wird.

Gehört zu: fixed.inc

Siehe auch: fdiv

8.10.66  fixed:strtofix

fixed:strtofix( sNumber[] );

string
Typ: String (20)

Die Funktion strtofix wandelt einen String in eine Festkommazahl um. Im Gegensatz zu fixedstr wird ein mögliches Vorzeichen berücksichtigt.

 
Beispiel:
new sNumber[MAX_NUMBER_LENGTH];
strcpy(sNumber,“-1.378”,MAX_NUMBER_LENGTH);
fNumber = strtofix(sNumber);

Es wird ein String definiert und anschließend mittels der Funktion strcpy mit „-1.378“ befüllt. Aus diesem String (sNumber) wird eine Festkommazahl gebildet (fNumber).

Gehört zu: math.inc

Siehe auch: fixedstr, fixtostr

8.10.67  fixtostr

fixtostr( fixed:fNumber, sNumber[], iMaxLength );

fixed:fNumber
Typ: Fixed (-2147482 - 2147482)

string
Typ: String (20)

iMaxLength
Typ: Integer (0 - 20)

Die Funktion fixtostr wandelt eine Festkommazahl in einen String um.

 
Beispiel aus plugin_sdal_logd_hp509 (Funktion: display_victim):
723    if(g_display_distance){  
724       new Meters[MAX_NUMBER_LENGTH];  
725       fixtostr(fixed:g_PlayerEnemyDistance[UserID],Meters,MAX_NUMBER_LENGTH);

Wenn die Entfernung zum Gegner nach dem eigenen Ableben angezeigt werden soll, wird zunächst die gespeicherte Entfernung (g_PlayerEnemyDistance[UserID]) in einen String umgewandelt (Meters). Die Textausgabe erfolgt später im Code.

Gehört zu: math.inc

Siehe auch: fixedstr, strtofix

8.10.68  format_command

format_command( sUser[],sCommand[],sData[],sText[] );

sUser[]
Typ: String (33)

sCommand[]
Typ: String (30)

sData[]
Typ: String (200)

sText[]
Typ: String (200)

Die Funktion bereitet einen Text zur Darstellung im Chat oder in den Logdateien auf, wenn ein Admin Mod Befehl ausgeführt wird. Dazu muss der ausführende Admin (sUser), der ausgeführte Befehl (sCommand) und die Parameter (sData) angegeben werden. Die Rückgabe erfolgt über sText.

Die Funktion wird üblicherweise nicht allein eingesetzt, da sie eine Unterfunktion von log_command und say_command ist.

 
Beispiel aus adminlib.inc (Funktion: format_command):
320 stock log_command(sUser[],sCommand[],sData[]) {  
321    new sText[MAX_TEXT_LENGTH];  
322    format_command(sUser,sCommand,sData,sText);  
323    log(sText);  
324 }

Username (sUser), der aufgerufende Befehl (sCommand) und die zugehörigen Parameter (sData) werden an format_command übergeben, der formatierte Text (sText) geloggt.

Gehört zu: adminlib.inc

Siehe auch: log_command, say_command

8.10.69  fround

fround( fixed:value, fround_method:method=fround_round );

fixed:value
Typ: Fixed (-2147482 - 2147482)

fround_method:method=fround_round
Typ: Enum (0=fround_round, fround_floor, fround_ceil)

Diese Funktion rundet eine Festkommazahl. Sie wird als Integer ausgegeben. Es gibt drei verschiedene Methoden zum Runden. Die Methode fround_round rundet ab 0,5 auf und darunter ab, bei fround_floor wird grundsätzlich abgerundet, bei fround_ceil wird aufgerundet.

 
Beispiel aus math.inc (Funktion: fixtostr):
20    if(fNumber<0.000){  
21       iNumber=fround(fNumber,fround_ceil);  
22    }  
23    else{  
24       iNumber=fround(fNumber,fround_floor);  
25    }

Wenn die Zahl fNumber negativ ist, wird aufgerundet, wenn sie positiv ist, wird abgerundet.

Gehört zu: fixed.inc

8.10.70  funcidx

funcidx( const name[] );

const name[]
Typ: String (20)

Die Funktion liefert den interen Index einer öffentlichen Funktion. Wird die angegebene Funktion nicht gefunden, gibt funcidx -1 zurück.

Ein sinnvoller Einsatz unter Admin Mod ist nicht gegeben.

 
Beispiel:
iID=funcidx(“admin_ban”);

Im Beispiel wird die interne ID der Funktion admin_ban aus dem Base Plugin ausgegeben.

Gehört zu: core.inc

8.10.71  get_serverinfo

get_serverinfo( sKey[], sValue[], iMaxLength );

sKey[]
Typ: String (100)

sValue[]
Typ: String (200)

iMaxLength
Typ: Integer (0 - 200)

Die Funktion liest die Daten (sValue), die mit dem Schlüssel (sKey) hinterlegt wurden, aus. Der Schlüssel und die Daten werden mit set_serverinfo gesetzt. Die Daten werden beim Mapwechsel nicht gelöscht. Der Speicher ist jedoch nur sehr gering bemessen, so dass die Verwendung dieser Funktion vermieden werden sollte.

 
Beispiel aus plugin_bk_cron10 (Funktion: lag_check):
463    get_serverinfo("last_cron",slastcheck,3);  
464    lastcheck=strtonum(slastcheck);

Der Inhalt des Schlüssels (last_cron) wird ausgelesen und mit einer maximalen Länge von 3 in die Variable slastcheck geschrieben. Der String wird anschließend in eine Ganzzahl umgewandelt. Auf diese Art und Weise kann insbesondere überprüft werden, wie lang der letzte Durchlauf vor dem Mapwechsel her ist. Beim Serverstart ist die Variable noch nicht gesetzt, so dass 0 zurückgegeben wird. Die Nutzung der vault.ini verbietet sich, da der Wert beim Beenden bzw. Absturz des Servers nicht automatisch auf 0 zurückgesetzt wird.

Gehört zu: admin.inc

Siehe auch: set_serverinfo

8.10.72  get_timer

get_timer( iTimer );

iTimer
Typ: Integer (0 - 511)

Die Funktion get_timer gibt den Status eines Timers aus (läuft (1), läuft nicht (0), gehört nicht dem Plugin (-1))

 
Beispiel:

if (get_timer(iTimer)) {  
   kill_timer(iTimer);  
}

Nur wenn der Timer mit dem Index (iTimer) aktuell läuft und dem eigenen Plugin gehört, wird der Timer gestoppt (kill_timer).

Gehört zu: admin.inc

Siehe auch: kill_timer, set_timer

8.10.73  get_userArmor

get_userArmor( sPlayer[], &armor );

sPlayer[]
Typ: String (33)

&armor
Typ: Integer (0 - 2147483647)

Die Funktion liefert den momentanen Wert der Rüstung des Spielers als Integerwert (armor) zurück.

 
Beispiel aus plugin_sdal_logd_hp5011 (Funktion: hp_kill):
441    playerinfo(iAID,Attacker,MAX_NAME_LENGTH,_,_,iATeam);  
442    playerinfo(iVID,Victim,MAX_NAME_LENGTH,_,_,iVTeam);  
443  
444    get_userHealth(Attacker, iAHealth);  
445    get_userArmor(Attacker, iAArmor);

Die Spielernamen des Angreifers und des Opfers sowie deren Teamzugehörigkeit werden über playerinfo ermittelt. Nicht benötigte Variablen werden durch Unterstriche von der Verarbeitung ausgeklammert. Diese Methode sollte nur auf Admin Mod 2.60.42 und neuer angewendet werden, da es schon einmal Probleme mit Memory Leaks gegeben hat.

Anschließend werden die verbleibenden Lebens- und Rüstungspunkte des Angreifers zur späteren Anzeige beim Opfer ausgelesen.

Gehört zu: admin.inc

Siehe auch: get_userFrags, get_userHealth

8.10.74  get_userAuthID

get_userAuthID( sPlayer[], sAuthid[], iMaxLength = MAX_AUTHID_LENGTH );

sPlayer[]
Typ: String (33)

sAuthid[]
Typ: String (39)

iMaxLength = MAX_AUTHID_LENGTH
Typ: Integer (0 - 39)

Die Funktion liefert die Steam ID des angegebenen Spielers (sPlayer) und speichert diese als String (sAuthid). Sollte es sich um einen Bot handeln, dann wird BOT als AuthID zurückgeliefert. Die Länge des Strings muss nicht angegeben werden, bzw. sollte stets gleich MAX_AUTHID_LENGTH (39) sein.

 
Beispiel aus plugin_base.inc (Funktion: admin_vote_kick):
625             get_userAuthID(real_user,sAuthID);  
626             if (vote(Text,"Yes","No","HandleKickVote",sAuthID)) {  
627                g_VoteInProgress = 1;  
628                g_AbortVote = 0;  
629             }

Es wird die AuthID (i.d.R. die Steam ID) eines Spielers (real_user) ermittelt. Ein Vote zum Kicken des Spielers wird angestoßen, wobei der späteren Voteauswertung die AuthID mitgeliefert wird. Des Weiteren werden 2 globale Variablen gesetzt, wenn der Vote erfolgreich abgesetzt wurde.

Gehört zu: admin.inc

Siehe auch: get_userWONID, playerinfo

8.10.75  get_userFrags

get_userFrags( sPlayer[], &frags );

sPlayer[]
Typ: String (33)

&frags
Typ: Integer (0 - 2147483647)

Die Funktion liefert die Anzahl der Frags (frags) des Spieler (sPlayer) über die gesamte Mapzeit als Integerwert.

 
Beispiel aus plugin_sdal_logd_hp5012 (Funktion: best_player):
994    for(j=1;j<=maxplayers;j++){  
995       if(playerinfo(j,Player,MAX_NAME_LENGTH)){  
996          get_userFrags(Player,PlayerPoints[j]);  
997          if(PlayerPoints[j]>mostfrags){  
998             mostfrags=PlayerPoints[j];  
999          }  
1000       }  
1001    }

Mittels einer For-Schleife soll der Spieler mit den meisten Frags ermittelt werden. Die For-Schleife überprüft alle Slots. Nur Slots, die mit Spielern bestückt sind, werden ausgewertet (Zeile 995). Wurde ein Spieler gefunden, werden seine Frags (get_userFrags) ermittelt. Falls die Anzahl seiner Frags größer als der bisherige Bestwert sind, wird die Anzahl seiner Frags zum neuen Bestwert.

Gehört zu: admin.inc

Siehe auch: get_userArmor, get_userHealth

8.10.76  get_userHealth

get_userHealth( sPlayer[], &health );

sPlayer[]
Typ: String (33)

&health
Typ: Integer (0 - 2147483647)

Die Funktion liefert die momentanen Lebenspunkte des Spielers als Integerwert.

 
Beispiel aus plugin_sdal_logd_hp5013 (Funktion: hp_kill):
441    playerinfo(iAID,Attacker,MAX_NAME_LENGTH,_,_,iATeam);  
442    playerinfo(iVID,Victim,MAX_NAME_LENGTH,_,_,iVTeam);  
443  
444    get_userHealth(Attacker, iAHealth);  
445    get_userArmor(Attacker, iAArmor);

Die Spielernamen des Angreifers und des Opfers sowie deren Teamzugehörigkeit werden über playerinfo ermittelt. Nicht benötigte Variablen werden durch Unterstriche von der Verarbeitung ausgeklammert. Diese Methode sollte nur auf Admin Mod 2.60.42 und neuer angewendet werden, da es schon einmal Probleme mit Memory Leaks gegeben hat.

Anschließend werden die verbleibenden Lebens- und Rüstungspunkte des Angreifers zur späteren Anzeige beim Opfer ausgelesen.

Gehört zu: admin.inc

Siehe auch: get_userArmor, get_userFrags

8.10.77  get_userindex

get_userindex( sPlayer[], &iIndex );

sPlayer[]
Typ: String (33)

&iIndex
Typ: Integer (0 - 32)

Die Funktion liefert auf Basis des Spielernamens seinen UserIndex (Server-Slot) als Integerwert.

 
Beispiel aus plugin_retribution (Funktion: admin_bury):
499          get_userindex(Data, nIndex);  
500          playerinfo(nIndex, TargetName, MAX_NAME_LENGTH, _, _, _, nDead);

Der Status eines Spielers (lebend oder tot) lässt sich mit Admin Mod nur mit der Funktion playerinfo ermitteln. Da sie den Userindex benötigt, muss zunächst aus dem Namen (Data) der Userindex (nIndex) ermittelt werden. Anschließend kann der Status abgefragt werden. TargetName ist eigentlich nicht notwendig, ist jedoch eine Pflichtrückgabe. Auf die weiteren Variablen kann verzichtet werden. Als Auslassungszeichen wird der Unterstrich verwendet.

Gehört zu: admin.inc

Siehe auch: get_userSessionID, playerinfo

8.10.78  get_userinfo

get_userinfo( sPlayer[], sKey[], sInfo[], iMaxLength );

sPlayer[]
Typ: String (33) max. Länge: 100

sKey[]
Typ: String (100)

sInfo[]
Typ: String (200)

iMaxLength
Typ: Integer (0 - 200)

Mit der Funktion get_userinfo lassen sich einige wenige Usereinstellungen abfragen. Diese Daten werden oftmals mit setinfo angelegt. Die Funktion benötigt einen Schlüssel (sKey), dessen Daten (sInfo) ausgelesen werden können. Um mögliche Schlüssel zu ermitteln, kann man den Serverbefehl user <username / Session ID> auf einen bestimmten Spieler anwenden.

Der für diese Usereinstellungen zur Verfügung gestellte Speicher ist extrem klein. Statsme schaffte es in der Vergangenheit mit seinen Usereinstellungen die Admin Mod Anmeldung unmöglich zu machen. Die Fehlermeldung „info string length exceeded“ zeigte dann, dass der geringe Speicher gänzlich aufgebraucht war.

Man kann mit der Funktion execclient und dem Setzen von setinfo Usereinstellungen verankern, man sollte dies aber unter allen Umständen vermeiden, sofern es nicht einer übergeordneten Aufgabe zuträglich ist. Mehr zu diesem Thema ist dem Abschnitt Was macht eigentlich Setinfo? zu entnehmen.

 
Beispiel aus plugin_bk_hltvannounce14 (Funktion: a_hltv):
56       get_userinfo(hltvname,hspecs,hltvspecs,MAX_NAME_LENGTH);  
57       get_userinfo(hltvname,hslots,hltvslots,MAX_NAME_LENGTH);  
58       get_userinfo(hltvname,hdelay,hltvdelay,MAX_NAME_LENGTH);  
59       get_userIP(hltvname,hltvip,MAX_IP_LENGTH,iPort);

Das erste get_userinfo ruft die belegten Slots des HLTV-Servers, das zweite die maximale Slotzahl und das dritte den eingestellten Delay in Sekunden ab. Die Variablennamen der Schlüsselnamen stimmen mit ihrem Inhalt überein (hspecs z.B. hat den Inhalt „hspecs“). Anschließend wird noch die IP-Adresse des HLTVs ermittelt (get_userIP).

Gehört zu: admin.inc

8.10.79  get_userIP

get_userIP( sPlayer[], sIP[], iMaxLength, &iPort = 0 );

sPlayer[]
Typ: String (33)

sIP[]
Typ: String (22)

iMaxLength Typ: Integer (0 - 22)

&iPort = 0 Typ: Integer (0 - 65535)

Diese Funktion liefert die IP des Spielers als String (sIP) auf Basis des Namens (sPlayer). Neben der IP wird auch der genutzte Port (iPort) ausgegeben.

 
Beispiel aus plugin_bk_hltvannounce15 (Funktion: hltvconnect):
205    get_userIP(hltvname,hltvip,MAX_IP_LENGTH,iPort);  
206    get_userinfo(hltvname,hslots,hltvinfo,MAX_NAME_LENGTH);  
207    ihltv=strtonum(hltvinfo);  
208    get_userinfo(hltvname,hspecs,hltvinfo,MAX_NAME_LENGTH);  
209    ihltv-=strtonum(hltvinfo);

Zunächst wird die IP des HLTV-Servers ermittelt. Anschließend werden die genutzte und die maximale Slotzahl ermittelt. Aus der Subtraktion ergibt sich die Anzahl der freien Plätze auf dem HLTV-Server.

Gehört zu: admin.inc

8.10.80  get_username

get_username( sPlayer[], sName[], iMaxLength );

sPlayer[]
Typ: String (33)

sName[]
Typ: String (33)

iMaxLength
Typ: Integer (0 - 33)

Mit dieser Funktion kann aus einem Teil des Spielernamens der gesamte Name ermittelt werden, sofern der Teil des Namens eindeutig ist. D.h. der Teil darf nicht gleichzeitig Teil des Namens eines anderen Spielers sein. Statt des Teilnamens kann auch die IP, Steam ID oder Session ID angegeben werden.

 
Beispiel aus plugin_base (Funktion: admin_vote_kick):
612       get_username(Data,real_user,MAX_NAME_LENGTH);  
613       say_command(User,Command,Data);  
614       if(check_immunity(real_user)!=0) {

Aus Data (ob Teil-/Name, IP oder ID) wird der vollständige Spielername ermittelt. Den Einstellungen admin_quiet folgend wird die Ausführung des Befehls im Chat kommentiert (say_command). Anschließend wird über die Funktion check_immunity überprüft, ob einer Spieler dieses Namens Immunitätsrechte besitzt.

Gehört zu: admin.inc

Siehe auch: playerinfo, get_userSessionID

8.10.81  get_userorigin

get_userorigin( sPlayer[], &iX, &iY, &iZ );

sPlayer[]
Typ: String (33)

&iX
Typ: Integer (-2147483648 - 2147483647)

&iY
Typ: Integer (-2147483648 - 2147483647)

&iZ
Typ: Integer (-2147483648 - 2147483647)

Die Funktion gibt die Position des angegebenen Spielers (sPlayer) auf der Map zurück. Die Rückgabe erfolgt in kartesischen Koordinaten (x, y, z).

 
Beispiel aus plugin_retribution (Funktion: admin_bury):
507             get_userorigin(TargetName, x, y, z);  
508             teleport(TargetName, x, y, (z-25));

Zunächst werden die Koordinaten des Spielers (TargetName) ermittelt. Anschließend wird er um 25 Einheiten tiefer gesetzt (teleport). Sofern sich der Spieler zu diesem Zeitpunkt nicht hoch in der Luft befindet, wird er in den Boden versetzt, so dass er sich nicht mehr bewegen kann.

Gehört zu: admin.inc

Siehe auch: distance, teleport

8.10.82  get_userSessionID

get_userSessionID( sPlayer[], &iSessionID );

sPlayer[]
Typ: String (33)

&iSessionID
Typ: Integer (0 - 2147483647)

Liefert die Session ID des Spielers als Integerwert zurück. Die Session ID ist eindeutig und wird während der gesamten Laufzeit des Servers nur einmal vergeben. Die Nutzung der Session ID für Plugins ist eher ungewöhnlich, da sie nur über get_username in einen Namen umgewandelt werden kann.

 
Beispiel aus plugin_spooge_AR16 (Funktion: HandleSay):
334        new SessionID;  
335        get_userSessionID (User,SessionID);  
336        numtostr(SessionID,CmdBuffer);  
337        plugin_exec("admin_slap",CmdBuffer);

Die Session ID wird aus dem Spielernamen (User) ermittelt und anschließend von einer Ganzzahl in einen String umgewandelt (numtostr). Abschließend wird die Session ID an den Admin Mod Befehl admin_slap weitergeleitet (plugin_exec)

Gehört zu: admin.inc

Siehe auch: get_username

8.10.83  get_userTeam

get_userTeam( sPlayer[], &team );

sPlayer[]
Typ: String (33)

&team
Typ: Integer (0 - 4, 500, 600)

Die Funktion ermittelt die Team ID des Spielers (sPlayer). Die Teamzugehörigkeit kann auch über die Funktion playerinfo ermittelt werden.

Sonderteams sind kein Team (0), Spectator (500) und HLTV (600). Verschiedene Modifikationen haben unterschiedliche Teams:






ModTeam 1 Team 2 Team 3 Team 4





CS Terrorist Counter-Terrorist- VIP
TFCTeam BlauTeam Rot Team GelbTeam Grün
DoDAxis Allies - -





 
Beispiel aus plugin_CS (Funktion: menuselect):
1512                     new Team;  
1513                     get_userTeam(UserName,Team);  
1514                     Team = clamp(Team,1,2) - 1;

Zunächst wird das Team des Spielers ermittelt. Anschließend wird zur Vermeidung einer Feldadressierung außerhalb des gültigen Bereichs (4 - AMX_ERR_BOUNDS) die möglichen Teams auf 1 und 2 begrenzt. Zur weiteren Bearbeitung werden die Teamnummern dekrementiert.

Gehört zu: admin.inc

Siehe auch: playerinfo

8.10.84  get_userWONID

get_userWONID( sPlayer[], &iWONID );

sPlayer[]
Typ: String (33)

&iWONID
Typ: Integer (0 - 2147483647)

Die Funktion gibt die WONID (iWONID) des Spielers (sPlayer) als Integerwert zurück. Da das WON-System von Valve17 inzwischen durch Steam18 ersetzt wurde, ist die Funktion nutzlos geworden. Statt dessen sollte get_userAuthID genutzt werden.

 
Beispiel aus plugin_sdal_look19 (Funktion: ann_timer):
246    get_userWONID( Player, iWon );  
247  
248    if(iWon!=0){  
249       numtostr(iWon,strWON);

Auf Basis des Spielernamens (Player) wird seine WONID (iWon) ermittelt. Falls die WONID nicht 0 ist, wird sie in einen String umgewandelt.

Gehört zu: admin.inc

Siehe auch: get_userAuthID, playerinfo

8.10.85  get_vaultdata

get_vaultdata( sKey[], sData[], iMaxLength );

sKey[]
Typ: String (100)

sData[]
Typ: String (200)

iMaxLength
Typ: Integer (0 - 200)

Die Funktion liest die Daten, die unter dem Schlüssel (sKey) stehen, als String (sData) aus der vault.ini aus. Die Daten bleiben über einen Mapchange bzw. einen Serverneustart erhalten. Das Schlüssel-Daten-Paar wird mit set_vaultdata oder set_vaultnumdata angelegt. Die Funktion ist ideal um pluginspezifische Einstellungen zu speichern.

Weiß man bereits, dass die ausgelesenen Daten als Ganzzahl vorliegen, sollte man der Funktion get_vaultnumdata den Vorzug geben.

 
Beispiel aus plugin_retribution (Funktion: AddUserFlag):
69          if(get_vaultdata(sAuthID,VaultData,MAX_DATA_LENGTH) != 0) {  
70             if (strcasestr(VaultData," llama") == -1) {  
71                strcat(VaultData," llama", MAX_DATA_LENGTH);  
72                set_vaultdata(sAuthID,VaultData);  
73             }

Es wird versucht den Schlüssel mit der Steam ID des Spielers zu finden. Ist dies der Fall, wird das Ergebnis in VaultData zwischengespeichert. Falls das Ergebnis nicht bereits den Teilstring „ llama“ beinhaltet, wird dies dem Ergebis angehängt (strcat) und zurück in die vault.ini geschrieben.

8.10.86  get_vaultnumdata

get_vaultnumdata( sKey[], &iData );

sKey[]
Typ: String (100)

&iData
Typ: Integer (-2147483648 - 2147483647)

Die Funktion liest die Daten, die unter dem Schlüssel (sKey) stehen, als Ganzzahl (iData) aus der vault.ini aus. Die Daten bleiben über einen Mapchange bzw. einen Serverneustart erhalten. Das Schlüssel-Daten-Paar wird mit set_vaultdata oder set_vaultnumdata angelegt. Die Funktion ist ideal um pluginspezifische Einstellungen zu speichern.

Ist im Schlüssel ein String hinterlegt, darf man die Funktion nicht anwenden. Statt dessen ist get_vaultdata zu verwenden.

 
Beispiel aus plugin_bk_botmanager20 (Funktion: addbot):
150    if(get_vaultnumdata("BK_BM_BOTS",iBots) && iBots<=playercount()){  
151       return PLUGIN_CONTINUE;  
152    }

Der Schlüssel BK_BM_BOTS wird ausgelesen und die Daten in iBots geschrieben. Wenn der Schlüssel vorhanden und iBots kleiner gleich der Spieleranzahl ist, wird die Ausführung der Funktion addbot gestoppt und somit kein weiterer Bot hinzugefügt.

8.10.87  getarg

getarg( arg, index=0 );

arg
Typ: Integer
Wertebreich: (0 - 2147483647)

index=0
Typ: Integer (0 - 2147483647)

Diese Funktion wird nur Fällen gebraucht, wenn man die Argumente einer Funktion mit variabler Argumentanzahl auslesen möchte. Dabei gibt „arg“ die Position des Arguments beginnend mit 0 an. Das Argument „index“ wird nur benötigt, wenn arg ein Feld (z.B. ein String) ist. Es gibt die auszulesende Zelle des Feldes an.

 
Beispiel:

sum(...){  
   new result = 0 ;  
   for (new i = 0; i < numargs(); ++i) {  
      result += getarg(i);  
   }  
   return result;  
}

Eine Funktion „sum“ mit variabler Argumentanzahl (...) wird definiert. Eine For-Schleife fragt die einzelnen Argumente ab und addiert sie. Die Summe wird zurückgegeben. Die Anzahl der übergebenen Argumente wird mit numargs ermittelt.

Gehört zu: core.inc

Siehe auch: numargs, setarg

8.10.88  getchar

getchar( echo=true );

echo=true
Typ: Integer (0 - 1)

Diese Funktion liest die Tastatureingabe eines Zeichens aus und schreibt es bei der Option 1 in die Befehlszeile zurück. Mangels einer solchen Befehlszeile ist die Funktion in Admin Mod nutzlos.

Gehört zu: console.inc

Siehe auch: getstring, getvalue

8.10.89  getproperty

getproperty( id=0, const name[]=“”, value=cellmin, string[]=“” );

id=0
Typ: Integer (-2147483648 - 2147483647)

const name[]=“”
Typ: String (variabel)

value=cellmin
Typ: Integer (-2147483648 - 2147483647)

const string[]=“”
Typ: String (variabel)

Mit dieser Funktion kann eine sogenannte Property bei gegebenem Schlüssel (name oder value) ausgelesen werden. Die Property wird als String im Speicher abgelegt. Es handelt sich um eine Funktion, deren Benutzung unter Admin Mod vermieden werden sollte. Stattdessen wird empfohlen z.B. auf die Funktionen get_vaultdata oder set_vaultdata zurückzugreifen.

Mehr Informationen zum Thema sind im Abschnitt 8.14 nachzulesen.

 
Beispiel:
getproperty(2,“test_prop”,sString);
getproperty(3,15,sString);

Das erste Beispiel liest die in ID 2 befindliche Property „test_prop“ in die Variable sString aus, während das zweite Beispiel die in ID 3 befindliche Property 15 ausliest.

Gehört zu: core.inc

Siehe auch: existproperty, deleteproperty, setproperty

8.10.90  getstring

getstring( string[], size=sizeof string, bool:pack=false );

string
Typ: String (200)

size=sizeof string
Typ: Integer (0 - 200)

bool:pack=false
Typ: Integer (0 - 1)

Diese Funktion liest die Tastatureingabe komplett als String aus. Mit bool:pack kann definiert werden, ob der String gepackt oder ungepackt erwartet und ausgelesen wird. Mangels einer Befehlszeile für diese Tastatureingabe ist die Funktion in Admin Mod nutzlos.

Gehört zu: console.inc

Siehe auch: getchar, getvalue

8.10.91  getstrvar

getstrvar( sVarname[], sValue[], iMaxLength );

sVarname[]
Typ: String (100)

sValue[]
Typ: String (200)

iMaxLength
Typ: Integer (0 - 200)

Mit der Funktion kann man eine Servervariable (sVarname) als String (sValue) auslesen.

 
Beispiel aus plugin_base (Funktion: admin_pass):
344          new sPasswd[MAX_NAME_LENGTH];  
345          getstrvar( "sv_password", sPasswd, MAX_NAME_LENGTH );  
346          snprintf(Text, MAX_TEXT_LENGTH, "The password is: %s.", sPasswd);  
347          selfmessage(Text);

Die Servervariable „sv_password“ wird in sPasswd ausgelesen, formatiert (snprintf) und anschließend beim Spieler, der den Befehl ausgeführt hat, ausgegeben.

Gehört zu: admin.inc

Siehe auch: exec, getvar, setstrvar

8.10.92  gettarget

gettarget( sPlayer[], sTargetName[], iMaxLength, iRange = 2048 );

sPlayer[]
Typ: String (33)

sTargetName[]
Typ: String (33)

iMaxLength
Typ: Integer (0 - 33)

iRange = 2048
Typ: Integer (0 - 2147483647)

Mit dieser Funktion kann man ermitteln, auf welchen Gegner (sTargetName) der Spieler (sPlayer) zielt. Sie gibt auch den Userindex des Spielers direkt zurück. Das Argument iRange definiert die Blickweite.

 
Beispiel aus plugin_blatt_monster21 (Funktion: BBMonsterSpawn):
430  if (strlen(TargetName) ==0) {  
431     gettarget(UserName,TargetName,MAX_DATA_LENGTH);  
432     if (strlen(TargetName) ==0) {  
433       return PLUGIN_HANDLED;  
434     }  
435   }

Wenn kein Spieler angegeben wurde, wird überprüft, auf welchen Spieler der Admin schaut. Schaut er niemanden an, bricht das Plugin die Ausführung ab.

Gehört zu: admin.inc

Siehe auch: pointto

8.10.93  getteamcount

getteamcount( iTeam );

&team
Typ: Integer (0 - 4, 500, 600)

Die Funktion ermittelt die Anzahl der Spieler eines Teams auf Basis der Team ID (iTeam).

Sonderteams sind kein Team (0), Spectator (500) und HLTV (600). Verschiedene Modifikationen haben unterschiedliche Teams:






ModTeam 1 Team 2 Team 3 Team 4





CS Terrorist Counter-Terrorist- VIP
TFCTeam BlauTeam Rot Team GelbTeam Grün
DoDAxis Allies - -





 
Beispiel aus plugin_bk_botmanager22 (Funktion: addbot):
144    new iTplayers=getteamcount(TERROR);  
145    new iCTplayers=getteamcount(CT);

Die Variablen iTplayers und iCTplayers werden deklariert und gleichzeitig mit der Spielerzahl des jeweiligen Teams gefüllt. Dabei sind TERROR und CT jeweils Konstanten (1 bzw. 2).

Gehört zu: admin.inc

Siehe auch: get_userTeam, playerinfo

8.10.94  getvalue

getvalue( base=10, end=’^r’, ... );

base
Typ: Integer (2 - 32)

end
Typ: String (1)

Diese Funktion liest die Tastatureingabe als Ganzzahl aus. Dabei kann die Basis (base) definiert werden, sowie Abschlusszeichen für die Eingabe. Mangels einer Befehlszeile für diese Tastatureingabe ist die Funktion in Admin Mod nutzlos.

Gehört zu: console.inc

8.10.95  getvar

getvar( sVarname[] );

sVarname[]
Typ: String (100)

Mit der Funktion kann man eine Servervariable (sVarname) als Ganzzahl auslesen.

 
Beispiel aus plugin_CS (Funktion: HandleKickVote):
648       new Ratio = getvar("kick_ratio");  
649       if (VoteCount >= Ratio*UserCount/100) {  
650          if (g_AbortVote) {  
651             say("Kick vote was aborted by an admin");  
652          } else {  
653             set_timer("KickUser",10,1,VoteUser);  
654          }

Die Servervariable „kick_ratio“ wird als Ganzzahl in Ratio ausgelesen. Falls genügend Stimmen für den Kick zusammengekommen sind, wird entweder der Kick abgebrochen, weil ein Admin ihn aufgehalten hat, oder nach 10 Sekunden der entsprechende Spieler vom Server geworfen.

Gehört zu: admin.inc

Siehe auch: getstrvar

8.10.96  glow

glow( sTarget[], iRed = 0, iGreen = 0, iBlue = 0 );

sTarget[]
Typ: String (33)

iRed = 0
Typ: Integer (0 - 255)

iGreen = 0
Typ: Integer (0 - 255)

iBlue = 0
Typ: Integer (0 - 255)

Die Funktion lässt den Spieler sTarget in einer Farbe leuchten. Die Farbanteile werden über RGB (Rot, Grün, Blau) angegeben. Das Glühen wird abgeschaltet, indem alle Farbwerte auf 0 gesetzt werden.

 
Beispiel aus plugin_fun (Funktion: GlowHelper):
82 GlowHelper(User[], Color[]) {  
83    new iGoodColor = 1;  
84  
85    if (streq(Color,"red")==1) {  
86       glow(User,250,10,10);  
87    } else if ( streq(Color, "blue")==1) {  
88       glow(User,10,10,250);  
89    } else if ( streq(Color, "green")==1) {  
90       glow(User,10,250,10);  
91    } else if ( streq(Color, "white")==1) {  
92       glow(User,250,250,250);  
93    } else if ( streq(Color, "yellow")==1) {  
94       glow(User,250,250,10);  
95    } else if ( streq(Color, "purple")==1) {  
96       glow(User,250,10,250);  
97    } else if ( streq(Color, "off")==1) {  
98       glow(User,0,0,0);  
99    } else {  
100       iGoodColor = 0;  
101    }  
102    return iGoodColor;  
103 }

Die Funktion GlowHelper wandelt Farben, die in einem String (Color) übergeben werden, in einen RGB-Wert um und lässt den entsprechenden Spieler (User) in dieser Farbe glühen. Bei „off“ wird das Glühen abgeschaltet. Ist die übergebende Farbe nicht definiert gibt die Funktion einen Fehlerwert (iGoodColor) zurück.

Gehört zu: admin.inc

8.10.97  godmode

godmode( sPlayer[], iOnOff );

sPlayer[]
Typ: String (33)

iOnOff
Typ: Integer (0 - 1)

Die Funktion macht den Spieler (sPlayer) unverwundbar, wenn man als iOnOff eine 1 übergibt. Mit 0 stellt man den Godmode wieder aus. Es wird eine Nachricht allen Spielern auf dem Server angezeigt, dass der Spieler diese Fähigkeit erhalten hat. Diese Nachricht kann nicht ausgeschaltet werden!

 
Beispiel aus plugin_cheat (Funktion: admin_godmode):
61    if (check_user(strGodModeUser)==1) {  
62       say_command(User,Command,Data,1);  
63       godmode(strGodModeUser,iGodMode);  
64    } else {  
65       selfmessage("Unrecognized player: ");  
66       selfmessage(strGodModeUser);  
67    }

Wenn der entsprechende Spieler (strGodModeUser) auf dem Server ist, wird die Verwendung des Godmodes bekannt gegeben. Aber auch ohne say_command wird eine Meldung an alle Spieler abgesetzt. Da hier erheblich in die Spielmechanik eingegriffen wird, kann die Meldung nicht unterdrückt werden. Anschließend wird der Godmode für den entsprechenden Spieler ausgeführt.

Ist der Spieler nicht auf dem Server, wird das dem aufrufenden Admin in der Console mitgeteilt.

Gehört zu: admin.inc

Siehe auch: noclip

8.10.98  heapspace

heapspace( );

Die Funktion gibt die Größe des freien Heap-Speichers in Zellen zurück.

Diese Funktion wird verwendet, um Speicherlöcher in Scripten aufzuspüren. Speicherlöcher sind Fehler im Programm, die den verwendeten Speicher immer weiter anwachsen lassen, bis keiner mehr zur Verfügung steht und die Scriptausführung mit dem Fehler AMX_ERR_STACKERR beendet werden muss.

Üblicherweise liegt der Fehler allerdings nicht am Script selber, sondern am Wirtsprogramm (= Adminmod). Der Stack und der Heap belegen einen gemeinsamen Speicherbereich im Script, in dem dynamische Daten abgelegt werden (z.B. Funktionsparameter, lokale Variablen). Die Größe dieses Speicherbereiches kann durch die Präprozessordirektive #pragma dynamic n verändert werden, wobei n die Größe in Zellen ist. Die Standardgröße ist 2048 Zellen.

 
Beispiel aus plugin_blatt_map23 (Funktion: DebugHeap):
3641 DebugHeap(context[]) {  
3642   if (g_DebugLevel >= 2) {  
3643     new heapsize[MAX_TEXT_LENGTH];  
3644     snprintf(heapsize,MAX_TEXT_LENGTH,"[%s] %i free bytes.",context,heapspace());  
3645     plugin_message(heapsize);  
3646   }  
3647   return 0;  
3648 }

Wenn der in der globalen Variable (g_DebugLevel) Debuglevel größer oder gleich zwei ist, wird der noch verbleibende Heap-Speicher ermittelt und mittels plugin_message in der Console (Spieler- oder Serverconsole) ausgegeben.

Gehört zu: core.inc

8.10.99  help

help( sKeyword[]);

sKeyword[]
Typ: String (100)

Diese Funktion ist veraltet und wird nicht mehr in Scripts verwendet.

Wenn früher in der adminmod.cfg ein help_file gesetzt wurde, konnte man z.B. per Script help(“vote”) ausführen, um sich alle Beschreibungen zu „vote“ in der Konsole anzeigen zu lassen. Wenn kein Schlüsselwort (sKeyword) angegeben wurde, wurden alle Funktionen angezeigt.

Die Funktionalität wurde durch den direkten Admin Mod Befehl admin_help und die Funktionen plugin_registercmd und plugin_registerhelp ersetzt.

8.10.100  index

index( sSource[], iChar );

sSource[]
Typ: String (200)

iChar
Typ: Integer (0 - 256)

Die Funktion ermittelt die Position des ersten Vorkommens des Zeichens (iChar) im String (sSource) von links beginnend. Für das Zeichen muss die ASCII-Nummer angegeben werden. Vereinfacht kann auch das entsprechende Zeichen in einfache Anführungszeichen gesetzt werden. Die Funktion liefert -1 zurück, falls das Zeichen nicht gefunden wurde.

Die Funktion ist ein Alias für strchr.

 
Beispiel aus plugin_blatt_map24 (Funktion: ReadMapLine):
3004   pos=index(Line,’ ’);  
3005   if (pos>0) {  
3006       Line[pos]=NULL_CHAR;  
3007   }  
3008  

Es wird das erste Leerzeichen von links in Line gesucht. Wurde ein Leerzeichen gefunden, wird es durch ein String-Endzeichen (NULL_CHAR) ersetzt. Alle Funktionen, die den String von links zu lesen beginnen, werden an dieser Stelle beendet. Beginnt man von rechts, werden die Zeichen hinter dem String-Endzeichen zuerst gelesen. Man sollte daher genau wissen, was man tut, wenn man ein String-Endzeichen manuell setzt. Die Verwendung von strsep wäre eine Alternative.

Gehört zu: string.inc

Siehe auch: rindex, strchr, strrchr

8.10.101  kick

kick( sPlayer[] );

sPlayer[]
Typ: String (33)

Die Funktion wirft den Spieler (sPlayer) vom Server.

 
Beispiel aus plugin_base (Funktion: admin_kick):
272 if (strlen(Reason) != 0) {  
273    snprintf(Text, MAX_TEXT_LENGTH, "You have been kicked because %s", Reason);  
274    message(real_user, Text);  
275 }  
276 kick(real_user);

Es wird überprüft, ob ein Grund für den Kick angegeben wurde. Wenn es der Fall ist, wird dies dem Spieler mitgeteilt (message). Anschließend wird der Spieler vom Server geworfen.

Gehört zu: admin.inc

Siehe auch: ban

8.10.102  kill_timer

kill_timer( iTimer );

iTimer
Typ: Integer (0 - 512)

Mit dieser Funktion kann man einen laufenden Timer abbrechen. Dafür wird der Timer-Index (iTimer) benötigt, den man beim Ausführen des Timers set_timer zurückgeliefert bekommt. Es können nur Timer abgebrochen werden, die vom selben Plugin ausgeführt wurden.

 
Beispiel aus plugin_fun (Funktion: KillDisco):
122    for (i = 1; i <= iMaxPlayers; i++) {  
123       if(playerinfo(i,Name,MAX_NAME_LENGTH)==1) {  
124          glow(Name,0,0,0);  
125       }  
126    }  
127    centersay("Disco . . . Is Dead.",10,0,255,0);  
128    kill_timer(iDiscoTimer);

Alle Plätze des Servers werden überprüft. Falls ein Platz durch einen Spieler belegt wird, wird ein eventuelles Glühen abgestellt. Eine zehnsekündige Nachricht in Grün verkündet, dass Disco tot ist. Anschließend wird der Discotimer mit dem Index iDiscoTimer abgebrochen.

Gehört zu: admin.inc

Siehe auch: set_timer

8.10.103  list_maps

list_maps( );

Die Funktion zeigt dem ausführenden Spieler alle Maps aus der mapcycle.txt in der Console.

 
Beispiel aus plugin_base (Funktion: admin_listmaps):
122    selfmessage("The maps on the mapcycle are:");  
123    list_maps();  
124    selfmessage("and the current map is:");  
125    currentmap(curmap,100);  
126    selfmessage(curmap);

Es wird eine Überschrift für die zur Verfügung stehenden Maps im Cycle in der Console ausgegeben. Es folgt die Ausgabe dieser Maps und die Überschrift für die aktuelle Map. Die aktuelle Map wird ermittelt und in der Console ausgegeben.

Gehört zu: admin.inc

8.10.104  listspawn

listspawn( sClass[] );

sClass[]
Typ: String (100)

Die Funktion gibt alle Items an, die gespawned wurden. Man kann aber auch nur nach einem Teil (sClass) suchen.

Die Funktionalität steht mittlerweile nicht mehr zur Verfügung.

 
Beispiel aus plugin_spawn (Funktion: admin_listspawn):
61    convert_string(HLData,Data,MAX_DATA_LENGTH);  
62    listspawn(Data);

Der Suchtext wird von einem HL- in einen Small-String konvertiert (convert_string). Anschließend werden die in das Muster fallenden Items in der Console angezeigt.

Gehört zu: admin.inc

Siehe auch: movespawn, removespawn, spawn

8.10.105  log

log( sLogEntry[] );

sLogEntry[]
Typ: String (256)

Mit dieser Funktion können Daten (sLogEntry) in die Logdateien geschrieben werden.

 
Beispiel aus plugin_base (Funktion: plugin_init):
870    currentmap(strMap, MAX_DATA_LENGTH);  
871    snprintf(ExecCommand, MAX_DATA_LENGTH, "%s.cfg", strMap);  
872    if ( fileexists(ExecCommand) ) {  
873       snprintf(ExecCommand, MAX_DATA_LENGTH, "exec %s.cfg", strMap);  
874       log(ExecCommand);  
875       exec(ExecCommand);  
876    }

Es wird die aktuelle Map ermittelt und überprüft, ob sich im Modverzeichnis eine Konfiguartionsdatei für diese spezielle Map befindet. Existiert die Datei, wird sie ausgeführt. Dies ist eine oftmals übersehene Funktion Admin Mods, die der Basisfunktionalität des HL-Servers zugeschlagen wird.

Unter anderem wird der ausgeführte Befehl in die Logdateien geschrieben (Zeile 874).

Gehört zu: admin.inc

Siehe auch: log_command

8.10.106  log_command

log_command( sUser[],sCommand[],sData[] );

sUser[]
Typ: String (33)

sCommand[]
Typ: String (30)

sData[]
Typ: String (200)

Die Funktion schreibt einen formatierten Text in die Logdateien. Dazu muss der ausführende Admin (sUser), der ausgeführte Befehl (sCommand) und die Parameter (sData) angegeben werden. Die Ausgabe kann durch die Einstellung von admin_quiet beeinflusst werden.

 
Beispiel aus plugin_base (Funktion: admin_ssay):
496    strstripquotes(Data);  
497    say(Data);  
498    log_command(User,Command,Data);

Der in den Chat zu schreibende Text (Data) wird möglicher Anführungszeichen befreit und ausgegeben. Anschließend wird der Text inklusive Admin und dem genutzten Befehl in die Logdateien geschrieben.

Gehört zu: adminlib.inc

Siehe auch: format_command, log, say_command

8.10.107  look_in_dir

look_in_dir( sDirectory[], sMatch[], sFilename [], iNumber );

sDirectory[]
Typ: String (100)

sMatch[]
Typ: String (100)

sFilename []
Typ: String (100)

iNumber
Typ: Integer (0 - 2147483647)

Diese Funktion ist nur unter dem Betriebssystem Windows möglich. Unter Angabe des Verzeichnisses (sDirectory) wird überprüft, ob eine Datei unter Angabe eines Musters (sMatch) existiert. Wenn dies der Fall ist, wird der Dateiname an einen String (sFileName) übergeben. Es ist auch möglich „*“ als Joker im Muster zu verwenden. Die Ausgabe des x-ten Eintrags kann über iNumber eingestellt werden.

 
Beispiel aus plugin_rules25 (Funktion: showrules):
17    new i = 0;  
18    rulefound = look_in_dir("rules", "*.cfg", strRule, i);  
19  
20    while (rulefound == 1 && i < 100) {  
21       len = strlen(strRule)-3;  
22       strncpy(strRule, strRule, len, len);  
23       selfmessage(strRule);  
24       i++;  
25       rulefound = look_in_dir("rules", "*.cfg", strRule, i);  
26    }

Es wird im Verzeichnis „rules“ nach allen Konfigurationsdateien („*.cfg“) gesucht. Dabei wird das erste Vorkommen (i) in strRule zurückgegeben. In einer While-Schleife werden weitere Dateien ermittelt. Dabei wird vor der Ausgabe des Dateinamens dieser Suffix entfernt.

Gehört zu: admin.inc

8.10.108  maptime

maptime( iWhichtime, iPrintToConsole = 0 );

iWhichtime
Typ: Integer (0 - 1)

iPrintToConsole = 0
Typ: Integer (0 - 1)

Die Funktion kann die abgelaufene und die verbleibende Spielzeit (in Sekunden) auf der aktuellen Map angeben. Es ist zu definieren (iWhichtime), ob die abgelaufene (0) oder die verbleibende (1) Zeit ausgegeben werden soll. Man kann auch optional angeben, ob die Zeit in die Console geschrieben werden soll.

Die Funktion erkennt nicht den Restart einer Map in Counter-Strike. In diesem Fall sollte auf timeleft oder LogD basierte Berechnungen zurückgegriffen werden.

 
Beispiel aus plugin_wm_chat26 (Funktion: wmtl_check):
99 public wmtl_check() {  
100    new iTmp = maptime(1, 0);  
101    switch(iTmp) {  
102       case 1200: {wm_timeleft(1);}  
103       case 600: {wm_timeleft(1);}  
104       case 300: {wm_timeleft(1);}  
105       case 150: {wm_timeleft(1);}  
106       case 60: {wm_timeleft(1);}  
107       case 5: {execall("speak five");}  
108       case 4: {execall("speak four");}  
109       case 3: {execall("speak three");}  
110       case 2: {execall("speak two");}  
111       case 1: {  
112          execall("speak one");  
113          kill_timer(TV[0]);  
114          kill_timer(TV[1]);  
115       }  
116    }  
117 }

Im Beispiel wird die verbleibende Mapzeit ermittelt, ohne sie in die Console zu schreiben. Über eine Switch-Verzweigung wird eine userspezifische Funktion angesprochen bzw. via HL-Speech (vox) von fünf auf eins heruntergezählt. Bei 1 werden zwei Timer abgebrochen.

Gehört zu: admin.inc

Siehe auch: timeleft

8.10.109  matherror

matherror( iError );

iError
Typ: Integer (0 - 3)

Wandelt einen Fehlercode aus den Festkommaberechnungen der math.inc in lesbaren Text um und schreibt diesen in die Logdateien. Kann in Kombination mit den meisten Festkommaberechnungen verwendet werden.

 
Beispiel:

new fixed:fNegative=-4.000;  
new iError=0;  
iError=f_sqrt(fNegative);  
matherror(iError);

Es wird versucht aus einer negativen Zahl (fNegative), die Wurzel zu ziehen. Die Variable fNegative wird auf -1 und der Fehlercode (iError) auf 1 gesetzt. Mit matherror wird die Meldung „No valid value for function input!“ in die Logs geschrieben.

Gehört zu: math.inc

Siehe auch: f_degtorad

8.10.110  max

max( a, b );

a
Typ: Integer (-2147483648 - 2147483647)

b
Typ: Integer (-2147483648 - 2147483647)

Die Funktion liefert den Maximalwert zweier Ganzzahlen. Warum nicht auf die nativen Funktionen zurückgegriffen wird (core.inc), entzieht sich der Kenntnis des Autors.

Eine vergleichbare Funktion f_max gibt es auch für Festkommazahlen.

 
Beispiel aus plugin_bk_botmanager27 (Funktion: admin_bot_set):
270    if(strcasecmp(sBotCvar,"bots")==0){  
271       iValue=min(max(strtonum(sValue),0),maxplayercount());  
272       if(get_vaultnumdata("BK_BM_BOTS",iBots) && iBots<iValue){  
273          set_vaultnumdata("BK_BM_BOTS",iValue);

Wenn die Option, die übergeben wurde, gleich „bots“ ist, wird die übergebene Botanzahl zunächst durch eine Max-Auswahl mit 0 nach unten und anschließend durch eine Min-Auswahl gegen die maximale Spielerzahl (maxplayercount) begrenzt. Dies hätte man auch über die Funktion clamp lösen können.

Anschließend wird überprüft, ob der Eintrag „BK_BM_BOTS“ in der vault.ini existiert, und ob die bisherige dort abgelegte Botanzahl kleiner als der neue Wert ist. Der neue Wert wird anschließend in „BK_BM_BOTS“ geschrieben.

Gehört zu: adminlib.inc

Siehe auch: clamp, f_max, f_min, min

8.10.111  maxplayercount

maxplayercount( );

Die Funktion ermittelt die maximale mögliche Spielerzahl auf dem Server.

 
Beispiel aus plugin_fun (Funktion: KillGlow):
105 KillGlow() {  
106        new i;  
107        new iMaxPlayers = maxplayercount();  
108        new Name[MAX_NAME_LENGTH];  
109  
110        for (i = 1; i <= iMaxPlayers; i++) {  
111                if(playerinfo(i,Name,MAX_NAME_LENGTH)==1) {  
112                    glow(Name,0,0,0);  
113                }  
114        }  
115 }

Die maximale Spielerzahl wird ermittelt und als Maximalwert für die For-Schleife verwendet. Auf diese Weise muss man nicht alle 32 theoretisch möglichen Slots durchsuchen. In dieser For-Schleife wird bei allen Spielern das Glühen abgeschaltet.

Gehört zu: admin.inc

Siehe auch: playercount

8.10.112  menu

menu( username[],text[],keys ,time=0 );

username[]
Typ: String (33)

text[]
Typ: String (512)

keys
Typ: Integer (0 - 1024)

time=0
Typ: Integer (0 - 2147483647)

Unter Angabe des Spielers (username) kann man eine Nachricht (text) in Form eines Menüs anzeigen lassen. Mit dem der Variable keys wird definiert, welche Ziffertasten als Eingabe-Optionen verwendet werden sollen. Die Zahl errechnet sich aus der Summe der Zweierpotenzen von 2n-1. Die Zahl n steht für die jeweilige Ziffertaste. Die Ziffer 0 ist für die Variable keys eine 10 (210-1 = 512). Der Wert 1024 sperrt alle Ziffertasten.

Sollen z.B. nur die Tasten 0 bis 3 auswählbar sein, ergibt sich

keys = 210-1 + 21-1 + 22-1 + 23-1 = 512 + 1 + 2 + 4 = 519

Mit der Variable time definiert man die Dauer der Bildschirmausgabe. Wird der Wert nicht angegeben oder wird eine 0 übergeben, bleibt das Menü offen bis etwas ausgewählt wurde oder das Menü von einem anderen überschrieben wurde. Es gibt keine Überprüfungsmöglichkeit, ob beim Spieler bereits ein Menü geöffnet ist.

Die Auswertung erfolgt über den registrierten HL-Befehl „menuselect“ (Tutorial).

 
Beispiel aus plugin_CS (Funktion: DrawSubMenu):
1625     strcat(Menutext,"^n^n\w0. Back",512);  
1626     Keys |= 512;  
1627     playerinfo(UserIndex,UserName,MAX_NAME_LENGTH);  
1628     g_UserMenuSelected[UserIndex] = -Menu;  
1629     menu(UserName,Menutext,Keys,0);

Es wird an den Menütext (Menutext) die Option 0 (Back) angehängt. Ein bitweises „Oder“ wird auf Keys und 512 angesetzt und das Ergebnis in Keys geschrieben. Hier hätte man auch einfach addieren können. Mittels playerinfo wird der Spielername ermittelt und die negative Nummer des Menüs wird in das globale Feld eingetragen, damit man weiß, in welchem Menü der Spieler sich befindet. Abschließend wird das Menü permanent bis zu einer Optionsauswahl bzw. einem überschreibenden Menü angezeigt.

Gehört zu: admin.inc

Siehe auch: vote

8.10.113  message

message( sTarget[], sMessage[] );

sTarget[]
Typ: String (33)

sMessage[]
Typ: String (100)

Die Funktion schreibt eine Nachricht (sMessage) in die Console der angegebenen Person (sTarget). Die Funktion messageex bietet einen größeren Umfang.

 
Beispiel aus plugin_base (Funktion: admin_kick):
272 if (strlen(Reason) != 0) {  
273    snprintf(Text, MAX_TEXT_LENGTH, "You have been kicked because %s", Reason);  
274    message(real_user, Text);  
275 }  
276 kick(real_user);

Es wird überprüft, ob ein Grund für den Kick angegeben wurde. Wenn dies der Fall ist, wird dies dem Spieler in der Konsole mitgeteilt. Anschließend wird der Spieler vom Server geworfen (kick).

Gehört zu: admin.inc

Siehe auch: centersayex, directmessage, messageex

8.10.114  messageex

messageex( sTarget[],sMessage[], print_type:iMessageType );

sTarget[]
Typ: String (33)

sMessage[]
Typ: String (100)

print_type:iMessageType
Typ: Enum (0=print_console, print_center, print_chat, print_tty, print_pretty)

Die Funktion schreibt eine Nachricht (sMessage) an die angegebene Person (sTarget). Die Art, wie sie dem Spieler angezeigt werden soll, wird mit print_type definiert.

Es gibt 5 Darstellungen:

print_console
Anzeige in der Konsole
print_center
Anzeige in normaler Schrift in der Mitte des Bildschirmes
print_chat
Anzeige im Chat
print_tty
Anzeige in gelb am linken, unteren Bildschirmrand
print_pretty
Anzeige in grün in der Mitte des Bildschirmes

 
Beispiel aus plugin_base (Funktion: admin_psay):
413    snprintf(Text, MAX_TEXT_LENGTH, "(Private Msg From %s): %s", User, Msg);  
414    if (iMsgToAdmin == 1) {  
415       log(Text);  
416    } else {  
417       messageex(TargetName, Text, print_chat);  
418    }

Stellt einen Präfix mit dem Absender (User) vor die eigentliche Nachricht (Msg). Wenn die Nachricht an einen Admin in der Serverconsole gehen soll, wird der Text in die Logdateien geschrieben. Anderenfalls wird dem Empfänger (TargetName) die Nachricht im Chat präsentiert.

8.10.115  min

min( a, b );

a
Typ: Integer (-2147483648 - 2147483647)

b
Typ: Integer (-2147483648 - 2147483647)

Die Funktion liefert den Minimalwert zweier Ganzzahlen. Warum nicht auf die nativen Funktionen zurückgegriffen wird (core.inc), entzieht sich der Kenntnis des Autors.

Eine vergleichbare Funktion f_min gibt es auch für Festkommazahlen.

 
Beispiel aus plugin_bk_botmanager28 (Funktion: admin_bot_set):
270    if(strcasecmp(sBotCvar,"bots")==0){  
271       iValue=min(max(strtonum(sValue),0),maxplayercount());  
272       if(get_vaultnumdata("BK_BM_BOTS",iBots) && iBots<iValue){  
273          set_vaultnumdata("BK_BM_BOTS",iValue);

Wenn die Option, die übergeben wurde, gleich „bots“ ist, wird die übergebene Botanzahl zunächst durch eine Max-Auswahl mit 0 nach unten und anschließend durch eine Min-Auswahl gegen die maximale Spielerzahl (maxplayercount) begrenzt. Dies hätte man auch über die Funktion clamp lösen können.

Anschließend wird überprüft, ob der Eintrag „BK_BM_BOTS“ in der vault.ini existiert, und ob die bisherige dort abgelegte Botanzahl kleiner als der neue Wert ist. Der neue Wert wird anschließend in „BK_BM_BOTS“ geschrieben.

Gehört zu: adminlib.inc

Siehe auch: clamp , f_max, f_min, max

8.10.116  motd

motd( sTarget[],sMessage[] );

sTarget[]
Typ: String (33)

sMessage[]
Typ: String (1536)

Sofern die Modifikation es unterstützt, kann man mit dieser Funktion ein „Message of the Day“ Fenster mit einer Nachricht (sMessage) bei einem bestimmten Spieler (sTarget) öffnen. Die Anzahl der Zeichen ist äußerst begrenzt. Insbesondere bei HTML-Seiten sollte man besser nur eine automatische Weiterleitung auf eine echte HTML-Seite generieren.

 
Beispiel aus plugin_base (Funktion: admin_motd):
810    strbreak(Data, Target, Msg, MAX_TEXT_LENGTH);  
811    if (strlen(Msg) == 0) {  
812       selfmessage( "Unparsable format: no message found.");  
813       return PLUGIN_HANDLED;  
814    } else if (check_user(Target) == 0) {  
815       selfmessage("Unrecognized player: ");  
816       selfmessage(Target);  
817       return PLUGIN_HANDLED;  
818    }  
819    get_username(Target,TargetName,MAX_NAME_LENGTH);  
820  
821    motd( TargetName, Msg );

Zunächst werden die übergebenen Daten aus dem Befehl in einen Spieler- und einen Nachrichtteil getrennt. Trennzeichen ist das erste Leerzeichen (strbreak). Wenn keine Nachricht gefunden wurde oder der Spieler nicht auffindbar ist, wird die Abarbeitung mit einer Fehlermeldung an den aufrufenden Admin abgebrochen. Die Funktion get_username macht aus einer ID oder einer IP einen Namen und nutzt diesen zur Ausgabe der Nachricht.

Gehört zu: admin.inc

8.10.117  movespawn

movespawn( iIdentity, iX, iY, iZ, iXAngle, iYAngle, iZAngle );

iIdentity
Typ: Integer (0 - 2147483647)

iX
Typ: Integer (-2147483648 - 2147483647)

iY
Typ: Integer (-2147483648 - 2147483647)

iZ
Typ: Integer (-2147483648 - 2147483647)

iXAngle
Typ: Integer (0 - 359)

iYAngle
Typ: Integer (0 - 359)

iZAngle
Typ: Integer (0 - 359)

Die Funktion verschiebt ein Item (iIdentity) auf eine bestimmte Position (iX, iY, iZ) und in einer bestimmten Ausrichtung (iXAngle, iYAngle, iZAngle).

Die Funktionalität steht mittlerweile nicht mehr zur Verfügung.

 
Beispiel aus plugin_spawn (Funktion: admin_movespawn):
143    if(movespawn(iIdentity,X,Y,Z,XAngle,YAngle,ZAngle)==1) {  
144       selfmessage("Success.");  
145       say_command(User,Command,Data);  
146    } else {  
147       selfmessage("Failed.");  
148    }

Es wird versucht ein Item zu verschieben. Falls dies erfolgreich war, wird eine Erfolgsmeldung an den Admin und alle anderen Spieler ausgegeben. Anderenfalls wird nur der Admin über den fehlgeschlagenen Versuch informiert.

Gehört zu: admin.inc

Siehe auch: listspawn, removespawn, spawn

8.10.118  nextmap

nextmap( sMap[], iMaxLength );

sMap[]
Typ: String (100)

iMaxLength
Typ: Integer (0 - 100)

Die Funktion gibt die nach der aktuellen geladene Map (sMap) aus. Sie berücksichtigt keine Plugins, die in den Mapwechsel eingreifen, sondern geht in der Ermittlung nach der Methode des HL-Servers vor. Nur bei der ersten Map nach dem Serverstart stimmt die Anzeige nicht.

 
Beispiel aus plugin_chat (Funktion: SayNextMap):
52 SayNextMap() {  
53    nextmap(NextMap,MAX_NAME_LENGTH);  
54    snprintf(Text, MAX_TEXT_LENGTH, "The next map will be: %s", NextMap);  
55    say(Text);  
56 }

Die nächste Map wird ermittelt, in einen Text eingebettet und im Chat an alle Spieler ausgegeben.

Gehört zu: admin.inc

Siehe auch: currentmap

8.10.119  noclip

noclip( sPlayer[], iOnOff );

sPlayer[]
Typ: String (33)

iOnOff
Typ: Integer (0 - 1)

Die Funktion lässt den Spieler (sPlayer) durch Wände gehen, wenn man als iOnOff eine 1 übergibt. Mit 0 stellt man den Noclip Modus wieder aus. Es wird eine Nachricht allen Spielern auf dem Server angezeigt, dass der Spieler diese Fähigkeit erhalten hat. Diese Nachricht kann nicht ausgeschaltet werden!

 
Beispiel aus plugin_cheat (Funktion: admin_noclip):
86    if (check_user(strNoclipUser)==1) {  
87       say_command(User,Command,Data,1);  
88       noclip(strNoclipUser,iNoclip);  
89    } else {  
90       selfmessage("Unrecognized player: ");  
91       selfmessage(strNoclipUser);  
92    }

Wenn der entsprechende Spieler (strNoclipUser) auf dem Server ist, wird die Verwendung des Noclip Modus bekannt gegeben. Aber auch ohne say_command wird eine Meldung an alle Spieler abgesetzt. Da hier erheblich in die Spielmechanik eingegriffen wird, kann die Meldung nicht unterdrückt werden. Anschließend wird der Noclip Modus für den entsprechenden Spieler ausgeführt.

Ist der Spieler nicht auf dem Server wird das dem aufrufenden Admin in der Console mitgeteilt.

Gehört zu: admin.inc

8.10.120  numargs

numargs( );

Diese Funktion wird nur Fällen gebraucht, wenn man die Anzahl der Argumente einer Funktion mit variabler Anzahl auslesen möchte.

 
Beispiel:

sum(...){  
   new result = 0 ;  
   for (new i = 0; i < numargs(); ++i) {  
      result += getarg(i);  
   }  
   return result;  
}

Eine Funktion „sum“ mit variabler Argumentanzahl (...) wird definiert. Eine For-Schleife fragt die einzelnen Argumente ab (getarg) und addiert sie. Die Summe wird zurückgegeben. Die Anzahl der übergebenen Argumente wurde dabei mit numargs ermittelt.

Gehört zu: core.inc

Siehe auch: numargs, setarg

8.10.121  numtostr

numtostr( num, str[] );

num
Typ: Integer (-2147483648 - 2147483647)

str[]
Typ: String (20)

Die Funktion wandelt eine Ganzzahl (num) in einen String (str) um.

 
Beispiel aus plugin_CS (Funktion: HandleRestartVote):
544    new Timelimit[MAX_NUMBER_LENGTH];  
545    numtostr((getvar("mp_timelimit") * 60 - timeleft() + 10) / 60,Timelimit);  
546    setstrvar("mp_timelimit",Timelimit);  
547    setstrvar("sv_restartround","10");  
548    say("Round restart vote succeeded.");

Vom aktuellen Zeitlimit auf dem Server wird die Restzeit abgezogen und 10 Sekunden addiert. Dieser Wert wird als neues Zeitlimit eingetragen. Anschließend wird ein Maprestart nach 10 Sekunden angefordert und der Restart allen Spielern mitgeteilt.

Gehört zu: adminlib.inc

Siehe auch: strtonum

8.10.122  playercount

playercount( );

Die Funktion gibt die Anzahl der Spieler auf dem Server als Ganzzahl zurück.

 
Beispiel aus plugin_logd_redirect29 (Funktion: logd_redirect):
71 Count = maxplayercount();  
72 Count2 = playercount();  
73  
74 snprintf(Text,MAX_TEXT_LENGTH,"Maxplayers = %i^nPlayerCount = %i",Count,Count2);  
75 messageex(User,Text,print_chat);

Es wird die maximal mögliche (Count) und die tatsächliche Spielerzahl (Count2) ermittelt. Die Ausgabe wird formatiert und im Chat des entsprechenden Spielers ausgegeben.

Gehört zu: admin.inc

Siehe auch: maxplayercount

8.10.123  playerinfo

playerinfo( iPlayerIndex, sName[], iLength, &iUserID = 0, &iWONID = 0,
&iTeam = 0, &iDead = 0, sAuthID[MAX_AUTHID_LENGTH] = “” );

iPlayerIndex
Typ: Integer (1 - 32)

sName[]
Typ: String (33)

iLength
Typ: Integer (0 - 33)

&iUserID = 0
Typ: Integer (0 - 2147483647)

&iWONID = 0
Typ: Integer (0 - 2147483647)

&iTeam = 0
Typ: Integer (0 - 4, 500, 600)

&iDead = 0
Typ: Integer (0 - 1)

sAuthID[MAX_AUTHID_LENGTH] = “”
Typ: String (39)

Diese Funktion dient zur umfassenden Ermittlung diverser Spielerinformation. Dies sind Name (sName), Session ID (iUserID), WONID (iWONID), Teamzugehörigkeit (iTeam), Lebensstatus (iDead) und die Steam ID (sAuthID). Sie gibt darüber hinaus direkt aus, ob ein Spieler mit dem zugehörigen Userindex existiert. Optionale Argumente können mit „_“ ausgespart werden, wenn nicht sie sondern die nachfolgenden benötigt werden.

 
Beispiel aus plugin_retribution (Funktion: admin_bury):
499          get_userindex(Data, nIndex);  
500          playerinfo(nIndex, TargetName, MAX_NAME_LENGTH, _, _, _, nDead);

Der Status eines Spielers (lebend oder tot) lässt sich mit Admin Mod nur mit der Funktion playerinfo ermitteln. Da sie den Userindex benötigt, muss zunächst aus dem Namen (Data) der Userindex (nIndex) ermittelt werden. Anschließend kann der Status abgefragt werden. TargetName ist eigentlich nicht notwendig, ist jedoch eine Pflichtrückgabe. Auf die weiteren Variablen kann verzichtet werden. Als Auslassungszeichen wird der Unterstrich verwendet. Die Steam ID wurde ebenfalls ausgelassen.

8.10.124  playsound

playsound( sTarget[], sSound[] );

sTarget[]
Typ: String (33)

sSound[]
Typ: String (100)

Die Funktion spielt eine Wave Datei (sSound) beim angegebenen Spieler (sTarget) ab. Der Spieler muss diese Datei bereits auf dem Rechner haben. Bei der Angabe der Wavedatei darf der Pfad nicht vergessen werden. Der Pfad beginnt im „sound“ Verzeichnis.

 
Beispiel aus plugin_retribution (Funktion: PlaySoundToAll):
98 PlaySoundToAll(sSound[]) {  
99    new i;  
100    new iMaxPlayers = maxplayercount();  
101    new Name[MAX_NAME_LENGTH];  
102  
103    if (getvar("admin_fx") != 0) {  
104       for (i = 1; i <= iMaxPlayers; i++) {  
105          if (playerinfo(i,Name,MAX_NAME_LENGTH) != 0) {  
106             playsound(Name, sSound);  
107          }  
108       }  
109    }  
110 }

Das Abspielen der Sounddatei (sSound) wird nur durchgeführt, wenn admin_fx angeschaltet ist. Anschließend werden mit einer For-Schleife alle Serverslots nach Spielern durchsucht. Wenn ein Spieler gefunden wurde, wird bei im die Sounddatei (sofern auf seinem Rechner vorhanden) abgespielt.

Gehört zu: admin.inc

Siehe auch: speakto

8.10.125  plugin_checkcommand

plugin_checkcommand( sCommand[], &iAccess = 0 );

sCommand[]
Typ: String (30)

&iAccess = 0
Typ: Integer (0 - 2147483647)

Die Funktion gibt zurück, wieviele Plugins den Admin Mod Befehl (sCommand) registriert haben. Darüber hinaus wird der dafür notwendige Access Level (iAccess) zurückgegeben. In Kombination mit plugin_exec lässt sich ein Plugin-Addon-System aufbauen.

 
Beispiel aus plugin_cw_creator30 (Funktion: warmup_end):
628    if (plugin_checkcommand("cwc_addon_start",iAccess)>0){  
629       plugin_exec("cwc_addon_start","");  
630       iAccess=0;  
631    }

In diesem Fall wird ausgewertet, ob mindestens ein Plugin den Admin Mod Befehl „cwc_addon_start“ registriert hat. Falls mindestens ein Plugin gefunden wurde, wird der Befehl ausgeführt.

Gehört zu: plugin.inc

8.10.126  plugin_command

plugin_command( HLCommand, HLData, HLUserName, UserIndex )

HLCommand
Typ: HLString (33)

HLData
Typ: HLString (200)

HLUserName
Typ: HLString (30)

UserIndex
Typ: Integer (0 - 32)

Bei der Funktion plugin_command handelt es sich um ein Event, mit dem alle Befehle abgefangen werden können. Sie wird vor allem in Antiflood Plugins eingesetzt.

 
Beispiel aus plugin_blatt_map31 (Funktion: plugin_command):
98 public plugin_command(HLCommand,HLData,HLUserName,UserIndex) {  
99   if (g_BuySupressed==0) {  
100     return PLUGIN_CONTINUE;  
101   }  
102  
103   new Command[MAX_COMMAND_LENGTH];  
104   safe_convert(HLCommand,Command,MAX_COMMAND_LENGTH);  
105  
106   if (strmatch(Command,"say",3)==1) {  
107     return PLUGIN_CONTINUE;  
108   }  
109   if (streq(Command,"drop")) {  
110     return PLUGIN_CONTINUE;  
111   }  
112  
113   return PLUGIN_HANDLED;  
114 }

In diesem Beispiel wird die Ausführung aller Befehle außer „say“ und „drop“ unterbunden (PLUGIN_HANDLED). Außerdem kann eine globale Variable (g_BuySupressed) das Unterbinden verhindern.

Dieser Code macht nur Sinn, wenn das Plugin als zweites (hinter plugin_antiflood ausgeführt wird. Nur Befehle aus Plugins, die sich in der Ladereihenfolge hinter plugin_blatt_map befinden, können blockiert werden.

8.10.127  plugin_connect

plugin_connect( HLUserName, HLIP, UserIndex )

HLUserName
Typ: HLString (30)

HLIP
Typ: HLIP (22)

UserIndex
Typ: Integer (0 - 32)

Bei der Funktion plugin_connect handelt es sich um ein Event, mit dem man Informationen zum den Server beitretenden Spieler erhalten (Name, IP, Slot) kann. Leider ist der Event in der Regel zu früh, so dass weder Spielername noch seine IP zurückgegeben werden. Nur der Slot (UserIndex) lässt sich zuverlässig nutzen. Mehr Informationen sind dem Tutorial zu entnehmen.

 
Beispiel aus plugin_message (Funktion: plugin_connect):
60 public plugin_connect(HLUserName, HLIP, UserIndex) {  
61    set_timer("say_hello",45,0);  
62    return PLUGIN_CONTINUE;  
63 }

Beim Beitreten eines Spielers wird ein 45 Sekunden Timer auf die Funktion „say_hello“ ausgelöst.

8.10.128  plugin_disconnect

plugin_disconnect( HLUserName, UserIndex )

HLUserName
Typ: HLString (30)

UserIndex
Typ: Integer (0 - 32)

Bei der Funktion plugin_disconnect handelt es sich um ein Event, mit dem man Informationen zum den Server verlassenden Spieler erhalten (Name, Slot) kann.

 
Beispiel aus plugin_bk_hltvannounce32 (Funktion: plugin_disconnect):
81 public plugin_disconnect(HLUserName, UserIndex){  
82    if (hltvid==UserIndex){  
83       hltvid=0;  
84       hltvteam=0;  
85 #if LANG==1  
86       typesay("Der HLTV ist jetzt offline!",3,181,40,44);  
87 #else  
88       typesay("The HLTV is offline!",3,181,40,44);  
89 #endif  
90    }  
91    return PLUGIN_CONTINUE;  
92 }

Falls es sich beim übergebenen Userindex (UserIndex) um den des HLTV-Servers (hltvid) handelt, wird Verlassen des HLTV-Servers mit typesay bekannt gegeben. Die Sprache wird beim Compilieren des Plugins durch die Direktive LANG eingestellt.

8.10.129  plugin_exec

plugin_exec( sCommand[], sArguments[] );

sCommand[]
Typ: String (30)

sArguments[]
Typ: String (200)

Um zu verhindern, dass man mit der Funktion exec pluginübergreifend das Rechtesystem untergräbt, wurde plugin_exec eingeführt. Diese Funktion überprüft, ob der ausführende Spieler auch die Rechte für den Befehl des anderen Admin Mod Plugins hat.

 
Beispiel aus plugin_cw_creator33 (Funktion: warmup_end):
628    if (plugin_checkcommand("cwc_addon_start",iAccess)>0){  
629       plugin_exec("cwc_addon_start","");  
630       iAccess=0;  
631    }

In diesem Beispiel wird ausgewertet, ob mindestens ein Plugin den Admin Mod Befehl „cwc_addon_start“ registriert hat. Falls mindestens ein Plugin gefunden wurde, wird der Befehl mit plugin_exec ausgeführt. Der Befehl erwartet keine Argumente, so dass sie leer gelassen wurden.

Gehört zu: admin.inc

Siehe auch: exec

8.10.130  plugin_info

plugin_info( HLOldName, HLNewName, UserIndex )

HLOldName
Typ: HLString (33)

HLNewName
Typ: HLString (33)

UserIndex
Typ: Integer (0 - 32)

Bei der Funktion plugin_info handelt es sich um ein Event, mit dem man den Namenswechsel eines Spielers auswerten kann. Das Event wird auch beim Connect mehrfach ausgeführt, so dass es hin und wieder als Ersatz für plugin_connect herangezogen wird. Da der Event nicht immer mit einem echten Namenswechsel verbunden ist, sollte man ihn mit Weitsicht verwenden.

 
Beispiel aus plugin_retribution (Funktion: plugin_info):
683 public plugin_info(HLOldName,HLNewName,UserIndex) {  
684    new iIgnoreGag = 0;  
685    new GagTime;  
686    new Command[MAX_TEXT_LENGTH];  
687    new NewName[MAX_NAME_LENGTH];  
688    new OldName[MAX_NAME_LENGTH];  
689  
690    convert_string(HLNewName, NewName, MAX_NAME_LENGTH);  
691    convert_string(HLOldName, OldName, MAX_NAME_LENGTH);  
692  
693    /* Only bother if the name has changed. */  
694    if(streq(OldName,NewName)==0) {

Der alte und der neue Spielername (HLNewName und HLOldName) werden in Small Strings konvertiert (convert_string). Die weitere Auswertung erfolt nur, wenn der alte nicht dem neuen Namen entspricht (streq).

8.10.131  plugin_init

plugin_init( )

Bei der Funktion plugin_init handelt es sich um ein Event, das nur beim Plugin Start ausgeführt. Es entspricht der main Funktion in der Sprache C. Jedes Plugin muss diese Funktion besitzen (siehe auch im Tutorial).

 
Beispiel aus plugin_antiflood (Funktion: plugin_init):
217 public plugin_init()  
218 {  
219    plugin_registerinfo("Admin Anti-Flood Plugin", "Auto kicks flooders", VERSION);  
220  
221    return PLUGIN_CONTINUE;  
222 }

Dieses Beispiel zeigt die simpelste Form von plugin_init. Es wird lediglich das Plugin bei Admin Mod registriert (plugin_registerinfo). Es können außerdem Befehle registriert aber auch beliebiger Code ausgeführt werden. Die Funktion plugin_exec funktioniert allerdings zu diesem Zeitpunkt prinzipbedingt noch nicht.

8.10.132  plugin_message

plugin_message( sMessage[] );

sMessage[]
Typ: String (100)

Die Funktion schreibt eine Nachricht (sMessage) in Console des aufrufenden Spielers. Im Gegensatz zur Funktion selfmessage wird auch das Plugin genannt, das die Nachricht ausgibt.

 
Beispiel aus plugin_CS (Funktion: LoadDefaultRestrictions):
937     if(get_vaultdata(strName,strKey,MAX_ITEMS+1)) {  
938         plugin_message("Map-specific saved weapon restrictions found.");  
939     } else if(get_vaultdata("WeaponRestrictions",strKey,MAX_ITEMS+1)) {  
940         plugin_message("Default saved weapon restrictions found.");  
941     } else {  
942         plugin_message("No saved weapon restrictions found.");  
943     }

Es wird nach mapspezifischen und allgemeinen Waffeneinschränkungen gesucht. Wenn der Eintrag (strName) in der vault.ini gefunden wurde, wird in der Console ausgegeben, dass mapspezifische Restriktionen geladen wurden. Beim Eintrag „WeaponRestrictions“ wird ausgegeben, dass die Standardeinschränkungen geladen wurden. Wurde kein Eintrag ausgemacht, erscheint in der Console, dass keine Restriktionen geladen wurden.

Gehört zu: plugin.inc

Siehe auch: selfmessage

8.10.133  plugin_registercmd

plugin_registercmd( Command[], Function[], RequiredAccess,
HelpMessage[]= “” );

Command[]
Typ: String (30)

Function[]
Typ: String (19)

RequiredAccess
Typ: Integer (0 - 2147483647)

HelpMessage[]= “”
Typ: String (150)

Die Funktion dient der Registrierung eines Befehls (Command), der z.B. in der Console eingegeben wird. Als Argumente müssen die aufzurufende Funktion (Function) und der nötige Access Level (RequiredAccess) angegeben werden. Optional kann ein Hilfetext (z.B. die Syntax) angegeben werden, der dann beim Aufruf von admin_help ausgegeben wird. Man verwendet diesen Befehl üblicherweise nur in plugin_init. Mehr zu diesem Befehl ist auch dem Tutorial zu entnehmen.

 
Beispiel aus plugin_bk_alltalk34 (Funktion: plugin_init):
27 plugin_registerinfo("Alltalk changer","Switches sv_alltalk",STRING_VERSION);  
28 plugin_registercmd("admin_alltalk","admin_alltalk",A_KICK,"Switches sv_alltalk.");

Zunächst wird das Plugin registriert. Anschließend wird der Befehl „admin_alltalk“ mit der gleichnamigen Funktion registriert. Der Spieler benötigt Kickrechte. Hier wurde aus Darstellungsgründen „A_KICK“ geschrieben. Richtig ist jedoch „ACCESS_KICK“. Einen Überblick über die Access Level und die zugehörigen Direktiven ist der admin.inc zu entnehmen. Zu letzt wird ein Hilfetext für die Anzeige in admin_help festgelegt.

8.10.134  plugin_registerhelp

plugin_registerhelp( Command[], RequiredAccess, HelpMessage[] );

Command[]
Typ: String (30)

RequiredAccess
Typ: Integer (0 - 2147483647)

HelpMessage[]
Typ: String (150)

Einen Hilfetext kann man bereits mit plugin_registercmd anlegen. Es gibt jedoch auch Fälle, bei denen z.B. zwei Argumente übergeben werden müssen. Basierend auf dem ersten Argument müssen unterschiedliche zweite Argumente eingegeben werden. Man kann dann für alle ersten Argumente Hilfetexte anlegen. Wichtig ist die Funktion auch beim Abfangen von „say“ Nachrichten. Da viele Plugins den Chat für die Befehlseingabe nutzen, sollte man die eigenen Chatbefehle mittels plugin_registerhelp mit einem Hilfetext ausstatten. Die Registrierung von „say“ sollte hingegen keinen Hilfetext beinhalten.

Es muss der dem Hilfetext (HelpMessage) zugehörige Befehl (Command) und der notwendige Access Level (RequiredAccess) angegeben werden. Beim Aufruf von admin_help wird der Hilfetext dann angezeigt.

 
Beispiel aus plugin_bk_timeleft35 (Funktion: plugin_init):
36 plugin_registerinfo("Akurates Timeleft","Genaue Restzeitangabe.",STRING_VERSION);  
37 plugin_registercmd("say","HandleSay",ACCESS_ALL);  
38 plugin_registerhelp("say",ACCESS_ALL,"say timeleft: Gibt die Restzeit an.");

Zunächst wird das Plugin registriert und anschließend der „say“ Befehl. D.h. alle Chatnachrichten (außer der Teamnachrichten) werden abgefangen. Da auch andere Plugins „say“ abfangen könnten, wird die Hilfe in plugin_registerhelp beschrieben.

Gehört zu: admin.inc

Siehe auch: plugin_registercmd

8.10.135  plugin_registerinfo

plugin_registerinfo( Name[], Description[], Version[] );

Name[]
Typ: String (100)

Description[]
Typ: String (200)

Version[]
Typ: String (150)

Dies Funktion registriert ein Plugin bei Admin Mod. Es muss ein Pluginname (Name), eine Beschreibung (Description) und eine Versionsnummer (Version) angegeben werden. Diese Informationen lassen sich mit admin_version abrufen.

 
Beispiel aus plugin_bk_alltalk36 (Funktion: plugin_init):
27 plugin_registerinfo("Alltalk changer","Switches sv_alltalk",STRING_VERSION);  
28 plugin_registercmd("admin_alltalk","admin_alltalk",A_KICK,"Switches sv_alltalk.");

Zunächst wird das Plugin registriert. Der Name ist „Alltalk changer“, die Beschreibung lautet „Switches sv_alltalk“ und die Versionsnummer entstammt einer globalen Variable (STRING_VERSION). Anschließend wird der Befehl „admin_alltalk“ registriert.

Gehört zu: admin.inc

8.10.136  pointto

pointto( iRange = 2048 );

iRange = 2048
Typ: Integer (0 - 2147483647)

Mit dieser Funktion kann man ermitteln, auf welchen Spieler der den Befehl aufrufende Spieler zielt. Die Funktion gibt die Session ID des anderen Spielers zurück. Die Session ID für eine ungültige Figur (z.B. Geisel) ist -1. Ist keine Figur im Blickfeld, wird eine 0 zurückgegeben. Das Argument iRange definiert die Blickweite.

Um auch den Blick anderer Spieler zu untersuchen, sollte man die Funktion gettarget nutzen. Zudem erspart man sich die Umwandlung der Session ID.

 
Beispiel aus plugin_seeuser37 (Funktion: admin_seeuser):
35         targetnumber = pointto();  
36         numtostr(targetnumber, numstring);  
37         get_username(numstring,targetname,MAX_NAME_LENGTH);  
38         get_userindex(targetname,targetnumber);

Zunächst wird die Session ID (targetnumber) des gegenüberstehenden Spielers ermittelt. Diese wird in einen String umgewandelt (numtostr), in einen Namen (targetname) und schließlich in einen Userindex (targetnumber) umgewandelt.

Gehört zu: admin.inc

Siehe auch: gettarget

8.10.137  print

print( const string[], foreground=-1, background=-1 );

string[]
Typ: String (0 - 2147483647)

foreground=-1
Typ: Integer (-1 - 7)

background=-1
Typ: String (-1 - 7)

Diese Funktion schreibt einen Text (string) in die Befehlszeile. Es können auch Vorder- und Hintergrundfarben (foreground und background) genutzt werden. Mangels einer solchen Befehlszeile ist die Funktion in Admin Mod nutzlos.

Gehört zu: console.inc

8.10.138  printf

printf( const format[], ... );

format[]
Typ: String (0 - 2147483647)

Diese Funktion schreibt einen Text (format) in die Befehlszeile. Es können andere Strings unterschiedlicher Datentypen in format eingebettet werden. Mangels einer solchen Befehlszeile ist die Funktion in Admin Mod nutzlos.

Gehört zu: console.inc

8.10.139  rainbow

rainbow( sText[], iTime, iRedStart, iGreenStart, iBlueStart, iRedEnd,
iGreenEnd, iBlueEnd );

sText[]
Typ: String (80)

iTime
Typ: Integer (0 - 2147483647)

iRedStart
Typ: Integer (0 - 255)

iGreenStart
Typ: Integer (0 - 255)

iBlueStart
Typ: Integer (0 - 255)

iRedEnd
Typ: Integer (0 - 255)

iGreenEnd
Typ: Integer (0 - 255)

iBlueEnd
Typ: Integer (0 - 255)

Mit dieser Funktion kann man eine Nachricht (sText) mit Farbverlauf in der Mitte des Bildschirmes produzieren. Das Argument iTime legt die Anzeigezeit in Sekunden fest. Die Start- und die Endfarbe werden in RGB vorgegeben (iRedStart, iGreenStart, iBlueStart bzw. iRedEnd, iGreenEnd, iBlueEnd).

Es ist kein Zeilenumbruch mit ^n möglich.

 
Beispiel aus plugin_budfroggy_rainbow38 (Funktion: admin_rsay):
155 if(ic1==1 && ic2==1){  
156    rainbow(Text,10,iRedS,iGreenS,iBlueS,iRedE,iGreenE,iBlueE);  
157 }else{  
158    iRedS = 255;  
159   iGreenS = 10;  
160   iBlueS = 10;  
161   iRedE = 10;  
162   iGreenE = 10;  
163   iBlueE = 255;  
164   rainbow( Data, 10, iRedS, iGreenS, iBlueS, iRedE, iGreenE, iBlueE);  
165 }

Falls Farben definiert wurden (ic1 und ic2 müssen 1 sein), wird die Nachricht für zehn Sekunden mit diesem Farbverlauf dargestellt. Anderenfalls wird ein Verlauf von Rot nach Blau durchgeführt.

Gehört zu: admin.inc

Siehe auch: centersay, typesay

8.10.140  random

random( max );

max
Typ: Integer (1 bis 2147483647)

Die Funktion gibt eine Pseudo-Zufallszahl zurück. Der Bereich der Zufallszahlen ist zum einen durch 0 und zum anderen durch max - 1 begrenzt. Man darf von dieser Funktion keine Zufallszahlen erwarten, die wissenschaftlichen Ansprüchen genügen. Aber dafür ist sie bei Admin Mod auch nicht gedacht.

 
Beispiel aus plugin_fun (Funktion: DiscoInferno):
937       for (i = 1; i <= iMaxPlayers; i++) {  
938          if(playerinfo(i,Name,MAX_NAME_LENGTH)==1) {  
939             Red = random(256);  
940             Green = random(256);  
941             Blue = random(256);  
942             glow(Name,Red,Green,Blue);  
943          }  
944       }

Mittels For-Schleife und der Funktion playerinfo werden alle Serverslots auf existierende Spieler überprüft. Ist ein Spieler gefunden worden, werden für jeden Farbanteil eine Zufallszahl für den Bereich 0 bis 255 erzeugt. Der Spieler glüht dann in der Farbe, die sich aus den Zufallszahlen ergab (glow).

Gehört zu: core.inc

8.10.141  readfile

readfile( sFilename[], sLine[], iLineNum, iMaxLength );

sFilename[]
Typ: String (200)

sLine[]
Typ: String (200)

iLineNum
Typ: Integer (0 - 2147483647)

iMaxLength
Typ: Integer (0 - 200)

Mit dieser Funktion kann eine Zeile (iLineNum) aus einer Datei (sFilename) ausgelesen werden. Die Zeile darf nicht länger als 200 Zeichen sein (iMaxLength). Die Rückgabe wird in der Variable sLine gespeichert.

Die Funktion ist sehr zeitintensiv, da gewartet werden muss bis der Festplattenzugriff erfolgt ist. Lädt man mehrere Zeilen mit einer For-Schleife, wird bei jeder Zeile die Datei neu geöffnet, was weitere Verzögerungen verursacht. Man sollte sich daher genau überlegen, ob man diese Funktion nutzen möchte. Beim Auslesen während des Serverstarts ist dies noch akzeptabel, ein Auslesen während der Spielzeit kann bei einer For-Schleife durchaus zu Aussetzern im Spiel führen (Lag). Wenn möglich sollte man seine Einstellungen über die vault.ini lesen und schreiben.

 
Beispiel aus plugin_bk_res39 (Funktion: add_res_data):
155       iLines=filesize(sMap,lines);  
156       for(i=1;i<=iLines;i++){  
157          readfile(sMap,sLine,i,MAX_DATA_LENGTH);  
158          writefile(sMap2,sLine,-1);  
159       }

Es wird die Anzahl der Zeilen der Datei (sMap) ausgelesen. Anschließend werden die Daten über eine For-Schleife zeilenweise von einer Datei (sMap) in eine andere (sMap2) kopiert. Die Zeilen übernehmen nicht unbedingt die Zeilennummer der Ursprungsdatei. Die Zeilen werden beim Schreiben nur angehängt (-1).

Gehört zu: admin.inc

Siehe auch: deletefile, filesize, resetfile, writefile

8.10.142  reject_message

reject_message( iPublic = 0 );

iPublic = 0
Typ: Integer (0 - 1)

Die Funktion gibt eine Fehlermeldung an den Spieler aus „You do not have access to this command“, wenn ein Spieler ohne die notwendigen Rechte versucht einen Befehlauszuführen. Diese Funktion greift auf die in admin_reject_msg definierte Nachricht zurück. Ist diese dort nicht definiert, wird dem Spieler „You do not have access to this command“ in der Konsole angezeigt. Verwendet man iPublic = 1, wird die Nachricht serverweit im Chat ausgegeben.

 
Beispiel aus plugin_base (Funktion: admin_rcon):
443    if (strstr(Data, "rcon_password") >= 0) {  
444       reject_message();  
445       return PLUGIN_HANDLED;  
446    }

Hierbei handelt es sich um eine Absicherung, dass kein Admin, der Zugriff zu admin_rcon hat, sich unberechtigt Zugriff zu RCon verschafft, indem er das Passwort ändert. Falls der String Data die Servervariable rcon_password beinhaltet, wird die Meldung „You do not have access to this command“ angezeigt und die weitere Abarbeitung abgebrochen.

Gehört zu: adminlib.inc

8.10.143  reload

reload( );

Die Funktion lädt alle Ini-Dateien von Admin Mod neu, wenn diese in der adminmod.cfg definiert wurden.

Dies kann sinnvoll sein, wenn man mit dem Plugin Änderungen an den Dateien vorgenommen hat und diese aktivieren möchte.

 
Beispiel aus plugin_base (Funktion: admin_reload):
452 public admin_reload(HLCommand,HLData,HLUserName,UserIndex) {  
453    reload();  
454    return PLUGIN_HANDLED;  
455 }

Hier werden auf Befehl einfach die Dateien neu geladen. Dies ist z.B. interessant, wenn man Änderungen an der users_ini vorgenommen hat und diese ohne Serverneustart oder Mapchange übernehmen möchte.

Gehört zu: admin.inc

8.10.144  removespawn

removespawn( iIdentity );

iIdentity
Typ: Integer (0 - 2147483647)

Die Funktion löscht ein Item (iIdentity).

Die Funktionalität steht mittlerweile nicht mehr zur Verfügung.

 
Beispiel aus plugin_spawn (Funktion: admin_removespawn):
168    if(removespawn(iIdentity)==1) {  
169       say_command(User,Command,Data);  
170       selfmessage( "Success.");  
171    } else {  
172       selfmessage( "Failed.");  
173    }

Es wird versucht ein Item zu löschen. Falls dies erfolgreich war, wird eine Erfolgsmeldung an den Admin und alle anderen Spieler ausgegeben. Anderenfalls wird nur der Admin über den fehlgeschlagenen Versuch informiert.

Gehört zu: admin.inc

Siehe auch: listspawn, movespawn, spawn

8.10.145  resetfile

resetfile( sFilename[] );

sFilename[]
Typ: String (100)

Unter Angabe des Dateinamens löscht die Funktion den Inhalt komplett. Die Datei bleibt jedoch im Gegensatz zu deletefile erhalten.

 
Beispiel aus plugin_cw_creator340 (Funktion: create_mapcycle):
338    resetfile(sPath);  
339    get_vaultdata("CWC_MAP1",Text,MAX_DATA_LENGTH);  
340    writefile(sPath,Text,-1);

Die Datei (sPath) wird geleert. Aus der vault.ini wird ein Mapname in Text eingelesen und anschließend in die leere Datei geschrieben.

Gehört zu: admin.inc

Siehe auch: deletefile, filesize, readfile, writefile

8.10.146  rindex

rindex( sSource[], iChar );

sSource[]
Typ: String (200)

iChar
Typ: Integer (0 - 256)

Die Funktion ermittelt die Position des ersten Vorkommens des Zeichens (iChar) im String (sSource) von rechts beginnend. Für das Zeichen muss die ASCII-Nummer angegeben werden. Vereinfacht kann auch das entsprechende Zeichen in einfache Anführungszeichen gesetzt werden. Die Funktion liefert -1 zurück, falls das Zeichen nicht gefunden wurde.

Die Funktion ist ein Alias für strrchr.

 
Beispiel:

new sTest[MAX_TEXT_LENGTH];  
strcpy(sTest,"Dies ist ein Test.",MAX_TEXT_LENGTH);  
new iTest=0;  
iTest=rindex(sTest,’ ’);

Es wird zunächst „Dies ist ein Test.“ in die Variable sTest geschrieben (strcpy). Nun wird von rechts nach dem ersten Auftreten eines Leerzeichens gesucht. Leerzeichen gibt es an den Positionen 4, 8 und 12. Dem entsprechend wird an iTest 12 übergeben.

Gehört zu: string.inc

Siehe auch: index, strchr, strrchr

8.10.147  say

say( sMessage[] );

sMessage[]
Typ: String (100)

Die Funktion gibt einen vorgegebenen Text (sMessage) im Chat aus.

 
Beispiel aus plugin_CS (Funktion: HandleKickVote):
648       new Ratio = getvar("kick_ratio");  
649       if (VoteCount >= Ratio*UserCount/100) {  
650          if (g_AbortVote) {  
651             say("Kick vote was aborted by an admin");  
652          } else {  
653             set_timer("KickUser",10,1,VoteUser);  
654          }

Die Servervariable „kick_ratio“ wird als Ganzzahl in Ratio ausgelesen. Falls genügend Stimmen für den Kick zusammengekommen sind, wird entweder der Kick abgebrochen, weil ein Admin ihn aufgehalten hat, oder nach 10 Sekunden der entsprechende Spieler vom Server geworfen. Falls ein Admin den Vote aufgehalten hat, wird dies allen Spielern im Chat mitgeteilt (Zeile 651).

Gehört zu: admin.inc

Siehe auch: centersay, typesay, messageex

8.10.148  say_command

say_command( sUser[], sCommand[], sData[], iOverride = 0 );

sUser[]
Typ: String (33)

sCommand[]
Typ: String (19)

sData[]
Typ: String (200)

iOverride = 0
Typ: Integer (0 - 1)

Die Funktion schreibt einen formatierten Text in den Chat. Dazu muss der ausführende Admin (sUser), der ausgeführte Befehl (sCommand) und die Parameter (sData) angegeben werden. Die Ausgabe kann durch die Einstellung von admin_quiet beeinflusst werden. Optional kann diese Einstellung auch ignoriert werden (iOverride = 1).

 
Beispiel aus plugin_base (Funktion: admin_map):
307    if (valid_map(Data)==1) {  
308       say_command(User,Command,Data);  
309       changelevel(Data, 4);

Wenn es sich bei Data um eine gültige Map handelt, wird basierend auf der Einstellung von admin_quiet im Chat mit Adminnamen und Befehl ausgegeben und nach 4 Sekunden ein Mapwechsel durchgeführt.

Gehört zu: adminlib.inc

Siehe auch: format_command, log_command

8.10.149  selfmessage

selfmessage( sMessage[] );

sMessage[]
Typ: String (100)

Die Funktion schreibt dem Spieler, der den zugehörigen Befehl ausgeführt hat, eine Nachricht (sMessage) in die Console.

 
Beispiel aus plugin_base (Funktion: admin_rcon):
435    if (check_auth(ACCESS_RCON)==0) {  
436       selfmessage("Laf. Silly bear.");  
437       return PLUGIN_HANDLED;  
438    }

Um zu verhindern, dass jemand auf die Idee kommt aus der Serverconsole den Befehl admin_rcon aufzurufen, was möglich aber unsinnig ist, wurde eine Abfangroutine implementiert. Nur wenn der User den Access Level 65536 (ACCESS_RCON) besitzt, wird der RCon-Befehl über Admin Mod abgesetzt. Anderenfalls wird der Admin, der den Befehl ausführte, etwas unhöflich in der Console auf das unsinnige Ansinnen hingewiesen (selfmessage).

Gehört zu: admin.inc

Siehe auch: directmessage, message, messageex

8.10.150  servertime

servertime( sTimeString[], iMaxLen, sFormat[] = „none” );

sTimeString[]
Typ: String (100)

iMaxLen[]
Typ: String (1 - 100)

sFormat[]
Typ: String (100)

Die Funktion gibt das aktuelle Datum und die Uhrzeit zurück (sTimeString mit Länge iMaxLen). Die Rückgabe erfolgt über die Formatvorgabe (sFormat). Falls diese nicht vorgegeben wurde, werden die abgelaufenen Sekunden seit dem 1.1.1970 ausgegeben.

In der folgenden Liste sind die Formatierungszeichen beschrieben:

%a
Wochentag (abgekürzt) (z.B. Mon für Montag)
%A
Wochentag (ausgeschrieben)
%b
Monat (abgekürzt) (z.B. Aug für August)
%B
Monat (ausgeschrieben)
%c
Vorgefertigtes Datums- und Zeitformat (%a %b %d %H:%M:%M %Y)
%d
Tag im Monat (01 - 31)
%H
Stunde im 24h Format (00 - 23)
%I
Stunde im 12h Format (00 - 12)
%j
Tag im Jahr (001 - 366)
%m
Monat (als Zahl) (01 - 12)
%M
Minute (00 - 59)
%p
Vor- und Nachmittagsperiode (AM oder PM)
%S
Sekunden (00 - 61)
%U
Kalenderwoche (Woche beginnt am ersten Sonntag) (00 - 53)
%w
Wochentag (als Zahl, Sonntag = 0) (0 - 6)
%W
Kalenderwoche (Woche beginnt am ersten Montag) (00 - 53)
%x
Vorgefertigtes Datumsformat (%m/%d/%y)
%X
Vorgefertigtes Zeitformat (%H:%M:%M)
%y
Jahr (letzten zwei Ziffern) (z.B. 09)
%Y
Jahr (alle Ziffern) (z.B. 2009)
%Z
Zeitzone (z.B. CET)

 
Beispiel aus plugin_dotw41 (Funktion: admin_time):
208    servertime(t_time, MAX_DATA_LENGTH, "%I:%M %p");  
209    servertime(t_date, MAX_DATA_LENGTH, "%A, %B %d %Y");  
210  
211    snprintf(Text, MAX_TEXT_LENGTH, "%s %s", t_time, t_date);  
212    selfmessage(Text);

Es wird die Serverzeit (t_time) und das Datum (t_date) ermittelt. Anschließend werden die beiden Zeitstrings mit einem Leerzeichen verknüpft und an den admin_time ausführenden Spieler in der Console ausgegeben. Dieser Code hätte auch mit nur einer servertime Abfrage und ohne snprintf geschrieben werden können.

Gehört zu: admin.inc

Siehe auch: systemtime

8.10.151  set_serverinfo

set_serverinfo( sKey[], sValue[] );

sKey[]
Typ: String (100)

sValue[]
Typ: String (200)

Die Funktion schreibt die Daten (sValue) mit dem Schlüssel (sKey) in ein kleinen Speicherbereich. Die Daten werden beim Mapwechsel nicht gelöscht. Der Speicher ist jedoch nur sehr gering bemessen, so dass die Verwendung dieser Funktion vermieden werden sollte.

 
Beispiel aus plugin_bk_cron42 (Funktion: lag_check):
499    numtostr(iTime,sTime);  
500    set_serverinfo("last_cron",sTime);

Die Sekundenzahl der aktuellen Minute (iTime) wird in einen String (sTime) umgewandelt. Anschließend wird ein Schlüssel „last_cron“ erstellt oder mit diesem String überschrieben. Auf diese Art und Weise kann insbesondere überprüft werden, wie lang der letzte Durchlauf vor dem Mapwechsel her ist. Beim Serverstart ist die Variable noch nicht gesetzt, so dass 0 zurückgegeben wird. Die Nutzung der vault.ini verbietet sich, da der Wert beim Beenden bzw. Absturz des Servers nicht automatisch auf 0 zurückgesetzt wird.

Gehört zu: admin.inc

Siehe auch: get_serverinfo, get_userinfo

8.10.152  set_timer

set_timer( sFunction[], iWaitSeconds, iRepeatCount, sParameter[]= “” );

sFunction[]
Typ: String (19)

iWaitSeconds
Typ: Integer (0 - 2147483647)

iRepeatCount
Typ: Integer (0 - 2147483647)

sParameter[]
Typ: String (200)

Mit dieser Funktion wird ein Timer erstellt. Dabei muss die bei Ablauf des Timers aufzurufende Funktion (sFunction), die Ablaufzeit (iWaitSeconds) und die Anzahl der Wiederholungen (iRepeatCount) übergeben werden. Die definierte Funktion muss öffentlich (public) sein. Unendlich viele Wiederholungen erreicht man durch die Angabe von 99999. Um nur einen einzigen Ablauf zu erreichen kann iRepeatCount auf 0 oder 1 gesetzt werden. Optional kann ein String (sParameter) an die aufzurufende Funktion übergeben werden. Die Funktion set_timer gibt die erstellte Timer ID direkt zurück. Mehr Informationen zur Verwendung von Timern können dem Tutorial entnommen werden.

 
Beispiel aus plugin_CS (Funktion: HandleKickVote):
648       new Ratio = getvar("kick_ratio");  
649       if (VoteCount >= Ratio*UserCount/100) {  
650          if (g_AbortVote) {  
651             say("Kick vote was aborted by an admin");  
652          } else {  
653             set_timer("KickUser",10,1,VoteUser);  
654          }

Die Servervariable „kick_ratio“ wird als Ganzzahl in Ratio ausgelesen. Falls genügend Stimmen für den Kick zusammengekommen sind, wird entweder der Kick abgebrochen, weil ein Admin ihn aufgehalten hat, oder ein Timer ausgelöst, der einmal nach 10 Sekunden die Funktion „KickUser“ ausführt. Der entsprechende Spieler wird von dieser Funktion dann vom Server geworfen.

Gehört zu: admin.inc

Siehe auch: get_timer, kill_timer

8.10.153  set_vaultdata

set_vaultdata( sKey[], sData[] );

sKey[]
Typ: String (100)

sData[]
Typ: String (200)

Die Funktion schreibtDaten (sData) mit dem Schlüssel (sKey) in die vault.ini. Die Daten bleiben über einen Mapchange bzw. einen Serverneustart erhalten. Das Schlüssel-Daten-Paar kann mit set_vaultdata oder get_vaultnumdata ausgelesen werden. Die Funktion ist ideal um pluginspezifische Einstellungen zu speichern.

Weiß man bereits, dass die zu schreibenden Daten als Ganzzahl vorliegen, sollte man der Funktion set_vaultnumdata den Vorzug geben.

Mit set_vaultdata kann auch ein Schlüssel gelöscht werden. Dazu muss ein leerer Datenstring übergeben werden.

 
Beispiel aus plugin_retribution (Funktion: AddUserFlag):
69          if(get_vaultdata(sAuthID,VaultData,MAX_DATA_LENGTH) != 0) {  
70             if (strcasestr(VaultData," llama") == -1) {  
71                strcat(VaultData," llama", MAX_DATA_LENGTH);  
72                set_vaultdata(sAuthID,VaultData);  
73             }

Es wird versucht den Schlüssel mit der Steam ID des Spielers zu finden. Ist dies der Fall, wird das Ergebnis in VaultData zwischengespeichert. Falls das Ergebnis nicht bereits den Teilstring „ llama“ beinhaltet, wird dies dem Ergebis angehängt (strcat) und zurück in die vault.ini geschrieben.

8.10.154  set_vaultnumdata

set_vaultnumdata( sKey[], iData );

sKey[]
Typ: String (100)

iData
Typ: Integer (0 - 2147483647)

Die Funktion schreibt Daten (sData) mit dem Schlüssel (sKey) als Ganzzahl (iData) in die vault.ini. Die Daten bleiben über einen Mapchange bzw. einen Serverneustart erhalten. Das Schlüssel-Daten-Paar wird mit get_vaultdata oder get_vaultnumdata ausgelesen. Die Funktion ist ideal um pluginspezifische Einstellungen zu speichern.

Ist im Schlüssel ein String hinterlegt, darf man die Funktion nicht anwenden. Statt dessen ist set_vaultdata zu verwenden.

 
Beispiel aus plugin_bk_botmanager43 (Funktion: plugin_init):
346    if(!get_vaultnumdata("BK_BM_BOTS",iBots)){  
347       set_vaultnumdata("BK_BM_BOTS",0);  
348       if(getvar("admin_debug")>0){  
349          log("[BK_BM] Basic setting missing in vault.ini. Creating new.");  
350       }  
351    }

Es wird überprüft, ob der Schlüssel BK_BM_BOTS existiert. Wenn dies nicht der Fall ist, wird der Schlüssel angelegt und eine 0 hineingeschrieben. Falls admin_debug größer als 0 ist, wird dies auch in den Logdateien dokumentiert.

8.10.155  setarg

setarg( arg, index=0, value );

arg
Typ: Integer (0 - 2147483647)

index=0
Typ: Integer (0 - 2147483647)

value
Typ: Integer (-2147483648 - 2147483647)

Diese Funktion wird nur Fällen gebraucht, wenn man die Argumente einer Funktion mit variabler Argumentanzahl verändern möchte. Dabei gibt „arg“ die Position des Arguments beginnend mit 0 an. Das Argument „index“ wird nur benötigt, wenn arg ein Feld (z.B. ein String) ist. Es gibt die zu schreibende Zelle des Feldes an. Das Argument „value“ ist der neue Wert, der zurückzuschreiben ist.

 
Beispiel:

sum(...){  
   new result = 0 ;  
   for (new i = 0; i < numargs(); ++i) {  
      result += getarg(i);  
   }  
   setarg(0,result);  
   return 1;  
}

Eine Funktion „sum“ mit variabler Argumentanzahl (...) wird definiert. Eine For-Schleife fragt die einzelnen Argumente ab und addiert sie. Die Summe wird über das erste Argument der Funktion „sum“ zurückgegeben. Die direkte Rückgabe ist immer 1. Die Anzahl der übergebenen Argumente wird mit numargs ermittelt.

Gehört zu: core.inc

Siehe auch: getarg, numargs

8.10.156  setproperty

setproperty( id=0, const name[]=“”, value=cellmin, const string[]=“” );

id=0
Typ: Integer (-2147483648 - 2147483647)

const name[]=“”
Typ: String (variabel)

value=cellmin
Typ: Integer (-2147483648 - 2147483647)

const string[]=“”
Typ: String (variabel)

Mit dieser Funktion kann eine so genannte Property bei gegebenem Schlüssel (name oder value) erstellt werden. Die Property wird als String im Speicher abgelegt. Es handelt sich um eine Funktion, deren Benutzung unter Admin Mod vermieden werden sollte. Stattdessen wird empfohlen z.B. die Funktionen get_vaultdata oder set_vaultdata zurückzugreifen.

Mehr Informationen zum Thema sind im Abschnitt 8.14 nachzulesen.

 
Beispiel:
setproperty(2,“test_prop”,sString);
setproperty(3,15,sString);

Das erste Beispiel erstellt unter der ID 2 die Property „test_prop“ mit dem Inhalt aus der Variable sString, während das zweite Beispiel unter der ID 3 die Property 15 mit dem gleichen Inhalt erstellt.

Gehört zu: core.inc

Siehe auch: existproperty, deleteproperty, getproperty

8.10.157  setstrvar

setstrvar( cvar[], value[] );

cvar[]
Typ: String (100)

value[]
Typ: String (100)

Mit dieser Funktion können Servervariablen (cvar) gesetzt werden. Der Inhalt (value) muss als String vorliegen. Eine äquivalente Funktion für Ganzzahlen existiert nicht, so dass diese vorab in einen String umgewandelt werden müssen (numtostr).

 
Beispiel aus plugin_CS (Funktion: HandleRestartVote):
544    new Timelimit[MAX_NUMBER_LENGTH];  
545    numtostr((getvar("mp_timelimit") * 60 - timeleft() + 10) / 60,Timelimit);  
546    setstrvar("mp_timelimit",Timelimit);  
547    setstrvar("sv_restartround","10");  
548    say("Round restart vote succeeded.");

Vom aktuellen Zeitlimit auf dem Server wird die Restzeit abgezogen und 10 Sekunden addiert. Dieser Wert wird in einen String umgewandelt (numtostr) und in die Servervariable „mp_timelimit“ als neues Zeitlimit eingetragen. Anschließend wird mit dem Setzen der Variable „sv_restartround“ auf 10 ein Maprestart nach 10 Sekunden angefordert und der Restart allen Spielern mitgeteilt.

Gehört zu: admin.inc

Siehe auch: exec, getstrvar, getvar

8.10.158  slap

slap( sPlayer[] );

sPlayer[]
Typ: String (33)

Die Funktion schlägt den angegebenen Spieler (sPlayer). Er wird dabei leicht in eine zufällige Richtung gestoßen, und es werden ihm fünf Lebenspunkte abgezogen. Ein Spieler kann durch diese Aktion nie weniger als einen Lebenspunkt bekommen. Der Schlag wird bei einem Lebenspunkt als abzugsfreier Stoß durchgeführt.

 
Beispiel aus plugin_retribution (Funktion: admin_slap):
317 if(check_immunity(Data)!=0) {  
318    snprintf(Text, MAX_TEXT_LENGTH, "Laf. You can’t slap %s", TargetName);  
319    messageex(User, Text, print_chat);  
320 } else {  
321    slap(Data);  
322 }

Hat die Person (Data) Immunitätsrechte, wird eine Fehlermeldung an den Admin ausgegeben. Anderenfalls wird die Person geschlagen.

Gehört zu: admin.inc

Siehe auch: slay, teleport

8.10.159  slay

slay( sPlayer[] );

sPlayer[]
Typ: String (33)

Der Spieler (sPlayer) wird durch diese Funktion getötet. Wenn admin_fx aktiviert ist, wird die Aktion durch zusätzliche Effekte untermalt.

 
Beispiel aus plugin_retribution (Funktion: admin_slap):
317 if(check_immunity(TargetName)!=0) {  
318    snprintf(Text, MAX_TEXT_LENGTH, "Laf. You can’t slay %s", TargetName);  
319    messageex(User, Text, print_chat);  
320 } else {  
321    if ( slay(TargetName) ) {  
322       PlaySoundToAll("ambience/thunder_clap.wav");

Hat die Person (Data) Immunitätsrechte, wird eine Fehlermeldung an den Admin ausgegeben. Anderenfalls wird die Person getötet. Wenn die Aktion erfolgreich war, wird darüber hinaus über eine pluginspezifische Funktion (PlaySoundToAll) eine Sounddatei bei allen Spielern abgespielt.

Gehört zu: admin.inc

Siehe auch: slap, teleport

8.10.160  snprintf

snprintf( sDest[], iLength, sFormat[], ... );

sDest[]
Typ: String (200)

iLength
Typ: Integer (0 - 200)

sFormat[]
Typ: String (200)

...
variable Anzahl an Argumenten (kommagetrennt)

 
Mit dieser Funktion können auf einfache Weise Variablen unterschiedlicher Datentypen (...) in einen String (sDest mit Länge iLength) eingebettet werden. Über einen weiteren String sFormat wird festgelegt, wie die Variablen eingebunden werden sollen. Die Reihenfolge der Platzhalter im Format-String muss der Reihenfolger der Argumente im Anschluss an selbigen entsprechen.

 
Folgende Platzhalter stehen zur Verfügung:

%c
Einzelnes Zeichen
%d
Ganzzahl (man sieht oft %i, was aber nicht korrekt ist, aber trotzdem funktioniert)
%q
Festkommazahl
%s
Zeichenkette (String)

 
Beispiel aus plugin_blatt_map44 (Funktion: DebugHeap):
3641 DebugHeap(context[]) {  
3642   if (g_DebugLevel >= 2) {  
3643     new heapsize[MAX_TEXT_LENGTH];  
3644     snprintf(heapsize,MAX_TEXT_LENGTH,"[%s] %i free bytes.",context,heapspace());  
3645     plugin_message(heapsize);  
3646   }  
3647   return 0;  
3648 }

Wenn der in der globalen Variable (g_DebugLevel) Debuglevel größer oder gleich zwei ist, wird der noch verbleibende Heap-Speicher ermittelt (Ganzzahl). Mit dem String (context) soll diese Ganzzahl in der Variable heapsize eingebettet werden. Die Reihenfolge der Platzhalter (%s vor %i) bestimmt die Reihenfolge der Argumente (context vor heapspace()). Ist context gleich „Test“ und die Rückgabe von heapspace gleich 936, dann sähe der String heapsize folgendermaßen aus:

[Test] 936 free bytes.

Zuletzt wird dieser Text in der Console unter Angabe des Pluginnamens ausgegeben (plugin_message).

Gehört zu: string.inc

Siehe auch: strsubst

8.10.161  spawn

spawn( sClass[], iX, iY, iZ, iXAngle, iYAngle, iZAngle );

sClass[]
Typ: String (100)

iX
Typ: Integer (-2147483648 - 2147483647)

iY
Typ: Integer (-2147483648 - 2147483647)

iZ
Typ: Integer (-2147483648 - 2147483647)

iXAngle
Typ: Integer (0 - 359)

iYAngle
Typ: Integer (0 - 359)

iZAngle
Typ: Integer (0 - 359)

Die Funktion erstellt ein Item (iClass) auf einer bestimmten Position (iX, iY, iZ) und in einer bestimmten Ausrichtung (iXAngle, iYAngle, iZAngle). Es wird die ID des Items zurückgegeben.

Die Funktionalität steht mittlerweile nicht mehr zur Verfügung.

 
Beispiel aus plugin_spawn (Funktion: admin_spawn):
143 iIdentity = spawn(strClass,X,Y,Z,XAngle,YAngle,ZAngle);  
144 if (iIdentity != 0) {  
145    snprintf(Text,MAX_TEXT_LENGTH,"Spawn created with ID %i.",iIdentity);  
146    selfmessage(Text);  
147    say_command(User,Command,Data);  
148 } else {  
149    selfmessage("Failed.");  
150 }

Es wird versucht ein Item an den genannten Koordinaten und in den gegebenen Winkeln zu erstellen. Falls dies erfolgreich war, wird eine Erfolgsmeldung an den Admin und alle anderen Spieler ausgegeben. Anderenfalls wird nur der Admin über den fehlgeschlagenen Versuch informiert.

Gehört zu: admin.inc

Siehe auch: listspawn, removespawn, spawn

8.10.162  speakto

speakto( sTarget[], sSentence[] );

sTarget[]
Typ: String (33)

sSentence[]
Typ: String (100)

Mit dieser Funktion kann man bei einem Spieler (sTarget) die in Half-Life integrierte Sprachausgabe nutzen. Dafür muss der Soundtyp und der zu sprechende Satz definiert werden (sSentence). Ein Überblick über die zur Verfügung stehenden Soundtypen und der jeweiligen Sounds kann dem Anhang entnommen werden.

 
Beispiel aus plugin_sdal_time_manager45 (Funktion: speak_timeleft):
717 numtoword(minutes,Min,MAX_NUMBER_LENGTH);  
718 numtoword(seconds,Sec,MAX_NUMBER_LENGTH);  
719 snprintf(Text,MAX_DATA_LENGTH,"fvox/%s minutes %s seconds remaining",Min,Sec);  
720 speakto(User,Text);

Mit der userdefinierten Funktion numtoword werden die Minuten und Sekunden von Ganzzahlen in ausgeschriebene, englischsprachige Strings umgewandelt (z.B. 10 in „ten“ oder 3 in „three“). Diese können von den Soundtypen vox (männliche Stimme) und fvox (weibliche Stimme) wiedergegeben werden. Da hier die weibliche Stimme benötigt wird, stellt man „fvox/“ dem Satz voran. Durch das Einbetten der Minuten und Sekunden kann der Satz (Text) beim Spieler (User) ausgegeben werden. Es können nur Wörter verwendet werden, die für den jeweiligen Soundtyp vorhanden sind.

Gehört zu: admin.inc

Siehe auch: playsound

8.10.163  strbreak

strbreak( str[], first[], second[], maxlen, flen=sizeof first,
slen=sizeof second );

str[]
Typ: String (200)

first[]
Typ: String (200)

second[]
Typ: String (200)

maxlen Typ: Integer (1 - 200)

flen=sizeof first Typ: Integer (1 - 200)

slen=sizeof second Typ: Integer (1 - 200)

Diese Funktion teilt einen gegebenen String (str mit der Länge maxlen) beim ersten Leerzeichen in zwei Teile (first und second). Die Längen der zwei Teile sind optional, und im Allgemeinen nicht notwendig zu definieren. Es gibt allerdings mittlerweile bessere Funktionen (strsep und strsplit), die das Gleiche und noch mehr können.

 
Beispiel aus plugin_base (Funktion: admin_ban):
57    convert_string(HLCommand,Command,MAX_COMMAND_LENGTH);  
58    convert_string(HLData,Data,MAX_DATA_LENGTH);  
59    convert_string(HLUserName,User,MAX_NAME_LENGTH);  
60  
61    strbreak(Data,ban_user,strTime, MAX_DATA_LENGTH);  
62    strbreak(strTime, strTime, strType, MAX_DATA_LENGTH);

Zunächst werden die HL Strings in Small Strings konvertiert (convert_string). Anschließend wird der zu bannende Spieler (ban_user) von der Dauer des Banns (strTime) getrennt. Ein weiterer Trennversuch sorgt dafür, dass der gegebenenfalls in strTime vorhandene Typ des Banns (ID oder IP) in strType abgetrennt wird. Ist er nicht angegeben, ist der String leer.

Gehört zu: adminlib.inc

Siehe auch: strsep, strsplit

8.10.164  strcasecmp

strcasecmp( sString1[], sString2[] );

sString1[]
Typ: String (200)

sString2[]
Typ: String (200)

Die Funktion vergleicht zwei Strings (sString1 und sString2) über ihre gesamte Länge. Groß- und Kleinschreibung wird nicht beachtet. Sind beide Strings identisch, wird eine 0 zurückgegeben. Man erhält eine 0 zurück, wenn beide Strings gleich sind. Ist das erste ungleiche Zeichen in den Strings bei sString1 größer als bei sString2, wird eine Zahl größer als 0 zurückgegeben. Umgekehrt wird eine Zahl kleiner als 0 zurückgegeben.

 
Beispiel aus plugin_bk_botmanager46 (Funktion: admin_bot_set):
266    strbreak(sValue,sBotCvar,sValue,MAX_DATA_LENGTH);  
267    strtrim(sValue," ",2);  
268    strtrim(sBotCvar," ",2);  
269  
270    if(strcasecmp(sBotCvar,"bots")==0){

Der Wert sValue wird in sBotCvar und sValue aufgeteilt (strbreak). Beiden Variablen werden am Anfang und am Ende von möglichen Leerzeichen befreit (strtrim). Die Ausführung der If-Verzweigung erfolgt nur, wenn die Variable sBotCvar genau dem String „bots“ entspricht, wobei die Groß- und Kleinschreibung keine Rolle spielt.

Gehört zu: string.inc

Siehe auch: strcmp, strncasecmp, strncmp

8.10.165  strcasestr

strcasestr( sSource[], sSearch[] );

sSource[]
Typ: String (200)

sSearch[]
Typ: String (200)

Die Funktion sucht einen String (sSearch) in einem anderen String (sSource). Groß- und Kleinschreibung wird nicht beachtet. Wird der Suchstring gefunden, gibt die Funktion eine Zahl größer als 0 zurück. Wenn der String nicht gefunden wurde, gibt die Funktion eine -1 zurück. Ist der Suchstring gleich dem anderen String wird eine 0 zurückgegeben.

 
Beispiel aus plugin_chat (Funktion: HandleSay):
57      if ( strcasestr(MessageMode[UserIndex], "admin_") >= 0 ) {  
58        plugin_exec( MessageMode[UserIndex], Data );  
59        return PLUGIN_HANDLED;

Es wird ohne Beachtung der Groß- und Kleinschreibung der String „admin_“ im Admin Mod Befehl (in MessageMode[UserIndex]) gesucht. Ist er enthalten, wird der Befehl mit den Parametern (Data) ausgeführt (plugin_exec) und die Ausführung beendet.

Gehört zu: string.inc

Siehe auch: strcasestrx, strstr

8.10.166  strcasestrx

strcasestrx( sSource[], sSearch[] );

sSource[]
Typ: String (200)

sSearch[]
Typ: String (200)

Die Funktion sucht einen String (sSearch) in einem anderen String (sSource). Groß- und Kleinschreibung wird nicht beachtet. Wird der Suchstring gefunden, gibt die Funktion eine Zahl größer als 0 zurück. Wenn der String nicht gefunden wurde oder leer ist, gibt die Funktion eine -1 zurück. Ist der Suchstring gleich dem anderen String wird eine 0 zurückgegeben.

 
Beispiel aus plugin_sdal_logd_hp5047 (Funktion: HandleSay):
677             if (strcasestrx(Data, "hp")!=-1){  
678                if(g_PlayerEnemyID[UserIndex]!=0 && IsDead == 1){  
679                   display_victim(User,UserIndex);  
680                }else{  
681                   display_statistik(User,UserIndex);  
682                }  
683             }else if (strcasestrx(Data, "myhits")!=-1){  
684                own_statistic(User,UserIndex);  
685             }else if (strcasestrx(Data, "hits")!=-1){  
686                most_damage(User,UserIndex);  
687             }else if (strcasestrx(Data, "weapon")!=-1){  
688                most_used_weapon(User,UserIndex);  
689             }

Die If-Verzweigung überprüft, ob einige Begriffe in Data vorkommen oder den gleichen Inhalt haben. Ist dies der Fall, werden entsprechende Unterfunktionen aufgerufen, die dem Spieler unterschiedliche Statistikinformationen auf dem Bildschirm darstellen.

Gehört zu: string.inc

Siehe auch: strcasestr, strstr

8.10.167  strcat

strcat( sDest[], sSource[], iMaxLen );

sDest[]
Typ: String (200)

sSearch[]
Typ: String (200)

iMaxLen
Typ: Integer (0 - 200)

Diese Funktion fügt einen String (sSource mit der Länge iMaxLen) an einen anderen (sDest) an.

 
Beispiel aus plugin_CS (Funktion: LoadDefaultRestrictions):
934     currentmap(strMap,100);  
935     strcpy(strName,"WeaponRestrictions_",100);  
936     strcat(strName,strMap,100);

Zunächst wird die aktuelle Map ermittelt und in strMap geschrieben. Danach wird die Zeichenkette „WeaponRestrictions_“ in die Variable strName geschrieben. Abschließend wird der String strName durch den String strMap erweitert. Ist die aktuelle Map „de_dust“, ist strName am Ende „WeaponRestrictions_de_dust“.

Gehört zu: string.inc

Siehe auch: strncat, snprintf

8.10.168  strchr

strchr( sSource[], iChar );

sSource[]
Typ: String (200)

iChar
Typ: Integer (0 - 256)

Die Funktion ermittelt die Position des ersten Vorkommens des Zeichens (iChar) im String (sSource) von links beginnend. Für das Zeichen muss die ASCII-Nummer angegeben werden. Vereinfacht kann auch das entsprechende Zeichen in einfache Anführungszeichen gesetzt werden. Die Funktion liefert -1 zurück, falls das Zeichen nicht gefunden wurde.

 
Beispiel aus plugin_blatt_map48 (Funktion: GetShortName):
3022   new pos = strchr(fullname,’_’);  
3023   if (pos>0) {  
3024     pos = pos +1;  
3025   }  
3026   else {  
3027     pos = 0;  
3028   }

Es wird das erste Vorkommen vom Unterstrich im String fullname gesucht. Ist die Position größer als 0, wird die Position inkrementiert. Andernfalls wird die Position auf 0 gesetzt.

Gehört zu: string.inc

Siehe auch: index

8.10.169  strcmp

strcmp( sString1[], sString2[] );

sString1[]
Typ: String (200)

sString2[]
Typ: String (200)

Die Funktion vergleicht zwei Strings (sString1 und sString2) über ihre gesamte Länge. Groß- und Kleinschreibung wird beachtet. Sind beide Strings identisch, wird eine 0 zurückgegeben. Man erhält eine 0 zurück, wenn beide Strings gleich sind. Ist das erste ungleiche Zeichen in den Strings bei sString1 größer als bei sString2, wird eine Zahl größer als 0 zurückgegeben. Umgekehrt wird eine Zahl kleiner als 0 zurückgegeben.

 
Beispiel aus plugin_CS (Funktion: SetRestrictions):
609     } else if(strcmp(Data,"help") == 0) {  
610         ShowHelp(Status);

Falls Data „help“ unter Berücksichtigung der Groß- und Kleinschreibung entspricht, wird eine pluginspezifische Funktion zur Darstellungen der Optionen ausgeführt.

Gehört zu: string.inc

Siehe auch: streq, strncasecmp, strncmp

8.10.170  strcount

strcount( sSource[], iChar );

sSource[]
Typ: String (200)

iChar
Typ: Integer (1 - 256)

Die Funktion zählt das Vorkommen eines Zeichens (iChar) in einem String (sSource). Vereinfacht kann auch das entsprechende Zeichen in einfache Anführungszeichen gesetzt werden.

 
Beispiel aus plugin_bk_cron49 (Funktion: admin_cron_add):
648 if(strcount(task,’ ’)<6){  
649    /* selfmessage("Task not valid!"); */  
650    selfmessage(cron_tnv);  
651    /* selfmessage("Usage: admin_cron_add <min> <h> <d> <mo> <wd> <cv> <cmd>"); */  
652    selfmessage(cron_adduse);  
653    return PLUGIN_HANDLED;  
654 }

Die Anzahl der Leerzeichen wird im String task gesucht. Falls die Anzahl kleiner als 6 ist, wird eine zweizeilige Fehlermeldung in der Console des Admins ausgegeben.

Gehört zu: string.inc

8.10.171  strcpy

strcpy( sDest[], sSource[], iMaxLen );

sDest[]
Typ: String (200)

sSource[]
Typ: String (200)

iMaxLen
Typ: Integer (0 - 200)

Kopiert einen String (sSource) über einen anderen (sDest mit der Länge iMaxLen).

 
Beispiel aus plugin_base (Funktion: admin_pass):
338    if (streq(Command, "admin_nopass")==1) {  
339       strcpy(Data,"^"^"",MAX_DATA_LENGTH);

Wenn der ausgeführte Befehl „admin_nopass“ lautet, werden keine Parameter erwartet. Um der Servervariable „sv_password“ später auf einen leeren Wert zu setzen, wird Data auf zwei Anführungszeichen gesetzt (“”).

Gehört zu: string.inc

Siehe auch: strncpy

8.10.172  strcspn

strcspn( sSource[], sSearch[] );

sSource[]
Typ: String (200)

sSearch[]
Typ: String (200)

Die Funktion sucht Zeichen aus einem String (sSearch) in einem anderen String (sSource). Sie gibt die Länge des Teilstrings zurück, der von links beginnend, kein Zeichen aus sSearch besitzt. Da Strings Felder sind, ist die Länge gleichzeitig die Position des ersten in sSearch vorhandenen Zeichens.

 
Beispiel:

new sTest[MAX_TEXT_LENGTH]="Test123Test";  
new iTest=strcspn(sTest,"1234567890");

Im Beispiel wird im String sTest nach Zahlen gesucht werden. Da die erste Zahl an der Position 4 liegt, wird als Länge 4 ausgegeben.

Gehört zu: string.inc

Siehe auch: strspn

8.10.173  streq

streq( strOne[], strTwo[] );

strOne[]
Typ: String (200)

strTwo[]
Typ: String (200)

Die Funktion überprüft unter Berücksichtigung der Groß- und Kleinschreibung, ob zwei Strings (strOne und strTwo) identisch sind. Sind sie identisch wird eine 0, wenn nicht wird eine 1 zurückgegeben.

 
Beispiel aus plugin_base (Funktion: admin_csay):
136    if (streq(Color,"red")==1) {  
137       centersay(Message,10,250,10,10);

Wenn der Text Color gleich „red“ ist, wird die Nachricht in Message für 10 Sekunden in einen hellem Rot dargestellt.

Gehört zu: adminlib.inc

Siehe auch: strcasecmp, strmatch

8.10.174  strgsep

strgsep( sSource[], sDelimiters[], sGrouping[], ... );

sSource[]
Typ: String (200)

sDelimiters[]
Typ: String (200)

sGrouping[]
Typ: String (200)

...
variable Anzahl an Argumenten und Stringlängen (kommagetrennt)

Diese Funktion trennt einen String (sSource) an im String (sDelimitiers) angegebenen Zeichen. Die Trennung wird dort nicht ausgeführt, wo die Zeichenkette von den im String (sGrouping) angegebenen Zeichen umschlossen wird. Werden nicht ausreichend Argumente (...) für die Aufnahme der Teilstrings angegeben, wird der Rest ungetrennt im letzten Argument übergeben.

Die Funktion gibt zurück, wieviele Teilstrings gefunden wurden bzw. -1, wenn kein Teilstring gefunden wurde.

 
Beispiel aus plugin_CS (Funktion: SetRestrictions):
710         strgsep(Data[7]," ","’",sPlayer,MAX_AUTHID_LENGTH,sWhat,MAX_DATA_LENGTH);  
711         if(check_user(sPlayer) == 0) {  
712             selfmessage("Unrecognized player: ");  
713             selfmessage(sPlayer);  
714             selfmessage("If the player name you specified containes spaces");  
715             selfmessage("try encosing it with single quotes (’).");  
716             return PLUGIN_HANDLED;  
717         }

Der String Data[7] wird an den Leerzeichen getrennt. Es werden nur zwei Argumente definiert (sPlayer und sWhat). Falls mehr als ein Leerzeichen auftritt, wird nur am ersten getrennt und der Rest in sWhat geschrieben. Hat ein Spieler ein Leerzeichen im Namen, würde der Spielername getrennt und der zweite Teil des Namens mit in sWhat geschrieben. Daher wurden als Gruppierungszeichen die einfachen Anführungszeichen gewählt. Ist der Spielername von diesen Zeichen umschlossen, wird dieser Teil für die Trennung ausgeschlossen und die Trennung am nächsten Leerzeichen durchgeführt.

Anschließend wird überprüft, ob eine Spieler dieses Namens existiert. Wenn nicht, wird eine vierzeilige Fehlermeldung in der Console ausgegeben.

8.10.175  strgsplit

strgsplit( sSource[], sDelimiters[], sGrouping[], ... );

sSource[]
Typ: String (200)

sDelimiters[]
Typ: String (200)

sGrouping[]
Typ: String (200)

...
variable Anzahl an Argumenten und Stringlängen (kommagetrennt)

Diese Funktion trennt einen String (sSource) an im String (sDelimitiers) angegebenen Zeichen. Die Trennung wird dort nicht ausgeführt, wo die Zeichenkette von den im String (sGrouping) angegebenen Zeichen umschlossen wird. Werden nicht ausreichend Argumente (...) für die Aufnahme der Teilstrings angegeben, wird der Rest verworfen.

Die Funktion gibt zurück, wieviele Teilstrings gefunden wurden bzw. -1, wenn kein Teilstring gefunden wurde.

 
Beispiel aus plugin_gnc_filtersay50 (Funktion: readcfg):
72 for (new i=0;(i<MAX_WORDS && readfile(filename,sData,(i+1),MAX_DATA_LENGTH));i++){  
73    strgsplit(sData, " ", "^"", BadWord[i], MAX_PL, GoodWord[i], MAX_PL);  
74  
75 }

Wenn der Dateiname existiert (fileexists), wird die gesamte Datei zeilenweise ausgelesen. Jede Zeile wird an den Leerzeichen getrennt, wobei in Begriffe in doppelten Anführungszeichen nicht getrennt werden. Ist ein zweites Leerzeichen außerhalb der Anführungszeichen vorhanden, wird der letzte Teilstring ignoriert.

8.10.176  strgtok

strgtok( sSource[], sDelimiters[], sGrouping[], sToken[], iMaxLen );

sSource[]
Typ: String (200)

sDelimiters[]
Typ: String (200)

sGrouping[]
Typ: String (200)

sToken[]
Typ: String (200)

iMaxLen
Typ: Integer (0 - 200)

Diese Funktion trennt einen String (sSource) am ersten im String (sDelimitiers) angegebenen Zeichen. Die Trennung wird dort nicht ausgeführt, wo die Zeichenkette von den im String (sGrouping) angegebenen Zeichen umschlossen wird. Sollen weitere Teilstrings abgetrennt werden, kann die Funktion wiederholt ausgeführt werden. Dabei darf sSource nicht angegeben werden. Ein möglicher Reststring kann mit strgtokrest ausgegeben werden. Bequemer sind die Funktionen strgsep und strgsplit für mehrere Trennungen.

Die Funktion gibt -1 zurück, wenn kein Trennzeichen gefunden wurde.

 
Beispiel:

new sTest[MAX_TEXT_LENGTH]="?Test/12?/3/Test";  
strgtok(sTest,"/","?",sToken1,MAX_DATA_LENGTH);  
strgtok("","/","?",sToken2,MAX_DATA_LENGTH);  
strgtokrest(sToken3,MAX_DATA_LENGTH);

Der String (sTest) soll getrennt an allen Slashes getrennt werden. Dabei sind mit Fragezeichen umrahmte Zeichenketten ausgenommen. Die Aktion wird dann wiederholt und am Ende der Rest ausgegeben. Demnach ist sToken1 = „Test/12“, sToken2 = „3“ und sToken3 =“Test“.

8.10.177  strgtokrest

strgtokrest( sRest[], iMaxLen );

sRest[]
Typ: String (200)

iMaxLen
Typ: Integer (0 - 200)

Die Funktion gibt den Reststring (sRest mit der Länge iMaxLen) nach Ausführung von strgtok aus. Ist strgtok oder der Reststring leer, wird -1 zurückgegeben.

 
Beispiel:

new sTest[MAX_TEXT_LENGTH]="?Test/12?/3/Test";  
strgtok(sTest,"/","?",sToken1,MAX_DATA_LENGTH);  
strgtok("","/","?",sToken2,MAX_DATA_LENGTH);  
strgtokrest(sToken3,MAX_DATA_LENGTH);

Der String (sTest) soll getrennt an allen Slashes getrennt werden. Dabei sind mit Fragezeichen umrahmte Zeichenketten ausgenommen. Die Aktion wird dann wiederholt und am Ende der Rest ausgegeben. Demnach ist sToken1 = „Test/12“, sToken2 = „3“ und sToken3 =“Test“.

8.10.178  strinit

strinit( sString[] );

sString[]
Typ: String (200)

Die Funktion löscht den Inhalt des angegebenen Strings (sString).

 
Beispiel aus plugin_hldsld_mapvote (Funktion: ResetVoteData):
277    new i;  
278    for(i=0;i<MAX_MAPS;i++) {  
279       strinit(Maps[i]);  
280    }

Die For-Schleife löscht alle Mapnamen aus dem Feld Maps.

Gehört zu: adminlib.inc

8.10.179  strlen

strlen( const string[] );

const string[]
Typ: String (200)

Die Funktion gibt die Länge der in einem String (string) abgelegten Zeichenkette aus. Sie kann auch mit gepackten Strings umgehen (siehe dazu strpack).

 
Beispiel aus plugin_base (Funktion: admin_kick):
272 if (strlen(Reason) != 0) {  
273    snprintf(Text, MAX_TEXT_LENGTH, "You have been kicked because %s", Reason);  
274    message(real_user, Text);  
275 }  
276 kick(real_user);

Über die Länge des Strings Reason wird überprüft, ob ein Grund für den Kick angegeben wurde. Wenn es der Fall ist, wird dies dem Spieler mitgeteilt (message). Anschließend wird der Spieler vom Server geworfen.

Gehört zu: core.inc

8.10.180  strmatch

strmatch( sOne[], sTwo[], iLength);

strOne[]
Typ: String (200)

strTwo[]
Typ: String (200)

iLength
Typ: Integer (1 - 200)

Die Funktion überprüft unter Berücksichtigung der Groß- und Kleinschreibung, ob zwei Strings (strOne und strTwo) für die ersten x Zeichen (iLength) identisch sind. Sind sie identisch wird eine 1, wenn nicht wird eine 0 zurückgegeben.

 
Beispiel aus plugin_fun (Funktion: HandleSay):
242   convert_string(HLCommand,Command,MAX_COMMAND_LENGTH);  
243   convert_string(HLData,Data,MAX_DATA_LENGTH);  
244   convert_string(HLUserName,User,MAX_NAME_LENGTH);  
245  
246   strstripquotes(Data);  
247  
248   if (strmatch(Data, "glow ", strlen("glow "))==1) {

Zunächst werden die Funktionsargumente in Small-Strings konvertiert (convert_string). Danach werden mögliche Anführungszeichen um den String entfernt (strstripquotes). Abschließend wird nur dann die If-Verzweigung ausgeführt, wenn die ersten 5 Zeichen von Data mit „glow „ übereinstimmen.

Gehört zu: adminlib.inc

Siehe auch: streq, strcasecmp

8.10.181  strncasecmp

strncasecmp( sString1[], sString2[], iNum );

sString1[]
Typ: String (200)

sString2[]
Typ: String (200)

iNum
Typ: Integer (0 - 200)

Die Funktion vergleicht zwei Strings (sString1 und sString2) über die Länge (iNum). Groß- und Kleinschreibung wird nicht beachtet. Sind beide Strings identisch, wird eine 0 zurückgegeben. Man erhält eine 0 zurück, wenn beide Strings gleich sind. Ist das erste ungleiche Zeichen in den Strings bei sString1 größer als bei sString2, wird eine Zahl größer als 0 zurückgegeben. Umgekehrt wird eine Zahl kleiner als 0 zurückgegeben.

 
Beispiel aus plugin_dio_motm51 (Funktion: say_motm):
210             if (strncasecmp(strColor,"!red",4)==0) {  
211                Red = 250;  
212                Green = 10;  
213                Blue =10;

Es wird überprüft, ob die ersten 4 Zeichen in strColor „!red“ entsprechen. Nur dann werden die Farbanteile (Red, Green und Blue) definiert.

Gehört zu: string.inc

Siehe auch: strcmp, strcasecmp, strncmp, strmatch

8.10.182  strncat

strncat( sDest[], sSource[], iNum, iMaxLen );

sDest[]
Typ: String (200)

sSearch[]
Typ: String (200)

iNum
Typ: Integer (0 - 200)

iMaxLen
Typ: Integer (0 - 200)

Diese Funktion fügt einen String (sSource mit der Länge iMaxLen) an einen anderen (sDest) an. Es werden jedoch nur eine bestimmte Anzahl an Zeichen (iNum) vom String (sSource) angehängt.

 
Beispiel:

new sTest1[MAX_TEXT_LENGTH]="Test123";  
new sTest2[MAX_TEXT_LENGTH]="Test456";  
strncat(sTest1,Test2,5,MAX_TEXT_LENGTH);

Es werden nur die ersten 5 Zeichen von sTest2 an sTest1 angehängt. Der String sTest1 ist nach der Anwendung von strncat „Test123Test4“.

Gehört zu: string.inc

Siehe auch: strcat, snprintf

8.10.183  strncmp

strncmp( sString1[], sString2[], iNum );

sString1[]
Typ: String (200)

sString2[]
Typ: String (200)

iNum
Typ: Integer (0 - 200)

Die Funktion vergleicht zwei Strings (sString1 und sString2) über eine bestimmte Länge (iNum). Groß- und Kleinschreibung wird beachtet. Sind beide Strings identisch, wird eine 0 zurückgegeben. Man erhält eine 0 zurück, wenn beide Strings gleich sind. Ist das erste ungleiche Zeichen in den Strings bei sString1 größer als bei sString2, wird eine Zahl größer als 0 zurückgegeben. Umgekehrt wird eine Zahl kleiner als 0 zurückgegeben.

 
Beispiel aus plugin_CS (Funktion: SetRestrictions):
679     if(strncmp(Data,"team ",5) == 0) {  
680         new sTeam[3];  
681         new sWhat[MAX_DATA_LENGTH];  
682         new iTeam;  
683         strsep(Data[5]," ",sTeam,3,sWhat,MAX_DATA_LENGTH);

Falls die ersten fünf Zeichen von Data unter Berücksichtigung der Groß- und Kleinschreibung „team “ entsprechen, wird der String Data[5] über ein Leerzeichen in sTeam und sWhat geteilt.

Gehört zu: string.inc

Siehe auch: strcasecmp, strcmp, strmatch, strncasecmp

8.10.184  strncpy

strncpy( sDest[], sSource[], iNum, iMaxLen );

sDest[]
Typ: String (200)

sSource[]
Typ: String (200)

iNum
Typ: Integer (0 - 200)

iMaxLen
Typ: Integer (0 - 200)

Kopiert einen String (sSource) über einen anderen (sDest mit der Länge iMaxLen), wobei nur eine bestimmte Anzahl an Zeichen (iNum) kopiert werden.

 
Beispiel aus plugin_jack9_chime52 (Funktion: SpeakTime):
93    if(streq(THour, "12")==1) {  
94       strncpy(words[1], "twelve ", strlen("twelve "),MAX_DATA_LENGTH);  
95    }

Wenn der String THour „12“ entspricht, werden nur die ersten 7 Zeichen von „twelve „ in words[1] geschrieben.

Gehört zu: string.inc

Siehe auch: strcpy

8.10.185  strpack

strpack( dest[], const source[] );

dest[]
Typ: String (200)

const source[]
Typ: String (200)

Durch diese Funktion wird ein String (source) gepackt und in einen anderen (dest) geschrieben. Der neue String benötigt nur ein Viertel des Speicherplatzes. Unter Umständen kann man ein wenig Speicher sparen. Es rentiert sich aber nur, wenn nicht gleichzeitig der gleiche String ungepackt definiert wird. Außerdem sollte man in Admin Mod seine Plugins auf Geschwindigkeit nicht Speicher optimieren. Speicher ist eigentlich nie ein Problem.

 
Beispiel:

new spTest[7 char];  
strpack(spTest,"Test123");

Es wird ein Feld spTest für einen gepackten String von sieben Zeichen länge definiert. Anschließend wird „Test123“ gepackt und in spTest geschrieben.

Gehört zu: core.inc

Siehe auch: strunpack

8.10.186  strrchr

strrchr( sSource[], iChar );

sSource[]
Typ: String (200)

iChar
Typ: Integer (0 - 256)

Die Funktion ermittelt die Position des ersten Vorkommens des Zeichens (iChar) im String (sSource) von rechts beginnend. Für das Zeichen muss die ASCII-Nummer angegeben werden. Vereinfacht kann auch das entsprechende Zeichen in einfache Anführungszeichen gesetzt werden. Die Funktion liefert -1 zurück, falls das Zeichen nicht gefunden wurde.

Die Funktion ist ein Alias für rindex.

 
Beispiel aus plugin_rindy_chasecam53 (Funktion: plugin_connect):
46     convert_string(HLIP,UserIP,MAX_IP_LENGTH);  
47     if(strrchr(UserIP,’:’) != -1) UserIP[strrchr(UserIP,’:’)] = 0;

Es wird zunächst der HL String HLIP in den Small String UserIP konvertiert. Anschließend wird überprüft, ob der Doppelpunkt in UserIP zu finden ist. Ist dies der Fall wird anstelle des Doppelpunktes ein 0 in die Zelle des Strings geschrieben, was den String an dieser Stelle beendet. Auf diese Weise wird der übergebene Port abgetrennt.

Gehört zu: string.inc

Siehe auch: index, rindex, strchr

8.10.187  strsep

strsep( sSource[], sDelimiters[], ... );

sSource[]
Typ: String (200)

sDelimiters[]
Typ: String (200)

...
variable Anzahl an Argumenten und Stringlängen (kommagetrennt)

Diese Funktion trennt einen String (sSource) an im String (sDelimitiers) angegebenen Zeichen. Werden nicht ausreichend Argumente (...) für die Aufnahme der Teilstrings angegeben, wird der Rest ungetrennt im letzten Argument übergeben.

Die Funktion gibt zurück, wieviele Teilstrings gefunden wurden bzw. -1, wenn kein Teilstring gefunden wurde.

 
Beispiel aus plugin_CS (Funktion: SetRestrictions):
679     if(strncmp(Data,"team ",5) == 0) {  
680         new sTeam[3];  
681         new sWhat[MAX_DATA_LENGTH];  
682         new iTeam;  
683         strsep(Data[5]," ",sTeam,3,sWhat,MAX_DATA_LENGTH);

Falls die ersten fünf Zeichen von Data „team “ unter Berücksichtigung der Groß- und Kleinschreibung entsprechen, wird der String Data[5] über ein Leerzeichen in sTeam und sWhat geteilt.

8.10.188  strsplit

strsplit( sSource[], sDelimiters[], ... );

sSource[]
Typ: String (200)

sDelimiters[]
Typ: String (200)

...
variable Anzahl an Argumenten und Stringlängen (kommagetrennt)

Diese Funktion trennt einen String (sSource) an im String (sDelimitiers) angegebenen Zeichen. Werden nicht ausreichend Argumente (...) für die Aufnahme der Teilstrings angegeben, wird der Rest verworfen.

Die Funktion gibt zurück, wieviele Teilstrings gefunden wurden bzw. -1, wenn kein Teilstring gefunden wurde.

 
Beispiel aus plugin_bk_cron54 (Funktion: admin_cron_refresh):
229                strsplit(timevar[j],"/",szaehler,3,snenner,3);  
230                zaehler=strtonum(szaehler);  
231                nenner=strtonum(snenner);

Der String timevar[j] wird über den Slash als Trennzeichen in zwei Strings (Länge jeweils 3) szaehler und snenner aufgeteilt. Beide Strings werden in Ganzzahlen umgewandelt (strtonum).

8.10.189  strspn

strspn(sSource[], sSearch[] );

sSource[]
Typ: String (200)

sSearch[]
Typ: String (200)

Die Funktion sucht Zeichen aus einem String (sSearch) in einem anderen String (sSource). Sie gibt die Länge des Teilstrings zurück, der von links beginnend, nur Zeichen aus sSearch besitzt. Da Strings Felder sind, ist die Länge gleichzeitig die Position des ersten in sSearch vorhandenen Zeichens.

 
Beispiel aus plugin_rindy_advretribution55 (Funktion: AdminSlapTeam):
91     if(strlen(Data) == 0 || strlen(Data) != strspn(Data,"1234")) {  
92         selfmessage("Wrong syntax");  
93         selfmessage("You must enter the team number (1 - 4).");

Es wird überprüft, ob die Stringlänge von Data 0 ist. Weiterhin wird überprüft, wie lang der Teilstring von Data ist, der nur die Zahlen von 1 bis 4 beinhalten. Ist die Länge des Teilstrings ungleich der Gesamtlänge, besteht der String nicht nur aus den Zahlen 1 bis 4. Es wird dann eine zweizeilige Fehlermeldung ausgegeben.

Gehört zu: string.inc

Siehe auch: strcspn

8.10.190  strstr

strstr( sSource[], sSearch[] );

sSource[]
Typ: String (200)

sSearch[]
Typ: String (200)

Die Funktion sucht einen String (sSearch) in einem anderen String (sSource). Groß- und Kleinschreibung wird beachtet. Wird der Suchstring gefunden, gibt die Funktion eine Zahl größer als 0 zurück. Wenn der String nicht gefunden wurde, gibt die Funktion eine -1 zurück. Ist der Suchstring gleich dem anderen String wird eine 0 zurückgegeben.

 
Beispiel aus plugin_base (Funktion: admin_rcon):
443    if (strstr(Data, "rcon_password") >= 0) {  
444       reject_message();  
445       return PLUGIN_HANDLED;  
446    }

Hierbei handelt es sich um eine Absicherung, dass kein Admin, der Zugriff zu admin_rcon hat, sich unberechtigt Zugriff zu RCon verschafft, indem er das Passwort ändert. Falls der String Data die Servervariable rcon_password beinhaltet, wird die Meldung „You do not have access to this command“ angezeigt und die weitere Abarbeitung abgebrochen.

Gehört zu: string.inc

Siehe auch: strcasestr, strcasestrx, strstrx

8.10.191  strstripquotes

strstripquotes( str[] );

str[]
Typ: String (200)

Die Funktion löscht eventuell vorhandene Anführungszeichen am Anfang und am Ende eines Strings. Es ist zwingend notwendig bei der Abarbeitung von Chatnachrichten (say, say_team) diese Funktion auszuführen. Der Text ist immer in Anführungszeichen.

Für beliebige Zeichen am Stringanfang und Ende kann auch strtrim verwendet werden.

 
Beispiel aus plugin_base (Funktion: admin_dmsg):
179    switch( sType[0] ) {  
180    case ’i’:  
181       tType = uid_index;  
182    case ’s’:  
183       tType = uid_SessionID;  
184    case ’w’:  
185       tType = uid_wonID;  
186    default:  
187       tType = uid_invalid;  
188    }  // switch()  
189  
190  
191    strstripquotes(sMessage);  
192    directmessage( sMessage, iUid, tType );

Abhängig vom Buchstaben, der sich in der ersten Zelle von sType befindet, wird der UID Typ festgelegt. Die um Anführungszeichen befreite Nachricht (Zeile 191: strstripquotes) wird der ID (Session ID oder Userindex) geschickt.

Gehört zu: adminlib.inc

Siehe auch: strtrim

8.10.192  strstrx

strstrx( sSource[], sSearch[] );

sSource[]
Typ: String (200)

sSearch[]
Typ: String (200)

Die Funktion sucht einen String (sSearch) in einem anderen String (sSource). Groß- und Kleinschreibung wird beachtet. Wird der Suchstring gefunden, gibt die Funktion eine Zahl größer als 0 zurück. Wenn der String nicht gefunden wurde oder leer ist, gibt die Funktion eine -1 zurück. Ist der Suchstring gleich dem anderen String wird eine 0 zurückgegeben.

 
Beispiel aus plugin_sdal_allowsounds56 (Funktion: plugin_init):
677    new sValue[MAX_TEXT_LENGTH];  
678    getstrvar( "amv_enable_beta", sValue, MAX_TEXT_LENGTH );  
679    if(strstrx(sValue,"menu1")!=-1){  
680       g_menuenabled=1;  
681    }

Der Inhalt der Servervariablen amv_enable_beta wird ausgelesen. Wenn der „menu1“ in sValue gefunden wurde, wird g_menuenabled auf 1 gesetzt.

Gehört zu: string.inc

Siehe auch: strstr, strcasestr, strcasestrx

8.10.193  strsubst

strsubst( sString[], sSubst[], sWith[], iMaxLen );

sString[]
Typ: String (200)

sSubst[]
Typ: String (200)

sWith[]
Typ: String (200)

iMaxLen
Typ: String (1 - 200)

Die Funktion erkennt, wo sich in einem String (sString mit der Länge iMaxLen) ein anderer String (sSubst) befindet. Alle Vorkommen von sSubst werden durch den String sWith ersetzt.

 
Beispiel aus plugin_retribution (Funktion: RemoveUserFlag):
179 if(get_vaultdata(sAuthID,VaultData,MAX_DATA_LENGTH) != 0) {  
180    if (strcasestr(VaultData," llama") != -1) {  
181       strsubst(VaultData," llama", "", MAX_DATA_LENGTH);  
182       set_vaultdata(sAuthID,VaultData);  
183    }  
184 }

Wenn eine Eintrag mit der AuthID in der vault.ini gefunden wurde, wird überprüft, ob die Zeichenkette „ llama“ enthalten ist. Ist dies der Fall, wird im String VaultData „ llama“ durch eine leere Zeichenkette ersetzt und somit gelöscht. Abschließend wird der Text zurück in die vault.ini geschrieben.

Gehört zu: string.inc

Siehe auch: snprintf

8.10.194  strtok

strtok( sSource[], sDelimiters[], sToken[], iMaxLen );

sSource[]
Typ: String (200)

sDelimiters[]
Typ: String (200)

sToken[]
Typ: String (200)

iMaxLen
Typ: Integer (0 - 200)

Diese Funktion trennt einen String (sSource) am ersten im String (sDelimitiers) angegebenen Zeichen. Sollen weitere Teilstrings abgetrennt werden, kann die Funktion wiederholt ausgeführt werden. Dabei darf sSource nicht angegeben werden. Ein möglicher Reststring kann mit strtokrest ausgegeben werden. Bequemer sind die Funktionen strsep und strsplit für mehrere Trennungen.

Die Funktion gibt -1 zurück, wenn kein Trennzeichen gefunden wurde.

 
Beispiel aus plugin_showip57 (Funktion: admin_showip):
102 strtok(UserIP[i], ":", IP, MAX_IPADDRESS);  
103 strcat(Name,IP,MAX_NAME_LENGTH);

Der String UserIP[i] wird am ersten Doppelpunkt geteilt und der erste Teil in den String IP geschrieben. Anschließend wird dieser an den String Name angehängt.

8.10.195  strtokrest

strtokrest( sRest[], iMaxLen );

sRest[]
Typ: String (200)

iMaxLen
Typ: Integer (0 - 200)

Die Funktion gibt den Reststring (sRest mit der Länge iMaxLen) nach Ausführung von strgtok aus. Ist strgtok oder der Reststring leer, wird -1 zurückgegeben.

 
Beispiel aus plugin_prison258 (Funktion: admin_showip):
102 strtok(line,":",storedmap,MAX_DATA_LENGTH);  
103 strtok("",":",tmp,MAX_DATA_LENGTH);  
104 x = strtonum(tmp);  
105 strtok("",":",tmp,MAX_DATA_LENGTH);  
106 y = strtonum(tmp);  
107 strtok("",":",tmp,MAX_DATA_LENGTH);  
108 z = strtonum(tmp);  
109 strtokrest(tmp,MAX_DATA_LENGTH);

Aus dem String line werden über den Doppelpunkt als Trennzeichen Stück für Stück Daten extrahiert und teilweise in Ganzzahlen (x, y, z) umgewandelt. Am Ende wird der Reststring ausgelesen.

8.10.196  strtonum

strtonum( sString[] );

sString[]
Typ: String (200)

Die Funktion wandelt eine als String vorliegende Zahl (sString) in eine Ganzzahl um.

 
Beispiel aus plugin_retribution (Funktion: admin_execteam):
207    strbreak(Data, strTeam, Cmd, MAX_TEXT_LENGTH);  
208    if (strlen(Cmd) == 0) {  
209       selfmessage( "Unparsable format: no command found.");  
210       return PLUGIN_HANDLED;  
211    }  
212    ExecTeam = strtonum(strTeam);

Der String Data wird am ersten Leerzeichen in strTeam und Cmd geteilt. Ist Cmd leer, wird eine Fehlermeldung in der Console ausgegeben. Anderenfalls wird strTeam in eine Ganzzahl umgewandelt.

Gehört zu: admin.inc

Siehe auch: numtostr

8.10.197  strtrim

strtrim( sString[], sTrim[], iWhere = 2 );

sString[]
Typ: String (200)

sTrim[]
Typ: String (200)

iWhere = 2
Typ: Integer (0 - 2)

Die Funktion entfernt die in einem String aufgeführten Zeichen (sTrim) am Anfang (iWhere=0), am Ende (iWhere=1) oder am Anfang und Ende (iWhere=2) eines Strings (sString). Sie gibt darüber hinaus die Anzahl der entfernten Zeichen an oder -1, wenn kein Zeichen entfernt wurde.

 
Beispiel aus plugin_bk_botmanager59 (Funktion: admin_bot_set):
266    strbreak(sValue,sBotCvar,sValue,MAX_DATA_LENGTH);  
267    strtrim(sValue," ",2);  
268    strtrim(sBotCvar," ",2);

Der Wert sValue wird in sBotCvar und sValue aufgeteilt (strbreak). Beiden Variablen werden am Anfang und am Ende von möglichen Leerzeichen befreit.

Gehört zu: string.inc

Siehe auch: strstripquotes

8.10.198  strunpack

strunpack( dest[], const source[] );

dest[]
Typ: String (200)

const source[]
Typ: String (200)

Durch diese Funktion wird ein String (source) entpackt und in einen anderen (dest) geschrieben. Die meisten Funktionen benötigen ungepackte Strings.

Unter Umständen kann man ein wenig Speicher sparen. Es rentiert sich aber nur, wenn nicht gleichzeitig der gleiche String ungepackt definiert wird. Außerdem sollte man in Admin Mod seine Plugins auf Geschwindigkeit nicht Speicher optimieren. Speicher ist eigentlich nie ein Problem.

 
Beispiel:

new spTest[7 char]=!"Test123";  
new sTest[7];  
strunpack(sTest,spTest);

Es wird ein gepackter String der Länge 7 definiert. Es ist das Ausrufezeichen vor der Zeichenkette „Test123“ zu beachten, das den Compiler anweist den Text als gepackt zu handhaben. Zu Letzt wird der String spTest in sTest entpackt.

Gehört zu: core.inc

Siehe auch: strpack

8.10.199  swapchars

swapchars( c );

c
Typ: Integer (-2147483648 bis 2147483647)

Die Funktion dreht die Bytes in einem Wert (c) um.

new iTest=33;  
iTest=swapchars( iTest );

Als zu drehender Wert wird 33 verwendet. Es handelt sich dabei um das Bitmuster „0000000000000000000000000100001“. Als Ergebnis wird wieder in iTest das Bitmuster „1000010000000000000000000000000“ geliefert (entspricht 553648128). Anhand des Bitmusters kann man die Funktionsweise von swapchars erkennen.

Gehört zu: core.inc

8.10.200  systemtime

systemtime( );

Die Funktion liefert die Sekunden seit dem 1.1.1970 zurück.

 
Beispiel aus plugin_retribution (Funktion: admin_gag):
207    if (strlen(strTime) != 0) {  
208       new Time = systemtime();  
209       GagTime = strtonum(strTime) * 60;  
210       GagTime += Time;  
211    }

Wenn der String strTime nicht leer ist, wird die aktuelle Sekundenzahl ermittelt. Anschließend wird der String strTime in eine Zahl umgewandelt und mit 60 multipliziert. Abschließend wird die Sekundenzahl zur Variable GagTime addiert.

Gehört zu: admin.inc

Siehe auch: servertime

8.10.201  teleport

teleport( sPlayer[], iX, iY, iZ );

sPlayer[]
Typ: String (33)

iX
Typ: Integer (-2147483648 - 2147483647)

iY
Typ: Integer (-2147483648 - 2147483647)

iZ
Typ: Integer (-2147483648 - 2147483647)

Diese Funktion teleportiert einen Spieler (sPlayer) zu den angegebenen Koordinaten (iX, iY, iZ). Wenn admin_fx in der adminmod.cfg aktiviert wurde, gibt es zusätzliche Effekte.

Valide Koordinaten kann man über die Funktion get_userorigin erhalten.

 
Beispiel aus plugin_retribution (Funktion: admin_bury):
507             get_userorigin(TargetName, x, y, z);  
508             teleport(TargetName, x, y, (z-25));

Zunächst werden die Koordinaten des Spielers (TargetName) ermittelt (get_userorigin). Anschließend wird er um 25 Einheiten tiefer gesetzt. Sofern sich der Spieler zu diesem Zeitpunkt nicht hoch in der Luft befindet, wird er in den Boden versetzt, so dass er sich nicht mehr bewegen kann.

Gehört zu: admin.inc

Siehe auch: get_userorigin

8.10.202  timeleft

timeleft( iPrintToConsole = 1 );

iPrintToConsole = 1
Typ: Integer (0 - 1)

Die Funktion ermittelt die verbleibenden Sekunden bis zum Mapwechsel. Über das Argument iPrintToConsole wird eingestellt, ob die Restzeit in Minuten und Sekunden auch in der Console angezeigt wird, wobei 0 keine Anzeige bedeutet.

 
Beispiel aus plugin_chat (Funktion: SayTimeleft):
61 SayTimeleft() {  
62    new Text[MAX_TEXT_LENGTH];  
63    new Seconds = timeleft(0);  
64  
65    Seconds /= 60;  
66    snprintf(Text, MAX_TEXT_LENGTH, "Time remaining on map: %i minutes", Seconds);  
67    say(Text);  
68 }

Die Anzahl der bis zum Mapende verbleibenden Sekunden wird ermittelt und in die Variable Seconds geschrieben. Diese wird durch 60 geteilt, um Minuten zu erhalten. Die Minutenzahl wird in den String Text eingebettet, der abschließend im Chat ausgegeben wird.

Gehört zu: admin.inc

Siehe auch: maptime

8.10.203  tolower

tolower( c );

c
Typ: Integer (0 - 256)

Wenn es sich bei einem Zeichen (c) um einen Großbuchstaben handelt, wandelt die Funktion dieses in einen Kleinbuchstaben um. Um nicht den ASCII-Code verwenden zu müssen, kann vereinfacht auch das entsprechende Zeichen in einfache Anführungszeichen gesetzt werden.

 
Beispiel aus plugin_CS (Funktion: strtolower):
1566 strtolower(String[]) {  
1567     new i;  
1568     for(i=0;String[i];i++) {  
1569         String[i] = tolower(String[i]);  
1570     }  
1571 }

Diese Funktion wandelt über ein For-Schleife alle Zeichen des Strings String in Kleinbuchstaben um.

Gehört zu: core.inc

Siehe auch: toupper

8.10.204  toupper

toupper( c ); Typ: Integer (0 - 256)

Wenn es sich bei einem Zeichen (c) um einen Kleinbuchstaben handelt, wandelt die Funktion dieses in einen Großbuchstaben um. Um nicht den ASCII-Code verwenden zu müssen, kann vereinfacht auch das entsprechende Zeichen in einfache Anführungszeichen gesetzt werden.

 
Beispiel aus plugin_CS (Funktion: ShowClass):
1343     Message[0] = toupper(Message[0]);  
1344     selfmessage(Message);

Diese Funktion wandelt den ersten Buchstaben des Strings Message in einen Großbuchstaben, um ihn dann auf der Console des Admins auszugeben.

Gehört zu: core.inc

Siehe auch: tolower

8.10.205  typesay

typesay( sMessage[], iTime, iRed, iGreen, iBlue );

sText[]
Typ: String (500) (max. Zeilenlänge: 80)

iTime
Typ: Integer (0 - 2147483647)

iRed
Typ: Integer (0 - 255)

iGreen
Typ: Integer (0 - 255)

iBlue
Typ: Integer (0 - 255)

Mit dieser Funktion kann man eine bunte Nachricht (sText) für alle Spieler in der linken unteren Ecke des Bildschirms produzieren. iTime ist die Einblendzeit in Sekunden. iRed ist der Rotanteil, iGreen der Grünanteil und iBlue der Blauanteil in der Nachricht. Die Funktion messageex ermöglicht die gleiche Funktionalität jedoch ohne Farbwahl für einzelne Spieler.

 
Beispiel aus plugin_base (Funktion: admin_tsay):
549    if (streq(Color,"red")==1) {  
550       typesay(Message,10,250,10,10);

Wenn der Text Color gleich „red“ ist, wird die Nachricht in Message für 10 Sekunden in einen hellem Rot dargestellt. Es ist zu beachten, dass eine Zeile maximal 80 Zeichen lang sein darf. Mit Zeilenumbrüchen sind bis zu 500 Zeichen möglich.

Gehört zu: admin.inc

Siehe auch: centersay, centersayex, messageex

8.10.206  unban

unban( sWONID[] );

sWONID[]
Typ: String (39)

Die Funktion entbannt den Spieler unter Angabe der Steam ID oder IP (sWONID).

 
Beispiel aus plugin_base (Funktion: admin_unban):
572 public admin_unban(HLCommand,HLData,HLUserName,UserIndex) {  
573    new Command[MAX_COMMAND_LENGTH];  
574    new Data[MAX_DATA_LENGTH];  
575    new User[MAX_NAME_LENGTH];  
576  
577    convert_string(HLCommand,Command,MAX_COMMAND_LENGTH);  
578    convert_string(HLData,Data,MAX_DATA_LENGTH);  
579    convert_string(HLUserName,User,MAX_NAME_LENGTH);  
580    unban(Data);  
581    log_command(User,Command,Data);  
582    return PLUGIN_HANDLED;  
583 }

Alle HL Strings werden in Small Strings umgewandelt. In der Variable Data wird die Steam ID oder die IP erwartet. Abschließend wird die Aktion basierend auf admin_quiet in die Logdateien geschrieben.

Gehört zu: admin.inc

Siehe auch: ban

8.10.207  userlist

userlist( sPattern[]= “” );

sPattern[]
Typ: String (33)

Diese Funktion gibt in der Console des aufrufenden Admins einen Überblick über die momentan Spielenden. Dabei wird der Name, die Session ID, die Steam ID, der Accesslevel und der Immunitätsstatus des Spielers angegeben. Man kann auch die Spielerausgabe über ein optionales Muster einschränken.

 
Beispiel aus plugin_base (Funktion: admin_userlist):
586 public admin_userlist(HLCommand,HLData,HLUserName,UserIndex) {  
587    new Data[MAX_DATA_LENGTH];  
588  
589    convert_string(HLData,Data,MAX_DATA_LENGTH);  
590    userlist(Data);  
591    return PLUGIN_HANDLED;  
592 }

Es wird die Spielerliste ausgegeben, die ggf. durch ein Muster (z.B. „a“ für alle Spieler, die ein „a“ im Namen haben) eingeschränkt wurde.

Gehört zu: admin.inc

8.10.208  valid_map

valid_map( sMap[] );

sMap[]
Typ: String (100)

Die Funktion überprüft, ob sich eine angegebene Map (sMap) auf dem Server befindet. Ist eine maps.ini in der adminmod.cfg definiert, gelten nur die dort eingetragenen Maps als gültig. Dieser Check lässt sich mit valid_mapex umgehen.

 
Beispiel aus plugin_base (Funktion: admin_map):
307    if (valid_map(Data)==1) {  
308       say_command(User,Command,Data);  
309       changelevel(Data, 4);

Falls es sich bei Data um eine gültige Map (auch unter Berücksichtigung der maps.ini) handelt, wird abhängig von der Einstellung admin_quiet eine Nachricht in den Chat geschrieben und nach vier Sekunden ein Wechsel auf die Map initiiert.

Gehört zu: admin.inc

Siehe auch: valid_mapex

8.10.209  valid_mapex

valid_mapex( sMap[] );

sMap[] 
Typ: String (100)

Die Funktion überprüft, ob sich eine angegebene Map (sMap) auf dem Server befindet. Ein zusätzlicher Check, ob die Map auch in der maps.ini steht, kann mit valid_map durchgeführt werden.

 
Beispiel:

   if (valid_mapex(Data)==1) {  
      say_command(User,Command,Data);  
      changelevel(Data, 4);

Falls es sich bei Data um eine gültige Map (unter Ausschluss der maps.ini) handelt, wird abhängig von der Einstellung admin_quiet eine Nachricht in den Chat geschrieben und nach vier Sekunden ein Wechsel auf die Map initiiert.

Gehört zu: admin.inc

Siehe auch: valid_map

8.10.210  version

version( );

Diese Funktion gibt die aktuelle Admin Mod Version in der Spielerconsole aus.

 
Beispiel:

public admin_ver(HLCommand,HLData,HLUserName,UserIndex) {  
   version();  
   return PLUGIN_HANDLED;  
}

Es wird die Versionsnummer Admin Mods beim aufrufenden Admin in der Console ausgegeben.

Gehört zu: admin.inc

8.10.211  vote

vote( sVoteString[], ... );

sVoteString[]
Typ: String (500)

...
variable Anzahl (max. 12) an Argumenten (kommagetrennt)

Diese Funktion führt einen Vote aus. Dabei muss eine Frage gestellt werden (sVoteString). Anschließend folgen kommagetrennt, die möglichen Anworten (max. 10). Die letzten zwei Argumente beinhalten die nach dem Vote aufzurufende Funktion und die an diese Funktion zu übergebenen Parameter. Mehr zur Verwendung dieser Funktion ist dem Tutorial zu entnehmen.

 
Beispiel aus plugin_base (Funktion: admin_vsay):
765    if (vote_allowed()!=1) {  
766       selfmessage( "Vote not allowed at this time.");  
767       return PLUGIN_HANDLED;  
768    }  
769  
770    log_command(User,Command,Data);  
771    vote(Data,"Yes","No","HandleVsay", Data);  
772    return PLUGIN_HANDLED;

Zunächst wird überprüft, ob überhaupt ein Vote erlaubt ist (vote_allowed). Wenn dies nicht der Fall ist, wird dem Admin eine Fehlermeldung ausgegeben. Anderenfalls wird der Befehl in die Logdateien geschrieben und ein Vote mit der in Data stehenden Frage und den Antwortmöglichkeiten „Yes“ und „No“ ausgeführt. Die aufzurufende Funktion lautet dabei „HandleVsay“, und die Frage wird als Parameter an diese Funktion übertragen.

Gehört zu: admin.inc

Siehe auch: vote_allowed

8.10.212  vote_allowed

vote_allowed( );

Diese Funktion überprüft, ob ein Vote ausgeführt werden darf. Sie gibt 1 zurück, wenn ein Vote erlaubt ist. Anderenfalls gibt sie 0 zurück.

 
Beispiel aus plugin_base (Funktion: admin_vsay):
765    if (vote_allowed()!=1) {  
766       selfmessage( "Vote not allowed at this time.");  
767       return PLUGIN_HANDLED;  
768    }  
769  
770    log_command(User,Command,Data);  
771    vote(Data,"Yes","No","HandleVsay", Data);  
772    return PLUGIN_HANDLED;

Zunächst wird überprüft, ob überhaupt ein Vote erlaubt ist (vote_allowed). Wenn dies nicht der Fall ist, wird dem Admin eine Fehlermeldung ausgegeben. Anderenfalls wird der Befehl in die Logdateien geschrieben und ein Vote mit der in Data stehenden Frage und den Antwortmöglichkeiten „Yes“ und „No“ ausgeführt.

Gehört zu: admin.inc

Siehe auch: vote

8.10.213  writefile

writefile( sFilename[], sLine[], iLineNum = -1 );

sFilename[]
Typ: String (200)

sLine[]
Typ: String (200)

iLineNum
Typ: Integer (0 - 2147483647)

Die Funktion schreibt einen Text (sLine) in eine Zeile (iLineNum) einer Datei (sFilename). Wird iLineNum nicht oder als -1 angegeben, wird der Text als neue Zeile an die Datei angehängt.

Die Funktion ist sehr zeitintensiv, da gewartet werden muss bis der Festplattenzugriff erfolgt ist. Schreibt man mehrere Zeilen mit einer For-Schleife, wird bei jeder Zeile die Datei neu geöffnet, was weitere Verzögerungen verursacht. Man sollte sich daher genau überlegen, ob man diese Funktion nutzen möchte. Beim Schreiben während des Serverstarts bzw. beim vereinzelten Anhängen von Text ist dies noch akzeptabel, ein Schreiben während der Spielzeit kann bei einer For-Schleife durchaus zu Aussetzern im Spiel führen (Lag). Wenn möglich sollte man seine Einstellungen über die vault.ini lesen und schreiben.

 
Beispiel aus plugin_bk_res60 (Funktion: add_res_data):
155       iLines=filesize(sMap,lines);  
156       for(i=1;i<=iLines;i++){  
157          readfile(sMap,sLine,i,MAX_DATA_LENGTH);  
158          writefile(sMap2,sLine,-1);  
159       }

Es wird die Anzahl der Zeilen der Datei (sMap) ausgelesen. Anschließend werden die Daten über eine For-Schleife zeilenweise von einer Datei (sMap) in eine andere (sMap2) kopiert. Die Zeilen übernehmen nicht unbedingt die Zeilennummer der Ursprungsdatei. Die Zeilen werden beim Schreiben nur angehängt (-1).

Gehört zu: admin.inc

Siehe auch: deletefile, filesize, readfile, resetfile

8.11  Compiler Fehler und Warnungen

Niemand arbeitet fehlerfrei. Einige Tipp- oder auch Denkfehler sorgen für Compilerfehler oder -warnungen. U.U. kann man auch den Compiler zum Absturz bringen. Oftmals sind die Rückmeldungen auf den ersten Blick nicht besonders verständlich.

Die Syntax der Fehlermeldungen lässt sich am besten an Hand eines Beispiels erklären:

plugin_test.sma(13) Warning [217]]: loose indentation

Zunächst wird angegeben, in welchem Quellcode der Fehler auftritt. In den runden Klammern wird die Zeile angegeben, in der der Fehler aufgefallen ist. Meistens muss man sich die vorhergehende Zeile ansehen. Insbesondere bei Klammersetzungsfehlern im Quellcode kann der Fehler aber auch an einer gänzlich anderen Stelle oberhalb der gemeldeten liegen.

Es wird weiterhin angegeben, ob es sich um einen Fehler oder nur eine Warnung handelt. Bei Warnungen wird zwar der Compiliervorgang weitergeführt, ob dieser aber auch fehlerfrei durchgeführt wurde, ist nicht garantiert. Es gibt keinen Grund eine Warnung zu ignorieren. Jedes saubere Plugin muss sich warnungsfrei compilieren lassen. In eckigen Klammern ist die Fehler- bzw. Warnungsnummer gegeben, an die sich die ausgeschriebene Fehlermeldung anschließt.

Die folgenden Meldungen wird man häufiger finden:

Error [001]
Die Meldung „expected token: “;”, but found “-identifier-”“ deutet darauf hin, dass am Ende der vorhergehenden Zeile ein Semikolon vergessen wurde.
Error [010]
Der Hinweis auf „invalid function or declaration“ hat meistens den Grund, dass man sich in der angegebenen Zeile vertippt hat.
Error [021]
Die Meldung „symbol already defined: “set_timer”“ bedeutet, dass man versucht, eine bereits definierte Funktion neu zu definieren.
Error [029]
Die Nachricht „invalid expression, assumed zero“ deutet auf ein Klammersetzungsproblem hin.
Error [039]
Die Meldung „argument type mismatch (argument 1)“ bedeutet, dass einer Funktion eine Variable mit falschem Datentyp übergeben wurde (z.B. Integer statt String). Als Hilfestellung wird auch angegeben, bei welchem Argument dies geschehen ist.
Warning [209]
Die Meldung „number of arguments does not match definition“ sagt aus, dass man einer Funktion zu wenige oder zu viele Argumente übergeben hat.
Warning [209]
Beim Hinweis „symbol is never used: “test”“ wird darauf hingewiesen, dass eine als privat definierte Funktion von keiner anderen Funktion aus dem Plugin aufgerufen wird. Der Code sollte dann entfernt oder die Funktion „public“ gemacht werden.
Warning [215]
Der Ausdruck „expression has no effect“ meint meistens, dass in der Zeile ein Vergleich nur mit einem Gleichheitszeichen angestellt wurde („=“ statt „==“).
Warning [217]
Die Meldung „loose indentation“ sollte bei konsequenter Anwendung von Klammern nicht mehr auftreten. Man kann aber auch auf Klammern verzichten und Tabulatoren nutzen. Dafür müssen dann aber auch die Einrückungen komplett stimmen. Auf Grund der besseren Übersicht und der geringeren Fehlerträchtigkeit sind aber Klammern zu empfehlen.
Warning [219]
Wenn die Meldung „local variable identifier shadows a symbol at a preceding level“ erscheint, versucht man eine Variable zu definieren, die bereits global genutzt wird. Meistens wurde sie in einer der Includes definiert und ist daher nicht gleich ersichtlich. Es sollte ausreichen, den Variablennamen zu ändern.

Der Compiler kann aber auch ganz unvermutet abstürzen. Dies kann in den folgenden Fällen auftreten:

  • Doppelt definierte globale Variablen
  • Irtümlich doppelt definierte Variablen. Eine Variable darf maximal 31 Zeichen lang sein. Ist sie länger als 31 Zeichen, wird sie abgeschnitten. Sind dann zwei Variablen in den ersten 31 Zeichen gleich, führt das zum Absturz.
  • Wenn bei großen Plugins in einer der ersten Zeilen ein abschließendes Anführungszeichen vergessen wurde, kann dies zum Absturz führen.

8.12  Runtime Fehler

Neben den Fehlern beim Compilieren können auch Fehler während der Laufzeit des Plugins auftreten. Die Meldungen können dann den Logdateien entnommen werden.

3 - AMX_ERR_STACKERR
Dem Plugin ist der Speicher für lokale Variablen ausgegangen (Standard: 8 kB). Mittels der Definition #pragma dynamic 4096 kann man den Speicher auf 16 kB (4096 Cells) erhöhen. Dies erfordert in jedem Fall ein Neucompilieren des Plugins.
4 - AMX_ERR_BOUNDS
Es wurde versucht auf eine Zelle eines Feldes zuzugreifen, das nicht existiert. Meistens ist eine For-Schleife einen Schritt zu lang gewählt worden.
10 - AMX_ERR_NATIVE
Einer Admin Mod Funktion wurden ungültige Argumente (z.B. außerhalb des Gültigkeitbereichs) übergeben. Dies kann auch passieren, wenn man eine Zeile aus einer Datei liest (readfile), die länger als die maximal definierte Stringlänge ist.
11 - AMX_ERR_DIVIDE
Bei einer Berechnung wurde versucht durch Null zu teilen.
17 - AMX_ERR_FORMAT
Beim Plugin handelt es sich nicht um ein gültiges. Als Gründe kommen in Frage, dass man die SMA-Datei hochgeladen hat, ein fehlerhaftes Plugin oder aber auch ein AMXMod(X) Plugin versucht zu laden.
19 - AMX_ERR_NOTFOUND
Ein Befehl wurde in Admin Mod definiert und auf eine öffentliche Funktion verwiesen, die von Admin Mod aber nicht gefunden wurde. Mögliche Gründe dafür können eine fehlende „public“ Deklaration oder ein Tippfehler beim Funktionsnamen sein.
122 - AMX_ERR_INIT
Ein interner Admin Mod Fehler ist aufgetreten. Einziger bekannter Grund ist der Inkrementierungsversuch bei einer Feldzelle mittels „++“, was auf Grund eines Compilerbugs fehlschlägt. Oft stürzt der Server aber auch einfach sang- und klanglos ohne Fehlermeldung ab.

Zum Komplettabsturz des Servers können auch Endlosschleifen führen. Auch sollte man vermeiden Variablen direkt in Schleifen zu definieren.

1   for(new i=1;i<10;i++) {  
2     say(‘‘Test’’);  
3   }

Die Variablen werden dann nicht immer im Speicher freigegeben. Inbesondere in Kombination mit einer „break“ Anweisung kann es zu einem Absturz kommen. Man sollte daher stets die Variablen vor der Schleife definieren.

8.13  LogD Events

Wie im Tutorial gezeigt, kann man die in Admin Mod vorhandenen Events durch LogD erweitern. Jeder LogD-Event hat eine bestimmte Nummer und eine dafür festgelegte Rückgabesyntax, die als Gesamtstring zurückgegeben wird. Der String muss im Plugin an den Leerzeichen getrennt und ggf. in Integer umgewandelt werden. Im Folgenden sollen die zur Verfügung stehenden Events mit ihrer Rückgabesyntax aufgelistet werden (Tabelle 8.1).


Tabelle 8.1.: LogD Events




EventName Variablen Beispiel




5 Servername sHostname Mein$Server




50 Connect iPlayerUI 12 1.2.3.4:12345
iPlayerIP




51 Enter Game iPlayerUI 16




52 Disconnect iPlayerUI 11




53 Suicide iPlayerUI 9 grenade
sWaffe




54 Team Select iPlayerUI 5 TERRORIST
sTeam




55 Role Select iPlayerUI 2 Medic
sRole




56 Change Name iPlayerUI 6 Me$Admin
sNewName




57 Kill iKillerUI 6 4 p228
iVictimUI
sWaffe




58 Damage iAttackerUI 3 1 p228 damage#28
iVictimUI damage_armor#0
damage#iDamage health#72 armor#0
damage_armor#iDA
health#iHealth
armor#iArmor




59 PvP Action iInvokerUI 5 10 Medic_Heal
iReceiverUI
sAction




60 Player Action iPlayerUI 1 Planted_The_Bomb
sAction




61 Team Action sTeam CT Target_Saved CT#1 T#0
sAction
CT#iScoreCT
T#iScoreT




62 World Action sAction Round_Start




63 Chat n/t (Normal/Team) n 7 Wer$ist$Admin?
iPlayerUI
sText




64 Team Alliance sInvokerTeam Red Blue
sReceiverTeam




65 Team Score ReportsTeam TERRORIST 9 7
iScore
iNumTeamPlayer




66 Private Chat iInvokerUI 5 3 Wer$ist$Admin?
iReceiverUI
sText





Die Variablen werden in der angegebenen Reihenfolge mit Leerzeichen als Trennzeichen im Rückgabestring zurückgegeben. Die Bezeichnung der Variablen ist in diesem Fall willkürlich. Das „s“ deutet an, dass der Wert als String in Admin Mod ausgewertet werden soll. Entsprechend steht das „i“ für einen Zahlenwert. Der eigentliche Name der Variablen soll den Zweck andeuten. „UI“ steht dabei verkürzt für den Userindex.

Um Leerzeichen (z.B. beim Chat) darstellen zu können, ohne dass diese beim Trennen Ärger bereiten, werden diese durch „$“ ersetzt. Optionen im String werden von ihrem Wert mit einem „#“ abgesetzt.

8.14  Properties in Small

Als Schlüssel kann entweder der Name oder der Wert der Property benutzt werden. Properties sind Schlüssel-Wert-Paare, die in der AMX-Scriptengine gespeichert werden. Jede Property hat eine Zeichenkette und eine Ganzzahl. Welches davon der Schlüssel, und welches der Wert ist, kann der Scriptautor bestimmen, indem er einen der beiden Parameter leer lässt. Die ID der Property dient dazu, dass verschiedene Scripte ihre Propertys auseinander halten können. Eine Property wird durch ihre ID und ihren Schlüssel eindeutig identifiziert.

Die Vorteile von Properties gegebnüber globalen Variablen sind, dass der Speicherplatz dynamisch verwaltet wird, und somit praktisch unbegrenzt Daten gespeichert werden können. Weiterhin bleiben die Daten auch über einen Kartenwechsel hinaus erhalten. Die Nachteile sind, dass mit zunehmender Benutzung von Properties die Zugriffsgeschwindigkeit abnimmt, da diese als einfach verkettete Liste implementiert sind. Ausserdem gibt es keine Möglichkeit festzustellen, ob im Propertybereich einer ID bereits Werte liegen. Zuletzt obliegt es dem Script-Autor, die angelegten Properties wieder zu löschen, da ansonsten der Speicherverbrauch immer weiter anwächst. Properties sollten in Adminmod daher z.Z. nicht verwendet werden.

Es wird empfohlen stattdessen auf die Befehle zur Vault Datei (vault.ini) zurückzugreifen (z.B. get_vaultdata). Wer dennoch die Properties nutzen möchte, kann die Funktionen deleteproperty, existproperty, getproperty und setproperty verwenden.

1http://www.compuphase.com/pawn/pawn.htm

2http://www.adminmod.de/plugins.php?plugin=plugin_bk_hltvannounce

3http://www.adminmod.de/plugins.php?plugin=plugin_cw_creator3

4http://www.adminmod.de/plugins.php?plugin=plugin_dale_consgreet

5http://www.adminmod.de/plugins.php?plugin=plugin_bk_res

6http://www.adminmod.de/plugins.php?plugin=plugin_sdal_logd_hp50

7http://www.adminmod.de/plugins.php?plugin=plugin_cw_creator

8http://www.adminmod.de/plugins.php?plugin=plugin_bk_cron

9http://www.adminmod.de/plugins.php?plugin=plugin_sdal_logd_hp50

10http://www.adminmod.de/plugins.php?plugin=plugin_bk_cron

11http://www.adminmod.de/plugins.php?plugin=plugin_sdal_logd_hp50

12http://www.adminmod.de/plugins.php?plugin=plugin_sdal_logd_hp50

13http://www.adminmod.de/plugins.php?plugin=plugin_sdal_logd_hp50

14http://www.adminmod.de/plugins.php?plugin=plugin_bk_hltvannounce

15http://www.adminmod.de/plugins.php?plugin=plugin_bk_hltvannounce

16http://www.adminmod.de/plugins.php?plugin=plugin_spooge_AR

17http://www.valvesoftware.com

18http://store.steampowered.com/about/

19http://www.adminmod.de/plugins.php?plugin=plugin_sdal_look

20http://www.adminmod.de/plugins.php?plugin=plugin_bk_botmanager

21http://www.adminmod.de/plugins.php?plugin=plugin_blatt_monster

22http://www.adminmod.de/plugins.php?plugin=plugin_bk_botmanager

23http://www.adminmod.de/plugins.php?plugin=plugin_blatt_map

24http://www.adminmod.de/plugins.php?plugin=plugin_blatt_map

25http://www.adminmod.de/plugins.php?plugin=plugin_rules

26http://www.adminmod.de/plugins.php?plugin=plugin_wm_chat

27http://www.adminmod.de/plugins.php?plugin=plugin_bk_botmanager

28http://www.adminmod.de/plugins.php?plugin=plugin_bk_botmanager

29http://www.adminmod.de/plugins.php?plugin=plugin_logd_redirect

30http://www.adminmod.de/plugins.php?plugin=plugin_cw_creator3

31http://www.adminmod.de/plugins.php?plugin=plugin_blatt_map

32http://www.adminmod.de/plugins.php?plugin=plugin_bk_hltvannounce

33http://www.adminmod.de/plugins.php?plugin=plugin_cw_creator3

34http://www.adminmod.de/plugins.php?plugin=plugin_bk_alltalk

35http://www.adminmod.de/plugins.php?plugin=plugin_bk_timeleft

36http://www.adminmod.de/plugins.php?plugin=plugin_bk_alltalk

37http://www.adminmod.de/plugins.php?plugin=plugin_seeuser

38http://www.adminmod.de/plugins.php?plugin=plugin_budfroggy_rainbow

39http://www.adminmod.de/plugins.php?plugin=plugin_bk_res

40http://www.adminmod.de/plugins.php?plugin=plugin_cw_creator3

41http://www.adminmod.de/plugins.php?plugin=plugin_dotw

42http://www.adminmod.de/plugins.php?plugin=plugin_bk_cron

43http://www.adminmod.de/plugins.php?plugin=plugin_bk_botmanager

44http://www.adminmod.de/plugins.php?plugin=plugin_blatt_map

45http://www.adminmod.de/plugins.php?plugin=plugin_sdal_time_manager

46http://www.adminmod.de/plugins.php?plugin=plugin_bk_botmanager

47http://www.adminmod.de/plugins.php?plugin=plugin_sdal_logd_hp50

48http://www.adminmod.de/plugins.php?plugin=plugin_blatt_map

49http://www.adminmod.de/plugins.php?plugin=plugin_bk_cron

50http://www.adminmod.de/plugins.php?plugin=plugin_gnc_filtersay

51http://www.adminmod.de/plugins.php?plugin=plugin_dio_motm

52http://www.adminmod.de/plugins.php?plugin=plugin_jack9_chime

53http://www.adminmod.de/plugins.php?plugin=plugin_rindy_chasecam

54http://www.adminmod.de/plugins.php?plugin=plugin_bk_cron

55http://www.adminmod.de/plugins.php?plugin=plugin_rindy_advretribution

56http://www.adminmod.de/plugins.php?plugin=plugin_sdal_allowsounds

57http://www.adminmod.de/plugins.php?plugin=plugin_showip

58http://www.adminmod.de/plugins.php?plugin=plugin_prison2

59http://www.adminmod.de/plugins.php?plugin=plugin_bk_botmanager

60http://www.adminmod.de/plugins.php?plugin=plugin_bk_res




Powered by phpBB® Forum Software © phpBB Limited
Deutsche Übersetzung durch phpBB.de
Original Design von "[ Half-Life Admin Mod © Alfred Reynolds 2000-2003 ] - [ site design by Jägermeister ]"