commit 4dc0f661e9d437dfae48d1bc064a23858ec03ab1
Author: zhao <1040110848@qq.com>
Date: Tue Jun 16 21:40:09 2020 +0800
完成基本功能
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/UnionBan-Client-Spigot.iml b/.idea/UnionBan-Client-Spigot.iml
new file mode 100644
index 0000000..d6ebd48
--- /dev/null
+++ b/.idea/UnionBan-Client-Spigot.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..d814718
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..aa00ffa
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
new file mode 100644
index 0000000..06bd384
--- /dev/null
+++ b/.idea/jarRepositories.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..4b661a5
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..e96534f
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/UnionBan-Client-Spigot.iml b/UnionBan-Client-Spigot.iml
new file mode 100644
index 0000000..8cb869f
--- /dev/null
+++ b/UnionBan-Client-Spigot.iml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml
new file mode 100644
index 0000000..ef95d22
--- /dev/null
+++ b/dependency-reduced-pom.xml
@@ -0,0 +1,53 @@
+
+
+ 4.0.0
+ cn.cnklp.studio
+ UnionBanClientSpigot
+ 1.0-SNAPSHOT
+
+
+
+ maven-shade-plugin
+ 3.2.3
+
+
+ package
+
+ shade
+
+
+ true
+
+
+
+
+
+ maven-compiler-plugin
+ 3.8.1
+
+
+ 1.8
+
+
+
+
+
+
+ spigotmc-repo
+ https://hub.spigotmc.org/nexus/content/repositories/snapshots/
+
+
+
+
+ org.spigotmc
+ spigot-api
+ 1.15.2-R0.1-SNAPSHOT
+ provided
+
+
+
+ UTF-8
+ UTF-8
+
+
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..6664333
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,65 @@
+
+
+ 4.0.0
+
+ cn.cnklp.studio
+ UnionBanClientSpigot
+ 1.0-SNAPSHOT
+
+
+
+ spigotmc-repo
+ https://hub.spigotmc.org/nexus/content/repositories/snapshots/
+
+
+
+
+
+ org.spigotmc
+ spigot-api
+ 1.15.2-R0.1-SNAPSHOT
+ provided
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.11.0
+
+
+
+
+ UTF-8
+ UTF-8
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.2.3
+
+
+ package
+
+ shade
+
+
+ true
+
+
+
+
+
+ maven-compiler-plugin
+ 3.8.1
+
+
+ 1.8
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/BanTask.java b/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/BanTask.java
new file mode 100644
index 0000000..919b2b8
--- /dev/null
+++ b/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/BanTask.java
@@ -0,0 +1,46 @@
+package cn.cnklp.studio.UnionBanClientSpigot;
+
+import org.bukkit.command.CommandSender;
+import org.bukkit.scheduler.BukkitRunnable;
+
+public class BanTask extends BukkitRunnable {
+ private final String username;
+ private final CommandSender sender;
+ private final ClientPlugin plugin;
+
+ public BanTask(ClientPlugin plugin, CommandSender sender, String username) {
+ this.sender = sender;
+ this.plugin = plugin;
+ this.username = username;
+ }
+
+ @Override
+ public void run() {
+ String uuid;
+ sender.sendMessage("Querying UUID of player " + username + " from Mojang server...");
+ try {
+ uuid = PlayerUUID.FromUsername(username);
+ sender.sendMessage("UUID of player " + username + " is " + uuid + ".");
+ } catch (Exception e) {
+ if (e.getMessage().equals("Player does not exist!")) {
+ sender.sendMessage("Player " + username + " does not exist!");
+ } else {
+ sender.sendMessage("Cannot connect to Mojang server!");
+ }
+ return;
+ }
+ try {
+ PlayerUUID.Ban(plugin.ServerAddress, uuid);
+ sender.sendMessage("Banned player " + username + " successfully!");
+ } catch (Exception e) {
+ if (e.getMessage().equals("Record exists!")) {
+ sender.sendMessage("Player " + username + " is already in the UnionBan list!");
+ } else if (e.getMessage().equals("Not logged in!")) {
+ sender.sendMessage("You have not logged in!");
+ } else {
+ e.printStackTrace();
+ sender.sendMessage("Failed to ban player " + username + "!");
+ }
+ }
+ }
+}
diff --git a/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/ClientPlugin.java b/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/ClientPlugin.java
new file mode 100644
index 0000000..f15700f
--- /dev/null
+++ b/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/ClientPlugin.java
@@ -0,0 +1,33 @@
+package cn.cnklp.studio.UnionBanClientSpigot;
+
+import org.bukkit.Bukkit;
+import org.bukkit.event.HandlerList;
+import org.bukkit.plugin.java.JavaPlugin;
+import org.bukkit.scheduler.BukkitTask;
+
+import java.net.CookieHandler;
+import java.net.CookieManager;
+import java.net.CookiePolicy;
+import java.util.Objects;
+
+public class ClientPlugin extends JavaPlugin {
+ public String ServerAddress = "https://api.unionban.icu";
+ public BukkitTask login = null;
+
+ @Override
+ public void onEnable() {
+ CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
+ getServer().getPluginManager().registerEvents(new PlayerLoginListener(this), this);
+ getServer().getPluginManager().registerEvents(new WhitelistListener(this), this);
+ CommandsExecutor executor = new CommandsExecutor(this);
+ Objects.requireNonNull(this.getCommand("unionban")).setExecutor(executor);
+ Objects.requireNonNull(this.getCommand("unionban")).setTabCompleter(executor);
+ saveDefaultConfig();
+ new LoginTask(this, Bukkit.getConsoleSender()).runTaskAsynchronously(this);
+ }
+
+ @Override
+ public void onDisable() {
+ HandlerList.unregisterAll(this);
+ }
+}
diff --git a/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/CommandsExecutor.java b/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/CommandsExecutor.java
new file mode 100644
index 0000000..eb7a376
--- /dev/null
+++ b/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/CommandsExecutor.java
@@ -0,0 +1,105 @@
+package cn.cnklp.studio.UnionBanClientSpigot;
+
+import org.bukkit.Bukkit;
+import org.bukkit.OfflinePlayer;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabExecutor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CommandsExecutor implements TabExecutor {
+ private final ClientPlugin plugin;
+ private final List SubCommands = new ArrayList<>();
+
+ public CommandsExecutor(ClientPlugin plugin) {
+ this.plugin = plugin;
+ SubCommands.add("help");
+ SubCommands.add("status");
+ SubCommands.add("login");
+ SubCommands.add("logout");
+ SubCommands.add("ban");
+ SubCommands.add("pardon");
+ }
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
+ if (sender.hasPermission("unionban.account")) {
+ if (args.length == 3 && args[0].equals("login")) {
+ if (plugin.login != null) {
+ plugin.login.cancel();
+ plugin.login = null;
+ }
+ plugin.getConfig().set("username", args[1]);
+ plugin.getConfig().set("password", args[2]);
+ plugin.getConfig().set("api_key", "");
+ plugin.saveConfig();
+ new LoginTask(plugin, sender).runTaskAsynchronously(plugin);
+ return true;
+ }
+ if (args.length == 1 && args[0].equals("logout")) {
+ sender.sendMessage("Logging out...");
+ if (plugin.login != null) {
+ plugin.login.cancel();
+ plugin.login = null;
+ }
+ plugin.getConfig().set("username", "");
+ plugin.getConfig().set("password", "");
+ plugin.getConfig().set("api_key", "");
+ plugin.saveConfig();
+ new LogoutTask(plugin, sender).runTaskAsynchronously(plugin);
+ return true;
+ }
+ }
+ if (sender.hasPermission("unionban.ban")) {
+ if (args.length == 2 && args[0].equals("ban")) {
+ new BanTask(plugin, sender, args[1]).runTaskAsynchronously(plugin);
+ return true;
+ }
+ if (args.length == 2 && args[0].equals("pardon")) {
+ new PardonTask(plugin, sender, args[1]).runTaskAsynchronously(plugin);
+ return true;
+ }
+ }
+ if (sender.hasPermission("unionban.info")) {
+ if (args.length == 0) {
+ return false;
+ }
+ if (args.length == 1 && args[0].equals("help")) {
+ return false;
+ }
+ if (args.length == 1 && args[0].equals("status")) {
+ new GetServerStatusTask(plugin, sender).runTaskAsynchronously(plugin);
+ return true;
+ }
+ sender.sendMessage("Unknown command. Type \"/unionban help\" for help.");
+ return true;
+ }
+ sender.sendMessage("You do not have permission to execute this command!");
+ StringBuilder builder = new StringBuilder();
+ builder.append(cmd);
+ for (String arg : args) {
+ builder.append(" ");
+ builder.append(arg);
+ }
+ plugin.getLogger().warning(sender.getName() + " tried to execute command: " + builder);
+ return true;
+ }
+
+ @Override
+ public List onTabComplete(CommandSender sender, Command cmd, String alias, String[] args) {
+ List result = new ArrayList<>();
+ if (args.length == 1) {
+ result.addAll(SubCommands);
+ } else if (args.length == 2 && (args[0].equals("ban") || args[0].equals("pardon"))) {
+ for (OfflinePlayer player : Bukkit.getOfflinePlayers()) {
+ String name = player.getName();
+ if (name != null) {
+ result.add(name);
+ }
+ }
+ }
+ return result;
+ }
+}
diff --git a/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/GetServerStatusTask.java b/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/GetServerStatusTask.java
new file mode 100644
index 0000000..7d60a51
--- /dev/null
+++ b/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/GetServerStatusTask.java
@@ -0,0 +1,74 @@
+package cn.cnklp.studio.UnionBanClientSpigot;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.bukkit.command.CommandSender;
+import org.bukkit.scheduler.BukkitRunnable;
+
+import javax.net.ssl.HttpsURLConnection;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.URL;
+
+class ServerStatus {
+ public String version;
+}
+
+public class GetServerStatusTask extends BukkitRunnable {
+ private final ClientPlugin plugin;
+ private final CommandSender sender;
+
+ public GetServerStatusTask(ClientPlugin plugin, CommandSender sender) {
+ this.plugin = plugin;
+ this.sender = sender;
+ }
+
+ public static String GetVersion(String ServerAddress) throws Exception {
+ URL url = new URL(ServerAddress);
+ HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
+ con.setReadTimeout(5000);
+ con.setConnectTimeout(5000);
+ con.setRequestProperty("User-Agent", "Mozilla/5.0");
+ con.setRequestProperty("Content-Type", "application/json");
+ con.setRequestMethod("GET");
+ con.setDoOutput(true);
+
+ int responseCode = con.getResponseCode();
+ if (responseCode != 200) {
+ con.disconnect();
+ throw new Exception("HTTP Response Code: " + responseCode);
+ }
+ BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
+ StringBuilder builder = new StringBuilder();
+ String inputLine;
+ while ((inputLine = reader.readLine()) != null) {
+ builder.append(inputLine);
+ }
+ reader.close();
+
+ con.disconnect();
+
+ ObjectMapper objectMapper = new ObjectMapper();
+ objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ ServerStatus status = objectMapper.readValue(builder.toString(), ServerStatus.class);
+
+ return status.version;
+ }
+
+ @Override
+ public void run() {
+ sender.sendMessage("Querying server status...");
+ try {
+ String version = GetVersion(plugin.ServerAddress);
+ sender.sendMessage("UnionBan Server is ON! Version: " + version);
+ String username = LoginTask.GetLoginStatus(plugin.ServerAddress).username;
+ sender.sendMessage("Logged in as " + plugin.getConfig().getString("username") + ".");
+ } catch (Exception e) {
+ if (e.getMessage().equals("Not logged in!")) {
+ sender.sendMessage("You have not logged in!");
+ } else {
+ sender.sendMessage("Failed to connect to UnionBan server.");
+ }
+ }
+ }
+}
diff --git a/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/KickPlayerTask.java b/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/KickPlayerTask.java
new file mode 100644
index 0000000..c572bb1
--- /dev/null
+++ b/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/KickPlayerTask.java
@@ -0,0 +1,20 @@
+package cn.cnklp.studio.UnionBanClientSpigot;
+
+import org.bukkit.Bukkit;
+import org.bukkit.scheduler.BukkitRunnable;
+
+import java.util.Objects;
+
+public class KickPlayerTask extends BukkitRunnable {
+ private final String username;
+ private final ClientPlugin plugin;
+
+ public KickPlayerTask(ClientPlugin plugin, String username) {
+ this.username = username;
+ this.plugin = plugin;
+ }
+
+ public void run() {
+ Objects.requireNonNull(Bukkit.getPlayer(username)).kickPlayer("You are in the UnionBan list!");
+ }
+}
diff --git a/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/LoginTask.java b/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/LoginTask.java
new file mode 100644
index 0000000..dd654de
--- /dev/null
+++ b/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/LoginTask.java
@@ -0,0 +1,216 @@
+package cn.cnklp.studio.UnionBanClientSpigot;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.bukkit.Bukkit;
+import org.bukkit.command.CommandSender;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.scheduler.BukkitRunnable;
+
+import javax.net.ssl.HttpsURLConnection;
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+
+class LoginStatus {
+ public String username;
+ public String api_key;
+}
+
+class Expire {
+ public int expire;
+}
+
+class UserInfo {
+ public String account;
+ public String password;
+}
+
+public class LoginTask extends BukkitRunnable {
+ private final ClientPlugin plugin;
+ private final CommandSender sender;
+
+ public LoginTask(ClientPlugin plugin, CommandSender sender) {
+ this.plugin = plugin;
+ this.sender = sender;
+ }
+
+ private static int LoginViaKey(String ServerAddress, String api_key) throws Exception {
+ LoginStatus key = new LoginStatus();
+ key.api_key = api_key;
+
+ ObjectMapper mapper = new ObjectMapper();
+ String json = mapper.writeValueAsString(key);
+
+ String Address = ServerAddress + "/session/";
+ URL url = new URL(Address);
+ HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
+ con.setReadTimeout(5000);
+ con.setConnectTimeout(5000);
+ con.setRequestProperty("User-Agent", "Mozilla/5.0");
+ con.setRequestProperty("Content-Type", "application/json");
+ con.setRequestMethod("PUT");
+ con.setDoOutput(true);
+
+ con.connect();
+
+ DataOutputStream stream = new DataOutputStream(con.getOutputStream());
+ stream.writeBytes(json);
+ stream.flush();
+ stream.close();
+
+ int responseCode = con.getResponseCode();
+
+ if (responseCode != 200) {
+ con.disconnect();
+ throw new Exception("Login failed!");
+ }
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
+ StringBuilder builder = new StringBuilder();
+ String inputLine;
+ while ((inputLine = reader.readLine()) != null) {
+ builder.append(inputLine);
+ }
+ reader.close();
+ con.disconnect();
+
+ mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ Expire expire = mapper.readValue(builder.toString(), Expire.class);
+
+ return expire.expire;
+ }
+
+ private static int LoginViaUsername(String ServerAddress, String username, String password) throws Exception {
+ UserInfo info = new UserInfo();
+ info.account = username;
+ info.password = password;
+
+ ObjectMapper mapper = new ObjectMapper();
+ String json = mapper.writeValueAsString(info);
+
+ String Address = ServerAddress + "/session/";
+ URL url = new URL(Address);
+ HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
+ con.setReadTimeout(5000);
+ con.setConnectTimeout(5000);
+ con.setRequestProperty("User-Agent", "Mozilla/5.0");
+ con.setRequestProperty("Content-Type", "application/json");
+ con.setRequestMethod("POST");
+ con.setDoOutput(true);
+
+ con.connect();
+
+ DataOutputStream stream = new DataOutputStream(con.getOutputStream());
+ stream.writeBytes(json);
+ stream.flush();
+ stream.close();
+
+ int responseCode = con.getResponseCode();
+
+ if (responseCode != 200) {
+ con.disconnect();
+ throw new Exception("Login failed!");
+ }
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
+ StringBuilder builder = new StringBuilder();
+ String inputLine;
+ while ((inputLine = reader.readLine()) != null) {
+ builder.append(inputLine);
+ }
+ reader.close();
+ con.disconnect();
+
+ mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ Expire expire = mapper.readValue(builder.toString(), Expire.class);
+
+ return expire.expire;
+ }
+
+ public static LoginStatus GetLoginStatus(String ServerAddress) throws Exception {
+ URL url = new URL(ServerAddress + "/user/");
+ HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
+ con.setReadTimeout(5000);
+ con.setConnectTimeout(5000);
+ con.setRequestProperty("User-Agent", "Mozilla/5.0");
+ con.setRequestProperty("Content-Type", "application/json");
+ con.setRequestMethod("GET");
+ con.setDoOutput(true);
+
+ int responseCode = con.getResponseCode();
+ if (responseCode != 200) {
+ con.disconnect();
+ throw new Exception("Not logged in!");
+ }
+ BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
+ StringBuilder builder = new StringBuilder();
+ String inputLine;
+ while ((inputLine = reader.readLine()) != null) {
+ builder.append(inputLine);
+ }
+ reader.close();
+
+ con.disconnect();
+
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+
+ return mapper.readValue(builder.toString(), LoginStatus.class);
+ }
+
+ @Override
+ public void run() {
+ FileConfiguration config = plugin.getConfig();
+ String username = config.getString("username");
+ String password = config.getString("password");
+ String api_key = config.getString("api_key");
+
+ sender.sendMessage("Logging in via api_key...");
+
+ if (api_key != null && !api_key.isEmpty()) {
+ try {
+ int expire = LoginViaKey(plugin.ServerAddress, api_key);
+ sender.sendMessage("Login success. The session will expires after " + expire + " seconds.");
+ plugin.login = new LoginTask(plugin, Bukkit.getConsoleSender()).runTaskLaterAsynchronously(plugin, expire * 20);
+ sender.sendMessage("Automated login scheduled.");
+ return;
+ } catch (Exception e) {
+ if (!e.getMessage().equals("Login failed!")) {
+ sender.sendMessage("Failed to connect to UnionBan server.");
+ sender.sendMessage("Failed to login!");
+ return;
+ }
+ }
+ }
+
+ sender.sendMessage("Cannot login via api_key. Trying username and password...");
+
+ if (username != null && username.isEmpty()) {
+ sender.sendMessage("Username is empty.");
+ sender.sendMessage("Failed to login!");
+ return;
+ }
+
+ try {
+ int expire = LoginViaUsername(plugin.ServerAddress, username, password);
+ sender.sendMessage("Login success. Updating api_key...");
+ api_key = GetLoginStatus(plugin.ServerAddress).api_key;
+ sender.sendMessage("Got new api_key: " + api_key + ". Saving to file...");
+ config.set("api_key", api_key);
+ plugin.saveConfig();
+ sender.sendMessage("The session will expires after " + expire + " seconds.");
+ plugin.login = new LoginTask(plugin, Bukkit.getConsoleSender()).runTaskLaterAsynchronously(plugin, expire * 20);
+ sender.sendMessage("Automated login scheduled.");
+ } catch (Exception e) {
+ e.printStackTrace();
+ if (e.getMessage().equals("Login failed!")) {
+ sender.sendMessage("Cannot login via username and password!");
+ } else {
+ sender.sendMessage("Failed to connect to UnionBan server.");
+ }
+ sender.sendMessage("Failed to login!");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/LogoutTask.java b/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/LogoutTask.java
new file mode 100644
index 0000000..58f14a0
--- /dev/null
+++ b/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/LogoutTask.java
@@ -0,0 +1,54 @@
+package cn.cnklp.studio.UnionBanClientSpigot;
+
+import org.bukkit.command.CommandSender;
+import org.bukkit.scheduler.BukkitRunnable;
+
+import javax.net.ssl.HttpsURLConnection;
+import java.net.URL;
+
+public class LogoutTask extends BukkitRunnable {
+ private final ClientPlugin plugin;
+ private final CommandSender sender;
+
+ public LogoutTask(ClientPlugin plugin, CommandSender sender) {
+ this.plugin = plugin;
+ this.sender = sender;
+ }
+
+ private static void Logout(String ServerAddress) throws Exception {
+ String Address = ServerAddress + "/session/";
+ URL url = new URL(Address);
+ HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
+ con.setReadTimeout(5000);
+ con.setConnectTimeout(5000);
+ con.setRequestProperty("User-Agent", "Mozilla/5.0");
+ con.setRequestProperty("Content-Type", "application/json");
+ con.setRequestMethod("DELETE");
+ con.setDoOutput(true);
+
+ con.connect();
+
+ int responseCode = con.getResponseCode();
+
+ if (responseCode != 204) {
+ con.disconnect();
+ throw new Exception("You have not logged in!");
+ }
+
+ con.disconnect();
+ }
+
+ @Override
+ public void run() {
+ try {
+ Logout(plugin.ServerAddress);
+ sender.sendMessage("Logged out successfully.");
+ } catch (Exception e) {
+ if (e.getMessage().equals("You have not logged in!")) {
+ sender.sendMessage("You have not logged in!");
+ } else {
+ sender.sendMessage("Cannot connect to UnionBan server!");
+ }
+ }
+ }
+}
diff --git a/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/PardonTask.java b/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/PardonTask.java
new file mode 100644
index 0000000..c2ebf60
--- /dev/null
+++ b/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/PardonTask.java
@@ -0,0 +1,46 @@
+package cn.cnklp.studio.UnionBanClientSpigot;
+
+import org.bukkit.command.CommandSender;
+import org.bukkit.scheduler.BukkitRunnable;
+
+public class PardonTask extends BukkitRunnable {
+ private final String username;
+ private final CommandSender sender;
+ private final ClientPlugin plugin;
+
+ public PardonTask(ClientPlugin plugin, CommandSender sender, String username) {
+ this.sender = sender;
+ this.plugin = plugin;
+ this.username = username;
+ }
+
+ @Override
+ public void run() {
+ String uuid;
+ sender.sendMessage("Querying UUID of player " + username + " from Mojang server...");
+ try {
+ uuid = PlayerUUID.FromUsername(username);
+ sender.sendMessage("UUID of player " + username + " is " + uuid + ".");
+ } catch (Exception e) {
+ if (e.getMessage().equals("Player does not exist!")) {
+ sender.sendMessage("Player " + username + " does not exist!");
+ } else {
+ sender.sendMessage("Cannot connect to Mojang server!");
+ }
+ return;
+ }
+ try {
+ PlayerUUID.Pardon(plugin.ServerAddress, uuid);
+ sender.sendMessage("Removed player " + username + " from UnionBan list successfully!");
+ } catch (Exception e) {
+ if (e.getMessage().equals("Record does not exist!")) {
+ sender.sendMessage("Player " + username + " is not in the UnionBan list!");
+ } else if (e.getMessage().equals("Not logged in!")) {
+ sender.sendMessage("You have not logged in!");
+ } else {
+ e.printStackTrace();
+ sender.sendMessage("Failed to remove player " + username + " from UnionBan list!");
+ }
+ }
+ }
+}
diff --git a/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/PlayerLoginListener.java b/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/PlayerLoginListener.java
new file mode 100644
index 0000000..cbd64ec
--- /dev/null
+++ b/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/PlayerLoginListener.java
@@ -0,0 +1,20 @@
+package cn.cnklp.studio.UnionBanClientSpigot;
+
+import org.bukkit.Bukkit;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerLoginEvent;
+
+public final class PlayerLoginListener implements Listener {
+ private final ClientPlugin plugin;
+
+ public PlayerLoginListener(ClientPlugin plugin) {
+ this.plugin = plugin;
+ }
+
+ @EventHandler
+ public void onLogin(PlayerLoginEvent event) {
+ Bukkit.getLogger().info("Player " + event.getPlayer().getName() + " is logging in!");
+ new PlayerLoginTask(plugin, event.getPlayer().getName()).runTaskAsynchronously(plugin);
+ }
+}
diff --git a/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/PlayerLoginTask.java b/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/PlayerLoginTask.java
new file mode 100644
index 0000000..8a2b98e
--- /dev/null
+++ b/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/PlayerLoginTask.java
@@ -0,0 +1,29 @@
+package cn.cnklp.studio.UnionBanClientSpigot;
+
+import org.bukkit.Bukkit;
+import org.bukkit.scheduler.BukkitRunnable;
+
+public class PlayerLoginTask extends BukkitRunnable {
+ private final String username;
+ private final ClientPlugin plugin;
+
+ public PlayerLoginTask(ClientPlugin plugin, String username) {
+ this.plugin = plugin;
+ this.username = username;
+ }
+
+ @Override
+ public void run() {
+ try {
+ String uuid = PlayerUUID.FromUsername(username);
+ plugin.getLogger().info("UUID of " + username + ": " + uuid);
+ boolean isBanned = PlayerUUID.IsBan(plugin.ServerAddress, uuid);
+ plugin.getLogger().info("Player " + username + " is banned: " + isBanned);
+ if (isBanned) {
+ new KickPlayerTask(plugin, username).runTask(plugin);
+ }
+ } catch (Exception e) {
+ Bukkit.getLogger().warning("Failed to get information about player " + username + "!");
+ }
+ }
+}
diff --git a/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/PlayerUUID.java b/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/PlayerUUID.java
new file mode 100644
index 0000000..deb1ff4
--- /dev/null
+++ b/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/PlayerUUID.java
@@ -0,0 +1,121 @@
+package cn.cnklp.studio.UnionBanClientSpigot;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import javax.net.ssl.HttpsURLConnection;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.URL;
+
+class MojangUserInfo {
+ public String id;
+}
+
+public class PlayerUUID {
+ public static boolean IsBan(String ServerAddress, String uuid) throws Exception {
+ String Address = ServerAddress + "/record/uuid/" + uuid;
+ URL url = new URL(Address);
+ HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
+ con.setReadTimeout(5000);
+ con.setConnectTimeout(5000);
+ con.setRequestProperty("User-Agent", "Mozilla/5.0");
+ con.setRequestProperty("Content-Type", "application/json");
+ con.setRequestMethod("GET");
+ con.setDoOutput(true);
+
+ int responseCode = con.getResponseCode();
+ con.disconnect();
+
+ if (responseCode == 200) {
+ return true;
+ } else if (responseCode == 404) {
+ return false;
+ } else {
+ throw new Exception("Failed to connect to UnionBan server!");
+ }
+ }
+
+ public static String FromUsername(String username) throws Exception {
+ String Address = "https://api.mojang.com/users/profiles/minecraft/" + username;
+ URL url = new URL(Address);
+ HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
+ con.setReadTimeout(5000);
+ con.setConnectTimeout(5000);
+ con.setRequestProperty("User-Agent", "Mozilla/5.0");
+ con.setRequestProperty("Content-Type", "application/json");
+ con.setRequestMethod("GET");
+ con.setDoOutput(true);
+
+ int responseCode = con.getResponseCode();
+ if (responseCode == 204) {
+ throw new Exception("Player does not exist!");
+ } else if (responseCode != 200) {
+ con.disconnect();
+ throw new Exception("Failed to connect to Mojang API!");
+ }
+ BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
+ StringBuilder builder = new StringBuilder();
+ String inputLine;
+ while ((inputLine = reader.readLine()) != null) {
+ builder.append(inputLine);
+ }
+ reader.close();
+
+ con.disconnect();
+
+ ObjectMapper objectMapper = new ObjectMapper();
+ objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ MojangUserInfo mojangUserInfo = objectMapper.readValue(builder.toString(), MojangUserInfo.class);
+
+ return mojangUserInfo.id.substring(0, 8) + "-" + mojangUserInfo.id.substring(8, 12) + "-" + mojangUserInfo.id.substring(12, 16) + "-" + mojangUserInfo.id.substring(16, 20) + "-" + mojangUserInfo.id.substring(20, 32);
+ }
+
+ public static void Ban(String ServerAddress, String uuid) throws Exception {
+ String Address = ServerAddress + "/record/uuid/" + uuid;
+ URL url = new URL(Address);
+ HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
+ con.setReadTimeout(5000);
+ con.setConnectTimeout(5000);
+ con.setRequestProperty("User-Agent", "Mozilla/5.0");
+ con.setRequestProperty("Content-Type", "application/json");
+ con.setRequestMethod("PUT");
+ con.setDoOutput(true);
+
+ con.connect();
+ int responseCode = con.getResponseCode();
+ con.disconnect();
+
+ if (responseCode == 409) {
+ throw new Exception("Record exists!");
+ } else if (responseCode == 403) {
+ throw new Exception("Not logged in!");
+ } else if (responseCode != 200) {
+ throw new Exception("Ban failed!");
+ }
+ }
+
+ public static void Pardon(String ServerAddress, String uuid) throws Exception {
+ String Address = ServerAddress + "/record/uuid/" + uuid;
+ URL url = new URL(Address);
+ HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
+ con.setReadTimeout(5000);
+ con.setConnectTimeout(5000);
+ con.setRequestProperty("User-Agent", "Mozilla/5.0");
+ con.setRequestProperty("Content-Type", "application/json");
+ con.setRequestMethod("DELETE");
+ con.setDoOutput(true);
+
+ con.connect();
+ int responseCode = con.getResponseCode();
+ con.disconnect();
+
+ if (responseCode == 404) {
+ throw new Exception("Record does not exist!");
+ } else if (responseCode == 403) {
+ throw new Exception("Not logged in!");
+ } else if (responseCode != 204) {
+ throw new Exception("Pardon failed!");
+ }
+ }
+}
diff --git a/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/WhitelistListener.java b/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/WhitelistListener.java
new file mode 100644
index 0000000..66b1951
--- /dev/null
+++ b/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/WhitelistListener.java
@@ -0,0 +1,32 @@
+package cn.cnklp.studio.UnionBanClientSpigot;
+
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerCommandPreprocessEvent;
+import org.bukkit.event.server.ServerCommandEvent;
+
+public class WhitelistListener implements Listener {
+ private final ClientPlugin plugin;
+
+ public WhitelistListener(ClientPlugin plugin) {
+ this.plugin = plugin;
+ }
+
+ void onWhitelist(String prefix, String command) {
+ if (command.startsWith(prefix) && command.length() > prefix.length() + 2 && command.charAt(prefix.length() + 1) != ' ') {
+ new WhitelistTask(plugin, command.substring(prefix.length() + 1)).runTask(plugin);
+ }
+ }
+
+ @EventHandler
+ public void PlayerAction(PlayerCommandPreprocessEvent event) {
+ String prefix = "/whitelist add";
+ onWhitelist(prefix, event.getMessage());
+ }
+
+ @EventHandler
+ public void ServerAction(ServerCommandEvent event) {
+ String prefix = "whitelist add";
+ onWhitelist(prefix, event.getCommand());
+ }
+}
diff --git a/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/WhitelistTask.java b/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/WhitelistTask.java
new file mode 100644
index 0000000..564efc8
--- /dev/null
+++ b/src/main/java/cn/cnklp/studio/UnionBanClientSpigot/WhitelistTask.java
@@ -0,0 +1,30 @@
+package cn.cnklp.studio.UnionBanClientSpigot;
+
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.scheduler.BukkitRunnable;
+
+public class WhitelistTask extends BukkitRunnable {
+ private final String username;
+ private final ClientPlugin plugin;
+
+ public WhitelistTask(ClientPlugin plugin, String username) {
+ this.username = username;
+ this.plugin = plugin;
+ }
+
+ @Override
+ public void run() {
+ try {
+ String uuid = PlayerUUID.FromUsername(username);
+ plugin.getLogger().info("UUID of " + username + ": " + uuid);
+ boolean isBanned = PlayerUUID.IsBan(plugin.ServerAddress, uuid);
+ plugin.getLogger().info("Player " + username + " is banned: " + isBanned);
+ if (isBanned) {
+ Bukkit.broadcastMessage(ChatColor.RED + "[UnionBan] Player " + username + " is in the UnionBan list!");
+ }
+ } catch (Exception e) {
+ Bukkit.getLogger().warning("Failed to get information about player " + username + "!");
+ }
+ }
+}
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
new file mode 100644
index 0000000..e30c526
--- /dev/null
+++ b/src/main/resources/config.yml
@@ -0,0 +1,4 @@
+# Do NOT change this file manually!
+username: ""
+password: ""
+api_key: ""
\ No newline at end of file
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
new file mode 100644
index 0000000..850dc1a
--- /dev/null
+++ b/src/main/resources/plugin.yml
@@ -0,0 +1,24 @@
+name: UnionBan-Client
+version: "1.0"
+api-version: "1.15"
+main: cn.cnklp.studio.UnionBanClientSpigot.ClientPlugin
+commands:
+ unionban:
+ description: UnionBan-Client
+ usage: |
+ /unionban help - Show this help.
+ /unionban status - Show status of UnionBan plugin and server.
+ /unionban login - Login to UnionBan server.
+ /unionban logout - Logout from UnionBan server.
+ /unionban ban - Add to UnionBan server(requires login).
+ /unionban pardon - Remove from UnionBan server(requires login).
+permissions:
+ unionban.info:
+ description: Allow user to get help and status of UnionBan plugin and server.
+ default: true
+ unionban.account:
+ description: Allow user to login or logout.
+ default: op
+ unionban.ban:
+ description: Allow user to add or remove player from UnionBan list.
+ default: op