К руководству

Документация 9.6.24

Серверная интеграция

Вызывайте exports только из доверенного серверного кода. Клиент не выбирает исключения, права или награды.

Пример чтения#

Пример проверяет статус администратора, но не выдаёт права. Сверьте export и формат ID с установленным пакетом.

local playerId = 12
local isAdmin = exports['tosun-ac']:isAdmin(playerId)

Проверка перед исключением#

Проверьте серверную сессию, игрока, позицию, права и срок. Не открывайте исключения через RegisterNetEvent без проверки. Следуйте руководству безопасности Cfx.

Официальное руководство Cfx

Уведомление о телепорте#

Каждый серверный скрипт, который перемещает игрока (дом, гараж, тюрьма, больница, работа), должен вызывать MarkTeleport непосредственно перед телепортом. Список доверенных не нужен, и ненадолго ослабляются только проверки движения и видимости; защита оружия, денег и от инъекций остаётся включённой. Когда все телепортирующие скрипты будут отправлять уведомление, наказание за телепорт v16 в настройках античита можно повысить до кика.

exports['tosun-ac']:MarkTeleport(source, 8000)
SetEntityCoords(GetPlayerPed(source), x, y, z)

Доверенные ресурсы#

Экспорты, которые исключают игроков, выдают права или выполняют массовые действия (SetExempt, addAdmin, whitelistPlayer и другие), принимают вызовы только от доверенных ресурсов. Отклонённый вызов один раз выводится в консоль вместе со строкой, которую нужно добавить. Храните список в server.cfg, чтобы обновления античита его не перезаписывали. Консольная команда tosunac_integration показывает доверенный список и последние отклонённые вызовы.

set tosun_ac_trusted_resources "my-housing,my-clothing"

Оружие, выданное вне инвентаря#

Скрипты, выдающие оружие без добавления в инвентарь, например арены, пейнтбол или меню, должны вызывать AllowWeapon при выдаче оружия. Иначе проверка оружия и инвентаря из 9.4.0 запишет его как заспавненное. Передайте название оружия или звёздочку для всего оружия; максимальная длительность — 1 час. Addon-оружие, которое античит не знает, добавьте в extraWeapons в конфигурации.

exports['tosun-ac']:AllowWeapon(source, "WEAPON_PISTOL", 600000)

Авторитет только на сервере#

Используйте TOSUN-AC-EXPORTS.md пакета. Регистр имён важен. Освобождения используют миллисекунды; AddWhitelist и WhitelistArea — секунды. Запускайте tosun-ac до зависимых скриптов; не пропускайте защиту молча при остановке. Успех вызова не проверяет правила вашей работы.

SetExempt и AllowWeapon требуют доверенный серверный ресурс. Добавляйте проверенные скрипты, сохраняя список. tosunac_integration показывает отказы. Отключение enforcement пропускает вызовы в audit с предупреждениями; не оставляйте постоянно.

set tosun_ac_trusted_resources "my-clothing,my-arena"

# Серверная консоль:
tosunac_integration

Сообщать перед телепортом#

Проверьте игрока, серверную точку, право и действие. MarkTeleport вызывается непосредственно перед перемещением. src и destination берутся из проверенного серверного процесса, не свободных клиентских параметров. Это фрагмент, не готовое сетевое событие.

Trust не требуется. Кратко ослабляет движение и связанные видимость/godmode/камеру; оружие, деньги, злоупотребление событиями и injection остаются. По умолчанию для ресурсов вне списка доверия: 15 секунд за вызов, 180 на игрока за десять минут. Продления расходуют бюджет; не вызывайте каждый tick.

-- Внутри уже проверенного серверного процесса:
local ok = exports["tosun-ac"]:MarkTeleport(src, 8000, "house_enter")
if ok then
    SetEntityCoords(GetPlayerPed(src), destination.x, destination.y, destination.z)
end

Разрешать конкретное оружие#

Для арены без предмета инвентаря проверьте серверный матч и вызовите AllowWeapon из доверенного ресурса. Выберите одно оружие и нужную длительность. Меняется только проверка владения и её damage-путь, не вся AC.

Максимум час; избегайте звёздочки без необходимости всех оружий. SetExempt — полное доверенное исключение до пяти минут. BypassDetection игнорирует detectionKey: полное до минуты, не отдельная проверка.

Не используйте source отключившегося игрока для поздней награды или исключения. Проверяйте текущую сессию во время действия. Доверенный ресурс всё равно обязан проверять права и цель.

  • Разрешённое действие работает, срок заканчивается.
  • Клиент не выбирает другого игрока, время, оружие или точку.
  • Недоверенный вызов возвращает false и предупреждение.
  • После перезапуска проверяются состояние и обычная игра.
-- my-arena: доверенный ресурс, проверенная сессия
local allowed = exports["tosun-ac"]:AllowWeapon(src, "WEAPON_PISTOL", 60000)
-- Выдайте оружие только в проверенном сценарии арены.

Завершайте исключения правильным серверным API#

Серверный SetExempt принимает src, миллисекунды и причину; клиентский — state, миллисекунды и причину. Сигнатуры невзаимозаменяемы. Клиентское исключение не даёт серверных полномочий. В доверенном серверном сценарии SetPlayerExempt со state false снимает временное исключение игрока. Сначала согласуйте пересекающиеся активности: это общее состояние игрока, не отдельный токен каждого ресурса. Снятие может завершить исключение другой активности. При этом сотрудник или whitelist панели могут сохранять IsExemptFromPunish истинным. Предпочитайте более узкие MarkTeleport или AllowWeapon, когда их достаточно.

  1. Завершайте или отменяйте разрешённую активность с проверенным текущим игроком и снимайте ненужное исключение.
  2. Проверяйте отмену, отключение и нормальное завершение; не продлевайте полное исключение постоянным фоновым циклом.
  3. Обычным игроком проверьте, откуда остаётся защита: сотрудник, whitelist панели или другая активность.
