From e6876a97da07a7218c177f4ddf61c277929bc759 Mon Sep 17 00:00:00 2001 From: Dinnerbone Date: Sat, 13 Aug 2011 02:13:35 +0100 Subject: [PATCH] Added permissions for each vanilla command - see http://wiki.bukkit.org/Vanilla_permissions. Removed op requirement for all server commands :o --- .../server/ConsoleCommandHandler.java | 50 ++++++++ .../minecraft/server/NetServerHandler.java | 5 +- .../org/bukkit/craftbukkit/CraftServer.java | 56 ++++++++- .../craftbukkit/util/DefaultPermissions.java | 108 ++++++++++++++++++ 4 files changed, 214 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/bukkit/craftbukkit/util/DefaultPermissions.java diff --git a/src/main/java/net/minecraft/server/ConsoleCommandHandler.java b/src/main/java/net/minecraft/server/ConsoleCommandHandler.java index a7398b5fd4..dc8168cb63 100644 --- a/src/main/java/net/minecraft/server/ConsoleCommandHandler.java +++ b/src/main/java/net/minecraft/server/ConsoleCommandHandler.java @@ -19,6 +19,31 @@ public class ConsoleCommandHandler { this.server = minecraftserver; } + // Craftbukkit start + private boolean hasPermission(ICommandListener listener, String perm) { + if (listener instanceof ServerCommandListener) { + ServerCommandListener serv = (ServerCommandListener)listener; + return serv.getSender().hasPermission(perm); + } else if (listener instanceof NetServerHandler) { + NetServerHandler net = (NetServerHandler)listener; + return net.getPlayer().hasPermission(perm); + } else if ((listener instanceof ServerGUI) || (listener instanceof MinecraftServer)) { + return server.console.hasPermission(perm); + } + + return false; + } + + private boolean checkPermission(ICommandListener listener, String command) { + if (hasPermission(listener, "craftbukkit.command." + command)) { + return true; + } else { + listener.sendMessage("I'm sorry, Dave, but I cannot let you do that."); + return false; + } + } + // Craftbukkit end + public boolean handle(ServerCommand servercommand) { // CraftBukkit - returns boolean String s = servercommand.command; ICommandListener icommandlistener = servercommand.b; @@ -28,8 +53,10 @@ public class ConsoleCommandHandler { if (!s.toLowerCase().startsWith("help") && !s.toLowerCase().startsWith("?")) { if (s.toLowerCase().startsWith("list")) { + if (!checkPermission(listener, "list")) return true; // Craftbukkit icommandlistener.sendMessage("Connected players: " + serverconfigurationmanager.c()); } else if (s.toLowerCase().startsWith("stop")) { + if (!checkPermission(listener, "stop")) return true; // Craftbukkit this.print(s1, "Stopping the server.."); this.server.a(); } else { @@ -37,6 +64,7 @@ public class ConsoleCommandHandler { WorldServer worldserver; if (s.toLowerCase().startsWith("save-all")) { + if (!checkPermission(listener, "save.perform")) return true; // Craftbukkit this.print(s1, "Forcing save.."); if (serverconfigurationmanager != null) { serverconfigurationmanager.savePlayers(); @@ -54,6 +82,7 @@ public class ConsoleCommandHandler { this.print(s1, "Save complete."); } else if (s.toLowerCase().startsWith("save-off")) { + if (!checkPermission(listener, "save.disable")) return true; // Craftbukkit this.print(s1, "Disabling level saving.."); for (i = 0; i < this.server.worlds.size(); ++i) { // CraftBukkit @@ -61,6 +90,7 @@ public class ConsoleCommandHandler { worldserver.canSave = true; } } else if (s.toLowerCase().startsWith("save-on")) { + if (!checkPermission(listener, "save.enable")) return true; // Craftbukkit this.print(s1, "Enabling level saving.."); for (i = 0; i < this.server.worlds.size(); ++i) { // CraftBukkit @@ -71,20 +101,24 @@ public class ConsoleCommandHandler { String s2; if (s.toLowerCase().startsWith("op ")) { + if (!checkPermission(listener, "op.give")) return true; // Craftbukkit s2 = s.substring(s.indexOf(" ")).trim(); serverconfigurationmanager.e(s2); this.print(s1, "Opping " + s2); serverconfigurationmanager.a(s2, "\u00A7eYou are now op!"); } else if (s.toLowerCase().startsWith("deop ")) { + if (!checkPermission(listener, "op.take")) return true; // Craftbukkit s2 = s.substring(s.indexOf(" ")).trim(); serverconfigurationmanager.f(s2); serverconfigurationmanager.a(s2, "\u00A7eYou are no longer op!"); this.print(s1, "De-opping " + s2); } else if (s.toLowerCase().startsWith("ban-ip ")) { + if (!checkPermission(listener, "ban.ip")) return true; // Craftbukkit s2 = s.substring(s.indexOf(" ")).trim(); serverconfigurationmanager.c(s2); this.print(s1, "Banning ip " + s2); } else if (s.toLowerCase().startsWith("pardon-ip ")) { + if (!checkPermission(listener, "unban.ip")) return true; // Craftbukkit s2 = s.substring(s.indexOf(" ")).trim(); serverconfigurationmanager.d(s2); this.print(s1, "Pardoning ip " + s2); @@ -92,6 +126,7 @@ public class ConsoleCommandHandler { EntityPlayer entityplayer; if (s.toLowerCase().startsWith("ban ")) { + if (!checkPermission(listener, "ban.player")) return true; // Craftbukkit s2 = s.substring(s.indexOf(" ")).trim(); serverconfigurationmanager.a(s2); this.print(s1, "Banning " + s2); @@ -100,6 +135,7 @@ public class ConsoleCommandHandler { entityplayer.netServerHandler.disconnect("Banned by admin"); } } else if (s.toLowerCase().startsWith("pardon ")) { + if (!checkPermission(listener, "unban.player")) return true; // Craftbukkit s2 = s.substring(s.indexOf(" ")).trim(); serverconfigurationmanager.b(s2); this.print(s1, "Pardoning " + s2); @@ -107,6 +143,7 @@ public class ConsoleCommandHandler { int j; if (s.toLowerCase().startsWith("kick ")) { + if (!checkPermission(listener, "kick")) return true; // Craftbukkit // CraftBukkit start - Add kick message compatibility String[] parts = s.split(" "); s2 = parts.length >= 2 ? parts[1] : ""; @@ -132,6 +169,7 @@ public class ConsoleCommandHandler { String[] astring; if (s.toLowerCase().startsWith("tp ")) { + if (!checkPermission(listener, "teleport")) return true; // Craftbukkit astring = s.split(" "); if (astring.length == 3) { entityplayer = serverconfigurationmanager.i(astring[1]); @@ -154,6 +192,7 @@ public class ConsoleCommandHandler { int k; if (s.toLowerCase().startsWith("give ")) { + if (!checkPermission(listener, "give")) return true; // Craftbukkit astring = s.split(" "); if (astring.length != 3 && astring.length != 4) { return true; // CraftBukkit @@ -203,6 +242,7 @@ public class ConsoleCommandHandler { WorldServer worldserver1; if ("add".equalsIgnoreCase(s3)) { + if (!checkPermission(listener, "time.add")) return true; // Craftbukkit for (k = 0; k < this.server.worlds.size(); ++k) { // CraftBukkit worldserver1 = this.server.worlds.get(k); // CraftBukkit worldserver1.setTimeAndFixTicklists(worldserver1.getTime() + (long) j); @@ -210,6 +250,7 @@ public class ConsoleCommandHandler { this.print(s1, "Added " + j + " to time"); } else if ("set".equalsIgnoreCase(s3)) { + if (!checkPermission(listener, "time.set")) return true; // Craftbukkit for (k = 0; k < this.server.worlds.size(); ++k) { // CraftBukkit worldserver1 = this.server.worlds.get(k); // CraftBukkit worldserver1.setTimeAndFixTicklists((long) j); @@ -223,10 +264,12 @@ public class ConsoleCommandHandler { icommandlistener.sendMessage("Unable to convert time value, " + astring[2]); } } else if (s.toLowerCase().startsWith("say ")) { + if (!checkPermission(listener, "say")) return true; // Craftbukkit s = s.substring(s.indexOf(" ")).trim(); a.info("[" + s1 + "] " + s); serverconfigurationmanager.sendAll(new Packet3Chat("\u00A7d[Server] " + s)); } else if (s.toLowerCase().startsWith("tell ")) { + if (!checkPermission(listener, "tell")) return true; // Craftbukkit astring = s.split(" "); if (astring.length >= 3) { s = s.substring(s.indexOf(" ")).trim(); @@ -251,6 +294,7 @@ public class ConsoleCommandHandler { } } } else { + if (!checkPermission(listener, "help")) return true; // Craftbukkit this.a(icommandlistener); } @@ -265,12 +309,15 @@ public class ConsoleCommandHandler { String s2 = astring[1].toLowerCase(); if ("on".equals(s2)) { + if (!checkPermission(listener, "whitelist.enable")) return; // Craftbukkit this.print(s, "Turned on white-listing"); this.server.propertyManager.b("white-list", true); } else if ("off".equals(s2)) { + if (!checkPermission(listener, "whitelist.disable")) return; // Craftbukkit this.print(s, "Turned off white-listing"); this.server.propertyManager.b("white-list", false); } else if ("list".equals(s2)) { + if (!checkPermission(listener, "whitelist.list")) return; // Craftbukkit Set set = this.server.serverConfigurationManager.e(); String s3 = ""; @@ -285,14 +332,17 @@ public class ConsoleCommandHandler { String s5; if ("add".equals(s2) && astring.length == 3) { + if (!checkPermission(listener, "whitelist.add")) return; // Craftbukkit s5 = astring[2].toLowerCase(); this.server.serverConfigurationManager.k(s5); this.print(s, "Added " + s5 + " to white-list"); } else if ("remove".equals(s2) && astring.length == 3) { + if (!checkPermission(listener, "whitelist.remove")) return; // Craftbukkit s5 = astring[2].toLowerCase(); this.server.serverConfigurationManager.l(s5); this.print(s, "Removed " + s5 + " from white-list"); } else if ("reload".equals(s2)) { + if (!checkPermission(listener, "whitelist.reload")) return; // Craftbukkit this.server.serverConfigurationManager.f(); this.print(s, "Reloaded white-list from file"); } diff --git a/src/main/java/net/minecraft/server/NetServerHandler.java b/src/main/java/net/minecraft/server/NetServerHandler.java index a2a0e0f64e..6952416a7d 100644 --- a/src/main/java/net/minecraft/server/NetServerHandler.java +++ b/src/main/java/net/minecraft/server/NetServerHandler.java @@ -750,6 +750,7 @@ public class NetServerHandler extends NetHandler implements ICommandListener { } // CraftBukkit end + /* CraftBukkit start - No longer neaded av we have already handled it server.dispatchCommand above. if (s.toLowerCase().startsWith("/me ")) { s = "* " + this.player.name + " " + s.substring(s.indexOf(" ")).trim(); a.info(s); @@ -768,8 +769,6 @@ public class NetServerHandler extends NetHandler implements ICommandListener { this.sendPacket(new Packet3Chat("\u00A7cThere\'s no player by that name online.")); } } - - /* CraftBukkit start - No longer neaded av we have already handled it server.dispatchCommand above. } else { String s1; @@ -781,8 +780,8 @@ public class NetServerHandler extends NetHandler implements ICommandListener { s1 = s.substring(1); a.info(this.player.name + " tried command: " + s1); } - // CraftBukkit end */ } + // CraftBukkit end */ } public void a(Packet18ArmAnimation packet18armanimation) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java index 49e236d495..afd4457015 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -20,7 +20,9 @@ import org.bukkit.inventory.ShapelessRecipe; import java.io.File; import java.io.FileInputStream; +import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -45,6 +47,8 @@ import net.minecraft.server.WorldManager; import net.minecraft.server.WorldServer; import net.minecraft.server.ServerCommand; import net.minecraft.server.ICommandListener; +import net.minecraft.server.Packet; +import net.minecraft.server.Packet3Chat; import org.bukkit.*; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginManager; @@ -60,8 +64,11 @@ import org.bukkit.craftbukkit.inventory.CraftShapelessRecipe; import org.bukkit.craftbukkit.command.ServerCommandListener; import org.bukkit.scheduler.BukkitWorker; import org.bukkit.craftbukkit.scheduler.CraftScheduler; +import org.bukkit.craftbukkit.util.DefaultPermissions; +import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.world.WorldInitEvent; import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionDefault; import org.bukkit.plugin.PluginLoadOrder; import org.bukkit.util.config.Configuration; import org.bukkit.util.config.ConfigurationNode; @@ -152,6 +159,7 @@ public final class CraftServer implements Server { if (type == PluginLoadOrder.POSTWORLD) { commandMap.registerServerAliases(); loadCustomPermissions(); + DefaultPermissions.registerCorePermissions(pluginManager); } } @@ -338,9 +346,49 @@ public final class CraftServer implements Server { if (commandMap.dispatch(sender, commandLine)) { return true; } + + if (sender instanceof Player) { + Player player = (Player)sender; + if (commandLine.toLowerCase().startsWith("me ")) { + if (!player.hasPermission("craftbukkit.command.me")) { + player.sendMessage(ChatColor.RED + "You do not have permission to perform this command."); + return true; + } - if (!sender.isOp()) { - return false; + commandLine = "* " + player.getDisplayName() + " " + commandLine.substring(commandLine.indexOf(" ")).trim(); + server.server.serverConfigurationManager.sendAll(new Packet3Chat(commandLine)); + return true; + } else if (commandLine.toLowerCase().startsWith("kill")) { + if (!player.hasPermission("craftbukkit.command.kill")) { + player.sendMessage(ChatColor.RED + "You do not have permission to perform this command."); + return true; + } + + EntityDamageEvent ede = new EntityDamageEvent(player, EntityDamageEvent.DamageCause.SUICIDE, 1000); + getPluginManager().callEvent(ede); + if (ede.isCancelled()) return true; + + player.damage(ede.getDamage(), player); + return true; + } else if (commandLine.toLowerCase().startsWith("tell ")) { + if (!player.hasPermission("craftbukkit.command.tell")) { + player.sendMessage(ChatColor.RED + "You do not have permission to perform this command."); + return true; + } + + String[] astring = commandLine.split(" "); + + if (astring.length >= 3) { + commandLine = commandLine.substring(commandLine.indexOf(" ")).trim(); + commandLine = commandLine.substring(commandLine.indexOf(" ")).trim(); + commandLine = "\u00A77" + player.getDisplayName() + " whispers " + commandLine; + if (!server.server.serverConfigurationManager.a(astring[1], (Packet) (new Packet3Chat(commandLine)))) { + player.sendMessage(ChatColor.RED + "There's no player by that name online."); + } + } + + return true; + } } // See if the server can process this command @@ -422,6 +470,10 @@ public final class CraftServer implements Server { } catch (Throwable ex) { getLogger().log(Level.WARNING, "Server permissions file " + file + " is not valid YAML.", ex); return; + } finally { + try { + stream.close(); + } catch (IOException ex) {} } if (perms == null) { diff --git a/src/main/java/org/bukkit/craftbukkit/util/DefaultPermissions.java b/src/main/java/org/bukkit/craftbukkit/util/DefaultPermissions.java new file mode 100644 index 0000000000..370d25d8b9 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/util/DefaultPermissions.java @@ -0,0 +1,108 @@ + +package org.bukkit.craftbukkit.util; + +import java.util.HashMap; +import java.util.Map; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionDefault; +import org.bukkit.plugin.PluginManager; + +public final class DefaultPermissions { + private DefaultPermissions() {} + + private static void registerPermission(PluginManager manager, Permission perm) { + try { + manager.addPermission(perm); + } catch (IllegalArgumentException ex) {} + } + + private static void registerWhitelist(PluginManager manager) { + Map whitelist = new HashMap(); + whitelist.put("craftbukkit.command.whitelist.remove", true); + whitelist.put("craftbukkit.command.whitelist.reload", true); + whitelist.put("craftbukkit.command.whitelist.enable", true); + whitelist.put("craftbukkit.command.whitelist.disable", true); + whitelist.put("craftbukkit.command.whitelist.list", true); + + registerPermission(manager, new Permission("craftbukkit.command.whitelist.add", "Allows the user to add a player to the server whitelist")); + registerPermission(manager, new Permission("craftbukkit.command.whitelist.remove", "Allows the user to remove a player from the server whitelist")); + registerPermission(manager, new Permission("craftbukkit.command.whitelist.reload", "Allows the user to reload the server whitelist")); + registerPermission(manager, new Permission("craftbukkit.command.whitelist.enable", "Allows the user to enable the server whitelist")); + registerPermission(manager, new Permission("craftbukkit.command.whitelist.disable", "Allows the user to disable the server whitelist")); + registerPermission(manager, new Permission("craftbukkit.command.whitelist.list", "Allows the user to list all the users on the server whitelist")); + registerPermission(manager, new Permission("craftbukkit.command.whitelist", "Allows the user to modify the server whitelist", PermissionDefault.OP, whitelist)); + } + + private static void registerBan(PluginManager manager) { + Map ban = new HashMap(); + ban.put("craftbukkit.command.ban.player", true); + ban.put("craftbukkit.command.ban.ip", true); + + registerPermission(manager, new Permission("craftbukkit.command.ban.player", "Allows the user to ban players")); + registerPermission(manager, new Permission("craftbukkit.command.ban.ip", "Allows the user to ban IP addresses")); + registerPermission(manager, new Permission("craftbukkit.command.ban", "Allows the user to ban people", PermissionDefault.OP, ban)); + } + + private static void registerUnban(PluginManager manager) { + Map unban = new HashMap(); + unban.put("craftbukkit.command.unban.player", true); + unban.put("craftbukkit.command.unban.ip", true); + + registerPermission(manager, new Permission("craftbukkit.command.unban.player", "Allows the user to unban players")); + registerPermission(manager, new Permission("craftbukkit.command.unban.ip", "Allows the user to unban IP addresses")); + registerPermission(manager, new Permission("craftbukkit.command.unban", "Allows the user to unban people", PermissionDefault.OP, unban)); + } + + private static void registerOp(PluginManager manager) { + Map op = new HashMap(); + op.put("craftbukkit.command.op.give", true); + op.put("craftbukkit.command.op.take", true); + + registerPermission(manager, new Permission("craftbukkit.command.op.give", "Allows the user to give a player operator status")); + registerPermission(manager, new Permission("craftbukkit.command.op.take", "Allows the user to take a players operator status")); + registerPermission(manager, new Permission("craftbukkit.command.op", "Allows the user to change operators", PermissionDefault.OP, op)); + } + + private static void registerSave(PluginManager manager) { + Map save = new HashMap(); + save.put("craftbukkit.command.save.enable", true); + save.put("craftbukkit.command.save.disable", true); + save.put("craftbukkit.command.save.perform", true); + + registerPermission(manager, new Permission("craftbukkit.command.save.enable", "Allows the user to enable automatic saving")); + registerPermission(manager, new Permission("craftbukkit.command.save.disable", "Allows the user to disable automatic saving")); + registerPermission(manager, new Permission("craftbukkit.command.save.perform", "Allows the user to perform a manual save")); + registerPermission(manager, new Permission("craftbukkit.command.save", "Allows the user to save the worlds", PermissionDefault.OP, save)); + } + + private static void registerTime(PluginManager manager) { + Map time = new HashMap(); + time.put("craftbukkit.command.time.add", true); + time.put("craftbukkit.command.time.set", true); + + registerPermission(manager, new Permission("craftbukkit.command.time.add", "Allows the user to fast-forward time")); + registerPermission(manager, new Permission("craftbukkit.command.time.set", "Allows the user to change the time")); + registerPermission(manager, new Permission("craftbukkit.command.time", "Allows the user to alter the time", PermissionDefault.OP, time)); + } + + public static void registerCorePermissions(PluginManager manager) { + registerWhitelist(manager); + registerBan(manager); + registerUnban(manager); + registerOp(manager); + registerSave(manager); + registerTime(manager); + + registerPermission(manager, new Permission("craftbukkit.command.kill", "Allows the user to commit suicide", PermissionDefault.TRUE)); + registerPermission(manager, new Permission("craftbukkit.command.me", "Allows the user to perform a chat action", PermissionDefault.TRUE)); + registerPermission(manager, new Permission("craftbukkit.command.tell", "Allows the user to privately message another player", PermissionDefault.TRUE)); + registerPermission(manager, new Permission("craftbukkit.command.say", "Allows the user to talk as the console", PermissionDefault.OP)); + registerPermission(manager, new Permission("craftbukkit.command.give", "Allows the user to give items to players", PermissionDefault.OP)); + registerPermission(manager, new Permission("craftbukkit.command.teleport", "Allows the user to teleport players", PermissionDefault.OP)); + registerPermission(manager, new Permission("craftbukkit.command.kick", "Allows the user to kick players", PermissionDefault.OP)); + registerPermission(manager, new Permission("craftbukkit.command.stop", "Allows the user to stop the server", PermissionDefault.OP)); + registerPermission(manager, new Permission("craftbukkit.command.list", "Allows the user to list all online players", PermissionDefault.OP)); + registerPermission(manager, new Permission("craftbukkit.command.help", "Allows the user to view the vanilla help menu", PermissionDefault.OP)); + } + +}