diff options
Diffstat (limited to 'EssentialsServerlist/src/net/mcserverlist')
3 files changed, 465 insertions, 0 deletions
diff --git a/EssentialsServerlist/src/net/mcserverlist/bukkit/Mcsl.java b/EssentialsServerlist/src/net/mcserverlist/bukkit/Mcsl.java new file mode 100644 index 000000000..c9b234fd7 --- /dev/null +++ b/EssentialsServerlist/src/net/mcserverlist/bukkit/Mcsl.java @@ -0,0 +1,149 @@ +package net.mcserverlist.bukkit; + +import com.earth2me.essentials.Essentials; +import java.io.*; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.event.Event; +import org.bukkit.event.Event.Priority; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.java.JavaPlugin; + + +public class Mcsl extends JavaPlugin +{ + private static final Logger logger = Logger.getLogger("Minecraft"); + private McslPlayerListener playerListener; + public final String author; + + public Mcsl() throws IOException + { + + PluginDescriptionFile desc = this.getDescription(); + + // Compile author list + List<String> authors = new ArrayList<String>(); + authors.add("Vimae Development"); + int alen = authors.size(); + if (alen == 1) + { + author = " by " + authors.get(0); + } + else if (alen > 1) + { + int i = 0; + StringBuilder bldr = new StringBuilder(); + for (String a : desc.getAuthors()) + { + if (i + 1 == alen) + { + if (alen > 2) bldr.append(","); + bldr.append(" and "); + } + else if (i++ > 0) + { + bldr.append(", "); + } + bldr.append(a); + } + bldr.insert(0, " by "); + author = bldr.toString(); + } + else + { + author = ""; + } + } + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) + { + McslCommands mcslCmd; + try + { + switch (McslCommands.valueOf(cmd.getName().toUpperCase())) + { + case WHITELIST: + whitelist(sender, WhitelistCommands.valueOf(args[0].toUpperCase()), args); + return true; + + default: + return false; + } + } + catch (IllegalArgumentException ex) + { + return false; + } + catch (Exception ex) + { + logger.log(Level.WARNING, "MCSL encountered an unknown error.", ex); + sender.sendMessage("MCSL encountered an unknown error."); + return true; + } + } + + @SuppressWarnings("LoggerStringConcat") + public void onEnable() + { + Plugin p = this.getServer().getPluginManager().getPlugin("Essentials"); + if (p != null) { + if (!this.getServer().getPluginManager().isPluginEnabled(p)) { + this.getServer().getPluginManager().enablePlugin(p); + } + } + playerListener = new McslPlayerListener(this); + getServer().getPluginManager().registerEvent(Event.Type.PLAYER_JOIN, playerListener, Priority.Monitor, this); + getServer().getPluginManager().registerEvent(Event.Type.PLAYER_QUIT, playerListener, Priority.Monitor, this); + getServer().getPluginManager().registerEvent(Event.Type.PLAYER_LOGIN, playerListener, Priority.Lowest, this); + + if (!this.getDescription().getVersion().equals(Essentials.getStatic().getDescription().getVersion())) { + logger.log(Level.WARNING, "Version mismatch! Please update all Essentials jars to the same version."); + } + logger.info(getDescription().getName() + " version " + getDescription().getVersion() + author + " enabled."); + } + + @SuppressWarnings("LoggerStringConcat") + public void onDisable() + { + logger.info(getDescription().getName() + " version " + getDescription().getVersion() + " disabled."); + } + + private void whitelist(CommandSender sender, WhitelistCommands cmd, String[] args) + { + if (!playerListener.isWhitelistEnabled()) + { + sender.sendMessage("§cThe whitelist is disabled."); + return; + } + + if (!sender.isOp()) + { + sender.sendMessage("§cYou must be an operator to manage the whitelist."); + return; + } + + switch (cmd) + { + case RELOAD: + playerListener.whitelistReload(); + sender.sendMessage("A whitelist updated has been queued."); + break; + } + } + + private enum McslCommands + { + WHITELIST + } + + private enum WhitelistCommands + { + RELOAD + } +} diff --git a/EssentialsServerlist/src/net/mcserverlist/bukkit/McslPlayerListener.java b/EssentialsServerlist/src/net/mcserverlist/bukkit/McslPlayerListener.java new file mode 100644 index 000000000..63e4343d2 --- /dev/null +++ b/EssentialsServerlist/src/net/mcserverlist/bukkit/McslPlayerListener.java @@ -0,0 +1,209 @@ +package net.mcserverlist.bukkit; + +import com.earth2me.essentials.Essentials; +import java.io.*; +import java.net.*; +import java.util.logging.*; +import org.bukkit.*; +import org.bukkit.entity.*; +import org.bukkit.event.player.*; + + +public class McslPlayerListener extends PlayerListener +{ + private final static Logger logger = Logger.getLogger("Minecraft"); + private boolean running = true; + private final Server server; + private Thread thread; + private Whitelist whitelist = null; + private volatile boolean updateNeeded = true; + + @SuppressWarnings("CallToThreadStartDuringObjectConstruction") + public McslPlayerListener(Mcsl parent) + { + this.server = parent.getServer(); + + // Get the data from the server.properties file as the server sees it, rather than reading it manually + try + { + this.whitelist = new Whitelist(server); + } + catch (Throwable ex) + { + // Disable the plugin + logger.log(Level.WARNING, "Error encountered while initializing MCServerlist plugin.", ex); + parent.getPluginLoader().disablePlugin(parent); + return; + } + + // Run Update on a set interval of 1 minute with an initial delay of 10 seconds + thread = new Thread(new UpdateRunnable()); + thread.setDaemon(true); + thread.start(); + } + + @Override + @SuppressWarnings("FinalizeDeclaration") + protected void finalize() throws Throwable + { + // Stop the timer + if (thread != null && thread.isAlive()) + { + running = false; + thread.join(); + } + + super.finalize(); + } + + @Override + public void onPlayerLogin(PlayerLoginEvent event) + { + if (event.getResult() != PlayerLoginEvent.Result.ALLOWED) + return; + + Player player = event.getPlayer(); + + // Check the whitelist + if (!Essentials.getSettings().getWhitelistEnabled() || player.isOp() || whitelist == null || whitelist.isAllowed(player.getName())) + { + // Player is an op, there is no whitelist, or the player is whitelisted. + return; + } + + // Player is not whitelisted. + event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "This server employs a whitelist."); + } + + @Override + public void onPlayerJoin(PlayerEvent event) + { + update(); + } + + @Override + public void onPlayerQuit(PlayerEvent event) + { + update(); + } + + public boolean isWhitelistEnabled() + { + return whitelist != null; + } + + public void whitelistReload() + { + whitelist.update(); + } + + public void update() + { + updateNeeded = true; + } + + + private class UpdateRunnable implements Runnable + { + @SuppressWarnings("SleepWhileInLoop") + public void run() + { + do + { + if (updateNeeded) + { + updateNeeded = false; + update(); + } + + try + { + Thread.sleep(60000); + } + catch (InterruptedException ex) + { + logger.info("Forcing MCServerlist update."); + } + } + while (running); + } + + @SuppressWarnings("CallToThreadDumpStack") + public void update() + { + // Check that we aren't receiving an event inappropriately + if (Essentials.getSettings().getMcslKey() == null || Essentials.getSettings().getMcslKey().equals("")) return; + // Compile a comma-space-delimted list of players + Player[] players = server.getOnlinePlayers(); + StringBuilder list = new StringBuilder(); + if (players.length > 0) + { + for (int i = 0; i < players.length; i++) + { + if (i > 0) list.append(", "); + list.append(players[i].getName()); + } + } + + try + { + // Compile POST data + StringBuilder data = new StringBuilder(); + data.append("key="); + data.append(URLEncoder.encode(Essentials.getSettings().getMcslKey(), "UTF-8")); + data.append("&player_count="); + data.append(Integer.toString(players.length)); + data.append("&max_players="); + data.append(Integer.toString(server.getMaxPlayers())); + data.append("&player_list="); + data.append(URLEncoder.encode(list.toString(), "UTF-8")); + + OutputStreamWriter tx = null; + BufferedReader rx = null; + try + { + // Send POST request + URL url = new URL("http://mcserverlist.net/api/update"); + // Swap line for testing purposes + //URL url = new URL("http://localhost/mcsl/update.php"); + HttpURLConnection http = (HttpURLConnection)url.openConnection(); + http.setRequestMethod("POST"); + http.setUseCaches(false); + http.setConnectTimeout(1000); + http.setAllowUserInteraction(false); + http.setInstanceFollowRedirects(true); + http.setRequestProperty("User-Agent", "Java;Mcsl"); + http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8"); + http.setRequestProperty("X-Mcsl-Key", Essentials.getSettings().getMcslKey()); + http.setRequestProperty("X-Minecraft-Name", URLEncoder.encode(server.getName(), "UTF-8")); + http.setRequestProperty("X-Minecraft-Version", server.getVersion()); + http.setDoInput(true); + http.setDoOutput(true); + tx = new OutputStreamWriter(http.getOutputStream()); + tx.write(data.toString()); + tx.flush(); + + // Get the HTTP response + rx = new BufferedReader(new InputStreamReader(http.getInputStream())); + for (String l = ""; rx.ready(); l = rx.readLine()) + { + if ("".equals(l)) continue; + else if (l.startsWith("i:")) logger.info(l.substring(2)); + else if (l.startsWith("w:")) logger.warning(l.substring(2)); + else System.out.println(l); + } + } + finally + { + if (tx != null) tx.close(); + if (rx != null) rx.close(); + } + } + catch (Exception ex) + { + logger.log(Level.WARNING, "Error communication with MCServerlist.", ex); + ex.printStackTrace(); + } + } + } +} diff --git a/EssentialsServerlist/src/net/mcserverlist/bukkit/Whitelist.java b/EssentialsServerlist/src/net/mcserverlist/bukkit/Whitelist.java new file mode 100644 index 000000000..96a96ecbc --- /dev/null +++ b/EssentialsServerlist/src/net/mcserverlist/bukkit/Whitelist.java @@ -0,0 +1,107 @@ +package net.mcserverlist.bukkit; + +import com.earth2me.essentials.Essentials; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.bukkit.Server; + + +public class Whitelist +{ + private static final Logger logger = Logger.getLogger("Minecraft"); + private List<String> allowed = new ArrayList<String>(); + private final Object allowedLock = new Object(); + private Server server; + + public Whitelist(Server server) + { + this.server = server; + } + + public void update() + { + Thread thread = new Thread(new UpdateRunnable()); + thread.setDaemon(true); + thread.start(); + } + + public boolean isAllowed(String player) + { + String p = player.toLowerCase(); + synchronized (allowedLock) + { + return allowed.contains(p); + } + } + + private class UpdateRunnable implements Runnable + { + @SuppressWarnings("CallToThreadDumpStack") + public void run() + { + // Check that we aren't receiving an event inappropriately + if (Essentials.getSettings().getMcslKey() == null || Essentials.getSettings().getMcslKey().equals("")) return; + + try + { + OutputStreamWriter tx = null; + BufferedReader rx = null; + try + { + // Send GET request + URL url = new URL("http://mcserverlist.net/api/whitelist"); + // Swap line for testing purposes + //URL url = new URL("http://localhost/mcsl/whitelist.php"); + HttpURLConnection http = (HttpURLConnection)url.openConnection(); + http.setRequestMethod("POST"); + http.setUseCaches(false); + http.setConnectTimeout(1000); + http.setAllowUserInteraction(false); + http.setInstanceFollowRedirects(true); + http.setRequestProperty("User-Agent", "Java;Mcsl"); + http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8"); + http.setRequestProperty("X-Mcsl-Key", Essentials.getSettings().getMcslKey()); + http.setRequestProperty("X-Minecraft-Name", URLEncoder.encode(server.getName(), "UTF-8")); + http.setRequestProperty("X-Minecraft-Version", server.getVersion()); + http.setDoInput(true); + http.setDoOutput(false); + + // Get the HTTP response + rx = new BufferedReader(new InputStreamReader(http.getInputStream())); + List<String> allowed = new ArrayList<String>(); + for (String l = ""; rx.ready(); l = rx.readLine()) + { + if ("".equals(l)) continue; + else if (l.startsWith("i:")) logger.info(l.substring(2)); + else if (l.startsWith("w:")) logger.warning(l.substring(2)); + else allowed.add(l.toLowerCase()); // Add to whitelist + } + + synchronized (Whitelist.this.allowedLock) + { + Whitelist.this.allowed = allowed; + allowed = null; // Remove our reference so that we don't accidentally use it + } + } + finally + { + if (tx != null) tx.close(); + if (rx != null) rx.close(); + } + } + catch (Exception ex) + { + logger.log(Level.WARNING, "Error communication with MCServerlist.", ex); + ex.printStackTrace(); + } + } + } +} |