-- Trusted server resource; src belongs to an authorised workflow.
-- Clear the temporary exemption when that workflow finishes or is cancelled.
local cleared = exports["tosun-ac"]:SetPlayerExempt(src, false, 0, "menu_finished")

Используйте помощники с явной обработкой результата#

Вспомогательные файлы моста добавляются в манифест вашего ресурса и не заменяют проверки прав. TosunAC.IsAvailable проверяет запуск AC; TosunAC.IsTrusted — доверие вызывающего ресурса. PlayerExempt возвращает ok и mode: full означает доверенное полное исключение, soft — ограниченное послабление движения и видимости. Истинный результат не равен полной неуязвимости. Если активности необходим full, определите остановку или отказ при soft, вместо продолжения с другим объёмом защиты. PlayerExemptOff снимает временное полное исключение серверным API.

  1. Загружайте серверный помощник до скрипта с TosunAC, сохраняя остальные зависимости манифеста.
  2. При старте активности проверяйте ok и mode; записывайте ресурс, причину и несекретный результат.
  3. Явно обработайте остановленный AC или отказ вызова; до повтора проверьте порядок запуска и доверие.
-- Add these lines to your own resource manifest:
client_script "@tosun-ac/bridge/tosun_ac_client.lua"
server_script "@tosun-ac/bridge/tosun_ac_server.lua"

Считайте читающие exports диагностикой, не приговором#

GetStatus возвращает небольшую сводку с настроенным framework и числом игроков, не полный аудит интеграций. GetIntegrationStatus описывает доверие вызывающего ресурса, не всех скриптов. IsMovementExempt и IsExemptFromPunish отвечают на разные вопросы. GetDetections носит историческое имя: читает баны игрока из ts_anticheat, а не все последние обнаружения. Пустой ответ не подтверждает отсутствие нарушений. Выполняйте запросы базы и широкие списки игроков по необходимости, не каждый tick. Используйте объекты по документированному назначению без ключей и лишних персональных данных в публичных отладочных выводах.

  1. При диагностике фиксируйте вызывающий ресурс и точную проверку состояния или исключения.
  2. Сопоставьте ожидаемый объём известного сценария с результатом прежде, чем менять наказания.
  3. После обновления перечитайте установленный TOSUN-AC-EXPORTS.md, особенно старые имена и порядок серверных/клиентских параметров.

Свяжите отложенное перемещение с жизнью игрока и ресурса#

Если вход в дом требует небольшой задержки, одного сохранения source игрока недостаточно. После отключения этот номер может получить другой игрок. Фрагмент server.lua — локальная функция для уже авторизованного серверного сценария, а не сетевое событие, доступное клиенту. Место назначения должен проверить сервер. Уникальный объект Lua в pending связывает отложенное перемещение с этим сценарием. При выходе запись удаляется; таймер ничего не делает, если не находит тот же объект. Новый игрок со старым source не получает прежнее перемещение.

Пример удаляет ожидающие записи при остановке tosun-ac или собственного ресурса. После задержки повторно проверяются состояние ресурса, присутствие игрока и ped. pcall перехватывает ошибку export; движение выполняется только при true от MarkTeleport. Эти проверки не дают права собственности на дом, рабочей роли или разрешения на точку назначения: подтвердите их до вызова. Код только сообщает о движении; он не снимает полные исключения и не меняет разрешения других скриптов. Отдельно проверьте отключение во время ожидания, остановку AC и обычный вход. Постоянный цикл или таймер обхода всех игроков не нужен: одна задержка относится к запущенному сценарию.

-- server.lua: call only from an already authorised server workflow.
-- destination is a server-validated location, never raw client input.
local pending = {}

local function scheduleValidatedMove(src, destination)
    src = tonumber(src)
    if not src or not GetPlayerName(src) then return false end
    if GetResourceState("tosun-ac") ~= "started" then return false end
    local ticket = {}
    local target = {x = destination.x, y = destination.y, z = destination.z}
    pending[src] = ticket
    SetTimeout(1500, function()
        if pending[src] ~= ticket then return end
        pending[src] = nil
        if not GetPlayerName(src) then return end
        if GetResourceState("tosun-ac") ~= "started" then return end
        local ped = GetPlayerPed(src)
        if not ped or ped == 0 then return end
        local called, allowed = pcall(function()
            return exports["tosun-ac"]:MarkTeleport(src, 8000, "house_delayed_entry")
        end)
        if called and allowed == true then
            SetEntityCoords(ped, target.x, target.y, target.z)
        end
    end)
    return true -- Scheduled, not yet moved.
end

AddEventHandler("playerDropped", function() pending[source] = nil end)
AddEventHandler("onResourceStop", function(name)
    if name == GetCurrentResourceName() or name == "tosun-ac" then
        pending = {}
    end
end)

Проверяйте доверие из ресурса, выполняющего интеграцию#

После изменения списка доверия поместите эту диагностику в ресурс, который действительно будет вызывать export. Команда работает только из консоли сервера; вызовы игроков игнорируются, поскольку src не равен нулю. Выполните my-resource-ac-check один раз. GetIntegrationStatus возвращает имя вызывающего ресурса, trusted и enforcing. Поэтому true, полученное из другого ресурса, не доказывает доверие к вашему скрипту одежды или арены. GetStatus показывает небольшую рабочую сводку с версией и выбранным framework, а не аудит всех интеграций.

Даже при успешном pcall результат должен быть таблицей. Ошибка вызова и false — разные наблюдения; не объявляйте конфигурацию проверенной, если export не удалось вызвать. При trusted=false и enforcing=true сравните имя вызывающего ресурса с проверенным списком доверия. enforcing=false может означать режим аудита; он не подтверждает безопасное ограничение всех чувствительных операций. Вывод содержит только ресурс, версию, framework и два логических значения, без идентификаторов игроков и ключей. Не выполняйте команду каждый tick. После обновления отдельно проверьте обычные и ожидаемо отклоняемые пути скрипта; диагностика чтения не гарантирует права на exports наказаний.

