Server API
Everything here lives in CoreServerAPI and runs from a server Script:
local hd = game:GetService("ReplicatedStorage"):WaitForChild("HD Admin")
local ServerAPI = require(hd.Core.ServerAPI)
Commands¶
requestCommand Server¶
ServerAPI.requestCommand(message: string, fromPlayer: Player?): (boolean, {any}, {Task})
Runs a command message exactly as if it was chatted. When no player is given, a Server User takes the caller's place, so commands can fire from anywhere in your game code without permission checks. When a player is provided, their roles, permissions and rate limits all apply, and any caller notices are sent to them. Returns whether approved, the notices produced, and the tasks it created.
-- Run as the server
ServerAPI.requestCommand(";fly all")
-- Or on behalf of a player
ServerAPI.requestCommand(";fly me", player)
getTasks Server¶
ServerAPI.getTasks(commandName: string?, target: Target?): {Task}
Returns the running tasks. Both filters are optional. ServerAPI.getTasks() returns every task, ServerAPI.getTasks("fly") every fly task, and ServerAPI.getTasks("fly", player) only that player's fly tasks.
endTasks Server¶
ServerAPI.endTasks(commandName: string?, target: Target?): number
Ends the matching tasks and returns how many were ended. This is ;unCommand in code form, with the same optional filters as getTasks.
-- End every fly in the server
ServerAPI.endTasks("fly")
-- Clear everything running on one player
ServerAPI.endTasks(nil, player)
canUseCommandAsync Server¶
ServerAPI.canUseCommandAsync(target: Target, commandName: string): (boolean, string?)
Whether the target's roles allow them to run the given command. Returns true, or false and the reason.
disableCommands Server¶
ServerAPI.disableCommands(player: Player)
Blocks the player from running any new commands until enableCommands is called or they rejoin. Useful while they're inside a minigame round or a cutscene. Their already-running tasks carry on, so pair this with endTasks if you want those cleared too. It's safe to call straight from PlayerAdded.
enableCommands Server¶
ServerAPI.enableCommands(player: Player)
Lets the player run commands again.
Roles¶
Role names are matched case-insensitively, so "VIP" and "vip" reach the same role.
giveRoleAsync Server¶
ServerAPI.giveRoleAsync(target: Target, roleName: string, options: ActionOptions?): (boolean, string?)
Gives the role to the target and returns true, or false and the reason it couldn't. Permanent grants save, travel cross-server, and work for offline targets too.
| Option | What it does |
|---|---|
scope |
"perm" saves forever (the default), "server" lasts this server only, "expire" removes itself after duration |
duration |
Seconds, required for scope "expire" |
reason |
The reason for giving |
callerUserId |
A UserId of the person who gave it and to rank-check against |
-- Reward a purchase forever
ServerAPI.giveRoleAsync(player, "VIP")
-- A 24 hour trial, granted by an offline head admin
ServerAPI.giveRoleAsync(player, "Mod", {
scope = "expire",
duration = 24 * 3600,
callerUserId = 1234567,
})
takeRoleAsync Server¶
ServerAPI.takeRoleAsync(target: Target, roleName: string, options: ActionOptions?): (boolean, string?)
Takes the role from the target, including permanent grants made on other servers or while they were offline. options accepts scope ("perm" or "server") and callerUserId, matching giveRoleAsync.
getRolesAsync Server¶
ServerAPI.getRolesAsync(target: Target): (boolean, {Role} | string)
Returns true and the target's roles ordered highest rank first, or false and a reason. The target must be in this server.
local success, roles = ServerAPI.getRolesAsync(player)
if success then
for _, role in roles do
print(role.name, role.rank)
end
end
getTopRoleAsync Server¶
ServerAPI.getTopRoleAsync(target: Target): (boolean, (Role | string)?)
Returns true and the target's most senior role (nil if they hold none), or false and a reason. The target must be in this server.
hasRoleAsync Server¶
ServerAPI.hasRoleAsync(target: Target, roleName: string): boolean
Whether the target currently holds the role. The target must be in this server.
getRole Server¶
ServerAPI.getRole(roleName: string): Role?
Returns the Role for the given name, or nil if no role matches.
getAllRoles Server¶
ServerAPI.getAllRoles(): {Role}
Returns every role in the game's configuration.
Moderation¶
banAsync Server¶
ServerAPI.banAsync(target: Target, options: BanOptions): (boolean, string?)
Bans the target for entering your game, and kicks them if they're currently in any server. Returns true and the new banId, or false and the reason it couldn't. Offline targets work too.
| Option | What it does |
|---|---|
reason |
Required, shown to the player when they try to join |
scope |
"perm" (the default), "server" for this server only, or "expire" |
duration |
Seconds, for scope "expire" |
expiresAt |
An absolute epoch which overrides duration |
banAlts |
Defaults to true, banning alt accounts through Roblox's BanService |
callerUserId |
A UserId to credit the ban to and rank-check against. Leave it out for a system ban with no restrictions |
-- A 7 day ban issued by your own anti-cheat
ServerAPI.banAsync(player, {
reason = "Exploiting",
scope = "expire",
duration = 7 * 24 * 3600,
})
unbanAsync Server¶
ServerAPI.unbanAsync(target: Target, banId: string?, options: UnbanOptions?): (boolean, string?, number?)
Clears the target's bans and returns (success, failReason, totalBansCleared). Pass a banId to clear one specific ban, or nil to clear them all. options accepts scope and callerUserId.
getBanAsync Server¶
ServerAPI.getBanAsync(target: Target): (BanRecord?, string?)
Returns the target's active BanRecord and its banId, checking offline records too, or nil if they aren't banned.
local ban, banId = ServerAPI.getBanAsync(userId)
if ban then
print(`Banned for '{ban.reason}' by {ban.bannedBy}`)
end
Prompts¶
prompt Shared¶
ServerAPI.prompt(promptType: PromptType, player: Player, text: string, options: PromptOptions?): PromptHandle
Shows the given prompt using HD Admin's own UI. promptType is one of:
| Prompt type | What it shows |
|---|---|
"info" "success" "warn" "error" |
Sidebar notices in the matching style |
"message" |
A centre-screen message |
"hint" |
A bar across the top of the screen |
"privateMessage" |
A full-screen message with a reply prompt |
"alert" |
A centre card that demands attention |
"vote" |
A poll the player can answer, with "voteResults" presenting the outcome |
"action" |
A card with buttons and controls you define |
Common options include title, duration, color, icon, openPage (clicking the notice opens that menu page) and dismissable. The vote and action types take a lot more than this, which autocomplete shows you in full.
The handle it returns lets you dismiss the prompt early with handle:Disconnect().
ServerAPI.prompt("success", player, "Quest complete!", {duration = 5})
Info¶
getSetting Shared¶
ServerAPI.getSetting(settingName: string, player: Player?): any
Returns the value of a game setting, like ServerAPI.getSetting("Prefix"). Pass a player to also apply their own You Settings, so you get the exact value that player experiences.
getVersion Shared¶
ServerAPI.getVersion(): string
The running HD Admin version, like "v2.0.0".
Emotes¶
getEmoteById Server¶
ServerAPI.getEmoteById(emoteId: number): Emote?
Returns the registered Emote with the given id, or nil.
getEmoteByName Server¶
ServerAPI.getEmoteByName(emoteName: string, matchLength: boolean?): Emote?
Returns the registered Emote matching the given name, or nil.
getRandomEmote Server¶
ServerAPI.getRandomEmote(): Emote?
addEmoteAsync Server¶
ServerAPI.addEmoteAsync(emote: IncompleteEmote, dontRegister: boolean?): (boolean, Emote | string)
Registers a new emote from an emote animation asset, so it can be played by ;emote and appear in the emotes menu. Only emoteId is required, and the missing details are fetched for you. Returns true and the completed Emote, or false and the reason it couldn't.
Types¶
Role¶
The full role configuration table, exactly as defined under ConfigRoles. See Roles.
BanRecord¶
type BanRecord = {
type: "perm" | "expire" | "server",
source: "admin" | "loader",
bannedBy: number | string,
bannedAt: number,
expiresAt: number?,
grantedOnJobId: string?, -- only present on server-scope bans
reason: string,
banAlts: boolean,
}
The banId isn't part of the record itself, so getBanAsync hands it to you as a second return value.
Task¶
See Task API.
Emote¶
type Emote = {
name: string,
originalName: string?,
order: number,
animationId: number,
emoteId: number,
}