Permission nodes for every command/subcommand with wildcard parents

This commit is contained in:
Claude committed 2026-09-30 17:59:24 +00:00
1 parent e6c6073eae
commit c256c15d0e
4 files changed
+193 -1

No files matched your search

@@ -228,6 +228,10 @@ public final class EconomyHandler implements CommandExecutor, Listener {
/** {@code guild}: the proceeds go to the player's guild bank instead of their balance. */
void handleSell(Player player, String[] args, boolean guild) {
if (args.length > 0 && args[0].equalsIgnoreCase("hand")) {
if (!guild && !player.hasPermission("scopenet.command.sell.hand")) {
player.sendMessage(ChatColor.RED + "You do not have permission to use /sell hand.");
return;
}
ItemStack hand = player.getInventory().getItemInMainHand();
if (hand.getType().isAir()) {
player.sendMessage(ChatColor.RED + "You are not holding any item to sell.");
@@ -280,6 +284,10 @@ public final class EconomyHandler implements CommandExecutor, Listener {
return;
}
if (args.length >= 2 && args[0].equalsIgnoreCase("sell")) {
if (!asGuild && !player.hasPermission("scopenet.command.market.sell")) {
player.sendMessage(ChatColor.RED + "You do not have permission to list items on the market.");
return;
}
ItemStack hand = player.getInventory().getItemInMainHand();
if (hand.getType().isAir()) {
player.sendMessage(ChatColor.RED + "Hold the item you want to sell in your main hand.");
@@ -458,6 +466,10 @@ public final class EconomyHandler implements CommandExecutor, Listener {
int slot = event.getRawSlot();
Long listingId = activeMarketListings.getOrDefault(event.getInventory(), Collections.emptyMap()).get(slot);
if (listingId == null || listingId < 0) return;
if (!player.hasPermission("scopenet.command.market.buy")) {
player.sendMessage(ChatColor.RED + "You do not have permission to buy from the market.");
return;
}
JsonObject payload = new JsonObject();
payload.addProperty("listing_id", listingId);
@@ -89,6 +89,10 @@ public final class GuildHandler implements CommandExecutor, Listener {
if (cmd.equals("guild") || cmd.equals("g")) {
if (args.length == 0 || args[0].equalsIgnoreCase("info") || args[0].equalsIgnoreCase("gui")) {
if (!player.hasPermission("scopenet.command.guild.info")) {
player.sendMessage(ChatColor.RED + "You do not have permission to use /guild info.");
return true;
}
handleGuildDashboard(player);
return true;
}
@@ -100,6 +104,14 @@ public final class GuildHandler implements CommandExecutor, Listener {
player.sendMessage(ChatColor.RED + "You do not have permission to use /guild " + permission + ".");
return true;
}
// Finer nodes for the money subcommands that do several things.
String detail = args.length > 1 ? args[1].toLowerCase() : "";
String fine = (sub.equals("sell") && detail.equals("hand")) ? "sell.hand"
: (sub.equals("market") && (detail.equals("sell") || detail.equals("buy"))) ? "market." + detail : null;
if (fine != null && !player.hasPermission("scopenet.command.guild." + fine)) {
player.sendMessage(ChatColor.RED + "You do not have permission to use /guild " + sub + " " + detail + ".");
return true;
}
switch (sub) {
case "create" -> handleCreate(player, args);
case "leave" -> handleLeave(player);
@@ -20,6 +20,10 @@ public final class ScopenetCommandHandler implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (args.length == 0 || args[0].equalsIgnoreCase("help")) {
if (!sender.hasPermission("scopenet.command.scopenet.help")) {
sender.sendMessage(ChatColor.RED + "You do not have permission to view SCOPENET help.");
return true;
}
sendHelp(sender);
return true;
}
@@ -97,8 +97,12 @@ commands:
permissions:
scopenet.admin:
description: Legacy administrator permission
description: Legacy administrator permission (status, reload, claim bypass)
default: op
children:
scopenet.command.scopenet.status: true
scopenet.command.scopenet.reload: true
scopenet.claims.bypass: true
scopenet.command.scopenet:
description: Use /scopenet
default: true
@@ -171,12 +175,18 @@ permissions:
scopenet.command.unclaim:
description: Use /unclaim
default: true
scopenet.command.scopenet.help:
description: Use /scopenet help
default: true
scopenet.command.scopenet.status:
description: Use /scopenet status
default: op
scopenet.command.scopenet.reload:
description: Use /scopenet reload
default: op
scopenet.command.guild.info:
description: Open the guild dashboard (/guild, /guild info)
default: true
scopenet.command.guild.create:
description: Use /guild create
default: true
@@ -204,3 +214,157 @@ permissions:
scopenet.command.guild.members:
description: Use /guild members
default: true
scopenet.command.guild.bank:
description: View the guild bank (/guild bank)
default: true
scopenet.command.guild.bank.deposit:
description: Deposit into the guild bank
default: true
scopenet.command.guild.bank.withdraw:
description: Withdraw from the guild bank (the panel also requires officer or leader)
default: true
scopenet.command.guild.sell:
description: Sell items to the shop for the guild bank (/guild sell)
default: true
scopenet.command.guild.sell.hand:
description: Use /guild sell hand
default: true
scopenet.command.guild.market:
description: Use the market as a guild (/guild market)
default: true
scopenet.command.guild.market.sell:
description: List items on the market for the guild
default: true
scopenet.command.guild.market.buy:
description: Buy market listings with guild money
default: true
scopenet.command.guild.pay:
description: Pay another guild (/guild pay)
default: true
scopenet.command.sell.hand:
description: Use /sell hand
default: true
scopenet.command.market.sell:
description: List an item with /market sell
default: true
scopenet.command.market.buy:
description: Buy listings from the /market GUI
default: true
scopenet.claims.bypass:
description: Build and break inside other guilds' claims
default: op
scopenet.command.guild.*:
description: Every /guild subcommand
default: false
children:
scopenet.command.guild: true
scopenet.command.guild.info: true
scopenet.command.guild.create: true
scopenet.command.guild.leave: true
scopenet.command.guild.claim: true
scopenet.command.guild.unclaim: true
scopenet.command.guild.map: true
scopenet.command.guild.chat: true
scopenet.command.guild.sethome: true
scopenet.command.guild.home: true
scopenet.command.guild.members: true
scopenet.command.guild.bank: true
scopenet.command.guild.bank.deposit: true
scopenet.command.guild.bank.withdraw: true
scopenet.command.guild.sell: true
scopenet.command.guild.sell.hand: true
scopenet.command.guild.market: true
scopenet.command.guild.market.sell: true
scopenet.command.guild.market.buy: true
scopenet.command.guild.pay: true
scopenet.command.*:
description: Every SCOPENET command and subcommand, including admin ones
default: false
children:
scopenet.command.scopenet: true
scopenet.command.spawn: true
scopenet.command.home: true
scopenet.command.sethome: true
scopenet.command.delhome: true
scopenet.command.back: true
scopenet.command.tpa: true
scopenet.command.tpaccept: true
scopenet.command.tpdeny: true
scopenet.command.rtp: true
scopenet.command.warp: true
scopenet.command.playtime: true
scopenet.command.balance: true
scopenet.command.pay: true
scopenet.command.baltop: true
scopenet.command.shop: true
scopenet.command.sell: true
scopenet.command.market: true
scopenet.command.orders: true
scopenet.command.trade: true
scopenet.command.transactions: true
scopenet.command.guild: true
scopenet.command.claim: true
scopenet.command.unclaim: true
scopenet.command.scopenet.help: true
scopenet.command.scopenet.status: true
scopenet.command.scopenet.reload: true
scopenet.command.guild.info: true
scopenet.command.guild.create: true
scopenet.command.guild.leave: true
scopenet.command.guild.claim: true
scopenet.command.guild.unclaim: true
scopenet.command.guild.map: true
scopenet.command.guild.chat: true
scopenet.command.guild.sethome: true
scopenet.command.guild.home: true
scopenet.command.guild.members: true
scopenet.command.guild.bank: true
scopenet.command.guild.bank.deposit: true
scopenet.command.guild.bank.withdraw: true
scopenet.command.guild.sell: true
scopenet.command.guild.sell.hand: true
scopenet.command.guild.market: true
scopenet.command.guild.market.sell: true
scopenet.command.guild.market.buy: true
scopenet.command.guild.pay: true
scopenet.command.sell.hand: true
scopenet.command.market.sell: true
scopenet.command.market.buy: true
scopenet.command.economy.*:
description: All economy commands
default: false
children:
scopenet.command.balance: true
scopenet.command.pay: true
scopenet.command.baltop: true
scopenet.command.shop: true
scopenet.command.sell: true
scopenet.command.sell.hand: true
scopenet.command.market: true
scopenet.command.market.sell: true
scopenet.command.market.buy: true
scopenet.command.orders: true
scopenet.command.trade: true
scopenet.command.transactions: true
scopenet.command.essentials.*:
description: All teleport and utility commands
default: false
children:
scopenet.command.spawn: true
scopenet.command.home: true
scopenet.command.sethome: true
scopenet.command.delhome: true
scopenet.command.back: true
scopenet.command.tpa: true
scopenet.command.tpaccept: true
scopenet.command.tpdeny: true
scopenet.command.rtp: true
scopenet.command.warp: true
scopenet.command.playtime: true
scopenet.*:
description: Everything SCOPENET
default: false
children:
scopenet.command.*: true
scopenet.admin: true
scopenet.claims.bypass: true