-- Place in the integrating resource's server.lua.
RegisterCommand("my-resource-ac-check", function(src)
    if src ~= 0 then return end -- Server console only.
    if GetResourceState("tosun-ac") ~= "started" then
        print("[integration] tosun-ac is not started")
        return
    end
    local okTrust, trust = pcall(function()
        return exports["tosun-ac"]:GetIntegrationStatus()
    end)
    local okStatus, status = pcall(function()
        return exports["tosun-ac"]:GetStatus()
    end)
    if not okTrust or type(trust) ~= "table"
        or not okStatus or type(status) ~= "table" then
        print("[integration] status query failed")
        return
    end
    print(("[integration] resource=%s version=%s framework=%s trusted=%s enforcing=%s")
        :format(GetCurrentResourceName(), tostring(status.version),
            tostring(status.framework), tostring(trust.trusted), tostring(trust.enforcing)))
end, false)

Регистрация событий с серверной проверкой#

Используйте RegisterSafeEvent в серверном скрипте. Имя события должно начинаться с имени вызывающего ресурса. Валидатор возвращает строго true после проверки игрока, задания, позиции, предметов и прав по серверным данным. Ключ клиента не дает разрешений. Выполненное задание нужно погасить один раз, чтобы не выдать награду повторно.

Используйте клиентский экспорт TriggerSafeServerEvent. sent означает только отправку, а не подтверждение платежа или награды. queued_until_key ждет не больше 30 секунд; заполненная очередь отклоняет новые вызовы. Не повторяйте экономические операции автоматически. После перезапуска AC зарегистрируйте обработчик снова.

Удалите и перенесите старые прямые обработчики RegisterNetEvent. Tosun AC не может отменить обработчик другого ресурса; старая операция остается способом обхода. Обработчики :safe для ProtectedEvents регистрируются только на сервере через AddEventHandler.

-- my-job/server.lua: own server-owned job state and framework adapter.
local activeJobs = {}
local function registerActions()
    if GetResourceState("tosun-ac") ~= "started" then return end
    local ok, reason = exports["tosun-ac"]:RegisterSafeEvent("my-job:finish",
        function(src)
            local job = activeJobs[src]
            return job ~= nil and job.completed == true
            -- Also verify server-owned position, role and inventory as required.
        end,
        function(src)
            local job = activeJobs[src]
            if not job then return end
            activeJobs[src] = nil -- consume before any yielding reward operation
            -- Give the server-owned reward through your validated framework adapter.
        end, {rateLimit=5, windowMs=10000, maxArgs=0})
    if not ok then print("[my-job] SafeEvent: " .. tostring(reason)) end
end
AddEventHandler("onResourceStart", function(name)
    if name == GetCurrentResourceName() or name == "tosun-ac" then registerActions() end
end)
AddEventHandler("playerDropped", function() activeJobs[source] = nil end)

-- my-job/client.lua:
local sent, state = exports["tosun-ac"]:TriggerSafeServerEvent("my-job:finish")
-- Read state; implement a separate application acknowledgement if needed.

Укажите точное имя вызывающего ресурса#

Добавьте set tosun_ac_trusted_resources "my-housing,my-clothing" в server.cfg, сохранив другие проверенные имена. Нужен ресурс/каталог, а не имя сервера, игрока или роль Discord. Используйте set, не setr; оставьте ts.EnforceExportCallerWhitelist = true. Доверие разрешает чувствительные exports, но не проверяет владение домом, предметы, работу или цель. Выполняйте диагностику в самом вызывающем ресурсе и проверяйте trusted=true и enforcing=true.

set tosun_ac_trusted_resources "my-housing,my-clothing"

# txAdmin server console:
tosunac_integration

-- In the invoking integration resource server script:
local status = exports["tosun-ac"]:GetIntegrationStatus()
print(status.resource, status.trusted, status.enforcing)

Пять списков с разными задачами#

Список доверенных ресурсов разрешает чувствительные серверные exports. Whitelist игроков защищает игрока. Whitelist ложных триггеров выключает ловушку, но не разрешает реальное событие. ts.ProtectedEvents — старый транспорт с ключом; стандартный список содержит test:event. Baseline ресурсов хранит проверенные файлы для контроля целостности. Запись в одном списке не меняет остальные. Не добавляйте все события framework в ProtectedEvents или в ловушки.

Полный каталог серверных exports пакета#

Имена и объявления аргументов сформированы по реальным серверным исходникам пакета. Это справочник, не сценарий последовательного выполнения. Соблюдайте регистр и сторону сервер/клиент. Включены внутренние диагностика, сканеры и транспорт: похожее имя не означает безопасную игровую операцию. Перед изменением данных изучите контракт и результаты; знание имени не даёт прав.

