Building a Permissions System
A flexible permission system for admin controls and rank-based access.
A permission system prevents players from using commands they shouldn't. Instead of hardcoding "if this player can do this", we define ranks with permission lists. This makes it easy to add new commands - just check if the player has the permission, and one place to change rank permissions.
How It Works
Each rank has a list of permissions (like "kick", "ban", "whitelist"). When a player tries to use a command, we check their rank's permissions. This is more flexible than hardcoding player names or UUIDs.
Define Ranks
First, we create all the ranks and what permissions each has:
const RANKS = {
player: {
name: "Player",
permissions: ["teleport", "home"],
color: "§7"
},
mod: {
name: "Moderator",
permissions: ["teleport", "home", "kick", "warn"],
color: "§b"
},
admin: {
name: "Administrator",
permissions: ["teleport", "home", "kick", "warn", "ban", "whitelist"],
color: "§c"
},
owner: {
name: "Owner",
permissions: ["*"], // All permissions
color: "§6"
}
};
What's the color field? We use it to color the player's nameTag based on their rank. Moderators appear blue, admins red, etc. This makes rank visually obvious.
What does "*" mean? It's a wildcard - means "all permissions". The owner can do anything without checking individual permissions.
Store Player Ranks
import { SuperDB } from "@minecraft/server";
const playerDB = new SuperDB({
name: "players",
immediateWrite: true
});
function setRank(playerId, rankKey) {
const player = playerDB.get(playerId) || { rank: "player" };
player.rank = rankKey;
playerDB.set(playerId, player);
}
function getRank(playerId) {
const player = playerDB.get(playerId);
return player?.rank || "player";
}
function getPermissions(playerId) {
const rankKey = getRank(playerId);
const rank = RANKS[rankKey];
return rank?.permissions || RANKS.player.permissions;
}
Check Permissions
function hasPermission(playerId, permission) {
const permissions = getPermissions(playerId);
return permissions.includes("*") || permissions.includes(permission);
}
function checkPermission(player, permission) {
if (!hasPermission(player.nameTag, permission)) {
player.sendMessage("You don't have permission for this!");
return false;
}
return true;
}
Protected Commands
import { world } from "@minecraft/server";
world.beforeEvents.chatSend.subscribe((event) => {
const player = event.sender;
const message = event.message;
// Admin kick command
if (message.startsWith("!kick ")) {
event.cancel = true;
if (!checkPermission(player, "kick")) return;
const targetName = message.split(" ")[1];
const target = world.getAllPlayers().find(p => p.nameTag === targetName);
if (!target) {
player.sendMessage("Player not found!");
return;
}
target.sendMessage("You have been kicked!");
console.log(`${player.nameTag} kicked ${targetName}`);
}
// Ban command
if (message.startsWith("!ban ")) {
event.cancel = true;
if (!checkPermission(player, "ban")) return;
const targetName = message.split(" ")[1];
// Store in ban list...
player.sendMessage(`Banned ${targetName}`);
}
});
Display Rank in Name
function getFormattedName(playerId) {
const rankKey = getRank(playerId);
const rank = RANKS[rankKey];
return `${rank.color}[${rank.name}] §r${playerId}`;
}
// Apply to nameTag on join
world.afterEvents.playerSpawn.subscribe((event) => {
const player = event.player;
const formattedName = getFormattedName(player.nameTag);
player.nameTag = formattedName;
});
Admin Panel
function showAdminPanel(player) {
const rankKey = getRank(player.nameTag);
const rank = RANKS[rankKey];
player.sendMessage("=== Admin Panel ===");
player.sendMessage(`Your rank: ${rank.name}`);
player.sendMessage("Available commands:");
rank.permissions.forEach(perm => {
const commands = {
kick: "!kick <player>",
ban: "!ban <player>",
warn: "!warn <player>",
whitelist: "!whitelist <player>"
};
if (commands[perm]) {
player.sendMessage(`- ${commands[perm]}`);
}
});
}
// Command to open admin panel
world.beforeEvents.chatSend.subscribe((event) => {
if (event.message === "!admin") {
event.cancel = true;
showAdminPanel(event.sender);
}
});