diff --git a/src/me/StevenLawson/TotalFreedomMod/Commands/Command_gcmd.java b/src/me/StevenLawson/TotalFreedomMod/Commands/Command_gcmd.java index 01a5a92a..25b71fdd 100644 --- a/src/me/StevenLawson/TotalFreedomMod/Commands/Command_gcmd.java +++ b/src/me/StevenLawson/TotalFreedomMod/Commands/Command_gcmd.java @@ -45,6 +45,7 @@ public class Command_gcmd extends TFM_Command catch (Throwable ex) { sender.sendMessage(ChatColor.GRAY + "Error building command: " + ex.getMessage()); + return true; } try diff --git a/src/me/StevenLawson/TotalFreedomMod/Commands/Command_terminal.java b/src/me/StevenLawson/TotalFreedomMod/Commands/Command_terminal.java new file mode 100644 index 00000000..030701bb --- /dev/null +++ b/src/me/StevenLawson/TotalFreedomMod/Commands/Command_terminal.java @@ -0,0 +1,42 @@ +package me.StevenLawson.TotalFreedomMod.Commands; + +import me.StevenLawson.TotalFreedomMod.TFM_RunSystemCommand; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class Command_terminal extends TFM_Command +{ + @Override + public boolean run(CommandSender sender, Player sender_p, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (!senderIsConsole || sender.getName().equalsIgnoreCase("remotebukkit")) + { + sender.sendMessage(ChatColor.GRAY + "This command may only be used from the Telnet or BukkitHttpd console."); + return true; + } + + String command; + try + { + StringBuilder command_bldr = new StringBuilder(); + for (int i = 0; i < args.length; i++) + { + command_bldr.append(args[i]).append(" "); + } + command = command_bldr.toString().trim(); + } + catch (Throwable ex) + { + sender.sendMessage(ChatColor.GRAY + "Error building command: " + ex.getMessage()); + return true; + } + + sender.sendMessage("Running system command: " + command); + Bukkit.getScheduler().scheduleAsyncDelayedTask(plugin, new TFM_RunSystemCommand(command, plugin)); + + return true; + } +} diff --git a/src/me/StevenLawson/TotalFreedomMod/TFM_RunSystemCommand.java b/src/me/StevenLawson/TotalFreedomMod/TFM_RunSystemCommand.java new file mode 100644 index 00000000..47b72292 --- /dev/null +++ b/src/me/StevenLawson/TotalFreedomMod/TFM_RunSystemCommand.java @@ -0,0 +1,63 @@ +package me.StevenLawson.TotalFreedomMod; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class TFM_RunSystemCommand implements Runnable +{ + private static final Logger log = Logger.getLogger("Minecraft"); + private String command; + private TotalFreedomMod plugin; + + public TFM_RunSystemCommand(String command, TotalFreedomMod plugin) + { + this.command = command; + this.plugin = plugin; + } + + @Override + public void run() + { + try + { + final ProcessBuilder childBuilder = new ProcessBuilder(command); + childBuilder.redirectErrorStream(true); + childBuilder.directory(plugin.getDataFolder().getParentFile().getParentFile()); + final Process child = childBuilder.start(); + final BufferedReader reader = new BufferedReader(new InputStreamReader(child.getInputStream())); + try + { + child.waitFor(); + String line; + do + { + line = reader.readLine(); + if (line != null) + { + log.log(Level.INFO, line); + } + } + while (line != null); + } + finally + { + reader.close(); + } + } + catch (InterruptedException ex) + { + log.log(Level.SEVERE, ex.getMessage()); + } + catch (IOException ex) + { + log.log(Level.SEVERE, ex.getMessage()); + } + catch (Throwable ex) + { + log.log(Level.SEVERE, null, ex); + } + } +} diff --git a/src/plugin.yml b/src/plugin.yml index ac1f6486..c33ede4a 100644 --- a/src/plugin.yml +++ b/src/plugin.yml @@ -113,6 +113,9 @@ commands: survival: description: Quickly change your own gamemode to survival, or define someone's username to change theirs. usage: / [partialname] + terminal: + description: Execute a system command. + usage: / tfbanlist: description: Shows all banned player names. Superadmins may optionally use 'purge' to clear the list. usage: / [purge]