-- tosun-ac / server
-- AddWhitelist(target, durationSec)
-- AllowWeapon(src, weapon, ms)
-- BanPlayerExt(playerId, reason)
-- BypassDetection(playerId, detectionKey, durationMs)
-- ClearArea(playerId, areaName)
-- ForensicLinksOf(license)
-- GetCloudThreatScore(src)
-- GetDetections(playerId, limit)
-- GetIntegrationStatus()
-- GetNearbyPlayers(playerId, radius)
-- GetPlayerInfo(playerId)
-- GetPlayerShieldData(src)
-- GetServerAuthorityStatus()
-- GetStatus()
-- IsExemptFromPunish(src)
-- IsInArea(playerId, areaName)
-- IsMovementExempt(src)
-- IsPlayerProtected(playerId)
-- IsWhitelisted(playerId)
-- KickPlayer(playerId, reason)
-- MarkTeleport(src, ms, reason)
-- NoteCloudViolation(src, reason, punishment)
-- OpenScanCache(sealed)
-- PauseAllDetections(durationMs)
-- PausePlayerDetections(playerId, durationMs)
-- RateLimit(src, key, max, windowMs)
-- RegisterSafeEvent(eventName, validator, handler, options)
-- RemoveWhitelist(target)
-- RequestShieldScreenshot(src)
-- ScanPolicyFingerprint(moduleFile, policy)
-- ScanResourceSnapshot(name, expected, callback)
-- SealScanCache(raw)
-- SetExempt(playerId, durationMs, reason)
-- SetPlayerExempt(playerId, state, durationMs, reason)
-- WhitelistArea(playerId, areaName, durationSec)
-- acV2Challenge(build, license, fp, version)
-- acV2Fingerprint()
-- acV2Integrity(raw)
-- acV2VerifyResponse(raw, build, license, fp, version, nonce, httpCode)
-- addAdmin(playerId)
-- addCheatSignature(pattern, signatureName, severity)
-- addSignatureEscrowSkip(resourceName, note)
-- addSignatureException(resourceName, filePath, signatureName, note)
-- applyTimeWithFramework(h, m)
-- applyWeatherWithFramework(weather)
-- approveResource(resourceName, approvedBy)
-- ban(playerId, reason)
-- batchDetection(playerName, license, steam, discord, ip, dtype, reason, punishment, banID, screenshot, configKey)
-- batchLog(message, playerId, playerName)
-- batchWebhook(url, payload)
-- blockResource(resourceName, reason)
-- centralHandshake()
-- centralPoll()
-- centralStatus()
-- checkIpReputation(ip)
-- cipherHasSession(src)
-- cipherIssueKey(src)
-- cipherVerify(src, payload, signature)
-- clearInventory(src)
-- crashGuardInspect(v)
-- crashGuardReject(src, p)
-- emergencyLockdown(reason)
-- fakeTriggerTrap(eventName, typ)
-- fakeTriggerWhitelist(eventName)
-- freezePlayer(src, freeze)
-- getAdminType(playerId)
-- getBanInfo(banID)
-- getBans(limit, offset)
-- getBaseline()
-- getBatchStats()
-- getCleanupStats()
-- getConfig(configType)
-- getInfectedFiles()
-- getOnlinePlayers()
-- getPlayerLocale(src)
-- getResources()
-- getRuntimeStats()
-- getSourceKey()
-- getStats()
-- getSuspicious()
-- giveWeapon(src, weapon, ammo)
-- healAll()
-- invalidateSignatureCache()
-- isAdmin(playerId)
-- isAdminMenuAllowed(playerId)
-- isPlayerFrozen(src)
-- isPlayerMuted(src)
-- isQuarantined(src)
-- isStaffPlayer(playerId)
-- issueEventKey(src)
-- licenseStatus()
-- lockdownStatus()
-- massFreeze(state)
-- mutePlayer(src, durationSec, reason, actor)
-- offlineBan(data, reason)
-- offlineBanByLicense(...)
-- phoneNotify(targetSrc, title, body, opts)
-- phoneNotifyAdmins(title, body, opts)
-- punish(playerId, reason, image, config, punish)
-- quarantine(src, reason, sec)
-- quarantineList()
-- refreshPanelPermissions()
-- refreshPanelWhitelist()
-- releaseQuarantine(src)
-- reloadSignatureExceptions()
-- reloadSignatureScanCaches()
-- removeAdmin(playerId)
-- removeSignatureEscrowSkip(idOrName)
-- removeSignatureException(id)
-- removeWhitelist(playerId)
-- reportInfection(resource, file, sigs, severity, callback)
-- rescanResources()
-- runCleanup()
-- scanAllResources()
-- scanSingleResource(name)
-- screenCapture(src, requestedBy)
-- setLockdown(state, reason)
-- setPlayerArmor(src, armor)
-- setPlayerHealth(src, hp)
-- setPlayerLocale(src, lang)
-- setSpeedLimit(kmh)
-- slayPlayer(src)
-- spectatePlayer(adminSrc, targetSrc)
-- stripWeapons(src)
-- translate(key, ...)
-- translateForPlayer(src, key, ...)
-- tsAutoSetup()
-- tsBackdoorScanStatus()
-- tsLicenseRecheck()
-- tsScanBackdoors(callback)
-- tsScanEvents()
-- tsSignatureScanStatus()
-- unban(banID)
-- unmutePlayer(src)
-- v6ScreenWatchLatest(serverId)
-- v6ScreenWatchPoll(rid)
-- v6ScreenWatchRequest(serverId, mode, requestedBy, panelUrl, forceBase64)
-- v9StreamHasSession(serverId)
-- warnPlayer(src, reason, actor)
-- webBridgeApplyInventory(src, action, itemName, count, slot)
-- webBridgeApplyMoney(src, moneyType, amount, action)
-- webBridgeFindByCitizen(cid)
-- webBridgeFindByLicense(license)
-- webBridgeGrantAdmin(src)
-- webBridgeRevokeAdmin(src)
-- whitelistPlayer(playerId, duration)

-- tosun-ac-guardian / server
-- guardianAlive()
-- guardianHold(reason,seconds)

-- tosun_render / server
-- GetStatus()

Клиентские exports и ограниченный переходный период#

Клиентский SetExempt принимает состояние, миллисекунды, причину; серверный — source игрока, миллисекунды, причину. Клиентский PauseDetections даёт ограниченный период для внешности, движения и камеры, не общую паузу. Общий бюджет продления — 240 секунд за десять минут, до 32 причин. IsExempt(config) требует точный ключ проверки; IsExempt() учитывает только проверенный персонал или полную доверенную/paused льготу. Оружие, события, injection и неизвестные проверки действуют. Обрабатывайте false без вызова каждый кадр.

