Dokumentation 9.6.24
Events und Trigger
Die Events, die Tosun AntiCheat für Ihre Skripte auslöst, die Events, die Sie zur Integration auslösen können, und die Konfigurationslisten, die Ihre eigenen Events Ausnahmen, Schlüsselprüfungen, Ratenlimits und Fallen zuordnen. Interne Anticheat-Events sind geschützt und dürfen nicht aufgerufen werden.
Überblick#
FiveM kennt lokale Events und Net-Events. Ein lokales Event bleibt auf einer Seite des Spiels: TriggerEvent löst es aus, AddEventHandler empfängt es. Ein Net-Event geht über das Netzwerk: Der Server sendet es mit TriggerClientEvent, ein Client sendet es mit TriggerServerEvent, und die empfangende Seite muss es mit RegisterNetEvent registrieren. Tosun AntiCheat verwendet beide Arten, auf dem Server und auf dem Client.
Diese Seite listet die Events, die das Anticheat für Ihre Listener auslöst, die Events, die Sie zur Integration Ihrer Skripte auslösen dürfen, und die Konfigurationslisten (ts.DetectionExempt, ts.ProtectedEvents, ts.EventLimiter, ts.triggerList), die Ihre eigenen Eventnamen zu Ausnahmen, Schlüsselprüfungen, Ratenlimits oder Fallen machen.
Das Anticheat registriert außerdem viele interne Events für den eigenen Join-Handshake, den Schlüsselaustausch, Shield, das Admin-Menü und Aktionen des Webpanels. Sie sind durch Nonces, Schlüssel, Signaturen, Ratenlimits oder Staff-Prüfungen geschützt, und einige davon sind Fallen. Sie gehören nicht zur Integrationsschnittstelle: Lösen Sie sie nicht aus, registrieren Sie keine Handler darauf und verwenden Sie ihre Namen nicht wieder. Nutzen Sie stattdessen die Exports.
| Art | Auslösen mit | Empfangen mit | Wer es auslösen kann |
|---|---|---|---|
| Lokales Server-Event | TriggerEvent | AddEventHandler | Jede Server-Ressource. |
| Lokales Client-Event | TriggerEvent | AddEventHandler | Jedes Client-Skript im Spiel dieses Spielers, eingeschleuster Cheat-Code eingeschlossen. |
| Net-Event, Client an Server | TriggerServerEvent | RegisterNetEvent + AddEventHandler | Jeder verbundene Spieler, mit beliebigen Argumenten. |
| Net-Event, Server an Client | TriggerClientEvent | RegisterNetEvent + AddEventHandler | Jede Server-Ressource. Ein Client-Skript kann denselben Namen auch lokal mit TriggerEvent auslösen. |
Häufige Integrationsaufgaben#
Wählen Sie das Event oder die Einstellung, die zu Ihrem Vorhaben passt. Jede wird weiter unten auf dieser Seite ausführlich beschrieben.
| Ziel | Verwenden |
|---|---|
| Reagieren, wenn eine Erkennung mit Bann, Kick oder Logzeile endet | ts_anticheat:playerBanned |
| Nur reagieren, wenn tatsächlich ein Bann verhängt wurde | ts_anticheat:banCommitted |
| Auf eine Entbannung reagieren | ts_anticheat:playerUnbanned |
| Den Live-Logfeed spiegeln | ts_anticheat:newLog |
| Den eigenen Cache auffrischen, wenn das Anticheat Einstellungen neu anwendet | tosun-ac:settingsReloaded / ts_anticheat:configUpdated |
| Eine Charakter-Umbenennung aus dem Panel in einem eigenen Framework anwenden | tosun-ac:renameCharacter |
| Client-Prüfungen nach einem eigenen Spawn einschalten | playerSpawned |
| Das Panel nach eigener Charakterauswahl aktualisieren | tosun-ac:panel:characterReady |
| Den Client den Staff-Status neu prüfen lassen | ts_anticheat:adminStateChanged |
| Einen Spieler auf dem Client aus Ihrem Server-Skript ausnehmen | tosun-ac:bridge:clientExempt |
| Spieler automatisch ausnehmen, wenn Ihr Menü- oder Aktions-Event ausgelöst wird | ts.DetectionExempt |
| Einen Schlüssel pro Spieler für Ihr eigenes Client-an-Server-Event verlangen | ts.ProtectedEvents + <name>:safe |
Server-Events, die das Anticheat auslöst#
Dies sind lokale Server-Events. Hören Sie in jedem Server-Skript mit AddEventHandler darauf. Lösen Sie sie nicht selbst aus; siehe die Sicherheitsabschnitte unten.
| Event | Wann es ausgelöst wird | Payload |
|---|---|---|
ts_anticheat:playerBanned | Bei jedem Erkennungsergebnis: BAN, KICK und LOG. Es wird vor dem Kick, dem Eintragen des Banns und den Logs ausgelöst. Für Spieler, die als Staff oder Whitelist übersprungen werden, wird es nicht ausgelöst. | Tabelle data: playerId (string), playerName, reason, banID, side ('server'), punishment ('BAN', 'KICK' oder 'LOG') |
ts_anticheat:banCommitted | Nur bei BAN-Ergebnissen (Erkennungen sowie die Exports ban und punish), direkt nachdem das Eintragen der Bannzeile in die Warteschlange gestellt wurde und vor dem Panel-Webhook und dem Drop. | playerId (number), Tabelle row: banID, playerName, reason, license, steam, discord, ip, HWID, HWID2 bis HWID5, config (Konfigurationsschlüssel der Erkennung) |
ts_anticheat:playerUnbanned | Nachdem der Export unban, der Befehl /ts unban oder das Menü im Spiel einen Bann entfernt hat. Entbannungen im Webpanel lösen es nicht aus. | banID (der an den Export unban übergebene Wert, unverändert) |
ts_anticheat:newLog | Jede Live-Logzeile: Erkennungen, Client-Logzeilen, Aktionen im Admin-Menü und einige interne Anticheat-Zeilen. | Tabelle payload: src (Kategorie-Label, keine Spieler-ID), event (Nachrichtentext), status (Standard 'Info'), playerName, time (os.time()) |
tosun-ac:settingsReloaded | Nachdem ein Einstellungs-Sync die Einstellungen neu angewendet hat. Das passiert beim Start und in fast jedem Sync-Zyklus, nicht nur, wenn sich etwas geändert hat. | keine |
ts_anticheat:shield:screenshot_saved | Ein angeforderter Shield-Screenshot ist angekommen und hat die Prüfungen bestanden. | src (number), b64 (Base64-Bild, 64 bis 2.500.000 Zeichen) |
ts_anticheat:shield:ban_video_saved | Das Gameplay-Video eines gekickten oder gebannten Spielers wurde innerhalb von 120 s hochgeladen. | src (number), videoUrl, reason, config (reason und config kommen vom Client) |
<name>:safe | Ein Aufruf eines in ts.ProtectedEvents gelisteten Events hat die Schlüssel- und Payload-Prüfungen bestanden. | src (number, ID eines Spielers online), danach die ursprünglichen Argumente nach dem Schlüssel |
tosun-ac:renameCharacter | Eine Charakter-Umbenennung im Webpanel bei einem anderen Framework als qb, qbcore, qbox, qbx oder esx. | citizenid (string), firstName (erstes Wort), lastName (Rest des Namens, kann '' sein) |
Client-Events, die das Anticheat auslöst#
Diese Events erreichen Client-Skripte. ts_anticheat:configUpdated ist ein lokales Client-Event; hören Sie mit AddEventHandler darauf. ts_anticheat:receiveEventKey ist ein Net-Event vom Server; registrieren Sie es in Ihrem Client-Skript mit RegisterNetEvent.
| Event | Typ | Wann es ausgelöst wird | Payload |
|---|---|---|---|
ts_anticheat:configUpdated | Lokales Client-Event | Nachdem der Client Einstellungen vom Server angewendet und seine DetectionExempt-Hooks neu gescannt hat. Rechnen Sie mit etwa einem Aufruf pro Sync-Intervall. | keine |
ts_anticheat:receiveEventKey | Net-Event, Server an Client | Als Antwort auf ts_anticheat:requestEventKey (Ihre Anfrage oder die des Anticheat selbst) und immer dann, wenn der Server dem Spieler einen neuen Schlüssel ausstellt. Es kommt nach dem Join-Handshake an. | key (string, der SafeEvents-Schlüssel des Spielers) |
Listener-Beispiel#
Ein Server-Skript, das auf Kicks und Banns reagiert, und ein Client-Skript, das einen Cache verwirft, wenn das Anticheat Einstellungen neu anwendet. Jeder Server-Listener prüft zuerst, dass das Anticheat das Event ausgelöst hat.
-- server.lua (Ihre Ressource)
local AC = 'tosun-ac' -- Name der Anticheat-Ressource (Ordner)
AddEventHandler('ts_anticheat:playerBanned', function(d)
if GetInvokingResource() ~= AC then return end -- gefälschte Aufrufe ignorieren
if d.punishment == 'LOG' then return end
print(('[AC] %s %s: %s'):format(d.punishment, d.playerName, d.reason))
end)
AddEventHandler('ts_anticheat:banCommitted', function(playerId, row)
if GetInvokingResource() ~= AC then return end
print('AC ban', row.banID, row.license, row.reason)
end)
-- client.lua (Ihre Ressource)
local myCache
AddEventHandler('ts_anticheat:configUpdated', function()
myCache = nil
end)playerBanned im Detail#
Der Name ist historisch bedingt. ts_anticheat:playerBanned wird bei jedem Erkennungsergebnis ausgelöst, nicht nur bei Banns. Filtern Sie auf data.punishment.
data.playerId ist ein String. Wandeln Sie ihn mit tonumber um, bevor Sie ihn als Server-ID verwenden.
Das Event wird vor der Aktion ausgelöst. Chat-Broadcast, Logs, DropPlayer und das Eintragen des Banns laufen nach Ihrem Handler.
Es wird nicht ausgelöst, wenn das Ziel offline ist, wenn der Spieler als Staff übersprungen wird (Teammitglieder werden übersprungen, außer ts.AdminBypassDetections ist false oder ts.Debug ist aktiv) oder wenn der Spieler auf der temporären Whitelist oder der Panel-Whitelist steht.
Eine banID wird für jedes Ergebnis erzeugt, aber nur bei BAN gespeichert. Ein KICK gegen ein Teammitglied wird abgebrochen, nachdem das Event bereits ausgelöst wurde.
Solange einem Spieler der Bannbildschirm (editable/server/sv_banscreen.lua) angezeigt wird, werden die meisten weiteren Erkennungen für diesen Spieler verschluckt, und es wird kein Event dafür ausgelöst.
banCommitted im Detail#
ts_anticheat:banCommitted ist der beste Hook für „ein Bann wurde tatsächlich verhängt“. Verwenden Sie playerBanned für Kicks und Logzeilen.
Es wird bei jedem BAN-Ergebnis der Straf-Pipeline des Anticheat ausgelöst: Erkennungen sowie die Exports ban und punish. Offline-Banns (die Exports offlineBan und offlineBanByLicense) und Banns aus dem Webpanel lösen es nicht aus.
Das Eintragen der Bannzeile wird mit MySQL.Async.execute in die Warteschlange gestellt und nicht abgewartet. Die Zeile ist also eventuell noch nicht in der Datenbank, wenn Ihr Handler läuft.
Bei den Kennungen in row ist das Präfix entfernt (license:, license2:, steam:, discord:, ip:). Eine fehlende Kennung oder ein fehlender Token ist der englische Text 'Not found'; eine fehlende ip ist 'Hidden'. HWID bis HWID5 sind rohe Spieler-Tokens.
newLog und settingsReloaded im Detail#
Beide Events werden häufig ausgelöst. Halten Sie ihre Handler schlank.
ts_anticheat:newLog: Das Feld src ist ein Kategorie-Label, keine Spieler-ID. Erkennungen verwenden 'DETECTION' mit status BAN, KICK oder LOG. Client-Logzeilen verwenden einen festen Tag und Status: 'AntiCheat' mit 'Tespit' (fest auf Türkisch für 'Detection'), 'AC-Grace' mit 'Info' und 'AC-FakeTrigger' mit 'Warning'. Einträge des Admin-Menüs verwenden normalerweise den Namen des Admins mit status BAN, KICK, INFO oder SUCCESS. Einige interne Zeilen verwenden andere Kategorien.
tosun-ac:settingsReloaded: Das Anticheat vergleicht alte und neue Werte nicht, daher wird das Event nach dem Start-Sync und in den meisten Sync-Zyklen ausgelöst, alle ts.ServerPerf.configSyncIntervalSec Sekunden (120 in der ausgelieferten Konfiguration, 60, wenn der Schlüssel fehlt, mindestens 20). Lesen Sie es als „Einstellungen wurden neu angewendet“, nicht als „Einstellungen haben sich geändert“.
Nach jedem solchen Sync sendet der Server die Einstellungen auch an alle Clients, und jeder Client löst dann ts_anticheat:configUpdated aus.
Löst eine andere Server-Ressource tosun-ac:settingsReloaded aus, führt das Anticheat für jeden Spieler online eine vollständige Aktualisierung der Staff-Berechtigungen durch.
Shield-Events für Screenshots und Videos#
Beide Events benötigen Shield (ts.shield.enabled nicht false; in der ausgelieferten Konfiguration aktiv).
ts_anticheat:shield:screenshot_saved: Fordern Sie einen Screenshot mit dem Server-Export RequestShieldScreenshot(src) an. Das Bild muss innerhalb von 60 s nach der Anfrage ankommen, und das Anticheat akzeptiert höchstens einen pro 20 s pro Spieler. Auch das Webpanel kann Screenshots anfordern, und diese lösen das Event ebenfalls aus.
ts_anticheat:shield:ban_video_saved: benötigt ts.shield.banGameplayVideo nicht false (in der ausgelieferten Konfiguration aktiv). Das Upload-Fenster ist nach einem KICK oder BAN 120 s lang offen, und der Host der Video-URL muss zum Panel passen.
reason und config in ban_video_saved kommen vom Client und werden weder auf Typ geprüft noch gekürzt. Behandeln Sie sie als nicht vertrauenswürdigen Text.
local AC = 'tosun-ac'
-- Server: Screenshot vom Spiel des Spielers anfordern
exports[AC]:RequestShieldScreenshot(src)
AddEventHandler('ts_anticheat:shield:screenshot_saved', function(src, b64)
if GetInvokingResource() ~= AC then return end
-- b64 ist ein Base64-Bildstring
end)Charakter-Umbenennung in einem eigenen Framework#
Das Webpanel kann einen Charakter umbenennen. Bei qb, qbcore, qbox und qbx aktualisiert das Anticheat players.charinfo; bei esx aktualisiert es users.firstname und users.lastname. Bei jedem anderen Wert von ts.Framework.framework löst es tosun-ac:renameCharacter aus, damit Sie die Umbenennung selbst anwenden können.
Das Anticheat meldet 'event_emitted_unknown_fw' an das Panel, unabhängig davon, ob ein Listener existiert.
Aus dem neuen Namen werden Steuerzeichen entfernt, er wird auf 64 Zeichen begrenzt und muss mindestens 3 Zeichen lang sein. firstName ist das erste Wort; lastName ist der Rest und kann leer sein.
Das Beispiel verwendet den oxmysql-Aufruf MySQL.update und eine erfundene Tabelle characters. Passen Sie die Abfrage an Ihr Schema an.
AddEventHandler('tosun-ac:renameCharacter', function(cid, first, last)
if GetInvokingResource() ~= 'tosun-ac' then return end
MySQL.update('UPDATE characters SET first = ?, last = ? WHERE cid = ?', { first, last, cid })
end)Events, die Sie auslösen können#
Dies sind die Anticheat-Events, die für das Auslösen durch Ihre Skripte gedacht sind. Die Tod- und Revive-Events der Frameworks sowie Ihre ts.DetectionExempt-Events werden in eigenen Abschnitten behandelt.
| Event | Auslösen von | Wirkung | Grenzen |
|---|---|---|---|
tosun-ac:panel:characterReady | Client, mit TriggerServerEvent. | Aktualisiert die Charakterdaten des Spielers in der Online-Spielerliste des Panels. | Ein Aufruf pro 20 s pro Spieler. |
ts_anticheat:locale:setSelf | Client, mit TriggerServerEvent und einem Sprachcode. | Setzt die Sprache der Server-Nachrichten des Anticheat nur für diesen Spieler. Gibt eine Zeile in der Serverkonsole aus. | Kein Ratenlimit. Der Code muss aus 2 oder 3 Kleinbuchstaben bestehen und eine vorhandene Datei locales/<lang>.json haben. |
ts_anticheat:requestEventKey | Client, mit TriggerServerEvent. | Sendet den SafeEvents-Schlüssel des Spielers über ts_anticheat:receiveEventKey zurück. | Ein Aufruf pro 3 s pro Spieler. Der Schlüssel geht nur an den anfragenden Spieler. |
playerSpawned | Client, mit TriggerEvent (lokal). | Schaltet die meisten Client-Prüfungen ein und startet die Spawn-Schonfrist. | Jede andere Ressource auf diesem Client empfängt es ebenfalls. |
ts_anticheat:adminStateChanged | Server, mit TriggerClientEvent an einen Spieler. | Der Client fragt den Server erneut nach seinem tatsächlichen Staff-Status. | Der Server antwortet höchstens einmal pro Sekunde pro Spieler. |
tosun-ac:bridge:clientExempt | Server, mit TriggerClientEvent; benötigt die Bridge-Datei in Ihrer Ressource. | Clientseitige Ausnahme für diesen Spieler. | 500 bis 300000 ms. |
Eigener Spawn: playerSpawned#
Die meisten Client-Prüfungen bleiben aus, bis das Anticheat das lokale Event playerSpawned sieht: Regeneration, Godmode, Teleport, Unsichtbarkeit, Freecam, Waffen, OCR, Natives, Koordinaten und Fahrzeug-Godmode. Normalerweise löst spawnmanager es aus.
Wenn Ihr Spawn- oder Multicharacter-System spawnmanager nicht verwendet, lösen Sie playerSpawned lokal aus, sobald der Spieler in der Welt ist, oder rufen Sie den Client-Export SetSpawned(true) auf.
playerSpawned startet außerdem die Spawn-Schonfrist aus ts.spawnGraceSecondsMs. Der ausgelieferte Wert ist 500, den der Code auf sein Minimum von 5000 ms anhebt; ohne den Schlüssel verwendet der Code 25000. Eine Erkennung innerhalb der Frist wird nicht abgebrochen. Sie fügt nur eine Logzeile 'AC-Grace' hinzu.
playerSpawned setzt außerdem den Todeszustand des Anticheat zurück und markiert einen Client-Teleport.
Die ausgelieferte Liste ts.DetectionExempt.clientEvents enthält playerSpawned, daher startet jedes playerSpawned zusätzlich eine Client-Ausnahme von defaultDurationMs (60 s).
SetSpawned(false) wirkt höchstens einmal alle 5 Minuten, und die Prüfungen schalten sich nach etwa 30 s sichtbarer Bewegung wieder ein.
-- Client, nach Ihrer eigenen Spawn-Logik
TriggerEvent('playerSpawned')
-- oder ohne Nebenwirkungen auf andere Ressourcen
exports['tosun-ac']:SetSpawned(true)Eigenes Multicharacter: characterReady#
Auf dem Server hört das Anticheat auf QBCore:Server:OnPlayerLoaded, QBCore:Server:PlayerLoaded, esx:playerLoaded und qbx_core:server:playerLoaded. Jedes davon überträgt den geladenen Charakter sofort in die Online-Spielerliste des Panels. Ein eigenes Multicharacter-Skript, das keines davon auslöst, sollte nach der Charakterauswahl tosun-ac:panel:characterReady vom Client auslösen.
Jeder Aufruf schreibt die Zeile des Spielers in die Datenbank und sendet, wenn Panel-URL und Schlüssel gesetzt sind, eine HTTPS-Anfrage an das Panel. Der Server akzeptiert daher einen Aufruf pro 20 s pro Spieler und ignoriert den Rest.
-- Client, nach abgeschlossener Charakterauswahl
TriggerServerEvent('tosun-ac:panel:characterReady')Spielersprache: locale:setSelf#
Ein Client kann die Sprache der Server-Nachrichten des Anticheat für sich selbst wählen. Bei Erfolg gibt der Server eine Zeile in der Serverkonsole aus.
Es ändert nur die Server-Nachrichten an diesen Spieler. Die clientseitige Sprache bleibt unverändert.
Der Client des Anticheat sendet dieses Event nicht selbst. Serverseitige Alternativen sind der Export setPlayerLocale und der Befehl ts_setlang.
-- Client
TriggerServerEvent('ts_anticheat:locale:setSelf', 'en')Staff-Änderungen: adminStateChanged#
Nachdem Ihr Admin-Skript Staff-Rechte vergeben oder entzogen hat, weisen Sie den Client des Spielers an, seinen Staff-Status neu zu prüfen. Das Event kann den Status nicht selbst ändern: Der Client sendet eine neue Nonce an den Server, und nur die Antwort des Servers entscheidet.
Im Anticheat sendet nichts dieses Event. Der Client prüft außerdem selbst alle 20 s neu, der Aufruf entfernt also nur diese Verzögerung.
Ein Cheat, der es lokal auslöst, gewinnt nichts; der Server beantwortet die Prüfung höchstens einmal pro Sekunde pro Spieler.
-- Server, nach Änderung der Staff-Rechte für src
TriggerClientEvent('ts_anticheat:adminStateChanged', src)Bridge-Event: tosun-ac:bridge:clientExempt#
Die Client-Bridge-Datei registriert dieses Net-Event in Ihrer eigenen Ressource. Ihr Server-Skript sendet es an einen Spieler, und die Bridge ruft für diesen Spieler den Client-Export SetExempt des Anticheat auf.
durationMs ist eine Zahl in ms oder ein Preset-Name in beliebiger Schreibweise: SHORT, MEDIUM, LONG oder XL (30, 60, 120 oder 180 s). Werte werden auf 500 bis 300000 ms begrenzt. Ohne Wert gilt der Standard der Convar (60000).
Der Ausnahme-Schlüssel ist 'bridge:' gefolgt von tag, oder von Ihrem Ressourcennamen, wenn tag nil ist.
Dies ist nur eine clientseitige Ausnahme. Server-Prüfungen laufen weiter.
Das Anticheat sendet dieses Event nie. Binden mehrere Ihrer Ressourcen die Bridge-Datei ein, läuft ein einzelnes TriggerClientEvent in jeder davon einmal.
- Fügen Sie client_script '@tosun-ac/bridge/tosun_ac_client.lua' zur fxmanifest.lua Ihrer Ressource hinzu.
- Optional, in server.cfg: Wenn Sie den Anticheat-Ordner umbenannt haben, fügen Sie setr tosun_ac_resource mit dem neuen Namen hinzu (Standard tosun-ac). Um die Standarddauer zu ändern, fügen Sie setr tosun_ac_bridge_client_ms mit einem Wert in ms hinzu (Standard 60000).
- Senden Sie aus Ihrem Server-Skript TriggerClientEvent('tosun-ac:bridge:clientExempt', src, durationMs, tag).
-- Server: Spieler 2 Minuten lang ausnehmen, solange ein Friseurmenü offen ist
TriggerClientEvent('tosun-ac:bridge:clientExempt', src, 'LONG', 'barber')Tod- und Revive-Events der Frameworks#
Der Client hört auf diese Events, um zu erkennen, wann ein Spieler tot oder kampfunfähig ist. Solange dieser Zustand aktiv ist, werden die Prüfungen für Regenerationsspitzen, Godmode, Teleport, Unsichtbarkeit, Zuschauen und einige weitere Client-Prüfungen übersprungen. Native Tode werden zusätzlich über das Schadens-Event gameEventTriggered erfasst.
Seit 9.5.9 beendet der Anticheat diesen Zustand von selbst, sobald der Spieler wieder eindeutig aktiv ist.
Ein eigenes Ambulance-Skript kann einen dieser Namen lokal auslösen, um den Zustand des Anticheat abzugleichen. Es sind gemeinsam genutzte Framework-Namen, daher laufen auch alle anderen Ressourcen auf diesem Client, die darauf hören (zum Beispiel ESX-Todesbildschirme).
| Event | Typ | Wirkung |
|---|---|---|
hospital:client:isDead | Net | Kampfunfähig; startet das Nach-Tod-Fenster von 25 s. |
hospital:client:SetDeathState | Net, Boolean-Argument | true: kampfunfähig und Nach-Tod-Fenster von 25 s. false: wiederbelebt und Nach-Revive-Fenster von 10 s. |
hospital:client:SetLaststand | Net, Boolean-Argument | true: kampfunfähig und Nach-Tod-Fenster von 25 s (false wird ignoriert). Zusätzlich eine automatische Ausnahme von 45 s. |
qb-medical:client:OnDeath | Net | Kampfunfähig; startet das Nach-Tod-Fenster von 25 s. |
esx:onPlayerDeath | Net | Kampfunfähig; startet das Nach-Tod-Fenster von 25 s. Zusätzlich eine automatische Ausnahme von 45 s. |
baseevents:onPlayerDied | Lokal (Net, solange autoExempt aktiv ist) | Startet das Nach-Tod-Fenster von 25 s. Zusätzlich eine automatische Ausnahme von 45 s. |
baseevents:onPlayerKilled | Nur lokal | Startet das Nach-Tod-Fenster von 25 s. |
hospital:client:Revive | Net | Wiederbelebt; startet das Nach-Revive-Fenster von 10 s. |
qb-ambulancejob:client:RevivePlayer | Net | Wiederbelebt; startet das Nach-Revive-Fenster von 10 s. |
qb-medical:client:OnRevive | Net | Wiederbelebt; startet das Nach-Revive-Fenster von 10 s. |
esx_ambulancejob:revive | Net | Wiederbelebt; startet das Nach-Revive-Fenster von 10 s. |
esx_basicneeds:onRevive | Net | Wiederbelebt; startet das Nach-Revive-Fenster von 10 s. |
playerSpawned | Lokal | Setzt den Kampfunfähig-Zustand zurück und lässt etwa 17 s des Nach-Tod-Fensters übrig. |
-- eigenes Ambulance-Skript (Client), nach Ihrer eigenen Revive-Logik
TriggerEvent('esx_ambulancejob:revive')Events für automatische Ausnahmen (autoExempt)#
Mit ts.autoExempt.enabled (true in der ausgelieferten Konfiguration) hört der Client auf gängige Framework-Events und gewährt über den Export SetExempt eine kurze Client-Ausnahme. Client-Erkennungen während der Ausnahme werden nicht bestraft; sie werden als LOG-Zeilen mit der Markierung '[exempt]' gemeldet. Setzen Sie ts.autoExempt.enabled = false, um das abzuschalten.
Der Kopfkommentar in client/anticheat_auto_exempt.lua behauptet, diese Events könnten nicht aus der Ferne ausgelöst werden. Das stimmt nicht: Sie sind mit RegisterNetEvent registriert, also kann auch der Server sie auslösen. Die Wirkung bleibt trotzdem eine reine Client-Ausnahme.
| Situation | Dauer | Events |
|---|---|---|
| Aussehen-Menüs | 180 s | illenium-appearance:client:openMenu, appearance:client:openMenu, fivem-appearance:client:openMenu, ox_appearance:openMenu |
| Kleidungsmenüs | 180 s | qb-clothing:client:openMenu, qb-clothes:client:openMenu, rcore_clothing:openClothingShop, clothing:client:openMenu |
| ESX-Skin- und Friseurmenüs | 180 s | esx_skin:openSaveableMenu, esx_skin:openRestrictedMenu, skinchanger:model:loaded, tgg_barber:open, barbershop:client:open |
| Charakterauswahl | 30 s | qb-multicharacter:client:chooseChar, qb-multicharacter:client:closeNUIdefault, esx_multicharacter:SetupCharacters, esx:restoreLoadout, ox:playerLoaded, qbx_core:client:playerLoggedOut |
| Tod und Laststand (QB, ESX) | 45 s | esx_ambulancejob:setDeathStatus, esx:onPlayerDeath, hospital:client:SetLaststand, hospital:client:OnPlayerLaststand, qb-ambulancejob:client:playerDead |
| Tod (andere Skripte) | 45 s | wasabi_ambulance:clientDeath, ars_ambulancejob:client:dead, baseevents:onPlayerDied, baseevents:onPlayerWasted |
| Charakter geladen | 15 s | QBCore:Client:OnPlayerLoaded, qbx_core:client:playerLoaded, esx:playerLoaded, ox:playerLoaded |
| Start des Anticheat auf dem Client | 60 s | onClientResourceStart |
Join-Sperre: Loaded-Events der Frameworks#
Mit ts.NetworkJoin.waitForFrameworkLoaded (true in der ausgelieferten Konfiguration) und dem Framework qb, qbox oder esx wartet der Client auf ein Loaded-Event des Frameworks, bevor er den Beitritt zum Anticheat abschließt. Das verzögert den Start des gesamten Client-Schutzes für diesen Spieler. Andere Framework-Werte überspringen das Warten.
Nach minReadyDelayMs (15 s in der ausgelieferten Konfiguration) und dem Ende des Ladebildschirms wartet der Client auf eines der Loaded-Events oder auf LocalPlayer.state.isLoggedIn (qb, qbox) bzw. ESX.PlayerLoaded (esx), insgesamt bis zu 180 s. Danach wartet er postFrameworkSettleMs (5 s in der ausgelieferten Konfiguration) und auf die Kollision, bevor er sich bereit meldet.
| Framework | Loaded-Events | Reset-Events |
|---|---|---|
qb | QBCore:Client:OnPlayerLoaded | QBCore:Client:OnPlayerUnload |
qbox | QBCore:Client:OnPlayerLoaded, qbx_core:client:playerLoggedIn, qbx_multicharacter:client:chooseChar | QBCore:Client:OnPlayerUnload |
esx | esx:playerLoaded | esx:onPlayerLogout |
Geschützte Events (SafeEvents)#
ts.ProtectedEvents lässt das Anticheat bei Ihren eigenen Client-an-Server-Events einen Schlüssel pro Spieler prüfen. Ein Aufruf, der die Prüfung besteht, wird auf dem Server erneut als lokales Event '<name>:safe' ausgelöst, mit der Spieler-ID als erstem Argument. Die ausgelieferte Liste enthält nur 'test:event'.
TriggerSafeServerEvent existiert nur im Client des Anticheat selbst und wird nicht exportiert. Andere Ressourcen müssen daher das receiveEventKey-Muster oben verwenden. Der Client des Anticheat fordert den Schlüssel alle 5 s an, bis er ankommt (höchstens 12 Versuche).
Der Server beantwortet höchstens eine Schlüsselanfrage pro 3 s pro Spieler, und die Anfragen des Anticheat selbst zählen mit. Kommt kein Schlüssel an, fordern Sie ihn nach einigen Sekunden erneut an. Lassen Sie Ihren Handler registriert und senden Sie immer den zuletzt erhaltenen Schlüssel.
- Fügen Sie Ihren Eventnamen zu ts.ProtectedEvents in configs/anticheat_config.lua hinzu. Die Liste wird einmal beim Start gelesen, starten Sie das Anticheat nach Änderungen also neu.
- Registrieren Sie in Ihrem Client-Skript ts_anticheat:receiveEventKey, um den Schlüssel zu speichern, und senden Sie dann ts_anticheat:requestEventKey.
- Senden Sie Ihr Event mit dem Schlüssel als erstem Argument: TriggerServerEvent(name, key, ...).
- Behandeln Sie in Ihrem Server-Skript '<name>:safe' mit AddEventHandler. Das erste Argument ist die Server-ID des Spielers, gefolgt von Ihren Argumenten.
-- configs/anticheat_config.lua
ts.ProtectedEvents = { ['my-shop:buy'] = true }
-- Client (Ihre Ressource)
local key
RegisterNetEvent('ts_anticheat:receiveEventKey', function(k) key = k end)
TriggerServerEvent('ts_anticheat:requestEventKey')
-- später, sobald key gesetzt ist:
TriggerServerEvent('my-shop:buy', key, 'bread')
-- Server (Ihre Ressource)
AddEventHandler('my-shop:buy:safe', function(src, item)
if GetInvokingResource() ~= 'tosun-ac' then return end
-- hier Geld, Bestand und Berechtigungen prüfen
end)Was SafeEvents prüft und was nicht#
SafeEvents prüft nur den Transport. Es bestraft nie jemanden und ersetzt nicht die Prüfungen in Ihrem eigenen Handler.
- Jeder Client-Aufruf zählt zuerst gegen ts.SafeEventRateLimit pro ts.SafeEventRateWindow Sekunden (standardmäßig 30 Aufrufe pro 10 s), auch ohne Schlüssel.
- Hat der Spieler noch keinen Schlüssel, wird der Aufruf stumm verworfen.
- Ein falscher Schlüssel, das Ratenlimit, mehr als ts.SafeEventMaxArgs Argumente (standardmäßig 64) oder eine fehlerhafte Payload verwerfen den Aufruf und schreiben eine Datenbank-Logzeile pro Spieler, Event und Fenster.
- Aufrufe vom Server (source 0) werden ignoriert und lösen kein ':safe'-Event aus.
- Das rohe Net-Event erreicht weiterhin jeden Handler, den Ihre eigene Ressource mit RegisterNetEvent registriert hat. Nur die ':safe'-Spiegelung ist abgesichert.
- Registrieren Sie den ':safe'-Namen nie mit RegisterNetEvent; sonst könnten Clients ihn direkt aufrufen.
- SafeEvents ist eine zusätzliche Schutzschicht. Ihr eigener Handler muss weiterhin Berechtigungen, Kontostände und Besitz prüfen.
- Fügen Sie keine Framework-Events (esx, qb) zur Liste hinzu. Deren Aufrufer senden keinen Schlüssel, daher lehnt SafeEvents diese Aufrufe ab, schreibt Logzeilen und löst nie ':safe' aus. Die eigenen Handler des Frameworks laufen trotzdem.
- Der türkische Kommentar in configs/anticheat_config.lua behauptet, Aufrufe ohne Schlüssel führten zu einem Fehlbann. In dieser Version werden sie nur verworfen.
ts.DetectionExempt: Ihre Events Ausnahmen zuordnen#
ts.DetectionExempt macht Ihre eigenen Eventnamen zu befristeten Erkennungsausnahmen. Verwenden Sie es für Menüs und Server-Aktionen, die Aussehen, Position oder Zustand eines Spielers legitim ändern: Kleidung, Friseure, Housing, Garagen, Charakterauswahl und Revives. Die Listen werden aus configs/anticheat_config.lua gelesen; Panel-Einstellungen ändern sie nicht. ts.MenuDetectionExempt ist ein für alte Konfigurationen beibehaltener Alias.
| Schlüssel | Typ | Ausgelieferter Wert | Wirkung |
|---|---|---|---|
enabled | Boolean | true | false schaltet alle DetectionExempt-Hooks ab. |
defaultDurationMs | Zahl (ms) | 60000 | Ausnahmedauer für Einträge ohne eigenes durationMs. Server-Einträge werden auf 1000 bis 120000 ms begrenzt, Client-Einträge auf 1000 bis 300000 ms. |
budgetMsPer10Min | Zahl (ms) | 240000 | Maximale weiche Ausnahmezeit, die ein Spieler in 10 Minuten aus serverEvents sammeln kann. |
clientEvents | Liste von Strings | 153 Einträge (142 eindeutige Namen) | Client-Net-Events. Wird eines ausgelöst, sind die Client-Prüfungen des Spielers ausgenommen. |
localEvents | Liste von Strings | 11 Einträge | Lokale Client-Events (nur TriggerEvent auf dem Client). Gleiche Wirkung wie clientEvents. |
serverEvents | Liste von Strings oder Tabellen | 34 Einträge | Client-an-Server-Net-Events. Löst ein Spieler eines aus, erhält dieser Spieler eine weiche Ausnahme. |
DetectionExempt.serverEvents#
Das Anticheat registriert jeden gelisteten Namen mit RegisterNetEvent. Löst ein Spieler ihn aus, erhält dieser Spieler eine weiche Ausnahme: Die serverseitigen Bewegungsprüfungen sowie die serverseitigen Prüfungen auf Godmode, Unsichtbarkeit, Noclip und Kamera werden gelockert, und die Client-Prüfungen des Spielers werden über ein State Bag ausgenommen. Es ist nie eine Immunität gegen Strafen.
Ein Eintrag ist ein String oder eine Tabelle: { event = 'name', durationMs = 60000, resource = 'owner-resource', always = true }. durationMs wird auf 1000 bis 120000 ms begrenzt.
Der Hook wird nur installiert, solange die Besitzer-Ressource gestartet ist oder startet. Der Besitzer ist das Event-Präfix vor dem ersten Doppelpunkt; qb-clothes wird qb-clothing zugeordnet und hospital wird qb-ambulancejob zugeordnet. Setzen Sie resource, wenn das Präfix vom Ressourcennamen abweicht. always = true installiert den Hook auch, wenn der Besitzer nicht läuft.
Hooks werden 2,5 s nach dem Start des Anticheat installiert und erneut 1 s nach dem Start jeder anderen Ressource.
Spieler können diese Events selbst auslösen, deshalb hat jeder Spieler ein Budget (budgetMsPer10Min). Ist es aufgebraucht, schreibt das Anticheat eine Konsolenwarnung und eine Datenbank-Logzeile und ignoriert weitere Anfragen dieses Spielers für den Rest der 10 Minuten.
Führen Sie tosunac_integration in der Serverkonsole aus, um zu sehen, wie viele Server-Ausnahme-Events eingehängt sind. Das funktioniert nur in der Serverkonsole, und die Ausgabe erscheint dort.
DetectionExempt.clientEvents und localEvents#
Namen aus clientEvents werden auf dem Client mit RegisterNetEvent registriert. Wird eines ausgelöst, vom Server oder über ein lokales TriggerEvent, ist der Client für defaultDurationMs ausgenommen.
clientEvents akzeptiert nur Strings. Tabelleneinträge, auch solche mit durationMs, werden auf dem Client stumm ignoriert.
Während der Ausnahme werden Client-Erkennungen nicht bestraft. Sie werden als LOG-Zeilen mit der Markierung '[exempt]' gemeldet, höchstens einmal pro Minute und Prüfung, damit Missbrauch im Panel sichtbar bleibt. Server-Prüfungen sind nicht betroffen.
localEvents funktioniert genauso, verwendet aber nur AddEventHandler und reagiert daher nur auf TriggerEvent auf dem Client.
Der Client scannt beide Listen 3,5 s nach dem Laden und erneut bei jedem Einstellungs-Sync.
Ein Event eines Skripts, das Sie nicht einsetzen, wird nie ausgelöst, zusätzliche Namen in der Liste schaden also nicht. Die ausgelieferte Liste clientEvents wiederholt 11 Namen; Duplikate sind harmlos.
DetectionExempt-Beispiel#
Fügen Sie Ihre Namen zu den vorhandenen Listen in configs/anticheat_config.lua hinzu und starten Sie danach das Anticheat neu. Wenn Sie die ganze Tabelle ersetzen, entfernen Sie die ausgelieferten Einträge. Das Beispiel zeigt nur neue Einträge.
Bevorzugen Sie die Exports, wenn Sie den Code kontrollieren: den Client-Export SetExempt(true, ms, reason), den Server-Export SetExempt(src, ms, reason) aus einer vertrauenswürdigen Ressource und den Server-Export MarkTeleport(src, ms) direkt vor dem Teleport eines Spielers.
ts.DetectionExempt = {
enabled = true,
defaultDurationMs = 60000,
budgetMsPer10Min = 240000,
-- Client-Net-Events: nur Strings
clientEvents = {
-- ...ausgelieferte Einträge...
'my-clothing:client:openMenu',
},
-- lokale Client-Events (TriggerEvent auf dem Client)
localEvents = {
-- ...ausgelieferte Einträge...
'my-menu:opened',
},
-- Client-an-Server-Events: weiche Ausnahme für den Absender
serverEvents = {
-- ...ausgelieferte Einträge...
'my-clothing:server:saveOutfit',
{ event = 'my-housing:server:enter', durationMs = 60000 },
{ event = 'myhouse:server:enter', resource = 'my-housing' },
{ event = 'my-garage:server:takeOut', durationMs = 45000, always = true },
},
}ts.EventLimiter: Ratenlimits für Net-Events#
ts.EventLimiter ordnet Eventnamen eine maximale Anzahl Aufrufe pro Spieler in 5 s zu. Das Anticheat registriert beim Laden jeden Namen mit RegisterServerEvent und zählt die Aufrufe pro Spieler; alle Zähler werden alle 5 s zurückgesetzt. Ihr eigener Handler für das Event läuft weiterhin.
Erreicht ein Zähler sein Limit, versucht das Anticheat eine Erkennung mit der Konfiguration ts.EventLimiter (server_event_spam, standardmäßig KICK).
Die ausgelieferte Liste hat 25 Einträge: test:event, esx:getSharedObject, Bank- und QBCore-Geld-Events, Revive, Fahrzeug-Spawn, Inventar, Gefängnis- und Handschellen-Events sowie HCheat:TempDisableDetection.
Namen und Limits werden beim Laden gelesen. Die Datenbanktabelle ac_event_limits ersetzt ts.EventLimiter beim Sync, ändert aber nicht die registrierten Handler. Starten Sie das Anticheat daher nach Änderungen an einem von beiden neu.
ts.EventLimiter = {
-- ...ausgelieferte Einträge...
['my-shop:buy'] = 10,
}Fallen-Events: diese Namen nie verwenden#
Einige Events existieren nur, um Cheats zu fangen. Mit diesen Regeln lösen Ihre eigenen Skripte nie eines davon aus.
- Das Anticheat registriert Fallen-Events, die nur Cheats auslösen. Lösen Sie sie nie aus und verwenden Sie ihre Namen nie erneut.
- Um die Fallen-Namen auf Ihrem eigenen Server zu sehen, führen Sie /ts evtlist aus (die Liste erscheint in der Serverkonsole). Damit ein Event nicht mehr als Falle gilt, verwenden Sie /ts evtwhitelist <eventName>. Siehe das Thema Befehle.
- Geben Sie Ihren eigenen Events Ihren Ressourcennamen als Präfix, zum Beispiel myresource:doThing, damit sie nie mit einer Falle kollidieren.
Ratenschutz für Sound-Events#
Das Anticheat registriert diese Sound-Events als Net-Events in seiner eigenen Ressource und zählt sie pro Spieler. Oberhalb von ts.premiumGuard.soundPerSec (standardmäßig 6 pro Sekunde) wendet es soundAction an (standardmäßig 'log'). Es bricht das Event nur ab, wenn soundCancel = true ist (standardmäßig false). Die Handler Ihrer Sound-Ressource laufen weiterhin, wenn diese Ressource das Event selbst registriert hat.
Der Schutz läuft nur, solange ts.premiumGuard.enabled und ts.premiumGuard.soundGuard true sind (beide true in der ausgelieferten Konfiguration). Lassen Sie soundCancel auf false, bis Sie geprüft haben, dass Ihre Sound-Skripte unter dem Limit bleiben.
| Event | Ressource |
|---|---|
InteractSound_SV:PlayOnAll | InteractSound |
InteractSound_SV:PlayWithinDistance | InteractSound |
InteractSound_SV:PlayOnOne | InteractSound |
xsound:stateSound | xsound |
xsound:server:play | xsound |
xsound:server:playUrl | xsound |
xsound:server:playUrlPos | xsound |
Events, die das Anticheat an andere Ressourcen sendet#
Nach Aktionen von Staff, Panel oder Erkennungen löst das Anticheat Events aus, die zu anderen Ressourcen gehören. Wenn Sie eine dieser Ressourcen einsetzen, rechnen Sie mit diesen Aufrufen.
Wetter und Uhrzeit verwenden nur die erste gestartete Sync-Ressource, in dieser Reihenfolge: qb-weather, Renewed-Weathersync (nur Export), cd_easytime, wd_weather, weathersync, vSync, qb-weathersync. Ist keine gestartet, setzt das Anticheat Wetter und Uhrzeit direkt auf jedem Client.
hospital:client:Revive und esx_ambulancejob:revive sind auch Listener des Anticheat (siehe Tod- und Revive-Events der Frameworks), daher öffnen diese Revives ebenfalls das Nach-Revive-Fenster von 10 s.
| Event | Seite | Gesendet, wenn |
|---|---|---|
qb-weather:server:RequestStateChange | Server lokal | Wetter- oder Zeitänderung, wenn qb-weather keinen Export setWeather oder setTime hat. Für die Uhrzeit ist der Wert eine Tabelle { hour, minute }. |
cd_easytime:setWeather, cd_easytime:setTime | Server lokal | Wetter- oder Zeitänderung mit cd_easytime. |
<res>:setWeather, <res>:setTime | Server lokal | Wetter- oder Zeitänderung mit wd_weather, weathersync, vSync oder qb-weathersync, wenn diese Ressource keinen passenden Export hat. |
wasabi_ambulance:revive | Client lokal | Revive durch Staff oder Panel, wenn wasabi_ambulance gestartet ist. |
hospital:client:Revive | Client lokal | Revive durch Staff oder Panel mit qb-ambulancejob oder Starter-Hospital. |
esx_ambulancejob:revive | Client lokal | Revive durch Staff oder Panel mit esx_ambulancejob. |
<res>:revive, <res>:client:Revive, <res>:client:revive | Client lokal | Revive durch Staff oder Panel in allen anderen Fällen: Die erste gestartete Ressource aus ambulance, qb-ambulancejob, cd_ambulance und ars_ambulancejob erhält alle drei Namen. Ist der Spieler danach noch tot, folgt eine native Wiederbelebung. |
QBCore:Notify | Client lokal; Server an Client | Jede Heilung durch das Anticheat, auch ohne qb-core (seine qb-core-Prüfung ist immer true). Außerdem Panel-Aktionen für Geld, Inventar und Benachrichtigungen. |
esx:showNotification, QBCore:Player:SetPlayerData, inventory:client:ItemBox | Server an Client | Panel-Aktionen für Geld, Inventar und Benachrichtigungen sowie Waffen-als-Item-Vergaben. |
chat:addMessage | Server an Client; Client lokal | Chatnachrichten und Panel-Broadcasts. Mit ts.chatMessages = true (Standard false) geht jedes Erkennungsergebnis, LOG eingeschlossen, fest auf Türkisch an alle Spieler (editable/server/sv_editme.lua). |
chat:addSuggestion | Client lokal | Fügt den Befehlsvorschlag /unspectate hinzu, wenn die Datei des Admin-Menüs geladen wird. |
qb-phone:client:CustomNotification, qs-smartphone:client:sendNotification, lb-phone:notification, yseries:notification, gks-phone:client:notification, roadphone:notify | Server an Client | Staff-Warnungen bei Kicks und Banns sowie die Exports phoneNotify und phoneNotifyAdmins. Nur das erste gestartete Telefon erhält sie (npwd verwendet einen Export; chat, wenn keines vorhanden ist). Benötigt ts.AdminMenu.enable = true. |
Sicherheit: wer welches Event auslösen darf#
Nur das Anticheat darf die Events auslösen, die es selbst auslöst. Andere Ressourcen dürfen sie nicht auslösen. Die Tabelle zeigt, wer welches Event auslösen darf.
| Event | Wer es auslösen darf |
|---|---|
ts_anticheat:playerBanned | Nur das Anticheat. |
ts_anticheat:banCommitted | Nur das Anticheat. |
ts_anticheat:newLog | Nur das Anticheat. |
ts_anticheat:shield:ban_video_saved | Nur das Anticheat. |
tosun-ac:settingsReloaded | Nur das Anticheat. |
ts_anticheat:configUpdated | Nur das Anticheat. |
ts_anticheat:adminStateChanged | Jede Server-Ressource. |
tosun-ac:panel:characterReady | Jeder Client. Auf einen Aufruf pro 20 s pro Spieler begrenzt. |
ts_anticheat:locale:setSelf | Jeder Client. Betrifft nur den Aufrufer. |
ts_anticheat:requestEventKey | Jeder Client. Der Schlüssel geht nur an den anfragenden Spieler. |
tosun-ac:bridge:clientExempt | Ihre Server-Skripte. |
Sicherheit: GetInvokingResource prüfen#
Jede Server-Ressource kann ein lokales Server-Event auslösen. Prüfen Sie in Ihren Listenern, dass das Anticheat es ausgelöst hat, bevor Sie handeln. Der eigene Listener des Anticheat für den Bannbildschirm verwendet eine ähnliche Prüfung.
Wenden Sie die Prüfung auf playerBanned, banCommitted, playerUnbanned, newLog, settingsReloaded, die Shield-Events, renameCharacter und Ihre '<name>:safe'-Handler an.
Lösen Sie die Events des Anticheat nie aus Ihren eigenen Ressourcen aus, auch nicht zum Testen. Mehrere eingebaute Listener prüfen den Aufrufer nicht.
AddEventHandler('ts_anticheat:banCommitted', function(playerId, row)
if GetInvokingResource() ~= 'tosun-ac' then return end -- Ihr Ordnername, falls umbenannt
-- hier können Sie sicher mit row arbeiten
end)Sicherheit: serverautoritatives Design#
Alles, was ein Client auslösen kann, wird als Hinweis behandelt, nicht als Autorität. Halten Sie sich in Ihren eigenen Handlern an dieselbe Regel.
- Client-Ausnahmen (clientEvents, localEvents, autoExempt, das Bridge-Event und der Client-Export SetExempt) ändern nie die serverseitige Durchsetzung. Solange sie aktiv sind, werden Client-Erkennungen als '[exempt]' protokolliert statt bestraft.
- Ausnahmen aus serverEvents sind weich: Auf dem Server lockern sie nur Bewegungs- und Sichtbarkeitsprüfungen (Strafen für Waffen, Geld, Schaden, Event-Missbrauch, Injection und Crashes gelten weiterhin), und jeder Spieler ist durch budgetMsPer10Min begrenzt.
- Der Staff-Status wird durch die Nonce-geschützte Antwort des Servers bestimmt. Ein an einen Client gesendetes Staff-Flag kann keine Admin-Rechte verleihen.
- Der SafeEvents-Schlüssel prüft nur den Transport. Ihr ':safe'-Handler muss Berechtigungen, Kontostände und Besitz auf dem Server prüfen.
- Ein Cheat kann Tod-Events der Frameworks lokal auslösen. Das Kampfunfähig-Flag wird nach etwa 20 s eindeutig aktiven Spiels zurückgesetzt.
- Um einen Spieler serverseitig auszunehmen, verwenden Sie die Exports: SetExempt(src, ms, reason) aus einer vertrauenswürdigen Ressource oder MarkTeleport(src, ms) vor einem Teleport.
Interne Events#
Neben den Events auf dieser Seite registriert das Anticheat interne Events für seinen Join-Handshake, den Schlüsselaustausch, Shield, das Admin-Menü, Aktionen des Webpanels und eine Begleitressource. Sie sind durch Nonces, Schlüssel, Signaturen, Ratenlimits oder Staff-Prüfungen geschützt, und mehrere davon sind Fallen, die den Aufrufer bestrafen. Sie werden hier bewusst nicht dokumentiert.
- Lösen Sie keine internen Events aus, weder vom Server noch von einem Client.
- Registrieren Sie keine Handler darauf und verwenden Sie ihre Namen nicht wieder.
- Lösen Sie kein Event aus, dessen Name mit ts_anticheat: oder tosun-ac: beginnt, es sei denn, diese Seite führt es als auslösbar auf.
- Verwenden Sie für Aktionen die Exports: zum Beispiel punish, MarkTeleport, freezePlayer, setPlayerHealth, RequestShieldScreenshot und quarantine.
Bekannte Probleme in 9.6.15#
Diese Verhaltensweisen stecken im ausgelieferten Code. Planen Sie sie ein.
- tosun-ac:settingsReloaded und ts_anticheat:configUpdated werden in fast jedem Sync-Zyklus ausgelöst, nicht nur bei geänderten Einstellungen.
- ts_anticheat:playerBanned wird bei KICK und LOG ebenso ausgelöst wie bei BAN.
- Die Telefon-Warnung an Staff für Live-Logs wartet auf den status 'TESPİT' oder 'Detection' in ts_anticheat:newLog, aber nichts sendet einen dieser Werte, daher wird diese Warnung nie ausgelöst.
- Jede Heilung durch das Anticheat löst auf dem Client QBCore:Notify aus, auch auf Servern ohne qb-core.
- ts.quarantine.autoQuarantine hat keine Wirkung: Seine einzige Eingabe ist ein internes Event, das nichts auslöst. Verwenden Sie stattdessen den Export quarantine.
- Mehrere Kommentare in configs/anticheat_config.lua sind auf Türkisch, und einige sind veraltet: Aufrufe ohne Schlüssel bei ts.ProtectedEvents werden verworfen, nicht gebannt, und ts.EventLimiter kickt nicht.
Unnötige Analyse nach Neustarts vermeiden#
Bei jedem Start werden SHA256-Inhaltsprüfsummen der Ressourcen geprüft. Unveränderte Dateien und Scanregeln verwenden authentifizierte Ergebnisse im Server-KVP statt aufwendiger Signatur- und Ereignisanalyse. Geänderte Dateien, Ausnahmen oder Regeln lösen neue Analysen aus. Die Prüfsummenprüfung liest weiterhin Dateien; ein fester resmon-Wert wird nicht garantiert.
- Den KVP-Cache bei normalen Updates behalten; beschädigte oder nicht verifizierbare Einträge werden erneut analysiert.
- Der Startkatalog erfasst wörtlich deklarierte Lua/JS-Ereignisnamen. Dynamische Namen, unlesbare oder Escrow-Dateien und DLLs gelten nicht als vollständig geprüft.
- Die manuelle automatische Einrichtung wartet auf die Sicherheitsanalyse. Unvollständige, verdächtige, geänderte oder abgelaufene Ressourcen werden nicht automatisch freigegeben.
- Spielerbeitritt, normales Spiel und Administratoraktionen auf einem Testserver prüfen; resmon zusammen mit Spielerzahl und Framework-Last bewerten.