summaryrefslogtreecommitdiffstats
path: root/EssentialsServerlist/src/net
diff options
context:
space:
mode:
Diffstat (limited to 'EssentialsServerlist/src/net')
-rw-r--r--EssentialsServerlist/src/net/mcserverlist/bukkit/Mcsl.java149
-rw-r--r--EssentialsServerlist/src/net/mcserverlist/bukkit/McslPlayerListener.java209
-rw-r--r--EssentialsServerlist/src/net/mcserverlist/bukkit/Whitelist.java107
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();
+ }
+ }
+ }
+}