-- tosun-ac / client
-- GetExemptions()
-- IsExempt(config)
-- IsPlayerAdmin()
-- NativeGuardThreat()
-- NativeGuardToken()
-- PauseDetections(durationMs)
-- SetExempt(state, durationMs, reason)
-- SetSpawned(state)
-- ShieldCaptureForBan(callback)
-- ShieldFlushBanVideo(callback)
-- TriggerSafeServerEvent(eventName, ...)
-- getConfig()
-- getV12Tolerance(key, default)
-- incNetRequest()
-- incScreenshotEvent()
-- shieldHook(hookType, detailJson)

Приватное состояние и значения возврата#

TosunAcState — внутренний API ресурса AC; другие ресурсы используют описанные exports. Серверные setExempt, setPause и setMovement возвращают boolean, максимум пять минут. При ошибке уведомления новое увеличение не сохраняется; отзыв и уменьшение сохраняются даже при false. Полная льгота, пауза и движение независимы. setStaff пишет совместимое зеркало, не выдаёт права администратора. isExemptFromBag/isPausedFromBag читают проверенные приватные разрешения, не изменяемые игроком bags. Успех не гарантирует доставку всем клиентам или паузу всех серверных детекторов.

-- Internal AC server API; external resources use guarded exports.
-- TosunAcState.setExempt(id, active, ms) -> boolean
-- TosunAcState.setPause(id, ms) -> boolean
-- TosunAcState.setMovement(id, ms) -> boolean
-- TosunAcState.remaining(id, kind) -> remaining milliseconds
-- TosunAcState.setStaff(id, staff) -> compatibility mirror only
-- AddWhitelist(target, durationSec): seconds
-- WhitelistArea(playerId, areaName, durationSec): seconds
-- IsInArea: named record lookup, not a coordinate/permission check
-- WhitelistArea grants broad client relief, not one chosen detector.
-- BypassDetection: detectionKey is ignored; full exemption, <=60000ms
-- Client: IsExempt("ts.antiFreeCam") -> scoped camera grace
-- Client: IsExempt() -> verified staff/full/pause only

Каталог событий не заменяет авторизацию#

Каталог исходников перечисляет фиксированные события протокола AC по стороне регистрации. Вычисляемые имена и события ваших ресурсов могут отсутствовать. Не повторяйте вручную внутренние события ключей, наказаний, конфигурации и меню. Обнаружение имени и направления не проверяет собственность или право на награду. Используйте RegisterSafeEvent с серверной валидацией. Защита панели и ac_protected_events создают правила ложных триггеров/honeypot, не валидаторы; при установке оставьте EventScanner.autoProtect=false.

-- tosun-ac/client/AddEventHandler
-- CEventShockingGunshotFired
-- baseevents:onPlayerDied
-- baseevents:onPlayerKilled
-- esx:onPlayerDeath
-- esx_ambulancejob:revive
-- esx_basicneeds:onRevive
-- gameEventTriggered
-- hospital:client:Revive
-- hospital:client:SetDeathState
-- hospital:client:SetLaststand
-- hospital:client:isDead
-- onClientResourceStart
-- onClientResourceStop
-- playerSpawned
-- qb-ambulancejob:client:RevivePlayer
-- qb-medical:client:OnDeath
-- qb-medical:client:OnRevive
-- tosun-ac:nui:pushToolState
-- tosun-ac:uploadTokenUpdated
-- ts_anticheat:adminStateChanged
-- ts_anticheat:adminStatus
-- ts_anticheat:bridge:capture
-- ts_anticheat:bridge:clearInventory
-- ts_anticheat:bridge:freeze
-- ts_anticheat:bridge:giveWeapon
-- ts_anticheat:bridge:heal
-- ts_anticheat:bridge:mute
-- ts_anticheat:bridge:revive
-- ts_anticheat:bridge:setArmor
-- ts_anticheat:bridge:setHealth
-- ts_anticheat:bridge:slay
-- ts_anticheat:bridge:speedLimit
-- ts_anticheat:bridge:stripWeapons
-- ts_anticheat:bridge:teleport
-- ts_anticheat:bridge:time
-- ts_anticheat:bridge:warning
-- ts_anticheat:bridge:weather
-- ts_anticheat:checkTaze
-- ts_anticheat:cipher:assigned
-- ts_anticheat:cipher:request_refresh
-- ts_anticheat:clearDone
-- ts_anticheat:configUpdated
-- ts_anticheat:detectclient
-- ts_anticheat:internal:receiveKey
-- ts_anticheat:internal:trapsChanged
-- ts_anticheat:isAdmin
-- ts_anticheat:joinBundle
-- ts_anticheat:liveSSRequest
-- ts_anticheat:newDetection
-- ts_anticheat:openAdminMenu
-- ts_anticheat:openAdminMenuAuthorized
-- ts_anticheat:panelBroadcast
-- ts_anticheat:panelHeal
-- ts_anticheat:panelRevive
-- ts_anticheat:panelTime
-- ts_anticheat:panelWeather
-- ts_anticheat:promptOpenMenu
-- ts_anticheat:receiveKey
-- ts_anticheat:receiveLiveSS
-- ts_anticheat:receiveLiveVideo
-- ts_anticheat:receivePlayerCount
-- ts_anticheat:receiveScreenshot
-- ts_anticheat:requestCoords
-- ts_anticheat:resourceGuardSync
-- ts_anticheat:shield:requestScreenshot
-- ts_anticheat:shield:uploadConfig
-- ts_anticheat:startVideoLiveStream
-- ts_anticheat:startVideoLiveWeb
-- ts_anticheat:startVideoRecording
-- ts_anticheat:stopVideoLiveStream
-- ts_anticheat:stopVideoLiveWeb
-- ts_anticheat:stopVideoRecording
-- ts_anticheat:syncBanList
-- ts_anticheat:syncConfig
-- ts_anticheat:syncIdentifiers
-- ts_anticheat:syncLogs
-- ts_anticheat:syncPlayers
-- ts_anticheat:takeScreenshot
-- ts_anticheat:unbanDone
-- ts_anticheat:webPanelScreenshot

