Bans are stored by the AstroShield backend and mirrored to your server, so that a banned player can be refused immediately, even if the backend is briefly unreachable. This page shows how to use that data from your own scripts.
The backend stores bans only. Kicks and warnings are not stored. A kick is still posted to your bans webhook, and every punishment fires astroshield:player:punished. getLocalRecords('kicks') and getLocalRecords('warns') return empty lists.
The ban record#
A ban record is a table with these fields:
| Field | Type | Meaning |
|---|---|---|
id | string | The ban ID. Six characters of letters and digits. This is the ID the player saw on the ban screen. |
username | string | The player's name when they were banned. |
detection | string | The detection that caused the ban, your own name from punishPlayer, or Custom Rule: <name>. |
description | string | The reason. |
license, license2, steam, discord, xbox | string | Identifiers of the player. |
ip | string | The player's IP at the time. |
hwid | string | A hardware token. |
evidence | string | URL of the video clip, when there is one. |
isManual | boolean | true for bans that were not created by a detection. |
createdAt | string | When the ban was made. |
expiresAt | string or nil | When a timed ban ends. nil means permanent. |
serverId, serverName | string | The license ID and name of the server. |
Treat identifiers and IPs as personal data. Do not post them publicly.
Read bans#
Quick: the local list#
local bans = exports.AstroShield:getLocalRecords('bans')
print(#bans .. ' bans on this server')getLocalRecords returns the list as last sent by the backend. It is instant, it never waits, and it leaves out timed bans that have ended.
Fresh: ask the backend#
CreateThread(function()
local result = exports.AstroShield:getRecords('bans', nil, 5000)
if result.success then
for _, ban in ipairs(result.data) do
print(ban.id, ban.username, ban.detection)
end
else
print('Backend did not answer, using the cached list', result.cached, result.error)
end
end)getRecords waits for the answer, so call it from a thread. It resolves to { success, data, cached, error }. When the backend does not answer in time, cached is true and data is the last known list.
React to changes#
Listen to astroshield:ban:created and astroshield:ban:deleted to mirror bans into your own systems, for example a Discord bot or a shared ban list between your servers.
AddEventHandler('astroshield:ban:created', function(ban)
TriggerEvent('myBot:announceBan', ban.id, ban.username, ban.detection)
end)Create a ban#
Use punishPlayer. It runs the full flow: isolate, evidence, record, drop, webhook.
exports.AstroShield:punishPlayer(src, 'myScript:exploit', 'Used the exploit', 'ban')Lift a ban#
Run the console command through ExecuteCommand. It removes the ban from the dashboard and from this server's memory.
ExecuteCommand(('astroshield unban %s'):format(banId))See Console commands and, for staff, Bans.