From 8e06e95325841f6f6dff888efe20828c85ba5a7a Mon Sep 17 00:00:00 2001 From: Pepich Date: Fri, 5 May 2017 00:18:40 +0200 Subject: [PATCH] Iniital commit after moving files --- .../exceptions/PlayerNotFoundException.java | 11 + src/com/redstoner/modules/abot/Abot.java | 80 ++++ .../modules/adminchat/Adminchat.java | 235 ++++++++++ .../modules/adminnotes/AdminNotes.java | 131 ++++++ .../modules/challenge/Challenge.java | 284 ++++++++++++ .../modules/chatalias/Chatalias.java | 354 +++++++++++++++ .../modules/chatgroups/Chatgroups.java | 408 ++++++++++++++++++ .../redstoner/modules/chatonly/ChatOnly.java | 8 + src/com/redstoner/modules/check/Check.java | 242 +++++++++++ src/com/redstoner/modules/clear/Clear.java | 40 ++ .../modules/clearonjoin/ClearOnJoin.java | 105 +++++ src/com/redstoner/modules/cycle/Cycle.java | 159 +++++++ .../redstoner/modules/damnspam/DamnSpam.java | 367 ++++++++++++++++ .../redstoner/modules/damnspam/SpamInput.java | 17 + .../modules/firstseen/FirstSeen.java | 111 +++++ .../modules/illumination/Illumination.java | 48 +++ src/com/redstoner/modules/imout/Imout.java | 59 +++ .../modules/lagchunks/LagChunks.java | 106 +++++ .../modules/lagchunks/LaggyChunk.java | 21 + .../loginsecurity/CancelledEventsHandler.java | 95 ++++ .../loginsecurity/CryptographyHandler.java | 53 +++ .../modules/loginsecurity/LoginSecurity.java | 318 ++++++++++++++ .../loginsecurity/RepeatingLoginRunnable.java | 37 ++ src/com/redstoner/modules/mentio/Mentio.java | 192 +++++++++ src/com/redstoner/modules/motd/Motd.java | 71 +++ .../redstoner/modules/nametags/Nametags.java | 135 ++++++ src/com/redstoner/modules/naming/Naming.java | 120 ++++++ .../modules/onlineplayers/OnlinePlayers.java | 89 ++++ .../redstoner/modules/pmtoggle/Pmtoggle.java | 100 +++++ .../redstoner/modules/reports/Reports.java | 163 +++++++ src/com/redstoner/modules/saylol/Saylol.java | 327 ++++++++++++++ .../redstoner/modules/scoreboard/Project.java | 334 ++++++++++++++ .../modules/scoreboard/ProjectManager.java | 53 +++ .../modules/scoreboard/Scoreboards.java | 147 +++++++ .../modules/scoreboard/scoreboards.cmd | 51 +++ .../modules/scriptutils/Scriptutils.java | 300 +++++++++++++ .../modules/skullclick/SkullClick.java | 60 +++ src/com/redstoner/modules/tag/Tag.java | 167 +++++++ src/com/redstoner/modules/vanish/Vanish.java | 243 +++++++++++ src/com/redstoner/modules/warn/Warn.java | 51 +++ .../redstoner/modules/webtoken/WebToken.java | 226 ++++++++++ 41 files changed, 6118 insertions(+) create mode 100644 src/com/redstoner/exceptions/PlayerNotFoundException.java create mode 100644 src/com/redstoner/modules/abot/Abot.java create mode 100644 src/com/redstoner/modules/adminchat/Adminchat.java create mode 100644 src/com/redstoner/modules/adminnotes/AdminNotes.java create mode 100644 src/com/redstoner/modules/challenge/Challenge.java create mode 100644 src/com/redstoner/modules/chatalias/Chatalias.java create mode 100644 src/com/redstoner/modules/chatgroups/Chatgroups.java create mode 100644 src/com/redstoner/modules/chatonly/ChatOnly.java create mode 100644 src/com/redstoner/modules/check/Check.java create mode 100644 src/com/redstoner/modules/clear/Clear.java create mode 100644 src/com/redstoner/modules/clearonjoin/ClearOnJoin.java create mode 100644 src/com/redstoner/modules/cycle/Cycle.java create mode 100644 src/com/redstoner/modules/damnspam/DamnSpam.java create mode 100644 src/com/redstoner/modules/damnspam/SpamInput.java create mode 100644 src/com/redstoner/modules/firstseen/FirstSeen.java create mode 100644 src/com/redstoner/modules/illumination/Illumination.java create mode 100644 src/com/redstoner/modules/imout/Imout.java create mode 100644 src/com/redstoner/modules/lagchunks/LagChunks.java create mode 100644 src/com/redstoner/modules/lagchunks/LaggyChunk.java create mode 100644 src/com/redstoner/modules/loginsecurity/CancelledEventsHandler.java create mode 100644 src/com/redstoner/modules/loginsecurity/CryptographyHandler.java create mode 100644 src/com/redstoner/modules/loginsecurity/LoginSecurity.java create mode 100644 src/com/redstoner/modules/loginsecurity/RepeatingLoginRunnable.java create mode 100644 src/com/redstoner/modules/mentio/Mentio.java create mode 100644 src/com/redstoner/modules/motd/Motd.java create mode 100644 src/com/redstoner/modules/nametags/Nametags.java create mode 100644 src/com/redstoner/modules/naming/Naming.java create mode 100644 src/com/redstoner/modules/onlineplayers/OnlinePlayers.java create mode 100644 src/com/redstoner/modules/pmtoggle/Pmtoggle.java create mode 100644 src/com/redstoner/modules/reports/Reports.java create mode 100644 src/com/redstoner/modules/saylol/Saylol.java create mode 100644 src/com/redstoner/modules/scoreboard/Project.java create mode 100644 src/com/redstoner/modules/scoreboard/ProjectManager.java create mode 100644 src/com/redstoner/modules/scoreboard/Scoreboards.java create mode 100644 src/com/redstoner/modules/scoreboard/scoreboards.cmd create mode 100644 src/com/redstoner/modules/scriptutils/Scriptutils.java create mode 100644 src/com/redstoner/modules/skullclick/SkullClick.java create mode 100644 src/com/redstoner/modules/tag/Tag.java create mode 100644 src/com/redstoner/modules/vanish/Vanish.java create mode 100644 src/com/redstoner/modules/warn/Warn.java create mode 100644 src/com/redstoner/modules/webtoken/WebToken.java diff --git a/src/com/redstoner/exceptions/PlayerNotFoundException.java b/src/com/redstoner/exceptions/PlayerNotFoundException.java new file mode 100644 index 0000000..e1ac8f9 --- /dev/null +++ b/src/com/redstoner/exceptions/PlayerNotFoundException.java @@ -0,0 +1,11 @@ +package com.redstoner.exceptions; + +public class PlayerNotFoundException extends Exception +{ + private static final long serialVersionUID = -7517266613348837760L; + + public PlayerNotFoundException() + { + super("That player could not be found!"); + } +} diff --git a/src/com/redstoner/modules/abot/Abot.java b/src/com/redstoner/modules/abot/Abot.java new file mode 100644 index 0000000..97688e8 --- /dev/null +++ b/src/com/redstoner/modules/abot/Abot.java @@ -0,0 +1,80 @@ +package com.redstoner.modules.abot; + +import java.io.File; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.JsonManager; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@AutoRegisterListener +@Version(major = 2, minor = 0, revision = 1, compatible = 2) +public class Abot implements Module, Listener +{ + private File answerFile = new File(Main.plugin.getDataFolder(), "abot.json"); + JSONArray answers; + + @EventHandler + public void onPlayerChat(AsyncPlayerChatEvent event) + { + for (Object rawObject : answers) + { + JSONObject entry = (JSONObject) rawObject; + JSONArray regexes = (JSONArray) entry.get("regex"); + for (Object regex : regexes) + { + if (event.getMessage().toLowerCase().matches((String) regex)) + { + Object hideperm = entry.get("hide-perm"); + if (hideperm == null || !event.getPlayer().hasPermission((String) hideperm)) + { + event.setCancelled(true); + Utils.sendMessage(event.getPlayer(), null, (String) entry.get("message"), '&'); + return; + } + } + } + } + } + + @Command(hook = "abot_reload") + public void loadAnswers(CommandSender sender) + { + answers = JsonManager.getArray(answerFile); + if (answers == null) + answers = new JSONArray(); + Utils.sendMessage(sender, null, "Loaded the abot.json file!"); + } + + @Override + public boolean onEnable() + { + loadAnswers(Bukkit.getConsoleSender()); + return true; + } + + // @noformat + @Override + public String getCommandString() + { + return "command abot {\n" + + " reload {" + + " help Reloads answes from the .json file.;\n" + + " run abot_reload;\n" + + " perm utils.abot.reload;" + + " }\n" + + "}"; + } + // format +} diff --git a/src/com/redstoner/modules/adminchat/Adminchat.java b/src/com/redstoner/modules/adminchat/Adminchat.java new file mode 100644 index 0000000..9fb529a --- /dev/null +++ b/src/com/redstoner/modules/adminchat/Adminchat.java @@ -0,0 +1,235 @@ +package com.redstoner.modules.adminchat; + +import java.io.File; +import java.util.ArrayList; +import java.util.UUID; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.json.simple.JSONObject; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.BroadcastFilter; +import com.redstoner.misc.JsonManager; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +/** AdminChat module. Allows staff to chat to other staff using /ac \ as well as a one char prefix or a toggle. + * + * @author Pepich */ +@AutoRegisterListener +@Version(major = 2, minor = 0, revision = 1, compatible = 2) +public class Adminchat implements Module, Listener +{ + private static final char defaultKey = ','; + private static final File keysLocation = new File(Main.plugin.getDataFolder(), "adminchat_keys.json"); + private ArrayList actoggled; + private static JSONObject keys; + + @Override + public boolean onEnable() + { + keys = JsonManager.getObject(keysLocation); + if (keys == null) + { + keys = new JSONObject(); + saveKeys(); + } + actoggled = new ArrayList(); + return true; + } + + // @noformat + @Override + public String getCommandString() + { + return "command ac {\n" + + " [string:message...] {\n" + + " help Sends a message in Admin Chat;\n" + + " perm utils.ac;\n" + + " run ac_msg message;\n" + + " }\n" + + "}\n" + + " \n" + + "command ackey {\n" + + " [string:key] {\n" + + " help Sets your Admin Chat key;\n" + + " perm utils.ac;\n" + + " type player;\n" + + " run setackey key;\n" + + " }\n" + + "}\n" + + "\n" + + "command act {\n" + + " on {\n" + + " help Turns on act;\n" + + " perm utils.ac;\n" + + " run act_on;\n" + + " }\n" + + " off {\n" + + " help Turns off act;\n" + + " perm utils.ac;\n" + + " run act_off;\n" + + " }\n" + + " [empty] {\n" + + " help toggles Admin Chat;\n" + + " perm utils.ac;\n" + + " run act;\n" + + " }\n" + + "}"; + } + // @format + + @Command(hook = "ac_msg") + public boolean acSay(CommandSender sender, String message) + { + String name; + if (sender instanceof Player) + name = ((Player) sender).getDisplayName(); + else + name = sender.getName(); + Utils.broadcast("§8[§cAC§8] §9" + name + "§8: §b", message, new BroadcastFilter() + { + @Override + public boolean sendTo(CommandSender recipient) + { + return recipient.hasPermission("utils.ac"); + } + }, '&'); + return true; + } + + /** Let's a Player toggle their auto-cg status to allow for automatically sending chat messages to their chatgroup. + * + * @param sender the issuer of the command. + * @param _void ignored. + * @return true. */ + @Command(hook = "act") + public boolean acToggleCommand(CommandSender sender) + { + if (actoggled.contains(((Player) sender).getUniqueId())) + { + actoggled.remove(((Player) sender).getUniqueId()); + Utils.sendMessage(sender, null, "ACT now §cdisabled"); + } + else + { + actoggled.add(((Player) sender).getUniqueId()); + Utils.sendMessage(sender, null, "ACT now §aenabled"); + } + return true; + } + + /** Let's a Player toggle their auto-cg status to allow for automatically sending chat messages to their chatgroup. + * + * @param sender the issuer of the command. + * @return true. */ + @Command(hook = "act_on") + public boolean acToggleOnCommand(CommandSender sender) + { + if (!actoggled.contains(((Player) sender).getUniqueId())) + { + actoggled.add(((Player) sender).getUniqueId()); + Utils.sendMessage(sender, null, "ACT now §aenabled"); + } + else + Utils.sendMessage(sender, null, "ACT was already enabled"); + return true; + } + + /** Let's a Player toggle their auto-cg status to allow for automatically sending chat messages to their chatgroup. + * + * @param sender the issuer of the command. + * @return true. */ + @Command(hook = "act_off") + public boolean acToggleOffCommand(CommandSender sender) + { + if (actoggled.contains(((Player) sender).getUniqueId())) + { + actoggled.remove(((Player) sender).getUniqueId()); + Utils.sendMessage(sender, null, "ACT now §cdisabled"); + } + else + { + Utils.sendMessage(sender, null, "ACT was already disabled"); + } + return true; + } + + /** Deals with chat events to allow for cgkeys and cgtoggle. + * + * @param event the chat event containing the player and the message. */ + @EventHandler + public void onPlayerChat(AsyncPlayerChatEvent event) + { + Player player = event.getPlayer(); + if (!player.hasPermission("utils.ac")) + return; + if (event.getMessage().startsWith(getKey(player))) + { + event.setCancelled(true); + acSay(event.getPlayer(), event.getMessage().replaceFirst(getKey(player), "")); + } + else if (actoggled.contains(event.getPlayer().getUniqueId())) + { + event.setCancelled(true); + acSay(event.getPlayer(), event.getMessage()); + } + } + + /** Sets the ackey of a Player. + * + * @param sender the issuer of the command. + * @param key the key to be set. Set to NULL or "" to get your current key. + * @return true. */ + @SuppressWarnings("unchecked") + @Command(hook = "setackey") + public boolean setAcKey(CommandSender sender, String key) + { + if (key.length() > 1) + { + Utils.sendErrorMessage(sender, null, + "Could not set your key to §6" + key + " §7, it can be at most one char."); + return true; + } + if (key == null || key.length() == 0) + { + getAcKey(sender); + return true; + } + Utils.sendMessage(sender, null, "Set your key to §6" + key); + keys.put(((Player) sender).getUniqueId().toString(), key + ""); + saveKeys(); + return true; + } + + /** This method will find the ChatgGroup key of any player. + * + * @param player the player to get the key from. + * @return the key. */ + public static String getKey(Player player) + { + String key = (String) keys.get(player.getUniqueId().toString()); + return (key == null ? "" + defaultKey : key); + } + + /** Prints a Players ackey to their chat. + * + * @param sender the issuer of the command. */ + public void getAcKey(CommandSender sender) + { + Utils.sendMessage(sender, null, "Your current ackey is §6" + getKey((Player) sender)); + } + + /** Saves the keys. */ + private void saveKeys() + { + JsonManager.save(keys, keysLocation); + } +} diff --git a/src/com/redstoner/modules/adminnotes/AdminNotes.java b/src/com/redstoner/modules/adminnotes/AdminNotes.java new file mode 100644 index 0000000..7877735 --- /dev/null +++ b/src/com/redstoner/modules/adminnotes/AdminNotes.java @@ -0,0 +1,131 @@ +package com.redstoner.modules.adminnotes; + +import java.io.File; +import java.text.SimpleDateFormat; + +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.json.simple.JSONArray; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.JsonManager; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@AutoRegisterListener +@Version(major = 2, minor = 0, revision = 0, compatible = 2) +public class AdminNotes implements Module, Listener +{ + JSONArray notes; + File saveFile = new File(Main.plugin.getDataFolder(), "adminnotes.json"); + + @Override + public boolean onEnable() + { + notes = JsonManager.getArray(saveFile); + if (notes == null) + notes = new JSONArray(); + return true; + } + + @EventHandler + public void onJoin(PlayerJoinEvent e) + { + if (e.getPlayer().hasPermission("utils.adminnotes")) + { + if (notes.size() > 0) + { + Utils.sendMessage(e.getPlayer(), null, "§cThere are " + notes.size() + " open notes!"); + } + } + } + + @Override + public void onDisable() + { + saveNotes(); + } + + @SuppressWarnings("unchecked") + @Command(hook = "an_create") + public void createNote(CommandSender sender, String note) + { + JSONArray temp = new JSONArray(); + temp.add(sender.getName()); + temp.add(note); + temp.add((double) System.currentTimeMillis() / 1000); + notes.add(temp); + Utils.sendMessage(sender, null, "§aNote added!"); + saveNotes(); + } + + @Command(hook = "an_del") + public void delNote(CommandSender sender, int id) + { + if (id < notes.size() && id >= 0 && notes.get(id) != null) + { + notes.remove(id); + Utils.sendMessage(sender, null, "§aNote " + id + " has been removed!"); + saveNotes(); + } + else + { + Utils.sendMessage(sender, null, "§cThat note does not exist!"); + } + } + + @Command(hook = "an_list") + public void list(CommandSender sender) + { + Utils.sendModuleHeader(sender); + for (Object note : notes) + { + String string = ChatColor.YELLOW + "" + notes.indexOf(note) + ": "; + string += "§a" + ((JSONArray) note).get(1); + string += "\n§e - " + ((JSONArray) note).get(0) + ", §6"; + SimpleDateFormat format = new SimpleDateFormat("MMM dd, yyyy HH:mm"); + string += format.format((double) ((JSONArray) note).get(2) * 1000); + Utils.sendMessage(sender, "", string); + } + } + + public void saveNotes() + { + JsonManager.save(notes, saveFile); + } + + // @noformat + @Override + public String getCommandString() + { + return "command an {\n" + + " perm utils.adminnotes;\n" + + " \n" + + " add [string:note...] {\n" + + " type player;\n" + + " help Creates a new admin note;\n" + + " run an_create note;\n" + + " perm utils.an;" + + " }\n" + + " \n" + + " del [int:id] {\n" + + " help Deletes an admin note;\n" + + " run an_del id;\n" + + " perm utils.an;" + + " }\n" + + " \n" + + " list {\n" + + " help Lists all notes;\n" + + " run an_list;\n" + + " perm utils.an;" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/challenge/Challenge.java b/src/com/redstoner/modules/challenge/Challenge.java new file mode 100644 index 0000000..0d020a8 --- /dev/null +++ b/src/com/redstoner/modules/challenge/Challenge.java @@ -0,0 +1,284 @@ +package com.redstoner.modules.challenge; + +import java.io.File; +import java.util.Random; + +import org.bukkit.command.CommandSender; +import org.json.simple.JSONArray; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.Version; +import com.redstoner.misc.JsonManager; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@Version(major = 2, minor = 0, revision = 1, compatible = 2) +public class Challenge implements Module +{ + private File challengeLocation = new File(Main.plugin.getDataFolder(), "challenges.json"); + private JSONArray challenges; + + @Override + public boolean onEnable() + { + challenges = JsonManager.getArray(challengeLocation); + if (challenges == null) + challenges = new JSONArray(); + return true; + } + + @Override + public void onDisable() + { + saveChallenges(); + } + + @SuppressWarnings("unchecked") + @Command(hook = "addchallenge") + public boolean addChallenge(CommandSender sender, String text) + { + if (challenges.contains(text)) + Utils.sendErrorMessage(sender, null, "That challenge already exists!"); + else + { + Utils.sendMessage(sender, null, "Successfully added a new challenge!"); + challenges.add(text); + saveChallenges(); + } + return true; + } + + @Command(hook = "delchallenge") + public boolean delChallenge(CommandSender sender, int id) + { + if (challenges.size() == 0) + { + Utils.sendErrorMessage(sender, null, "There are no challenges yet!"); + return true; + } + if (id < 0 || id >= challenges.size()) + { + Utils.sendErrorMessage(sender, null, "The ID must be at least 0 and at most " + (challenges.size() - 1)); + return true; + } + Utils.sendMessage(sender, null, "Successfully deleted the challenge: " + challenges.remove(id), '&'); + saveChallenges(); + return true; + } + + @SuppressWarnings("unchecked") + @Command(hook = "setchallenge") + public boolean setChallenge(CommandSender sender, int id, String text) + { + if (challenges.size() == 0) + { + Utils.sendErrorMessage(sender, null, "There are no challenges yet!"); + return true; + } + if (id < 0 || id >= challenges.size()) + { + Utils.sendErrorMessage(sender, null, "The ID must be at least 0 and at most " + (challenges.size() - 1)); + return true; + } + Utils.sendMessage(sender, null, + "Successfully changed the challenge: &a" + challenges.get(id) + " &7to: &e" + text, '&'); + challenges.set(id, text); + saveChallenges(); + return true; + } + + @Command(hook = "challengeid") + public boolean challengeId(CommandSender sender, int id) + { + if (challenges.size() == 0) + { + Utils.sendErrorMessage(sender, null, "There are no challenges yet!"); + return true; + } + if (id < 0 || id >= challenges.size()) + { + Utils.sendErrorMessage(sender, null, "The ID must be at least 0 and at most " + (challenges.size() - 1)); + return true; + } + Utils.sendMessage(sender, null, "&a" + challenges.get(id), '&'); + return true; + } + + @Command(hook = "challenge") + public boolean challenge(CommandSender sender) + { + if (challenges.size() == 0) + { + Utils.sendErrorMessage(sender, null, "There are no challenges yet!"); + return true; + } + int id = (new Random()).nextInt(challenges.size()); + Utils.sendMessage(sender, null, "&a" + challenges.get(id), '&'); + return true; + } + + @Command(hook = "listchallenges") + public boolean listChallenges(CommandSender sender, int page) + { + if (challenges.size() == 0) + { + Utils.sendErrorMessage(sender, null, "There are no challenges yet!"); + return true; + } + page = page - 1; + int start = page * 10; + int end = start + 10; + int pages = (int) Math.ceil(challenges.size() / 10d); + if (start < 0) + { + Utils.sendErrorMessage(sender, null, "Page number too small, must be at least 0!"); + return true; + } + if (start > challenges.size()) + { + Utils.sendErrorMessage(sender, null, "Page number too big, must be at most " + pages + "!"); + return true; + } + Utils.sendModuleHeader(sender); + Utils.sendMessage(sender, "", "&ePage " + (page + 1) + "/" + pages + ":", '&'); + for (int i = start; i < end && i < challenges.size(); i++) + Utils.sendMessage(sender, "", "&a" + i + "&8: &e" + challenges.get(i), '&'); + return true; + } + + @Command(hook = "listchallengesdef") + public boolean listChallengesDefault(CommandSender sender) + { + return listChallenges(sender, 1); + } + + @Command(hook = "searchchallenge") + public boolean search(CommandSender sender, boolean insensitive, String text) + { + Utils.sendModuleHeader(sender); + boolean found = false; + if (insensitive) + { + text = text.toLowerCase(); + for (int i = 0; i < challenges.size(); i++) + { + if (((String) challenges.get(i)).toLowerCase().contains(text)) + { + Utils.sendMessage(sender, "", "&a" + i + "&8: &e" + challenges.get(i), '&'); + found = true; + } + } + } + else + { + for (int i = 0; i < challenges.size(); i++) + { + if (((String) challenges.get(i)).contains(text)) + { + Utils.sendMessage(sender, "", "&a" + i + "&8: &e" + challenges.get(i), '&'); + found = true; + } + } + } + if (!found) + { + Utils.sendMessage(sender, "", "&cCouldn't find any matching challenges.", '&'); + } + return true; + } + + @Command(hook = "matchchallenge") + public boolean match(CommandSender sender, boolean insensitive, String regex) + { + Utils.sendModuleHeader(sender); + boolean found = false; + if (insensitive) + { + regex = regex.toLowerCase(); + for (int i = 0; i < challenges.size(); i++) + { + if (((String) challenges.get(i)).toLowerCase().matches(regex)) + { + Utils.sendMessage(sender, "", "&a" + i + ": " + challenges.get(i), '&'); + found = true; + } + } + } + else + { + for (int i = 0; i < challenges.size(); i++) + { + if (((String) challenges.get(i)).matches(regex)) + { + Utils.sendMessage(sender, "", "&a" + i + ": " + challenges.get(i), '&'); + found = true; + } + } + } + if (!found) + { + Utils.sendMessage(sender, "", "&cCouldn't find any matching challenges.", '&'); + } + return true; + } + + public void saveChallenges() + { + JsonManager.save(challenges, challengeLocation); + } + + // @noformat + @Override + public String getCommandString() + { + return "command challenge {\n" + + " add [string:text...] {\n" + + " help Adds a challenge.;\n" + + " run addchallenge text;\n" + + " perm utils.challenge.add;\n" + + " }\n" + + " del [int:id] {\n" + + " help Removes a challenge.;\n" + + " run delchallenge id;\n" + + " perm utils.challenge.admin;\n" + + " }\n" + + " set [int:id] [string:text...] {\n" + + " help Sets a challenge.;\n" + + " run setchallenge id text;\n" + + " perm utils.challenge.admin;\n" + + " }\n" + + " id [int:id] {\n" + + " help Get a paticular challenge.;\n" + + " run challengeid id;\n" + + " perm utils.challenge.id;\n" + + " }\n" + + " list [int:page] {\n" + + " help Shows challenges.;\n" + + " run listchallenges page;\n" + + " perm utils.challenge.list;\n" + + " }\n" + + " list {\n" + + " help Shows challenges.;\n" + + " run listchallengesdef;\n" + + " perm utils.challenge.list;\n" + + " }\n" + + " search [flag:-i] [string:text...] {\n" + + " help Search challenges.;\n" + + " run searchchallenge -i text;\n" + + " perm utils.challenge.search;\n" + + " }\n" + + " match [flag:-i] [string:regex...] {\n" + + " help Search challenges. But better.;\n" + + " run matchchallenge -i regex;\n" + + " perm utils.challenge.match;\n" + + " }\n" + + " [empty] {\n" + + " help Gives a challenge.;\n" + + " run challenge;\n" + + " perm utils.challenge;\n" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/chatalias/Chatalias.java b/src/com/redstoner/modules/chatalias/Chatalias.java new file mode 100644 index 0000000..8e2f174 --- /dev/null +++ b/src/com/redstoner/modules/chatalias/Chatalias.java @@ -0,0 +1,354 @@ +package com.redstoner.modules.chatalias; + +import java.io.File; +import java.util.Set; +import java.util.UUID; +import java.util.regex.Pattern; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.permissions.PermissionAttachmentInfo; +import org.json.simple.JSONObject; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.JsonManager; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@AutoRegisterListener +@Version(major = 2, minor = 0, revision = 5, compatible = 2) +public class Chatalias implements Module, Listener +{ + // to export chatalias data to json: + // pyeval [save_json_file("aliases/" + uuid, shared['modules']['chatalias'].data[uuid]) for uuid in shared['modules']['chatalias'].data] + // HANDLE WITH CARE! This will create an array of null entries the size of len(data)! + private final String[] commands = new String[] {"e?r", "e?m .+? ", "e?t", "e?w", "e?msg .+? ", "e?message .+? ", + "e?whisper .+? ", "e?me", "cg say", "ac"}; + private JSONObject aliases = new JSONObject(); + + @Override + public boolean onEnable() + { + for (Player p : Bukkit.getOnlinePlayers()) + { + loadAliases(p.getUniqueId()); + } + return true; + } + + @Override + public void onDisable() + { + for (Object key : aliases.keySet()) + { + UUID uuid = UUID.fromString((String) key); + saveAliases(uuid); + } + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) + { + loadAliases(event.getPlayer().getUniqueId()); + } + + @EventHandler + public void onPlayerLeave(PlayerQuitEvent event) + { + aliases.remove(event.getPlayer().getUniqueId().toString()); + } + + @SuppressWarnings("unchecked") + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerChat(AsyncPlayerChatEvent event) + { + Player player = event.getPlayer(); + UUID uuid = player.getUniqueId(); + if (!aliases.containsKey(uuid.toString())) + { + loadAliases(player.getUniqueId()); + if (!aliases.containsKey(uuid.toString())) + return; + } + JSONObject playerAliases = (JSONObject) aliases.get(uuid.toString()); + boolean changed = false; + for (Object key : playerAliases.keySet()) + { + String keyword = (String) key; + String replacement = (String) playerAliases.get(key); + if (keyword.startsWith("R: ")) + { + keyword = keyword.replace("R: ", ""); + event.setMessage(event.getMessage().replaceAll(keyword, replacement)); + } + else + { + if (keyword.startsWith("N: ")) + keyword = keyword.replace("N: ", ""); + else + { + changed = true; + playerAliases.put("N: " + key, replacement); + } + event.setMessage(event.getMessage().replace(keyword, replacement)); + } + int maxLength; + try + { + maxLength = Integer.valueOf(getPermissionContent(player, "utils.alias.length.")); + } + catch (NumberFormatException e) + { + maxLength = 255; + } + if (event.getMessage().length() > maxLength) + { + Utils.sendErrorMessage(player, null, "The generated message is too long!"); + event.setCancelled(true); + return; + } + } + event.setMessage(colorify(event.getMessage(), player)); + if (changed) + saveAliases(uuid); + } + + public static String colorify(String message, CommandSender sender) + { + if (sender.hasPermission("essentials.chat.color")) + message = message.replaceAll("&([0-9a-fA-FrR])", "§$1"); + if (sender.hasPermission("essentials.chat.format")) + message = message.replaceAll("&(l-oL-OrR)", "§$1"); + if (sender.hasPermission("essentials.chat.magic")) + message = message.replaceAll("&([kKrR])", "§$1"); + return message; + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerCommand(PlayerCommandPreprocessEvent event) + { + if (event.isCancelled()) + return; + boolean listening = false; + String regex = ""; + for (String s : commands) + { + regex = "^\\/(.*:)?" + s + ".*"; + if (event.getMessage().matches(regex)) + { + listening = true; + break; + } + } + if (!listening) + return; + Player player = event.getPlayer(); + UUID uuid = player.getUniqueId(); + JSONObject playerAliases = (JSONObject) aliases.get(uuid.toString()); + String command = event.getMessage().replaceFirst(regex.replaceAll("\\.\\*$", ""), ""); + command = event.getMessage().replace(command, ""); + event.setMessage(event.getMessage().replaceFirst(Pattern.quote(command), "§§")); + for (Object key : playerAliases.keySet()) + { + String keyword = (String) key; + String replacement = (String) playerAliases.get(key); + if (keyword.startsWith("R: ")) + { + keyword = keyword.replace("R: ", ""); + event.setMessage(event.getMessage().replaceAll(keyword, replacement)); + } + else + { + if (keyword.startsWith("N: ")) + keyword = keyword.replace("N: ", ""); + event.setMessage(event.getMessage().replace(keyword, replacement)); + } + int maxLength; + try + { + maxLength = Integer.valueOf(getPermissionContent(player, "utils.alias.length.")); + } + catch (NumberFormatException e) + { + maxLength = 255; + } + if (event.getMessage().length() > maxLength) + { + Utils.sendErrorMessage(player, null, "The generated message is too long!"); + event.setCancelled(true); + return; + } + } + event.setMessage(command + event.getMessage().substring(2)); + } + + @SuppressWarnings("unchecked") + @Command(hook = "addalias") + public boolean addAlias(CommandSender sender, boolean regex, String keyword, String replacement) + { + if (regex && keyword.equals(".*")) + { + Utils.sendErrorMessage(sender, null, "You may not define the wildcard regex as an alias."); + return true; + } + Player player = (Player) sender; + UUID uuid = player.getUniqueId(); + JSONObject data = (JSONObject) aliases.get(uuid.toString()); + keyword = (regex ? "R: " : "N: ") + keyword; + if (!data.containsKey(keyword)) + { + int maxAmount; + try + { + maxAmount = Integer.valueOf(getPermissionContent(player, "utils.alias.amount.")); + } + catch (NumberFormatException e) + { + maxAmount = 25; + } + if (data.size() == maxAmount) + { + Utils.sendErrorMessage(sender, null, "You already reached your maximum of aliases!"); + return true; + } + } + data.put(keyword, replacement); + if (sender.hasPermission("essentials.chat.color")) + Utils.sendMessage(sender, null, + "Successfully created alias " + keyword.substring(3) + " §7-> " + replacement + " §7for you.", '&'); + else + Utils.sendMessage(sender, null, + "Successfully created alias " + keyword.substring(3) + " §7-> " + replacement + " §7for you."); + saveAliases(uuid); + return true; + } + + @Command(hook = "delalias") + public boolean delAlias(CommandSender sender, boolean regex, String keyword) + { + Player player = (Player) sender; + UUID uuid = player.getUniqueId(); + JSONObject data = (JSONObject) aliases.get(uuid.toString()); + keyword = (regex ? "R: " : "N: ") + keyword; + if (data.remove(keyword) != null) + { + Utils.sendMessage(sender, null, "Successfully removed the alias!"); + saveAliases(uuid); + return true; + } + else + { + Utils.sendErrorMessage(sender, null, + "That alias doesn't exist! Hint: regex/no regex does matter for this."); + return true; + } + } + + @Command(hook = "listaliases") + public boolean listAliases(CommandSender sender) + { + Utils.sendModuleHeader(sender); + Player player = (Player) sender; + UUID uuid = player.getUniqueId(); + JSONObject data = (JSONObject) aliases.get(uuid.toString()); + for (Object key : data.keySet()) + { + if (sender.hasPermission("essentials.chat.color")) + Utils.sendMessage(sender, "", (String) key + " §7-> " + data.get(key), '&'); + else + Utils.sendMessage(sender, "", (String) key + " §7-> " + data.get(key)); + } + return true; + } + + private String getPermissionContent(Player player, String permnode) + { + Set perms = player.getEffectivePermissions(); + for (PermissionAttachmentInfo perm : perms) + if (perm.getPermission().toString().startsWith(permnode)) + return perm.getPermission().replace(permnode, ""); + return null; + } + + @SuppressWarnings("unchecked") + private void loadAliases(UUID uuid) + { + JSONObject defaults = new JSONObject(); + defaults.put("dataFormat", "v1"); + JSONObject data = new JSONObject(); + data.put("N: ./", "/"); + defaults.put("data", data); + JSONObject playerAliases = JsonManager + .getObject(new File(Main.plugin.getDataFolder(), "aliases/" + uuid.toString() + ".json")); + if (playerAliases == null) + { + playerAliases = defaults; + } + String dataFormat = (String) playerAliases.get("dataFormat"); + if (dataFormat == null) + { + JSONObject temp = new JSONObject(); + temp.put("dataFormat", "v1"); + JSONObject tempAliases = new JSONObject(); + { + for (Object key : playerAliases.keySet()) + { + tempAliases.put("N: " + key, playerAliases.get(key)); + } + } + temp.put("data", tempAliases); + aliases.put(uuid.toString(), temp.get("data")); + } + else if (dataFormat.equals("v1")) + aliases.put(uuid.toString(), playerAliases.get("data")); + else + { + Utils.error("Unknown data format for alias set of player " + uuid.toString()); + aliases.put(uuid.toString(), ((JSONObject) defaults.get("data")).clone()); + saveAliases(uuid); + } + } + + @SuppressWarnings("unchecked") + private void saveAliases(UUID uuid) + { + JSONObject temp = new JSONObject(); + temp.put("dataFormat", "v1"); + temp.put("data", aliases.get(uuid.toString())); + JsonManager.save(temp, new File(Main.plugin.getDataFolder(), "aliases/" + uuid.toString() + ".json")); + } + + // @noformat + @Override + public String getCommandString() + { + return "command alias {\n" + + " add [flag:-r] [string:keyword] [string:replacement...] {\n" + + " help Adds a new alias. Set -r to make it a regex-alias.;\n" + + " run addalias -r keyword replacement;\n" + + " }\n" + + " del [flag:-r] [string:keyword] {\n" + + " help Deletes an alias. -r indicates if it was a regex-alias.;\n" + + " run delalias -r keyword;\n" + + " }\n" + + " list {\n" + + " help Lists your aliases.;\n" + + " run listaliases;\n" + + " }\n" + + " perm utils.alias;\n" + + " type player;\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/chatgroups/Chatgroups.java b/src/com/redstoner/modules/chatgroups/Chatgroups.java new file mode 100644 index 0000000..8244aa6 --- /dev/null +++ b/src/com/redstoner/modules/chatgroups/Chatgroups.java @@ -0,0 +1,408 @@ +package com.redstoner.modules.chatgroups; + +import java.io.File; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.json.simple.JSONObject; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.BroadcastFilter; +import com.redstoner.misc.JsonManager; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +/** The ChatGroups module. Allows people to have private sub-chats that can be accessed via a single char prefix or a toggle. + * + * @author Pepich */ +@AutoRegisterListener +@Version(major = 2, minor = 0, revision = 2, compatible = 2) +public class Chatgroups implements Module, Listener +{ + private static final char defaultKey = ':'; + private static final File groupsLocation = new File(Main.plugin.getDataFolder(), "chatgroups.json"); + private static final File keysLocation = new File(Main.plugin.getDataFolder(), "chatgroup_keys.json"); + private ArrayList cgtoggled; + private static JSONObject groups, keys; + + @Override + public boolean onEnable() + { + groups = JsonManager.getObject(groupsLocation); + if (groups == null) + { + groups = new JSONObject(); + saveGroups(); + } + keys = JsonManager.getObject(keysLocation); + if (keys == null) + { + keys = new JSONObject(); + saveKeys(); + } + cgtoggled = new ArrayList(); + return true; + } + + @Override + public void onDisable() + { + saveKeys(); + saveGroups(); + } + + // @noformat + @Override + public String getCommandString() + { + return "command cgt {\n" + + " [empty] {\n" + + " help Toggles your cgtoggle status.;\n"+ + " type player;\n" + + " run cgtoggle;\n" + + " }\n" + + "}\n" + + "command cgkey {\n" + + " [string:key] {\n" + + " help Sets your chatgroup key.;\n" + + " run setcgkey key;\n" + + " type player;\n" + + " }\n" + + "}\n" + + "command cgsay {\n" + + " [string:message...] {\n" + + " help Chats in your chatgroup.;\n"+ + " run cgsay message;\n" + + " }\n" + + "}\n" + + "command cg {\n" + + " join [string:group] {\n" + + " help Joins a chatgroup.;\n" + + " run cgjoin group;\n" + + " }\n" + + " leave {\n" + + " help Leaves your chatgroup.;\n" + + " run cgleave;\n" + + " }\n" + + " info {\n" + + " help Displays info about your chatgroup.;\n" + + " run cginfo;\n" + + " }\n" + + + "}"; + } + // @format + + /** Prints chatgroup info (like players in the group, groupname) to the sender. + * + * @param sender the issuer of the command. + * @return true. */ + @SuppressWarnings("unchecked") + @Command(hook = "cginfo") + public boolean cgInfo(CommandSender sender) + { + String group = getGroup(sender); + if (group == null) + Utils.sendErrorMessage(sender, null, "You are not in a chatgroup!"); + else + { + Utils.sendModuleHeader(sender); + Utils.sendMessage(sender, "", "Your current chatgroup is: §6" + group); + ArrayList players = new ArrayList(); + Iterator iter = groups.keySet().iterator(); + while (iter.hasNext()) + { + String id = iter.next(); + if (((String) groups.get(id)).equals(group)) + { + if (!id.equals("CONSOLE")) + { + UUID uuid = UUID.fromString(id); + Player p = Bukkit.getPlayer(uuid); + if (p != null) + players.add(p.getDisplayName()); + else + players.add(Bukkit.getOfflinePlayer(UUID.fromString(id)).getName()); + } + else + players.add(id); + } + } + StringBuilder sb = new StringBuilder("&6Other players in this group: &9"); + for (String player : players) + { + sb.append(player); + sb.append("&7, &9"); + } + sb.delete(sb.length() - 2, sb.length()); + Utils.sendMessage(sender, "", sb.toString(), '&'); + } + return true; + } + + /** Prints a Players cgkey to their chat. + * + * @param sender the issuer of the command. */ + public void getCgKey(CommandSender sender) + { + Utils.sendMessage(sender, null, "Your current cgkey is §6" + getKey((Player) sender)); + } + + /** Sets the cgkey of a Player. + * + * @param sender the issuer of the command. + * @param key the key to be set. Set to NULL or "" to get your current key. + * @return true. */ + @SuppressWarnings("unchecked") + @Command(hook = "setcgkey") + public boolean setCgKey(CommandSender sender, String key) + { + if (key.length() > 1) + { + Utils.sendErrorMessage(sender, null, + "Could not set your key to §6" + key + " §7, it can be at most one char."); + return true; + } + if (key == null || key.length() == 0) + { + getCgKey(sender); + return true; + } + Utils.sendMessage(sender, null, "Set your key to §6" + key); + keys.put(((Player) sender).getUniqueId().toString(), key + ""); + saveKeys(); + return true; + } + + /** Let's a Player toggle their auto-cg status to allow for automatically sending chat messages to their chatgroup. + * + * @param sender the issuer of the command. + * @return true. */ + @Command(hook = "cgtoggle") + public boolean cgToggleCommand(CommandSender sender) + { + if (getGroup(sender) != null) + if (cgtoggled.contains(((Player) sender).getUniqueId())) + { + cgtoggled.remove(((Player) sender).getUniqueId()); + Utils.sendMessage(sender, null, "CGT now §cdisabled"); + } + else + { + cgtoggled.add(((Player) sender).getUniqueId()); + Utils.sendMessage(sender, null, "CGT now §aenabled"); + } + else + Utils.sendErrorMessage(sender, null, "You are not in a chatgroup!"); + return true; + } + + /** Lets a CommandSender leave their group. + * + * @param sender the command issuer. + * @return true. */ + @Command(hook = "cgleave") + public boolean cgLeave(CommandSender sender) + { + String group = removeGroup(sender); + if (group == null) + { + Utils.sendErrorMessage(sender, null, "You were not in a chatgroup!"); + return true; + } + String name; + if (sender instanceof Player) + name = ((Player) sender).getDisplayName(); + else + name = sender.getName(); + sendToGroup(group, "&9" + name + " &7left the group!"); + Utils.sendMessage(sender, null, "Successfully removed you from your group!"); + if (sender instanceof Player) + cgtoggled.remove(((Player) sender).getUniqueId()); + return true; + } + + /** Lets a CommandSender join a group. + * + * @param sender the command issuer. + * @param name the name of the group. + * @return true. */ + @Command(hook = "cgjoin") + public boolean cgJoin(CommandSender sender, String name) + { + String pname; + if (sender instanceof Player) + pname = ((Player) sender).getDisplayName(); + else + pname = sender.getName(); + sendToGroup(name, "&9" + pname + " &7joined the group!"); + setGroup(sender, name); + Utils.sendMessage(sender, null, "Successfully joined group §6" + name); + return true; + } + + /** Sends a message to a group. + * + * @param sender the sender of the message - the message will be sent to the group of the sender. + * @param message the message to be sent. + * @return true. */ + @Command(hook = "cgsay") + public boolean cgSay(CommandSender sender, String message) + { + String group = getGroup(sender); + if (group != null) + sendToGroup(sender, message); + else + Utils.sendErrorMessage(sender, null, "You are not in a chatgroup right now!"); + return true; + } + + /** Deals with chat events to allow for cgkeys and cgtoggle. + * + * @param event the chat event containing the player and the message. */ + @EventHandler + public void onPlayerChat(AsyncPlayerChatEvent event) + { + String group = getGroup(event.getPlayer()); + Player player = event.getPlayer(); + if (group != null) + { + if (event.getMessage().startsWith(getKey(player))) + { + event.setCancelled(true); + sendToGroup(event.getPlayer(), event.getMessage().substring(1)); + } + else if (cgtoggled.contains(event.getPlayer().getUniqueId())) + { + event.setCancelled(true); + sendToGroup(event.getPlayer(), event.getMessage()); + } + } + } + + /** Finds the group of a CommandSender. + * + * @param target the CommandSender to get the group of. + * @return the group of the target or NULL if he doesn't have one. */ + public static String getGroup(CommandSender target) + { + if (target instanceof Player) + return (String) groups.get(((Player) target).getUniqueId().toString()); + else + return (String) groups.get("CONSOLE"); + } + + /** Sets the group of the CommandSender. + * + * @param target the CommandSender to set the group of. + * @param group the name of the group to join. */ + @SuppressWarnings("unchecked") + private void setGroup(CommandSender target, String group) + { + if (target instanceof Player) + groups.put(((Player) target).getUniqueId().toString(), group); + else + groups.put("CONSOLE", group); + saveGroups(); + } + + /** Removes a CommandSender from their chatgroup. Will also save the groups after finishing + * + * @param target the CommandSender to get their group removed. */ + private String removeGroup(CommandSender target) + { + String group; + if (target instanceof Player) + group = (String) groups.remove(((Player) target).getUniqueId().toString()); + else + group = (String) groups.remove("CONSOLE"); + saveGroups(); + return group; + } + + /** This method will find the ChatgGroup key of any player. + * + * @param player the player to get the key from. + * @return the key. */ + public static String getKey(Player player) + { + String key = (String) keys.get(player.getUniqueId().toString()); + return (key == null ? "" + defaultKey : key); + } + + /** This method sends a message to a chatgroup. + * + * @param sender the sender of the message. Also defines which group the message will be sent to. + * @param message the message to be sent. */ + private void sendToGroup(CommandSender sender, String message) + { + String name; + if (sender instanceof Player) + name = ((Player) sender).getDisplayName(); + else + name = sender.getName(); + String group = getGroup(sender); + Utils.broadcast("§8[§bCG§8] §9", name + "§8: §6" + message, new BroadcastFilter() + { + @Override + public boolean sendTo(CommandSender recipient) + { + String rgroup = getGroup(recipient); + if (rgroup != null) + return rgroup.equals(group); + else + return false; + } + }, '&'); + if (getGroup(Bukkit.getConsoleSender()) == null || !getGroup(Bukkit.getConsoleSender()).equals(group)) + { + Utils.info(name + " in " + group + ": " + message + " §8(hidden)"); + } + } + + /** This method sends a message to a chatgroup. + * + * @param sender the sender of the message. Also defines which group the message will be sent to. + * @param message the message to be sent. */ + private void sendToGroup(String group, String message) + { + Utils.broadcast(null, message, new BroadcastFilter() + { + @Override + public boolean sendTo(CommandSender recipient) + { + String rgroup = getGroup(recipient); + if (rgroup != null) + return rgroup.equals(group); + else + return false; + } + }, '&'); + if (getGroup(Bukkit.getConsoleSender()) == null || !getGroup(Bukkit.getConsoleSender()).equals(group)) + { + Utils.info("In " + group + ": " + message + " §8(hidden)"); + } + } + + /** Saves the groups. */ + private void saveGroups() + { + JsonManager.save(groups, groupsLocation); + } + + /** Saves the keys. */ + private void saveKeys() + { + JsonManager.save(keys, keysLocation); + } +} diff --git a/src/com/redstoner/modules/chatonly/ChatOnly.java b/src/com/redstoner/modules/chatonly/ChatOnly.java new file mode 100644 index 0000000..dd41de6 --- /dev/null +++ b/src/com/redstoner/modules/chatonly/ChatOnly.java @@ -0,0 +1,8 @@ +package com.redstoner.modules.chatonly; + +import com.redstoner.annotations.Version; +import com.redstoner.modules.Module; + +@Version(major = 3, minor = 0, revision = 0, compatible = 3) +public class ChatOnly implements Module +{} diff --git a/src/com/redstoner/modules/check/Check.java b/src/com/redstoner/modules/check/Check.java new file mode 100644 index 0000000..d6219b4 --- /dev/null +++ b/src/com/redstoner/modules/check/Check.java @@ -0,0 +1,242 @@ +package com.redstoner.modules.check; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Serializable; +import java.net.MalformedURLException; +import java.net.URL; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; +import java.util.Scanner; + +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.CommandSender; +import org.bukkit.event.Listener; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import com.nemez.cmdmgr.Command; +import com.nemez.cmdmgr.Command.AsyncType; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Utils; +import com.redstoner.misc.mysql.JSONManager; +import com.redstoner.misc.mysql.MysqlHandler; +import com.redstoner.misc.mysql.elements.ConstraintOperator; +import com.redstoner.misc.mysql.elements.MysqlConstraint; +import com.redstoner.misc.mysql.elements.MysqlDatabase; +import com.redstoner.misc.mysql.elements.MysqlTable; +import com.redstoner.modules.Module; + +@Version(major = 2, minor = 0, revision = 1, compatible = 2) +public class Check implements Module, Listener +{ + MysqlTable table; + + @Override + public boolean onEnable() + { + Map config = JSONManager.getConfiguration("check.json"); + if (config == null || !config.containsKey("database") || !config.containsKey("table")) + { + Utils.error("Could not load the Check config file, disabling!"); + return false; + } + try + { + MysqlDatabase database = MysqlHandler.INSTANCE + .getDatabase((String) config.get("database") + "?autoReconnect=true"); + table = database.getTable((String) config.get("table")); + } + catch (NullPointerException e) + { + Utils.error("Could not use the Check config, disabling!"); + return false; + } + return true; + } + + @SuppressWarnings("deprecation") + @Command(hook = "checkCommand", async = AsyncType.ALWAYS) + public void checkCommand(final CommandSender sender, final String player) + { + Utils.sendModuleHeader(sender); + Utils.sendMessage(sender, "", "&7Please note that the data may not be fully accurate!", '&'); + OfflinePlayer oPlayer; + oPlayer = Bukkit.getPlayer(player); + if (oPlayer == null) + oPlayer = Bukkit.getServer().getOfflinePlayer(player); + sendData(sender, oPlayer); + } + + public String read(URL url) + { + String data = ""; + try + { + Scanner in = new Scanner(new InputStreamReader(url.openStream())); + while (in.hasNextLine()) + { + data += in.nextLine(); + } + in.close(); + return data; + } + catch (IOException e) + { + e.printStackTrace(); + } + return null; + } + + public JSONObject getIpInfo(OfflinePlayer player) + { + String ip = ""; + if (player.isOnline()) + { + ip = player.getPlayer().getAddress().getHostString(); + } + else + { + try + { + ip = (String) table.get("last_ip", new MysqlConstraint("uuid", ConstraintOperator.EQUAL, + player.getUniqueId().toString().replace("-", "")))[0]; + } + catch (Exception e) + { + e.printStackTrace(); + return null; + } + } + try + { + URL ipinfo = new URL("http://ipinfo.io/" + ip + "/json"); + String rawJson = read(ipinfo); + return (JSONObject) new JSONParser().parse(rawJson); + } + catch (Exception e) + { + e.printStackTrace(); + } + return null; + } + + public String getFirstJoin(OfflinePlayer player) + { + Long firstJoin = player.getFirstPlayed(); + Date date = new Date(firstJoin); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + return format.format(date); + } + + public String getLastSeen(OfflinePlayer player) + { + Long lastSeen = player.getLastPlayed(); + Date date = new Date(lastSeen); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + return format.format(date); + } + + public Object[] getWebsiteData(OfflinePlayer player) + { + MysqlConstraint constraint = new MysqlConstraint("uuid", ConstraintOperator.EQUAL, + player.getUniqueId().toString().replace("-", "")); + try + { + int id = (int) table.get("id", constraint)[0]; + String email = (String) table.get("email", constraint)[0]; + boolean confirmed = (boolean) table.get("confirmed", constraint)[0]; + return new Object[] {"https://redstoner.com/users/" + id, email, confirmed}; + } + catch (Exception e) + { + return new Object[] {null}; + } + } + + public String getCountry(JSONObject data) + { + return (String) data.get("country"); + } + + public String getAllNames(OfflinePlayer player) + { + String uuid = player.getUniqueId().toString().replace("-", ""); + String nameString = ""; + try + { + String rawJson = read(new URL("https://api.mojang.com/user/profiles/" + uuid + "/names")); + System.out.println("name for " + uuid + " : " + rawJson); + JSONArray names = (JSONArray) new JSONParser().parse(rawJson); + for (Object obj : names) + { + nameString += ((JSONObject) obj).get("name") + ", "; + } + nameString = nameString.substring(0, nameString.length() - 2); + return nameString; + } + catch (MalformedURLException | ParseException e) + { + e.printStackTrace(); + } + return null; + } + + public void sendData(CommandSender sender, OfflinePlayer player) + { + JSONObject ipInfo = getIpInfo(player); + try + { + // data + String firstJoin = getFirstJoin(player); + String lastSeen = getLastSeen(player); + firstJoin = (firstJoin.equals("1970-01-01 01:00")) ? "&eNever" : "&7(yyyy-MM-dd hh:mm:ss) &e" + firstJoin; + lastSeen = (lastSeen.equals("1970-1-1 1:0")) ? "&eNever" : "&7(yyyy-MM-dd hh:mm:ss) &e" + lastSeen; + Object[] websiteData = getWebsiteData(player); + String websiteUrl = (websiteData[0] == null) ? "None" : (String) websiteData[0]; + String email = (websiteData[0] == null) ? "Unknown" : (String) websiteData[1]; + boolean emailNotConfirmed = (websiteData[0] == null) ? false : !((boolean) websiteData[2]); + String country = (ipInfo == null) ? "Unknown" : getCountry(ipInfo); + String namesUsed = getAllNames(player); + if (namesUsed == null) + namesUsed = "None"; + // messages + Utils.sendMessage(sender, "", "&7Data provided by Redstoner:", '&'); + Utils.sendMessage(sender, "", "&6> UUID: &e" + player.getUniqueId(), '&'); + Utils.sendMessage(sender, "", "&6> First joined: " + firstJoin, '&'); + Utils.sendMessage(sender, "", "&6> Last seen: " + lastSeen, '&'); + Utils.sendMessage(sender, "", "&6> Website account: &e" + websiteUrl, '&'); + Utils.sendMessage(sender, "", "&6> email: &e" + email, '&'); + if (emailNotConfirmed) + Utils.sendMessage(sender, "", "&6> &4Email NOT Confirmed!", '&'); + Utils.sendMessage(sender, "", "&7Data provided by ipinfo:", '&'); + Utils.sendMessage(sender, "", "&6> Country: &e" + country, '&'); + Utils.sendMessage(sender, "", "&7Data provided by Mojang:", '&'); + Utils.sendMessage(sender, "", "&6> All ingame names used so far: &e" + namesUsed, '&'); + } + catch (Exception e) + { + e.printStackTrace(); + Utils.sendErrorMessage(sender, null, "&cSorry, something went wrong while fetching data", '&'); + } + } + + // @noformat + @Override + public String getCommandString() + { + return "command check {\n" + + " perm utils.check;\n" + + " \n" + + " [string:player] {\n" + + " run checkCommand player;\n" + + " help Get info on a player;\n" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/clear/Clear.java b/src/com/redstoner/modules/clear/Clear.java new file mode 100644 index 0000000..e50844c --- /dev/null +++ b/src/com/redstoner/modules/clear/Clear.java @@ -0,0 +1,40 @@ +package com.redstoner.modules.clear; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@Version(major = 2, minor = 0, revision = 1, compatible = 2) +public class Clear implements Module +{ + @Command(hook = "clear") + public boolean clearInventory(CommandSender sender) + { + Player player = (Player) sender; + Inventory inv = player.getInventory(); + for (int i = 0; i < 36; i++) + inv.clear(i); + Utils.sendMessage(sender, null, "Cleared your inventory!"); + return true; + } + + // @noformat + @Override + public String getCommandString() + { + return "command clear{\n" + + " [empty] {\n" + + " help clears your inventory;\n" + + " type player;\n" + + " perm utils.clear;\n" + + " run clear;\n" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/clearonjoin/ClearOnJoin.java b/src/com/redstoner/modules/clearonjoin/ClearOnJoin.java new file mode 100644 index 0000000..b818563 --- /dev/null +++ b/src/com/redstoner/modules/clearonjoin/ClearOnJoin.java @@ -0,0 +1,105 @@ +package com.redstoner.modules.clearonjoin; + +import java.io.File; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.json.simple.JSONArray; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.Version; +import com.redstoner.misc.JsonManager; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@Version(major = 2, minor = 1, revision = 0, compatible = 2) +public class ClearOnJoin implements Module, Listener +{ + private File listLocation = new File(Main.plugin.getDataFolder(), "clearonjoins.json"); + private JSONArray list; + + @SuppressWarnings({ "unchecked", "deprecation" }) + @Command(hook = "clearonjoin") + public void clearOnJoin(CommandSender sender, String player) + { + list.add("!" + Bukkit.getServer().getOfflinePlayer(player).getUniqueId().toString()); + saveList(); + Utils.sendMessage(sender, null, player + "'s inventory will be cleared next time they join."); + } + + @SuppressWarnings("unchecked") + @Command(hook = "clearonjoinself") + public void clearOnJoinSelf(CommandSender sender) + { + String name = ((Player)sender).getUniqueId().toString(); + if (list.contains(name)) + { + list.remove(name); + Utils.sendMessage(sender, null, "Your inventory will no longer be cleared upon joining."); + saveList(); + return; + } + list.add(name); + saveList(); + Utils.sendMessage(sender, null, "Your inventory will now be cleared upon joining."); + } + + @EventHandler + public void uponJoin(PlayerJoinEvent e) + { + Player player = e.getPlayer(); + String playerUUID = player.getUniqueId().toString(); + String playerName = player.getName(); + if (list.contains(playerName) || list.contains(playerUUID)) + { + e.getPlayer().getInventory().clear(); + Utils.sendMessage(player, null, "Inventory cleared."); + } + else if (list.contains("!" + playerName)) + { + player.getInventory().clear(); + list.remove("!" + playerName); + saveList(); + Utils.sendMessage(player, null, "Inventory cleared."); + } + } + + public void saveList() + { + JsonManager.save(list, listLocation); + } + + @Override + public boolean onEnable() + { + list = JsonManager.getArray(listLocation); + if (list == null) + list = new JSONArray(); + Bukkit.getServer().getPluginManager().registerEvents(this, Main.plugin); + return true; + } + + // @noformat + @Override + public String getCommandString() + { + return "command clearonjoin {\n" + + " [string:name] {\n" + + " help Clears that player's inventory the next time they join.;\n" + + " run clearonjoin name;\n" + + " perm utils.clearonjoin.other;\n" + + " }\n" + + " [empty] {\n" + + " help Clears your inventory every time you join.;\n" + + " run clearonjoinself;\n" + + " perm utils.clearonjoin.self;\n" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/cycle/Cycle.java b/src/com/redstoner/modules/cycle/Cycle.java new file mode 100644 index 0000000..5f6d2a7 --- /dev/null +++ b/src/com/redstoner/modules/cycle/Cycle.java @@ -0,0 +1,159 @@ +package com.redstoner.modules.cycle; + +import java.io.File; +import java.util.UUID; + +import org.bukkit.GameMode; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerItemHeldEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.json.simple.JSONArray; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.JsonManager; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@AutoRegisterListener +@Version(major = 2, minor = 0, revision = 0, compatible = 2) +public class Cycle implements Module, Listener +{ + private File cycleFile = new File(Main.plugin.getDataFolder(), "cycle.json"); + private JSONArray no_cyclers; + + @Override + public boolean onEnable() + { + no_cyclers = JsonManager.getArray(cycleFile); + if (no_cyclers == null) + no_cyclers = new JSONArray(); + return true; + } + + @Override + public void onDisable() + { + saveCyclers(); + } + + private void saveCyclers() + { + JsonManager.save(no_cyclers, cycleFile); + } + + @Command(hook = "cycle_on") + public boolean cycleOn(CommandSender sender) + { + UUID uid = ((Player) sender).getUniqueId(); + if (no_cyclers.remove(uid.toString())) + { + Utils.sendMessage(sender, null, "Cycle enabled!"); + saveCyclers(); + } + else + Utils.sendMessage(sender, null, "Cycle was already enabled!"); + return true; + } + + @SuppressWarnings("unchecked") + @Command(hook = "cycle_off") + public boolean cycleOff(CommandSender sender) + { + UUID uid = ((Player) sender).getUniqueId(); + if (!no_cyclers.contains(uid.toString())) + { + Utils.sendMessage(sender, null, "Cycle disabled!"); + no_cyclers.add(uid.toString()); + saveCyclers(); + } + else + Utils.sendMessage(sender, null, "Cycle was already disabled!"); + return true; + } + + @EventHandler + public void onInventoryCycle(PlayerItemHeldEvent event) + { + Player player = event.getPlayer(); + UUID uid = player.getUniqueId(); + if (!player.getGameMode().equals(GameMode.CREATIVE) || player.isSneaking() + || no_cyclers.contains(uid.toString())) + return; + int prev_slot = event.getPreviousSlot(); + int new_slot = event.getNewSlot(); + if (prev_slot == 0 && new_slot == 8) + shift(player, true); + else if (prev_slot == 8 && new_slot == 0) + shift(player, false); + } + + private void shift(Player player, boolean down) + { + Inventory inv = player.getInventory(); + ItemStack[] items = inv.getStorageContents(); + int shift = down ? -9 : 9; + shift = (shift + items.length) % items.length; + for (int i = 0; i < 4; i++) + { + items = join(subset(items, shift, items.length), subset(items, 0, shift)); + ItemStack[] hotbar = subset(items, 0, 9); + boolean found = false; + for (ItemStack item : hotbar) + if (item != null) + { + found = true; + break; + } + if (found) + break; + } + inv.setStorageContents(items); + } + + private ItemStack[] subset(ItemStack[] items, int start, int end) + { + ItemStack[] result = new ItemStack[end - start]; + for (int i = start; i < end; i++) + { + result[i - start] = items[i]; + } + return result; + } + + private ItemStack[] join(ItemStack[] items1, ItemStack[] items2) + { + ItemStack[] result = new ItemStack[items1.length + items2.length]; + for (int i = 0; i < items1.length; i++) + result[i] = items1[i]; + int offset = items1.length; + for (int i = 0; i < items2.length; i++) + result[i + offset] = items2[i]; + return result; + } + + // @noformat + @Override + public String getCommandString() + { + return "command cycle {\n" + + " on {\n" + + " help Turns on cycle;\n" + + " type player;\n" + + " run cycle_on;\n" + + " }\n" + + " off {\n" + + " help Turns off cycle;\n" + + " type player;\n" + + " run cycle_off;\n" + + " }\n" + + "}"; + } + // format +} diff --git a/src/com/redstoner/modules/damnspam/DamnSpam.java b/src/com/redstoner/modules/damnspam/DamnSpam.java new file mode 100644 index 0000000..8b9d0fa --- /dev/null +++ b/src/com/redstoner/modules/damnspam/DamnSpam.java @@ -0,0 +1,367 @@ +package com.redstoner.modules.damnspam; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@AutoRegisterListener +@Version(major = 2, minor = 0, revision = 1, compatible = 2) +public class DamnSpam implements Module, Listener +{ + File configFile = new File(Main.plugin.getDataFolder(), "DamnSpam.json"); + Map inputs; + boolean changingInput = false; + List acceptedInputs; + HashMap attachedBlocks; + HashMap players; + int maxTimeout = 240; + String timeoutErrorString = "&cThe timeout must be -1 or within 0 and " + maxTimeout; + + @Override + public boolean onEnable() + { + loadInputs(); + acceptedInputs = new ArrayList(); + Collections.addAll(acceptedInputs, Material.WOOD_BUTTON, Material.STONE_BUTTON, Material.LEVER); + attachedBlocks = new HashMap(); + attachedBlocks.put(Material.LEVER, + new int[][] {{0, 7, 8, 15}, {5, 6, 13, 14}, {4, 12}, {3, 11}, {2, 10}, {1, 9}}); + attachedBlocks.put(Material.STONE_BUTTON, + new int[][] {{0, 8}, {5, 6, 7, 13, 14, 15}, {4, 12}, {3, 11}, {2, 10}, {1, 9}}); + attachedBlocks.put(Material.WOOD_BUTTON, + new int[][] {{0, 8}, {5, 6, 7, 13, 14, 15}, {4, 12}, {3, 11}, {2, 10}, {1, 9}}); + players = new HashMap(); + return true; + } + + public void loadInputs() + { + inputs = new HashMap(); + try + { + FileReader reader = new FileReader(configFile); + JSONObject json = (JSONObject) new JSONParser().parse(reader); + for (Object key : json.keySet()) + { + JSONObject inputData = (JSONObject) json.get(key); + String uuid = (String) inputData.get("creator"); + Double timeoutOn = (Double) inputData.get("timeout_on"); + Double timeoutOff = (Double) inputData.get("timeout_off"); + Double lastTime = (Double) inputData.get("last_time"); + inputs.put((String) key, new SpamInput(uuid, timeoutOff, timeoutOn, lastTime)); + } + } + catch (IOException | ParseException e) + { + e.printStackTrace(); + } + } + + @SuppressWarnings("unchecked") + public void saveInputs() + { + JSONObject json = new JSONObject(); + for (String key : inputs.keySet()) + { + JSONObject jsonInput = new JSONObject(); + SpamInput input = inputs.get(key); + jsonInput.put("creator", input.player); + jsonInput.put("timeout_on", input.timeoutOn); + jsonInput.put("timeout_off", input.timeoutOff); + jsonInput.put("last_time", input.lastTime); + json.put(key, jsonInput); + } + try + { + PrintWriter writer = new PrintWriter(configFile); + writer.write(json.toJSONString()); + writer.close(); + } + catch (FileNotFoundException e) + { + e.printStackTrace(); + } + } + + public String locationString(Location loc) + { + return loc.getWorld().getName() + ";" + loc.getBlockX() + ";" + loc.getBlockY() + ";" + loc.getBlockZ(); + } + + public boolean isAcceptableTimeout(double timeout) + { + return (timeout > 0 && timeout <= maxTimeout) || timeout == -1; + } + + public boolean canBuild(Player player, Block block) + { + BlockBreakEvent event = new BlockBreakEvent(block, player); + Bukkit.getPluginManager().callEvent(event); + return !event.isCancelled(); + } + + @Command(hook = "damnspamSingle") + public void damnspam(CommandSender sender, double seconds) + { + boolean destroyingInput = false; + seconds = (double) Math.round(seconds * 100) / 100; + if (seconds == 0) + destroyingInput = true; + else if (!isAcceptableTimeout(seconds)) + { + Utils.sendMessage(sender, null, "&cThe timeout must be -1 or within 0 and " + maxTimeout, '&'); + return; + } + Utils.sendMessage(sender, null, "&aPlease click the input you would like to set.", '&'); + setPlayer((Player) sender, destroyingInput, seconds, seconds); + } + + @Command(hook = "damnspamDouble") + public void damnspam(CommandSender sender, double secondsOff, double secondsOn) + { + boolean destroyingInput = false; + secondsOn = (double) Math.round(secondsOn * 100) / 100; + secondsOff = (double) Math.round(secondsOff * 100) / 100; + if (secondsOn == 0 && secondsOff == 0) + { + destroyingInput = true; + } + else if (!(isAcceptableTimeout(secondsOn) && isAcceptableTimeout(secondsOff))) + { + Utils.sendMessage(sender, null, "&cThe timeout must be -1 or within 0 and " + maxTimeout, '&'); + return; + } + Utils.sendMessage(sender, null, "&aPlease click the input you would like to set.", '&'); + setPlayer((Player) sender, destroyingInput, secondsOff, secondsOn); + } + + public void setPlayer(Player player, boolean destroying, double timeoutOff, double timeoutOn) + { + SpamInput input = null; + if (!destroying) + { + input = new SpamInput(player.getUniqueId().toString(), timeoutOff, timeoutOn, 0); + } + players.put(player, input); + } + + public boolean attemptInputRegister(Player player, Block block, Cancellable event) + { + if (players.containsKey(player)) + { + if (!acceptedInputs.contains(block.getType())) + { + Utils.sendMessage(player, null, "&cThat block is not an acceptable input!", '&'); + return true; + } + String typeStr = block.getType().toString().toLowerCase().replace("_", " "); + String locationStr = locationString(block.getLocation()); + changingInput = true; + boolean buildCheck = canBuild(player, block); + changingInput = false; + if (!buildCheck) + { + Utils.sendMessage(player, null, + "&cThere is no timeout to remove on this " + typeStr + "(by setting the timeout to 0)", '&'); + return true; + } + SpamInput input = players.get(player); + if (input == null) + { + if (!inputs.containsKey(locationStr)) + { + Utils.sendMessage(player, null, + "&cThere is no timeout to remove on this " + typeStr + "(by setting the timeout to 0)", + '&'); + return true; + } + inputs.remove(locationStr); + Utils.sendMessage(player, null, "&aSuccessfully removed the timeout for this " + typeStr, '&'); + } + else + { + inputs.put(locationStr, players.get(player)); + Utils.sendMessage(player, null, "&aSuccessfully set a timeout for this " + typeStr, '&'); + } + event.setCancelled(true); + players.remove(player); + saveInputs(); + return true; + } + return false; + } + + public void checkBlockBreak(BlockBreakEvent event, Block block) + { + if (!acceptedInputs.contains(block.getType())) + return; + String posStr = locationString(block.getLocation()); + if (!inputs.containsKey(posStr)) + return; + SpamInput input = inputs.get(posStr); + Player sender = event.getPlayer(); + String typeStr = block.getType().toString().toLowerCase().replace("_", " "); + String inputStr = (block.getLocation().equals(event.getBlock()) ? "this " + typeStr + : "the " + typeStr + " attached to that block"); + if (!sender.isSneaking()) + { + Utils.sendMessage(sender, null, "&cYou cannot destroy " + inputStr, '&'); + Utils.sendMessage(sender, "", "&c&nSneak&c and break or set the timeout to 0 if you want to remove it.", + '&'); + event.setCancelled(true); + return; + } + if (sender.hasPermission("damnspam.admin") || sender.getUniqueId().toString().equals(input.player)) + { + inputs.remove(posStr); + saveInputs(); + Utils.sendMessage(sender, null, "&aSuccesfully removed " + inputStr, '&'); + } + else + { + Utils.sendMessage(sender, null, "&cYou are not allowed to remove " + inputStr, '&'); + event.setCancelled(true); + } + } + + @SuppressWarnings("deprecation") + public List getAttachedBlocks(Block block) + { + List blocks = new ArrayList(); + BlockFace[] directions = {BlockFace.DOWN, BlockFace.UP, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.WEST, + BlockFace.EAST}; + for (int i = 0; i < directions.length; i++) + { + Block side = block.getRelative(directions[i]); + int[][] dvalues = attachedBlocks.get(side.getType()); + if (dvalues != null) + { + boolean onSide = false; + for (int val : dvalues[i]) + { + if (side.getData() == (byte) val) + { + onSide = true; + break; + } + } + if (onSide) + blocks.add(side); + } + } + return blocks; + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onBreak(BlockBreakEvent event) + { + if (changingInput || event.isCancelled()) + return; + boolean register = attemptInputRegister(event.getPlayer(), event.getBlock(), event); + if (!register) + { + Block block = event.getBlock(); + checkBlockBreak(event, block); + for (Block affected : getAttachedBlocks(block)) + { + checkBlockBreak(event, affected); + } + } + } + + @SuppressWarnings("deprecation") + @EventHandler(priority = EventPriority.HIGHEST) + public void onInteract(PlayerInteractEvent event) + { + boolean register = attemptInputRegister(event.getPlayer(), event.getClickedBlock(), event); + if (!register && event.getAction().equals(Action.RIGHT_CLICK_BLOCK) && !event.isCancelled()) + { + Player sender = event.getPlayer(); + Block block = event.getClickedBlock(); + String posStr = locationString(block.getLocation()); + SpamInput data = inputs.get(posStr); + if (data != null) + { + String btype = block.getType().toString().toLowerCase().replace("_", " "); + double checktime = 0; + if (btype.equals("lever") && block.getData() < 8) + checktime = data.timeoutOff; + else + checktime = data.timeoutOn; + double timeLeft = (data.lastTime + checktime) + - ((double) Math.round((double) System.currentTimeMillis() / 10) / 100); + timeLeft = (double) Math.round(timeLeft * 100) / 100; + if (checktime == -1) + { + event.setCancelled(true); + Utils.sendMessage(sender, null, "&cThis " + btype + " is locked permanently by /damnspam.", '&'); + } + else if (timeLeft > 0) + { + event.setCancelled(true); + Utils.sendMessage(sender, null, "&cThis " + btype + " has a damnspam timeout of " + checktime + + ", with " + timeLeft + " left.", '&'); + } + else + { + data.lastTime = (double) Math.round((double) System.currentTimeMillis() / 10) / 100; + } + inputs.put(posStr, data); + } + } + } + + // @noformat + @Override + public String getCommandString() + { + return "command damnspam {\n" + + " perm utils.damnspam;\n" + + " \n" + + " [double:seconds] {\n" + + " run damnspamSingle seconds;\n" + + " help Set single input cooldown for button or lever.;\n" + + " type player;\n" + + " }\n" + + " \n" + + " [double:secondsOff] [double:secondsOn] {\n" + + " run damnspamDouble secondsOff secondsOn;\n" + + " help Set input cooldown after it's been turned off and turned on (for lever only).;\n" + + " type player;\n" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/damnspam/SpamInput.java b/src/com/redstoner/modules/damnspam/SpamInput.java new file mode 100644 index 0000000..9735dd9 --- /dev/null +++ b/src/com/redstoner/modules/damnspam/SpamInput.java @@ -0,0 +1,17 @@ +package com.redstoner.modules.damnspam; + +public class SpamInput { + + protected String player; + protected double timeoutOn; + protected double timeoutOff; + protected double lastTime; + + protected SpamInput(String player, double timeoutOff, double timeoutOn, double lastTime) { + this.player = player; + this.timeoutOff = timeoutOff; + this.timeoutOn = timeoutOn; + this.lastTime = lastTime; + } + +} diff --git a/src/com/redstoner/modules/firstseen/FirstSeen.java b/src/com/redstoner/modules/firstseen/FirstSeen.java new file mode 100644 index 0000000..2d4702f --- /dev/null +++ b/src/com/redstoner/modules/firstseen/FirstSeen.java @@ -0,0 +1,111 @@ +package com.redstoner.modules.firstseen; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.Statistic; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@Version(major = 2, minor = 0, revision = 7, compatible = 2) +public class FirstSeen implements Module +{ + @SuppressWarnings("deprecation") + @Command(hook = "firstseenP") + public void firstseen(CommandSender sender, String person) + { + Utils.sendMessage(sender, "", "&7Please note that the data may not be fully accurate!", '&'); + OfflinePlayer oPlayer = Bukkit.getPlayer(person); + if (oPlayer == null) + oPlayer = Bukkit.getServer().getOfflinePlayer(person); + Long firstJoin = oPlayer.getFirstPlayed(); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + String disDate = format.format(new Date(firstJoin)); + if (disDate.equals("1969-12-31 19:00")) + { + Utils.sendMessage(sender, null, "&3" + oPlayer.getName() + "&c has never joined.", '&'); + } + else + { + Utils.sendMessage(sender, null, "&3" + oPlayer.getName() + " &efirst joined&a " + disDate + "&e.", '&'); + } + } + + @Command(hook = "firstseen") + public void firstseen(CommandSender sender) + { + firstseen(sender, sender.getName()); + } + + @Command(hook = "playtimeDef") + public boolean playtime(CommandSender sender) + { + return playtime(sender, sender.getName()); + } + + @Command(hook = "playtime") + public boolean playtime(CommandSender sender, String name) + { + if (name == null) + name = sender.getName(); + Player player = Bukkit.getPlayer(name); + if (player == null) + { + Utils.sendErrorMessage(sender, null, + "That player couldn't be found! Hint: Currently, you can only check statistics of players that are online!"); + return true; + } + int ticks_lived = player.getStatistic(Statistic.PLAY_ONE_TICK); + int days = ticks_lived / 1728000; + int hours = (ticks_lived % 1728000) / 72000; + int minutes = (ticks_lived % 72000) / 1200; + Utils.sendMessage(sender, null, + "The player &e" + name + " &7has been on for " + + (days == 0 && hours == 0 && minutes == 0 ? "less than a minute." + : ("a total of: &e" + (days != 0 ? (days + "d ") : "") + + ((hours != 0 || days != 0) ? (hours + "h ") : "") + + ((minutes != 0 || hours != 0 || days != 0) ? (minutes + "m") : ""))), + '&'); + return true; + } + + // @noformat + @Override + public String getCommandString() + { + return "command firstseen {\n" + + " [empty] {\n" + + " run firstseen;\n" + + " type player;\n" + + " help Gives the date and time they first joined;\n" + + " perm utils.firstseen;\n" + + " }\n" + + " [string:person] {\n" + + " run firstseenP person;\n" + + " help Gives the date and time when a player first joined;\n" + + " perm utils.firstseen.other;\n" + + " }\n" + + "}\n" + + "command playtime {\n" + + " [empty] {\n" + + " type player;\n" + + " run playtimeDef;\n" + + " perm utils.playtime;\n" + + " help Displays your total playtime!;\n" + + " }\n" + + " [string:name] {\n" + + " run playtime name;\n" + + " perm utils.playtime.others;\n" + + " help Displays the playtime of another player. The player must be online!;\n" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/illumination/Illumination.java b/src/com/redstoner/modules/illumination/Illumination.java new file mode 100644 index 0000000..b18276c --- /dev/null +++ b/src/com/redstoner/modules/illumination/Illumination.java @@ -0,0 +1,48 @@ +package com.redstoner.modules.illumination; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@Version(major = 2, minor = 0, revision = 1, compatible = 2) +public class Illumination implements Module +{ + PotionEffect effect = new PotionEffect(PotionEffectType.NIGHT_VISION, Integer.MAX_VALUE, 0, false, false); + + @Command(hook = "illuminate") + public void illuminate(CommandSender sender) + { + Player player = (Player) sender; + if (player.hasPotionEffect(PotionEffectType.NIGHT_VISION)) + { + player.removePotionEffect(PotionEffectType.NIGHT_VISION); + Utils.sendMessage(sender, null, "Night Vision Disabled."); + } + else + { + player.addPotionEffect(effect, true); + Utils.sendMessage(sender, null, "Night Vision Enabled."); + } + } + + // @noformat + @Override + public String getCommandString() + { + return "command nightvision {\n" + + " [empty] {\n" + + " run illuminate;\n" + + " type player;\n" + + " help Gives the player infinte night vision;\n" + + " perm utils.illuminate;\n" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/imout/Imout.java b/src/com/redstoner/modules/imout/Imout.java new file mode 100644 index 0000000..463800f --- /dev/null +++ b/src/com/redstoner/modules/imout/Imout.java @@ -0,0 +1,59 @@ +package com.redstoner.modules.imout; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@Version(major = 2, minor = 0, revision = 1, compatible = 2) +public class Imout implements Module +{ + List imout_toggle_list = new ArrayList(); + + @Command(hook = "imout") + public void onImoutCommand(CommandSender sender) + { + String symbol; + Player s = (Player) sender; + String name = sender.getName(); + if (imout_toggle_list.contains(name)) + { + symbol = "§a§l+"; + Utils.sendModuleHeader(sender); + Utils.sendMessage(sender, "", "§eWelcome back! You are no longer hidden"); + s.performCommand("vanish off"); + s.performCommand("act off"); + imout_toggle_list.remove(name); + } + else + { + symbol = "§c§l-"; + sender.sendMessage("§eYou just left... Or didn't you?"); + s.performCommand("vanish on"); + s.performCommand("act on"); + imout_toggle_list.add(name); + } + Utils.broadcast(symbol, " §7" + name, null); + } + + // @noformat + @Override + public String getCommandString() + { + return "command imout {\n" + + " [empty] {\n" + + " help Makes you magically disappear;\n" + + " type player;\n" + + " perm utils.imout;\n" + + " run imout;\n" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/lagchunks/LagChunks.java b/src/com/redstoner/modules/lagchunks/LagChunks.java new file mode 100644 index 0000000..abbf048 --- /dev/null +++ b/src/com/redstoner/modules/lagchunks/LagChunks.java @@ -0,0 +1,106 @@ +package com.redstoner.modules.lagchunks; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.nemez.cmdmgr.Command; +import com.nemez.cmdmgr.Command.AsyncType; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@Version(major = 2, minor = 0, revision = 1, compatible = 2) +public class LagChunks implements Module +{ + private List laggyChunks = new ArrayList(); + + private void scan(int amount) + { + laggyChunks.clear(); + for (World world : Bukkit.getServer().getWorlds()) + { + for (Chunk chunk : world.getLoadedChunks()) + { + if (chunk.getEntities().length > amount) + { + Location entLoc = chunk.getEntities()[0].getLocation(); + laggyChunks.add(new LaggyChunk(entLoc.getBlockX(), entLoc.getBlockY(), entLoc.getBlockZ(), world, + chunk.getEntities().length)); + } + } + } + } + + @Command(hook = "list_cmd") + public void list(CommandSender sender) + { + if (laggyChunks.size() > 0) + { + Utils.sendModuleHeader(sender); + for (LaggyChunk lc : laggyChunks) + { + Utils.sendMessage(sender, "", "§b[§a" + laggyChunks.indexOf(lc) + "§b]: §a" + lc.x + "§7, §a" + lc.y + + "§7, §a" + lc.z + " §7(" + lc.world.getName() + ") §a- §b" + lc.amount + " entities"); + } + Utils.sendMessage(sender, "", "§2-------------------"); + } + else + Utils.sendMessage(sender, null, "Couldn't find any chunks with that many entities."); + } + + @Command(hook = "scan_cmd", async = AsyncType.ALWAYS) + public void scan_cmd(CommandSender sender, int amount) + { + scan(amount); + list(sender); + } + + @Command(hook = "tp") + public void tp(CommandSender sender, int number) + { + Player player = (Player) sender; + if (number < laggyChunks.size()) + { + player.teleport(laggyChunks.get(number).getLocation()); + Utils.sendMessage(player, null, "§aTeleported to chunk " + number + "!"); + } + else + { + Utils.sendErrorMessage(sender, null, "§4Invalid chunk number! Use §e/lc list §4to show laggy chunks!"); + } + } + + // @noformat + @Override + public String getCommandString() + { + return "command lc {\n" + + " perm utils.lagchunks;\n" + + " \n" + + " list {\n" + + " run list_cmd;\n" + + " help re-lists already scanned chunks;\n" + + " }\n" + + " \n" + + " [int:amount] {\n" + + " run scan_cmd amount;\n" + + " help scans for laggy chunks;\n" + + " }\n" + + " \n" + + " tp [int:number] {\n" + + " run tp number;\n" + + " help teleports to the specified chunk;\n" + + " type player;\n" + + " }\n" + + "}\n" + + " "; + } + // @format +} diff --git a/src/com/redstoner/modules/lagchunks/LaggyChunk.java b/src/com/redstoner/modules/lagchunks/LaggyChunk.java new file mode 100644 index 0000000..3ff4d6f --- /dev/null +++ b/src/com/redstoner/modules/lagchunks/LaggyChunk.java @@ -0,0 +1,21 @@ +package com.redstoner.modules.lagchunks; + +import org.bukkit.Location; +import org.bukkit.World; + +public class LaggyChunk { + public final int x, y, z, amount; + public final World world; + + public LaggyChunk(int x, int y, int z, World world, int amount) { + this.x = x; + this.y = y; + this.z = z; + this.world = world; + this.amount = amount; + } + + public Location getLocation() { + return new Location(world, x, y, z); + } +} diff --git a/src/com/redstoner/modules/loginsecurity/CancelledEventsHandler.java b/src/com/redstoner/modules/loginsecurity/CancelledEventsHandler.java new file mode 100644 index 0000000..e39d781 --- /dev/null +++ b/src/com/redstoner/modules/loginsecurity/CancelledEventsHandler.java @@ -0,0 +1,95 @@ +package com.redstoner.modules.loginsecurity; + +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerItemHeldEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerPickupArrowEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; + +public class CancelledEventsHandler implements Listener { + private LoginSecurity mainClass; + + public CancelledEventsHandler(LoginSecurity mainClass) { + this.mainClass = mainClass; + } + + @EventHandler + public void onMove(PlayerMoveEvent e) { + if (isLoggingIn(e.getPlayer())) { + e.getPlayer().teleport(LoginSecurity.loggingIn.get(e.getPlayer().getUniqueId())); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onChat(AsyncPlayerChatEvent e) { + if (isLoggingIn(e.getPlayer())) { + e.getPlayer().sendMessage(ChatColor.RED + "You must login before you can chat!"); + e.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onCommand(PlayerCommandPreprocessEvent e) { + String command = e.getMessage(); + + if (!command.startsWith("/login") && isLoggingIn(e.getPlayer())) { + e.getPlayer().sendMessage(ChatColor.RED + "You must login before you can execute commands!"); + e.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onItemHold(PlayerItemHeldEvent e) { + if (isLoggingIn(e.getPlayer())) { + e.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onItemPickup(PlayerPickupItemEvent e) { + if (isLoggingIn(e.getPlayer())) { + e.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onItemDrop(PlayerDropItemEvent e) { + if (isLoggingIn(e.getPlayer())) { + e.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onInteract(PlayerInteractEvent e) { + if (isLoggingIn(e.getPlayer())) { + e.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onArrowPickup(PlayerPickupArrowEvent e) { + if (isLoggingIn(e.getPlayer())) { + e.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onInvClick(InventoryClickEvent e) { + if (e.getWhoClicked() instanceof Player && isLoggingIn((Player) e.getWhoClicked())) { + e.setCancelled(true); + } + } + + private boolean isLoggingIn(Player player) { + return mainClass.isLoggingIn(player); + } +} diff --git a/src/com/redstoner/modules/loginsecurity/CryptographyHandler.java b/src/com/redstoner/modules/loginsecurity/CryptographyHandler.java new file mode 100644 index 0000000..48e81a9 --- /dev/null +++ b/src/com/redstoner/modules/loginsecurity/CryptographyHandler.java @@ -0,0 +1,53 @@ +package com.redstoner.modules.loginsecurity; + +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; +import java.util.Base64; + +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; + +public class CryptographyHandler { + public static String hash(String password, String salt) { + String algorithm = "PBKDF2WithHmacSHA256"; + int derivedKeyLength = 256; + int iterations = 200000; + byte[] decodedSalt = Base64.getDecoder().decode(salt.getBytes()); + + KeySpec spec = new PBEKeySpec(password.toCharArray(), decodedSalt, iterations, derivedKeyLength); + + byte[] hashed = null; + + try { + SecretKeyFactory f = SecretKeyFactory.getInstance(algorithm); + + hashed = f.generateSecret(spec).getEncoded(); + } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { + e.printStackTrace(); + } + + return Base64.getEncoder().encodeToString(hashed).substring(0, 43); + } + + public static boolean verify(String password, String salt, String hash) { + return hash(password, salt).equals(hash); + } + + public static boolean verify(String password, String stored) { + String[] split = stored.split("\\$"); + + return verify(password, split[3], split[4]); + } + + public static String generateSalt() throws NoSuchAlgorithmException, NoSuchProviderException { + SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); + + byte[] salt = new byte[16]; + random.nextBytes(salt); + + return Base64.getEncoder().encodeToString(salt).substring(0, 22); + } +} diff --git a/src/com/redstoner/modules/loginsecurity/LoginSecurity.java b/src/com/redstoner/modules/loginsecurity/LoginSecurity.java new file mode 100644 index 0000000..38129c5 --- /dev/null +++ b/src/com/redstoner/modules/loginsecurity/LoginSecurity.java @@ -0,0 +1,318 @@ +package com.redstoner.modules.loginsecurity; + +import java.io.Serializable; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.scheduler.BukkitScheduler; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.misc.mysql.JSONManager; +import com.redstoner.misc.mysql.MysqlHandler; +import com.redstoner.misc.mysql.elements.ConstraintOperator; +import com.redstoner.misc.mysql.elements.MysqlConstraint; +import com.redstoner.misc.mysql.elements.MysqlDatabase; +import com.redstoner.misc.mysql.elements.MysqlField; +import com.redstoner.misc.mysql.elements.MysqlTable; +import com.redstoner.misc.mysql.types.text.VarChar; +import com.redstoner.modules.Module; + +@AutoRegisterListener +@Version(major = 2, minor = 0, revision = 1, compatible = 2) +public class LoginSecurity implements Module, Listener +{ + protected static Map loggingIn; + private MysqlTable table; + + @Override + public boolean onEnable() + { + Map config = JSONManager.getConfiguration("loginsecurity.json"); + if (config == null || !config.containsKey("database") || !config.containsKey("table")) + { + Utils.sendErrorMessage(Bukkit.getConsoleSender(), null, + "Could not load the LoginSecurity config file, disabling!"); + return false; + } + try + { + MysqlDatabase database = MysqlHandler.INSTANCE.getDatabase((String) config.get("database")); + MysqlField uuid = new MysqlField("uuid", new VarChar(36), true); + MysqlField pass = new MysqlField("pass", new VarChar(88), true); + database.createTableIfNotExists((String) config.get("table"), uuid, pass); + table = database.getTable((String) config.get("table")); + } + catch (NullPointerException e) + { + Utils.sendErrorMessage(Bukkit.getConsoleSender(), null, + "Could not use the LoginSecurity config, disabling!"); + return false; + } + loggingIn = new HashMap<>(); + Bukkit.getServer().getPluginManager().registerEvents(new CancelledEventsHandler(this), Main.plugin); + return true; + } + + public static Map getLoggingIn() + { + return loggingIn; + } + + @Command(hook = "register") + public void register(CommandSender sender, String password) + { + Player player = (Player) sender; + if (isRegistered(player)) + { + player.sendMessage(ChatColor.GREEN + "You are already registered!"); + return; + } + try + { + if (registerPlayer(player, password)) + { + player.sendMessage(ChatColor.GREEN + "Succesfully registered!"); + return; + } + } + catch (NoSuchAlgorithmException | NoSuchProviderException e) + { + e.printStackTrace(); + } + player.sendMessage(ChatColor.RED + "Failed to register, please contact an admin!"); + } + + @Command(hook = "login") + public void login(CommandSender sender, String password) + { + Player player = (Player) sender; + if (!isRegistered(player)) + { + player.sendMessage(ChatColor.RED + "You are not registered!"); + return; + } + if (CryptographyHandler.verify(password, getHash(player))) + { + loggingIn.remove(player.getUniqueId()); + } + else + { + player.sendMessage(ChatColor.RED + "Wrong password!"); + } + } + + @Command(hook = "cgpass") + public void cgpass(CommandSender sender, String oldPassword, String newPassword) + { + Player player = (Player) sender; + if (!isRegistered(player)) + { + player.sendMessage(ChatColor.RED + "You are not registered!"); + return; + } + if (!CryptographyHandler.verify(oldPassword, getHash(player))) + { + player.sendMessage(ChatColor.RED + "The old password you entered is wrong!"); + return; + } + if (oldPassword.equals(newPassword)) + { + player.sendMessage(ChatColor.RED + "You entered the same password!"); + return; + } + if (table.delete(getUuidConstraint(player))) + { + try + { + registerPlayer(player, newPassword); + player.sendMessage(ChatColor.GREEN + "Succesfully changed password!"); + } + catch (NoSuchAlgorithmException | NoSuchProviderException e) + { + e.printStackTrace(); + player.sendMessage(ChatColor.RED + "Failed to set new password!"); + } + } + else + { + player.sendMessage(ChatColor.RED + "Failed to remove old password from database!"); + } + } + + @Command(hook = "rmpass") + public void rmpass(CommandSender sender, String oldPassword) + { + Player player = (Player) sender; + if (!isRegistered(player)) + { + player.sendMessage(ChatColor.RED + "You are not registered!"); + return; + } + if (!CryptographyHandler.verify(oldPassword, getHash(player))) + { + player.sendMessage(ChatColor.RED + "The old password you entered is wrong!"); + return; + } + if (table.delete(getUuidConstraint(player))) + { + player.sendMessage(ChatColor.GREEN + "Succesfully removed password!"); + } + else + { + player.sendMessage(ChatColor.RED + "Failed to remove old password from database!"); + } + } + + @Command(hook = "rmotherpass") + public void rmotherpass(CommandSender sender, String playerName) + { + if (playerName.equals("")) + { + sender.sendMessage(ChatColor.RED + "That's not a valid player!"); + return; + } + @SuppressWarnings("deprecation") + OfflinePlayer player = Bukkit.getOfflinePlayer(playerName); + if (!isRegistered(player)) + { + sender.sendMessage(ChatColor.RED + "That player is not registered!"); + return; + } + if (table.delete(getUuidConstraint(player))) + { + sender.sendMessage(ChatColor.GREEN + "Successfully removed " + playerName + "'s password!"); + } + else + { + sender.sendMessage(ChatColor.RED + "Failed to remove " + playerName + "'s password!"); + } + } + + @EventHandler + public void onJoin(PlayerJoinEvent e) + { + Player player = e.getPlayer(); + if (!isRegistered(player)) + { + return; + } + Utils.sendMessage(player, null, "You'll have to log in within 60s or you'll be kicked!"); + loggingIn.put(player.getUniqueId(), player.getLocation()); + BukkitScheduler scheduler = Bukkit.getScheduler(); + RepeatingLoginRunnable repeatingRunnable = new RepeatingLoginRunnable(this, player); + repeatingRunnable.setId(scheduler.scheduleSyncRepeatingTask(Main.plugin, repeatingRunnable, 0L, 2L)); + scheduler.scheduleSyncDelayedTask(Main.plugin, new Runnable() + { + @Override + public void run() + { + if (isLoggingIn(player)) + { + scheduler.cancelTask(repeatingRunnable.getId()); + player.kickPlayer("You didn't login in time!"); + } + } + }, 1200L); + } + + public boolean isLoggingIn(Player player) + { + return loggingIn.containsKey(player.getUniqueId()); + } + + public MysqlConstraint getUuidConstraint(OfflinePlayer player) + { + return new MysqlConstraint("uuid", ConstraintOperator.EQUAL, player.getUniqueId().toString()); + } + + public boolean isRegistered(OfflinePlayer player) + { + return table.get("uuid", getUuidConstraint(player)).length > 0; + } + + public String getHash(OfflinePlayer player) + { + return (String) table.get("pass", getUuidConstraint(player))[0]; + } + + public boolean registerPlayer(Player player, String password) + throws NoSuchAlgorithmException, NoSuchProviderException + { + String salt = CryptographyHandler.generateSalt(); + String hash = CryptographyHandler.hash(password, salt); + String toInsert = "$pbkdf2-sha256$200000$" + salt + "$" + hash; + return table.insert(player.getUniqueId().toString(), toInsert); + } + + // @noformat + @Override + public String getCommandString() + { + return "command register {\n" + + " perm utils.loginsecurity;\n" + + " \n" + + " [string:password] {\n" + + " run register password;\n" + + " help Protects your account with a password;\n" + + " type player;\n" + + " }\n" + + "}\n" + + "\n" + + "command login {\n" + + " perm utils.loginsecurity;\n" + + " \n" + + " [string:password] {\n" + + " run login password;\n" + + " help Logs you in;\n" + + " type player;\n" + + " }\n" + + "}\n" + + "\n" + + "command cgpass {\n" + + " perm utils.loginsecurity;\n" + + " \n" + + " [string:oldPassword] [string:newPassword] {\n" + + " run cgpass oldPassword newPassword;\n" + + " help Changes your password to the specified one;\n" + + " type player;\n" + + " }\n" + + "}\n" + + "\n" + + "command rmpass {\n" + + " perm utils.loginsecurity;\n" + + " \n" + + " [string:oldPassword] {\n" + + " run rmpass oldPassword;\n" + + " help Removes the password of your account;\n" + + " type player;\n" + + " }\n" + + "}\n" + + "\n" + + "command rmotherpass {\n" + + " perm utils.loginsecurity.admin;\n" + + " \n" + + " [string:playerName] {\n" + + " run rmotherpass playerName;\n" + + " help removes the password of another player;\n" + + " perm utils.loginsecurity.admin;\n" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/loginsecurity/RepeatingLoginRunnable.java b/src/com/redstoner/modules/loginsecurity/RepeatingLoginRunnable.java new file mode 100644 index 0000000..4e8db6d --- /dev/null +++ b/src/com/redstoner/modules/loginsecurity/RepeatingLoginRunnable.java @@ -0,0 +1,37 @@ +package com.redstoner.modules.loginsecurity; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +public class RepeatingLoginRunnable implements Runnable { + private int id = -1; + private Player player; + private LoginSecurity mainClass; + + public RepeatingLoginRunnable(LoginSecurity mainClass, Player player) { + this.player = player; + this.mainClass = mainClass; + } + + @Override + public void run() { + if (!player.isOnline()) { + LoginSecurity.loggingIn.remove(player.getUniqueId()); + Bukkit.getScheduler().cancelTask(id); + } + + if (!mainClass.isLoggingIn(player)) { + player.sendMessage(ChatColor.GREEN + "Successfully logged in!"); + Bukkit.getScheduler().cancelTask(id); + } + } + + public void setId(int id) { + this.id = id; + } + + public int getId() { + return id; + } +} diff --git a/src/com/redstoner/modules/mentio/Mentio.java b/src/com/redstoner/modules/mentio/Mentio.java new file mode 100644 index 0000000..ea2598d --- /dev/null +++ b/src/com/redstoner/modules/mentio/Mentio.java @@ -0,0 +1,192 @@ +package com.redstoner.modules.mentio; + +import java.io.File; +import java.util.UUID; +import java.util.regex.Pattern; + +import org.bukkit.Sound; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.JsonManager; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@AutoRegisterListener +@Version(major = 2, minor = 0, revision = 2, compatible = 2) +public class Mentio implements Module, Listener +{ + private File mentioLocation = new File(Main.plugin.getDataFolder(), "mentio.json"); + private JSONObject mentios; + + @Override + public boolean onEnable() + { + loadMentios(); + return true; + } + + @Override + public void onDisable() + { + saveMentios(); + } + + @SuppressWarnings("unchecked") + @Command(hook = "addmentio") + public boolean addMentio(CommandSender sender, String trigger) + { + Player player = (Player) sender; + UUID uuid = player.getUniqueId(); + JSONArray playerMentios = (JSONArray) mentios.get(uuid.toString()); + if (playerMentios == null) + { + playerMentios = new JSONArray(); + playerMentios.add(player.getName()); + playerMentios.add(player.getDisplayName().split(" ")[0].replaceAll("§[0-9a-fk-o]", "")); + } + if (playerMentios.contains(trigger)) + Utils.sendErrorMessage(sender, null, "You already had that as a mentio!"); + else + { + playerMentios.add(trigger); + Utils.sendMessage(sender, null, "Successfully added the trigger §e" + trigger + " §7for you!"); + mentios.put(uuid.toString(), playerMentios); + saveMentios(); + } + return true; + } + + @SuppressWarnings("unchecked") + @Command(hook = "delmentio") + public boolean delMentio(CommandSender sender, String trigger) + { + Player player = (Player) sender; + UUID uuid = player.getUniqueId(); + JSONArray playerMentios = (JSONArray) mentios.get(uuid.toString()); + if (playerMentios == null) + { + playerMentios = new JSONArray(); + playerMentios.add(player.getName()); + playerMentios.add(player.getDisplayName().split(" ")[0].replaceAll("§[0-9a-fk-o]", "")); + } + if (!playerMentios.remove(trigger)) + Utils.sendErrorMessage(sender, null, "You didn't have that as a mentio!"); + else + { + Utils.sendMessage(sender, null, "Successfully removed the trigger §e" + trigger + " §7for you!"); + mentios.put(uuid.toString(), playerMentios); + saveMentios(); + } + return true; + } + + @SuppressWarnings("unchecked") + @Command(hook = "listmentios") + public boolean listMentios(CommandSender sender) + { + Utils.sendModuleHeader(sender); + Player player = (Player) sender; + UUID uuid = player.getUniqueId(); + JSONArray playerMentios = (JSONArray) mentios.get(uuid.toString()); + if (playerMentios == null) + { + playerMentios = new JSONArray(); + playerMentios.add(player.getName()); + playerMentios.add(player.getDisplayName().split(" ")[0].replaceAll("§[0-9a-fk-or]", "")); + } + for (Object raw : playerMentios) + { + String mentio = (String) raw; + Utils.sendMessage(sender, "&2 -> &e", mentio, '&'); + } + return true; + } + + @SuppressWarnings("unchecked") + @EventHandler(priority = EventPriority.MONITOR) + public void onPlayerChat(AsyncPlayerChatEvent event) + { + if (event.isCancelled()) + return; + for (Player player : event.getRecipients()) + { + UUID uuid = player.getUniqueId(); + JSONArray playerMentios = (JSONArray) mentios.get(uuid.toString()); + if (playerMentios == null) + { + playerMentios = new JSONArray(); + playerMentios.add(player.getName()); + playerMentios.add(player.getDisplayName().split(" ")[0].replaceAll("§[0-9a-fk-o]", "")); + } + for (Object raw : playerMentios) + { + String mentio = (String) raw; + if (event.getMessage().toLowerCase().contains(mentio.toLowerCase())) + { + event.getRecipients().remove(player); + String temp = event.getMessage().replaceAll("(?i)" + Pattern.quote(mentio) + ".*", ""); + String lastColorCodes = "§r"; + char lastChar = ' '; + for (char c : temp.toCharArray()) + { + if (lastChar == '§') + lastColorCodes += "§" + c; + lastChar = c; + } + Utils.sendMessage(player, "", + event.getFormat().replace("%1$s", event.getPlayer().getDisplayName()).replace("%2$s", + event.getMessage().replaceFirst("(?i)(" + Pattern.quote(mentio) + ")([^ ]*)", + "§a§o$1$2" + lastColorCodes))); + player.playSound(player.getLocation(), Sound.ENTITY_CHICKEN_EGG, 1, 1); + return; + } + } + } + } + + private void loadMentios() + { + mentios = JsonManager.getObject(mentioLocation); + if (mentios == null) + mentios = new JSONObject(); + } + + private void saveMentios() + { + JsonManager.save(mentios, mentioLocation); + } + + // @noformat + @Override + public String getCommandString() + { + return "command mentio {\n" + + " add [string:trigger] {\n" + + " help Triggers you when the trigger gets said.;\n" + + " run addmentio trigger;\n" + + " }\n" + + " delete [string:trigger] {\n" + + " help Deletes a mentio.;\n" + + " run delmentio trigger;\n" + + " }\n" + + " list {\n" + + " help Lists your mentios.;\n" + + " run listmentios;\n" + + " }\n" + + " perm utils.mentio;\n" + + " type player;\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/motd/Motd.java b/src/com/redstoner/modules/motd/Motd.java new file mode 100644 index 0000000..95e578f --- /dev/null +++ b/src/com/redstoner/modules/motd/Motd.java @@ -0,0 +1,71 @@ +package com.redstoner.modules.motd; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.event.EventHandler; +import org.bukkit.event.server.ServerListPingEvent; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@AutoRegisterListener +@Version(major = 2, minor = 0, revision = 1, compatible = 2) +public class Motd implements Module +{ + private String default_motd, motd; + + @Command(hook = "setmotd") + public boolean setMotd(CommandSender sender, String motd) + { + if (motd.equals("--reset")) + this.motd = default_motd; + else + this.motd = motd; + Utils.sendMessage(sender, null, "The new motd is:\n" + this.motd, '&'); + return true; + } + + @Command(hook = "getmotd") + public boolean getMotd(CommandSender sender) + { + Utils.sendMessage(sender, null, motd, '&'); + return true; + } + + @EventHandler + public void onServerPing(ServerListPingEvent event) + { + event.setMotd(motd); + } + + @Override + public boolean onEnable() + { + default_motd = Bukkit.getMotd(); + return true; + } + + // @noformat + @Override + public String getCommandString() + { + return "command setmotd {\n" + + " [string:motd...] {\n" + + " help Sets the motd. Use --reset to reset to default;\n" + + " run setmotd motd;\n" + + " perm utils.setmotd;" + + " }\n" + + "}\n" + + "command getmotd {\n" + + " [empty] {\n" + + " help Returns the motd;\n" + + " run getmotd;\n" + + " perm utils.getmotd;" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/nametags/Nametags.java b/src/com/redstoner/modules/nametags/Nametags.java new file mode 100644 index 0000000..66fccd6 --- /dev/null +++ b/src/com/redstoner/modules/nametags/Nametags.java @@ -0,0 +1,135 @@ +package com.redstoner.modules.nametags; + +import java.util.ArrayList; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.server.ServerCommandEvent; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@AutoRegisterListener +@Version(major = 2, minor = 0, revision = 2, compatible = 2) +public class Nametags implements Module, Listener +{ + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) + { + sortSpecific(event.getPlayer()); + } + + @EventHandler + public void commandPreprocessEvent(PlayerCommandPreprocessEvent event) + { + ArrayList toSort = new ArrayList(); + if (event.getMessage().contains("promote") || event.getMessage().contains("demote") + || event.getMessage().matches("pex user .* group (set|add|leave)")) + { + String[] args = event.getMessage().split(" "); + for (String s : args) + { + Player p = Bukkit.getPlayer(s); + if (p != null) + toSort.add(p); + } + } + Bukkit.getScheduler().scheduleSyncDelayedTask(Main.plugin, new Runnable() + { + @Override + public void run() + { + for (Player p : toSort) + sortSpecific(p); + } + }); + } + + @EventHandler + public void consoleCommand(ServerCommandEvent event) + { + if (event.getCommand().contains("promote") || event.getCommand().contains("demote") + || event.getCommand().matches("pex user .* group (set|add|leave)")) + { + String[] args = event.getCommand().split(" "); + for (String s : args) + { + Player p = Bukkit.getPlayer(s); + if (p != null) + sortSpecific(p); + } + } + } + + @Command(hook = "sort") + public boolean sortAll(CommandSender sender) + { + for (Player p : Bukkit.getOnlinePlayers()) + sortSpecific(p); + Utils.sendMessage(sender, null, "Sorted tab for ya!"); + return true; + } + + @Command(hook = "sortspecific") + public boolean sortSpecific(CommandSender sender, String player) + { + Player p = Bukkit.getPlayer(player); + if (p == null) + { + Utils.sendErrorMessage(sender, null, "That player couldn't be found!"); + return true; + } + else + sortSpecific(p); + Utils.sendMessage(sender, null, "Sorted §e" + player + " §7for ya!"); + return true; + } + + public void sortSpecific(Player player) + { + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), + "scoreboard teams join " + getTeam(player) + " " + player.getName()); + } + + private String getTeam(Player player) + { + String[] teams = new String[] {"admin", "mod", "trainingmod", "trusted", "builder", "member", "visitor"}; + char prefix = 'a'; + for (String team : teams) + { + if (player.hasPermission("group." + team)) + { + return prefix + "_" + team; + } + prefix++; + } + return "g_visitor"; + } + + // @noformat + @Override + public String getCommandString() + { + return "command tab {\n" + + " sort {\n" + + " help Resorts the entirety of tab.;\n" + + " run sort;\n" + + " }\n" + + " sort [string:player] {\n" + + " help Resorts one player.;\n" + + " run sortspecific player;\n" + + " }\n" + + " perm utils.tab.admin;\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/naming/Naming.java b/src/com/redstoner/modules/naming/Naming.java new file mode 100644 index 0000000..c117b4b --- /dev/null +++ b/src/com/redstoner/modules/naming/Naming.java @@ -0,0 +1,120 @@ +package com.redstoner.modules.naming; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.command.CommandSender; +import org.bukkit.craftbukkit.v1_11_R1.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +import net.md_5.bungee.api.ChatColor; +import net.minecraft.server.v1_11_R1.BlockPosition; +import net.minecraft.server.v1_11_R1.ChatMessage; +import net.minecraft.server.v1_11_R1.ContainerAnvil; +import net.minecraft.server.v1_11_R1.EntityHuman; +import net.minecraft.server.v1_11_R1.EntityPlayer; +import net.minecraft.server.v1_11_R1.PacketPlayOutOpenWindow; + +@Version(major = 2, minor = 0, revision = 1, compatible = 2) +public class Naming implements Module +{ + @Command(hook = "anvil") + public void anvil(CommandSender sender) + { + EntityPlayer p = ((CraftPlayer) sender).getHandle(); + AnvilContainer container = new AnvilContainer(p); + int c = p.nextContainerCounter(); + p.playerConnection.sendPacket( + new PacketPlayOutOpenWindow(c, "minecraft:anvil", new ChatMessage("Repairing", new Object[] {}), 0)); + p.activeContainer = container; + p.activeContainer.windowId = c; + p.activeContainer.addSlotListener(p); + } + + @Command(hook = "name") + public void name(CommandSender sender, String name) + { + name = ChatColor.translateAlternateColorCodes('&', name); + ItemStack item = ((Player) sender).getInventory().getItemInMainHand(); + ItemMeta meta = item.getItemMeta(); + if (meta == null) + { + Utils.sendErrorMessage(sender, null, "You can not rename that item!"); + return; + } + meta.setDisplayName(name); + item.setItemMeta(meta); + Utils.sendMessage(sender, null, "Name set to " + name); + } + + @Command(hook = "lore") + public void lore(CommandSender sender, String name) + { + List lore = new ArrayList(); + name = ChatColor.translateAlternateColorCodes('&', name); + lore.add(name); + ItemStack item = ((Player) sender).getInventory().getItemInMainHand(); + ItemMeta meta = item.getItemMeta(); + if (meta == null) + { + Utils.sendErrorMessage(sender, null, "You can not change the lore of that item!"); + return; + } + meta.setLore(lore); + item.setItemMeta(meta); + item.getItemMeta().setLore(lore); + Utils.sendMessage(sender, null, "Lore set to " + name); + } + + public class AnvilContainer extends ContainerAnvil + { + public AnvilContainer(EntityHuman entity) + { + super(entity.inventory, entity.world, new BlockPosition(0, 0, 0), entity); + } + + @Override + public boolean a(EntityHuman entityhuman) + { + return true; + } + } + + // @noformat + @Override + public String getCommandString() + { + return "command anvil {\n" + + " [empty] {\n" + + " run anvil;\n" + + " type player;\n" + + " help Opens anvil GUI.;\n" + + " perm utils.anvil;\n" + + " }\n" + + "}\n" + + "command name {\n" + + " [string:name...] {\n" + + " run name name;\n" + + " type player;\n" + + " help Names item in hand.;\n" + + " perm utils.name;\n" + + " }\n" + + "}\n" + + "command lore {\n" + + " [string:name...] {\n" + + " run lore name;\n" + + " type player;\n" + + " help Adds lore to item in hand.;\n" + + " perm utils.lore;\n" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/onlineplayers/OnlinePlayers.java b/src/com/redstoner/modules/onlineplayers/OnlinePlayers.java new file mode 100644 index 0000000..eca260c --- /dev/null +++ b/src/com/redstoner/modules/onlineplayers/OnlinePlayers.java @@ -0,0 +1,89 @@ +package com.redstoner.modules.onlineplayers; + +import java.io.File; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.JsonManager; +import com.redstoner.misc.Main; +import com.redstoner.modules.Module; + +@AutoRegisterListener +@Version(major = 3, minor = 0, revision = 1, compatible = 3) +@SuppressWarnings("unchecked") +public class OnlinePlayers implements Module, Listener +{ + private File saveFile = null; + private JSONObject output = null; + private JSONArray players = null; + + @Override + public void postEnable() + { + saveFile = new File(Main.plugin.getDataFolder(), "players.json"); + output = new JSONObject(); + players = new JSONArray(); + output.put("dataFormat", "v1"); + rescan(); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onPlayerJoin(PlayerJoinEvent event) + { + add(event.getPlayer()); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onPlayerQuit(PlayerQuitEvent event) + { + remove(event.getPlayer()); + } + + public void rescan() + { + players = new JSONArray(); + for (Player p : Bukkit.getOnlinePlayers()) + add(p); + save(); + } + + public synchronized void add(Player player) + { + JSONObject jsonPlayer = new JSONObject(); + jsonPlayer.put("name", player.getName()); + jsonPlayer.put("uuid", player.getUniqueId().toString()); + jsonPlayer.put("joined", System.currentTimeMillis()); + players.add(jsonPlayer); + save(); + } + + public synchronized void remove(Player player) + { + JSONArray toRemove = new JSONArray(); + for (Object obj : players) + { + JSONObject o = (JSONObject) obj; + if (((String) o.get("uuid")).equals(player.getUniqueId().toString())) + toRemove.add(obj); + } + players.removeAll(toRemove); + save(); + } + + public synchronized void save() + { + output.put("players", players); + output.put("amount", players.size()); + JsonManager.save((JSONObject) output.clone(), saveFile); + } +} diff --git a/src/com/redstoner/modules/pmtoggle/Pmtoggle.java b/src/com/redstoner/modules/pmtoggle/Pmtoggle.java new file mode 100644 index 0000000..c5df720 --- /dev/null +++ b/src/com/redstoner/modules/pmtoggle/Pmtoggle.java @@ -0,0 +1,100 @@ +package com.redstoner.modules.pmtoggle; + +import java.util.HashMap; +import java.util.Map.Entry; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +import com.nemez.cmdmgr.Command; +import com.nemez.cmdmgr.Command.AsyncType; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@AutoRegisterListener +@Version(major = 2, minor = 0, revision = 1, compatible = 2) +public class Pmtoggle implements Module, Listener +{ + HashMap toggles = new HashMap(); + + @Command(hook = "pmtoggle_off", async = AsyncType.ALWAYS) + public boolean pmtoggle_off(CommandSender sender) + { + Player player = (Player) sender; + if (toggles.remove(player) != null) + Utils.sendMessage(player, null, "Your pmtoggle was removed!"); + else + Utils.sendMessage(player, null, "You didn't have pmtoggle enabled! Use /pmtoggle to enabled it."); + return true; + } + + @Command(hook = "pmtoggle", async = AsyncType.ALWAYS) + public boolean pmtoggle(CommandSender sender, String player) + { + Player p = Bukkit.getPlayer(player); + if (p == null && !player.equals("CONSOLE")) + { + Utils.sendMessage(sender, null, "§cThat player couldn't be found!"); + return true; + } + toggles.put((Player) sender, player); + Utils.sendMessage(sender, null, "Locked your pmtoggle onto §6" + player + "§7."); + return true; + } + + @EventHandler + public void onPlayerChat(AsyncPlayerChatEvent event) + { + Player player = event.getPlayer(); + if (toggles.containsKey(player)) + { + Bukkit.dispatchCommand(player, "m " + toggles.get(player) + " " + event.getMessage()); + event.setCancelled(true); + } + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) + { + toggles.remove(event.getPlayer()); + String player = event.getPlayer().getName(); + if (toggles.containsValue(player)) + { + for (Entry entry : toggles.entrySet()) + { + if (entry.getValue().equals(player)) + { + toggles.remove(player); + Utils.sendMessage(entry.getKey(), null, + "We removed your pmtoggle for &6" + player + "&7, as they left the game.", '&'); + } + } + } + } + + // @noformat + @Override + public String getCommandString() + { + return "command pmtoggle {\n" + + " [empty] {\n" + + " help Turns off your toggle.;\n" + + " type player;\n" + + " run pmtoggle_off;\n" + + " }\n" + + " [string:player] {\n" + + " help Turns on your pmtoggle and locks onto .;\n" + + " type player;\n" + + " run pmtoggle player;\n" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/reports/Reports.java b/src/com/redstoner/modules/reports/Reports.java new file mode 100644 index 0000000..cb1022e --- /dev/null +++ b/src/com/redstoner/modules/reports/Reports.java @@ -0,0 +1,163 @@ +package com.redstoner.modules.reports; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.Version; +import com.redstoner.misc.JsonManager; +import com.redstoner.misc.Main; +import com.redstoner.modules.Module; + +import net.md_5.bungee.api.ChatColor; + +/** Report module. Allows reports to be created and handled by staff + * + * @author Redempt */ +@Version(major = 2, minor = 0, revision = 0, compatible = 2) +public class Reports implements Module +{ + private int task = 0; + private JSONArray reports; + private JSONArray archived; + private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd kk:mm"); + + @Override + public boolean onEnable() + { + reports = JsonManager.getArray(new File(Main.plugin.getDataFolder(), "reports.json")); + archived = JsonManager.getArray(new File(Main.plugin.getDataFolder(), "archived_reports.json")); + if (reports == null) + { + reports = new JSONArray(); + } + if (archived == null) + { + archived = new JSONArray(); + } + // Notify online staff of open reports + task = Bukkit.getScheduler().scheduleSyncRepeatingTask(Main.plugin, () -> + { + if (reports.size() <= 0) + { + return; + } + for (Player player : Bukkit.getOnlinePlayers()) + { + if (player.hasPermission("utils.report")) + { + player.sendMessage(ChatColor.RED + "There are " + ChatColor.YELLOW + reports.size() + ChatColor.RED + + " open reports!"); + } + } + } , 2400, 2400); + return true; + } + + @Override + public void onDisable() + { + // Save reports, cancel notifier task + Bukkit.getScheduler().cancelTask(task); + JsonManager.save(reports, new File(Main.plugin.getDataFolder(), "reports.json")); + JsonManager.save(archived, new File(Main.plugin.getDataFolder(), "archived_reports.json")); + } + + @Override + public String getCommandString() + { + return "command report {" + "[string:message...] {" + "type player;" + "help Report a player or incident;" + + "run report message;" + "}" + "}" + "command rp {" + "perm utils.report;" + "open {" + + "help List all open reports;" + "run report_open;" + "}" + "close [int:id] {" + "help Close a report;" + + "run report_close id;" + "}" + "tp [int:id] {" + "help Teleport to the location of a report;" + + "run report_tp id;" + "type player;" + "}" + "}"; + } + + @Command(hook = "report_tp") + public void tpReport(CommandSender sender, int id) + { + // Check for invalid ID + Player player = (Player) sender; + if (id > reports.size() - 1 || id < 0) + { + sender.sendMessage(ChatColor.RED + "Invalid ID!"); + return; + } + JSONObject report = (JSONObject) reports.get(id); + String loc = (String) report.get("location"); + String[] split = loc.split(";"); + // Location from string + int x = Integer.parseInt(split[0]); + int y = Integer.parseInt(split[1]); + int z = Integer.parseInt(split[2]); + World world = Bukkit.getWorld(split[3]); + Location location = new Location(world, x, y, z); + player.teleport(location); + } + + @SuppressWarnings("unchecked") + @Command(hook = "report_close") + public void closeReport(CommandSender sender, int id) + { + // Check for invalid ID + if (id > reports.size() - 1 || id < 0) + { + sender.sendMessage(ChatColor.RED + "Invalid ID!"); + return; + } + // Move report to archived reports + JSONObject report = (JSONObject) reports.get(id); + reports.remove(id); + archived.add(report); + sender.sendMessage(ChatColor.GREEN + "Report #" + id + " closed!"); + } + + @Command(hook = "report_open") + public void listOpen(CommandSender sender) + { + int i = 0; + for (Object object : reports) + { + JSONObject report = (JSONObject) object; + String message = ""; + message += ChatColor.DARK_GRAY + "[" + ChatColor.YELLOW + i + ChatColor.DARK_GRAY + "]"; + message += "[" + ChatColor.YELLOW + report.get("time") + ChatColor.DARK_GRAY + "] "; + message += ChatColor.DARK_AQUA + "" + report.get("name"); + message += ChatColor.WHITE + ": " + ChatColor.YELLOW + report.get("message"); + sender.sendMessage(message); + i++; + } + if (i == 0) + { + sender.sendMessage(ChatColor.GREEN + "There are no open reports."); + } + } + + @SuppressWarnings("unchecked") + @Command(hook = "report") + public void report(CommandSender sender, String message) + { + Player player = (Player) sender; + // Create report JSONObject + JSONObject report = new JSONObject(); + report.put("name", player.getName()); + report.put("time", dateFormat.format(new Date())); + report.put("message", message); + String loc = ""; + // Location to string + loc += player.getLocation().getBlockX() + ";" + player.getLocation().getBlockY() + ";" + + player.getLocation().getBlockZ() + ";" + player.getLocation().getWorld().getName(); + report.put("location", loc); + reports.add(report); + sender.sendMessage(ChatColor.GREEN + "Report created!"); + } +} diff --git a/src/com/redstoner/modules/saylol/Saylol.java b/src/com/redstoner/modules/saylol/Saylol.java new file mode 100644 index 0000000..a259ac3 --- /dev/null +++ b/src/com/redstoner/modules/saylol/Saylol.java @@ -0,0 +1,327 @@ +package com.redstoner.modules.saylol; + +import java.io.File; +import java.util.Random; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.json.simple.JSONArray; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.Version; +import com.redstoner.misc.BroadcastFilter; +import com.redstoner.misc.JsonManager; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@Version(major = 2, minor = 0, revision = 0, compatible = 2) +public class Saylol implements Module +{ + private long lastLol = 0; + private File lolLocation = new File(Main.plugin.getDataFolder(), "lol.json"); + private JSONArray lols; + + @Override + public boolean onEnable() + { + lols = JsonManager.getArray(lolLocation); + if (lols == null) + lols = new JSONArray(); + return true; + } + + @Override + public void onDisable() + { + saveLols(); + } + + @SuppressWarnings("unchecked") + @Command(hook = "addlol") + public boolean addLol(CommandSender sender, String text) + { + if (lols.contains(text)) + Utils.sendErrorMessage(sender, null, "This lol already exists!"); + else + { + Utils.sendMessage(sender, null, "Successfully added a new lol!"); + lols.add("&e" + text); + saveLols(); + } + return true; + } + + @Command(hook = "dellol") + public boolean delLol(CommandSender sender, int id) + { + if (lols.size() == 0) + { + Utils.sendErrorMessage(sender, null, "There are no lols yet!"); + return true; + } + if (id < 0 || id >= lols.size()) + { + Utils.sendErrorMessage(sender, null, "The ID must be at least 0 and at most " + (lols.size() - 1)); + return true; + } + Utils.sendMessage(sender, null, "Successfully deleted the lol: " + lols.remove(id), '&'); + saveLols(); + return true; + } + + @SuppressWarnings("unchecked") + @Command(hook = "setlol") + public boolean setLol(CommandSender sender, int id, String text) + { + if (lols.size() == 0) + { + Utils.sendErrorMessage(sender, null, "There are no lols yet!"); + return true; + } + if (id < 0 || id >= lols.size()) + { + Utils.sendErrorMessage(sender, null, "The ID must be at least 0 and at most " + (lols.size() - 1)); + return true; + } + Utils.sendMessage(sender, null, "Successfully changed the lol: &e" + lols.get(id) + " &7to: &e" + text, '&'); + lols.set(id, text); + saveLols(); + return true; + } + + @Command(hook = "lolid") + public boolean lolId(CommandSender sender, int id) + { + if (lols.size() == 0) + { + Utils.sendErrorMessage(sender, null, "There are no lols yet!"); + return true; + } + long time = System.currentTimeMillis(); + if (time - lastLol < 15000) + { + Utils.sendErrorMessage(sender, null, + "You can't use saylol for another " + (14 - (int) Math.ceil((time - lastLol) / 1000)) + "s."); + return true; + } + if (id < 0 || id >= lols.size()) + { + Utils.sendErrorMessage(sender, null, "The ID must be at least 0 and at most " + (lols.size() - 1)); + return true; + } + String name; + if (sender instanceof Player) + name = ((Player) sender).getDisplayName(); + else + name = "&9" + sender.getName(); + Utils.broadcast("&8[&blol&8] ", name + "&8: &e" + lols.get(id), new BroadcastFilter() + { + @Override + public boolean sendTo(CommandSender recipient) + { + return recipient.hasPermission("utils.lol.see"); + } + }, '&'); + lastLol = time; + return true; + } + + @Command(hook = "saylol") + public boolean saylol(CommandSender sender) + { + if (lols.size() == 0) + { + Utils.sendErrorMessage(sender, null, "There are no lols yet!"); + return true; + } + long time = System.currentTimeMillis(); + if (time - lastLol < 15000) + { + Utils.sendErrorMessage(sender, null, + "You can't use saylol for another " + (14 - (int) Math.ceil((time - lastLol) / 1000)) + "s."); + return true; + } + String name; + if (sender instanceof Player) + name = ((Player) sender).getDisplayName(); + else + name = "&9" + sender.getName(); + Random random = new Random(); + int id = random.nextInt(lols.size()); + Utils.broadcast("&8[&blol&8] ", name + "&8: &e" + lols.get(id), new BroadcastFilter() + { + @Override + public boolean sendTo(CommandSender recipient) + { + return recipient.hasPermission("utils.lol.see"); + } + }, '&'); + lastLol = time; + return true; + } + + @Command(hook = "listlols") + public boolean listLols(CommandSender sender, int page) + { + if (lols.size() == 0) + { + Utils.sendErrorMessage(sender, null, "There are no lols yet!"); + return true; + } + page = page - 1; + int start = page * 10; + int end = start + 10; + int pages = (int) Math.ceil(lols.size() / 10d); + if (start < 0) + { + Utils.sendErrorMessage(sender, null, "Page number too small, must be at least 0!"); + return true; + } + if (start > lols.size()) + { + Utils.sendErrorMessage(sender, null, "Page number too big, must be at most " + pages + "!"); + return true; + } + Utils.sendModuleHeader(sender); + Utils.sendMessage(sender, "", "&ePage " + (page + 1) + "/" + pages + ":", '&'); + for (int i = start; i < end && i < lols.size(); i++) + Utils.sendMessage(sender, "", "&a" + i + "&8: &e" + lols.get(i), '&'); + return true; + } + + @Command(hook = "listlolsdef") + public boolean listLolsDefault(CommandSender sender) + { + return listLols(sender, 1); + } + + @Command(hook = "searchlol") + public boolean search(CommandSender sender, boolean insensitive, String text) + { + Utils.sendModuleHeader(sender); + boolean found = false; + if (insensitive) + { + text = text.toLowerCase(); + for (int i = 0; i < lols.size(); i++) + { + if (((String) lols.get(i)).toLowerCase().contains(text)) + { + Utils.sendMessage(sender, "", "&a" + i + "&8: &e" + lols.get(i), '&'); + found = true; + } + } + } + else + { + for (int i = 0; i < lols.size(); i++) + { + if (((String) lols.get(i)).contains(text)) + { + Utils.sendMessage(sender, "", "&a" + i + "&8: &e" + lols.get(i), '&'); + found = true; + } + } + } + if (!found) + { + Utils.sendMessage(sender, "", "&cCouldn't find any matching lols.", '&'); + } + return true; + } + + @Command(hook = "matchlol") + public boolean match(CommandSender sender, boolean insensitive, String regex) + { + Utils.sendModuleHeader(sender); + boolean found = false; + if (insensitive) + { + regex = regex.toLowerCase(); + for (int i = 0; i < lols.size(); i++) + { + if (((String) lols.get(i)).toLowerCase().matches(regex)) + { + Utils.sendMessage(sender, "", "&a" + i + ": " + lols.get(i), '&'); + found = true; + } + } + } + else + { + for (int i = 0; i < lols.size(); i++) + { + if (((String) lols.get(i)).matches(regex)) + { + Utils.sendMessage(sender, "", "&a" + i + ": " + lols.get(i), '&'); + found = true; + } + } + } + if (!found) + { + Utils.sendMessage(sender, "", "&cCouldn't find any matching lols.", '&'); + } + return true; + } + + public void saveLols() + { + JsonManager.save(lols, lolLocation); + } + + // @noformat + @Override + public String getCommandString() + { + return "command lol {\n" + + " add [string:text...] {\n" + + " help Lols a text.;\n" + + " run addlol text;\n" + + " perm utils.lol.admin;\n" + + " }\n" + + " del [int:id] {\n" + + " help Unlols a lol.;\n" + + " run dellol id;\n" + + " perm utils.lol.admin;\n" + + " }\n" + + " set [int:id] [string:text...] {\n" + + " help Relols a lol.;\n" + + " run setlol id text;\n" + + " perm utils.lol.admin;\n" + + " }\n" + + " id [int:id] {\n" + + " help Lols specifically.;\n" + + " run lolid id;\n" + + " perm utils.lol.id;\n" + + " }\n" + + " list [int:page] {\n" + + " help Shows lols.;\n" + + " run listlols page;\n" + + " perm utils.lol.list;\n" + + " }\n" + + " list {\n" + + " help Shows lols.;\n" + + " run listlolsdef;\n" + + " perm utils.lol.list;\n" + + " }\n" + + " search [flag:-i] [string:text...] {\n" + + " help Search lols.;\n" + + " run searchlol -i text;\n" + + " perm utils.lol.search;\n" + + " }\n" + + " match [flag:-i] [string:regex...] {\n" + + " help Search lols. But better.;\n" + + " run matchlol -i regex;\n" + + " perm utils.lol.match;\n" + + " }\n" + + " [empty] {\n" + + " help Lols.;\n" + + " run saylol;\n" + + " perm utils.lol;\n" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/scoreboard/Project.java b/src/com/redstoner/modules/scoreboard/Project.java new file mode 100644 index 0000000..dbdc9fb --- /dev/null +++ b/src/com/redstoner/modules/scoreboard/Project.java @@ -0,0 +1,334 @@ +package com.redstoner.modules.scoreboard; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Score; +import org.bukkit.scoreboard.Scoreboard; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +import com.redstoner.misc.JsonManager; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; + +public class Project +{ + private int progress; + private Project parent; + private final String projectID; + private String projectName; + private String displayName; + private UUID owner; + private JSONArray admins, members; + private int localID; + private Location location; + private Scoreboard scoreboard; + ArrayList subs = new ArrayList(); + + private Project(String projectID, Project parent, String name, String displayName, UUID owner, int localID, + Location location, JSONArray admins, JSONArray members) + { + this.parent = parent; + this.projectID = projectID; + this.progress = 0; + this.owner = owner; + this.location = location; + this.projectName = name; + this.localID = localID; + this.displayName = displayName; + this.admins = admins; + this.members = members; + scoreboard = Bukkit.getScoreboardManager().getNewScoreboard(); + updateScoreboard(); + } + + private Project(String projectID, Project parent, String name, String displayName, UUID owner, int localID, + Location location) + { + this(projectID, null, name, displayName, owner, localID, location, new JSONArray(), new JSONArray()); + } + + private Project(Project parent, String name, String displayName, UUID owner, int localID, Location location) + { + this(ProjectManager.getNextID(name), null, name, displayName, owner, localID, location); + } + + public Project(String name, String displayName, UUID owner, int localID, Location location) + { + this(null, name, displayName, owner, localID, location); + } + + /** This method returns the progress of this project. + * + * @return the progress in percent, as an integer between 0 and 100 (inclusive). */ + public int getProgress() + { + return progress; + } + + /** This method sets the progress to the given parameter. The value must be between 0 and 100 (inclusive).
+ * If this project is not a leaf, then only 0 and 100 can be set, recursively overriding the progress of all sub-projects.
+ * This method will invoke updateProgress(). + * + * @param sender The CommandSender responsible for updating the progress. + * @param progress the new progress, 0 ≤ progress ≤ 100. */ + public void setProgress(CommandSender sender, int progress) + { + if (progress < 0 || progress > 100) + { + if (sender != null) + Utils.sendErrorMessage(sender, null, "Progress must be between 0% and 100%!"); + return; + } + if (subs.size() == 0) + { + if (sender != null) + Utils.sendMessage(sender, null, "Updated the project's progress to &e" + progress + "%&7.", '&'); + this.progress = progress; + updateProgress(); + } + else + { + if (progress == 100) + { + for (Project project : subs) + { + project.setProgress(sender, progress); + } + updateProgress(); + if (sender != null) + Utils.sendMessage(sender, null, "Set the entire branch to done!"); + } + if (progress == 0) + { + for (Project project : subs) + { + project.setProgress(null, progress); + } + updateProgress(); + if (sender != null) + Utils.sendMessage(sender, null, "Set the entire branch to not done!"); + } + else + { + if (sender != null) + { + Utils.sendErrorMessage(sender, null, + "Can not set progress of a non-end project node to anything but 100 or 0!"); + Utils.sendErrorMessage(sender, null, "Please update the corresponding sub-project!"); + } + } + } + } + + /** This method updates the progress on the project, calculating it from the sub-projects if exists and updating the parent as well.
+ * This will also update the scoreboard. */ + public void updateProgress() + { + if (subs.size() != 0) + {} + if (parent != null) + { + parent.updateProgress(); + } + updateScoreboard(); + } + + /** This returns the unique project identifier of this project, consisting of [name]#[ID]. + * + * @return the unique identifier. */ + public String getUUID() + { + return projectID; + } + + /** This method allows access to the parent project. + * + * @return the parent project, or null if this is the root project. */ + public Project getParent() + { + return parent; + } + + /** Teleports a player to the location assigned with this project. If no location can be found, the parent project's location will be used.
+ * If at the root Project no valid location was found, the player will not be teleported and an error message will be sent. + * + * @param player the player to be teleported. + * @return true if the teleport was successfull. */ + public boolean tp(Player player) + { + if (location == null) + { + if (parent != null) + { + return parent.tp(player); + } + else + { + if (player.getUniqueId().equals(owner)) + Utils.sendErrorMessage(player, null, + "No location was assigned with this project! Use &e/project option location set &7(or one of the interactive menus )to define a location!"); + else + Utils.sendErrorMessage(player, null, + "No location was assigned with this project! Ask a project administrator to define one!"); + return false; + } + } + else + { + player.teleport(location); + Utils.sendMessage(player, null, "Teleported you to the projects location!"); + return true; + } + } + + /** This method converts a JSONObject representation of a Project back into the original project.
+ * It will also load all sub-projects recursively, and load complex types back from Strings. + * + * @param project The JSONObject containing the Project. + * @return the project that was represented by the JSONObject. */ + public static Project getProject(JSONObject project) + { + ArrayList subs = new ArrayList(); + for (Object obj : (JSONArray) project.get("subs")) + { + subs.add(Project.getProject((JSONObject) obj)); + } + String projectName = (String) project.get("projectName"); + String displayName = (String) project.get("displayName"); + String projectID = (String) project.get("projectID"); + UUID owner = UUID.fromString((String) project.get("owner")); + JSONArray admins = (JSONArray) project.get("admins"); + JSONArray members = (JSONArray) project.get("members"); + int localID = (int) project.get("localID"); + int progress = (int) project.get("progress"); + Location location = getStringLocation((String) project.get("location")); + Project result = new Project(projectID, null, projectName, displayName, owner, localID, location, admins, + members); + for (Project sub : subs) + sub.parent = result; + result.progress = progress; + return result; + } + + /** This method turns the project into a JSONObject for storing on the file system. It will recursively turn all sub-projects into JSONObjects
+ * and it will also convert all complex types into Strings. + * + * @return A JSONObject representing the project. */ + @SuppressWarnings("unchecked") + public JSONObject toJSONObject() + { + JSONObject project = new JSONObject(); + JSONArray subProjects = new JSONArray(); + for (Project subProject : subs) + { + subProjects.add(subProject.toJSONObject()); + } + project.put("subs", subProjects); + project.put("projectName", this.projectName); + project.put("displayName", this.displayName); + project.put("projectID", this.projectID); + project.put("owner", owner.toString()); + project.put("admins", admins); + project.put("members", members); + project.put("localID", localID); + project.put("progress", progress); + project.put("parent", parent.toString()); + project.put("location", getLocationString(location)); + return project; + } + + /** This method converts a location into a String representation ready for storing on the file system. + * + * @param location The location to be turned into a String. + * @return The String representation of the location. */ + public static String getLocationString(Location location) + { + UUID worldID = location.getWorld().getUID(); + return worldID + ";" + location.getX() + ";" + location.getY() + ";" + location.getZ() + ";" + location.getYaw() + + ";" + location.getPitch(); + } + + /** This method converts a String representation of a location back into its original location. + * + * @param location The String representation of the location. + * @return the location described by the String given, or null if the world containing it is gone. + * @throws NumberFormatException when the floats given as coordinates are invalid. + * @throws NumberFormatException when the UUID given as world descriptor is invalid. */ + public static Location getStringLocation(String location) throws NumberFormatException, IllegalArgumentException + { + String[] params = location.split(";"); + return new Location(Bukkit.getWorld(UUID.fromString(params[0])), Float.parseFloat(params[1]), + Float.parseFloat(params[2]), Float.parseFloat(params[3]), Float.parseFloat(params[4]), + Float.parseFloat(params[5])); + } + + /** This method refreshes the scoreboard assigned with the project and will be called internally when any value changes.
+ * You can call this method at any time before displaying the scoreboard to make sure that the displayed values are accurate. */ + public void updateScoreboard() + { + Objective project = scoreboard.registerNewObjective("Project", "dummy"); + project.setDisplaySlot(DisplaySlot.SIDEBAR); + if (displayName != null) + project.setDisplayName(displayName); + else + project.setDisplayName(projectName); + Score progress = project.getScore("§aProgress"); + progress.setScore(this.progress); + save(); + } + + private void save() + { + if (parent == null) + JsonManager.save(toJSONObject(), + new File(Main.plugin.getDataFolder(), "scoreboards/projects/" + projectID + ".json")); + else + parent.save(); + } + + /** This method returns the UUID of the owner of this project. + * + * @return the UUID of the owner, null if the owner is console. */ + public UUID getOwner() + { + return owner; + } + + /** This method returns how many sub-projects can be created within this project, depending on the permissions of the project owner.
+ *
+ * Please note that as of Version 3.0.x, this value is always 5 and not respecting permissions. + * + * @return The maximum amount of sub-projects this project can have. */ + public int getMaxSubprojects() + { + return 5; + } + + /** This method returns an unmodifiable copy of the sub-projects. If you want to modify the list, use the corresponding add/delete/clear methods
+ * of the project holding the list. You can still perform actions on all sub-projects as usual. + * + * @return An unmodifiable copy of the sub-projects list. */ + public synchronized List getSubProjects() + { + return Collections.unmodifiableList(subs); + } + + /** This method returns the scoreboard generated by the project status. + * + * @return the scoreboard object. */ + public Scoreboard getScoreboard() + { + return scoreboard; + } +} diff --git a/src/com/redstoner/modules/scoreboard/ProjectManager.java b/src/com/redstoner/modules/scoreboard/ProjectManager.java new file mode 100644 index 0000000..b246737 --- /dev/null +++ b/src/com/redstoner/modules/scoreboard/ProjectManager.java @@ -0,0 +1,53 @@ +package com.redstoner.modules.scoreboard; + +import java.io.File; + +import org.bukkit.command.CommandSender; +import org.json.simple.JSONObject; + +import com.redstoner.misc.JsonManager; +import com.redstoner.misc.Main; + +public class ProjectManager +{ + private static File dataFile = new File(Main.plugin.getDataFolder(), "projectIDs.json"); + private static JSONObject IDs; + + static + { + IDs = JsonManager.getObject(dataFile); + if (IDs == null) + IDs = new JSONObject(); + } + + /** This method generates a unique identifier for a project by name. + * + * @param name The name of the project. + * @return The project identifier, as [name]#[ID]. */ + @SuppressWarnings("unchecked") + public static String getNextID(String name) + { + Object raw = IDs.get(name); + int i = 1; + if (raw != null) + i = (int) raw + 1; + IDs.put(name, i); + save(); + return name + "#" + i; + } + + /** Saves the current state into a file. */ + private static void save() + { + JsonManager.save(IDs, dataFile); + } + + /** This method finds the currently active project by a CommandSender and will return it as part of the tree. + * + * @param sender The sender of whom the project is to be found. + * @return the currently active project of the sender or null, if none are active. */ + public static Project getCurrentProject(CommandSender sender) + { + return null; + } +} diff --git a/src/com/redstoner/modules/scoreboard/Scoreboards.java b/src/com/redstoner/modules/scoreboard/Scoreboards.java new file mode 100644 index 0000000..8a03ebb --- /dev/null +++ b/src/com/redstoner/modules/scoreboard/Scoreboards.java @@ -0,0 +1,147 @@ +package com.redstoner.modules.scoreboard; + +import java.io.File; +import java.util.HashMap; +import java.util.Set; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.permissions.PermissionAttachmentInfo; +import org.json.simple.JSONObject; + +import com.nemez.cmdmgr.Command; +import com.nemez.cmdmgr.CommandManager; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.exceptions.MissingVersionException; +import com.redstoner.misc.JsonManager; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.misc.VersionHelper; +import com.redstoner.modules.Module; + +@AutoRegisterListener +@Version(major = 3, minor = 0, revision = 0, compatible = 3) +public class Scoreboards implements Module, Listener +{ + final File cmdFile = new File( + new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile()).getParentFile(), + "Scoreboard.cmd"); + final File scoreboardsFolder = new File(Main.plugin.getDataFolder(), "scoreboards"); + HashMap playerData = new HashMap(); + + @Override + public boolean onEnable() + { + if (!scoreboardsFolder.exists()) + scoreboardsFolder.mkdirs(); + playerData.put(Bukkit.getConsoleSender(), + JsonManager.getObject(new File(scoreboardsFolder, "scoreboards/players/console.json"))); + return true; + } + + @Override + public void postEnable() + { + CommandManager.registerCommand(cmdFile, this, Main.plugin); + } + + @Override + public void onDisable() + { + save(); + for (Player p : Bukkit.getOnlinePlayers()) + { + p.setScoreboard(Bukkit.getScoreboardManager().getMainScoreboard()); + } + playerData.remove(Bukkit.getConsoleSender()); + } + + private void save() + { + JsonManager.save(playerData.get(Bukkit.getConsoleSender()), + new File(scoreboardsFolder, "scoreboards/players/console.json")); + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) + { + Player player = event.getPlayer(); + JSONObject data = JsonManager.getObject( + new File(scoreboardsFolder, "scoreboards/players/" + player.getUniqueId().toString() + ".json")); + if (data == null) + data = new JSONObject(); + playerData.put(player, data); + Project currentProject = ProjectManager.getCurrentProject(player); + if (currentProject == null) + return; + else + player.setScoreboard(currentProject.getScoreboard()); + } + + @EventHandler + public void onPlayerLeave(PlayerQuitEvent event) + { + Player player = event.getPlayer(); + player.setScoreboard(Bukkit.getScoreboardManager().getMainScoreboard()); + JsonManager.save(playerData.remove(player), + new File(scoreboardsFolder, "scoreboards/players/" + player.getUniqueId().toString() + ".json")); + } + + @Command(hook = "project") + public boolean project(CommandSender sender) throws MissingVersionException + { + Utils.sendMessage(sender, null, "This server is running version" + VersionHelper.getVersion(this.getClass())); + return true; + } + + @Command(hook = "create") + public boolean createProject(CommandSender sender, boolean sub, String name) + { + JSONObject data = playerData.get(sender); + if (!sub) + { + int max = Integer.parseInt(getPermissionContent(sender, "utils.scoreboards.projects.amount.")); + int amount = 0; + Object raw = data.get("amount"); + if (raw != null) + amount = (int) raw; + if (amount >= max) + { + Utils.sendErrorMessage(sender, null, "You have already reached the maximum amount of " + max + + " projects! Delete an old project before you create a new one!"); + return true; + } + } + else + { + Project currentProject = ProjectManager.getCurrentProject(sender); + int max = currentProject.getMaxSubprojects(); + int amount = currentProject.getSubProjects().size(); + Object raw = data.get("amount"); + if (raw != null) + amount = (int) raw; + if (amount >= max) + { + Utils.sendErrorMessage(sender, null, "You have already reached the maximum amount of " + max + + " projects! Delete an old project before you create a new one!"); + return true; + } + } + return true; + } + + private static String getPermissionContent(CommandSender sender, String permnode) + { + Set perms = sender.getEffectivePermissions(); + for (PermissionAttachmentInfo perm : perms) + if (perm.getPermission().toString().startsWith(permnode)) + return perm.getPermission().replace(permnode, ""); + return null; + } +} diff --git a/src/com/redstoner/modules/scoreboard/scoreboards.cmd b/src/com/redstoner/modules/scoreboard/scoreboards.cmd new file mode 100644 index 0000000..e6fd956 --- /dev/null +++ b/src/com/redstoner/modules/scoreboard/scoreboards.cmd @@ -0,0 +1,51 @@ +command project { + [empty] { + help Prints version info.; + run project; + perm utils.scoreboards; + } + create [flag:-s] [string:name] { + help Creates a new Project. The -s flag indicates that you are trying to create a new sub-project instead.; + run create -s name; + perm utils.scoreboards.use; + } + delete { + help Deletes the current project. This will also delete the entire branch attached to it, but no parents.; + run delete; + perm utils.scoreboards.use; + } + explore [string:name] { + help Switches to the specified project. If you have multiple projects with the same name reachable in one step (example: you are in 5x5_top and want to go to 5x5_top_trigger, but you also have a project called trigger) then you need to specify the full path like this: 5x5_top_trigger; + run explore name; + perm utils.scoreboards.use; + } + hide { + help Deselects the current project. Use the &e/project explore &7command to view it again!; + run hide; + } + option { + help Opens an interactive option menu to let you change the projects settings.; + run optionMenu; + perm utils.scoreboards.use; + } + option [string:option] { + help Opens an interactive option menu to let you change the specified setting.; + run optionName name; + perm utils.scoreboards.use; + } + option [string:option] [string:value...] { + help Lets you directly modify the options of a project. If no value is specified, an interactive menu opens.; + run option name value; + perm utils.scoreboards.use; + } + manage { + help Opns an interactive menu that lets you manage the project in its entirety.; + run manage; + perm utils.scoreboards.use; + } + invite [flag:-e] [string:name] { + help Invites a player to the current project and all sub projects. If the -e is set, subprojects will be excluded.; + run invite e name; + perm utils.scoreboards.use; + } +} \ No newline at end of file diff --git a/src/com/redstoner/modules/scriptutils/Scriptutils.java b/src/com/redstoner/modules/scriptutils/Scriptutils.java new file mode 100644 index 0000000..9818817 --- /dev/null +++ b/src/com/redstoner/modules/scriptutils/Scriptutils.java @@ -0,0 +1,300 @@ +package com.redstoner.modules.scriptutils; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@Version(major = 2, minor = 0, revision = 1, compatible = 2) +public class Scriptutils implements Module +{ + /** Prints Bukkit restart message + * arg 0 timeout + * arg 1 $(whoami); + * arg 2: reason */ + @Command(hook = "script_restart") + public void print_restart(CommandSender sender, String timeout, String name, String reason) + { + Utils.broadcast("", "§2§l=============================================", null); + Utils.broadcast("", "§r", null); + Utils.broadcast("", "§r", null); + Utils.broadcast("", "§9" + name + " is restarting the server.", null); + Utils.broadcast("", "§a§lServer is going to restart in " + timeout + " seconds.", null); + Utils.broadcast("", "§6§l" + reason, null); + Utils.broadcast("", "§r", null); + Utils.broadcast("", "§r", null); + Utils.broadcast("", "§2§l=============================================", null); + } + + /** Prints the Bukkit shut down message + * arg 0 timeout + * arg 1 $(whoami); + * arg 2: reason */ + @Command(hook = "script_stop") + public void print_stop(CommandSender sender, String timeout, String name, String reason) + { + Utils.broadcast("", "§2§l=============================================", null); + Utils.broadcast("", "§r", null); + Utils.broadcast("", "§r", null); + Utils.broadcast("", "§9" + name + " is shutting down the server.", null); + Utils.broadcast("", "§a§lServer is going to shut down in " + timeout + " seconds.", null); + Utils.broadcast("", "§6§l" + reason, null); + Utils.broadcast("", "§r", null); + Utils.broadcast("", "§r", null); + Utils.broadcast("", "§2§l=============================================", null); + } + + /** Prints the shut down abort message */ + @Command(hook = "script_stop_abort") + public void abort_stop(CommandSender sender) + { + Utils.broadcast("", "§4§oShut down has been aborted.", null); + } + + /** Prints the restart abort message */ + @Command(hook = "script_restart_abort") + public void abort_restart(CommandSender sender) + { + Utils.broadcast("", "§4§oRestart has been aborted.", null); + } + + /** Prints the backup started message, saves all worlds and turns off world saving */ + @Command(hook = "script_backup_begin") + public void print_backup_begin(CommandSender sender) + { + Utils.broadcast("", "§4 =§2 Starting backup now.", null); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "save-all"); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "save-off"); + } + + /** Prints the backup finished message and turns on world saving */ + @Command(hook = "script_backup_end") + public void print_backup_end(CommandSender sender) + { + Utils.broadcast("", "§4 =§2 Backup completed.", null); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "save-on"); + } + + /** Prints the backup error message and turns on world saving */ + @Command(hook = "script_backup_error") + public void print_backup_error(CommandSender sender) + { + Utils.broadcast("", "§4 =§c§l Error while backing up!", null); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "save-on"); + } + + /** Prints the world trimming started message and starts trimming */ + @Command(hook = "script_trim") + public void print_backup_trim(CommandSender sender) + { + Utils.broadcast("", "§4 =§3 Deleting all chunks beyond border now.", null); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "wb Creative trim 1000000 15"); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "wb trim confirm"); + } + + /** Prints the trimming finished message + * arg 0 size difference of world + * arg 1: world border trim data */ + @Command(hook = "script_trim_result") + public void print_backup_trim_res(CommandSender sender, String size, String data) + { + Utils.broadcast("", "§4 =§3 Chunk deletion saved " + data + " (§a" + size + "MB§3)", null); + } + + /** Prints the database backup started message and admin-chat warning */ + @Command(hook = "script_backup_database_begin") + public void print_backup_db_begin(CommandSender sender) + { + Utils.broadcast("", "§6 =§2 Starting database backup now.", null); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "ac §aLogblock may be unavailable!"); + } + + /** Prints the database dumps compression started message */ + @Command(hook = "script_backup_database_dumps") + public void print_backup_db_dumps(CommandSender sender) + { + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "ac §aDumps completed, logblock available again."); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "ac §aNow compressing dumps, will take a while..."); + } + + /** Prints the database finished message and backup size in admin-chat + * arg 0 size of backup */ + @Command(hook = "script_backup_database_end") + public void print_backup_db_end(CommandSender sender, String size) + { + Utils.broadcast("", "§6 =§2 Database backup completed.", null); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "ac §abackup size: §2" + size + "MB§a."); + } + + /** Prints the database backup error message */ + @Command(hook = "script_backup_database_error") + public void print_backup_db_error(CommandSender sender) + { + Utils.broadcast("", "§6 =§c§l Error while backing up database!", null); + } + + /** Prints the database backup abort message */ + @Command(hook = "script_backup_database_abort") + public void print_backup_db_abort(CommandSender sender) + { + Utils.broadcast("", "§6 =§2 Database backup aborted.", null); + } + + /** Prints the spigot update message */ + @Command(hook = "script_spigot_update") + public void print_update(CommandSender sender) + { + Utils.broadcast("", "§9 =§2 A new Spigot version has been downloaded!", null); + Utils.broadcast("", "§9 =§2 Update will be applied after the next reboot.", null); + } + + /** Prints the admin-chat warning for disk is filled + * arg 0 fill percentage */ + @Command(hook = "script_disk_filled") + public void print_disk_filled(CommandSender sender, String percentage) + { + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), + "ac §4§lWARNING:§6 Disk is filled > 96% (" + percentage + "%);"); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "ac §4 Server will shut down at 98%!"); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "ac §4 Contact an admin §nimmediately§4!"); + } + + /** Saves all worlds, kicks players and shuts down the server + * arg 0: reason */ + @Command(hook = "script_shutdown") + public void shutdown(CommandSender sender, String reason) + { + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "save-all"); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "kickall " + reason); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "stop"); + } + + // @noformat + @Override + public String getCommandString() + { + return "command script_restart {\n" + + " [string:timeout] [string:name] [string:reason] {\n" + + " help Prints bukkit restart message;\n" + + " type console;\n" + + " run script_restart timeout name reason;\n" + + " }\n" + + "}\n" + + "command script_stop {\n" + + " [string:timeout] [string:name] [string:reason] {\n" + + " help Prints bukkit shut down message;\n" + + " type console;\n" + + " run script_stop timeout name reason;\n" + + " }\n" + + "}\n" + + "command script_restart_abort {\n" + + " [empty] {\n" + + " help Prints the restart abort message;\n" + + " type console;\n" + + " run script_restart_abort;\n" + + " }\n" + + "}\n" + + "command script_stop_abort {\n" + + " [empty] {\n" + + " help Prints the shut down abort message;\n" + + " type console;\n" + + " run script_stop_abort;\n" + + " }\n" + + "}\n" + + "command script_backup_begin {\n" + + " [empty] {\n" + + " help Prints the backup started message, saves all worlds and turns off world saving;\n" + + " type console;\n" + + " run script_backup_begin;\n" + + " }\n" + + "}\n" + + "command script_backup_end {\n" + + " [empty] {\n" + + " help Prints the backup finished message and turns on world saving;\n" + + " type console;\n" + + " run script_backup_end;\n" + + " }\n" + + "}\n" + + "command script_backup_error {\n" + + " [empty] {\n" + + " help Prints the backup error message and turns on world saving;\n" + + " type console;\n" + + " run script_backup_error;\n" + + " }\n" + + "}\n" + + "command script_trim {\n" + + " [empty] {\n" + + " help Prints the world trimming started message and starts trimming;\n" + + " type console;\n" + + " run script_trim;\n" + + " }\n" + + "}\n" + + "command script_trim_result {\n" + + " [string:size] [string:data...] {\n" + + " help Prints the trimming finished message;\n" + + " type console;\n" + + " run script_trim_result size data;\n" + + " }\n" + + "}\n" + + "command script_backup_database_begin {\n" + + " [empty] {\n" + + " help Prints the database backup started message and admin-chat warning;\n" + + " type console;\n" + + " run script_backup_database_begin;\n" + + " }\n" + + "}\n" + + "command script_backup_database_dumps {\n" + + " [empty] {\n" + + " help Prints the database dumps cmpression started message;\n" + + " type console;\n" + + " run script_backup_database_dumps;\n" + + " }\n" + + "}\n" + + "command script_backup_database_end {\n" + + " [string:size] {\n" + + " help Prints the database finished message and backup size in admin-chat;\n" + + " type console;\n" + + " run script_backup_database_end size;\n" + + " }\n" + + "}\n" + + "command script_backup_database_error {\n" + + " [empty] {\n" + + " help Prints the database backup error message;\n" + + " type console;\n" + + " run script_backup_database_error;\n" + + " }\n" + + "}\n" + + "command script_backup_database_abort {\n" + + " [empty] {\n" + + " help Prints the database backup abort message;\n" + + " type console;\n" + + " run script_backup_database_abort;\n" + + " }\n" + + "}\n" + + "command script_spigot_update {\n" + + " [empty] {\n" + + " help Prints the spigot update message;\n" + + " type console;\n" + + " run script_spigot_update;\n" + + " }\n" + + "}\n" + + "command script_disk_filled {\n" + + " [string:percentage] {\n" + + " help Prints the admin-chat warning for disk is filled;\n" + + " type console;\n" + + " run script_disk_filled percentage;\n" + + " }\n" + + "}\n" + + "command script_shutdown {\n" + + " [string:reason] {\n" + + " help Saves all worlds, kicks players and shuts down the server;\n" + + " type console;\n" + + " run script_shutdown reason;\n" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/skullclick/SkullClick.java b/src/com/redstoner/modules/skullclick/SkullClick.java new file mode 100644 index 0000000..d4bddb2 --- /dev/null +++ b/src/com/redstoner/modules/skullclick/SkullClick.java @@ -0,0 +1,60 @@ +package com.redstoner.modules.skullclick; + +import org.bukkit.block.BlockState; +import org.bukkit.block.Skull; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; + +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@Version(major = 1, minor = 0, revision = 1, compatible = 1) +@AutoRegisterListener +public class SkullClick implements Module, Listener +{ + private boolean seen = false; + + @SuppressWarnings("deprecation") + @EventHandler + public void onClick(PlayerInteractEvent e) + { + // For some reason the event gets fired twice, this fixes it. Lol. + if (seen) + { + seen = false; + return; + } + seen = true; + if (e.getAction() == Action.RIGHT_CLICK_BLOCK && !e.isCancelled()) + { + BlockState block = e.getClickedBlock().getState(); + if (block instanceof Skull) + { + Skull skull = (Skull) block; + String owner = skull.getOwner(); + if (owner == null || owner.equals("")) + { + Utils.sendMessage(e.getPlayer(), null, "§eThat skull has no owner."); + } + else + { + Utils.sendMessage(e.getPlayer(), null, "§eThat's " + owner + "."); + } + if (!e.getPlayer().isSneaking()) + { + e.setCancelled(true); + } + } + } + } + + @Override + public String getCommandString() + { + return null; + } +} diff --git a/src/com/redstoner/modules/tag/Tag.java b/src/com/redstoner/modules/tag/Tag.java new file mode 100644 index 0000000..9685bf5 --- /dev/null +++ b/src/com/redstoner/modules/tag/Tag.java @@ -0,0 +1,167 @@ +package com.redstoner.modules.tag; + +import java.io.File; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.CommandSender; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +import com.nemez.cmdmgr.Command; +import com.nemez.cmdmgr.Command.AsyncType; +import com.redstoner.annotations.Version; +import com.redstoner.misc.JsonManager; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@Version(major = 2, minor = 0, revision = 0, compatible = 2) +public class Tag implements Module +{ + private File tagLocation = new File(Main.plugin.getDataFolder(), "tag.json"); + private JSONObject tags; + + @Override + public boolean onEnable() + { + tags = JsonManager.getObject(tagLocation); + if (tags == null) + tags = new JSONObject(); + return true; + } + + @Override + public void onDisable() + { + saveTags(); + } + + @SuppressWarnings({"deprecation", "unchecked"}) + @Command(hook = "addtag", async = AsyncType.ALWAYS) + public boolean addTag(CommandSender sender, String name, String tag) + { + OfflinePlayer player = Bukkit.getOfflinePlayer(name); + if (player == null) + { + Utils.sendErrorMessage(sender, null, "That player doesn't exist!"); + return true; + } + Utils.sendModuleHeader(sender); + UUID uuid = player.getUniqueId(); + JSONArray tagArray; + if (tags.containsKey(uuid.toString())) + tagArray = (JSONArray) tags.get(uuid.toString()); + else + tagArray = new JSONArray(); + tagArray.add(tag); + if (!tags.containsKey(uuid.toString())) + tags.put(uuid.toString(), tagArray); + Utils.sendMessage(sender, null, "Successfully added note &e" + tag + " &7to player &e" + name + "&7!", '&'); + saveTags(); + return true; + } + + @SuppressWarnings("deprecation") + @Command(hook = "deltag", async = AsyncType.ALWAYS) + public boolean delTag(CommandSender sender, String name, int id) + { + if (id < 1) + { + Utils.sendErrorMessage(sender, null, "The ID you entered is too small, it must be at least 1!"); + return true; + } + OfflinePlayer player = Bukkit.getOfflinePlayer(name); + if (player == null) + { + Utils.sendErrorMessage(sender, null, "That player doesn't exist!"); + return true; + } + UUID uuid = player.getUniqueId(); + if (!tags.containsKey(uuid.toString())) + { + Utils.sendMessage(sender, null, "&eThere are no notes about that player.", '&'); + return true; + } + JSONArray tagArray = (JSONArray) tags.get(uuid.toString()); + int size = tagArray.size(); + if (size == 0) + { + Utils.sendErrorMessage(sender, null, + "Empty entry found! You might consider running a database cleanup, contact an admin to do this."); + Utils.log("Found empty tag entry. Database cleanup is recommended."); + return true; + } + if (id > size) + { + Utils.sendErrorMessage(sender, null, "The number you entered is too big! It must be at most " + size + "!"); + return true; + } + Utils.sendMessage(sender, null, "Successfully removed note: &e" + tagArray.remove(id - 1), '&'); + if (tagArray.size() == 0) + tags.remove(uuid.toString()); + saveTags(); + return true; + } + + @SuppressWarnings("deprecation") + @Command(hook = "checktag", async = AsyncType.ALWAYS) + public boolean checkTags(CommandSender sender, String name) + { + OfflinePlayer player = Bukkit.getOfflinePlayer(name); + if (player == null) + { + Utils.sendErrorMessage(sender, null, "That player doesn't exist!"); + return true; + } + Utils.sendModuleHeader(sender); + UUID uuid = player.getUniqueId(); + if (!tags.containsKey(uuid.toString())) + { + Utils.sendMessage(sender, "", "&eThere are no notes about that player.", '&'); + return true; + } + JSONArray tagArray = (JSONArray) tags.get(uuid.toString()); + int size = tagArray.size(); + Utils.sendMessage(sender, "", "There are " + size + " notes about this player:"); + if (size == 0) + { + tags.remove(uuid.toString()); + saveTags(); + return true; + } + for (int i = 0; i < size; i++) + Utils.sendMessage(sender, "", "&a" + (i + 1) + "&8: &e" + tagArray.get(i), '&'); + return true; + } + + public void saveTags() + { + JsonManager.save(tags, tagLocation); + } + + // @noformat + @Override + public String getCommandString() + { + return "command tag {\n" + + " add [string:player] [string:tag...] {\n" + + " help Tags a player.;\n" + + " run addtag player tag;\n" + + " perm utils.tag;\n" + + " }\n" + + " del [string:player] [int:id] {\n" + + " help Removes a tag.;\n" + + " run deltag player id;\n" + + " perm utils.tag;\n" + + " }\n" + + " check [string:player] {\n" + + " help Lists all tags of a player.;\n" + + " run checktag player;\n" + + " perm utils.tag;\n" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/vanish/Vanish.java b/src/com/redstoner/modules/vanish/Vanish.java new file mode 100644 index 0000000..d7eb372 --- /dev/null +++ b/src/com/redstoner/modules/vanish/Vanish.java @@ -0,0 +1,243 @@ +package com.redstoner.modules.vanish; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map.Entry; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@AutoRegisterListener +@Version(major = 2, minor = 0, revision = 3, compatible = 2) +public class Vanish implements Module, Listener +{ + private ArrayList vanished = new ArrayList(); + private HashMap> vanishOthers = new HashMap>(); + + @Command(hook = "vanish") + public boolean vanish(CommandSender sender) + { + UUID uid = ((Player) sender).getUniqueId(); + if (vanished.contains(uid)) + { + vanished.remove(uid); + Utils.sendMessage(sender, null, "You are no longer vanished!"); + unvanishPlayer((Player) sender); + } + else + { + vanished.add(uid); + Utils.sendMessage(sender, null, "You are now vanished!"); + vanishPlayer((Player) sender); + } + return true; + } + + @Command(hook = "vanish_on") + public boolean vanishOn(CommandSender sender) + { + UUID uid = ((Player) sender).getUniqueId(); + if (vanished.contains(uid)) + Utils.sendMessage(sender, null, + "You were already vanished, however we refreshed the vanish for you just to be sure!"); + else + { + vanished.add(uid); + Utils.sendMessage(sender, null, "You are now vanished!"); + } + vanishPlayer((Player) sender); + return true; + } + + @Command(hook = "vanish_off") + public boolean vanishOff(CommandSender sender) + { + UUID uid = ((Player) sender).getUniqueId(); + if (!vanished.contains(uid)) + Utils.sendMessage(sender, null, + "You were not vanished, however we refreshed the vanish for you just to be sure!"); + else + { + vanished.remove(uid); + Utils.sendMessage(sender, null, "You are no longer vanished!"); + } + unvanishPlayer((Player) sender); + return true; + } + + @Command(hook = "vanish_other") + public boolean vanishOther(CommandSender sender, String name) + { + Player player = Bukkit.getPlayer(name); + if (player == null) + { + Utils.sendMessage(sender, null, "&cPlayer &6" + name + " &ccould not be found!", '&'); + return true; + } + UUID uid = player.getUniqueId(); + if (player.hasPermission("utils.vanish")) + { + if (vanished.contains(uid)) + { + vanished.remove(uid); + Utils.sendMessage(sender, null, "Successfully unvanished player &6" + name, '&'); + Utils.sendMessage(player, null, "You are no longer vanished!"); + } + else + { + vanished.add(uid); + Utils.sendMessage(sender, null, "Successfully vanished player &6" + name, '&'); + Utils.sendMessage(player, null, "You are now vanished!"); + } + return true; + } + for (Entry> entry : vanishOthers.entrySet()) + { + if (entry.getValue().contains(uid)) + { + entry.getValue().remove(uid); + Utils.sendMessage(sender, null, "Successfully unvanished player &6" + name, '&'); + Utils.sendMessage(player, null, "You are no longer vanished!"); + if (entry.getValue().size() == 0) + vanishOthers.remove(entry.getKey()); + return true; + } + } + UUID uuid = ((Player) sender).getUniqueId(); + ArrayList toAddTo = vanishOthers.get(uuid); + if (toAddTo == null) + toAddTo = new ArrayList(); + toAddTo.add(uid); + vanishOthers.put(uuid, toAddTo); + Utils.sendMessage(sender, null, "Successfully vanished player &6" + name, '&'); + Utils.sendMessage(player, null, "You are now vanished!"); + return true; + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onPlayerJoin(PlayerJoinEvent event) + { + Player player = event.getPlayer(); + if (vanished.contains(player.getUniqueId())) + { + for (Player p : Bukkit.getOnlinePlayers()) + { + if (!p.hasPermission("utils.vanish")) + p.hidePlayer(player); + } + event.setJoinMessage(null); + } + if (player.hasPermission("utils.vanish")) + return; + for (UUID uid : vanished) + { + Player p = Bukkit.getPlayer(uid); + if (p == null) + continue; + player.hidePlayer(p); + } + for (Entry> entry : vanishOthers.entrySet()) + { + for (UUID uid : entry.getValue()) + { + Player p = Bukkit.getPlayer(uid); + if (p == null) + continue; + player.hidePlayer(p); + } + } + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onPlayerLeave(PlayerQuitEvent event) + { + Player player = event.getPlayer(); + UUID uid = player.getUniqueId(); + if (vanished.contains(player.getUniqueId())) + { + event.setQuitMessage(null); + } + if (vanishOthers.containsKey(uid)) + { + ArrayList toUnvanish = vanishOthers.remove(uid); + for (UUID uuid : toUnvanish) + { + Player p = Bukkit.getPlayer(uuid); + if (p != null) + unvanishPlayer(p); + } + } + boolean wasVanished = false; + for (Entry> entry : vanishOthers.entrySet()) + { + if (entry.getValue().contains(uid)) + { + entry.getValue().remove(uid); + wasVanished = true; + break; + } + } + if (wasVanished) + unvanishPlayer(player); + } + + private void vanishPlayer(Player player) + { + for (Player p : Bukkit.getOnlinePlayers()) + { + if (!p.hasPermission("utils.vanish")) + p.hidePlayer(player); + } + } + + private void unvanishPlayer(Player player) + { + for (Player p : Bukkit.getOnlinePlayers()) + p.showPlayer(player); + } + + // @noformat + @Override + public String getCommandString() + { + return "command vanish {\n" + + " [empty] {\n" + + " help Toggles your vanish status.;\n" + + " type player;\n" + + " run vanish;\n" + + " perm utils.vanish;\n" + + " }\n" + + " on {\n" + + " help Turns your vanish on.;\n" + + " type player;\n" + + " run vanish_on;\n" + + " perm utils.vanish;\n" + + " }\n" + + " off {\n" + + " help Turns your vanish off.;\n" + + " type player;\n" + + " run vanish_off;\n" + + " perm utils.vanish;\n" + + " }\n" + + " [string:name] {\n" + + " help Toggles someone elses vanish;\n" + + " run vanish_other name;\n" + + " perm utils.vanishother;\n" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/warn/Warn.java b/src/com/redstoner/modules/warn/Warn.java new file mode 100644 index 0000000..53202a1 --- /dev/null +++ b/src/com/redstoner/modules/warn/Warn.java @@ -0,0 +1,51 @@ +package com.redstoner.modules.warn; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@Version(major = 2, minor = 0, revision = 1, compatible = 2) +public class Warn implements Module +{ + @Command(hook = "warn") + public void warn_normal(CommandSender sender) + { + String name = ((Player) sender).getDisplayName(); + Utils.broadcast(null, "§2Lag incoming! - §9" + name, null); + } + + @Command(hook = "warnp") + public void warn_possible(CommandSender sender) + { + String name = ((Player) sender).getDisplayName(); + Utils.broadcast(null, "§2Possible lag incoming! - §9" + name, null); + } + + // @noformat + @Override + public String getCommandString() + { + return "command warn {\n" + + " [empty] {\n" + + " run warn;\n" + + " type player;\n" + + " help Warns other players about definite lag;\n" + + " perm utils.warn;\n" + + " }\n" + + "}\n" + + "\n" + + "command warnp {\n" + + " [empty] {\n" + + " run warnp;\n" + + " type player;\n" + + " help Warns other players about possible lag;\n" + + " perm utils.warn;\n" + + " }\n" + + "}"; + } + //@format +} diff --git a/src/com/redstoner/modules/webtoken/WebToken.java b/src/com/redstoner/modules/webtoken/WebToken.java new file mode 100644 index 0000000..0418a38 --- /dev/null +++ b/src/com/redstoner/modules/webtoken/WebToken.java @@ -0,0 +1,226 @@ +package com.redstoner.modules.webtoken; + +import java.io.IOException; +import java.util.Random; +import java.util.UUID; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.json.simple.parser.ParseException; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Utils; +import com.redstoner.misc.mysql.Config; +import com.redstoner.misc.mysql.MysqlHandler; +import com.redstoner.misc.mysql.elements.ConstraintOperator; +import com.redstoner.misc.mysql.elements.MysqlConstraint; +import com.redstoner.misc.mysql.elements.MysqlDatabase; +import com.redstoner.misc.mysql.elements.MysqlTable; +import com.redstoner.modules.Module; + +@Version(major = 2, minor = 0, revision = 3, compatible = 2) +public class WebToken implements Module +{ + private static final int TOKEN_LENGTH = 6; + private static final String CONSONANTS = "bcdfghjklmnpqrstvwxyz"; + private static final String VOWELS = "aeiou"; + private MysqlTable table; + + @Override + public boolean onEnable() + { + Config config; + try + { + config = Config.getConfig("WebToken.json"); + } + catch (IOException | ParseException e1) + { + e1.printStackTrace(); + return false; + } + if (config == null || !config.containsKey("database") || !config.containsKey("table")) + { + Utils.error("Could not load the WebToken config file, disabling!"); + config.put("database", "redstoner"); + config.put("table", "webtoken"); + return false; + } + try + { + MysqlDatabase database = MysqlHandler.INSTANCE.getDatabase(config.get("database") + "?autoReconnect=true"); + table = database.getTable(config.get("table")); + } + catch (NullPointerException e) + { + Utils.error("Could not use the WebToken config, disabling!"); + return false; + } + return true; + } + + private String getNextId() throws Exception + { + Object[] results = table.get("select id from register_tokens order by id desc limit 1;"); + if (results[0] instanceof Integer) + { + return ((int) results[0]) + 1 + ""; + } + else if (results[0] instanceof String) + { + int id = Integer.valueOf((String) results[0]); + return id + 1 + ""; + } + else + { + throw new Exception("Token query returned invalid result!"); + } + } + + private String query(String emailOrToken, UUID uuid) throws Exception + { + if (!(emailOrToken.equals("token") && emailOrToken.equals("email"))) + { + throw new Exception("Invalid database query: " + emailOrToken); + } + Object[] results = table.get(emailOrToken, + new MysqlConstraint("uuid", ConstraintOperator.EQUAL, uuid.toString().replaceAll("-", ""))); + if (results instanceof String[]) + { + String[] tokenResults = (String[]) results; + if (tokenResults.length == 1) + { + return tokenResults[0]; + } + else + { + return null; + } + } + else + { + throw new Exception("Token query returned invalid result!"); + } + } + + private boolean match(String string, String regex) + { + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(string); + return matcher.find(); + } + + private void printToken(Player player, String email, String token) + { + Utils.sendModuleHeader(player); + Utils.sendMessage(player, "", "§aEmail: " + email); + Utils.sendMessage(player, "", "§aToken: " + token); + Utils.sendMessage(player, "", "§cIMPORTANT: never share the token with anyone!"); + Utils.sendMessage(player, "", "§cIt could be used to claim your website account!"); + } + + private String generateToken() + { + String token = ""; + Random random = new Random(); + int start = random.nextInt(2); + for (int i = 0; i < TOKEN_LENGTH; i++) + { + if (i % 2 == start) + { + token += CONSONANTS.charAt(random.nextInt(21)); + } + else + { + token += VOWELS.charAt(random.nextInt(5)); + } + } + return token; + } + + @Command(hook = "token") + public void token(CommandSender sender) + { + Player player = (Player) sender; + UUID uuid = player.getUniqueId(); + try + { + String token = query("token", uuid); + if (token == null) + { + Utils.sendErrorMessage(player, null, "§cYou don't have a token yet! Use " + ChatColor.YELLOW + + "/gettoken " + ChatColor.RED + " to get one."); + } + else + { + String email = query("email", uuid); + printToken(player, email, token); + } + } + catch (Exception e) + { + Utils.sendErrorMessage(player, null, "Error getting your token, please contact an admin!"); + e.printStackTrace(); + } + } + + @Command(hook = "gettoken") + public void token(CommandSender sender, String email) + { + Player player = (Player) sender; + if (match(email, "^.+@(.+\\..{2,}|\\[[0-9a-fA-F:.]+\\])$")) + { + String uuid = player.getUniqueId().toString().replaceAll("-", ""); + String token = generateToken(); + try + { + String id = getNextId(); + table.delete(new MysqlConstraint("uuid", ConstraintOperator.EQUAL, uuid)); + table.insert(id, uuid, token, email); + player.sendMessage(ChatColor.GREEN + "Token generated!"); + printToken(player, email, token); + } + catch (Exception e) + { + Utils.sendErrorMessage(player, null, "Error getting your token, please contact an admin!"); + e.printStackTrace(); + } + } + else + { + Utils.sendErrorMessage(player, null, "Hmm... That doesn't look like a valid email!"); + } + } + + // @noformat + @Override + public String getCommandString() + { + return "command token {\n" + + " perm utils.webtoken;\n" + + " \n" + + " [empty] {\n" + + " help Displays an already generated token;\n" + + " type player;\n" + + " perm utils.webtoken;\n" + + " run token;\n" + + " }\n" + + "}\n" + + "\n" + + "command gettoken {\n" + + " perm utils.webtoken;\n" + + " \n" + + " [string:email...] {\n" + + " help Generates a token used for website authentication;\n" + + " type player;\n" + + " perm utils.webtoken;\n" + + " run gettoken email;\n" + + " }\n" + + "}"; + } + // @format +}