-- tosun-ac/client/RegisterNUICallback
-- Armour
-- DeleteAll
-- DeleteObjects
-- DeletePeds
-- DeleteVehicles
-- GetPlayerIdentifiers
-- Health
-- addLog
-- armourPlayer
-- banPlayer
-- bringAll
-- bringPlayer
-- cancelAnimation
-- clearNearbyObjects
-- clearNearbyPeds
-- clearNearbyVehicles
-- devtoolsdetected
-- exit
-- freezeAll
-- freezePlayerToggle
-- getBans
-- getLogs
-- getPlayerCount
-- getPlayers
-- giveWeaponPlayer
-- healAll
-- healPlayer
-- isInVehicle
-- kickPlayer
-- liveWatchStart
-- liveWatchStop
-- nuiDependencyMissing
-- nuiWatermark
-- repair
-- returnOCRResult
-- reviveAll
-- revivePlayer
-- screenshotPlayer
-- selfRevive
-- setHealthPlayer
-- setTime
-- setWeather
-- shield_devtools
-- shield_heartbeat
-- shield_heartbeat_fail
-- shield_screenshot
-- shield_tokens
-- shield_video_final
-- shield_video_segment
-- slayPlayer
-- spawnVehicle
-- spectatePlayer
-- stopSpectate
-- stripWeaponsPlayer
-- toggleESP
-- toggleFreecam
-- toggleGodmode
-- toggleInvisible
-- toggleNoclip
-- tosunRenderResult
-- tpToPlayer
-- unbanPlayer
-- verifyModel
-- videoLiveSegmentResult
-- videoRecordingResult
-- videoRecordingStartResult
-- warnPlayerNUI

-- tosun-ac/client/RegisterNetEvent
-- QBCore:Client:OnPlayerLoaded
-- QBCore:Client:OnPlayerUnload
-- esx:onPlayerDeath
-- esx:onPlayerLogout
-- esx:playerLoaded
-- esx_ambulancejob:revive
-- esx_basicneeds:onRevive
-- hospital:client:Revive
-- hospital:client:SetDeathState
-- hospital:client:SetLaststand
-- hospital:client:isDead
-- qb-ambulancejob:client:RevivePlayer
-- qb-medical:client:OnDeath
-- qb-medical:client:OnRevive
-- qbx_core:client:playerLoggedIn
-- qbx_multicharacter:client:chooseChar
-- ts_anticheat:adminStateChanged
-- ts_anticheat:adminStatus
-- ts_anticheat:bridge:capture
-- ts_anticheat:bridge:clearInventory
-- ts_anticheat:bridge:freeze
-- ts_anticheat:bridge:giveWeapon
-- ts_anticheat:bridge:heal
-- ts_anticheat:bridge:mute
-- ts_anticheat:bridge:revive
-- ts_anticheat:bridge:setArmor
-- ts_anticheat:bridge:setHealth
-- ts_anticheat:bridge:slay
-- ts_anticheat:bridge:speedLimit
-- ts_anticheat:bridge:stripWeapons
-- ts_anticheat:bridge:teleport
-- ts_anticheat:bridge:time
-- ts_anticheat:bridge:warning
-- ts_anticheat:bridge:weather
-- ts_anticheat:checkTaze
-- ts_anticheat:cipher:assigned
-- ts_anticheat:cipher:request_refresh
-- ts_anticheat:clearDone
-- ts_anticheat:detectclient
-- ts_anticheat:isAdmin
-- ts_anticheat:joinBundle
-- ts_anticheat:liveSSRequest
-- ts_anticheat:newDetection
-- ts_anticheat:openAdminMenu
-- ts_anticheat:openAdminMenuAuthorized
-- ts_anticheat:panelBroadcast
-- ts_anticheat:panelHeal
-- ts_anticheat:panelRevive
-- ts_anticheat:panelTime
-- ts_anticheat:panelWeather
-- ts_anticheat:promptOpenMenu
-- ts_anticheat:receiveEventKey
-- ts_anticheat:receiveKey
-- ts_anticheat:receiveLiveSS
-- ts_anticheat:receiveLiveVideo
-- ts_anticheat:receivePlayerCount
-- ts_anticheat:receiveScreenshot
-- ts_anticheat:requestCoords
-- ts_anticheat:resourceGuardSync
-- ts_anticheat:shield:requestScreenshot
-- ts_anticheat:shield:uploadConfig
-- ts_anticheat:startVideoLiveStream
-- ts_anticheat:startVideoLiveWeb
-- ts_anticheat:startVideoRecording
-- ts_anticheat:stopVideoLiveStream
-- ts_anticheat:stopVideoLiveWeb
-- ts_anticheat:stopVideoRecording
-- ts_anticheat:syncBanList
-- ts_anticheat:syncConfig
-- ts_anticheat:syncIdentifiers
-- ts_anticheat:syncLogs
-- ts_anticheat:syncPlayers
-- ts_anticheat:takeScreenshot
-- ts_anticheat:unbanDone
-- ts_anticheat:uploadToken
-- ts_anticheat:webPanelScreenshot

