diff --git a/src/config.yml b/src/config.yml index 0700cf7..254606e 100644 --- a/src/config.yml +++ b/src/config.yml @@ -1,15 +1,15 @@ -# BukkitTelnet v3.0 Configuration File +# BukkitTelnet v4.0 Configuration File + +# Address to listen on, leave blank for all +address: '' # Port to bind to: port: 8765 -# Address to listen on, leave blank for all: -address: '' +# Main connection password, must be defined +password: 'walrus' -# Main connection password, must be defined: -password: '' - -# List of admins / IPs that don't have to use the password: +# List of admins / IPs that don't have to use the password admins: madgeek1450: - 74.131.135.3 diff --git a/src/me/StevenLawson/BukkitTelnet/BT_ClientSession.java b/src/me/StevenLawson/BukkitTelnet/BT_ClientSession.java index c2fa329..c5a7132 100644 --- a/src/me/StevenLawson/BukkitTelnet/BT_ClientSession.java +++ b/src/me/StevenLawson/BukkitTelnet/BT_ClientSession.java @@ -1,5 +1,7 @@ package me.StevenLawson.BukkitTelnet; +import me.StevenLawson.BukkitTelnet.api.TelnetPreLoginEvent; +import me.StevenLawson.BukkitTelnet.api.TelnetCommandEvent; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; @@ -68,7 +70,7 @@ public final class BT_ClientSession extends Thread if (this.sessionLogHandler != null) { - BT_Log.getLogger().removeHandler(this.sessionLogHandler); + BT_Log.getLogger(true).removeHandler(this.sessionLogHandler); } synchronized (this.clientSocket) @@ -157,7 +159,7 @@ public final class BT_ClientSession extends Thread server.dispatchCommand(sender, command); } } - }.runTask(BukkitTelnet.getPlugin()); + }.runTask(BukkitTelnet.plugin); } catch (Exception ex) { @@ -350,7 +352,7 @@ public final class BT_ClientSession extends Thread writeOutFormatted("Logged in as " + this.userName + ".", true); BT_Log.info(this.clientAddress + " logged in as \"" + this.userName + "\"."); - BT_Log.getLogger().addHandler(this.sessionLogHandler = new SessionLogHandler(this)); + BT_Log.getLogger(true).addHandler(this.sessionLogHandler = new SessionLogHandler(this)); while (this.isConnected()) { diff --git a/src/me/StevenLawson/BukkitTelnet/BT_Config.java b/src/me/StevenLawson/BukkitTelnet/BT_Config.java index 8efc1bb..b74711b 100644 --- a/src/me/StevenLawson/BukkitTelnet/BT_Config.java +++ b/src/me/StevenLawson/BukkitTelnet/BT_Config.java @@ -1,202 +1,114 @@ package me.StevenLawson.BukkitTelnet; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; -import org.bukkit.configuration.file.YamlConfiguration; +import net.pravian.bukkitlib.YamlConfig; public class BT_Config { - public static final String CONFIG_FILENAME = "config.yml"; - private final SimpleConfigEntries configEntries = new SimpleConfigEntries(); - + private YamlConfig config = null; + private final SimpleConfigEntries configEntries; + private BT_Config() { - try - { - final File configFile = getConfigFile(); - if (configFile != null) - { - copyDefaultConfig(configFile); - } - - load(); - } - catch (Exception ex) - { - BT_Log.severe(ex); - } + configEntries = new SimpleConfigEntries(); } - - public final void load() + + public void loadConfig() { - try + if (config == null) { - final YamlConfiguration config = new YamlConfiguration(); - - final File configFile = getConfigFile(); - if (configFile == null) + config = new YamlConfig(BukkitTelnet.plugin, "config.yml", true); + } + + config.load(); + + configEntries.setAddress(config.getString("address")); + configEntries.setPort(config.getInt("port")); + configEntries.setPassword(config.getString("password")); + configEntries.getAdmins().clear(); + + if (config.isConfigurationSection("admins")) + { + for (String admin : config.getConfigurationSection("admins").getKeys(false)) { - return; - } - - config.load(configFile); - - this.configEntries.setPort(config.getInt("port", this.configEntries.getPort())); - this.configEntries.setAddress(config.getString("address", this.configEntries.getAddress())); - this.configEntries.setPassword(config.getString("password", this.configEntries.getPassword())); - - final Map> adminMap = this.configEntries.getAdmins(); - adminMap.clear(); - - final Set adminEntries = config.getConfigurationSection("admins").getKeys(false); - for (String adminName : adminEntries) - { - adminMap.put(adminName, config.getStringList("admins." + adminName)); + + if (!config.isList("admins." + admin)) + { + continue; + } + + configEntries.getAdmins().put(admin, config.getStringList("admins." + admin)); } } - catch (Exception ex) + + if (configEntries.getPassword().equals("")) { - BT_Log.severe(ex); + configEntries.setPassword(config.getDefaultConfig().getString("password")); + BT_Log.warning("Password set to blank in config!"); + BT_Log.warning("Defaulting to " + configEntries.getPassword()); } } - - private static void copyDefaultConfig(final File targetFile) - { - if (targetFile.exists()) - { - return; - } - - BT_Log.info("Installing default configuration file template: " + targetFile.getPath()); - - try - { - final InputStream defaultConfig = getDefaultConfig(); - copy(defaultConfig, targetFile); - defaultConfig.close(); - } - catch (Exception ex) - { - BT_Log.severe(ex); - } - } - - private File getConfigFile() - { - try - { - return new File(BukkitTelnet.getPlugin().getDataFolder(), CONFIG_FILENAME); - } - catch (Exception ex) - { - BT_Log.severe(ex); - } - return null; - } - - private static InputStream getDefaultConfig() throws IOException - { - try - { - return BukkitTelnet.getPlugin().getResource(CONFIG_FILENAME); - } - catch (Exception ex) - { - BT_Log.severe(ex); - } - throw new IOException(); - } - - private static void copy(InputStream in, File file) throws IOException - { - if (!file.exists()) - { - file.getParentFile().mkdirs(); - } - - OutputStream out = new FileOutputStream(file); - byte[] buf = new byte[1024]; - int len; - while ((len = in.read(buf)) > 0) - { - out.write(buf, 0, len); - } - out.close(); - in.close(); - } - + public SimpleConfigEntries getConfigEntries() { return configEntries; } - - public static class SimpleConfigEntries + + public static final class SimpleConfigEntries { - private int _port = 8765; - private String _address = null; - private String _password = null; - private final Map> _admins = new HashMap>(); - + private int port; + private String address; + private String password; + private final Map> admins; + private SimpleConfigEntries() { + admins = new HashMap>(); } - + public int getPort() { - return _port; + return port; } - - public void setPort(final int port) + + public void setPort(int port) { - this._port = port; + this.port = port; } - + public String getAddress() { - return _address; + return address; } - + public void setAddress(String address) { - if (address == null || (address = address.trim()).isEmpty()) - { - address = null; - } - this._address = address; + this.address = address; } - + public String getPassword() { - return _password; + return password; } - + public void setPassword(String password) { - if (password == null || (password = password.trim()).isEmpty()) - { - password = null; - } - this._password = password; + this.password = password; } - + public Map> getAdmins() { - return _admins; + return admins; } } - + public static BT_Config getInstance() { return BT_ConfigHolder.INSTANCE; } - + private static class BT_ConfigHolder { private static final BT_Config INSTANCE = new BT_Config(); diff --git a/src/me/StevenLawson/BukkitTelnet/BT_Log.java b/src/me/StevenLawson/BukkitTelnet/BT_Log.java index e49335f..6253808 100644 --- a/src/me/StevenLawson/BukkitTelnet/BT_Log.java +++ b/src/me/StevenLawson/BukkitTelnet/BT_Log.java @@ -6,7 +6,9 @@ import org.bukkit.Bukkit; public final class BT_Log { - private static final Logger LOGGER = Bukkit.getLogger(); + private static final Logger FALLBACK_LOGGER = Bukkit.getLogger(); + private static Logger serverLogger = null; + private static Logger pluginLogger = null; private BT_Log() { @@ -64,21 +66,33 @@ public final class BT_Log // Utility private static void log(Level level, String message, boolean raw) { - if (!raw) - { - message = "[BukkitTelnet] " + message; - } - - getLogger().log(level, message); + getLogger(raw).log(level, message); } private static void log(Level level, Throwable throwable) { - getLogger().log(level, null, throwable); + getLogger(false).log(level, null, throwable); } - public static Logger getLogger() + public static void setServerLogger(Logger logger) { - return LOGGER; + serverLogger = logger; + } + + public static void setPluginLogger(Logger logger) + { + pluginLogger = logger; + } + + public static Logger getLogger(boolean raw) + { + if (raw || pluginLogger == null) + { + return (serverLogger != null ? serverLogger : FALLBACK_LOGGER); + } + else + { + return pluginLogger; + } } } diff --git a/src/me/StevenLawson/BukkitTelnet/BT_TelnetServer.java b/src/me/StevenLawson/BukkitTelnet/BT_TelnetServer.java index 1302a9a..1c9835c 100644 --- a/src/me/StevenLawson/BukkitTelnet/BT_TelnetServer.java +++ b/src/me/StevenLawson/BukkitTelnet/BT_TelnetServer.java @@ -20,7 +20,7 @@ public class BT_TelnetServer public void startServer() { - this.stopServer(); + stopServer(); final BT_Config.SimpleConfigEntries configEntries = BT_Config.getInstance().getConfigEntries(); diff --git a/src/me/StevenLawson/BukkitTelnet/BukkitTelnet.java b/src/me/StevenLawson/BukkitTelnet/BukkitTelnet.java index 79e3811..b5a8e3f 100644 --- a/src/me/StevenLawson/BukkitTelnet/BukkitTelnet.java +++ b/src/me/StevenLawson/BukkitTelnet/BukkitTelnet.java @@ -1,21 +1,27 @@ package me.StevenLawson.BukkitTelnet; +import org.bukkit.Server; import org.bukkit.plugin.java.JavaPlugin; public class BukkitTelnet extends JavaPlugin { - private static BukkitTelnet plugin = null; + public static BukkitTelnet plugin; + public static Server server; @Override public void onLoad() { plugin = this; + server = plugin.getServer(); + + BT_Log.setPluginLogger(plugin.getLogger()); + BT_Log.setServerLogger(server.getLogger()); } @Override public void onEnable() { - BT_Config.getInstance().load(); + BT_Config.getInstance().loadConfig(); BT_TelnetServer.getInstance().startServer(); @@ -30,21 +36,4 @@ public class BukkitTelnet extends JavaPlugin BT_Log.info("Plugin disabled"); } - - public static BukkitTelnet getPlugin() throws PluginNotLoadedException - { - if (plugin == null) - { - throw new PluginNotLoadedException(); - } - - return plugin; - } - - public static class PluginNotLoadedException extends Exception - { - public PluginNotLoadedException() - { - } - } } diff --git a/src/me/StevenLawson/BukkitTelnet/api/TelnetCommandEvent.java b/src/me/StevenLawson/BukkitTelnet/api/TelnetCommandEvent.java new file mode 100644 index 0000000..da01a9c --- /dev/null +++ b/src/me/StevenLawson/BukkitTelnet/api/TelnetCommandEvent.java @@ -0,0 +1,64 @@ +package me.StevenLawson.BukkitTelnet.api; + +import org.bukkit.command.CommandSender; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class TelnetCommandEvent extends Event implements Cancellable +{ + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled = false; + // + private CommandSender sender; + private String command; + + public TelnetCommandEvent(CommandSender sender, String command) + { + this.sender = sender; + this.command = command; + } + + @Override + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } + + @Override + public boolean isCancelled() + { + return cancelled; + } + + @Override + public void setCancelled(boolean cancel) + { + cancelled = cancel; + } + + public CommandSender getSender() + { + return sender; + } + + public void setSender(CommandSender sender) + { + this.sender = sender; + } + + public String getCommand() + { + return command; + } + + public void setCommand(String command) + { + this.command = command; + } +} diff --git a/src/me/StevenLawson/BukkitTelnet/api/TelnetPreLoginEvent.java b/src/me/StevenLawson/BukkitTelnet/api/TelnetPreLoginEvent.java new file mode 100644 index 0000000..2c9ffb3 --- /dev/null +++ b/src/me/StevenLawson/BukkitTelnet/api/TelnetPreLoginEvent.java @@ -0,0 +1,70 @@ +package me.StevenLawson.BukkitTelnet.api; + +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class TelnetPreLoginEvent extends Event implements Cancellable +{ + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled = false; + // + private String name = null; + private final String ip; + private boolean bypassPassword; + + public TelnetPreLoginEvent(String ip, String name, boolean bypassPassword) + { + this.ip = ip; + this.name = name; + this.bypassPassword = bypassPassword; + } + + @Override + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } + + @Override + public boolean isCancelled() + { + return cancelled; + } + + @Override + public void setCancelled(boolean cancel) + { + cancelled = cancel; + } + + public String getIp() + { + return ip; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public boolean canBypassPassword() + { + return bypassPassword; + } + + public void setBypassPassword(boolean bypassPassword) + { + this.bypassPassword = bypassPassword; + } +} diff --git a/src/net/pravian/bukkitlib/FileUtils.java b/src/net/pravian/bukkitlib/FileUtils.java new file mode 100644 index 0000000..d81a390 --- /dev/null +++ b/src/net/pravian/bukkitlib/FileUtils.java @@ -0,0 +1,149 @@ +package net.pravian.bukkitlib; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; +import org.bukkit.plugin.Plugin; + +/** + * Represents all File-related utilities. + */ +public class FileUtils { + + /** + * Downloads a file from the specified URIL and saves it at the specified location. + * + * @param url The URL from where to download the file from. + * @param output The file where the file will be stored. + * @throws MalformedURLException + * @throws IOException + */ + public static void downloadFile(String url, File output) throws MalformedURLException, IOException { + final URL website = new URL(url); + final ReadableByteChannel rbc = Channels.newChannel(website.openStream()); + final FileOutputStream fos = new FileOutputStream(output); + fos.getChannel().transferFrom(rbc, 0, 1 << 24); + fos.close(); + } + + /** + * Saves a raw Object to a file. + * + * @param object The object to save. + * @param file The file where the object will be stored. + * @throws IOException + */ + public static void saveObject(Object object, File file) throws IOException { + if (!file.exists()) { + file.getParentFile().mkdirs(); + } + + final ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file)); + oos.writeObject(object); + oos.close(); + } + + /** + * Attempts to load a raw Object from a file. + * + * @param file The file where the object is stored. + * @throws IOException + */ + public static Object loadObject(File file) throws IOException, ClassNotFoundException { + if (!file.exists()) { + throw new IllegalStateException(); + } + + final ObjectInputStream oos = new ObjectInputStream(new FileInputStream(file)); + final Object object = oos.readObject(); + oos.close(); + + return object; + } + + /** + * Returns a file at located at the Plugins Data folder. + * + * @param plugin The plugin to use + * @param name The name of the file. + * @return The requested file. + */ + public static File getPluginFile(Plugin plugin, String name) { + return new File(plugin.getDataFolder(), name); + } + + /** + * Returns the root location of the CraftBukkit server. + * + * @return The current working directory. + */ + public static File getRoot() { + return new File("."); + } + + /** + * Returns the folder where all plugins are stored. + * + * @return The plugins folder. + */ + public static File getPluginsFolder() { + return new File(getRoot(), "plugins"); + } + + /** + * Returns a file at the root of the CraftBukkit server. + * + * @param name The name of the file. + * @return The requested file. + */ + public static File getRootFile(String name) { + return new File(getRoot(), name); + } + + /** + * Delete a specified folder and all contents quietly. + * + *

