Aktionen
Aktionen sind Code-Snippets, die ausgeführt werden, wenn ein Log-Ereignis vom Spielserver importiert wird. Verwende sie, um Daten zu verarbeiten und Reaktionen zu automatisieren.
Aktionen unterstützen jetzt sowohl einen server-spezifischen Workflow als auch einen Marktplatz-Workflow. Für das gemeinsame Modell hinter Marktplatz-, installierten und eigenen Aktionen siehe das Konzept Aktions-Marktplatz.
Hinweis zur Datenquelle: Aktionen hängen von importierten Server-Logs ab. Kommen Logs später an, wird die Aktionsausführung entsprechend verzögert. Vollständige Informationen zum Import-Verhalten findest du im Konzept des Log-Imports.
Navigationspfad
Server Admin->Aktionen
Tabs
Die Aktionsansicht ist in drei Tabs aufgeteilt:
Marktplatz: öffentliche Creator-Aktionen durchsuchen und auf dem aktuellen Server installierenInstalliert: bereits auf diesem Server installierte Marktplatz-Aktionen verwaltenEigene Aktionen: servereigene Aktionen mit lokalem Lua-Code erstellen und pflegen
Jeder Tab hat ein Suchfeld (Name und Beschreibung) und Filter: der Marktplatz nach Auslöser, Verifizierung und danach, ob die Aktion hier schon installiert ist; die Tabs Installiert und Eigene Aktionen nach Auslöser und danach, ob die Aktion aktiv ist.
Installierte Marktplatz-Aktionen übernehmen Code, Trigger-Ereignis und Konfigurationsschema aus der Creator-Definition. Server-Mitarbeiter verwalten nur den Aktiv-Status und die Konfigurationswerte für diesen Server.
Fertige Belohnungs-Aktionen
- Kill-Reward zahlt dem Killer für jeden PvP-Kill eine Belohnung und kann dem Opfer eine Strafe abziehen. Optionale Einstellungen legen fest, welche Kills zahlen: keine Belohnung für Spawnkills, keine Belohnung für ein Opfer, das weniger als eine bestimmte Zahl Minuten am Leben war (ein längerer Schutz für frische Spawns), keine Belohnung unter einer Mindest-K/D des Opfers und eine Staffel nach der K/D des Opfers – entweder ein fester Betrag pro Stufe oder ein Faktor auf die Kill-Belohnung. Jede Stufe gilt ab ihrer K/D bis zur nächsten Stufe. Es zählt die K/D, die dzbot im Profil des Opfers zeigt. Bleiben die Felder leer, zahlt jeder Kill wie bisher die Kill-Belohnung.
- Group Wage zahlt jedem Mitglied einer dzbot-Gruppe (Admin → Gruppen) einen festen Lohn pro Tag, Woche (ab Montag) oder Monat. Sie läuft über den Scheduler: Lege nach der Installation eine Scheduler-Aufgabe Aktion ausführen für sie an, mit den Zeiten, die du willst, z. B. jeden Montag um 18:00. Jedes Mitglied bekommt höchstens einmal pro Zeitraum in der Zeitzone deines Servers Geld – ein erneuter Lauf, von Hand oder aus einer zweiten Aufgabe, zahlt niemandem doppelt. Auf Wunsch zahlt sie nur Mitgliedern, die in den letzten Tagen auf dem Server waren, schickt jedem eine Discord-DM und postet eine Zusammenfassung in einen Kanal. Den Buchungstext legst du selbst fest. Installiere sie nur auf einem Server: Das Guthaben gilt für die ganze Organisation, eine Kopie auf einem zweiten Server zahlt denselben Mitgliedern noch einmal.
Fertige Spawnkill-Aktionen
Beide richten sich standardmäßig nach dem Label Spawnkill, also nach der Einstellung PvP-Kill – Mindest-Überlebenszeit des Opfers (2 Minuten, solange du sie nicht geändert hast) – dieselben Kills, die der Killfeed markiert und die Statistiken auslassen. Beide bieten stattdessen auch eine eigene Grenze in Minuten an, gezählt in 5-Minuten-Schritten.
- Spawn-Trap Detection meldet jeden Spawnkill in einem Moderationskanal und zählt ihn in der Spielervariable
fresh_spawn_killsdes Killers, die auf der Spieler-Detailseite steht. Kills von Spielern, die selbst erst weniger als eine bestimmte Zahl Minuten am Leben waren (Standard 30), bleiben außen vor – zwei frische Spawns, die sich gegenseitig erschießen, zählen nicht. - Fresh Spawn Autoban bannt einen Spieler, der innerhalb eines gleitenden Zeitfensters eine bestimmte Zahl Spawnkills macht (Standard 5 in 10 Minuten), und kann jeden Bann in einem Kanal posten.
- Raid Autoban bannt einen Spieler, der eine Basisstruktur auf einen Schlag zerstört — eine Kettensäge durch einen Zaun oder ein Tor —, außerhalb der Raid-Zeiten, die du einträgst (z. B. Samstag & Sonntag 18:00 – 23:59; ein Zeitfenster darf über Mitternacht gehen). Ohne Zeitfenster wird jeder solche Raid gebannt. Bann-Dauer, -Umfang und -Grund sind einstellbar, ein Filter begrenzt es auf Zonen, Fraktionen oder Gruppen, und im Nur-melden-Modus postet es Raids in einen Kanal, ohne zu bannen. Abbauen mit Werkzeug zählt nicht: Das Log unterscheidet nicht, ob ein Besitzer seine eigene Wand abbaut oder ein Raider. Außerdem bannt es die Mittäter: alle, die in den 10 Minuten vor dem Raid im Umkreis von 100 m waren und nicht zur geraideten Basis gehören. Zur Basis gehören alle mit mindestens 3 geloggten Bauaktionen an dieser Basis, deren andere Accounts und alle Mitglieder ihrer Fraktionen und der verbündeten Fraktionen. So kann sich nicht einer opfern, während der Rest der Gruppe weiter raidet. Positionen werden nur alle paar Minuten geloggt, deshalb kann auch jemand erwischt werden, der nur vorbeigelaufen ist — die Meldung nennt alle, die mit dem Raider gebannt wurden, und falsche Banns hebst du von Hand auf. Umkreis, Minuten und Mindest-Bauaktionen sind einstellbar; schalte die Mittäter aus, um nur den Raider zu bannen. Steht an der Stelle keine bekannte Basis, wird kein Mittäter gebannt.
- Explosive Raid Autoban macht dasselbe, wenn jemand außerhalb der Raid-Zeiten Sprengstoff in einer Basis platziert, zu der er nicht gehört. DayZ loggt keine Wand, die von Sprengstoff zerstört wird, nur das Platzieren der Ladung — so lässt sich ein Sprengstoff-Raid überhaupt erkennen. Standardmäßig zählen Plastik- und improvisierter Sprengstoff, Claymores nicht (die legt man auch zur Verteidigung); die Liste der Klassennamen ist einstellbar. Sprengstoff außerhalb jeder bekannten Basis oder in der eigenen Basis wird ignoriert. Mittäter werden wie bei Raid Autoban gebannt.
Fertige Discord-Feeds
Jeder postet eine Art von Ereignis in einen Discord-Kanal, den du auswählst. Jeder Feed hat einen Ereignis-Filter (welche Ereignisse zählen — siehe Ereignis-Filter-Felder) und einen Discord-Post, den du mit Live-Vorschau gestaltest (siehe Discord-Embed-Felder). Sie laufen neben dem eingebauten Kill- und Schadensfeed aus Einstellungen → Discord, der bleibt, wie er ist.
- Login Feed und Logout Feed — ein Spieler ist beigetreten oder gegangen. Die Position ist standardmäßig aus; schalte das Feld Location nur in einem Admin-Kanal ein.
- Build Feed und Placement Feed — jedes gebaute Basenteil und jedes platzierte Zelt, Fass, jede Flagge oder Falle, mit Kartenlink. Gedacht für einen Admin-Kanal: Es zeigt, wo Basen stehen.
- PvE Death Feed — eine Aktion pro Todesart, installiere die, die du willst: Infected (Infizierte), Animals & Environment (Wölfe, Bären, Minen, Fallen, Sprengstoff, Fahrzeuge, Feuer, Stürze — die Ursache so, wie DayZ sie loggt), Bled Out (verblutet), Drowned (ertrunken) und Suicide (laut auf vollen Servern: viele Spieler bringen sich zum Respawnen um).
- Long-Range Kill Feed — Spieler-Kills ab 300 m; die Entfernung änderst du im Filter.
- Kill Streak Feed — postet, wenn ein Spieler eine Killserien-Marke erreicht (standardmäßig 3, 5, 10 …), wenn
jemand eine Serie von mindestens 5 beendet, und, wenn du es einschaltest, Todesserien. Die Serien stehen in den
Spielervariablen
feed_kill_streakundfeed_death_streak, zählen ab der Installation der Aktion und enden nur mit einem Tod durch einen anderen Spieler. Der Filter entscheidet, welche Kills zählen. - Rich Kill Feed — jeder Spieler-Kill mit seinen Kill-Merkmalen unter dem Titel, Waffe und Entfernung. Gut für einen zweiten Kanal, z. B. nur Kopfschüsse.
- Admin Kill Feed — jeder Spieler-Kill mit Waffe, Entfernung, Merkmalen, Kartenlink, Zonen, der Position des Killers und beiden Spieler-IDs, für einen Kanal nur für Admins.
- Raid Feed — jede auf einen Schlag zerstörte Basisstruktur (eine Kettensäge durch einen Zaun oder ein Tor), mit Werkzeug und Kartenlink.
Eine Aktion hat genau einen festen Auslöser, deshalb sind Logins und Logouts, Bauen und Platzieren und jede PvE-Todesart eigene Aktionen. Jeder Lauf steht im Tab Logs der Aktion, auch mit dem Grund, wenn der Filter ein Ereignis übersprungen hat.
Zugriffsvoraussetzungen
Aktionen haben jetzt drei Berechtigungsebenen:
- actions.edit: Erlaubt das Bearbeiten serverseitiger Konfigurationswerte sowie das Aktivieren und Deaktivieren installierter oder eigener Aktionen
- actions.manage_marketplace: Erlaubt das Installieren von Marktplatz-Aktionen sowie das Entfernen installierter Marktplatz-Aktionen
- actions.edit_code: Erlaubt das Erstellen und Pflegen eigener Aktionen einschließlich Lua-Code und Konfigurationsschema
Diese Trennung ermöglicht es Serveradministratoren, operative Aktionsverwaltung, Marktplatz-Verwaltung und lokale Code-Erstellung getrennt zu vergeben.
Aktionssprache: Lua
Aktionen werden in Lua geschrieben, einer leichtgewichtigen, hochrangigen, multi-paradigmatischen Programmiersprache, die primär für den eingebetteten Einsatz in Anwendungen entwickelt wurde.
Aktionsskripte laufen direkt. Zwei globale Variablen sind verfügbar:
data: Ereignis-Payload des aktuellen Log-Ereignissesconfig: Aufgelöste Aktionskonfigurationswerte
Um Werte beim Erstellen von Skripten zu prüfen, verwende die print-Funktion.
Hier ist ein Beispiel einer einfachen Aktion, die die Log-Ereignisdaten in die Konsole ausgibt:
print(data);
Kill-Kontext in data.flags
player_kill und player_killed tragen den Kill-Kontext in data.flags: headshot, revenge, trade, team_kill, alliance_violation und spawn_kill sind true oder false; multi_kill ist die Zahl der Kills des Killers innerhalb von 45 Sekunden (2, 3, 4 …) und nil bei einem einzelnen Kill. player_hit_player und player_hit_by_player tragen data.flags.friendly_fire.
player_kill sagt außerdem, wie lange das Opfer am Leben war: data.victim.minutes_alive in 5-Minuten-Schritten und data.victim.seconds_alive, in den ersten 5 Minuten eines Lebens sekundengenau; nil, wenn dzbot nicht weiß, wann das Leben des Opfers begann.
if data.flags.headshot then
player.change_balance(data.killer.username, 50, "Kopfschuss-Bonus");
end
if data.flags.multi_kill and data.flags.multi_kill >= 3 then
discord.send_to_channel(config.channelId, data.killer.username .. " hat " .. data.flags.multi_kill .. " Kills in 45 Sekunden!");
end
Zonen eines Ereignisses
Jedes Ereignis mit Position (Kills, Treffer, Tode, Bauen, Platzieren, Flaggen, der Fünf-Minuten-Ping player_online und mehr) bringt in data.zones die Zonen mit, in denen es passiert ist — eine Liste mit id und name (in der Serversprache) jeder Zone. Ist das Ereignis in keiner Zone passiert, ist die Liste leer. Inaktive Zonen tauchen nicht auf; eine geänderte Zone gilt nach etwa zehn Sekunden für neue Ereignisse.
for _, zone in ipairs(data.zones) do
print("Passiert in " .. zone.name .. " (#" .. zone.id .. ")");
end
Lass die Zonen mit einem Feld vom Typ zone_select auswählen und vergleiche dessen Wert mit tostring(zone.id):
local wanted = {};
for _, id in ipairs(config.zones or {}) do wanted[tostring(id)] = true end
for _, zone in ipairs(data.zones) do
if wanted[tostring(zone.id)] then
player.change_balance(data.killer.username, 100, "Kill in " .. zone.name);
break;
end
end
Der Log Explorer speichert die Zonen mit dem Ereignis, sodass du auch später siehst, wo es passiert ist.
Konfigurationsfelder
Aktionen unterstützen benutzerdefinierte Konfigurationsfelder, mit denen du deine Lua-Skripte parametrisieren kannst, ohne den Code zu bearbeiten. Das ist nützlich für:
- Moderatoren das Anpassen von Aktionsverhalten zu erlauben, ohne Code-Zugriff
- Dieselbe Aktionsvorlage mit verschiedenen Einstellungen wiederzuverwenden
- Sensible Werte (wie Kanal-IDs) vom Code zu trennen
Bei Marktplatz-Aktionen werden diese Felder vom Creator definiert. Server-Admins setzen nur die Werte in der installierten Server-Kopie.
Konfigurationsfelder definieren
Bei eigenen Aktionen werden Konfigurationsfelder im Code-Tab über den Konfigurationsschema-Builder definiert.
Bei Marktplatz-Aktionen werden Konfigurationsfelder im Creator Space vom Autor definiert und erscheinen anschließend auf jeder Server-Installation.
Jedes Feld hat:
- Name: Schlüssel in Lua (
config.<name>) - Typ: siehe Feldtypen unten
- Standard: Fallback-Wert, wenn kein Wert in den Einstellungen gespeichert ist
- Beschreibung: Hilfetext, der im Einstellungs-Tab angezeigt wird
- Pflichtfeld: Die Aktion lässt sich nicht speichern und läuft nicht, solange das Feld sichtbar und leer ist
Empfohlene Benennung: camelCase oder snake_case ohne Leerzeichen.
Sektionen und Bedingungen
Mit einer Sektion fasst du die Felder danach unter einer Überschrift zusammen, bis zur nächsten Sektion. Eine Sektion hat keinen Wert und taucht nie in config auf.
Jedes Feld und jede Sektion kann unter Nur anzeigen, wenn … eine Bedingung bekommen: Wähle ein Feld weiter oben, einen Operator (ist, ist nicht, ist eines von, ist gesetzt, ist größer als, enthält …) und einen Wert, und verknüpfe Regeln mit alle zutreffen / mindestens eine zutrifft, verschachtelten Gruppen und nicht. Eine Bedingung an einer Sektion blendet alle Felder darin aus.
Ein typischer Aufbau: oben ein Block mit Schaltern (bannen, DM schicken, Ticket öffnen), danach pro Schalter eine Sektion, die nur sichtbar ist, solange er an ist, und die Einstellungen dieses Schritts enthält. So sieht der Betreiber nur die Einstellungen dessen, was er wirklich nutzt.
Daraus folgt:
- Eine Bedingung kann nur Felder weiter oben lesen. Der Builder verweigert ein Verschieben, das eine Bedingung brechen würde, und beim Umbenennen eines Feldes werden alle Bedingungen mitgezogen, die es lesen.
- Ein ausgeblendetes Feld gilt nicht: Es kommt im Script als
nilan, auch wenn es einen Standardwert hat, und ist nie Pflicht. Sein gespeicherter Wert bleibt erhalten; schaltest du das steuernde Feld wieder an, ist er wieder da. - Für die Bedingungen der Felder danach zählt ein ausgeblendetes Feld als leer. Blendest du ein Feld aus, verschwindet also auch alles, was davon abhängt.
Konfigurationswerte setzen
Nachdem ein Feld im Code-Tab definiert wurde, können Benutzer mit actions.edit dessen Wert im Einstellungs-Tab setzen.
Zur Laufzeit werden Config-Werte wie folgt aufgelöst:
nil, wenn das Feld durch seine Bedingung oder seine Sektion ausgeblendet ist- Andernfalls der gespeicherte Wert aus dem Einstellungs-Tab (falls vorhanden)
- Andernfalls der Feld-Standard aus dem Schema
- Andernfalls
nil
Nur im Schema definierte Felder werden in config verfügbar gemacht.
Feldtypen
| Typ | Lua-Wert | Hinweise |
|---|---|---|
string | string|nil | Einzeiliger Text; leer → nil |
textarea | string|nil | Mehrzeiliger Text; in Lua identisch zu string |
email | string|nil | Eingabe einer E-Mail-Adresse; in Lua identisch zu string |
number | number|nil | Als Integer oder Float geparst |
boolean | bool|nil | Checkbox; leer → nil |
coordinate | table|nil | Kartenauswahl — .x, .z, optional .y, .radius |
generic_select | string|nil oder string[] | Auswahl aus einer festen Liste; string[] bei multiple: true |
faction_select | string|nil oder string[] | Fraktions-IDs des Servers |
zone_select | string|nil oder string[] | Zonen-IDs des Servers — mit tostring(zone.id) aus data.zones vergleichen |
player_select | string|nil oder string[] | Spielernamen des Servers |
relation_select | string[] | Immer ein Array, nie nil |
discord_channel_select | string|nil oder string[] | IDs von Discord-Textchannels |
discord_category_select | string|nil oder string[] | IDs von Discord-Kategorien |
discord_role_select | string|nil oder string[] | IDs von Discord-Rollen |
discord_guild_select | string|nil oder string[] | IDs von Discord-Guilds |
object_list | table[] | Wiederholbare Liste von Objekten, nie nil — leer ergibt {} |
event_filter | table | Bedingungen aus einem Formular — an filter.matches(config.<name>, data) übergeben. Nur für Aktionen |
discord_embed | table|nil | Ein Discord-Post mit Live-Vorschau — mit discord.send_embed(channel, config.<name>, data) senden. Nur für Aktionen |
Leere Werte werden als nil behandelt, sofern nicht anders angegeben.
Wähle den Typ danach, was das Feld bezeichnet, nicht nach dem Lua-Wert, den es liefert: Ein Discord-Kanal, eine Rolle, eine Kategorie oder eine Gilde → der passende discord_*_select; ein Spieler → player_select; eine Fraktion → faction_select; eine Zone → zone_select; eine feste Auswahl → generic_select. Der Wert einer Auswahl ist bereits die ID (bzw. der Benutzername) als Zeichenkette, die die Action-Funktionen erwarten — ein reines string-Feld wäre dagegen ein fehleranfälliges Freitextfeld. Verwende string nur für echten Freitext.
Ereignis-Filter-Felder
Mit einem Feld vom Typ event_filter entscheidet der Betreiber in einem Formular statt in Lua, auf welche Ereignisse
die Aktion reagiert. In den Einstellungen fügt er Bedingungen einzeln hinzu — angeboten werden nur die, die das
Ereignis der Aktion beantworten kann (ein Login hat keine Entfernung, ein Bau kein Opfer):
- Zonen: Das Ereignis fand in einer der gewählten Zonen statt — oder, mit Außerhalb, in keiner davon
- Entfernung: mindestens und/oder höchstens so viele Meter (Kills; bei Treffern die Entfernung zwischen Angreifer und Opfer)
- Waffe oder Gegenstand: Die Waffe (bzw. beim Bauen, Platzieren und Einpacken der Gegenstand) enthält eines der
Wörter, ohne auf Groß- und Kleinschreibung zu achten —
mosintrifft Mosin 91/30 - Kill-Merkmale: jedes Merkmal Egal, Ja (muss gesetzt sein) oder Nein (darf nicht gesetzt sein) — Kopfschuss, Multi-Kill, Rache, Trade, Teamkill, Allianzbruch, Eigenbeschuss, Spawnkill
- Killer / Opfer (bzw. Angreifer, Absender, Spieler … — wie das Ereignis sie nennt): Mitglied einer der gewählten Fraktionen, einer der gewählten dzbot-Gruppen, und Spielervariablen mit ist, ist nicht, ist größer als, enthält, ist leer und Ähnlichem verglichen
Ein Ereignis zählt nur, wenn es alle Bedingungen erfüllt; ohne Bedingungen zählt jedes. Das Skript prüft es in einer
Zeile mit filter.matches. Spieler-Bedingungen lesen die Datenbank einmal pro Spieler und Lauf,
alles andere kostet nichts.
Discord-Embed-Felder
Ein Feld vom Typ discord_embed ist ein Discord-Post, den der Betreiber in den Einstellungen gestaltet — mit einer
Vorschau, wie Discord ihn zeigen wird, gefüllt mit Beispieldaten des Ereignisses der Aktion: Titel (optional als Link),
Text, Farbe, Felder zum Ausschalten, Nebeneinanderstellen und Sortieren per Ziehen, Fußzeile, Vorschaubild und der
Zeitpunkt des Ereignisses. Ein Klick auf einen Platzhalter fügt ihn an der Cursor-Position ein.
Platzhalter sind die Daten des Ereignisses als Punktpfade — {killer.username}, {weapon}, {distance},
{time.string} — dazu {server.name}, {zone} (erste Zone), {zones} (alle), {flags} (die Kill-Merkmale als
Wörter, in der Sprache des Servers) und bei Ereignissen mit Position {location.place}, {location.label},
{location.url} (iZurvive) und {location.link} (ein fertiger Kartenlink). Namen und andere Texte aus dem Ereignis
werden maskiert, ein Spieler namens **boss** erscheint also wörtlich; Discords Grenzen werden eingehalten (Titel 256
Zeichen, Text 4096, Feldwert 1024, 25 Felder, 6000 insgesamt). Das Skript sendet ihn mit
discord.send_embed. Werte, die das Skript selbst in
data schreibt (etwa eine Seriennummer), lassen sich als zusätzliche Platzhalter anbieten: in den Einstellungen des
Felds als Zeilen name|Beispielwert.