diff --git a/pom.xml b/pom.xml index 03d4f3f..63cd6c9 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ vip.floatationdevice mgbridge - 0.9.3 + 0.9.4 jar MGBridge @@ -74,7 +74,7 @@ vip.floatationdevice guilded4j - 0.9.4 + 0.9.5 diff --git a/src/main/java/vip/floatationdevice/mgbridge/BindManager.java b/src/main/java/vip/floatationdevice/mgbridge/BindManager.java index d0f22f6..6929a15 100755 --- a/src/main/java/vip/floatationdevice/mgbridge/BindManager.java +++ b/src/main/java/vip/floatationdevice/mgbridge/BindManager.java @@ -4,9 +4,9 @@ import java.util.HashMap; import java.util.UUID; +import static vip.floatationdevice.mgbridge.I18nUtil.translate; import static vip.floatationdevice.mgbridge.MGBridge.instance; import static vip.floatationdevice.mgbridge.MGBridge.log; -import static vip.floatationdevice.mgbridge.I18nUtil.translate; public class BindManager { diff --git a/src/main/java/vip/floatationdevice/mgbridge/BukkitCommandExecutor.java b/src/main/java/vip/floatationdevice/mgbridge/BukkitCommandExecutor.java index 6a95b94..e2729d3 100644 --- a/src/main/java/vip/floatationdevice/mgbridge/BukkitCommandExecutor.java +++ b/src/main/java/vip/floatationdevice/mgbridge/BukkitCommandExecutor.java @@ -12,11 +12,13 @@ import static vip.floatationdevice.mgbridge.ConfigManager.proxy; import static vip.floatationdevice.mgbridge.ConfigManager.token; import static vip.floatationdevice.mgbridge.I18nUtil.translate; -import static vip.floatationdevice.mgbridge.MGBridge.*; +import static vip.floatationdevice.mgbridge.MGBridge.instance; +import static vip.floatationdevice.mgbridge.MGBridge.log; public class BukkitCommandExecutor implements CommandExecutor { - public static final Random r = new Random(); // used to generate random bind code + static final Random r = new Random(); // used to generate random bind code + @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { @@ -24,15 +26,29 @@ public boolean onCommand(CommandSender sender, Command command, String label, St { try { - instance.gEventListener.disconnect(); + try {instance.gEventListener.disconnect();} catch(IllegalArgumentException ignored) {} + if(ConfigManager.loadConfig()) + { + instance.g4JClient = new G4JClient(token); + instance.g4JClient.setProxy(proxy); + instance.gEventListener.connect(); + log.info("MGBridge reloaded"); + if(sender instanceof Player) sender.sendMessage("[§eMGBridge§f] §aMGBridge reloaded"); + } + else + { + log.severe("MGBridge reloaded with errors"); + if(sender instanceof Player) sender.sendMessage("[§eMGBridge§f] §cMGBridge reloaded with errors"); + } + return true; + } + catch(Throwable e) + { + log.severe("Failed to reload MGBridge"); + e.printStackTrace(); + if(sender instanceof Player) sender.sendMessage("[§eMGBridge§f] §cFailed to reload MGBridge"); + return false; } - catch(IllegalArgumentException ignored){} - ConfigManager.loadConfig(); - instance.g4JClient = new G4JClient(token); - instance.g4JClient.getChatMessageManager().setProxy(proxy); - instance.gEventListener.connect(); - sender.sendMessage("MGBridge reloaded"); - return true; } if(!(sender instanceof Player)) diff --git a/src/main/java/vip/floatationdevice/mgbridge/ConfigManager.java b/src/main/java/vip/floatationdevice/mgbridge/ConfigManager.java index e68d7cf..a3b7314 100644 --- a/src/main/java/vip/floatationdevice/mgbridge/ConfigManager.java +++ b/src/main/java/vip/floatationdevice/mgbridge/ConfigManager.java @@ -23,10 +23,15 @@ public class ConfigManager static Proxy proxy = Proxy.NO_PROXY; static String toGuildedMessageFormat = "**{PLAYER} ⟫** {MESSAGE}"; static String toMinecraftMessageFormat = "[§eGuilded§r] <{PLAYER}> {MESSAGE}"; + + /** + * Load the config file of MGBridge. + * @return True if the config file is loaded and valid, false otherwise. + */ static boolean loadConfig() { File cfgFile = new File(instance.getDataFolder(), "config.yml"); - if (!cfgFile.exists()) + if(!cfgFile.exists()) { // create default config file if it doesn't exist log.severe("Config file not found and an empty one will be created. Set the token and channel UUID and RESTART server."); instance.saveDefaultConfig(); diff --git a/src/main/java/vip/floatationdevice/mgbridge/GuildedCommandExecutor.java b/src/main/java/vip/floatationdevice/mgbridge/GuildedCommandExecutor.java index 938e5d4..3c0c3a9 100644 --- a/src/main/java/vip/floatationdevice/mgbridge/GuildedCommandExecutor.java +++ b/src/main/java/vip/floatationdevice/mgbridge/GuildedCommandExecutor.java @@ -15,12 +15,12 @@ public interface GuildedCommandExecutor * Gets the description of the subcommand. * @return The description of the subcommand. */ - String getDescription(); + String getCommandDescription(); /** * Gets the usage of the subcommand. * @return The usage of the subcommand. */ - String getUsage(); + String getCommandUsage(); boolean execute(ChatMessage msg, String[] args); } diff --git a/src/main/java/vip/floatationdevice/mgbridge/GuildedEventListener.java b/src/main/java/vip/floatationdevice/mgbridge/GuildedEventListener.java index 8b61fe2..785e9de 100644 --- a/src/main/java/vip/floatationdevice/mgbridge/GuildedEventListener.java +++ b/src/main/java/vip/floatationdevice/mgbridge/GuildedEventListener.java @@ -8,15 +8,13 @@ import vip.floatationdevice.guilded4j.event.GuildedWebSocketWelcomeEvent; import vip.floatationdevice.guilded4j.object.ChatMessage; -import java.util.ArrayList; import java.util.HashMap; -import java.util.Map; -import java.util.TreeMap; -import static vip.floatationdevice.mgbridge.BindManager.*; -import static vip.floatationdevice.mgbridge.I18nUtil.translate; -import static vip.floatationdevice.mgbridge.MGBridge.*; +import static vip.floatationdevice.mgbridge.BindManager.bindMap; import static vip.floatationdevice.mgbridge.ConfigManager.*; +import static vip.floatationdevice.mgbridge.I18nUtil.translate; +import static vip.floatationdevice.mgbridge.MGBridge.getPlayerName; +import static vip.floatationdevice.mgbridge.MGBridge.log; @SuppressWarnings({"unused", "UnstableApiUsage"}) public class GuildedEventListener @@ -24,24 +22,38 @@ public class GuildedEventListener G4JWebSocketClient ws; // used to connect to guilded and receive guilded messages private final HashMap executors = new HashMap<>(); // subcommands of the guilded command "/mgb" + /** + * Gets the map of subcommands of the Guilded command "/mgb". + * @return A HashMap object. The key is the name of the subcommand, the value is the GuildedCommandExecutor object of the subcommand. + */ public HashMap getExecutors() { return executors; } + /** + * Register a subcommand. + * @param executor The GuildedCommandExecutor object of the subcommand. + */ public GuildedEventListener registerExecutor(GuildedCommandExecutor executor) { executors.put(executor.getCommandName(), executor); return this; } + /** + * Unregister a subcommand. + * @param commandName The name of the subcommand. + * @throws IllegalArgumentException If the subcommand does not exist. + */ public GuildedEventListener unregisterExecutor(String commandName) { - if(executors.remove(commandName) == null) throw new IllegalArgumentException("No executor found for command " + commandName); + if(executors.remove(commandName) == null) + throw new IllegalArgumentException("No executor found for command " + commandName); return this; } - public void unregisterAllExecutors() + void unregisterAllExecutors() { executors.clear(); } diff --git a/src/main/java/vip/floatationdevice/mgbridge/I18nUtil.java b/src/main/java/vip/floatationdevice/mgbridge/I18nUtil.java index 045f52b..c7ce661 100755 --- a/src/main/java/vip/floatationdevice/mgbridge/I18nUtil.java +++ b/src/main/java/vip/floatationdevice/mgbridge/I18nUtil.java @@ -8,11 +8,17 @@ public class I18nUtil { private static FileConfiguration l; - private static String lang = "en_US"; + private static String lang = null; + /** + * Set the language of the plugin. + * @param language Locale code of the language to use. + * @return The language code. + */ public static String setLanguage(String language) { - if(language == null || language.equals("")) return lang; + if(language == null || language.equals("")) + throw new IllegalArgumentException("Language cannot be null or empty"); lang = language; File langFile = new File(MGBridge.instance.getDataFolder(), "lang_" + lang + ".yml"); if(!langFile.exists()) MGBridge.instance.saveResource("lang_" + lang + ".yml", false); @@ -20,14 +26,26 @@ public static String setLanguage(String language) return lang; } + /** + * Translate a string. + * @param key The key of the string. + * @return The translated string. If the key does not exist, return "[NO TRANSLATION: key]" + * @throws IllegalArgumentException If the language is not set. + */ public static String translate(String key) { if(l == null) throw new IllegalStateException("Translation engine not initialized"); return l.getString(key) == null ? "[NO TRANSLATION: " + key + "]" : l.getString(key); } + /** + * Get the language of the plugin. + * @return The language of the plugin. + * @throws IllegalStateException If the language is not set. + */ public static String getLanguage() { + if(lang == null) throw new IllegalStateException("Translation engine not initialized"); return lang; } } diff --git a/src/main/java/vip/floatationdevice/mgbridge/MGBridge.java b/src/main/java/vip/floatationdevice/mgbridge/MGBridge.java index 1fb4e1a..83902d9 100755 --- a/src/main/java/vip/floatationdevice/mgbridge/MGBridge.java +++ b/src/main/java/vip/floatationdevice/mgbridge/MGBridge.java @@ -19,13 +19,15 @@ import java.util.logging.Logger; import static vip.floatationdevice.mgbridge.ConfigManager.*; -import static vip.floatationdevice.mgbridge.ConfigManager.toGuildedMessageFormat; import static vip.floatationdevice.mgbridge.I18nUtil.translate; public final class MGBridge extends JavaPlugin implements Listener { + /** + * The instance of the plugin. + */ public static MGBridge instance; - public static Logger log; + static Logger log; G4JClient g4JClient = null; GuildedEventListener gEventListener = null; @@ -50,7 +52,7 @@ public void onEnable() .registerExecutor(new Command_rmbind()) .registerExecutor(new Command_ping()) .registerExecutor(new Command_list()); - g4JClient.getChatMessageManager().setProxy(proxy); + g4JClient.setProxy(proxy); Bukkit.getPluginManager().registerEvents(this, this); sendGuildedEmbed(new Embed().setTitle(translate("mgb-started").replace("%VERSION%", getDescription().getVersion())).setColor(0xffffff), null, null, null); } @@ -71,6 +73,7 @@ public void onDisable() gEventListener.unregisterAllExecutors(); gEventListener = null; } + if(g4JClient != null) { ChatMessage result = null; @@ -124,6 +127,13 @@ public void onLeave(PlayerQuitEvent event) sendGuildedEmbed(new Embed().setTitle(translate("player-disconnected").replace("%PLAYER%", event.getPlayer().getName())).setColor(0xffff00), null, null, null); } + /** + * Sends a message to Guilded server. + * @param msg The content of the message. + * @param replyTo The ID of the message to reply to. Set to null to not reply. + * @param isPrivate Whether the reply is private or not. + * @param isSilent Whether the reply is silent or not. + */ public void sendGuildedMessage(String msg, String replyTo, Boolean isPrivate, Boolean isSilent) { Bukkit.getScheduler().runTaskAsynchronously(instance, new Runnable() @@ -157,6 +167,13 @@ public void run() }); } + /** + * Sends an embed to Guilded server. + * @param emb The embed to send. + * @param replyTo The ID of the message to reply to. Set to null to not reply. + * @param isPrivate Whether the reply is private or not. + * @param isSilent Whether the reply is silent or not. + */ public void sendGuildedEmbed(Embed emb, String replyTo, Boolean isPrivate, Boolean isSilent) { Bukkit.getScheduler().runTaskAsynchronously(instance, new Runnable() @@ -198,14 +215,36 @@ static boolean notSet(String... s) return false; } + /** + * Gets the name of a player by UUID. + * @param u The UUID of the player. + * @return The name of the player. If the player is not found, returns "???". + */ public static String getPlayerName(final UUID u) { try {return Bukkit.getPlayer(u).getName();} - catch(NullPointerException e) {return Bukkit.getOfflinePlayer(u).getName();} + catch(NullPointerException e) + { + String s = Bukkit.getOfflinePlayer(u).getName(); + return s != null ? s : "???"; + } } + /** + * Gets the Guilded event listener. + * @return The GuildedEventListener object. + */ public GuildedEventListener getGEventListener() { return gEventListener; } + + /** + * Gets the G4JClient used by the plugin. + * @return The G4JClient object. + */ + public G4JClient getG4JClient() + { + return g4JClient; + } } diff --git a/src/main/java/vip/floatationdevice/mgbridge/gce/Command_help.java b/src/main/java/vip/floatationdevice/mgbridge/gce/Command_help.java index 1ac8091..4c78c3b 100644 --- a/src/main/java/vip/floatationdevice/mgbridge/gce/Command_help.java +++ b/src/main/java/vip/floatationdevice/mgbridge/gce/Command_help.java @@ -15,13 +15,13 @@ public String getCommandName() } @Override - public String getDescription() + public String getCommandDescription() { return translate("g-cmd-help-desc"); } @Override - public String getUsage() + public String getCommandUsage() { return "/mgb help"; } diff --git a/src/main/java/vip/floatationdevice/mgbridge/gce/Command_helpof.java b/src/main/java/vip/floatationdevice/mgbridge/gce/Command_helpof.java index f340539..a6b4ea6 100644 --- a/src/main/java/vip/floatationdevice/mgbridge/gce/Command_helpof.java +++ b/src/main/java/vip/floatationdevice/mgbridge/gce/Command_helpof.java @@ -15,13 +15,13 @@ public String getCommandName() } @Override - public String getDescription() + public String getCommandDescription() { return translate("g-cmd-helpof-desc"); } @Override - public String getUsage() + public String getCommandUsage() { return "/mgb helpof "; } @@ -34,9 +34,9 @@ public boolean execute(ChatMessage msg, String[] args) GuildedCommandExecutor gce = instance.getGEventListener().getExecutors().get(args[0]); String desc = null, usage = null; try - {// GuildedCommandExecutor from MGB version 0.9.2 and older doesn't implement getDescription() and getUsage() - desc = gce.getDescription(); - usage = gce.getUsage(); + {// GuildedCommandExecutor from MGB version 0.9.3 and older doesn't implement getCommandDescription() and getCommandUsage() + desc = gce.getCommandDescription(); + usage = gce.getCommandUsage(); } catch(AbstractMethodError e) { diff --git a/src/main/java/vip/floatationdevice/mgbridge/gce/Command_list.java b/src/main/java/vip/floatationdevice/mgbridge/gce/Command_list.java index 473ffcb..78b255d 100644 --- a/src/main/java/vip/floatationdevice/mgbridge/gce/Command_list.java +++ b/src/main/java/vip/floatationdevice/mgbridge/gce/Command_list.java @@ -17,10 +17,10 @@ public class Command_list implements GuildedCommandExecutor public String getCommandName(){return "list";} @Override - public String getDescription(){return translate("g-cmd-list-desc");} + public String getCommandDescription(){return translate("g-cmd-list-desc");} @Override - public String getUsage(){return "/mgb list";} + public String getCommandUsage(){return "/mgb list";} @Override public boolean execute(ChatMessage msg, String[] args) diff --git a/src/main/java/vip/floatationdevice/mgbridge/gce/Command_mkbind.java b/src/main/java/vip/floatationdevice/mgbridge/gce/Command_mkbind.java index e88569b..f53eb99 100644 --- a/src/main/java/vip/floatationdevice/mgbridge/gce/Command_mkbind.java +++ b/src/main/java/vip/floatationdevice/mgbridge/gce/Command_mkbind.java @@ -8,7 +8,8 @@ import static vip.floatationdevice.mgbridge.BindManager.*; import static vip.floatationdevice.mgbridge.I18nUtil.translate; -import static vip.floatationdevice.mgbridge.MGBridge.*; +import static vip.floatationdevice.mgbridge.MGBridge.getPlayerName; +import static vip.floatationdevice.mgbridge.MGBridge.instance; public class Command_mkbind implements GuildedCommandExecutor { @@ -16,10 +17,10 @@ public class Command_mkbind implements GuildedCommandExecutor public String getCommandName(){return "mkbind";} @Override - public String getDescription(){return translate("g-cmd-mkbind-desc");} + public String getCommandDescription(){return translate("g-cmd-mkbind-desc");} @Override - public String getUsage(){return "/mgb mkbind ";} + public String getCommandUsage(){return "/mgb mkbind ";} @Override public boolean execute(ChatMessage msg, String[] args) @@ -49,7 +50,7 @@ public boolean execute(ChatMessage msg, String[] args) } catch(NullPointerException ignored) {} // player is offline. ignore instance.sendGuildedEmbed(new Embed().setTitle(translate("g-bind-success").replace("%PLAYER%", getPlayerName(bindMap.get(msg.getCreatorId())))).setColor(0x00ff00), msg.getId(), null, null); - log.info(translate("c-bind-success").replace("%PLAYER%", getPlayerName(bindMap.get(msg.getCreatorId())))); + instance.getLogger().info(translate("c-bind-success").replace("%PLAYER%", getPlayerName(bindMap.get(msg.getCreatorId())))); saveBindMap(); Bukkit.getServer().getPluginManager().callEvent(new UserBoundEvent(msg.getCreatorId(), bindMap.get(msg.getCreatorId()))); return true; diff --git a/src/main/java/vip/floatationdevice/mgbridge/gce/Command_ping.java b/src/main/java/vip/floatationdevice/mgbridge/gce/Command_ping.java index 678633b..d00655a 100644 --- a/src/main/java/vip/floatationdevice/mgbridge/gce/Command_ping.java +++ b/src/main/java/vip/floatationdevice/mgbridge/gce/Command_ping.java @@ -13,10 +13,10 @@ public class Command_ping implements GuildedCommandExecutor public String getCommandName(){return "ping";} @Override - public String getDescription(){return translate("g-cmd-ping-desc");} + public String getCommandDescription(){return translate("g-cmd-ping-desc");} @Override - public String getUsage(){return "/mgb ping";} + public String getCommandUsage(){return "/mgb ping";} @Override public boolean execute(ChatMessage msg, String[] args) diff --git a/src/main/java/vip/floatationdevice/mgbridge/gce/Command_rmbind.java b/src/main/java/vip/floatationdevice/mgbridge/gce/Command_rmbind.java index c344f92..63d7172 100644 --- a/src/main/java/vip/floatationdevice/mgbridge/gce/Command_rmbind.java +++ b/src/main/java/vip/floatationdevice/mgbridge/gce/Command_rmbind.java @@ -11,7 +11,7 @@ import static vip.floatationdevice.mgbridge.BindManager.bindMap; import static vip.floatationdevice.mgbridge.BindManager.saveBindMap; import static vip.floatationdevice.mgbridge.I18nUtil.translate; -import static vip.floatationdevice.mgbridge.MGBridge.*; +import static vip.floatationdevice.mgbridge.MGBridge.getPlayerName; import static vip.floatationdevice.mgbridge.MGBridge.instance; public class Command_rmbind implements GuildedCommandExecutor @@ -20,10 +20,10 @@ public class Command_rmbind implements GuildedCommandExecutor public String getCommandName(){return "rmbind";} @Override - public String getDescription(){return translate("g-cmd-rmbind-desc");} + public String getCommandDescription(){return translate("g-cmd-rmbind-desc");} @Override - public String getUsage(){return "/mgb rmbind";} + public String getCommandUsage(){return "/mgb rmbind";} @Override public boolean execute(ChatMessage msg, String[] args) @@ -37,7 +37,7 @@ public boolean execute(ChatMessage msg, String[] args) catch(Exception ignored) {} // player is offline. ignore UUID removed = bindMap.remove(msg.getCreatorId()); instance.sendGuildedEmbed(new Embed().setTitle(translate("g-unbind-success")).setColor(0x00ff00), msg.getId(), null, null); - log.info(translate("c-unbind-success").replace("%PLAYER%", getPlayerName(removed))); + instance.getLogger().info(translate("c-unbind-success").replace("%PLAYER%", getPlayerName(removed))); saveBindMap(); Bukkit.getServer().getPluginManager().callEvent(new UserUnboundEvent(msg.getCreatorId(), removed)); return true;