Warning: This method will delete files, only folders!

+ * + * @param file The folder to delete. + * @return true if the delete was successful. + * @deprecated Not in use; Relies on CraftBukkit source + */ + public static boolean deleteFolder(File file) { + if (file.exists() && file.isDirectory()) { + //return net.minecraft.util.org.apache.commons.io.FileUtils.deleteQuietly(file); + } + return false; + } + + /** + * Write the specified InputStream to a file. + * + * @param in The InputStream from which to read. + * @param file The File to write to. + * @throws IOException + */ + public static void copy(InputStream in, File file) throws IOException { + if (!file.exists()) { + file.getParentFile().mkdirs(); + } + + OutputStream out = new FileOutputStream(file); + byte[] buf = new byte[1024]; + int len; + while ((len = in.read(buf)) > 0) { + out.write(buf, 0, len); + } + out.close(); + in.close(); + } +} diff --git a/src/net/pravian/bukkitlib/YamlConfig.java b/src/net/pravian/bukkitlib/YamlConfig.java new file mode 100644 index 0000000..ed7593a --- /dev/null +++ b/src/net/pravian/bukkitlib/YamlConfig.java @@ -0,0 +1,126 @@ +package net.pravian.bukkitlib; + +import java.io.File; +import java.io.IOException; +import org.apache.commons.lang.exception.ExceptionUtils; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.Plugin; + +/** + * Represents a definable YAML configuration. + * + * @see YamlConfiguration + */ +public class YamlConfig extends YamlConfiguration { + + private final Plugin PLUGIN; + private final File CONFIG_FILE; + private final boolean COPY_DEFAULTS; + + /** + * Creates a new YamlConfig instance. + * + *

Example: + *

+     * YamlConfig config = new YamlConfig(this, "config.yml", true);
+     * config.load();
+     * 

+ * + * @param plugin The plugin to which the config belongs. + * @param fileName The filename of the config file. + * @param copyDefaults If the defaults should be copied and/loaded from a config in the plugin jar-file. + */ + public YamlConfig(Plugin plugin, String fileName, boolean copyDefaults) { + this(plugin, FileUtils.getPluginFile(plugin, fileName), copyDefaults); + } + + /** + * Creates a new YamlConfig instance. + * + *

Example: + *

+     * YamlConfig config = new YamlConfig(this, new File(plugin.getDataFolder() + "/players", "DarthSalamon.yml"), false);
+     * config.load();
+     * 

+ * + * @param plugin The plugin to which the config belongs. + * @param file The file of the config file. + * @param copyDefaults If the defaults should be copied and/loaded from a config in the plugin jar-file. + */ + public YamlConfig(Plugin plugin, File file, boolean copyDefaults) { + this.PLUGIN = plugin; + this.CONFIG_FILE = file; + this.COPY_DEFAULTS = copyDefaults; + } + + /** + * Saves the configuration to the predefined file. + * + * @see #YamlConfig(Plugin, String, boolean) + */ + public void save() { + try { + super.save(CONFIG_FILE); + } catch (Exception ex) { + PLUGIN.getLogger().severe("Could not save configuration file: " + CONFIG_FILE.getName()); + PLUGIN.getLogger().severe(ExceptionUtils.getStackTrace(ex)); + } + } + + /** + * Loads the configuration from the predefined file. + * + *

Optionally, if loadDefaults has been set to true, the file will be copied over from the default inside the jar-file of the owning plugin.

+ * + * @see #YamlConfig(Plugin, String, boolean) + */ + public void load() { + try { + if (COPY_DEFAULTS) { + if (!CONFIG_FILE.exists()) { + CONFIG_FILE.getParentFile().mkdirs(); + try { + FileUtils.copy(PLUGIN.getResource(CONFIG_FILE.getName()), CONFIG_FILE); + } catch (IOException ex) { + PLUGIN.getLogger().severe("Could not write default configuration file: " + CONFIG_FILE.getName()); + PLUGIN.getLogger().severe(ExceptionUtils.getStackTrace(ex)); + } + PLUGIN.getLogger().info("Installed default configuration " + CONFIG_FILE.getName()); + } + + super.addDefaults(getDefaultConfig()); + } + + super.load(CONFIG_FILE); + } catch (Exception ex) { + PLUGIN.getLogger().severe("Could not load configuration file: " + CONFIG_FILE.getName()); + PLUGIN.getLogger().severe(ExceptionUtils.getStackTrace(ex)); + } + } + + /** + * Returns the raw YamlConfiguration this config is based on. + * + * @return The YamlConfiguration. + * @see YamlConfiguration + */ + public YamlConfiguration getConfig() { + return this; + } + + /** + * Returns the default configuration as been stored in the jar-file of the owning plugin. + * @return The default configuration. + */ + public YamlConfiguration getDefaultConfig() { + final YamlConfiguration DEFAULT_CONFIG = new YamlConfiguration(); + try { + DEFAULT_CONFIG.load(PLUGIN.getResource(CONFIG_FILE.getName())); + } catch (Throwable ex) { + PLUGIN.getLogger().severe("Could not load default configuration: " + CONFIG_FILE.getName()); + PLUGIN.getLogger().severe(ExceptionUtils.getStackTrace(ex)); + return null; + } + return DEFAULT_CONFIG; + } +} \ No newline at end of file diff --git a/src/plugin.yml b/src/plugin.yml index 25a792a..34e5004 100644 --- a/src/plugin.yml +++ b/src/plugin.yml @@ -1,5 +1,5 @@ name: BukkitTelnet main: me.StevenLawson.BukkitTelnet.BukkitTelnet -version: 3.0 +version: 4.0 description: Telnet console access plugin. -authors: [bekvon, Madgeek1450] +authors: [bekvon, Madgeek1450, DarthSalamon]