package com.alecgorge.minecraft.jsonapi; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.InetAddress; import java.net.MalformedURLException; import java.security.KeyStore; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Properties; import java.util.Set; import java.util.logging.FileHandler; import java.util.logging.Handler; import java.util.logging.Logger; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManagerFactory; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Server; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.MemoryConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerEggThrowEvent; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginLoader; import org.bukkit.plugin.java.JavaPlugin; import org.java_websocket.server.DefaultSSLWebSocketServerFactory; import com.alecgorge.minecraft.jsonapi.McRKit.api.RTKInterface; import com.alecgorge.minecraft.jsonapi.adminium.Adminium3; import com.alecgorge.minecraft.jsonapi.adminium.PushNotificationDaemon; import com.alecgorge.minecraft.jsonapi.api.JSONAPICallHandler; import com.alecgorge.minecraft.jsonapi.api.JSONAPIStream; import com.alecgorge.minecraft.jsonapi.api.StreamPusher; import com.alecgorge.minecraft.jsonapi.config.UsersConfig; import com.alecgorge.minecraft.jsonapi.dynamic.APIWrapperMethods; import com.alecgorge.minecraft.jsonapi.dynamic.API_Method; import com.alecgorge.minecraft.jsonapi.dynamic.Caller; import com.alecgorge.minecraft.jsonapi.dynamic.JSONAPIMethodProvider; import com.alecgorge.minecraft.jsonapi.packets.netty.JSONAPINettyInjector; import com.alecgorge.minecraft.jsonapi.packets.netty.router.RouteMatcher; import com.alecgorge.minecraft.jsonapi.permissions.GroupManager; import com.alecgorge.minecraft.jsonapi.streams.PerformanceStreamDataProvider; import com.alecgorge.minecraft.jsonapi.streams.StreamManager; import com.alecgorge.minecraft.jsonapi.streams.console.ConsoleHandler; import com.alecgorge.minecraft.jsonapi.streams.console.ConsoleLogFormatter; import com.alecgorge.minecraft.jsonapi.streams.console.Log4j2ConsoleHandler; import com.alecgorge.minecraft.jsonapi.util.OfflinePlayerLoader; import com.alecgorge.minecraft.jsonapi.util.TickRateCounter; /** * * @author alecgorge */ public class JSONAPI extends JavaPlugin implements JSONAPIMethodProvider { public PluginLoader pluginLoader; // private Server server; public JSONServer jsonServer; public JSONSocketServer jsonSocketServer; public JSONWebSocketServer jsonWebSocketServer; public JSONWebSocketServer sslJsonWebSocketServer; public JSONAPIMessageListener jsonMessageListener = new JSONAPIMessageListener(this); private StreamManager streamManager = new StreamManager(); public boolean logging = false; public String logFile = "false"; public String salt = ""; public int port = 20059; public boolean allowSendingOldStreamMessages = true; private long startupDelay = 2000; public List<String> whitelist = new ArrayList<String>(); public List<String> method_noauth_whitelist = new ArrayList<String>(); UsersConfig auth; public boolean anyoneCanUseCallAdmin = true; public String serverName = "default"; public StreamPusher streamPusher; public boolean useGroups = false; TickRateCounter tickRateCounter; public boolean adminiumEnabled = true; RouteMatcher router = new RouteMatcher(); private Logger log = Bukkit.getLogger(); public Logger outLog = Logger.getLogger("JSONAPI"); private Handler handler; public RTKInterface rtkAPI = null; public InetAddress bindAddress; // for dynamic access public static JSONAPI instance; PushNotificationDaemon adminium; Adminium3 adminium3; GroupManager groupManager; JSONAPINettyInjector injector = null; //#if jsonapiDebug=="yes" //$ public static boolean shouldDebug = true; //#else public static boolean shouldDebug = false; //#endif public static void dbug(Object objects) { if(JSONAPI.shouldDebug) { System.out.println(objects); } } protected void initalize(PluginLoader pluginLoader, Server instance, PluginDescriptionFile desc, File folder, File plugin, ClassLoader cLoader) { this.pluginLoader = pluginLoader; // server = instance; } public JSONAPI() { super(); JSONAPI.instance = this; } public JSONServer getJSONServer() { return jsonServer; } public GroupManager getGroupManager() { return groupManager; } public UsersConfig getAuthTable() { return auth; } public synchronized StreamManager getStreamManager() { return this.streamManager; } public void registerStreamManager(String streamName, JSONAPIStream stream) { getStreamManager().registerStream(streamName, stream); } public void deregisterStream(String streamName) { getStreamManager().deregisterStream(streamName); } public void registerMethod(String method) { getJSONServer().getCaller().loadString("[" + method + "]", false); } public void registerMethods(String method) { getJSONServer().getCaller().loadString(method, false); } public synchronized Caller getCaller() { return getJSONServer().getCaller(); } @API_Method(namespace = "jsonapi", isProvidedByV2API=false) public List<String> getStreamSources() { return new ArrayList<String>(getStreamManager().getStreams().keySet()); } public void registerAPICallHandler(JSONAPICallHandler handler) { getCaller().registerAPICallHandler(handler); } public void registerMethods(JSONAPIMethodProvider obj) { getCaller().registerMethods(obj); } public void deregisterAPICallHandler(JSONAPICallHandler handler) { getCaller().deregisterAPICallHandler(handler); } public TickRateCounter getTickRateCounter() { return tickRateCounter; } private JSONAPIPlayerListener l = new JSONAPIPlayerListener(this); YamlConfiguration yamlConfig; File yamlFile; public ClassLoader myClassLoader() { return getClassLoader(); } public void onEnable() { /* try { int countI = 0, countB = 0; JSONObject o = new JSONObject(); for(Item i : Item.byId) { if(i == null) continue; countI++; if(i.id < 256) continue; System.out.println(String.format("name: %25s id: %4s class: %s", i.getName(), i.id, i.getClass())); String[] names = null; for(Field f : i.getClass().getDeclaredFields()) { if(f.getType().isAssignableFrom(String[].class)) { f.setAccessible(true); names = (String[]) f.get(i); if(names[0].contains("_")) { names = null; continue; } break; } } if(i instanceof ItemCloth) { names = ItemDye.a; } if(names == null) { continue; } //LocaleI18n.get(arg0) for(int j = 0; j < names.length; j++) { System.out.println(String.format("\t%d: %s", j, names[j])); } JSONObject obj = new JSONObject(); obj.put(", value) o.put(String.valueOf(i.id), obj); } for(Block b : Block.byId) { if(b == null) continue; countB++; System.out.println(String.format("name: %25s id: %4s materal: %s class: %s", b.getName(), b.id, b.material.getClass(), b.getClass())); String[] names = null; for(Field f : b.getClass().getDeclaredFields()) { if(f.getType().isAssignableFrom(String[].class)) { f.setAccessible(true); names = (String[]) f.get(b); if(names[0].contains("_")) { names = null; continue; } break; } } if(b instanceof BlockCloth) { names = ItemDye.a; } if(names == null) { continue; } for(int j = 0; j < names.length; j++) { System.out.println(String.format("\t%d: %s", j, names[j])); } } System.out.println("items: " + countI + " blocks: " + countB); } catch(Exception e) { } */ // for minecraft forge, Logger.getLogger("JSONAPI"); doesn't output anything... try { Class.forName("net.minecraftforge.common.MinecraftForge"); outLog = log; } catch (Error e) {} catch (Exception e) {} boolean rtkInstalled = Bukkit.getPluginManager().getPlugin("RemoteToolkitPlugin") != null; try { auth = new UsersConfig(this); if (!getDataFolder().exists()) { getDataFolder().mkdir(); } yamlFile = new File(getDataFolder(), "config.yml"); File methods = new File(getDataFolder(), "methods.json"); File methodsFolder = new File(getDataFolder(), "methods"); File rtkConfig = new File(getDataFolder(), "config_rtk.yml"); File groups = new File(getDataFolder(), "groups.yml"); if (!methods.exists()) { InputStream in = getResource("methods.json"); OutputStream out = new FileOutputStream(methods); byte[] buffer = new byte[1024]; int len; while ((len = in.read(buffer)) != -1) { out.write(buffer, 0, len); } in.close(); out.close(); log.info("[JSONAPI] methods.json has been copied from the jar"); } if (!methodsFolder.exists()) { methodsFolder.mkdirs(); } String[] methodsFiles = new String[] { "chat.json", "dynmap.json", "econ.json", "permissions.json", "fs.json", "readme.txt", "remotetoolkit.json", "system.json", "world.json" }; for (String f : methodsFiles) { File outF = new File(methodsFolder, f); if (!outF.exists()) { outF.createNewFile(); InputStream in = getResource("methods/" + f); OutputStream out = new FileOutputStream(outF); byte[] buffer = new byte[1024]; int len; while ((len = in.read(buffer)) != -1) { out.write(buffer, 0, len); } in.close(); out.close(); } } if (!yamlFile.exists()) { yamlFile.createNewFile(); InputStream in = getResource("config.yml"); OutputStream out = new FileOutputStream(yamlFile); byte[] buffer = new byte[1024]; int len; while ((len = in.read(buffer)) != -1) { out.write(buffer, 0, len); } in.close(); out.close(); log.info("[JSONAPI] config.yml has been copied from the jar"); } if (rtkInstalled && !rtkConfig.exists()) { rtkConfig.createNewFile(); InputStream in = getResource("config_rtk.yml"); OutputStream out = new FileOutputStream(rtkConfig); byte[] buffer = new byte[1024]; int len; while ((len = in.read(buffer)) != -1) { out.write(buffer, 0, len); } in.close(); out.close(); log.info("[JSONAPI] config_rtk.yml has been copied from the jar"); } if (!groups.exists()) { groups.createNewFile(); InputStream in = getResource("groups.yml"); OutputStream out = new FileOutputStream(groups); byte[] buffer = new byte[1024]; int len; while ((len = in.read(buffer)) != -1) { out.write(buffer, 0, len); } in.close(); out.close(); log.info("[JSONAPI] groups.yml has been copied from the jar"); } String reconstituted = ""; int max_queue_age = 30; int max_queue_length = 500; if (yamlFile.exists()) { yamlConfig = new YamlConfiguration(); yamlConfig.load(yamlFile); // VERY IMPORTANT yamlConfig.addDefault("method-whitelist", new String[]{ "getPlayerLimit", "dynmap.getPort"} ); MemoryConfiguration stream_pusher_config = new MemoryConfiguration(); stream_pusher_config.addDefault("max_queue_age", 30); stream_pusher_config.addDefault("max_queue_length", 500); yamlConfig.addDefault("options.stream_pusher", stream_pusher_config); yamlConfig.options().copyDefaults(true); yamlConfig.save(yamlFile); logging = yamlConfig.getBoolean("options.log-to-console", true); logFile = yamlConfig.getString("options.log-to-file", "false"); whitelist = yamlConfig.getStringList("options.ip-whitelist"); for (String ip : whitelist) { reconstituted += ip + ","; } max_queue_age = yamlConfig.getInt("max_queue_age", 30); max_queue_length = yamlConfig.getInt("max_queue_length", 500); salt = yamlConfig.getString("options.salt", ""); port = yamlConfig.getInt("options.port", 20059); startupDelay = yamlConfig.getInt("options.startup-delay", 2000); anyoneCanUseCallAdmin = yamlConfig.getBoolean("options.anyone-can-use-calladmin", false); allowSendingOldStreamMessages = yamlConfig.getBoolean("options.send-previous-stream-messages", true); serverName = getServer().getServerName(); adminiumEnabled = yamlConfig.getBoolean("options.adminium-push-enabled", true); if(yamlConfig.contains("options.use-new-api")) { useGroups = yamlConfig.getBoolean("options.use-new-api", false); } else { yamlConfig.set("options.use-new-api", false); yamlConfig.save(yamlFile); } String host = yamlConfig.getString("options.bind-address", ""); if (host.equals("")) { bindAddress = null; } else { bindAddress = InetAddress.getByName(host); } method_noauth_whitelist = yamlConfig.getStringList("method-whitelist"); File usersFile = new File(getDataFolder(), "users.yml"); if(usersFile.exists()) { auth.init(); } else { if(!yamlConfig.contains("logins")) { usersFile.createNewFile(); InputStream in = getResource("users.yml"); OutputStream out = new FileOutputStream(usersFile); byte[] buffer = new byte[1024]; int len; while ((len = in.read(buffer)) != -1) { out.write(buffer, 0, len); } in.close(); out.close(); log.info("[JSONAPI] users.yml has been copied from the jar"); auth.init(); } else { Set<String> logins = ((ConfigurationSection) yamlConfig.get("logins")).getKeys(false); List<String> fullgroups = new ArrayList<String>(); fullgroups.add("full_control"); for (String k : logins) { String password = yamlConfig.getString("logins." + k); HashMap<String, Object> map = new HashMap<String, Object>(); map.put("username", k); map.put("password", password); map.put("groups", fullgroups); auth.users.add(map); } yamlConfig.set("logins", null); yamlConfig.save(yamlFile); auth.save(); } } } if (rtkInstalled) { YamlConfiguration yamlRTK = new YamlConfiguration(); try { yamlRTK.load(rtkConfig); Properties rtkProps = new Properties(); rtkProps.load(new FileInputStream("toolkit/remote.properties")); int port = Integer.parseInt(rtkProps.getProperty("remote-control-port")); String salt = rtkProps.getProperty("auth-salt"); rtkAPI = new RTKInterface(port, "localhost", yamlRTK.getString("RTK.username"), yamlRTK.getString("RTK.password"), salt); } catch (Exception e) { // e.printStackTrace(); } } if (!logging) { outLog.setUseParentHandlers(false); for (Handler h : outLog.getHandlers()) { outLog.removeHandler(h); } } if (!logFile.equals("false") && !logFile.isEmpty()) { FileHandler fh = new FileHandler(logFile, true); fh.setFormatter(new ConsoleLogFormatter()); outLog.addHandler(fh); } if (auth.getUsers().size() == 0) { log.severe("[JSONAPI] No valid logins for JSONAPI. Check config.yml"); return; } log.info("[JSONAPI] Logging to file: " + logFile); log.info("[JSONAPI] Logging to console: " + String.valueOf(logging)); log.info("[JSONAPI] IP Whitelist = " + (reconstituted.equals("") ? "None, all requests are allowed." : reconstituted)); jsonServer = new JSONServer(auth, this, startupDelay); // add console stream support handler = new ConsoleHandler(jsonServer); new Log4j2ConsoleHandler(jsonServer); log.info("[JSONAPI] Attempting to use port " + port); jsonSocketServer = new JSONSocketServer(port + 1, jsonServer); jsonWebSocketServer = new JSONWebSocketServer(port + 2, jsonServer); jsonWebSocketServer.start(); setupSSLWebsockets(); // new PortMapper(this); // map dem ports registerStreamManager("chat", getJSONServer().chat); registerStreamManager("egg", getJSONServer().eggStream); registerStreamManager("formatted_chat", getJSONServer().formattedChat); registerStreamManager("console", getJSONServer().console); registerStreamManager("connections", getJSONServer().connections); streamPusher = new StreamPusher(streamManager, new File(getDataFolder(), "push_locations.yml"), max_queue_age, max_queue_length); groupManager = new GroupManager(this); initialiseListeners(); adminium = new PushNotificationDaemon(new File(getDataFolder(), "adminium.yml"), this); adminium3 = new Adminium3(this); tickRateCounter = new TickRateCounter(this); injector = new JSONAPINettyInjector(this); // must load this after the tick counter exists! registerStreamManager("performance", getJSONServer().performance); PerformanceStreamDataProvider.enqueue(this); registerMethods(this); } catch (Exception ioe) { log.severe("[JSONAPI] Couldn't start server!\n"); ioe.printStackTrace(); // System.exit( -1 ); } } @Override public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) { if (sender instanceof ConsoleCommandSender) { if (cmd.getName().equals("reloadjsonapi")) { if (sender instanceof ConsoleCommandSender) { log.info("Reloading JSONAPI"); onDisable(); onEnable(); } return true; } else if (cmd.getName().equals("jsonapi-list")) { listMethods(sender); return true; } else if (cmd.getName().equals("jsonapi") && args.length > 0 && args[0].equals("status")) { jsonServer.connectionInfo(); return true; } /* * else if(!adminium.init && args.length > 1 && * cmd.getName().equals("calladmin")) { * System.out.println(sender.getName() + ": " + * join(Arrays.asList(args), " ")); return true; } */ } if (args.length >= 1 && cmd.getName().equals("calladmin")) { adminium3.calladmin(sender, join(Arrays.asList(args), " ")); // adminium 2.x if(adminium.init) adminium.calladmin(sender, join(Arrays.asList(args), " ")); return true; } if (cmd.getName().equals("jsonapi") && (sender.hasPermission("jsonapi.command") || sender instanceof ConsoleCommandSender)) { if (args.length == 0) { sender.sendMessage("If you don't know how to use this, you should probably use /help jsonapi"); return true; } String subCommand = args[0]; if (subCommand.equals("list")) { if (args.length == 1) { listMethods(sender); } else { listMethods(sender, args[1]); } return true; } else if(subCommand.equals("reloadgroups")) { groupManager.loadFromConfig(); sender.sendMessage("Groups reloaded!"); } else if (subCommand.equals("reload")) { log.info("Reloading JSONAPI"); onDisable(); onEnable(); return true; } else if (subCommand.equals("subscribe")) { if (args.length != 3) { sender.sendMessage(ChatColor.RED + "Incorrect number of args. Should be /jsonapi subscribe [stream-name] [url-to-POST-to]"); return true; } try { streamPusher.subscribe(args[1], args[2], true); sender.sendMessage(ChatColor.GREEN + "Subscription setup."); } catch (MalformedURLException e) { sender.sendMessage(ChatColor.RED + "Invalid URL: " + e.getMessage()); } catch (Exception e) { sender.sendMessage(ChatColor.RED + "Error: " + e.getMessage()); } return true; } else if (subCommand.equals("users")) { if (args.length == 1 || args[1].equals("list")) { List<String> usernames = new ArrayList<String>(); try { // for(JSONAPIUser u : getJSONServer().getLogins().getUsers()) { // usernames.add(u.getUsername()); // } }catch(Exception e) { e.printStackTrace(); } sender.sendMessage("Usernames: " + join(usernames, ", ")); return true; } else if (args.length == 3 && args[2].equals("password")) { UsersConfig logins = getJSONServer().getLogins(); if (!logins.userExists(args[1])) { sender.sendMessage(ChatColor.RED + "No JSONAPI user named " + args[1]); return true; } sender.sendMessage(args[1] + "'s password: " + logins.getUser(args[1]).getPassword()); return true; } else if (args.length == 4 && args[1].equals("add")) { try { String username = args[2]; String password = args[3]; List<String> g = new ArrayList<String>(); g.add("full_control"); // getJSONServer().getLogins().getUsers().add(new JSONAPIUser(username, password, g)); yamlConfig.set("logins", getJSONServer().getLogins()); yamlConfig.save(yamlFile); sender.sendMessage(ChatColor.GREEN + "Created a new user with the username '" + username + "' and password '" + password + "'"); } catch (IOException e) { sender.sendMessage(ChatColor.RED + "Error: " + e.getMessage()); e.printStackTrace(); } return true; } } } /*else if (cmd.getName().equals("adminium")) { if (!adminium.init) { sender.sendMessage(ChatColor.RED + "You need Adminium for that."); return true; } if (args.length == 0) { sender.sendMessage(ChatColor.RED + "/adminium [user (username)|create-user (username) (group name)|set-group (username) (group name)|list-groups]"); return true; } String sub = args[0]; if (args.length == 2 && sub.equals("user")) { String username = args[1]; if (!adminium.groupAssignments.containsKey(username)) { sender.sendMessage(ChatColor.GREEN + username + " has access to everything and is not in a group."); return true; } sender.sendMessage(ChatColor.GREEN + username + " is in the group " + adminium.groupAssignments.get(username)); return true; } else if (args.length == 3 && (sub.equals("create-user") || sub.equals("set-group"))) { try { String username = args[1]; String groupName = args[2]; if (!adminium.groupPerms.containsKey(groupName)) { sender.sendMessage(ChatColor.RED + groupName + " is a non-existant group!"); return true; } String pass = ""; if (!getJSONServer().getLogins().containsKey(username)) { pass = genPassword(); getJSONServer().getLogins().put(username, pass); yamlConfig.set("logins", getJSONServer().getLogins()); yamlConfig.save(yamlFile); } else { pass = getJSONServer().getLogins().get(username); } adminium.groupAssignments.put(username, groupName); adminium.saveConfig(); sender.sendMessage(ChatColor.GREEN + "This user has the following information"); sender.sendMessage(ChatColor.GREEN + "Username: " + username); sender.sendMessage(ChatColor.GREEN + "Password: " + pass); sender.sendMessage(ChatColor.GREEN + "Group name: " + groupName); sender.sendMessage(ChatColor.GREEN + "Salt: " + salt); } catch (IOException e) { sender.sendMessage(ChatColor.RED + "Error: " + e.getMessage()); e.printStackTrace(); } return true; } else if (args.length == 1 && sub.equals("list-groups")) { sender.sendMessage(ChatColor.GREEN + join(new ArrayList<String>(adminium.groupPerms.keySet()), ", ")); return true; } return true; }*/ return false; } private void listMethods(CommandSender sender) { listMethods(sender, "-1"); } private void listMethods(CommandSender sender, String testKey) { for (String key : jsonServer.getCaller().methods.keySet()) { if (!testKey.equals("-1") && !testKey.equals(key)) { continue; } StringBuilder sb = new StringBuilder((key.trim().equals("") ? "Default Namespace" : key.trim()) + ": "); for (String m : jsonServer.getCaller().methods.get(key).keySet()) { sb.append(jsonServer.getCaller().methods.get(key).get(m).getName()).append(", "); } sender.sendMessage(sb.substring(0, sb.length() - 2).toString() + "\n"); } } public String join(List<String> list, String conjunction) { StringBuilder sb = new StringBuilder(); boolean first = true; for (String item : list) { if (first) first = false; else sb.append(conjunction); sb.append(item); } return sb.toString(); } public RouteMatcher getRouter() { return router; } void setupSSLWebsockets() { // load up the key store String STORETYPE = "JKS"; String KEYSTORE = "ssl.jks"; String STOREPASSWORD = "jsonapi_store"; String KEYPASSWORD = "jsonapi_key"; File kf = new File(getDataFolder(), KEYSTORE ); if (kf.exists()) { try { KeyStore ks = KeyStore.getInstance(STORETYPE); ks.load(new FileInputStream(kf), STOREPASSWORD.toCharArray()); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(ks, KEYPASSWORD.toCharArray()); TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); tmf.init(ks); SSLContext sslContext = null; sslContext = SSLContext.getInstance("TLS"); sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); sslJsonWebSocketServer = new JSONWebSocketServer(port + 3, jsonServer); sslJsonWebSocketServer.setWebSocketFactory(new DefaultSSLWebSocketServerFactory(sslContext)); sslJsonWebSocketServer.start(); } catch(Exception e) { e.printStackTrace(); } } } @Override public void onDisable() { if (jsonServer != null) { injector.close(); try { log.info("[JSONAPI] Stopping JSON server"); jsonServer.stop(); log.info("[JSONAPI] Stopping JSON socket server"); jsonSocketServer.stop(); log.info("[JSONAPI] Stopping JSON WebSocket server"); jsonWebSocketServer.stop(); log.info("[JSONAPI] Tearing down API methods"); APIWrapperMethods.getInstance().pluginDisable(); log.info("[JSONAPI] Cancelling performance monitoring"); getTickRateCounter().cancel(); } catch (Exception e) { e.printStackTrace(); } log.removeHandler(handler); } } public static Player loadOfflinePlayer(String exactPlayerName) { return OfflinePlayerLoader.load(exactPlayerName); } private void initialiseListeners() { getServer().getPluginManager().registerEvents(l, this); } /** * From a password, a number of iterations and a salt, returns the * corresponding digest * * @param iterationNb * int The number of iterations of the algorithm * @param password * String The password to encrypt * @param salt * byte[] The salt * @return byte[] The digested password * @throws NoSuchAlgorithmException * If the algorithm doesn't exist */ public static String SHA256(String password) throws NoSuchAlgorithmException { MessageDigest digest = MessageDigest.getInstance("SHA-256"); digest.reset(); byte[] input = null; try { input = digest.digest(password.getBytes("UTF-8")); StringBuffer hexString = new StringBuffer(); for (int i = 0; i < input.length; i++) { String hex = Integer.toHexString(0xFF & input[i]); if (hex.length() == 1) { hexString.append('0'); } hexString.append(hex); } return hexString.toString(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return "UnsupportedEncodingException"; } public void disable() { jsonServer.stop(); } public static class JSONAPIPlayerListener implements Listener { JSONAPI p; // This controls the accessibility of functions / variables from the // main class. public JSONAPIPlayerListener(JSONAPI plugin) { p = plugin; } @EventHandler public void onPlayerChat(AsyncPlayerChatEvent event) { p.jsonServer.logChat(event); } @EventHandler public void onPlayerJoin(PlayerJoinEvent event) { p.jsonServer.logConnected(event.getPlayer().getName()); } @EventHandler public void onPlayerQuit(PlayerQuitEvent event) { p.jsonServer.logDisconnected(event.getPlayer().getName()); } @EventHandler public void onPlayerThrowEgg (PlayerEggThrowEvent event) { p.jsonServer.logEggThrow(event); } } }