-- tosun-ac/server/AddEventHandler
-- QBCore:Server:OnPlayerLoaded
-- QBCore:Server:PlayerLoaded
-- chatMessage
-- clearPedTasksEvent
-- entityControlEvent
-- entityCreated
-- entityCreating
-- esx:playerLoaded
-- eventTriggered
-- explosionEvent
-- fireEvent
-- giveWeaponEvent
-- onResourceStart
-- onResourceStop
-- onServerResourceStart
-- playerConnecting
-- playerDropped
-- playerJoining
-- ptFxEvent
-- qbx_core:server:playerLoaded
-- rconCommand
-- removeAllWeaponsEvent
-- removeWeaponEvent
-- requestControlEvent
-- respawnPlayerPedEvent
-- startProjectileEvent
-- tosun-ac:nuiPermissionRefreshed
-- tosun-ac:panel:characterReady
-- tosun-ac:server:detection
-- tosun-ac:server:logResourceActivity
-- tosun-ac:server:nuiWatermark
-- tosun-ac:server:signedDetection
-- tosun-ac:settingsReloaded
-- ts_anticheat:GetPlayerIdentifiers
-- ts_anticheat:addAdmin_internal
-- ts_anticheat:addLog
-- ts_anticheat:adminDelEntity
-- ts_anticheat:banCommitted
-- ts_anticheat:banPlayer
-- ts_anticheat:banRelay
-- ts_anticheat:bridge:freeze
-- ts_anticheat:bringAllPlayers
-- ts_anticheat:bringPlayer
-- ts_anticheat:cipher:detection
-- ts_anticheat:cipher:request
-- ts_anticheat:clearTasks
-- ts_anticheat:client:scriptsReady
-- ts_anticheat:configUpdated
-- ts_anticheat:deleteObjects
-- ts_anticheat:deletePeds
-- ts_anticheat:deleteVehicles
-- ts_anticheat:freezeAllPlayers
-- ts_anticheat:getBanList
-- ts_anticheat:getLogs
-- ts_anticheat:getPlayerCount
-- ts_anticheat:getPlayers
-- ts_anticheat:healAllPlayers
-- ts_anticheat:internal:pushResourceGuard
-- ts_anticheat:internal:suspicious
-- ts_anticheat:kickPlayer
-- ts_anticheat:liveSSResult
-- ts_anticheat:liveWatchStart
-- ts_anticheat:liveWatchStop
-- ts_anticheat:logAdminMenu
-- ts_anticheat:newLog
-- ts_anticheat:playerBanned
-- ts_anticheat:requestAdminStatus
-- ts_anticheat:requestEventKey
-- ts_anticheat:requestKey
-- ts_anticheat:requestOpenAdminMenu
-- ts_anticheat:returnCoords
-- ts_anticheat:reviveAllPlayers
-- ts_anticheat:screenshotPlayer
-- ts_anticheat:screenshotResult
-- ts_anticheat:server:<computed suffix> [template only; not a runnable exact event]
-- ts_anticheat:server:checkIsAdmin
-- ts_anticheat:server:clientXkzuqBwmTjN7Gab4QzuN9QYZJ1WxxU
-- ts_anticheat:server:requestJoinHandshake
-- ts_anticheat:server:requestResourceGuard
-- ts_anticheat:server:requestSyncData
-- ts_anticheat:server:tazed
-- ts_anticheat:serverClear
-- ts_anticheat:setInvisible
-- ts_anticheat:setTime
-- ts_anticheat:setWeather
-- ts_anticheat:shield:ban_video_saved
-- ts_anticheat:spawnVehicle
-- ts_anticheat:targetArmour
-- ts_anticheat:targetFreeze
-- ts_anticheat:targetGiveWeapon
-- ts_anticheat:targetHeal
-- ts_anticheat:targetRevive
-- ts_anticheat:targetSetHealth
-- ts_anticheat:targetSlay
-- ts_anticheat:targetStripWeapons
-- ts_anticheat:targetWarn
-- ts_anticheat:tpToPlayer
-- ts_anticheat:unbanPlayer
-- ts_anticheat:v10:exec
-- ts_anticheat:v6:detection
-- ts_anticheat:v6:screenshotResult
-- ts_anticheat:verifyModel
-- ts_anticheat:videoResult
-- vehicleComponentControlEvent
-- weaponDamageEvent

-- tosun-ac/server/RegisterNetEvent
-- tosun-ac:panel:characterReady
-- tosun-ac:server:detection
-- tosun-ac:server:logResourceActivity
-- tosun-ac:server:nuiWatermark
-- tosun-guard:acMissing
-- tosun-guard:hello
-- tosun-guard:tick
-- tosun:nativeGuard:status
-- ts_anticheat:GetPlayerIdentifiers
-- ts_anticheat:addLog
-- ts_anticheat:adminDelEntity
-- ts_anticheat:banPlayer
-- ts_anticheat:banRelay
-- ts_anticheat:bridge:freeze
-- ts_anticheat:bringAllPlayers
-- ts_anticheat:bringPlayer
-- ts_anticheat:cipher:detection
-- ts_anticheat:cipher:request
-- ts_anticheat:client:scriptsReady
-- ts_anticheat:deleteObjects
-- ts_anticheat:deletePeds
-- ts_anticheat:deleteVehicles
-- ts_anticheat:freezeAllPlayers
-- ts_anticheat:getBanList
-- ts_anticheat:getLogs
-- ts_anticheat:getPlayerCount
-- ts_anticheat:getPlayers
-- ts_anticheat:healAllPlayers
-- ts_anticheat:kickPlayer
-- ts_anticheat:liveSSResult
-- ts_anticheat:liveWatchStart
-- ts_anticheat:liveWatchStop
-- ts_anticheat:logAdminMenu
-- ts_anticheat:requestAdminStatus
-- ts_anticheat:requestEventKey
-- ts_anticheat:requestKey
-- ts_anticheat:requestOpenAdminMenu
-- ts_anticheat:returnCoords
-- ts_anticheat:reviveAllPlayers
-- ts_anticheat:screenshotPlayer
-- ts_anticheat:screenshotResult
-- ts_anticheat:server:checkIsAdmin
-- ts_anticheat:server:clientXkzuqBwmTjN7Gab4QzuN9QYZJ1WxxU
-- ts_anticheat:server:requestJoinHandshake
-- ts_anticheat:server:requestResourceGuard
-- ts_anticheat:server:requestSyncData
-- ts_anticheat:server:tazed
-- ts_anticheat:serverClear
-- ts_anticheat:setInvisible
-- ts_anticheat:setTime
-- ts_anticheat:setWeather
-- ts_anticheat:shield:banVideo
-- ts_anticheat:shield:heartbeat_fail
-- ts_anticheat:shield:requestUploadConfig
-- ts_anticheat:shield:screenshot
-- ts_anticheat:shield:tokens
-- ts_anticheat:spawnVehicle
-- ts_anticheat:targetArmour
-- ts_anticheat:targetFreeze
-- ts_anticheat:targetGiveWeapon
-- ts_anticheat:targetHeal
-- ts_anticheat:targetRevive
-- ts_anticheat:targetSetHealth
-- ts_anticheat:targetSlay
-- ts_anticheat:targetStripWeapons
-- ts_anticheat:targetWarn
-- ts_anticheat:tpToPlayer
-- ts_anticheat:unbanPlayer
-- ts_anticheat:v10:exec
-- ts_anticheat:v6:detection
-- ts_anticheat:v6:screenshotResult
-- ts_anticheat:verifyModel
-- ts_anticheat:videoResult

