diff --git a/src/com/cypherx/xauth/CommandHandler.java b/src/com/cypherx/xauth/CommandHandler.java new file mode 100644 index 0000000..e19b536 --- /dev/null +++ b/src/com/cypherx/xauth/CommandHandler.java @@ -0,0 +1,265 @@ +package com.cypherx.xauth; + +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.entity.Player; +import org.bukkit.plugin.PluginDescriptionFile; + +import com.cypherx.xauth.Settings.Keys; + +public class CommandHandler +{ + private final xAuth plugin; + PluginDescriptionFile pdfFile; + + public CommandHandler(final xAuth instance) + { + plugin = instance; + pdfFile = plugin.getDescription(); + } + + public void handlePlayerCommand(Player player, Command cmd, String[] args) + { + if (cmd.getName().equalsIgnoreCase("register")) + { + if (args.length != 1) + player.sendMessage(xAuth.strings.getString("register.usage")); + //player.sendMessage(ChatColor.RED + "Correct Usage: /register "); + else if (!xAuth.settings.getBool(Keys.REG_ENABLED)) + player.sendMessage(xAuth.strings.getString("register.err.disabled")); + //player.sendMessage(ChatColor.RED + "Registrations are currently disabled."); + else if (plugin.isRegistered(player.getName())) + player.sendMessage(xAuth.strings.getString("register.err.registered")); + //player.sendMessage(ChatColor.RED + "You are already registered."); + else if (args[0].length() < xAuth.settings.getInt(Keys.PW_MIN_LENGTH)) + //player.sendMessage(xAuth.strings.get(Strings.Keys.REG_ERR_REGISTERED, xAuth.settings.getInt(Keys.PW_MIN_LENGTH))); + player.sendMessage(xAuth.strings.getString("register.err.password", xAuth.settings.getInt(Keys.PW_MIN_LENGTH))); + //player.sendMessage(ChatColor.RED + "Your password must contain " + xAuth.settings.getInt(Keys.PW_MIN_LENGTH) + " or more characters."); + else + { + plugin.addAuth(player.getName(), args[0]); + plugin.login(player); + player.sendMessage(xAuth.strings.getString("register.success1")); + player.sendMessage(xAuth.strings.getString("register.success2", args[0])); + //player.sendMessage(ChatColor.GREEN + "You have successfully registered!"); + //player.sendMessage(ChatColor.GREEN + "Your password is: " + ChatColor.WHITE + args[0]); + System.out.println("[" + pdfFile.getName() + "] Player '" + player.getName() + "' has registered"); + } + } + else if (cmd.getName().equalsIgnoreCase("login")) + { + if (args.length != 1) + player.sendMessage(ChatColor.RED + "Correct Usage: /login "); + else if (!plugin.isRegistered(player.getName())) + player.sendMessage(ChatColor.RED + "You are not registered."); + else if (plugin.sessionExists(player.getName())) + player.sendMessage(ChatColor.RED + "You are already logged in."); + else + { + if (plugin.checkPass(player, args[0])) + { + plugin.login(player); + player.sendMessage(ChatColor.GREEN + "You are now logged in."); + System.out.println("[" + pdfFile.getName() + "] Player '" + player.getName() + "' has authenticated"); + } + else + player.sendMessage(ChatColor.RED + "Incorrect password!"); + } + } + else if (cmd.getName().equalsIgnoreCase("changepw")) + { + if (plugin.canUseCommand(player, "xauth.admin.changepw")) + { + if (args.length == 1) + { + if (!plugin.sessionExists(player.getName())) + player.sendMessage(ChatColor.RED + "You must login before changing your password!"); + else if (!xAuth.settings.getBool(Keys.ALLOW_CHANGEPW)) + player.sendMessage(ChatColor.RED + "Password changes are currently disabled."); + else if (args[0].length() < xAuth.settings.getInt(Keys.PW_MIN_LENGTH)) + player.sendMessage(ChatColor.RED + "Your password must contain " + xAuth.settings.getInt(Keys.PW_MIN_LENGTH) + " or more characters."); + else + { + plugin.changePass(player.getName(), args[0]); + player.sendMessage(ChatColor.GREEN + "Your password has been changed to: " + ChatColor.WHITE + args[0]); + System.out.println("[" + pdfFile.getName() + "] Player '" + player.getName() + "' has changed their password"); + } + } + else if (args.length == 2) + { + if (!plugin.isRegistered(args[0])) + player.sendMessage(ChatColor.RED + "This player is not registered"); + else + { + plugin.changePass(args[0], args[1]); + player.sendMessage(ChatColor.GREEN + args[0] + "'s password has been changed to: " + ChatColor.WHITE + args[1]); + System.out.println("[" + pdfFile.getName() + "] " + player.getName() + " has changed " + args[0] + "'s password"); + } + } + else + { + player.sendMessage(ChatColor.RED + "Correct usage: /changepw [player] "); + } + } + else + { + if (args.length != 1) + player.sendMessage(ChatColor.RED + "Correct Usage: /changepw "); + else if (!plugin.sessionExists(player.getName())) + player.sendMessage(ChatColor.RED + "You must login before changing your password!"); + else if (!xAuth.settings.getBool(Keys.ALLOW_CHANGEPW)) + player.sendMessage(ChatColor.RED + "Password changes are currently disabled."); + else if (args[0].length() < xAuth.settings.getInt(Keys.PW_MIN_LENGTH)) + player.sendMessage(ChatColor.RED + "Your password must contain " + xAuth.settings.getInt(Keys.PW_MIN_LENGTH) + " or more characters."); + else + { + plugin.changePass(player.getName(), args[0]); + player.sendMessage(ChatColor.GREEN + "Your password has been changed to: " + ChatColor.WHITE + args[0]); + System.out.println("[" + pdfFile.getName() + "] Player '" + player.getName() + "' has changed their password"); + } + } + } + else if (cmd.getName().equalsIgnoreCase("unregister")) + { + if (plugin.canUseCommand(player, "xauth.admin.unregister")) + { + if (args.length != 1) + player.sendMessage(ChatColor.RED + "Correct Usage: /unregister "); + else if (!plugin.isRegistered(args[0])) + player.sendMessage(ChatColor.RED + "This player is not registered!"); + else + { + plugin.removeAuth(args[0]); + player.sendMessage(ChatColor.GREEN + args[0] + " has been unregistered."); + System.out.println("[" + pdfFile.getName() + "] " + player.getName() + " has unregistered " + args[0]); + } + } + } + else if (cmd.getName().equalsIgnoreCase("authreload")) + { + if (plugin.canUseCommand(player, "xauth.admin.reload")) + { + plugin.reload(); + player.sendMessage(ChatColor.YELLOW + "[" + pdfFile.getName() + "] Configuration & Accounts reloaded"); + } + } + else if (cmd.getName().equalsIgnoreCase("toggle")) + { + Boolean canToggleReg = plugin.canUseCommand(player, "xauth.admin.toggle.reg"); + Boolean canTogglePw = plugin.canUseCommand(player, "xauth.admin.toggle.changepw"); + Boolean canToggleSave = plugin.canUseCommand(player, "xauth.admin.toggle.autosave"); + + if (canToggleReg || canTogglePw || canToggleSave) + { + if (args.length != 1) + player.sendMessage(ChatColor.RED + "Correct Usage: /toggle "); + else if (args[0].equalsIgnoreCase("reg")) + { + if (!canToggleReg) + player.sendMessage(ChatColor.RED + "You aren't allow to toggle that!"); + else + { + Boolean b = xAuth.settings.getBool(Keys.REG_ENABLED); + xAuth.settings.update(Keys.REG_ENABLED, (b ? false : true)); + player.sendMessage(ChatColor.YELLOW + "[" + pdfFile.getName() + "] Registrations are now " + (b ? "disabled." : "enabled.")); + System.out.println("[" + pdfFile.getName() + "] " + player.getName() + " has " + (b ? "disabled" : "enabled") + " registrations"); + } + + } + else if (args[0].equalsIgnoreCase("changepw")) + { + if (!canTogglePw) + player.sendMessage(ChatColor.RED + "You aren't allow to toggle that!"); + else + { + Boolean b = xAuth.settings.getBool(Keys.ALLOW_CHANGEPW); + xAuth.settings.update(Keys.ALLOW_CHANGEPW, (b ? false : true)); + player.sendMessage(ChatColor.YELLOW + "[" + pdfFile.getName() + "] Password changes are now " + (b ? "disabled." : "enabled.")); + System.out.println("[" + pdfFile.getName() + "] " + player.getName() + " has " + (b ? "disabled" : "enabled") + " password changes"); + } + } + else if (args[0].equalsIgnoreCase("autosave")) + { + if (!canToggleSave) + player.sendMessage(ChatColor.RED + "You aren't allow to toggle that!"); + else + { + Boolean b = xAuth.settings.getBool(Keys.AUTOSAVE); + xAuth.settings.update(Keys.AUTOSAVE, (b ? false : true)); + player.sendMessage(ChatColor.YELLOW + "[" + pdfFile.getName() + "] Autosaving of account modifications is now " + (b ? "disabled." : "enabled.")); + System.out.println("[" + pdfFile.getName() + "] " + player.getName() + " has " + (b ? "disabled" : "enabled") + " autosave"); + } + } + else + player.sendMessage(ChatColor.RED + "Correct Usage: /toggle "); + } + } + } + + public void handleConsoleCommand(Command cmd, String[] args) + { + if (cmd.getName().equalsIgnoreCase("register")) + { + if (args.length != 2) + System.out.println("Correct Usage: /register "); + else if (plugin.isRegistered(args[0])) + System.out.println("Player '" + args[0] + "' is already registered"); + else + { + plugin.addAuth(args[0], args[1]); + System.out.println(args[0] + " has been registered with password: " + args[1]); + } + } + else if (cmd.getName().equalsIgnoreCase("changepw")) + { + if (args.length != 2) + System.out.println("Correct Usage: /changepw "); + else if (!plugin.isRegistered(args[0])) + System.out.println("Player '" + args[0] + "' is not registered"); + else + { + plugin.changePass(args[0], args[1]); + System.out.println(args[0] + "'s password has been changed to: " + args[1]); + } + } + else if (cmd.getName().equalsIgnoreCase("unregister")) + { + if (args.length != 1) + System.out.println("Correct Usage: /unregister "); + else if (!plugin.isRegistered(args[0])) + System.out.println("Player '" + args[0] + "' is not registered"); + else + { + plugin.removeAuth(args[0]); + System.out.println(args[0] + " has been unregistered"); + } + } + else if (cmd.getName().equalsIgnoreCase("authreload")) + plugin.reload(); + else if (cmd.getName().equalsIgnoreCase("toggle")) + { + if (args.length != 1) + System.out.println("Correct Usage: /toggle "); + else if (args[0].equalsIgnoreCase("reg")) + { + Boolean b = xAuth.settings.getBool(Keys.REG_ENABLED); + xAuth.settings.update(Keys.REG_ENABLED, (b ? false : true)); + System.out.println("[" + pdfFile.getName() + "] Registrations are now " + (b ? "disabled" : "enabled")); + } + else if (args[0].equalsIgnoreCase("changepw")) + { + Boolean b = xAuth.settings.getBool(Keys.ALLOW_CHANGEPW); + xAuth.settings.update(Keys.ALLOW_CHANGEPW, (b ? false : true)); + System.out.println("[" + pdfFile.getName() + "] Password changes are now " + (b ? "disabled" : "enabled")); + } + else if (args[0].equalsIgnoreCase("autosave")) + { + Boolean b = xAuth.settings.getBool(Keys.AUTOSAVE); + xAuth.settings.update(Keys.AUTOSAVE, (b ? false : true)); + System.out.println("[" + pdfFile.getName() + "] Autosaving of account modifications is now " + (b ? "disabled" : "enabled")); + } + else + System.out.println("Correct Usage: /toggle "); + } + } +} \ No newline at end of file diff --git a/src/com/cypherx/xauth/Session.java b/src/com/cypherx/xauth/Session.java new file mode 100644 index 0000000..9679bfd --- /dev/null +++ b/src/com/cypherx/xauth/Session.java @@ -0,0 +1,39 @@ +package com.cypherx.xauth; + +import java.util.Date; + +import org.bukkit.entity.Player; + +public class Session +{ + private Player player; + private Date loginTime; + private String addr; + + public Session(Player player) + { + this.player = player; + loginTime = new Date(); + addr = player.getAddress().getAddress().getHostAddress(); + } + + public Boolean isExpired(Date timeoutTime) + { + if (timeoutTime.compareTo(new Date()) < 0) + return true; + + return false; + } + + public Boolean isValidAddr(String testAddr) + { + if (addr.equals(testAddr)) + return true; + + return false; + } + + public Player getPlayer() { return player; } + + public Long getLoginTime() { return loginTime.getTime(); } +} \ No newline at end of file diff --git a/src/com/cypherx/xauth/Settings.java b/src/com/cypherx/xauth/Settings.java new file mode 100644 index 0000000..476e0ef --- /dev/null +++ b/src/com/cypherx/xauth/Settings.java @@ -0,0 +1,116 @@ +package com.cypherx.xauth; + +import java.io.File; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +import org.bukkit.util.config.Configuration; + +public class Settings +{ + interface Keys + { + public static final String REG_ENABLED = "registration.enabled"; + public static final String ALLOW_CHANGE_PW = "misc.allow-change-pw";//old allow-changepw + public static final String ALLOW_CHANGEPW = "misc.allow-changepw";//new allow-changepw + public static final String SAVE_ON_CHANGE = "misc.save-on-change";//old autosave + public static final String AUTOSAVE = "misc.autosave";//new autosave + public static final String SESSION_TIMEOUT = "session.timeout"; + public static final String NOTIFY_LIMIT = "notify.limit"; + public static final String PW_MIN_LENGTH = "registration.pw-min-length"; + public static final String ALLOWED_CMDS = "misc.allowed-cmds"; + } + + private static Configuration config; + private static final ConcurrentHashMap settings = new ConcurrentHashMap(); + + public Settings (File file) + { + config = new Configuration(file); + load(); + } + + public void load() + { + config.load(); + + //Booleans + String key = Keys.REG_ENABLED; + if (config.getProperty(key) == null) + config.setProperty(key, true); + settings.put(key, config.getBoolean(key, true)); + + key = Keys.ALLOW_CHANGE_PW; + if (config.getProperty(key) != null) + { + settings.put(key, config.getBoolean(key, true)); + config.removeProperty(key); + } + key = Keys.ALLOW_CHANGEPW; + if (config.getProperty(key) == null) + config.setProperty(key, getBool(Keys.ALLOW_CHANGE_PW) == null ? true : getBool(Keys.ALLOW_CHANGE_PW)); + settings.put(key, config.getBoolean(key, true)); + + key = Keys.SAVE_ON_CHANGE; + if (config.getProperty(key) != null) + { + settings.put(key, config.getBoolean(key, true)); + config.removeProperty(key); + } + key = Keys.AUTOSAVE; + if (config.getProperty(key) == null) + config.setProperty(key, getBool(Keys.SAVE_ON_CHANGE) == null ? true : getBool(Keys.SAVE_ON_CHANGE)); + settings.put(key, config.getBoolean(key, true)); + //end Booleans + + //Integers + key = Keys.SESSION_TIMEOUT; + if (config.getProperty(key) == null) + config.setProperty(key, 3600); + settings.put(key, config.getInt(key, 3600)); + + key = Keys.NOTIFY_LIMIT; + if (config.getProperty(key) == null) + config.setProperty(key, 5); + settings.put(key, config.getInt(key, 5)); + + key = Keys.PW_MIN_LENGTH; + if (config.getProperty(key) == null) + config.setProperty(key, 3); + settings.put(key, config.getInt(key, 3)); + //end Integers + + //String Arrays + key = Keys.ALLOWED_CMDS; + if (config.getProperty(key) == null) + config.setProperty(key, Arrays.asList(new String[] {"/register", "/login"})); + settings.put(key, config.getStringList(key, Arrays.asList(new String[] {"/register", "/login"}))); + //end String Arrays + + config.save(); + } + + public void update(String key, Object value) + { + settings.replace(key, value); + config.setProperty(key, value); + config.save(); + } + + public Boolean getBool(String key) + { + return (Boolean)settings.get(key); + } + + public int getInt(String key) + { + return (Integer)settings.get(key); + } + + @SuppressWarnings("unchecked") + public List getStrArr(String key) + { + return (List)settings.get(key); + } +} \ No newline at end of file diff --git a/src/com/cypherx/xauth/Strings.java b/src/com/cypherx/xauth/Strings.java new file mode 100644 index 0000000..31490eb --- /dev/null +++ b/src/com/cypherx/xauth/Strings.java @@ -0,0 +1,98 @@ +package com.cypherx.xauth; + +import java.util.concurrent.ConcurrentHashMap; +import java.io.File; + +import org.bukkit.util.config.Configuration; + +public class Strings +{ + private static String[] keys = + { + "register.login", + "register.usage", + "register.err.disabled", + "register.err.registered", + "register.err.password", + "register.success1", + "register.success2" + }; + + private static final String[][] keyUpdates = + { + + }; + + private static Configuration config; + private static final ConcurrentHashMap defaults = new ConcurrentHashMap(); + private static final ConcurrentHashMap strings = new ConcurrentHashMap(); + + public Strings(File file) + { + config = new Configuration(file); + config.load(); + fillDefaults(); + + if (file.exists() && keyUpdates.length > 0) + updateKeys(); + + load(); + config.save(); + } + + private void fillDefaults() + { + defaults.put("register.login", "&cYou are not registered. Please register using /register ."); + defaults.put("register.usage", "&cCorrect Usage: /register "); + defaults.put("register.err.disabled", "&cRegistrations are currently disabled."); + defaults.put("register.err.registered", "&cYou are already registered."); + defaults.put("register.err.password", "&cYour password must contain %1 or more characters."); + defaults.put("register.success1", "&aYou have successfully registered!"); + defaults.put("register.success2", "&aYour password is: &f%1"); + } + + private void updateKeys() + { + String fromKey, toKey, holder; + for (String[] update : keyUpdates) + { + fromKey = update[0]; + if (config.getProperty(fromKey) != null) + { + toKey = update[1]; + holder = config.getString(fromKey); + config.removeProperty(fromKey); + config.setProperty(toKey, holder); + } + } + } + + private void load() + { + for (String key : keys) + { + if (config.getProperty(key) == null) + config.setProperty(key, defaults.get(key)); + strings.put(key, config.getString(key).replace("&", "\u00a7")); + } + } + + public String getString(String key) + { + return strings.get(key); + } + + public String getString(String key, Object replacement) + { + return strings.get(key).replace("%1", replacement.toString()); + //return replace(strings.get(key), new Object[]{replacement}); + } + + public String replace(String str, Object[] replacements) + { + int i; + for (i = 0; i < replacements.length; i++) + str.replace(("%" + i).toString(), replacements[i].toString()); + return str; + } +} \ No newline at end of file diff --git a/src/com/cypherx/xauth/Whirlpool.java b/src/com/cypherx/xauth/Whirlpool.java new file mode 100644 index 0000000..b7df248 --- /dev/null +++ b/src/com/cypherx/xauth/Whirlpool.java @@ -0,0 +1,236 @@ +package com.cypherx.xauth; + +import java.util.Arrays; + +class Whirlpool { + public static final int DIGESTBITS = 512; + public static final int DIGESTBYTES = DIGESTBITS >>> 3; + protected static final int R = 10; + private static final String sbox = + "\u1823\uc6E8\u87B8\u014F\u36A6\ud2F5\u796F\u9152" + + "\u60Bc\u9B8E\uA30c\u7B35\u1dE0\ud7c2\u2E4B\uFE57" + + "\u1577\u37E5\u9FF0\u4AdA\u58c9\u290A\uB1A0\u6B85" + + "\uBd5d\u10F4\ucB3E\u0567\uE427\u418B\uA77d\u95d8" + + "\uFBEE\u7c66\udd17\u479E\ucA2d\uBF07\uAd5A\u8333" + + "\u6302\uAA71\uc819\u49d9\uF2E3\u5B88\u9A26\u32B0" + + "\uE90F\ud580\uBEcd\u3448\uFF7A\u905F\u2068\u1AAE" + + "\uB454\u9322\u64F1\u7312\u4008\uc3Ec\udBA1\u8d3d" + + "\u9700\ucF2B\u7682\ud61B\uB5AF\u6A50\u45F3\u30EF" + + "\u3F55\uA2EA\u65BA\u2Fc0\udE1c\uFd4d\u9275\u068A" + + "\uB2E6\u0E1F\u62d4\uA896\uF9c5\u2559\u8472\u394c" + + "\u5E78\u388c\ud1A5\uE261\uB321\u9c1E\u43c7\uFc04" + + "\u5199\u6d0d\uFAdF\u7E24\u3BAB\ucE11\u8F4E\uB7EB" + + "\u3c81\u94F7\uB913\u2cd3\uE76E\uc403\u5644\u7FA9" + + "\u2ABB\uc153\udc0B\u9d6c\u3174\uF646\uAc89\u14E1" + + "\u163A\u6909\u70B6\ud0Ed\ucc42\u98A4\u285c\uF886"; + + private static long[][] C = new long[8][256]; + private static long[] rc = new long[R + 1]; + + static { + for (int x = 0; x < 256; x++) { + char c = sbox.charAt(x/2); + long v1 = ((x & 1) == 0) ? c >>> 8 : c & 0xff; + long v2 = v1 << 1; + if (v2 >= 0x100L) { + v2 ^= 0x11dL; + } + long v4 = v2 << 1; + if (v4 >= 0x100L) { + v4 ^= 0x11dL; + } + long v5 = v4 ^ v1; + long v8 = v4 << 1; + if (v8 >= 0x100L) { + v8 ^= 0x11dL; + } + long v9 = v8 ^ v1; + + C[0][x] = + (v1 << 56) | (v1 << 48) | (v4 << 40) | (v1 << 32) | + (v8 << 24) | (v5 << 16) | (v2 << 8) | (v9 ); + + for (int t = 1; t < 8; t++) { + C[t][x] = (C[t - 1][x] >>> 8) | ((C[t - 1][x] << 56)); + } + } + + rc[0] = 0L; + for (int r = 1; r <= R; r++) { + int i = 8*(r - 1); + rc[r] = + (C[0][i ] & 0xff00000000000000L) ^ + (C[1][i + 1] & 0x00ff000000000000L) ^ + (C[2][i + 2] & 0x0000ff0000000000L) ^ + (C[3][i + 3] & 0x000000ff00000000L) ^ + (C[4][i + 4] & 0x00000000ff000000L) ^ + (C[5][i + 5] & 0x0000000000ff0000L) ^ + (C[6][i + 6] & 0x000000000000ff00L) ^ + (C[7][i + 7] & 0x00000000000000ffL); + } + } + + protected byte[] bitLength = new byte[32]; + protected byte[] buffer = new byte[64]; + protected int bufferBits = 0; + protected int bufferPos = 0; + protected long[] hash = new long[8]; + protected long[] K = new long[8]; + protected long[] L = new long[8]; + protected long[] block = new long[8]; + protected long[] state = new long[8]; + + public Whirlpool() {} + + protected void processBuffer() { + for (int i = 0, j = 0; i < 8; i++, j += 8) { + block[i] = + (((long)buffer[j ] ) << 56) ^ + (((long)buffer[j + 1] & 0xffL) << 48) ^ + (((long)buffer[j + 2] & 0xffL) << 40) ^ + (((long)buffer[j + 3] & 0xffL) << 32) ^ + (((long)buffer[j + 4] & 0xffL) << 24) ^ + (((long)buffer[j + 5] & 0xffL) << 16) ^ + (((long)buffer[j + 6] & 0xffL) << 8) ^ + (((long)buffer[j + 7] & 0xffL) ); + } + + for (int i = 0; i < 8; i++) { + state[i] = block[i] ^ (K[i] = hash[i]); + } + + for (int r = 1; r <= R; r++) { + for (int i = 0; i < 8; i++) { + L[i] = 0L; + for (int t = 0, s = 56; t < 8; t++, s -= 8) { + L[i] ^= C[t][(int)(K[(i - t) & 7] >>> s) & 0xff]; + } + } + for (int i = 0; i < 8; i++) { + K[i] = L[i]; + } + K[0] ^= rc[r]; + + for (int i = 0; i < 8; i++) { + L[i] = K[i]; + for (int t = 0, s = 56; t < 8; t++, s -= 8) { + L[i] ^= C[t][(int)(state[(i - t) & 7] >>> s) & 0xff]; + } + } + for (int i = 0; i < 8; i++) { + state[i] = L[i]; + } + } + + for (int i = 0; i < 8; i++) { + hash[i] ^= state[i] ^ block[i]; + } + } + + public void NESSIEinit() { + Arrays.fill(bitLength, (byte)0); + bufferBits = bufferPos = 0; + buffer[0] = 0; + Arrays.fill(hash, 0L); + } + + public void NESSIEadd(byte[] source, long sourceBits) { + int sourcePos = 0; + int sourceGap = (8 - ((int)sourceBits & 7)) & 7; + int bufferRem = bufferBits & 7; + int b; + long value = sourceBits; + for (int i = 31, carry = 0; i >= 0; i--) { + carry += (bitLength[i] & 0xff) + ((int)value & 0xff); + bitLength[i] = (byte)carry; + carry >>>= 8; + value >>>= 8; + } + + while (sourceBits > 8) { + b = ((source[sourcePos] << sourceGap) & 0xff) | + ((source[sourcePos + 1] & 0xff) >>> (8 - sourceGap)); + if (b < 0 || b >= 256) { + throw new RuntimeException("LOGIC ERROR"); + } + buffer[bufferPos++] |= b >>> bufferRem; + bufferBits += 8 - bufferRem; + if (bufferBits == 512) { + processBuffer(); + bufferBits = bufferPos = 0; + } + buffer[bufferPos] = (byte)((b << (8 - bufferRem)) & 0xff); + bufferBits += bufferRem; + sourceBits -= 8; + sourcePos++; + } + if (sourceBits > 0) { + b = (source[sourcePos] << sourceGap) & 0xff; + buffer[bufferPos] |= b >>> bufferRem; + } else { + b = 0; + } + if (bufferRem + sourceBits < 8) { + bufferBits += sourceBits; + } else { + bufferPos++; + bufferBits += 8 - bufferRem; + sourceBits -= 8 - bufferRem; + if (bufferBits == 512) { + processBuffer(); + bufferBits = bufferPos = 0; + } + buffer[bufferPos] = (byte)((b << (8 - bufferRem)) & 0xff); + bufferBits += (int)sourceBits; + } + } + + public void NESSIEfinalize(byte[] digest) { + buffer[bufferPos] |= 0x80 >>> (bufferBits & 7); + bufferPos++; + if (bufferPos > 32) { + while (bufferPos < 64) { + buffer[bufferPos++] = 0; + } + processBuffer(); + bufferPos = 0; + } + while (bufferPos < 32) { + buffer[bufferPos++] = 0; + } + System.arraycopy(bitLength, 0, buffer, 32, 32); + processBuffer(); + for (int i = 0, j = 0; i < 8; i++, j += 8) { + long h = hash[i]; + digest[j ] = (byte)(h >>> 56); + digest[j + 1] = (byte)(h >>> 48); + digest[j + 2] = (byte)(h >>> 40); + digest[j + 3] = (byte)(h >>> 32); + digest[j + 4] = (byte)(h >>> 24); + digest[j + 5] = (byte)(h >>> 16); + digest[j + 6] = (byte)(h >>> 8); + digest[j + 7] = (byte)(h ); + } + } + + public void NESSIEadd(String source) { + if (source.length() > 0) { + byte[] data = new byte[source.length()]; + for (int i = 0; i < source.length(); i++) { + data[i] = (byte)source.charAt(i); + } + NESSIEadd(data, 8*data.length); + } + } + + static String display(byte[] array) { + char[] val = new char[2*array.length]; + String hex = "0123456789ABCDEF"; + for (int i = 0; i < array.length; i++) { + int b = array[i] & 0xff; + val[2*i] = hex.charAt(b >>> 4); + val[2*i + 1] = hex.charAt(b & 15); + } + return String.valueOf(val); + } +} \ No newline at end of file diff --git a/src/com/cypherx/xauth/xAuth.java b/src/com/cypherx/xauth/xAuth.java new file mode 100644 index 0000000..8faca41 --- /dev/null +++ b/src/com/cypherx/xauth/xAuth.java @@ -0,0 +1,494 @@ +package com.cypherx.xauth; + +import java.io.*; +import java.math.BigInteger; +import java.security.MessageDigest; +import java.util.concurrent.ConcurrentHashMap; +import java.util.Date; +import java.util.HashMap; + +import net.minecraft.server.PropertyManager; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.Event.Priority; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.PluginManager; + +import com.cypherx.xauth.Settings.Keys; +import com.nijiko.permissions.PermissionHandler; +import com.nijikokun.bukkit.Permissions.Permissions; + +/** + * xAuth for Bukkit + * + * @author CypherX + */ +public class xAuth extends JavaPlugin +{ + private final xAuthPlayerListener playerListener = new xAuthPlayerListener(this); + private final xAuthBlockListener blockListener = new xAuthBlockListener(this); + private final xAuthEntityListener entityListener = new xAuthEntityListener(this); + private final HashMap debugees = new HashMap(); + + private static final String DIR = "plugins/xAuth/"; + private static final String CONFIG_FILE = "config.yml"; + private static final String STRINGS_FILE = "strings.yml"; + private static final String AUTH_FILE = "auths.txt"; + + public static Settings settings; + public static Strings strings; + public static PermissionHandler Permissions; + + public static Plugin multiInv = null; + private static Boolean fullyEnabled = false; + + private ConcurrentHashMap auths = new ConcurrentHashMap(); + private ConcurrentHashMap inventory = new ConcurrentHashMap(); + private ConcurrentHashMap armor = new ConcurrentHashMap(); + private ConcurrentHashMap sessions = new ConcurrentHashMap(); + private ConcurrentHashMap lastNotifyTimes = new ConcurrentHashMap(); + + public void onEnable() + { + multiInv = getServer().getPluginManager().getPlugin("MultiInv"); + + if (multiInv != null) + { + System.out.println("[xAuth] MultiInv detected, switching to compatibility mode"); + } + + /*Whirlpool w = new Whirlpool(); + byte[] digest = new byte[Whirlpool.DIGESTBYTES]; + w.NESSIEinit(); + w.NESSIEadd("The quick brown fox jumps over the lazy dog"); + w.NESSIEfinalize(digest); + System.out.println(Whirlpool.display(digest));*/ + + PluginDescriptionFile pdfFile = this.getDescription(); + PropertyManager props = new PropertyManager(new File("server.properties")); + if (props.a("online-mode", true)) + { + System.out.println("[" + pdfFile.getName() + "] Stopping - Server is running in online-mode"); + this.setEnabled(false); + this.getServer().getPluginManager().disablePlugin(this); + return; + } + + File fDir = new File(DIR); + + if (!fDir.exists()) + fDir.mkdir(); + + try + { + File fAuths = new File(DIR + AUTH_FILE); + + if (!fAuths.exists()) + fAuths.createNewFile(); + } + catch (Exception e) + { + System.out.println(e.getMessage()); + } + + settings = new Settings(new File(DIR + CONFIG_FILE)); + strings = new Strings(new File(DIR + STRINGS_FILE)); + getAuths(); + setupPermissions(); + + //REMOVE WHEN PERSISTENT SESSIONS ARE ADDED + //Hide inventory of any players online while server is starting (means /reload was used) + Player[] players = getServer().getOnlinePlayers(); + if (players.length > 0) + { + for (Player player : players) + { + saveInventory(player); + player.sendMessage(ChatColor.RED + "Server reloaded! You must log in again."); + } + } + //END REMOVE + + PluginManager pm = getServer().getPluginManager(); + pm.registerEvent(Event.Type.PLAYER_CHAT, playerListener, Priority.Highest, this); + pm.registerEvent(Event.Type.PLAYER_COMMAND_PREPROCESS, playerListener, Event.Priority.Normal, this); + pm.registerEvent(Event.Type.PLAYER_DROP_ITEM, playerListener, Event.Priority.Highest, this); + pm.registerEvent(Event.Type.PLAYER_PICKUP_ITEM, playerListener, Event.Priority.Highest, this); + pm.registerEvent(Event.Type.PLAYER_ITEM, playerListener, Event.Priority.Highest, this); + pm.registerEvent(Event.Type.PLAYER_JOIN, playerListener, Event.Priority.Highest, this); + pm.registerEvent(Event.Type.PLAYER_MOVE, playerListener, Event.Priority.Highest, this); + pm.registerEvent(Event.Type.PLAYER_QUIT, playerListener, Event.Priority.Highest, this); + + pm.registerEvent(Event.Type.BLOCK_BREAK, blockListener, Priority.Highest, this); + //pm.registerEvent(Event.Type.BLOCK_DAMAGED, blockListener, Priority.Highest, this); + pm.registerEvent(Event.Type.BLOCK_INTERACT, blockListener, Priority.Highest, this); + pm.registerEvent(Event.Type.BLOCK_PLACED, blockListener, Priority.Highest, this); + + pm.registerEvent(Event.Type.ENTITY_DAMAGED, entityListener, Priority.Highest, this); + pm.registerEvent(Event.Type.ENTITY_TARGET, entityListener, Priority.Highest, this); + + //PluginDescriptionFile pdfFile = this.getDescription(); + System.out.println("[" + pdfFile.getName() + "]" + " v" + pdfFile.getVersion() + " Enabled!"); + fullyEnabled = true; + } + + public void getAuths() + { + PluginDescriptionFile pdfFile = this.getDescription(); + System.out.println("[" + pdfFile.getName() + "] Loading player accounts.."); + + try + { + BufferedReader authReader = new BufferedReader(new FileReader(DIR + AUTH_FILE)); + + String line; + while ((line = authReader.readLine()) != null) + { + String[] split = line.split(":"); + auths.put(split[0], line); + } + authReader.close(); + System.out.print("[" + pdfFile.getName() + "] Done! Loaded " + auths.size() + " Accounts!"); + } + catch (Exception e) + { + System.out.println(e.getMessage()); + } + } + + public void onDisable() + { + //Restore players inventories so they are not lost + Player[] players = getServer().getOnlinePlayers(); + if (players.length > 0) + { + for (Player player : players) + if (!sessionExists(player.getName())) + restoreInventory(player); + } + + if (fullyEnabled) + updateAuthFile(); + + PluginDescriptionFile pdfFile = this.getDescription(); + System.out.println("[" + pdfFile.getName() + "]" + " v" + pdfFile.getVersion() + " Disabled"); + } + + public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) + { + if (!this.isEnabled()) + return false; + + CommandHandler cmdHandler = new CommandHandler(this); + + if (sender instanceof Player) + cmdHandler.handlePlayerCommand((Player)sender, cmd, args); + else if (sender instanceof ConsoleCommandSender) + cmdHandler.handleConsoleCommand(cmd, args); + + return true; + } + + //AUTH / REGISTER FUNCTIONS + public void addAuth(String pName, String pass) + { + String hash = md5(pass); + auths.put(pName.toLowerCase(), pName.toLowerCase() + ":" + hash); + + if (settings.getBool(Keys.AUTOSAVE)) + updateAuthFile(); + } + + public Boolean isRegistered(String pName) + { + if (auths.containsKey(pName.toLowerCase())) + return true; + + return false; + } + + public void changePass(String pName, String pass) + { + String hash = md5(pass); + + auths.remove(pName.toLowerCase()); + auths.put(pName.toLowerCase(), pName.toLowerCase() + ":" + hash); + + if (settings.getBool(Keys.AUTOSAVE)) + updateAuthFile(); + } + + public void removeAuth(String pName) + { + pName = pName.toLowerCase(); + auths.remove(pName); + + if (sessionExists(pName)) + removeSession(pName); + + if (settings.getBool(Keys.AUTOSAVE)) + updateAuthFile(); + } + + public void updateAuthFile() + { + try + { + BufferedWriter authWriter = new BufferedWriter(new FileWriter(DIR + AUTH_FILE)); + for (String key: auths.keySet()) + { + authWriter.write(auths.get(key)); + authWriter.newLine(); + } + authWriter.close(); + } + catch (Exception e) + { + System.out.println(e.getMessage()); + } + } + + //LOGIN / LOGOUT FUNCTIONS + public void login(Player player) + { + startSession(player); + restoreInventory(player); + } + + public Boolean checkPass(Player player, String pass) + { + String hash = md5(pass); + if (auths.get(player.getName().toLowerCase()).equals(player.getName().toLowerCase() + ":" + hash)) + return true; + else + return false; + } + + public void logout(Player player) + { + String pName = player.getName(); + + if (sessionExists(pName)) + { + Session session = sessions.get(pName.toLowerCase()); + + if (session.isExpired(new Date(session.getLoginTime() + (settings.getInt(Keys.SESSION_TIMEOUT) * 1000)))) + removeSession(pName); + } + else + restoreInventory(player); + } + + //NOTIFY FUNCTIONS + public void handleEvent(Player player, Cancellable event) + { + if (!sessionExists(player.getName())) + { + event.setCancelled(true); + + if (canNotify(player)) + notifyPlayer(player); + } + } + + public Boolean isCmdAllowed(String cmd) + { + if (settings.getStrArr(Keys.ALLOWED_CMDS).contains(cmd)) + return true; + + return false; + } + + public Boolean canNotify(Player player) + { + if (lastNotifyTimes.get(player) == null) + return true; + + Date nextNotifyTime = new Date(lastNotifyTimes.get(player).getTime() + (settings.getInt(Keys.NOTIFY_LIMIT) * 1000)); + if (nextNotifyTime.compareTo(new Date()) < 0) + return true; + + return false; + } + + public void notifyPlayer(Player player) + { + player.sendMessage(ChatColor.GRAY + "You must be logged in to do that!"); + updateNotifyTime(player, new Date()); + } + + public void updateNotifyTime(Player player, Date date) + { + lastNotifyTimes.remove(player); + lastNotifyTimes.put(player, date); + } + + //INVENTORY FUNCTIONS + public void saveInventory(Player player) + { + PlayerInventory playerInv = player.getInventory(); + inventory.put(player, playerInv.getContents()); + playerInv.clear(); + armor.put(player, playerInv.getArmorContents()); + playerInv.setHelmet(null); + playerInv.setChestplate(null); + playerInv.setLeggings(null); + playerInv.setBoots(null); + } + + public void restoreInventory(Player player) + { + PlayerInventory playerInv = player.getInventory(); + + if (inventory.containsKey(player)) + { + playerInv.setContents(inventory.get(player)); + inventory.remove(player); + } + + if (armor.containsKey(player)) + { + playerInv.setBoots(armor.get(player)[0].getTypeId() == 0 ? null : armor.get(player)[0]); + playerInv.setLeggings(armor.get(player)[1].getTypeId() == 0 ? null : armor.get(player)[1]); + playerInv.setChestplate(armor.get(player)[2].getTypeId() == 0 ? null : armor.get(player)[2]); + playerInv.setHelmet(armor.get(player)[3].getTypeId() == 0 ? null : armor.get(player)[3]); + armor.remove(player); + } + + CraftWorld cWorld = (CraftWorld)player.getWorld(); + CraftPlayer cPlayer = (CraftPlayer)player; + cWorld.getHandle().m().d().a(cPlayer.getHandle()); + } + + //SESSION FUNCTIONS + public void startSession(Player player) + { + sessions.put(player.getName().toLowerCase(), new Session(player)); + } + + public Boolean sessionExists(String pName) + { + if (sessions.containsKey(pName.toLowerCase())) + return true; + + return false; + } + + public Boolean isLoggedIn(Player player) + { + if (sessionExists(player.getName())) + { + if (isSessionValid(player)) + return true; + + removeSession(player.getName()); + } + + return false; + } + + public Boolean isSessionValid(Player player) + { + Session session = sessions.get(player.getName().toLowerCase()); + if (session.isExpired(new Date(session.getLoginTime() + (settings.getInt(Keys.SESSION_TIMEOUT) * 1000)))) + return false; + + if (!session.isValidAddr(player.getAddress().getAddress().getHostAddress())) + return false; + + return true; + } + + public void removeSession(String pName) + { + pName = pName.toLowerCase(); + if (sessionExists(pName)) + sessions.remove(pName); + } + + //MISC FUNCTIONS + private void setupPermissions() + { + PluginDescriptionFile pdfFile = this.getDescription(); + Plugin test = this.getServer().getPluginManager().getPlugin("Permissions"); + + if (xAuth.Permissions == null) + { + if (test != null) + xAuth.Permissions = ((Permissions)test).getHandler(); + else + System.out.println("[" + pdfFile.getName() + "] Permissions plugin not detected, defaulting to ops.txt"); + } + } + + public String md5(String str) + { + try + { + MessageDigest md = MessageDigest.getInstance("MD5"); + byte[] messageDigest = md.digest(str.getBytes()); + BigInteger number = new BigInteger(1, messageDigest); + String hashtext = number.toString(16); + while (hashtext.length() < 32) + hashtext = "0" + hashtext; + + return hashtext; + } + catch (Exception e) + { + System.out.println(e.getMessage()); + } + + return null; + } + + public boolean canUseCommand(Player player, String node) + { + if (xAuth.Permissions == null) + { + if (!player.isOp()) + return false; + + return true; + } + + if (!xAuth.Permissions.has(player, node)) + return false; + + return true; + } + + public void reload() + { + PluginDescriptionFile pdfFile = this.getDescription(); + updateAuthFile(); + settings = new Settings(new File(DIR + CONFIG_FILE)); + strings = new Strings(new File(DIR + STRINGS_FILE)); + getAuths(); + System.out.println("[" + pdfFile.getName() + "] Configuration & Accounts reloaded"); + } + + public boolean isDebugging(final Player player) + { + if (debugees.containsKey(player)) + return debugees.get(player); + else + return false; + } + + public void setDebugging(final Player player, final boolean value) + { + debugees.put(player, value); + } +} \ No newline at end of file diff --git a/src/com/cypherx/xauth/xAuthBlockListener.java b/src/com/cypherx/xauth/xAuthBlockListener.java new file mode 100644 index 0000000..cd9294b --- /dev/null +++ b/src/com/cypherx/xauth/xAuthBlockListener.java @@ -0,0 +1,58 @@ +package com.cypherx.xauth; + +import org.bukkit.entity.Player; +import org.bukkit.event.block.*; + +/** + * Authenticate block listener + * @author CypherX + */ +public class xAuthBlockListener extends BlockListener +{ + private final xAuth plugin; + + public xAuthBlockListener(final xAuth plugin) + { + this.plugin = plugin; + } + + //Prevents players from breaking blocks + public void onBlockBreak(BlockBreakEvent event) + { + if (event.isCancelled()) + return; + + Player player = event.getPlayer(); + plugin.handleEvent(player, event); + } + + //Prevents player from damaging a block + /*public void onBlockDamage(BlockDamageEvent event) + { + Player player = event.getPlayer(); + plugin.handleEvent(player, event); + }*/ + + //Prevents player from using switches, buttons, etc. + public void onBlockInteract(BlockInteractEvent event) + { + if (event.isCancelled()) + return; + + if (event.isPlayer()) + { + Player player = (Player)event.getEntity(); + plugin.handleEvent(player, event); + } + } + + //Prevents player from placing blocks + public void onBlockPlace(BlockPlaceEvent event) + { + if (event.isCancelled()) + return; + + Player player = event.getPlayer(); + plugin.handleEvent(player, event); + } +} \ No newline at end of file diff --git a/src/com/cypherx/xauth/xAuthEntityListener.java b/src/com/cypherx/xauth/xAuthEntityListener.java new file mode 100644 index 0000000..69c9987 --- /dev/null +++ b/src/com/cypherx/xauth/xAuthEntityListener.java @@ -0,0 +1,51 @@ +package com.cypherx.xauth; + +import org.bukkit.entity.*; +import org.bukkit.event.entity.*; + +/** + * Authenticate entity listener + * @author CypherX + */ +public class xAuthEntityListener extends EntityListener +{ + private final xAuth plugin; + + public xAuthEntityListener(final xAuth plugin) + { + this.plugin = plugin; + } + + //Prevents player from taking damage or giving damage + public void onEntityDamage(EntityDamageEvent event) + { + if (event.isCancelled()) + return; + + Entity entity = event.getEntity(); + + //Player taking damage + if (entity instanceof Player) + plugin.handleEvent((Player)entity, event); + //Player dealing damage to other entity + else if (event instanceof EntityDamageByEntityEvent) + { + EntityDamageByEntityEvent edbeEvent = (EntityDamageByEntityEvent)event; + Entity damager = edbeEvent.getDamager(); + + if (damager instanceof Player) + plugin.handleEvent((Player)damager, event); + } + } + + //Prevents monsters from attacking player + public void onEntityTarget(EntityTargetEvent event) + { + if (event.isCancelled()) + return; + + Entity entity = event.getTarget(); + if (entity instanceof Player) + plugin.handleEvent((Player)entity, event); + } +} \ No newline at end of file diff --git a/src/com/cypherx/xauth/xAuthPlayerListener.java b/src/com/cypherx/xauth/xAuthPlayerListener.java new file mode 100644 index 0000000..62c9325 --- /dev/null +++ b/src/com/cypherx/xauth/xAuthPlayerListener.java @@ -0,0 +1,149 @@ +package com.cypherx.xauth; + +import org.bukkit.entity.Player; +import org.bukkit.event.player.*; +//import org.bukkit.inventory.ItemStack; +//import org.bukkit.inventory.PlayerInventory; +import org.bukkit.ChatColor; + +/** + * Handle events for all Player related events + * @author CypherX + */ +public class xAuthPlayerListener extends PlayerListener +{ + private final xAuth plugin; + + public xAuthPlayerListener(final xAuth instance) + { + plugin = instance; + } + + public void onPlayerJoin(PlayerEvent event) + { + //PlayerInventory inv; + //ItemStack[] is; + Player player = event.getPlayer(); + + if (!plugin.isLoggedIn(player)) + { + /*System.out.println("[xAuth] :: Join - Before saving inventory"); + + inv = event.getPlayer().getInventory(); + is = inv.getContents(); + for (ItemStack item : is) + System.out.println(item.getType() + " : " + item.getAmount());*/ + + plugin.saveInventory(player); + + /*System.out.println("[xAuth] :: Join - After saving inventory"); + + inv = event.getPlayer().getInventory(); + is = inv.getContents(); + for (ItemStack item : is) + System.out.println(item.getType() + " : " + item.getAmount());*/ + + if (!plugin.isRegistered(player.getName())) + player.sendMessage(ChatColor.RED + "You are not registered. Please register using /register ."); + else + player.sendMessage(ChatColor.RED + "Please log in using /login ."); + } + + /*if (!plugin.isRegistered(player.getName())) + { + plugin.saveInventory(player); + player.sendMessage(ChatColor.RED + "You are not registered. Please register using /register ."); + } + else if (!plugin.isLoggedIn(player)) + { + plugin.saveInventory(player); + player.sendMessage(ChatColor.RED + "Please log in using /login ."); + }*/ + } + + public void onPlayerQuit(PlayerEvent event) + { + /*PlayerInventory inv; + ItemStack[] is; + + System.out.println("[xAuth] :: Quit - Before restoring inventory"); + + inv = event.getPlayer().getInventory(); + is = inv.getContents(); + for (ItemStack item : is) + System.out.println(item.getType() + " : " + item.getAmount());*/ + + plugin.logout(event.getPlayer()); + + /*System.out.println("[xAuth] :: Quit - After restoring inventory"); + inv = event.getPlayer().getInventory(); + is = inv.getContents(); + for (ItemStack item : is) + System.out.println(item.getType() + " : " + item.getAmount());*/ + } + + //Prevents players from executing commands + public void onPlayerCommandPreprocess(PlayerChatEvent event) + { + if (event.isCancelled()) + return; + + Player player = event.getPlayer(); + String[] msg = event.getMessage().split(" "); + + if (!plugin.isCmdAllowed(msg[0])) + plugin.handleEvent(player, event); + } + + //Prevents player from being able to chat + public void onPlayerChat(PlayerChatEvent event) + { + if (event.isCancelled()) + return; + + Player player = event.getPlayer(); + plugin.handleEvent(player, event); + } + + //Prevents player from being able to drop an item (inventory should be empty anyway) + public void onPlayerDropItem(PlayerDropItemEvent event) + { + if (event.isCancelled()) + return; + + Player player = event.getPlayer(); + plugin.handleEvent(player, event); + } + + //Prevents player from using an item such as food + public void onPlayerItem(PlayerItemEvent event) + { + if (event.isCancelled()) + return; + + Player player = event.getPlayer(); + plugin.handleEvent(player, event); + } + + //Prevents player from moving + public void onPlayerMove(PlayerMoveEvent event) + { + if (event.isCancelled()) + return; + + Player player = event.getPlayer(); + plugin.handleEvent(player, event); + if (event.isCancelled()) + player.teleportTo(event.getFrom()); + } + + //Prevents player from picking up items + public void onPlayerPickupItem(PlayerPickupItemEvent event) + { + if (event.isCancelled()) + return; + + Player player = event.getPlayer(); + plugin.handleEvent(player, event); + } +} \ No newline at end of file diff --git a/src/plugin.yml b/src/plugin.yml new file mode 100644 index 0000000..6b74908 --- /dev/null +++ b/src/plugin.yml @@ -0,0 +1,23 @@ +name: xAuth +main: com.cypherx.xauth.xAuth +version: 1.1.4 + +commands: + register: + description: + usage: + login: + description: + usage: + changepw: + description: + usage: + unregister: + description: + usage: + authreload: + description: + usage: + toggle: + description: + usage: \ No newline at end of file