Server exports
Ban, kick, unban, read your ban list, whitelist a player for one session, or read their standing, all from your own server scripts.
Raven exposes ten server-side exports so your own resources can act on a player through Raven, read your ban list, and ask what standing a player has. Every action, whether a ban, kick or unban, is recorded on your dashboard exactly like a detection would, with the name of the resource that asked, so the player shows up in your bans list and stays reviewable.
The whole surface
| Export | Returns | Blocks for |
|---|---|---|
ban(source, reason, description, banAdmin) | Ban id as a string, or false | Up to 6 seconds |
kick(source, reason, description, kickAdmin) | true, or false | Returns as soon as the drop is done |
unban(banId, reason) | Ban id as a string, or false | Up to 5 seconds |
isbanned(source) | true or false | Up to 5 seconds, cached 15 seconds per player |
getbans() | Table of active bans, newest first | Up to 5 seconds, cached 5 seconds |
addtempwhitelist(source) | true, or false | Local read, no wait |
removetempwhitelist(source) | true, or false | Local read, no wait |
gettrustscore(source) | Whole number out of 100, or nil | Local read, no wait |
isadmin(source) | true or false | Local read, no wait |
iswhitelisted(source) | true or false | Local read, no wait |
Arguments
| Argument | Used by | What it is |
|---|---|---|
source | ban, kick, isbanned, the whitelist and standing exports | The player server id as a number. A string that looks like a number is accepted too. Anything else returns the failure value without a cloud call. |
reason | ban, kick, unban | Optional string shown to the player and stored with the record. An empty string counts as omitted, so ban falls back to "Banned by an admin." and kick to "Kicked by an admin." |
description | ban, kick | Optional second string. It is handed to the integration events and to nothing else, so it is context for your own handlers rather than a field on the dashboard record. |
banAdmin / kickAdmin | ban, kick | Optional boolean, last. false by default, so a call against anyone tagged for in-game staff access on your dashboard is refused rather than carried out. An ace right does not count here. Pass true when you mean it. |
banId | unban | The id of the ban to remove, the value shown on your dashboard or returned when the ban was created. A non-string or an empty string returns false. |
Ban a player
exports['rac']:ban(source, reason, description, banAdmin)
Bans the player on source through Raven. The ban is recorded on your dashboard as a manual ban, the player is dropped with your configured ban message, and a ban id is issued. Returns the ban id as a string once the ban is recorded, or false if the player id is not a number, is one of your admins and banAdmin was not passed, or is already being actioned. If the dashboard refuses the ban or does not answer, the player is kicked instead and the call returns false.
One case returns true: the export waits about 6 seconds for the id, and an answer that lands after that is too late to be returned. A slow dashboard can do it, and so can one of your integration event handlers holding the drop for longer than the wait. Either way the ban is real and the id is simply not back yet, so read it off your bans list rather than off the call.
On a resource older than 1.8.9, ban returns true instead of the id, and it also returns true when the ban failed and the player was kicked instead, so there it tells you the player is gone rather than that they are banned.
RegisterCommand('banplayer', function(source, args)
local target = tonumber(args[1])
local reason = table.concat(args, ' ', 2)
if target then
exports['rac']:ban(target, reason)
end
end, true)Kick a player
exports['rac']:kick(source, reason, description, kickAdmin)
Kicks the player on source through Raven. The kick is sent to your dashboard and the player is dropped with your configured kick message. Returns true once the player has been dropped, or false if the player id is not a number, is one of your admins and kickAdmin was not passed, or is already being actioned.
Unlike ban, the kick does not wait on the dashboard before dropping the player, so true means the player is gone rather than that the record landed. If a handler asks to delay the drop, this call blocks for that window.
exports['rac']:kick(source, 'Breaking server rules')Unban a player
exports['rac']:unban(banId, reason)
Removes a ban by its id. Pass the banId shown on the dashboard or returned when the ban was created. The ban is marked as removed, the trust score the ban took is refunded, and the player can connect again. The call waits up to about 5 seconds and returns the ban's id as a string once it is lifted, including when it had already been lifted, so a retry is safe. It returns false if the dashboard refuses, for example because no ban has that id, or does not answer in time. No answer is not a success: the ban may still be in place.
On a resource older than 1.8.9 the call does not wait at all: it returns true straight away, whatever the dashboard then decides, so check the Bans List to see whether the ban was lifted.
exports['rac']:unban('ban-1718900000000-a1b2c3d', 'Appeal accepted')Check if a player is banned
exports['rac']:isbanned(source)
Returns true if the player on source has an active ban on your server, or false otherwise. The check runs against your dashboard, waits up to about 5 seconds, and caches the answer for 15 seconds per connected player, so polling it stays cheap. An id that is not a number returns false without a cloud call.
A failed or timed-out check falls back to the cached answer, and to false when there is none. So false means either no ban or no answer. Do not use it as the only gate on something that matters; the connection check Raven runs on join is the authority there.
if exports['rac']:isbanned(source) == true then
print('That player has an active ban.')
endRead your ban list
exports['rac']:getbans()
Returns a table of your server's active bans, newest first, so you can build your own in-game ban panel. The list comes from your dashboard, holds up to 500 bans, and is cached for 5 seconds. Lifted bans are not in it.
| Field | What it holds |
|---|---|
id | The ban id, the same value unban takes. |
reason | The reason the player was shown. |
manual | true when an admin, the console or a script placed the ban, false when a detection did. |
name | The player name at the time of the ban. |
at | When the ban was placed, as an ISO 8601 string. |
actor | Who placed it, by name, or nil. |
actorKind | One of player, console or resource, or nil on an older record. |
A call that cannot reach the dashboard returns the last good list, or an empty table when there has not been one, so an empty table means either no bans or no answer. Check it against something you know is there if the difference matters.
local bans = exports['rac']:getbans()
if type(bans) == 'table' then
for _, ban in ipairs(bans) do
print(ban.id, ban.reason, ban.manual and 'manual' or 'system')
end
endTemporary whitelist
exports['rac']:addtempwhitelist(source)
exports['rac']:removetempwhitelist(source)
Gives the player the same standing a whitelisted moderator has, for as long as they stay connected, and takes it away again. Both return true when applied and false when Raven has no session for that id, which is the case for a player who is not connected or whose join has not been verified yet. The whitelist takes effect at once.
This is the tool for a scripted sequence that would otherwise look like cheating: a cutscene that needs noclip, a minigame that makes someone briefly invincible, a staged event that moves people faster than a player could.
exports['rac']:addtempwhitelist(source)
exports['rac']:removetempwhitelist(source)Read a player's standing
exports['rac']:gettrustscore(source)
exports['rac']:isadmin(source)
exports['rac']:iswhitelisted(source)
gettrustscore returns the player's trust score out of 100 as a whole number, or nil if nobody has scored them yet. Treat nil as unknown rather than as zero: a brand new player has no score, not a bad one.
isadmin is true for a verified player whose identifier is tagged for in-game staff access on your moderator list, so it answers "has Raven been told this player is staff" rather than "is this player staff in my framework". It reads no ace right, and it says nothing about which of the fourteen abilities they hold. iswhitelisted is true for a whitelist from your panel, from txAdmin, or from addtempwhitelist. All three read Raven's own session table, so they return at once with no call out to the cloud.
local trust = exports['rac']:gettrustscore(source)
if trust ~= nil and trust < 30 then
print('Low trust, watch this one')
endCooldowns
Every export sits behind a token bucket so a busy or buggy script cannot flood the cloud or spin the server. Normal use never trips one, including a burst of real actions from a large server. The bucket starts full, each call takes one token, and tokens come back at the refill rate, so a steady rate under the refill never runs out.
| Export | Bucket | Refill | Returns when empty |
|---|---|---|---|
ban, kick | 60 | 30 a second | Timeouted request, wait N seconds |
unban | 50 | 10 a second | Timeouted request, wait N seconds |
isbanned | 128 | 40 a second | Timeouted request, wait N seconds |
getbans | 5 | 1 a second | Timeouted request, wait N seconds |
addtempwhitelist, removetempwhitelist, gettrustscore, isadmin, iswhitelisted | 120 | 40 a second | false, or nil from gettrustscore |