-- tosun-ac/server/RegisterServerEvent
-- ts_anticheat:clearTasks

-- tosun-ac/shared/AddEventHandler
-- onClientResourceStart
-- onResourceStop
-- playerDropped
-- ts_anticheat:locale:reload
-- ts_anticheat:locale:setSelf
-- ts_anticheat:locale:sync

-- tosun-ac/shared/RegisterNetEvent
-- ts_anticheat:locale:setSelf
-- ts_anticheat:locale:sync

-- tosun-ac-guardian/server/AddEventHandler
-- onResourceStart
-- onResourceStop

-- tosun_render/server/AddEventHandler
-- onResourceStart

-- tosun-ac/client / RegisterCommand
-- stopspectate
-- tsdelaimed
-- tsfreecam
-- tsmenu
-- unspectate

-- tosun-ac/server / RegisterCommand
-- ac_cleanup
-- acfreeze
-- acping
-- acstats
-- acunfreeze
-- acwarn
-- capture
-- clearinv
-- emergency
-- giveweapon
-- massfreeze
-- mute
-- setarmor
-- sethp
-- speedlimit
-- stripweapons
-- tosunac_backdoorscan
-- tosunac_db_check
-- tosunac_db_status
-- tosunac_doctor
-- tosunac_eventscan
-- tosunac_integration
-- tosunac_license_status
-- tosunac_setup
-- ts
-- ts_adminsync
-- ts_broadcast
-- ts_capture
-- ts_clearinv
-- ts_emergency
-- ts_freeze
-- ts_giveweapon
-- ts_healall
-- ts_kickall
-- ts_lockdown
-- ts_massfreeze
-- ts_modping
-- ts_mute
-- ts_players
-- ts_revive
-- ts_setarmor
-- ts_sethp
-- ts_settime
-- ts_setweather
-- ts_slay
-- ts_speedlimit
-- ts_stripweapons
-- ts_tphere
-- ts_tpto
-- ts_unfreeze
-- ts_unmute
-- ts_v9_help
-- ts_warn
-- ts_warnings
-- unmute

-- tosun-ac/shared / RegisterCommand
-- ts_setlang

-- tosun-ac-guardian/server / RegisterCommand
-- tosunac_guardian_pause
-- tosunac_guardian_resume
-- tosunac_guardian_status

-- tosun_render/server / RegisterCommand
-- tosun_render_status

SafeEvent: перезапуск, очередь и ошибки#

RegisterSafeEvent требует имя с префиксом ресурса, validator и handler. Validator возвращает ровно true после проверки текущих серверных данных. Удалите старый сырой сетевой handler: AC не отменяет независимые обработчики других ресурсов. Регистрируйте снова после перезапуска своего ресурса или tosun-ac. Клиентские статусы: sent, queued_until_key, queue_full, invalid_event_or_arguments, resource_stopping. sent означает отправку, не квитанцию награды. Очередь — до 32 вызовов на 30 секунд. Ошибка handler не повторяется и не подтверждается автоматически. Нужны отдельная квитанция и идемпотентная операция; деньги/предметы автоматически не повторять.

-- Client TriggerSafeServerEvent results:
-- true,  "sent"
-- false, "queued_until_key"
-- false, "queue_full"
-- false, "invalid_event_or_arguments"
-- false, "resource_stopping"

-- Server RegisterSafeEvent results:
-- true, "registered"
-- false + server_resource_required / use_own_resource_prefix
-- false + invalid_callbacks_or_options / already_registered / registration_capacity

-- Server log may say: application handler failed.
-- No automatic replay; implement an application receipt.

Отчёт в очереди ещё не подтверждает запись#

reportInfection(resource, file, sigs, severity[, callback]) возвращает true только при постановке DB-операции в очередь. Необязательный callback вызывается максимум один раз: success, affectedRows; успех требует положительного целого числа строк. Без ответа driver завершение не гарантировано. Resource 1–190 байт букв/цифр/_.-, file 1–500 байт, severity 1–50 букв/цифр/_- (по умолчанию warning). sigs — непустая строка или плотный список1–32 строк; объединённое значение до255 байт. NUL/CR/LF запрещены. Неверный ввод, отсутствующий/отклоняющий driver или синхронная ошибка: false. Не повторяйте автоматически при неизвестном результате.

-- A reviewed server reporting workflow; fictional non-secret labels.
-- resource: 1..190 bytes, letters/digits/underscore/dot/hyphen
-- file: 1..500 bytes; signatures joined: 1..255 bytes
-- severity: 1..50 bytes, letters/digits/underscore/hyphen (no dot)
local queued = exports["tosun-ac"]:reportInfection(
    "my-housing", "server.lua", {"reviewed_pattern"}, "warning",
    function(success, affectedRows)
        print(success and "[scan] report saved" or "[scan] report not confirmed")
    end)
-- queued=true is dispatch only; it is not the completion callback.
-- Do not automatically retry an operation with an uncertain outcome.