├── .gitignore ├── nb-configuration.xml ├── pom.xml └── src └── main └── java ├── BukkitLibs.java ├── Colorize.java ├── block └── Regeneration.java ├── command ├── AbstractCommand.java ├── AnnotationCommand.java ├── CommandRegistrationFactory.java └── Commander.java ├── configuration ├── Config.java ├── ConfigManager.java └── LocationParser.java ├── database └── SimpleEbean.java ├── enchantment ├── AbstractEnchantment.java └── CustomEnchantment.java ├── events └── SimpleListener.java ├── item ├── AddGlow.java ├── CommandItem.java ├── InventoryParser.java └── RunnableMenu.java ├── packets ├── PacketWriter.java ├── Rope_NMS.java └── Rope_Reflection.java ├── theories ├── AwesomeLoader.java └── TellRaw.java ├── thread ├── Download.java ├── QueryPool.java ├── SimpleTimer.java ├── TestImage.java └── TextReader.java └── utils ├── ChestUtils.java ├── Cooldowns.java ├── CooldownsLite.java ├── GeneralUtils.java ├── Performance.java ├── ReflectionUtil.java └── SpreadPlayers.java /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ -------------------------------------------------------------------------------- /nb-configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 16 | mit 17 | 18 | 19 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | org.goblom 6 | Bukkit-Libs 7 | 1.0 8 | jar 9 | 10 | Bukkit-Libs 11 | http://maven.apache.org 12 | 13 | 14 | UTF-8 15 | 16 | 17 | 18 | bukkit-repo 19 | http://repo.bukkit.org/content/groups/public 20 | 21 | always 22 | 23 | 24 | always 25 | 26 | 27 | 28 | comphenix-rep 29 | Comphenix Repository 30 | http://repo.comphenix.net/content/groups/public 31 | 32 | 33 | 34 | 35 | com.comphenix.protocol 36 | ProtocolLib 37 | LATEST 38 | 39 | 40 | com.sk89q 41 | worldguard 42 | 5.8.1-SNAPSHOT 43 | 44 | 45 | org.bukkit 46 | bukkit 47 | 1.7.10-R0.1-SNAPSHOT 48 | 49 | 50 | org.bukkit 51 | craftbukkit 52 | 1.7.10-R0.1-SNAPSHOT 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /src/main/java/BukkitLibs.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2013 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | 26 | 27 | import java.sql.Connection; 28 | import java.sql.ResultSet; 29 | import java.text.SimpleDateFormat; 30 | import java.util.Date; 31 | import org.bukkit.Bukkit; 32 | import org.bukkit.ChatColor; 33 | import org.bukkit.command.Command; 34 | import org.bukkit.command.CommandExecutor; 35 | import org.bukkit.command.CommandSender; 36 | import org.bukkit.entity.Player; 37 | import command.CommandRegistrationFactory; 38 | import thread.QueryPool; 39 | 40 | /** 41 | * Just a Holder Class. Stuff will be added to this sometime in the future 42 | * 43 | * @author Goblom 44 | */ 45 | public class BukkitLibs { 46 | 47 | public void QueryThreadTesting() { 48 | Connection connection = null; //Nulling for example, you should never do this 49 | 50 | QueryPool.scheduleQuery(connection, "SELECT * FROM `stats` WHERE `player`='Goblom';", new QueryPool.DataHandler() { 51 | private SimpleDateFormat sdf = new SimpleDateFormat("EEE, MMM d, K:mm a"); 52 | @Override 53 | public void onQuery(String sql) { 54 | System.out.println("Query Started On: " + sdf.format(new Date(getStartTime()))); 55 | System.out.println("Query Being Made: " + sql); 56 | } 57 | 58 | @Override 59 | public void onDataRecieved(boolean failed, ResultSet rs) { 60 | if (failed) { 61 | //lets throw the exception 62 | throw new RuntimeException("The Query Failed At: " + sdf.format(new Date(getEndTime())), getException()); 63 | } 64 | 65 | //lets do stuff with the data 66 | System.out.println("The Query Finished On: " + sdf.format(new Date(getEndTime()))); 67 | 68 | int kills = -1, deaths = -1; 69 | 70 | try { 71 | kills = rs.getInt("kills"); 72 | deaths = rs.getInt("deaths"); 73 | } catch (Exception e) { 74 | e.printStackTrace(); 75 | } 76 | 77 | //do stuff with that data 78 | System.out.println("Kills: " + kills); 79 | System.out.println("Deaths: " + deaths); 80 | } 81 | }); 82 | } 83 | 84 | public void CommandRegistrationFactoryTesting() { 85 | CommandRegistrationFactory factory = new CommandRegistrationFactory("command_name"); 86 | // CommandRegistrationFactory.buildCommand("command_name"); 87 | 88 | factory.withAliases("alias1", "alias2", "alias3"); 89 | factory.withCommandExecutor(new CommandExecutor() { 90 | public boolean onCommand(CommandSender cs, Command cmnd, String string, String[] strings) { 91 | cs.sendMessage("This is a dynamic command"); 92 | return true; 93 | } 94 | }); 95 | factory.withDescription("This is a dynamic command."); 96 | factory.withPermission("test.permission"); 97 | factory.withPermissionMessage(ChatColor.RED + "&lYou do not have permission to use this command."); 98 | factory.withPlugin(Bukkit.getPluginManager().getPlugin("some plugin name")); 99 | factory.withUsage("/ [args]"); 100 | 101 | factory.register(); 102 | // .build(); 103 | 104 | /******************************** 105 | * Lets write a command 106 | * 107 | * Values: 108 | * Command: /heal 109 | * Aliases: /h 110 | * Usage: / [amount] 111 | * Permission: heal.use 112 | * Permission Message: You do not have permission do /heal 113 | */ 114 | CommandRegistrationFactory healCommand = CommandRegistrationFactory.buildCommand("heal"); 115 | healCommand.withAliases("h"); 116 | healCommand.withDescription("Heal a player"); 117 | healCommand.withUsage("/ [amount]"); 118 | healCommand.withPermission("heal.use"); 119 | healCommand.withPermissionMessage("You do not have permission do do /heal"); 120 | healCommand.withCommandExecutor(new CommandExecutor() { 121 | public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { 122 | if (!(sender instanceof Player)) return true; 123 | if (args.length >= 1) { 124 | Player toHeal = Bukkit.getPlayer(args[0]); 125 | if (toHeal != null) { 126 | if (args.length >= 2) { 127 | try { 128 | toHeal.setHealth(Double.valueOf(args[1])); 129 | sender.sendMessage("You have healed " + toHeal.getName()); 130 | toHeal.sendMessage("You have been healed!"); 131 | } catch (NumberFormatException e) { 132 | sender.sendMessage("Health must be a number!"); 133 | } 134 | } else { 135 | toHeal.setHealth(20.0D); 136 | sender.sendMessage("You have healed " + toHeal.getName()); 137 | toHeal.sendMessage("You have been healed!"); 138 | } 139 | } else sender.sendMessage("That player is not online!"); 140 | } else { 141 | ((Player) sender).setHealth(20.0D); 142 | sender.sendMessage("You have been healed!"); 143 | } 144 | return true; 145 | } 146 | }); 147 | factory.build(); 148 | 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /src/main/java/Colorize.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2014 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | 26 | import com.google.common.collect.Lists; 27 | import java.util.List; 28 | import java.util.Random; 29 | import org.bukkit.ChatColor; 30 | 31 | /** 32 | * 33 | * @author Goblom 34 | */ 35 | public class Colorize { 36 | 37 | private static final Random RANDOM = new Random(); 38 | 39 | private static final char[] COLORS = {'1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; 40 | private static final char[] STYLES = {'l', 'n', 'o', 'k', 'm'}; //do not use r 41 | private static final char[] ALL_COLORS = {'1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'l', 'n', 'o', 'k', 'm'}; //do not use r 42 | 43 | public static String getRandomColorCode(boolean withExtra) { 44 | char[] toRandomize = (withExtra ? ALL_COLORS : COLORS); 45 | 46 | return "&" + String.valueOf(toRandomize[RANDOM.nextInt(toRandomize.length)]); 47 | } 48 | 49 | public static Stylize style(String toStyle) { 50 | return new Stylize(toStyle); 51 | } 52 | 53 | public static class Stylize { 54 | 55 | private final String toStyle; 56 | 57 | protected Stylize(String toStyle) { 58 | this.toStyle = toStyle; 59 | } 60 | 61 | public String toRainbow() { 62 | StringBuilder sb = new StringBuilder(); 63 | 64 | for (char c : toStyle.toCharArray()) { 65 | sb.append(Colorize.getRandomColorCode(false) + String.valueOf(c)); 66 | } 67 | 68 | return ChatColor.translateAlternateColorCodes('&', sb.toString()); 69 | } 70 | 71 | public String toGarbage() { 72 | List characters = Lists.newArrayList(); 73 | 74 | for (char c : toStyle.toCharArray()) { 75 | characters.add(c); 76 | } 77 | 78 | StringBuilder sb = new StringBuilder(toStyle.length()); 79 | while (!characters.isEmpty()) { 80 | int randPicker = (int) (Math.random() * characters.size()); 81 | sb.append(characters.remove(randPicker)); 82 | } 83 | 84 | return sb.toString(); 85 | } 86 | 87 | public String toStripe(ChatColor colorOne, ChatColor colorTwo) { 88 | StringBuilder sb = new StringBuilder(); 89 | boolean a = true; 90 | for (char c : toStyle.toCharArray()) { 91 | sb.append(a ? colorOne : colorTwo); 92 | sb.append(c); 93 | } 94 | 95 | return sb.toString(); 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/block/Regeneration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2014 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package block; 25 | 26 | import com.google.common.collect.Lists; 27 | import com.google.common.collect.Maps; 28 | import java.util.List; 29 | import java.util.Map; 30 | import org.bukkit.Location; 31 | import org.bukkit.block.Block; 32 | import org.bukkit.block.BlockState; 33 | import org.bukkit.event.block.BlockBreakEvent; 34 | import org.bukkit.event.block.BlockPlaceEvent; 35 | import org.bukkit.plugin.Plugin; 36 | import org.bukkit.scheduler.BukkitRunnable; 37 | 38 | /** 39 | * Regeneration v1.0 40 | * 41 | * A simple block regeneration class that allows a person to request a location 42 | * to be regenerated after a certain amount of time. 43 | * 44 | * @author Goblom 45 | */ 46 | public class Regeneration { 47 | 48 | private final Plugin plugin; 49 | private static final Map toRegen = Maps.newHashMap(); 50 | private static final List tasks = Lists.newArrayList(); 51 | 52 | /** 53 | * @see Regeneration 54 | * @param plugin 55 | */ 56 | public Regeneration(Plugin plugin) { 57 | this.plugin = plugin; 58 | } 59 | 60 | /** 61 | * Checks to see if the task list is not empty and need to run tasks 62 | * 63 | * @return true if there are tasks that need to run 64 | */ 65 | public boolean hasTasks() { 66 | return !tasks.isEmpty(); 67 | } 68 | 69 | /** 70 | * Forces all tasks to run 71 | */ 72 | public void forceTasks() { 73 | for (BlockRegen task : tasks) { 74 | //i overwrote the cancel task 75 | task.cancel(); 76 | } 77 | } 78 | 79 | /** 80 | * Checks if the location you want to regen already has a regen task running 81 | * on it 82 | * 83 | * @param location 84 | * @return true if that location already has a {@link BlockRegen} task 85 | */ 86 | public boolean alreadyScheduled(Location location) { 87 | return toRegen.containsKey(location); 88 | } 89 | 90 | /** 91 | * Request the location for a {@link BlockRegen} task 92 | * 93 | * @param block the block to regen back to 94 | * @param ticksLater ticks later for regen task to run 95 | * @return true if task was started, false if a task is {@link Regeneration#alreadyScheduled(org.bukkit.Location) 96 | * } 97 | */ 98 | public boolean request(Block block, long ticksLater) { 99 | return request(block.getState(), ticksLater); 100 | } 101 | 102 | /** 103 | * Request the location for a {@link BlockRegen} task 104 | * 105 | * @param state the state to regen back to 106 | * @param ticksLater ticks later for regen task to run 107 | * @return true if task was started, false if a task is {@link Regeneration#alreadyScheduled(org.bukkit.Location) 108 | * } 109 | */ 110 | public boolean request(BlockState state, long ticksLater) { 111 | if (alreadyScheduled(state.getLocation())) { 112 | return false; 113 | } 114 | 115 | this.toRegen.put(state.getLocation(), state); 116 | 117 | BlockRegen regenTask = new BlockRegen(state.getLocation(), state); 118 | regenTask.runTaskLater(plugin, ticksLater); 119 | 120 | return tasks.add(regenTask); 121 | } 122 | 123 | /** 124 | * Does the event task for you, just pass the {@link BlockBreakEvent} to 125 | * this 126 | * 127 | * @param event 128 | * @param ticksLater 129 | */ 130 | public void onBlockBreak(BlockBreakEvent event, long ticksLater) { 131 | request(event.getBlock(), ticksLater); 132 | } 133 | 134 | /** 135 | * Does the event task for you, just pass the {@link BlockPlaceEvent} to 136 | * this 137 | * 138 | * @param event 139 | * @param ticksLater 140 | */ 141 | public void onBlockPlace(BlockPlaceEvent event, long ticksLater) { 142 | request(event.getBlockReplacedState(), ticksLater); 143 | } 144 | 145 | /** 146 | * BlockRegen 147 | * 148 | * The Regeneration task that is scheduled whenever a regen is requested 149 | */ 150 | public class BlockRegen extends BukkitRunnable { 151 | 152 | private final BlockState state; 153 | private final Location location; 154 | private boolean hasRun = false; 155 | 156 | protected BlockRegen(Location location, BlockState state) { 157 | this.state = state; 158 | this.location = location; 159 | } 160 | 161 | public Location getLocation() { 162 | return location; 163 | } 164 | 165 | public BlockState getState() { 166 | return state; 167 | } 168 | 169 | @Override 170 | public void cancel() { 171 | if (!hasRun) { 172 | run(); 173 | } 174 | 175 | super.cancel(); 176 | } 177 | 178 | @Override 179 | public void run() { 180 | getLocation().getBlock().setType(getState().getType()); 181 | getLocation().getBlock().setData(getState().getBlock().getData()); 182 | 183 | finish(); 184 | } 185 | 186 | public void finish() { 187 | this.hasRun = true; 188 | if (toRegen.containsKey(getLocation())) { 189 | toRegen.remove(getLocation()); 190 | } 191 | 192 | if (tasks.contains(this)) { 193 | tasks.remove(this); 194 | } 195 | } 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /src/main/java/command/AbstractCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2013 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package command; 26 | 27 | import java.lang.reflect.Field; 28 | import java.util.List; 29 | 30 | import org.bukkit.Bukkit; 31 | import org.bukkit.command.Command; 32 | import org.bukkit.command.CommandExecutor; 33 | import org.bukkit.command.CommandMap; 34 | import org.bukkit.command.CommandSender; 35 | import org.bukkit.command.TabExecutor; 36 | 37 | /** 38 | * For a How-To on how to use AbstractCommand see this post @ http://forums.bukkit.org/threads/195990/ 39 | * 40 | * @author Goblom 41 | */ 42 | public abstract class AbstractCommand implements CommandExecutor, TabExecutor { 43 | 44 | protected final String command; 45 | protected final String description; 46 | protected final List alias; 47 | protected final String usage; 48 | protected final String permMessage; 49 | 50 | protected static CommandMap cmap; 51 | 52 | public AbstractCommand(String command) { 53 | this(command, null, null, null, null); 54 | } 55 | 56 | public AbstractCommand(String command, String usage) { 57 | this(command, usage, null, null, null); 58 | } 59 | 60 | public AbstractCommand(String command, String usage, String description) { 61 | this(command, usage, description, null, null); 62 | } 63 | 64 | public AbstractCommand(String command, String usage, String description, String permissionMessage) { 65 | this(command, usage, description, permissionMessage, null); 66 | } 67 | 68 | public AbstractCommand(String command, String usage, String description, List aliases) { 69 | this(command, usage, description, null, aliases); 70 | } 71 | 72 | public AbstractCommand(String command, String usage, String description, String permissionMessage, List aliases) { 73 | this.command = command.toLowerCase(); 74 | this.usage = usage; 75 | this.description = description; 76 | this.permMessage = permissionMessage; 77 | this.alias = aliases; 78 | } 79 | 80 | public void register() { 81 | ReflectCommand cmd = new ReflectCommand(this.command); 82 | if (this.alias != null) cmd.setAliases(this.alias); 83 | if (this.description != null) cmd.setDescription(this.description); 84 | if (this.usage != null) cmd.setUsage(this.usage); 85 | if (this.permMessage != null) cmd.setPermissionMessage(this.permMessage); 86 | getCommandMap().register("", cmd); 87 | cmd.setExecutor(this); 88 | } 89 | 90 | final CommandMap getCommandMap() { 91 | if (cmap == null) { 92 | try { 93 | final Field f = Bukkit.getServer().getClass().getDeclaredField("commandMap"); 94 | f.setAccessible(true); 95 | cmap = (CommandMap) f.get(Bukkit.getServer()); 96 | return getCommandMap(); 97 | } catch (Exception e) { e.printStackTrace(); } 98 | } else if (cmap != null) { return cmap; } 99 | return getCommandMap(); 100 | } 101 | 102 | private final class ReflectCommand extends Command { 103 | private AbstractCommand exe = null; 104 | protected ReflectCommand(String command) { super(command); } 105 | public void setExecutor(AbstractCommand exe) { this.exe = exe; } 106 | @Override public boolean execute(CommandSender sender, String commandLabel, String[] args) { 107 | if (exe != null) { return exe.onCommand(sender, this, commandLabel, args); } 108 | return false; 109 | } 110 | 111 | @Override public List tabComplete(CommandSender sender, String alais, String[] args) { 112 | if (exe != null) { return exe.onTabComplete(sender, this, alais, args); } 113 | return null; 114 | } 115 | } 116 | 117 | public abstract boolean onCommand(CommandSender sender, Command cmd, String label, String[] args); 118 | 119 | public List onTabComplete(CommandSender sender, Command cmd, String label, String[] args) { 120 | return null; 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/main/java/command/AnnotationCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2014 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package command; 25 | 26 | import com.google.common.collect.Maps; 27 | import static command.AbstractCommand.cmap; 28 | import command.AnnotationCommand.Annotations.AnonCommand; 29 | import command.AnnotationCommand.Annotations.AnonCommandFull; 30 | import command.AnnotationCommand.Annotations.AnonDescription; 31 | import command.AnnotationCommand.Annotations.AnonPermission; 32 | import command.AnnotationCommand.Annotations.AnonPermissionMessage; 33 | import command.AnnotationCommand.Annotations.AnonUsage; 34 | import java.lang.annotation.ElementType; 35 | import java.lang.annotation.Retention; 36 | import java.lang.annotation.RetentionPolicy; 37 | import java.lang.annotation.Target; 38 | import java.lang.reflect.Field; 39 | import java.lang.reflect.Method; 40 | import java.util.Map; 41 | import org.bukkit.Bukkit; 42 | import org.bukkit.command.Command; 43 | import org.bukkit.command.CommandExecutor; 44 | import org.bukkit.command.CommandMap; 45 | import org.bukkit.command.CommandSender; 46 | 47 | /** 48 | * 49 | * @author Goblom 50 | */ 51 | public class AnnotationCommand { 52 | 53 | protected static final String PERMISSION_MESSAGE = "&cI'm sorry, but you do not have permission to perform this command. Please contact the server administrators if you believe that this is an error."; 54 | 55 | private static CommandMap COMMAND_MAP; 56 | 57 | static { 58 | try { 59 | final Field f = Bukkit.getServer().getClass().getDeclaredField("commandMap"); 60 | f.setAccessible(true); 61 | cmap = (CommandMap) f.get(Bukkit.getServer()); 62 | } catch (Exception e) { 63 | System.out.println("ERRORS WILL STRIKE EVERYWHERE"); 64 | e.printStackTrace(); 65 | } 66 | } 67 | 68 | public static void registerListener(CommandListener listener) { 69 | for (Method method : listener.getClass().getMethods()) { 70 | AnonCommandFull full = method.getAnnotation(AnonCommandFull.class); 71 | 72 | if (full != null) { 73 | registerCommand(method, listener, full.command(), full.description(), full.usage(), full.permission(), full.permissionMessage()); 74 | } else { 75 | AnonCommand command = method.getAnnotation(AnonCommand.class); 76 | AnonDescription description = method.getAnnotation(AnonDescription.class); 77 | AnonUsage usage = method.getAnnotation(AnonUsage.class); 78 | AnonPermission permission = method.getAnnotation(AnonPermission.class); 79 | AnonPermissionMessage permissionMessage = method.getAnnotation(AnonPermissionMessage.class); 80 | 81 | if (command == null) return; 82 | String desc = (description == null ? "Command handled by AnonCommand" : description.value()); 83 | String us = (usage == null ? "" : usage.value()); 84 | String perm = (permission == null ? "" : permission.value()); 85 | String permMessage = (permissionMessage == null ? PERMISSION_MESSAGE : permissionMessage.value()); 86 | 87 | registerCommand(method, listener, command.value(), desc, us, perm, permMessage); 88 | } 89 | } 90 | } 91 | 92 | private static void registerCommand(Method method, CommandListener listener, String command, String description, String usage, String permission, String permissionMessage) { 93 | ReflectCommand cmd = new ReflectCommand(new CommandData(method, listener, command)); 94 | cmd.setUsage(usage); 95 | cmd.setDescription(description); 96 | cmd.setPermission(permission); 97 | cmd.setPermissionMessage(permissionMessage); 98 | 99 | COMMAND_MAP.register("", cmd); 100 | } 101 | 102 | public static interface CommandListener { } 103 | 104 | public static class CommandEvent { 105 | 106 | public final CommandSender sender; 107 | public final Command command; 108 | public final String[] args; 109 | 110 | private CommandEvent(CommandSender sender, Command command, String[] args) { 111 | this.sender = sender; 112 | this.args = args; 113 | this.command = command; 114 | } 115 | 116 | public String getArg(int index) { 117 | return args[index]; 118 | } 119 | 120 | public boolean isNumerical(String str) { 121 | try { 122 | Integer.parseInt(str); 123 | return true; 124 | } catch (Exception e) { 125 | return false; 126 | } 127 | } 128 | } 129 | 130 | public static class Annotations { 131 | 132 | @Target(ElementType.METHOD) 133 | @Retention(RetentionPolicy.RUNTIME) 134 | public static @interface AnonCommand { 135 | public String value(); 136 | } 137 | 138 | @Target(ElementType.METHOD) 139 | @Retention(RetentionPolicy.RUNTIME) 140 | public static @interface AnonDescription { 141 | public String value(); 142 | } 143 | 144 | @Target(ElementType.METHOD) 145 | @Retention(RetentionPolicy.RUNTIME) 146 | public static @interface AnonUsage { 147 | public String value(); 148 | } 149 | 150 | @Target(ElementType.METHOD) 151 | @Retention(RetentionPolicy.RUNTIME) 152 | public static @interface AnonPermission { 153 | public String value(); 154 | } 155 | 156 | @Target(ElementType.METHOD) 157 | @Retention(RetentionPolicy.RUNTIME) 158 | public static @interface AnonPermissionMessage { 159 | public String value(); 160 | } 161 | 162 | @Target(ElementType.METHOD) 163 | @Retention(RetentionPolicy.RUNTIME) 164 | public static @interface AnonCommandFull { 165 | 166 | public String command(); 167 | 168 | public String description() default "Command handled by AnonCommand"; 169 | 170 | public String usage() default ""; 171 | 172 | public String permission() default ""; 173 | 174 | public String permissionMessage() default PERMISSION_MESSAGE; 175 | } 176 | } 177 | 178 | private static class CommandData implements CommandExecutor { 179 | private Method method; 180 | private CommandListener listener; 181 | private String command; 182 | 183 | private CommandData(Method method, CommandListener listener, String command) { 184 | this.method = method; 185 | this.listener = listener; 186 | this.command = command; 187 | } 188 | 189 | public String getCommand() { 190 | return this.command; 191 | } 192 | 193 | public Method getMethod() { 194 | return this.method; 195 | } 196 | 197 | public CommandListener getListener() { 198 | return this.listener; 199 | } 200 | @Override 201 | public int hashCode() { 202 | return (method.getName() + listener.getClass().getCanonicalName()).hashCode(); 203 | } 204 | 205 | @Override 206 | public boolean equals(Object obj) { 207 | if (obj instanceof CommandData) { 208 | return this.hashCode() == obj.hashCode(); 209 | } 210 | 211 | return false; 212 | } 213 | 214 | @Override 215 | public String toString() { 216 | return listener.getClass().getCanonicalName() + ":" + method.getName(); 217 | } 218 | 219 | public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { 220 | try { 221 | getMethod().invoke(getListener(), new CommandEvent(sender, command, args)); 222 | } catch (Exception e) { 223 | e.printStackTrace(); 224 | } 225 | 226 | return true; 227 | } 228 | } 229 | 230 | private static class ReflectCommand extends Command { 231 | private CommandData data; 232 | 233 | private ReflectCommand(CommandData data) { 234 | super(data.getCommand()); 235 | this.data = data; 236 | } 237 | @Override 238 | public boolean execute(CommandSender sender, String commandLabel, String[] args) { 239 | return data.onCommand(sender, this, commandLabel, args); 240 | } 241 | 242 | } 243 | } 244 | -------------------------------------------------------------------------------- /src/main/java/command/CommandRegistrationFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2014 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package command; 25 | 26 | import java.lang.reflect.Field; 27 | import java.util.Arrays; 28 | import java.util.List; 29 | import org.bukkit.Bukkit; 30 | import org.bukkit.ChatColor; 31 | import org.bukkit.command.Command; 32 | import org.bukkit.command.CommandExecutor; 33 | import org.bukkit.command.CommandMap; 34 | import org.bukkit.command.CommandSender; 35 | import org.bukkit.command.TabCompleter; 36 | import org.bukkit.command.TabExecutor; 37 | import org.bukkit.plugin.Plugin; 38 | 39 | /** 40 | * TODO: 41 | * Write documentation 42 | * 43 | * @author Goblom 44 | */ 45 | public class CommandRegistrationFactory { 46 | 47 | private static CommandMap cmap; 48 | 49 | private String commandLabel; 50 | private String description; 51 | private List aliases; 52 | private String usage; 53 | private String permission; 54 | private String permissionMessage; 55 | private String fromPlugin; 56 | private CommandExecutor commandExecutor; 57 | private TabExecutor tabExecutor; 58 | 59 | public CommandRegistrationFactory(String command) { 60 | this.commandLabel = command; 61 | } 62 | 63 | public void build() { 64 | register(); 65 | } 66 | 67 | public CommandRegistrationFactory withCommandExecutor(CommandExecutor exec) { 68 | this.commandExecutor = exec; 69 | return this; 70 | } 71 | 72 | public CommandRegistrationFactory withPlugin(Plugin plugin) { 73 | this.fromPlugin = plugin.getName(); 74 | return this; 75 | } 76 | 77 | public CommandRegistrationFactory withPermissionMessage(String message) { 78 | this.permissionMessage = ChatColor.translateAlternateColorCodes('&', message); 79 | return this; 80 | } 81 | 82 | public CommandRegistrationFactory withPermission(String permission) { 83 | this.permission = permission; 84 | return this; 85 | } 86 | 87 | public CommandRegistrationFactory withUsage(String usage) { 88 | this.usage = usage; 89 | return this; 90 | } 91 | 92 | public CommandRegistrationFactory withAliases(String... aliases) { 93 | this.aliases = Arrays.asList(aliases); 94 | return this; 95 | } 96 | 97 | public CommandRegistrationFactory withDescription(String description) { 98 | this.description = description; 99 | return this; 100 | } 101 | 102 | public CommandRegistrationFactory withTabExecutor(TabExecutor tab) { 103 | this.tabExecutor = tab; 104 | return this; 105 | } 106 | 107 | public void register() { 108 | ReflectCommand command; 109 | if (this.commandLabel != null && !this.commandLabel.isEmpty()) { 110 | command = new ReflectCommand(this.commandLabel); 111 | } else { 112 | throw new CommandNotPreparedException("Command does not have a name."); 113 | } 114 | 115 | if (this.commandExecutor == null) { 116 | throw new CommandNotPreparedException(this.commandLabel + " does not have an executor."); 117 | } 118 | 119 | if (this.aliases != null) { 120 | command.setAliases(this.aliases); 121 | } 122 | 123 | if (this.description != null) { 124 | command.setDescription(this.description); 125 | } 126 | 127 | if (this.permission != null) { 128 | command.setPermission(this.permission); 129 | } 130 | 131 | if (this.permissionMessage != null) { 132 | command.setPermissionMessage(this.permissionMessage); 133 | } 134 | 135 | if (this.usage != null) { 136 | command.setUsage(this.usage); 137 | } 138 | 139 | if (this.tabExecutor != null) { 140 | command.setTabExecutor(this.tabExecutor); 141 | } 142 | 143 | getCommandMap().register((this.fromPlugin != null ? this.fromPlugin : ""), command); 144 | command.setExecutor(this.commandExecutor); 145 | } 146 | 147 | private final CommandMap getCommandMap() { 148 | if (cmap == null) { 149 | try { 150 | final Field f = Bukkit.getServer().getClass().getDeclaredField("commandMap"); 151 | f.setAccessible(true); 152 | cmap = (CommandMap) f.get(Bukkit.getServer()); 153 | return getCommandMap(); 154 | } catch (Exception e) { 155 | e.printStackTrace(); 156 | } 157 | } else if (cmap != null) { 158 | return cmap; 159 | } 160 | return getCommandMap(); 161 | } 162 | 163 | private final class ReflectCommand extends Command { 164 | 165 | private CommandExecutor exe = null; 166 | private TabExecutor tab = null; 167 | 168 | protected ReflectCommand(String command) { 169 | super(command); 170 | } 171 | 172 | private void setExecutor(CommandExecutor exe) { 173 | this.exe = exe; 174 | } 175 | 176 | private void setTabExecutor(TabExecutor tab) { 177 | this.tab = tab; 178 | } 179 | 180 | @Override 181 | public boolean execute(CommandSender sender, String commandLabel, String[] args) { 182 | if (exe != null) { 183 | return exe.onCommand(sender, this, commandLabel, args); 184 | } 185 | return false; 186 | } 187 | 188 | @Override 189 | public List tabComplete(CommandSender sender, String commandLabel, String[] args) { 190 | if (tab != null) { 191 | return tab.onTabComplete(sender, this, usage, args); 192 | } 193 | return null; 194 | } 195 | } 196 | 197 | public class CommandNotPreparedException extends RuntimeException { 198 | 199 | public CommandNotPreparedException(String message) { 200 | super(message); 201 | } 202 | } 203 | 204 | public static CommandRegistrationFactory buildCommand(String command) { 205 | return new CommandRegistrationFactory(command); 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /src/main/java/command/Commander.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2014 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package command; 26 | 27 | import com.google.common.collect.Lists; 28 | import java.util.Collections; 29 | import java.util.List; 30 | import org.bukkit.command.CommandSender; 31 | 32 | /** 33 | * 34 | * @author Goblom 35 | */ 36 | public class Commander { 37 | 38 | private static List commands = Lists.newArrayList(); 39 | 40 | public static SubCommand getSubCommand(String name) { 41 | for (SubCommand cmd : commands) { 42 | for (String alias : cmd.getAliases()) { 43 | if (alias.equalsIgnoreCase(name)) { 44 | return cmd; 45 | } 46 | } 47 | } 48 | 49 | return null; 50 | } 51 | 52 | public static void handle(CommandSender sender, String[] args, int subCommandIndex, String... failedMessage) { 53 | try { 54 | SubCommand cmd = getSubCommand(args[subCommandIndex]); 55 | cmd.handle(sender, args); 56 | } catch (Exception e) { 57 | sender.sendMessage(failedMessage); 58 | } 59 | } 60 | 61 | public static void registerSubCommand(SubCommand cmd) { 62 | commands.add(cmd); 63 | } 64 | 65 | public static void registerSubCommand(List alias, String description, final CommandHandler handler) { 66 | registerSubCommand(new SubCommand(alias, description) { 67 | 68 | @Override 69 | public void handle(CommandSender sender, String[] args) { 70 | handler.handle(sender, args); 71 | } 72 | }); 73 | } 74 | 75 | public static List getRegisteredCommands() { 76 | return Collections.unmodifiableList(commands); 77 | } 78 | 79 | public static abstract class SubCommand implements CommandHandler { 80 | private final List alias; 81 | private final String description; 82 | 83 | public SubCommand(List alias, String description) { 84 | this.alias = alias; 85 | this.description = description; 86 | } 87 | 88 | public List getAliases() { 89 | return this.alias; 90 | } 91 | 92 | public String getDescription() { 93 | return this.description; 94 | } 95 | } 96 | 97 | public interface CommandHandler { 98 | public void handle(CommandSender sender, String[] args); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/main/java/configuration/Config.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2014 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package configuration; 26 | 27 | import java.io.File; 28 | import org.bukkit.configuration.file.FileConfiguration; 29 | import org.bukkit.configuration.file.YamlConfiguration; 30 | import org.bukkit.plugin.Plugin; 31 | 32 | /** 33 | * 34 | * @author Goblom 35 | */ 36 | public class Config { 37 | private final Plugin plugin; 38 | private final File file; 39 | private FileConfiguration config; 40 | 41 | public Config(Plugin plugin, String file) { 42 | this.plugin = plugin; 43 | this.file = new File(plugin.getDataFolder(), (file.endsWith(".yml") ? file : file + ".yml")); 44 | 45 | if (!this.file.exists()) { 46 | try { 47 | this.file.createNewFile(); 48 | } catch (Exception e) { 49 | e.printStackTrace(); 50 | } 51 | } 52 | 53 | this.config = YamlConfiguration.loadConfiguration(this.file); 54 | } 55 | 56 | public FileConfiguration getFileConfiguration() { 57 | return this.config; 58 | } 59 | 60 | public File getFile() { 61 | return this.file; 62 | } 63 | 64 | public void set(String path, Object value) { 65 | set(path, value, false); 66 | } 67 | 68 | public void set(String path, Object value, boolean save) { 69 | this.config.set(path, value); 70 | 71 | if (save) { 72 | save(); 73 | } 74 | } 75 | 76 | public T get(String path, T def) { 77 | if (!contains(path)) { 78 | set(path, def, true); 79 | } 80 | 81 | return (T) this.config.get(path); 82 | } 83 | 84 | public void save() { 85 | try { 86 | this.config.save(getFile()); 87 | } catch (Exception e) { 88 | e.printStackTrace(); 89 | } 90 | } 91 | 92 | public void reload() { 93 | this.config = YamlConfiguration.loadConfiguration(file); 94 | } 95 | 96 | public boolean contains(String path) { 97 | return this.config.contains(path); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/configuration/ConfigManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2013 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package configuration; 25 | 26 | import java.io.File; 27 | import java.util.HashMap; 28 | import java.util.Map; 29 | import org.bukkit.configuration.file.FileConfiguration; 30 | import org.bukkit.configuration.file.YamlConfiguration; 31 | import org.bukkit.plugin.Plugin; 32 | import org.bukkit.plugin.java.JavaPlugin; 33 | 34 | /** 35 | * Config Manager v1 36 | * 37 | * Easily Create, Load and get data from files in your plugins folder. Supports 38 | * only YAML configuration files, can hold as many configurations as you want. 39 | * 40 | * @author Goblom 41 | */ 42 | public class ConfigManager { 43 | 44 | private static final Plugin PLUGIN = JavaPlugin.getProvidingPlugin(ConfigManager.class); 45 | private static Map configs = new HashMap(); 46 | 47 | /** 48 | * Checks to see if the ConfigManager knows about fileName 49 | * 50 | * @param fileName file to check 51 | * @return true if file is loaded, false if not 52 | */ 53 | public static boolean isFileLoaded(String fileName) { 54 | return configs.containsKey(fileName); 55 | } 56 | 57 | /** 58 | * Loads a files configuration into Memory 59 | * 60 | * @param plugin Plugin to load file from if fileName does not exist in 61 | * Plugins folder 62 | * @param fileName File to load 63 | */ 64 | public static void load(String fileName) { 65 | File file = new File(PLUGIN.getDataFolder(), fileName); 66 | if (!file.exists()) { 67 | try { 68 | PLUGIN.saveResource(fileName, false); 69 | } catch (Exception e) { 70 | e.printStackTrace(); 71 | } 72 | } 73 | if (!isFileLoaded(fileName)) { 74 | configs.put(fileName, YamlConfiguration.loadConfiguration(file)); 75 | } 76 | } 77 | 78 | /** 79 | * Gets the FileConfiguration for a specified file 80 | * 81 | * @param fileName File to load data from 82 | * @return File Configuration 83 | */ 84 | public static FileConfiguration get(String fileName) { 85 | if (isFileLoaded(fileName)) { 86 | return configs.get(fileName); 87 | } 88 | return null; 89 | } 90 | 91 | /** 92 | * Updates the FileConfiguration at the given path. If path already exists 93 | * this will return false. 94 | * 95 | * @param fileName File to update 96 | * @param path Path to update 97 | * @param value Data to set at path 98 | * @return True if successful, otherwise false 99 | */ 100 | public static boolean update(String fileName, String path, Object value) { 101 | if (isFileLoaded(fileName)) { 102 | if (!configs.get(fileName).contains(path)) { 103 | configs.get(fileName).set(path, value); 104 | return true; 105 | } 106 | } 107 | return false; 108 | } 109 | 110 | /** 111 | * Sets data at any given path. If path already exists it will be over 112 | * written. 113 | * 114 | * @param fileName File to update 115 | * @param path Path to set 116 | * @param value Data to set at path 117 | */ 118 | public static void set(String fileName, String path, Object value) { 119 | if (isFileLoaded(fileName)) { 120 | configs.get(fileName).set(path, value); 121 | } 122 | } 123 | 124 | /** 125 | * Create YAML Comments at the given path 126 | * 127 | * @param fileName File to add comments to 128 | * @param path Path to add comments too 129 | * @param comments Comments to add 130 | * 131 | * @deprecated Not Tested/Experimental 132 | */ 133 | public void addComment(String fileName, String path, String... comments) { 134 | if (isFileLoaded(fileName)) { 135 | for (String comment : comments) { 136 | if (!configs.get(fileName).contains(path)) { 137 | configs.get(fileName).set("_COMMENT_" + comments.length, " " + comment); 138 | } 139 | } 140 | } 141 | } 142 | 143 | /** 144 | * Removes a path from the FileConfiguration. 145 | * 146 | * @param fileName File to update 147 | * @param path Path to remove 148 | */ 149 | public static void remove(String fileName, String path) { 150 | if (isFileLoaded(fileName)) { 151 | configs.get(fileName).set(path, null); 152 | } 153 | } 154 | 155 | /** 156 | * Checks if a file has a path. 157 | * 158 | * @param fileName File to check 159 | * @param path Path to check 160 | * @return True if path exists, otherwise false. 161 | */ 162 | public static boolean contains(String fileName, String path) { 163 | if (isFileLoaded(fileName)) { 164 | return configs.get(fileName).contains(path); 165 | } 166 | return false; 167 | } 168 | 169 | /** 170 | * Reload the config from the given Plugin. 171 | * 172 | * @param plugin Plugin to get the File from 173 | * @param fileName File to reload 174 | */ 175 | public static void reload(String fileName) { 176 | File file = new File(PLUGIN.getDataFolder(), fileName); 177 | if (isFileLoaded(fileName)) { 178 | try { 179 | configs.get(fileName).load(file); 180 | } catch (Exception e) { 181 | e.printStackTrace(); 182 | } 183 | } 184 | } 185 | 186 | /** 187 | * Save the config for the given plugin 188 | * 189 | * @param plugin Plugin dir to save to the file to 190 | * @param fileName File to save 191 | */ 192 | public static void save(String fileName) { 193 | File file = new File(PLUGIN.getDataFolder(), fileName); 194 | if (isFileLoaded(fileName)) { 195 | try { 196 | configs.get(fileName).save(file); 197 | } catch (Exception e) { 198 | e.printStackTrace(); 199 | } 200 | } 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /src/main/java/configuration/LocationParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2013 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package configuration; 26 | 27 | import java.util.ArrayList; 28 | import java.util.List; 29 | import org.bukkit.Bukkit; 30 | import org.bukkit.Location; 31 | import org.bukkit.configuration.file.FileConfiguration; 32 | 33 | /** 34 | * 35 | * @author Goblom 36 | */ 37 | public class LocationParser { 38 | private final FileConfiguration config; 39 | 40 | public LocationParser(FileConfiguration config) { 41 | this.config = config; 42 | } 43 | 44 | 45 | public Location getFromString(String path, String splitBy, boolean yawPitch) { 46 | String[] parse = config.getString(path).split(splitBy); 47 | if (!yawPitch) { 48 | return new Location(Bukkit.getWorld(parse[0]), Double.valueOf(parse[1]), Double.valueOf(parse[2]), Double.valueOf(parse[3])); 49 | } else return new Location(Bukkit.getWorld(parse[0]), Double.valueOf(parse[1]), Double.valueOf(parse[2]), Double.valueOf(parse[3]), Float.valueOf(parse[4]), Float.valueOf(parse[5])); 50 | } 51 | 52 | public String convertToString(Location loc, String splitBy, boolean yawPitch) { 53 | String world = loc.getWorld().getName(); 54 | double x = loc.getX(); 55 | double y = loc.getY(); 56 | double z = loc.getZ(); 57 | float yaw = loc.getYaw(); 58 | float pitch = loc.getPitch(); 59 | 60 | if (!yawPitch) { 61 | return world + splitBy + x + splitBy + y + splitBy + z; 62 | } else return world + splitBy + x + splitBy + y + splitBy + z + splitBy + yaw + splitBy + pitch; 63 | } 64 | 65 | public boolean isInside(Location checkInside, Location corner1, Location corner2) { 66 | int x1 = Math.min(corner1.getBlockX(), corner2.getBlockX()); 67 | int y1 = Math.min(corner1.getBlockY(), corner2.getBlockY()); 68 | int z1 = Math.min(corner1.getBlockZ(), corner2.getBlockZ()); 69 | int x2 = Math.max(corner1.getBlockX(), corner2.getBlockX()); 70 | int y2 = Math.max(corner1.getBlockY(), corner2.getBlockY()); 71 | int z2 = Math.max(corner1.getBlockZ(), corner2.getBlockZ()); 72 | 73 | return checkInside.getBlockX() >= x1 && checkInside.getBlockX() <= x2 && 74 | checkInside.getBlockY() >= y1 && checkInside.getBlockY() <= y2 && 75 | checkInside.getBlockZ() >= z1 && checkInside.getBlockZ() <= z2; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/database/SimpleEbean.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2014 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package database; 25 | 26 | import com.avaje.ebean.EbeanServer; 27 | import com.avaje.ebean.EbeanServerFactory; 28 | import com.avaje.ebean.config.DataSourceConfig; 29 | import com.avaje.ebean.config.ServerConfig; 30 | import com.avaje.ebean.config.dbplatform.SQLitePlatform; 31 | import com.avaje.ebeaninternal.api.SpiEbeanServer; 32 | import com.avaje.ebeaninternal.server.ddl.DdlGenerator; 33 | import com.avaje.ebeaninternal.server.lib.sql.TransactionIsolation; 34 | import java.io.BufferedReader; 35 | import java.io.StringReader; 36 | import java.lang.reflect.Field; 37 | import java.lang.reflect.Method; 38 | import java.net.URLConnection; 39 | import java.util.ArrayList; 40 | import java.util.HashMap; 41 | import java.util.List; 42 | import java.util.logging.Level; 43 | import java.util.logging.Logger; 44 | import javax.persistence.Column; 45 | import javax.persistence.Entity; 46 | import javax.persistence.GeneratedValue; 47 | import javax.persistence.GenerationType; 48 | import javax.persistence.Id; 49 | import javax.persistence.Table; 50 | import org.bukkit.Bukkit; 51 | import org.bukkit.configuration.file.FileConfiguration; 52 | import org.bukkit.plugin.Plugin; 53 | import org.bukkit.plugin.java.JavaPlugin; 54 | 55 | /** 56 | * 57 | * @author Goblom 58 | */ 59 | public class SimpleEbean { 60 | 61 | private JavaPlugin plugin; 62 | private ClassLoader classLoader; 63 | private Level loggerLevel; 64 | private boolean usingSQLite; 65 | private ServerConfig serverConfig; 66 | private EbeanServer ebeanServer; 67 | private List> databaseClasses; 68 | 69 | public SimpleEbean(JavaPlugin plugin) { 70 | this(plugin, true); 71 | } 72 | 73 | public SimpleEbean(JavaPlugin plugin, boolean loadDefaults) { 74 | this.plugin = plugin; 75 | try { 76 | Method getClassLoader = JavaPlugin.class.getDeclaredMethod("getClassLoader"); 77 | getClassLoader.setAccessible(true); 78 | 79 | this.classLoader = (ClassLoader) getClassLoader.invoke(plugin); 80 | } catch (Exception e) { 81 | throw new RuntimeException("Failed to retrieve the ClassLoader of the plugin using Reflection", e); 82 | } 83 | 84 | if (loadDefaults) { 85 | FileConfiguration config = plugin.getConfig(); 86 | config.addDefault("Database.Driver", "com.mysql.jdbc.Driver"); 87 | config.addDefault("Database.Name", plugin.getName().replace(" ", "_")); 88 | config.addDefault("Database.Host", "jdbc:mysql://localhost:3306"); 89 | config.addDefault("Database.User", "root"); 90 | config.addDefault("Database.Password", ""); 91 | config.addDefault("Database.Isolation", "TRANSACTION_SERIALIZABLE"); 92 | config.addDefault("Database.Logging", false); 93 | config.addDefault("Database.Rebuild", false); 94 | config.options().copyDefaults(true); 95 | plugin.saveConfig(); 96 | } 97 | } 98 | 99 | public void load(List> databaseClasses) { 100 | String driver = plugin.getConfig().getString("Database.Driver"); 101 | String name = plugin.getConfig().getString("Database.Name"); 102 | String host = plugin.getConfig().getString("Database.Host"); 103 | String user = plugin.getConfig().getString("Database.User"); 104 | String password = plugin.getConfig().getString("Database.Password"); 105 | String isolation = plugin.getConfig().getString("Database.Isolation"); 106 | boolean logging = plugin.getConfig().getBoolean("Database.Logging"); 107 | boolean rebuild = plugin.getConfig().getBoolean("Database.Rebuild"); 108 | 109 | load(driver, name, host, user, password, isolation, logging, rebuild, databaseClasses); 110 | } 111 | 112 | public void load(String driver, String database, String host, String user, String password, String isolation, boolean logging, boolean rebuild, List> classes) { 113 | this.databaseClasses = classes; 114 | initializeDatabase(driver, host + "/" + database, user, password, isolation, logging, rebuild); 115 | } 116 | 117 | /** 118 | * Initialize the database using the passed arguments 119 | * 120 | * @param driver Database-driver to use. For example: org.sqlite.JDBC 121 | * @param url Location of the database. For example: 122 | * jdbc:sqlite:{DIR}{NAME}.db 123 | * @param username Username required to access the database 124 | * @param password Password belonging to the username, may be empty 125 | * @param isolation Isolation type. For example: SERIALIZABLE, also see 126 | * TransactionIsolation 127 | * @param logging If set to false, all logging will be disabled 128 | * @param rebuild If set to true, all tables will be dropped and recreated. 129 | * 130 | * Be sure to create a backup before doing so! 131 | */ 132 | public void initializeDatabase(String driver, String url, String username, String password, String isolation, boolean logging, boolean rebuild) { 133 | // Logging needs to be set back to the original level, no matter what 134 | // happens 135 | try { 136 | // Disable all logging 137 | disableDatabaseLogging(logging); 138 | 139 | // Prepare the database 140 | prepareDatabase(driver, url, username, password, isolation); 141 | 142 | // Load the database 143 | loadDatabase(); 144 | 145 | // Create all tables 146 | installDatabase(rebuild); 147 | } catch (Exception ex) { 148 | throw new RuntimeException("An exception has occured while initializing the database", ex); 149 | } finally { 150 | // Enable all logging 151 | enableDatabaseLogging(logging); 152 | } 153 | } 154 | 155 | private void disableDatabaseLogging(boolean logging) { 156 | // If logging is allowed, nothing has to be changed 157 | if (logging) { 158 | return; 159 | } 160 | 161 | // Retrieve the level of the root logger 162 | loggerLevel = Logger.getLogger("").getLevel(); 163 | 164 | // Set the level of the root logger to OFF 165 | Logger.getLogger("").setLevel(Level.OFF); 166 | } 167 | 168 | private void prepareDatabase(String driver, String url, String username, String password, String isolation) { 169 | // Setup the data source 170 | DataSourceConfig ds = new DataSourceConfig(); 171 | ds.setDriver(driver); 172 | ds.setUrl(replaceDatabaseString(url)); 173 | ds.setUsername(username); 174 | ds.setPassword(password); 175 | ds.setIsolationLevel(TransactionIsolation.getLevel(isolation)); 176 | 177 | // Setup the server configuration 178 | ServerConfig sc = new ServerConfig(); 179 | sc.setDefaultServer(false); 180 | sc.setRegister(false); 181 | sc.setName(ds.getUrl().replaceAll("[^a-zA-Z0-9]", "")); 182 | 183 | // Get all persistent classes 184 | List> classes = getDatabaseClasses(); 185 | 186 | // Do a sanity check first 187 | if (classes.size() == 0) { 188 | // Exception: There is no use in continuing to load this database 189 | throw new RuntimeException("Database has been enabled, but no classes are registered to it"); 190 | } 191 | 192 | // Register them with the EbeanServer 193 | sc.setClasses(classes); 194 | 195 | // Check if the SQLite JDBC supplied with Bukkit is being used 196 | if (ds.getDriver().equalsIgnoreCase("org.sqlite.JDBC")) { 197 | // Remember the database is a SQLite-database 198 | usingSQLite = true; 199 | 200 | // Modify the platform, as SQLite has no AUTO_INCREMENT field 201 | sc.setDatabasePlatform(new SQLitePlatform()); 202 | sc.getDatabasePlatform().getDbDdlSyntax().setIdentity(""); 203 | } 204 | 205 | prepareDatabaseAdditionalConfig(ds, sc); 206 | 207 | // Finally the data source 208 | sc.setDataSourceConfig(ds); 209 | 210 | // Store the ServerConfig 211 | serverConfig = sc; 212 | } 213 | 214 | private void loadDatabase() { 215 | // Declare a few local variables for later use 216 | ClassLoader currentClassLoader = null; 217 | Field cacheField = null; 218 | boolean cacheValue = true; 219 | 220 | try { 221 | // Store the current ClassLoader, so it can be reverted later 222 | currentClassLoader = Thread.currentThread().getContextClassLoader(); 223 | 224 | // Set the ClassLoader to Plugin ClassLoader 225 | Thread.currentThread().setContextClassLoader(classLoader); 226 | 227 | // Get a reference to the private static "defaultUseCaches"-field in 228 | // URLConnection 229 | cacheField = URLConnection.class.getDeclaredField("defaultUseCaches"); 230 | 231 | // Make it accessible, store the default value and set it to false 232 | cacheField.setAccessible(true); 233 | cacheValue = cacheField.getBoolean(null); 234 | cacheField.setBoolean(null, false); 235 | 236 | // Setup Ebean based on the configuration 237 | ebeanServer = EbeanServerFactory.create(serverConfig); 238 | } catch (Exception ex) { 239 | throw new RuntimeException("Failed to create a new instance of the EbeanServer", ex); 240 | } finally { 241 | // Revert the ClassLoader back to its original value 242 | if (currentClassLoader != null) { 243 | Thread.currentThread().setContextClassLoader(currentClassLoader); 244 | } 245 | 246 | // Revert the "defaultUseCaches"-field in URLConnection back to its 247 | // original value 248 | try { 249 | if (cacheField != null) { 250 | cacheField.setBoolean(null, cacheValue); 251 | } 252 | } catch (Exception e) { 253 | System.out.println("Failed to revert the \"defaultUseCaches\"-field back to its original value, URLConnection-caching remains disabled."); 254 | } 255 | } 256 | } 257 | 258 | private void installDatabase(boolean rebuild) { 259 | // Check if the database already (partially) exists 260 | boolean databaseExists = false; 261 | 262 | List> classes = getDatabaseClasses(); 263 | for (int i = 0; i < classes.size(); i++) { 264 | try { 265 | // Do a simple query which only throws an exception if the table 266 | // does not exist 267 | ebeanServer.find(classes.get(i)).findRowCount(); 268 | 269 | // Query passed without throwing an exception, a database 270 | // therefore already exists 271 | databaseExists = true; 272 | break; 273 | } catch (Exception ex) { 274 | // Do nothing 275 | } 276 | } 277 | 278 | // Check if the database has to be created or rebuilt 279 | if (!rebuild && databaseExists) { 280 | return; 281 | } 282 | 283 | // Create a DDL generator 284 | SpiEbeanServer serv = (SpiEbeanServer) ebeanServer; 285 | DdlGenerator gen = serv.getDdlGenerator(); 286 | 287 | // Fire "before drop" event 288 | try { 289 | beforeDropDatabase(); 290 | } catch (Exception ex) { 291 | // If the database exists, dropping has to be canceled to prevent 292 | // data-loss 293 | if (databaseExists) { 294 | throw new RuntimeException("An unexpected exception occured", ex); 295 | } 296 | } 297 | 298 | // Generate a DropDDL-script 299 | gen.runScript(true, gen.generateDropDdl()); 300 | 301 | // If SQLite is being used, the database has to reloaded to release all 302 | // resources 303 | if (usingSQLite) { 304 | loadDatabase(); 305 | } 306 | 307 | // Generate a CreateDDL-script 308 | if (usingSQLite) { 309 | // If SQLite is being used, the CreateDLL-script has to be validated 310 | // and potentially fixed to be valid 311 | gen.runScript(false, validateCreateDDLSqlite(gen.generateCreateDdl())); 312 | } else { 313 | gen.runScript(false, gen.generateCreateDdl()); 314 | } 315 | 316 | // Fire "after create" event 317 | try { 318 | afterCreateDatabase(); 319 | } catch (Exception ex) { 320 | throw new RuntimeException("An unexpected exception occured", ex); 321 | } 322 | } 323 | 324 | private void enableDatabaseLogging(boolean logging) { 325 | // If logging is allowed, nothing has to be changed 326 | if (logging) { 327 | return; 328 | } 329 | 330 | // Set the level of the root logger back to the original value 331 | Logger.getLogger("").setLevel(loggerLevel); 332 | } 333 | 334 | private String replaceDatabaseString(String input) { 335 | input = input.replaceAll("\\{DIR\\}", plugin.getDataFolder().getPath().replaceAll("\\\\", "/") + "/"); 336 | input = input.replaceAll("\\{NAME\\}", plugin.getDescription().getName().replaceAll("[^\\w_-]", "")); 337 | 338 | return input; 339 | } 340 | 341 | private String validateCreateDDLSqlite(String oldScript) { 342 | try { 343 | // Create a BufferedReader out of the potentially invalid script 344 | BufferedReader scriptReader = new BufferedReader(new StringReader(oldScript)); 345 | 346 | // Create an array to store all the lines 347 | List scriptLines = new ArrayList(); 348 | 349 | // Create some additional variables for keeping track of tables 350 | HashMap foundTables = new HashMap(); 351 | String currentTable = null; 352 | int tableOffset = 0; 353 | 354 | // Loop through all lines 355 | String currentLine; 356 | while ((currentLine = scriptReader.readLine()) != null) { 357 | // Trim the current line to remove trailing spaces 358 | currentLine = currentLine.trim(); 359 | 360 | // Add the current line to the rest of the lines 361 | scriptLines.add(currentLine.trim()); 362 | 363 | // Check if the current line is of any use 364 | if (currentLine.startsWith("create table")) { 365 | // Found a table, so get its name and remember the line it 366 | // has been encountered on 367 | currentTable = currentLine.split(" ", 4)[2]; 368 | foundTables.put(currentLine.split(" ", 3)[2], scriptLines.size() - 1); 369 | } else if (currentLine.startsWith(";") && currentTable != null 370 | && !currentTable.equals("")) { 371 | // Found the end of a table definition, so update the entry 372 | int index = scriptLines.size() - 1; 373 | foundTables.put(currentTable, index); 374 | 375 | // Remove the last ")" from the previous line 376 | String previousLine = scriptLines.get(index - 1); 377 | previousLine = previousLine.substring(0, previousLine.length() - 1); 378 | scriptLines.set(index - 1, previousLine); 379 | 380 | // Change ";" to ");" on the current line 381 | scriptLines.set(index, ");"); 382 | 383 | // Reset the table-tracker 384 | currentTable = null; 385 | } else if (currentLine.startsWith("alter table")) { 386 | // Found a potentially unsupported action 387 | String[] alterTableLine = currentLine.split(" ", 4); 388 | 389 | if (alterTableLine[3].startsWith("add constraint")) { 390 | // Found an unsupported action: ALTER TABLE using ADD 391 | // CONSTRAINT 392 | String[] addConstraintLine = alterTableLine[3].split(" ", 4); 393 | 394 | // Check if this line can be fixed somehow 395 | if (addConstraintLine[3].startsWith("foreign key")) { 396 | // Calculate the index of last line of the current 397 | // table 398 | int tableLastLine = foundTables.get(alterTableLine[2]) + tableOffset; 399 | 400 | // Add a "," to the previous line 401 | scriptLines.set(tableLastLine - 1, scriptLines.get(tableLastLine - 1) + ","); 402 | 403 | // Add the constraint as a new line - Remove the ";" 404 | // on the end 405 | String constraintLine = String.format("%s %s %s", addConstraintLine[1], addConstraintLine[2], addConstraintLine[3]); 406 | scriptLines.add(tableLastLine, constraintLine.substring(0, constraintLine.length() - 1)); 407 | 408 | // Remove this line and raise the table offset 409 | // because a line has been inserted 410 | scriptLines.remove(scriptLines.size() - 1); 411 | tableOffset++; 412 | } else { 413 | // Exception: This line cannot be fixed but is known 414 | // the be unsupported by SQLite 415 | throw new RuntimeException("Unsupported action encountered: ALTER TABLE using ADD CONSTRAINT with " + addConstraintLine[3]); 416 | } 417 | } 418 | } 419 | } 420 | 421 | // Turn all the lines back into a single string 422 | String newScript = ""; 423 | for (String newLine : scriptLines) { 424 | newScript += newLine + "\n"; 425 | } 426 | 427 | // Print the new script 428 | System.out.println(newScript); 429 | 430 | // Return the fixed script 431 | return newScript; 432 | } catch (Exception ex) { 433 | // Exception: Failed to fix the DDL or something just went plain 434 | // wrong 435 | throw new RuntimeException("Failed to validate the CreateDDL-script for SQLite", ex); 436 | } 437 | } 438 | 439 | /** 440 | * Method called before the loaded database is being dropped 441 | */ 442 | protected void beforeDropDatabase() { } 443 | 444 | /** 445 | * Method called after the loaded database has been created 446 | */ 447 | protected void afterCreateDatabase() { } 448 | 449 | /** 450 | * Method called near the end of prepareDatabase, before the 451 | * dataSourceConfig is attached to the serverConfig. 452 | * 453 | * @param dataSourceConfig 454 | * @param serverConfig 455 | */ 456 | protected void prepareDatabaseAdditionalConfig(DataSourceConfig dataSourceConfig, ServerConfig serverConfig) { } 457 | 458 | public EbeanServer getDatabase() { 459 | return this.ebeanServer; 460 | } 461 | 462 | public List> getDatabaseClasses() { 463 | return this.databaseClasses; 464 | } 465 | 466 | @Entity 467 | @Table(name = "example_table") 468 | public static class Example { 469 | 470 | @Id 471 | @Column(unique = true, updatable = false) 472 | @GeneratedValue( strategy = GenerationType.IDENTITY ) 473 | private String uuid; 474 | 475 | @Column(updatable = true) 476 | private int kills; 477 | 478 | @Column(updatable = true) 479 | private int deaths; 480 | 481 | public String getUuid() { 482 | return this.uuid; 483 | } 484 | 485 | public void setUuid(String uuid) { 486 | this.uuid = uuid; 487 | } 488 | 489 | public int getKills() { 490 | return this.kills; 491 | } 492 | 493 | public void setKills(int kills) { 494 | this.kills = kills; 495 | } 496 | 497 | public int getDeaths() { 498 | return this.deaths; 499 | } 500 | 501 | public void setDeaths(int deaths) { 502 | this.deaths = deaths; 503 | } 504 | 505 | public void save() { 506 | //this will be null for example, but it should not be when using in production 507 | SimpleEbean database = null; 508 | boolean save = false; 509 | String uuid = Bukkit.getPlayer("Goblom").getUniqueId().toString(); 510 | 511 | Example example = database.getDatabase().find(Example.class).where().idEq(uuid).findUnique(); 512 | 513 | if (example == null) { 514 | example = new Example(); 515 | example.setUuid(uuid); 516 | save = true; 517 | } 518 | 519 | example.setKills(this.getKills()); 520 | example.setDeaths(this.getDeaths()); 521 | 522 | if (save) { 523 | database.getDatabase().save(example); 524 | } else { 525 | database.getDatabase().update(example); 526 | } 527 | } 528 | } 529 | } 530 | -------------------------------------------------------------------------------- /src/main/java/enchantment/AbstractEnchantment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2014 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package enchantment; 25 | 26 | import java.lang.reflect.Field; 27 | import org.bukkit.enchantments.Enchantment; 28 | import org.bukkit.enchantments.EnchantmentTarget; 29 | import org.bukkit.inventory.ItemStack; 30 | 31 | /** 32 | * 33 | * @author Goblom 34 | */ 35 | public abstract class AbstractEnchantment extends Enchantment { 36 | 37 | public AbstractEnchantment(int id) { 38 | super(id); 39 | 40 | if (id > 256) { 41 | throw new IllegalArgumentException("An enchantment id has to be lower then 256!"); 42 | } 43 | 44 | try { 45 | Field f = Enchantment.class.getDeclaredField("acceptingNew"); 46 | f.setAccessible(true); 47 | f.set(null, Boolean.valueOf(true)); 48 | Enchantment.registerEnchantment(this); 49 | f.set(null, f.getBoolean(null)); 50 | } catch (Exception e) { 51 | e.printStackTrace(); 52 | } 53 | } 54 | 55 | public abstract boolean canEnchantItem(ItemStack item); 56 | 57 | public abstract boolean conflictsWith(Enchantment enchantment); 58 | 59 | public abstract EnchantmentTarget getItemTarget(); 60 | 61 | public abstract int getMaxLevel(); 62 | 63 | public abstract int getStartLevel(); 64 | 65 | public abstract int getWeight(); 66 | 67 | @Override 68 | public String getName() { 69 | return "Usages" + this.getId(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/enchantment/CustomEnchantment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2014 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package enchantment; 25 | 26 | import org.bukkit.enchantments.Enchantment; 27 | import org.bukkit.enchantments.EnchantmentTarget; 28 | import org.bukkit.inventory.ItemStack; 29 | 30 | /** 31 | * 32 | * @author Goblom 33 | */ 34 | public class CustomEnchantment extends AbstractEnchantment { 35 | 36 | public CustomEnchantment(int id) { 37 | super(id); 38 | } 39 | 40 | @Override 41 | public boolean canEnchantItem(ItemStack itemstack) { 42 | return false; 43 | } 44 | 45 | @Override 46 | public boolean conflictsWith(Enchantment enchantment) { 47 | return false; 48 | } 49 | 50 | @Override 51 | public EnchantmentTarget getItemTarget() { 52 | return EnchantmentTarget.ALL; 53 | } 54 | 55 | @Override 56 | public int getMaxLevel() { 57 | return 1; 58 | } 59 | 60 | @Override 61 | public int getStartLevel() { 62 | return 1; 63 | } 64 | 65 | @Override 66 | public int getWeight() { 67 | return 1000; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/events/SimpleListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2014 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package events; 26 | 27 | import com.google.common.collect.Lists; 28 | import java.util.Collections; 29 | import java.util.List; 30 | import org.bukkit.event.HandlerList; 31 | import org.bukkit.event.Listener; 32 | import org.bukkit.plugin.Plugin; 33 | 34 | /** 35 | * Make a listener extend this class then all you need to do is "new ExampleListener(myPlugin);" 36 | * @author Goblom 37 | */ 38 | public abstract class SimpleListener implements Listener { 39 | 40 | private static final List listeners = Lists.newArrayList(); 41 | 42 | public static final void unregisterAll() { 43 | for (SimpleListener listener : listeners) { 44 | listener.unregister(); 45 | } 46 | } 47 | 48 | public static final List getRegistered() { 49 | return Collections.unmodifiableList(listeners); 50 | } 51 | 52 | protected Plugin plugin; 53 | 54 | public SimpleListener(Plugin plugin) { 55 | this.plugin = plugin; 56 | plugin.getServer().getPluginManager().registerEvents(this, plugin); 57 | SimpleListener.listeners.add(this); 58 | 59 | logRegister(); 60 | } 61 | 62 | protected void logRegister() { 63 | plugin.getLogger().info("Registered " + getClass().getSimpleName()); 64 | } 65 | 66 | public final void unregister() { 67 | HandlerList.unregisterAll(this); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/item/AddGlow.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2013 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package item; 26 | 27 | import java.lang.reflect.Field; 28 | import org.bukkit.enchantments.Enchantment; 29 | import org.bukkit.enchantments.EnchantmentTarget; 30 | import org.bukkit.inventory.ItemStack; 31 | import enchantment.AbstractEnchantment; 32 | 33 | /** 34 | * Make items glow without having those nasty Enchantment Names on the items 35 | * lore. 36 | * 37 | * @author Goblom 38 | */ 39 | public class AddGlow { 40 | 41 | public static void makeGlow(ItemStack item) { 42 | item.addUnsafeEnchantment(new GlowEffect(100), 1); 43 | } 44 | 45 | private static final class GlowEffect extends AbstractEnchantment { 46 | public GlowEffect(int id) { super(id); } 47 | @Override 48 | public boolean canEnchantItem(ItemStack itemstack) { return false; } 49 | @Override 50 | public boolean conflictsWith(Enchantment enchantment) { return false; } 51 | @Override 52 | public EnchantmentTarget getItemTarget() { return EnchantmentTarget.ALL; } 53 | @Override 54 | public int getMaxLevel() { return 1; } 55 | @Override 56 | public int getStartLevel() { return 1; } 57 | @Override 58 | public int getWeight() { return 1000; } 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/item/CommandItem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2014 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package item; 26 | 27 | import net.minecraft.util.org.apache.commons.lang3.Validate; 28 | import org.bukkit.Bukkit; 29 | import org.bukkit.ChatColor; 30 | import org.bukkit.entity.Player; 31 | import org.bukkit.event.EventHandler; 32 | import org.bukkit.event.HandlerList; 33 | import org.bukkit.event.Listener; 34 | import org.bukkit.event.block.Action; 35 | import org.bukkit.event.player.PlayerInteractEvent; 36 | import org.bukkit.inventory.ItemStack; 37 | import org.bukkit.plugin.Plugin; 38 | 39 | /** 40 | * 41 | * @author Goblom 42 | */ 43 | public class CommandItem { 44 | private ItemStack item; 45 | private UseRunner useRunner; 46 | private Listener listener; 47 | private Action[] runWith; 48 | private boolean isDestroyed = false; 49 | 50 | public CommandItem(Plugin plugin, ItemStack itemStack, UseRunner runner, Action... actions) { 51 | this(plugin, itemStack, runner, false, actions); 52 | } 53 | 54 | public CommandItem(Plugin plugin, ItemStack itemStack, UseRunner runner, final boolean checkLore, Action... actions) { 55 | Validate.notNull(actions, "You must have an action"); 56 | 57 | this.item = itemStack; 58 | this.useRunner = runner; 59 | this.runWith = actions; 60 | 61 | this.listener = new Listener() { 62 | @EventHandler 63 | public void onPlayerInteract(PlayerInteractEvent event) { 64 | if (isDestroyed()) return; 65 | ItemStack handItem = event.getItem(); 66 | if (handItem == null) return; 67 | CHECK: for (Action action : runWith) { 68 | if (event.getAction().equals(action)) { 69 | if (isSimilar(handItem, item, checkLore)) { 70 | useRunner.onUse(event.getPlayer()); 71 | 72 | if (useRunner.willDestroy()) { 73 | destroy(); 74 | } 75 | 76 | event.setCancelled(true); 77 | break CHECK; 78 | } 79 | } 80 | } 81 | } 82 | }; 83 | 84 | Bukkit.getServer().getPluginManager().registerEvents(listener, plugin); 85 | } 86 | 87 | public void destroy() { 88 | HandlerList.unregisterAll(listener); 89 | this.listener = null; 90 | this.item = null; 91 | this.useRunner = null; 92 | this.runWith = null; 93 | this.isDestroyed = true; 94 | } 95 | 96 | public boolean isDestroyed() { 97 | return this.isDestroyed; 98 | } 99 | 100 | public ItemStack getItemStack() { 101 | return item; 102 | } 103 | 104 | public static abstract class UseRunner { 105 | private boolean destroy; 106 | 107 | public final void setWillDestroy(boolean bln) { 108 | this.destroy = bln; 109 | } 110 | 111 | public final boolean willDestroy() { 112 | return this.destroy; 113 | } 114 | 115 | public abstract void onUse(Player player); 116 | } 117 | 118 | //******************************************************* 119 | // Item Similarity Checking 120 | //******************************************************* 121 | private boolean isSimilarName(ItemStack one, ItemStack two) { 122 | try { 123 | String N1 = strip(one.getItemMeta().getDisplayName()); 124 | String N2 = strip(two.getItemMeta().getDisplayName()); 125 | return N1.equals(N1); 126 | } catch (Exception e) {} 127 | return false; 128 | } 129 | 130 | private String strip(String str) { 131 | return ChatColor.stripColor(str); 132 | } 133 | 134 | private boolean isSimilar(ItemStack one, ItemStack two, boolean checkLore) { 135 | boolean name = isSimilarName(one, two); 136 | boolean id = one.getTypeId() == two.getTypeId(); 137 | boolean dura = one.getDurability() == two.getDurability(); 138 | boolean lore = true; 139 | if (checkLore) { 140 | if (hasLore(one) && hasLore(two)) { 141 | if (hasLoreSize(one) && hasLoreSize(two)) { 142 | if (getLoreSize(one) == getLoreSize(two)) { 143 | int size = getLoreSize(one); 144 | for (int i = 0; i < size; i++) { 145 | String l1 = getLoreLine(one, i); 146 | String l2 = getLoreLine(two, i); 147 | if (!l1.equals(l2)) { 148 | lore = false; 149 | break; 150 | } 151 | } 152 | } else { 153 | lore = false; 154 | } 155 | } 156 | } 157 | } 158 | return name && id && dura && lore; 159 | } 160 | 161 | private boolean hasLore(ItemStack item) { 162 | if (item.hasItemMeta()) { 163 | if (item.getItemMeta().hasLore()) { 164 | return true; 165 | } 166 | } 167 | return false; 168 | } 169 | 170 | private int getLoreSize(ItemStack item) { 171 | if (hasLore(item)) { 172 | return item.getItemMeta().getLore().size(); 173 | } 174 | return 0; 175 | } 176 | 177 | private boolean hasLoreSize(ItemStack item) { 178 | return hasLore(item) && getLoreSize(item) >= 1; 179 | } 180 | 181 | private String getLoreLine(ItemStack item, int index) { 182 | try { 183 | return item.getItemMeta().getLore().get(index); 184 | } catch (Exception e) {} 185 | return ""; 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /src/main/java/item/InventoryParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2013 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package item; 26 | 27 | import java.io.File; 28 | import java.io.IOException; 29 | import java.util.Collection; 30 | import java.util.HashSet; 31 | import org.bukkit.Bukkit; 32 | import org.bukkit.Material; 33 | import org.bukkit.configuration.file.FileConfiguration; 34 | import org.bukkit.configuration.file.YamlConfiguration; 35 | import org.bukkit.enchantments.Enchantment; 36 | import org.bukkit.entity.Player; 37 | import org.bukkit.inventory.ItemStack; 38 | import org.bukkit.inventory.meta.ItemMeta; 39 | import org.bukkit.plugin.Plugin; 40 | import org.bukkit.potion.PotionEffect; 41 | import org.bukkit.potion.PotionEffectType; 42 | 43 | /** 44 | * 45 | * @author Goblom 46 | */ 47 | public class InventoryParser { 48 | private final String pluginName; 49 | 50 | public InventoryParser(Plugin plugin) { 51 | this.pluginName = plugin.getName(); 52 | } 53 | 54 | public Plugin getPlugin() { 55 | return Bukkit.getPluginManager().getPlugin(pluginName); 56 | } 57 | 58 | public File getFileForPlayer(Player player) { 59 | return new File(getPlugin().getDataFolder() + File.pathSeparator + "inv" + File.pathSeparator + "players" + File.pathSeparator + player.getName() + ".yml"); 60 | } 61 | 62 | public FileConfiguration getConfigForPlayer(Player player) { 63 | return YamlConfiguration.loadConfiguration(getFileForPlayer(player)); 64 | } 65 | 66 | public void saveInventory(Player player) { 67 | ParseForPlayer pfp = new ParseForPlayer(player); 68 | pfp.saveInventory(false); 69 | } 70 | 71 | public class ParseForPlayer { 72 | private final String playerName; 73 | private final File playerFile; 74 | 75 | public ParseForPlayer(Player player) { 76 | this.playerName = player.getName(); 77 | this.playerFile = getFileForPlayer(player); 78 | } 79 | 80 | public Player getPlayer() { 81 | return Bukkit.getPlayer(playerName); 82 | } 83 | 84 | public File getFile() { 85 | return playerFile; 86 | } 87 | 88 | private FileConfiguration getFileConfig() { 89 | return YamlConfiguration.loadConfiguration(getFile()); 90 | } 91 | 92 | public boolean saveInventory(boolean override) { 93 | if (getFile().exists() && override) getFile().delete(); 94 | 95 | ItemStack[] armor = getPlayer().getInventory().getArmorContents(); 96 | ItemStack[] contents = getPlayer().getInventory().getContents(); 97 | Collection potionEffects = getPlayer().getActivePotionEffects(); 98 | 99 | FileConfiguration playerConfig = getFileConfig(); 100 | 101 | for (int i = 0; i < armor.length; i++) { 102 | ItemStack item = armor[i]; 103 | if ((item != null) && (item.getType() != Material.AIR)) { 104 | playerConfig.set("Armor." + i + ".Material", item.getType().name()); 105 | playerConfig.set("Armor." + i + ".Amount", item.getAmount()); 106 | playerConfig.set("Armor." + i + ".Durability", item.getDurability()); 107 | // playerConfig.set("Armor." + i + ".MaterialData", item.getData().getData()); 108 | if (item.hasItemMeta()) { 109 | ItemMeta meta = item.getItemMeta(); 110 | if (meta.hasDisplayName()) playerConfig.set("Armor." + i + ".ItemMeta.Display-Name", meta.getDisplayName()); 111 | if (meta.hasLore()) playerConfig.set("Armor." + i + ".ItemMeta.Lore", meta.getLore()); 112 | if (meta.hasEnchants()) { 113 | for (Enchantment enchant : meta.getEnchants().keySet()) { 114 | playerConfig.set("Armor." + i + ".ItemMeta.Enchantment." + enchant.getName() + ".Level", meta.getEnchantLevel(enchant)); 115 | } 116 | } 117 | } 118 | } else playerConfig.set("Armor." + i + ".Material", Material.AIR.name()); 119 | } 120 | 121 | for (int i = 0; i < contents.length; i++) { 122 | ItemStack item = contents[i]; 123 | if ((item != null) && (item.getType() != Material.AIR)) { 124 | playerConfig.set("Contents." + i + ".Material", item.getType().name()); 125 | playerConfig.set("Contents." + i + ".Amount", item.getAmount()); 126 | playerConfig.set("Contents." + i + ".Durability", item.getDurability()); 127 | // playerConfig.set("Contents." + i + ".MaterialData", item.getData().getData()); 128 | if (item.hasItemMeta()) { 129 | ItemMeta meta = item.getItemMeta(); 130 | if (meta.hasDisplayName()) playerConfig.set("Contents." + i + ".ItemMeta.Display-Name", meta.getDisplayName()); 131 | if (meta.hasLore()) playerConfig.set("Contents." + i + ".ItemMeta.Lore", meta.getLore()); 132 | if (meta.hasEnchants()) { 133 | // for (Enchantment enchant : meta.getEnchants().keySet()) { 134 | // playerConfig.set("Contents." + i + ".ItemMeta.Enchantment." + enchant.getName() + ".Level", meta.getEnchantLevel(enchant)); 135 | // } 136 | for (Enchantment enchant : item.getEnchantments().keySet()) { 137 | playerConfig.set("Contents." + i + ".ItemMeta.Enchantment." + enchant.getName() + ".Level", item.getEnchantmentLevel(enchant)); 138 | } 139 | } 140 | } 141 | } else playerConfig.set("Contents." + i + ".Material", Material.AIR.name()); 142 | } 143 | 144 | for (PotionEffect effect : potionEffects) { 145 | playerConfig.set("Effects." + effect.getType().getName() + ".Level", effect.getAmplifier()); 146 | playerConfig.set("Effects." + effect.getType().getName() + ".Duration", effect.getDuration()); 147 | playerConfig.set("Effects." + effect.getType().getName() + ".Ambience", effect.isAmbient()); 148 | } 149 | 150 | try { 151 | playerConfig.save(getFile()); 152 | return true; 153 | } catch (IOException e) { return false; } 154 | } 155 | 156 | public ItemStack[] getArmor() { 157 | ItemStack[] items = null; 158 | FileConfiguration config = getFileConfig(); 159 | 160 | if (getFile().exists()) { 161 | if (config.contains("Armor")) { 162 | if (config.isConfigurationSection("Armor")) { 163 | int size = config.getInt("Armor", 4); 164 | items = new ItemStack[size]; 165 | for (int i = 0; i < size; i++) { 166 | if (config.contains("Armor." + i)) { 167 | Material mat = Material.getMaterial(config.getString("Armor." + i + ".Material")); 168 | if (mat != Material.AIR) { 169 | int amount = config.getInt("Armor." + i + ".Amount"); 170 | short durability = (short) config.getInt("Armor." + i + ".Durability"); 171 | ItemStack item = new ItemStack(mat, amount, durability); 172 | 173 | if (config.contains("Armor." + i + ".ItemMeta")) { 174 | ItemMeta meta = item.getItemMeta(); 175 | if (config.contains("Armor." + i + ".ItemMeta.Lore")) meta.setLore(config.getStringList("Armor." + i + ".ItemMeta.Lore")); 176 | if (config.contains("Armor." + i + ".ItemMeta.Display-Name")) meta.setDisplayName(config.getString("Armor." + i + ".ItemMeta.Display-Name")); 177 | if (config.contains("Armor." + i + ".ItemMeta.Enchantment")) { 178 | // for (String enchantName : config.getConfigurationSection("Armor." + i + ".ItemMeta.Enchantment").getKeys(false)) { 179 | // meta.addEnchant(Enchantment.getByName(enchantName), config.getInt("Armor." + i + ".ItemMeta.Enchantment." + enchantName + ".Level"), true); 180 | // } 181 | for (Enchantment enchant : item.getEnchantments().keySet()) { 182 | config.set("Contents." + i + ".ItemMeta.Enchantment." + enchant.getName() + ".Level", item.getEnchantmentLevel(enchant)); 183 | } 184 | } 185 | item.setItemMeta(meta); 186 | } 187 | items[i] = item; 188 | } else items[i] = new ItemStack(Material.AIR); 189 | } 190 | } 191 | } 192 | } 193 | return items; 194 | } else { 195 | saveInventory(false); 196 | return getArmor(); 197 | } 198 | } 199 | 200 | public ItemStack[] getContents() { 201 | ItemStack[] items = null; 202 | FileConfiguration config = getFileConfig(); 203 | 204 | if (getFile().exists()) { 205 | if (config.contains("Contents")) { 206 | if (config.isConfigurationSection("Contents")) { 207 | int size = config.getInt("Contents", 4); 208 | items = new ItemStack[size]; 209 | for (int i = 0; i < size; i++) { 210 | if (config.contains("Contents." + i)) { 211 | Material mat = Material.getMaterial(config.getString("Contents." + i + ".Material")); 212 | if (mat != Material.AIR) { 213 | int amount = config.getInt("Contents." + i + ".Amount"); 214 | short durability = (short) config.getInt("Contents." + i + ".Durability"); 215 | ItemStack item = new ItemStack(mat, amount, durability); 216 | 217 | if (config.contains("Contents." + i + ".ItemMeta")) { 218 | ItemMeta meta = item.getItemMeta(); 219 | if (config.contains("Contents." + i + ".ItemMeta.Lore")) meta.setLore(config.getStringList("Contents." + i + ".ItemMeta.Lore")); 220 | if (config.contains("Contents." + i + ".ItemMeta.Display-Name")) meta.setDisplayName(config.getString("Contents." + i + ".ItemMeta.Display-Name")); 221 | if (config.contains("Contents." + i + ".ItemMeta.Enchantment")) { 222 | for (String enchantName : config.getConfigurationSection("Contents." + i + ".ItemMeta.Enchantment").getKeys(false)) { 223 | meta.addEnchant(Enchantment.getByName(enchantName), config.getInt("Contents." + i + ".ItemMeta.Enchantment." + enchantName + ".Level"), true); 224 | } 225 | } 226 | item.setItemMeta(meta); 227 | } 228 | items[i] = item; 229 | } else items[i] = new ItemStack(Material.AIR); 230 | } 231 | } 232 | } 233 | } 234 | return items; 235 | } else { 236 | saveInventory(false); 237 | return getContents(); 238 | } 239 | } 240 | 241 | public ItemStack[][] getAllItems() { 242 | return new ItemStack[][] { getArmor(), getContents() }; 243 | } 244 | 245 | public Collection getPotionEffects() { 246 | Collection effects = new HashSet(); 247 | FileConfiguration config = getFileConfig(); 248 | 249 | if (config.contains("Effects") && config.isConfigurationSection("Effects")) { 250 | for (String string : config.getConfigurationSection("Effects").getKeys(false)) { 251 | int level = config.getInt("Effects." + string + ".Level"); 252 | int duration = config.getInt("Effects." + string + ".Duration"); 253 | boolean ambient = config.getBoolean("Effects." + string + ".Ambience"); 254 | effects.add(new PotionEffect(PotionEffectType.getByName(string), duration, level, ambient)); 255 | } 256 | } 257 | return effects; 258 | } 259 | } 260 | } 261 | -------------------------------------------------------------------------------- /src/main/java/packets/PacketWriter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2014 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package packets; 26 | 27 | import java.lang.reflect.Field; 28 | import java.lang.reflect.Method; 29 | import org.bukkit.Bukkit; 30 | import org.bukkit.entity.Player; 31 | 32 | /** 33 | * 34 | * @author Goblom 35 | */ 36 | public class PacketWriter { 37 | private static final String VERSION = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3]; 38 | 39 | public static class PacketNotFoundException extends ClassNotFoundException { 40 | private PacketNotFoundException(String string) { 41 | super(string); 42 | } 43 | } 44 | 45 | public static class InvalidPacketException extends Exception { 46 | private InvalidPacketException(String str) { 47 | super(str); 48 | } 49 | } 50 | 51 | private final Class packetClass; 52 | private final Object packetObject; 53 | 54 | public PacketWriter(String packet) throws PacketNotFoundException, InvalidPacketException { 55 | this.packetClass = getNMSClass(packet); 56 | 57 | if (this.packetClass == null) { 58 | throw new PacketNotFoundException(packet + " was unable to be found."); 59 | } 60 | 61 | Object obj = null; 62 | try { 63 | obj = packetClass.newInstance(); 64 | } catch (Exception e) { } 65 | 66 | if (obj == null) { 67 | throw new InvalidPacketException("Packet was unable to be initialized"); 68 | } 69 | 70 | this.packetObject = obj; 71 | } 72 | 73 | private static Class getNMSClass(String name) { 74 | Class clazz = null; 75 | try { 76 | clazz = Class.forName("net.minecraft.server." + VERSION + "." + name); 77 | } catch (Exception e) { 78 | e.printStackTrace(); 79 | } 80 | return clazz; 81 | } 82 | 83 | private static Field getField(Class clazz, String name) { 84 | Field field = null; 85 | 86 | try { 87 | field = clazz.getField(name); 88 | } catch (Exception e) { } 89 | 90 | if (field == null) { 91 | try { 92 | field = clazz.getDeclaredField(name); 93 | } catch (Exception e) { } 94 | } 95 | 96 | if (field != null) { 97 | field.setAccessible(true); 98 | } 99 | 100 | return field; 101 | } 102 | 103 | public PacketWriter write(String field, Object value) { 104 | Field f = getField(packetClass, field); 105 | 106 | if (f == null) { 107 | throw new RuntimeException("Field " + field + " was not found for " + packetClass.getSimpleName()); 108 | } 109 | 110 | if (!f.getType().equals(value.getClass())) { 111 | throw new RuntimeException("Field " + field + " uses a different object value"); 112 | } 113 | 114 | try { 115 | f.set(packetObject, value); 116 | } catch (IllegalAccessException e) { 117 | throw new RuntimeException("Field " + field + " is not accessible.", e); 118 | } catch (IllegalArgumentException e) { 119 | throw new RuntimeException(e); 120 | } 121 | 122 | return this; 123 | } 124 | 125 | public void send(Player... players) { 126 | Class packetClass = getNMSClass("Packet"); 127 | if (packetClass != null) { 128 | for (Player player : players) { 129 | try { 130 | Object handle = player.getClass().getMethod("getHandle").invoke(player); 131 | Object playerConnection = handle.getClass().getField("playerConnection").get(handle); 132 | 133 | playerConnection.getClass().getMethod("sendPacket", packetClass).invoke(playerConnection, packetObject); 134 | } catch (Exception e) { 135 | e.printStackTrace(); 136 | } 137 | } 138 | } 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /src/main/java/packets/Rope_NMS.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2014 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package packets; 26 | 27 | import net.minecraft.server.v1_7_R4.EntityBat; 28 | import net.minecraft.server.v1_7_R4.EntityWitherSkull; 29 | import net.minecraft.server.v1_7_R4.PacketPlayOutAttachEntity; 30 | import net.minecraft.server.v1_7_R4.PacketPlayOutEntityDestroy; 31 | import net.minecraft.server.v1_7_R4.PacketPlayOutSpawnEntity; 32 | import net.minecraft.server.v1_7_R4.PacketPlayOutSpawnEntityLiving; 33 | import net.minecraft.server.v1_7_R4.WorldServer; 34 | import org.bukkit.Bukkit; 35 | import org.bukkit.Location; 36 | import org.bukkit.craftbukkit.v1_7_R4.CraftWorld; 37 | import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer; 38 | import org.bukkit.entity.Player; 39 | 40 | /** 41 | * Credits to @Desile for the original resource. (Uses entities, not packets) 42 | * 43 | * @author Goblom 44 | */ 45 | public class Rope_NMS { 46 | 47 | private Location loc_start, loc_end; 48 | private EntityWitherSkull ent_start, ent_end; 49 | private EntityBat ent_bat_start, ent_bat_end; 50 | 51 | public Rope_NMS(Location start, Location end) { 52 | this(start, end, true); 53 | } 54 | 55 | public Rope_NMS(Location start, Location end, boolean spawn) { 56 | this.loc_start = start; 57 | this.loc_end = end; 58 | 59 | if (spawn) { 60 | spawn(); 61 | } 62 | } 63 | 64 | public void setStart(Location start) { 65 | this.loc_start = start; 66 | spawn(); 67 | } 68 | 69 | public void setEnd(Location end) { 70 | this.loc_end = end; 71 | spawn(); 72 | } 73 | 74 | public Location getStart() { 75 | return loc_start; 76 | } 77 | 78 | public Location getEnd() { 79 | return loc_end; 80 | } 81 | 82 | private void makeEnt() { 83 | WorldServer world_start = ((CraftWorld) loc_start.getWorld()).getHandle(); 84 | WorldServer world_end = ((CraftWorld) loc_end.getWorld()).getHandle(); 85 | 86 | if (ent_start == null) { 87 | this.ent_start = new EntityWitherSkull(world_start); 88 | } 89 | 90 | if (ent_end == null) { 91 | this.ent_end = new EntityWitherSkull(world_end); 92 | } 93 | 94 | if (ent_bat_start == null) { 95 | this.ent_bat_start = new EntityBat(world_start); 96 | } 97 | 98 | if (ent_bat_end == null) { 99 | this.ent_bat_end = new EntityBat(world_end); 100 | } 101 | 102 | this.ent_start.setLocation(loc_start.getX(), loc_start.getY(), loc_start.getZ(), 0, 0); 103 | this.ent_end.setLocation(loc_end.getX(), loc_end.getY(), loc_end.getZ(), 0, 0); 104 | this.ent_bat_start.setLocation(loc_start.getX(), loc_start.getY(), loc_start.getZ(), 0, 0); 105 | this.ent_bat_end.setLocation(loc_end.getX(), loc_end.getY(), loc_end.getZ(), 0, 0); 106 | 107 | this.ent_bat_start.setLeashHolder(ent_bat_end, true); //Try with false 108 | } 109 | 110 | public void spawn() { 111 | makeEnt(); 112 | PacketPlayOutSpawnEntity skull_start = new PacketPlayOutSpawnEntity(ent_start, 66); 113 | PacketPlayOutSpawnEntity skull_end = new PacketPlayOutSpawnEntity(ent_end, 66); 114 | PacketPlayOutSpawnEntityLiving bat_start = new PacketPlayOutSpawnEntityLiving(ent_bat_start); 115 | PacketPlayOutSpawnEntityLiving bat_end = new PacketPlayOutSpawnEntityLiving(ent_bat_start); 116 | PacketPlayOutAttachEntity attach_start = new PacketPlayOutAttachEntity(0, ent_start, ent_bat_start); 117 | PacketPlayOutAttachEntity attach_end = new PacketPlayOutAttachEntity(0, ent_end, ent_bat_end); 118 | 119 | for (Player player : Bukkit.getOnlinePlayers()) { 120 | spawn(player, skull_start, skull_end, bat_start, bat_end, attach_start, attach_end); 121 | } 122 | } 123 | 124 | protected void spawn(Player player, PacketPlayOutSpawnEntity skull_start, PacketPlayOutSpawnEntity skull_end, PacketPlayOutSpawnEntityLiving bat_start, PacketPlayOutSpawnEntityLiving bat_end, PacketPlayOutAttachEntity attach_start, PacketPlayOutAttachEntity attach_end) { 125 | CraftPlayer cP = (CraftPlayer) player; 126 | 127 | cP.getHandle().playerConnection.sendPacket(skull_start); 128 | cP.getHandle().playerConnection.sendPacket(skull_end); 129 | cP.getHandle().playerConnection.sendPacket(bat_end); 130 | cP.getHandle().playerConnection.sendPacket(bat_start); 131 | cP.getHandle().playerConnection.sendPacket(attach_start); 132 | cP.getHandle().playerConnection.sendPacket(attach_end); 133 | } 134 | 135 | public void spawn(Player player) { 136 | makeEnt(); 137 | PacketPlayOutSpawnEntity skull_start = new PacketPlayOutSpawnEntity(ent_start, 66); 138 | PacketPlayOutSpawnEntity skull_end = new PacketPlayOutSpawnEntity(ent_end, 66); 139 | PacketPlayOutSpawnEntityLiving bat_start = new PacketPlayOutSpawnEntityLiving(ent_bat_start); 140 | PacketPlayOutSpawnEntityLiving bat_end = new PacketPlayOutSpawnEntityLiving(ent_bat_start); 141 | PacketPlayOutAttachEntity attach_start = new PacketPlayOutAttachEntity(0, ent_start, ent_bat_start); 142 | PacketPlayOutAttachEntity attach_end = new PacketPlayOutAttachEntity(0, ent_end, ent_bat_end); 143 | 144 | spawn(player, skull_start, skull_end, bat_start, bat_end, attach_start, attach_end); 145 | } 146 | 147 | public void deSpawn() { 148 | PacketPlayOutEntityDestroy destroy = new PacketPlayOutEntityDestroy(new int[] { ent_start.getId(), ent_end.getId(), ent_bat_start.getId(), ent_bat_end.getId() }); 149 | 150 | for (Player player : Bukkit.getOnlinePlayers()) { 151 | deSpawn(player, destroy); 152 | } 153 | } 154 | 155 | public void deSpawn(Player player) { 156 | deSpawn(player, new PacketPlayOutEntityDestroy(new int[] { ent_start.getId(), ent_end.getId(), ent_bat_start.getId(), ent_bat_end.getId() })); 157 | } 158 | 159 | protected void deSpawn(Player player, PacketPlayOutEntityDestroy destroy) { 160 | CraftPlayer cP = (CraftPlayer) player; 161 | cP.getHandle().playerConnection.sendPacket(destroy); 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /src/main/java/packets/Rope_Reflection.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2014 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package packets; 26 | 27 | import com.google.common.collect.Maps; 28 | import java.lang.reflect.Method; 29 | import java.util.Map; 30 | import org.bukkit.Bukkit; 31 | import org.bukkit.Location; 32 | import org.bukkit.entity.Player; 33 | 34 | /** 35 | * 36 | * @author Goblom 37 | */ 38 | public class Rope_Reflection { 39 | private static final String VERSION = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3]; 40 | 41 | private Map locations = Maps.newHashMap(); 42 | private Map witherSkulls = Maps.newHashMap(); 43 | private Map bats = Maps.newHashMap(); 44 | 45 | private enum Type { 46 | Start, End; 47 | } 48 | 49 | public Rope_Reflection(Location start, Location end) { 50 | this(start, end, true); 51 | } 52 | 53 | public Rope_Reflection(Location start, Location end, boolean spawn) { 54 | this.locations.put(Type.Start, start); 55 | this.locations.put(Type.End, end); 56 | 57 | if (spawn) { 58 | spawn(); 59 | } 60 | } 61 | 62 | public void setStart(Location loc) { 63 | this.locations.put(Type.Start, loc); 64 | spawn(); 65 | } 66 | 67 | public void setEnd(Location loc) { 68 | this.locations.put(Type.End, loc); 69 | spawn(); 70 | } 71 | 72 | public void spawn() { 73 | for (Player player : Bukkit.getOnlinePlayers()) { 74 | spawn(player); 75 | } 76 | } 77 | 78 | public void deSpawn() { 79 | for (Player player : Bukkit.getOnlinePlayers()) { 80 | deSpawn(player); 81 | } 82 | } 83 | 84 | public void spawn(Player player) { 85 | makeEntity(); 86 | 87 | try { 88 | Class PacketPlayOutSpawnEntity = getNMSClass("PacketPlayOutSpawnEntity"); 89 | Class PacketPlayOutAttachEntity = getNMSClass("PacketPlayOutAttachEntity"); 90 | Class PacketPlayOutSpawnEntityLiving = getNMSClass("PacketPlayOutSpawnEntityLiving"); 91 | Class Entity = getNMSClass("Entity"); 92 | Class EntityLiving = getNMSClass("EntityLiving"); 93 | 94 | Object skullStart, skullEnd, batStart, batEnd, attachStart, attachEnd; 95 | 96 | skullStart = PacketPlayOutSpawnEntity.getConstructor(Entity, int.class).newInstance(getSkull(Type.Start), 66); 97 | skullEnd = PacketPlayOutSpawnEntity.getConstructor(Entity, int.class).newInstance(getSkull(Type.End), 66); 98 | batStart = PacketPlayOutSpawnEntityLiving.getConstructor(EntityLiving).newInstance(getBat(Type.Start)); 99 | batEnd = PacketPlayOutSpawnEntityLiving.getConstructor(EntityLiving).newInstance(getBat(Type.End)); 100 | attachStart = PacketPlayOutAttachEntity.getConstructor(int.class, Entity, Entity).newInstance(0, skullStart, batStart); 101 | attachEnd = PacketPlayOutAttachEntity.getConstructor(int.class, Entity, Entity).newInstance(0, skullEnd, batEnd); 102 | 103 | sendPackets(player, skullStart, skullEnd, batStart, batEnd, attachStart, attachEnd); 104 | } catch (Exception e) { 105 | e.printStackTrace(); 106 | } 107 | } 108 | 109 | public void deSpawn(Player player) { 110 | try { 111 | Class PacketPlayOutEntityDestroy = getNMSClass("PacketPlayOutEntityDestroy"); 112 | int batStartId, batEndId, skullStartId, skullEndId; 113 | 114 | batStartId = (Integer) getBat(Type.Start).getClass().getMethod("getId").invoke(getBat(Type.Start)); 115 | batEndId = (Integer) getBat(Type.End).getClass().getMethod("getId").invoke(getBat(Type.End)); 116 | skullStartId = (Integer) getSkull(Type.Start).getClass().getMethod("getId").invoke(getBat(Type.Start)); 117 | skullEndId = (Integer) getSkull(Type.End).getClass().getMethod("getId").invoke(getBat(Type.End)); 118 | 119 | Object packet = PacketPlayOutEntityDestroy.getConstructor(int[].class).newInstance(new int[] { batStartId, batEndId, skullStartId, skullEndId}); 120 | sendPacket(player, packet); 121 | } catch (Exception e) { 122 | e.printStackTrace(); 123 | } 124 | } 125 | 126 | private Location getLocation(Type type) { 127 | return this.locations.get(type); 128 | } 129 | 130 | private Object getSkull(Type type) { 131 | return this.witherSkulls.get(type); 132 | } 133 | 134 | private Object getBat(Type type) { 135 | return this.bats.get(type); 136 | } 137 | 138 | private void makeEntity() { 139 | try { 140 | Class World = getNMSClass("World"); 141 | Class WorldServer = getNMSClass("WorldServer"); 142 | Class CraftWorld = getCraftClass("CraftWorld"); 143 | Class EntityBat = getNMSClass("EntityBat"); 144 | Class EntityWitherSkull = getNMSClass("EntityWitherSkull"); 145 | 146 | Object worldStart = getHandle(CraftWorld.cast(getLocation(Type.Start))); 147 | Object worldEnd = getHandle(CraftWorld.cast(getLocation(Type.End))); 148 | 149 | Object witherStart, witherEnd, batStart, batEnd; 150 | 151 | witherStart = getSkull(Type.Start); 152 | witherEnd = getSkull(Type.End); 153 | batStart = getBat(Type.Start); 154 | batEnd = getBat(Type.End); 155 | 156 | if (witherStart == null) { 157 | witherStart = EntityWitherSkull.getConstructor(World).newInstance(worldStart); 158 | } 159 | 160 | if (witherEnd == null) { 161 | witherEnd = EntityWitherSkull.getConstructor(World).newInstance(worldEnd); 162 | } 163 | 164 | if (batStart == null) { 165 | batStart = EntityBat.getConstructor(World).newInstance(worldStart); 166 | } 167 | 168 | if (batEnd == null) { 169 | batEnd = EntityBat.getConstructor(World).newInstance(worldEnd); 170 | } 171 | 172 | setLocation(witherStart, getLocation(Type.Start)); 173 | setLocation(witherEnd, getLocation(Type.End)); 174 | setLocation(batStart, getLocation(Type.Start)); 175 | setLocation(batEnd, getLocation(Type.End)); 176 | 177 | setLeashHolder(batStart, batEnd, true); // try with false 178 | 179 | this.witherSkulls.put(Type.Start, witherStart); 180 | this.witherSkulls.put(Type.End, witherEnd); 181 | this.bats.put(Type.Start, batStart); 182 | this.bats.put(Type.End, batEnd); 183 | } catch (Exception e) { 184 | e.printStackTrace(); 185 | } 186 | } 187 | 188 | //********************************************** 189 | // Reflection based methods... 190 | //********************************************** 191 | 192 | private static void sendPackets(Player player, Object... packets) { 193 | for (Object packet : packets) { 194 | sendPacket(player, packet); 195 | } 196 | } 197 | 198 | private static Class getCraftClass(String name) { 199 | Class clazz = null; 200 | try { 201 | clazz = Class.forName("org.bukkit.craftbukkit." + VERSION + "." + name); 202 | } catch (Exception e) { 203 | e.printStackTrace(); 204 | } 205 | 206 | return clazz; 207 | } 208 | 209 | private static Class getNMSClass(String name) { 210 | Class clazz = null; 211 | try { 212 | clazz = Class.forName("net.minecraft.server." + VERSION + "." + name); 213 | } catch (Exception e) { 214 | e.printStackTrace(); 215 | } 216 | return clazz; 217 | } 218 | 219 | private static Object getHandle(Object obj) { 220 | try { 221 | return obj.getClass().getMethod("getHandle").invoke(obj); 222 | } catch (Exception e) { 223 | e.printStackTrace(); 224 | } 225 | return null; 226 | } 227 | 228 | private static Object getPlayerConnection(Player player) { 229 | try { 230 | Object handle = getHandle(player); 231 | return handle.getClass().getField("playerConnection").get(handle); 232 | } catch (Exception e) { 233 | e.printStackTrace(); 234 | } 235 | 236 | return null; 237 | } 238 | 239 | private static void setLeashHolder(Object EntityInsentient, Object Entity, boolean xxx) { 240 | try { 241 | Class EntityClass = getNMSClass("Entity"); 242 | Method setLeashHolder = EntityInsentient.getClass().getMethod("setLeashHolder", new Class[] { EntityClass, boolean.class }); 243 | setLeashHolder.invoke(EntityInsentient, new Object[] { Entity, xxx }); 244 | } catch (Exception e) { 245 | e.printStackTrace(); 246 | } 247 | } 248 | 249 | private static void setLocation(Object entity, Location loc) { 250 | try { 251 | Method setLocation = entity.getClass().getMethod("setLocation", new Class[] { double.class, double.class, double.class, float.class, float.class }); 252 | setLocation.invoke(entity, loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch()); 253 | } catch (Exception e) { 254 | e.printStackTrace(); 255 | } 256 | } 257 | 258 | private static void sendPacket(Player player, Object packet) { 259 | try { 260 | Class Packet = getNMSClass("Packet"); 261 | Object playerConnection = getPlayerConnection(player); 262 | playerConnection.getClass().getMethod("sendPacket", Packet).invoke(playerConnection, packet); 263 | } catch (Exception e) { 264 | e.printStackTrace(); 265 | } 266 | } 267 | } 268 | -------------------------------------------------------------------------------- /src/main/java/theories/AwesomeLoader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2014 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package theories; 26 | 27 | import java.io.File; 28 | import java.net.MalformedURLException; 29 | import java.net.URL; 30 | import java.net.URLClassLoader; 31 | import java.util.ArrayList; 32 | import java.util.List; 33 | import java.util.logging.Level; 34 | import java.util.logging.Logger; 35 | 36 | /** 37 | * 38 | * @author Goblom 39 | */ 40 | public class AwesomeLoader { 41 | 42 | private transient Object[] v; 43 | private final Object[] EMPTY_VALUE = {}; 44 | 45 | public AwesomeLoader() { 46 | v = EMPTY_VALUE; 47 | } 48 | 49 | public AwesomeLoader(Object v) { 50 | this.v = new Object[] { v }; 51 | } 52 | 53 | public V loadFile(File file) { 54 | V c = null; 55 | if (!file.getName().endsWith(".class")) { 56 | return c; 57 | } 58 | String name = file.getName().substring(0, file.getName().lastIndexOf(".")); 59 | 60 | ClassLoader loader; 61 | 62 | try { 63 | loader = new URLClassLoader(new URL[] { file.toURI().toURL() }, ((V) v[0]).getClass().getClassLoader()); 64 | } catch (MalformedURLException e) { 65 | log("Error while loading ClassLoader."); 66 | return c; 67 | } 68 | try { 69 | Class clazz = loader.loadClass(name); 70 | Object obj = clazz.newInstance(); 71 | 72 | //Need to check instanceof here but unable to tackle the problem. 73 | log("Loaded class: " + ((V) obj).getClass().getSimpleName()); 74 | c = (V) obj; 75 | } catch (ClassNotFoundException ex) { 76 | Logger.getLogger(AwesomeLoader.class.getName()).log(Level.SEVERE, null, ex); 77 | } catch (InstantiationException ex) { 78 | Logger.getLogger(AwesomeLoader.class.getName()).log(Level.SEVERE, null, ex); 79 | } catch (IllegalAccessException ex) { 80 | Logger.getLogger(AwesomeLoader.class.getName()).log(Level.SEVERE, null, ex); 81 | } 82 | return c; 83 | } 84 | 85 | public V loadFile(String file) { 86 | return loadFile(new File(file)); 87 | } 88 | 89 | public List loadDirectory(File dir) { 90 | List list = new ArrayList(); 91 | 92 | if (!dir.exists()) { 93 | log("Unable to load files from directory. Does Directory exist?"); 94 | return list; 95 | } 96 | 97 | if (dir.isDirectory()) { 98 | ClassLoader loader; 99 | try { 100 | loader = new URLClassLoader(new URL[] { dir.toURI().toURL() }, ((V) v[0]).getClass().getClassLoader()); 101 | } catch (MalformedURLException e) { 102 | log("Error while loading ClassLoader."); 103 | return list; 104 | } 105 | 106 | for (File file : dir.listFiles()) { 107 | if (!file.getName().endsWith(".class")) { 108 | continue; //We only want to load class files 109 | } 110 | String name = file.getName().substring(0, file.getName().lastIndexOf(".")); 111 | 112 | try { 113 | Class clazz = loader.loadClass(name); 114 | Object obj = clazz.newInstance(); 115 | 116 | //Need to check instanceof here but unable to tackle the problem. 117 | list.add((V) obj); 118 | log("Loaded class: " + ((V) obj).getClass().getSimpleName()); 119 | } catch (ClassNotFoundException ex) { 120 | Logger.getLogger(AwesomeLoader.class.getName()).log(Level.SEVERE, null, ex); 121 | } catch (InstantiationException ex) { 122 | Logger.getLogger(AwesomeLoader.class.getName()).log(Level.SEVERE, null, ex); 123 | } catch (IllegalAccessException ex) { 124 | Logger.getLogger(AwesomeLoader.class.getName()).log(Level.SEVERE, null, ex); 125 | } 126 | } 127 | } 128 | return list; 129 | } 130 | 131 | public List loadDirectory(String directory) { 132 | return loadDirectory(new File(directory)); 133 | } 134 | 135 | private void log(String message) { 136 | Logger.getLogger("AwesomeLoader").warning(message); 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/main/java/theories/TellRaw.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2013 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package theories; 26 | 27 | import java.util.ArrayList; 28 | import java.util.List; 29 | import org.bukkit.ChatColor; 30 | import org.bukkit.entity.Player; 31 | import org.bukkit.inventory.ItemStack; 32 | 33 | import net.minecraft.server.v1_7_R4.ChatSerializer; 34 | import net.minecraft.server.v1_7_R4.PacketPlayOutChat; 35 | import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer; 36 | 37 | //import com.comphenix.protocol.PacketType; 38 | //import com.comphenix.protocol.ProtocolLibrary; 39 | //import com.comphenix.protocol.ProtocolManager; 40 | //import com.comphenix.protocol.events.PacketContainer; 41 | //import com.comphenix.protocol.wrappers.WrappedChatComponent; 42 | //import java.lang.reflect.InvocationTargetException; 43 | 44 | /** 45 | * 46 | * @author Goblom 47 | */ 48 | public class TellRaw { 49 | private final List messages = new ArrayList(); 50 | 51 | public TellRaw(String... message) { 52 | for (String m : message) { 53 | messages.add("text:\"" + m + "\","); 54 | } 55 | } 56 | 57 | public TellRaw addFormat(int messageIndex, Format format) { 58 | String oldMessage = messages.get(messageIndex); 59 | messages.set(messageIndex, oldMessage + format.getFormat() + ":" + true + ","); 60 | return this; 61 | } 62 | 63 | public TellRaw addColor(int messageIndex, ChatColor color) { 64 | String oldMessage = messages.get(messageIndex); 65 | messages.set(messageIndex, oldMessage + "color:" + color.name().toLowerCase() + ","); 66 | return this; 67 | } 68 | 69 | public TellRaw addClickEvent(int messageIndex, Action action, String value) { 70 | String oldMessage = messages.get(messageIndex); 71 | messages.set(messageIndex, oldMessage + "clickEvent:{action:" + action.getAction() + ",value:\"" + value + "\"}"); 72 | return this; 73 | } 74 | 75 | public TellRaw addHoverEvent(int messageIndex, Action action, String value) { 76 | String oldMessage = messages.get(messageIndex); 77 | messages.set(messageIndex, oldMessage + "hoverEvent:{action:" + action.getAction() + ",value:\"" + value + "\"}"); 78 | return this; 79 | } 80 | 81 | public String itemToJSON(ItemStack i) { 82 | String json = "{id:" + i.getTypeId() + ","; 83 | if (i.hasItemMeta()) { 84 | json = json + "tag:{display:{"; 85 | if (i.getItemMeta().hasDisplayName()) { 86 | json = json + "Name:" + i.getItemMeta().getDisplayName() + ","; 87 | } 88 | if (i.getItemMeta().hasLore()) { 89 | String lores = "Lore:["; 90 | for (String lore : i.getItemMeta().getLore()) { 91 | lores = "\"" + lore + "\"" + ","; 92 | } 93 | json = json + lores; 94 | } 95 | json = json + "]}}"; 96 | } 97 | return json + "}"; 98 | } 99 | 100 | public enum Format { 101 | BOLD("bold"), 102 | UNDERLINED("underlined"), 103 | ITALIC("italic"), 104 | STRIKETHROUGH("strikethrough"), 105 | OBFUSTICATED("obfusticated"); 106 | private final String format; 107 | Format(String format) { this.format = format; } 108 | public String getFormat() { return format; } 109 | } 110 | 111 | public enum Action { 112 | RUN_COMMAND("run_command"), 113 | SHOW_TEXT("show_text"), 114 | SHOW_ITEM("show_item"), 115 | SHOW_ACHIEVEMENT("show_achievement"), 116 | SUGGEST_COMMAND("suggest_command"), 117 | OPEN_URL("open_url"); 118 | 119 | private final String action; 120 | Action(String action) { this.action = action; } 121 | public String getAction() { return action; } 122 | } 123 | 124 | private String removeExcess(String message) { //Fixes extra commas that have been added 125 | return message.replaceAll(",]", "]").replaceAll(",}", "}"); 126 | } 127 | 128 | public List getMessages() { 129 | return messages; 130 | } 131 | 132 | public String[] getMessagesAsArray() { 133 | return messages.toArray(new String[0]); 134 | } 135 | 136 | public void send(Player player) { 137 | ((CraftPlayer) player).getHandle().playerConnection.sendPacket(new PacketPlayOutChat(ChatSerializer.a(toString()), true)); 138 | } 139 | 140 | // public void send(Player player) { 141 | // ProtocolManager manager = ProtocolLibrary.getProtocolManager(); 142 | // PacketContainer messagePacket = manager.createPacket(PacketType.Play.Server.CHAT); 143 | // messagePacket.getChatComponents().write(0, WrappedChatComponent.fromJson(toString())); 144 | // try { 145 | // manager.sendServerPacket(player, messagePacket); 146 | // } catch (InvocationTargetException e) { 147 | // e.printStackTrace(); 148 | // } 149 | // } 150 | 151 | @Override 152 | public String toString() { 153 | String message = "{"; 154 | for (String m : messages) { 155 | if (message.equals("{")) { 156 | message = message + m + ",extra:["; 157 | } else { 158 | message = "{" + message + m + "},"; 159 | } 160 | } 161 | return removeExcess(message + "}"); 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /src/main/java/thread/Download.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2013 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package thread; 26 | 27 | import java.io.BufferedInputStream; 28 | import java.io.BufferedOutputStream; 29 | import java.io.FileOutputStream; 30 | import java.io.IOException; 31 | import java.net.HttpURLConnection; 32 | import java.net.MalformedURLException; 33 | import java.net.URL; 34 | import java.util.logging.Level; 35 | import java.util.logging.Logger; 36 | 37 | /** 38 | * 39 | * @author Goblom 40 | */ 41 | public class Download implements Runnable { 42 | private final String link, path; 43 | private final boolean print; 44 | 45 | public Download(String link, String path, boolean printStatus) { 46 | this.link = link; 47 | this.path = path; 48 | this.print = printStatus; 49 | } 50 | 51 | @Override 52 | public void run() { 53 | try { 54 | if (print) System.out.println("[Download] File: " + link); 55 | if (print) System.out.println("[Download] Save To: " + path); 56 | 57 | URL url = new URL(link); 58 | HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 59 | BufferedInputStream bis = new BufferedInputStream(conn.getInputStream()); 60 | FileOutputStream fos = new FileOutputStream(path); 61 | BufferedOutputStream bos = new BufferedOutputStream(fos, 1024); 62 | 63 | float dataRead = 0; 64 | byte[] b = new byte[1024]; 65 | int i = 0; 66 | 67 | while ((i = bis.read(b, 0, 1024)) >= 0) { 68 | dataRead++; //dataRead = dataRead + 1; 69 | if (print) System.out.println("[Download] Downloaded: " + dataRead); 70 | bos.write(b, 0, i); 71 | } 72 | 73 | bos.close(); 74 | fos.close(); 75 | bis.close(); 76 | 77 | if (print) System.out.println("[Download] File Downloaded!"); 78 | } catch (MalformedURLException e) { e.printStackTrace(); 79 | } catch (IOException e) { e.printStackTrace(); } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/thread/QueryPool.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2014 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package thread; 25 | 26 | import com.google.common.collect.Lists; 27 | import java.sql.Connection; 28 | import java.sql.ResultSet; 29 | import java.sql.SQLException; 30 | import java.util.List; 31 | 32 | /** 33 | * QueryPool v1.0 34 | * 35 | * This will make threaded queries to an SQL connection and feed results through 36 | * a {@link DataHandler} for you to interpret 37 | * 38 | * @author Goblom 39 | */ 40 | public class QueryPool { 41 | 42 | /** 43 | * Keep this class entirely static 44 | */ 45 | private QueryPool() { } 46 | 47 | static { 48 | QueryPool.thread = new SQLThread(); 49 | QueryPool.thread.start(); 50 | 51 | QueryPool.toMake = Lists.newArrayList(); 52 | QueryPool.queriesMade = 0; 53 | QueryPool.queriesFailed = 0; 54 | QueryPool.waitTime = 1000; 55 | } 56 | 57 | /** 58 | * The thread task that runs all the queries 59 | */ 60 | private static SQLThread thread; 61 | 62 | /** 63 | * A List of all scheduled queries to be ran 64 | */ 65 | private static List toMake; 66 | 67 | /** 68 | * A counter to count the amount of queries made... because stats 69 | */ 70 | private static long queriesMade; 71 | 72 | /** 73 | * A counter to count the amount of queries failed... because stats 74 | */ 75 | private static long queriesFailed; 76 | 77 | /** 78 | * The amount of time the {@link QueryThread#thread} should wait before 79 | * running another query task 80 | */ 81 | private static long waitTime; 82 | 83 | /** 84 | * Stop the {@link SQLThread} 85 | * 86 | * @param andFinishAllQueries should we run all remaining SQL queries before 87 | * stopping the thread 88 | */ 89 | public static void stopThread(boolean andFinishAllQueries) { 90 | QueryPool.SQLThread.instantiated = false; 91 | 92 | if (andFinishAllQueries) { 93 | QueryPool.thread.wait = false; 94 | 95 | while (!toMake.isEmpty()) { 96 | doQuery(); 97 | } 98 | } 99 | 100 | QueryPool.thread.interrupt(); 101 | QueryPool.thread = null; 102 | } 103 | 104 | /** 105 | * If you have stopped the thread with 106 | * {@link QueryThread#stopThread(boolean)} you can use this to start the 107 | * thread again 108 | */ 109 | public static void startThread() { 110 | if (QueryPool.thread != null || QueryPool.thread.hasStarted()) { 111 | return; 112 | } 113 | 114 | QueryPool.thread = new SQLThread(); 115 | QueryPool.thread.start(); 116 | } 117 | 118 | /** 119 | * Set how long the {@link SQLThread} should wait before running another 120 | * query task 121 | * 122 | * @param time How long the {@link SQLThread} should wait 123 | */ 124 | public static void setWaitTime(long time) { 125 | if (time == 0) { 126 | return; 127 | } 128 | QueryPool.waitTime = time; 129 | } 130 | 131 | /** 132 | * @see QueryThread#queriesFailed 133 | * 134 | * @return The amount of queries that have failed 135 | */ 136 | public static long queriesFailed() { 137 | return QueryPool.queriesFailed; 138 | } 139 | 140 | /** 141 | * @see QueryThread#queriesMade 142 | * 143 | * @return The amount of queries that have been made 144 | */ 145 | public static long queriesMade() { 146 | return QueryPool.queriesMade; 147 | } 148 | 149 | /** 150 | * How many queries are left to be ran 151 | * 152 | * @return The size of the query pool 153 | */ 154 | public static int queryPool() { 155 | return QueryPool.toMake.size(); 156 | } 157 | 158 | /** 159 | * Schedule a query to be ran inside the {@link SQLThread} later on 160 | * 161 | * @param conn The SQL Connection to the sql query on 162 | * @param sql The SQL Query to run on the connection 163 | * @param handler The {@link DataHandler} to handle the data that is 164 | * received through the query. 165 | */ 166 | public static void scheduleQuery(Connection conn, String sql, DataHandler handler) { 167 | QueryPool.toMake.add(new Query(conn, sql, handler)); 168 | } 169 | 170 | /** 171 | * A simple way of getting the first query of {@link QueryThread#toMake} and 172 | * removing it in order to have a sort of progression 173 | * 174 | * @return The first {@link Query} in {@link QueryThread#toMake} returns 175 | * null if there is no query or there was an exception thrown 176 | */ 177 | private static Query getFirst() { 178 | try { 179 | return QueryPool.toMake.remove(0); 180 | } catch (Exception e) { } 181 | return null; 182 | } 183 | 184 | /** 185 | * The Method that runs the first {@link Query} in the 186 | * {@link QueryThread#queryPool()} 187 | */ 188 | private static void doQuery() { 189 | QueryPool.Query query = QueryPool.getFirst(); 190 | 191 | if (query == null) { 192 | return; 193 | } 194 | 195 | try { 196 | String sql = query.getQuery(); 197 | DataHandler handler = query.getHandler(); 198 | Connection conn = query.getConnection(); 199 | 200 | handler.start = System.currentTimeMillis(); 201 | handler.onQuery(sql); 202 | ResultSet rs = null; 203 | 204 | try { 205 | rs = conn.prepareStatement(sql).executeQuery(); 206 | } catch (SQLException e) { 207 | handler.sqlException = e; 208 | QueryPool.queriesFailed++; 209 | } 210 | 211 | handler.end = System.currentTimeMillis(); 212 | handler.onDataRecieved(rs == null, rs); 213 | } catch (Exception e) { 214 | QueryPool.queriesFailed++; 215 | e.printStackTrace(); 216 | } 217 | 218 | QueryPool.queriesMade++; 219 | } 220 | 221 | /** 222 | * Read and interpret data that is fed from the {@link Query} 223 | */ 224 | public static class DataHandler { 225 | 226 | private SQLException sqlException = null; 227 | private long start, end; 228 | 229 | /** 230 | * The time that the {@link Query} started 231 | * 232 | * @return 233 | */ 234 | public final long getStartTime() { 235 | return start; 236 | } 237 | 238 | /** 239 | * The time that {@link Query} finished 240 | * 241 | * @return 242 | */ 243 | public final long getEndTime() { 244 | return end; 245 | } 246 | 247 | /** 248 | * The {@link SQLException} that was generated by the query if it failed 249 | * 250 | * @return the {@link SQLException} that was generated if the query 251 | * failed 252 | */ 253 | public final SQLException getException() { 254 | return sqlException; 255 | } 256 | 257 | /** 258 | * @param sqlQuery The SQL query to be made on the {@link Connection} 259 | */ 260 | public void onQuery(String sqlQuery) { } 261 | 262 | /** 263 | * When the query is finished the data is fed through this 264 | * 265 | * @param failed If the resultset is null or there was an 266 | * {@link SQLException} 267 | * @param rs The return data from the SQL query on the 268 | * {@link Connection} 269 | */ 270 | public void onDataRecieved(boolean failed, ResultSet rs) { } 271 | } 272 | 273 | /** 274 | * This is a handler class to hold all the data of a 275 | * {@link QueryThread#scheduleQuery(java.sql.Connection, java.lang.String, org.goblom.bukkitlibs.thread.QueryThread.DataHandler)} 276 | */ 277 | private static class Query { 278 | 279 | private final String sql; 280 | private final DataHandler handler; 281 | private final Connection connection; 282 | 283 | /** 284 | * Do not allow any outside forces instantiate this class 285 | * 286 | * @param conn The connection that is used to run the SQL query 287 | * @param sql The SQL Query to be made on the connection 288 | * @param handler The handler that is fed all the data from the Result 289 | */ 290 | private Query(Connection conn, String sql, DataHandler handler) { 291 | this.connection = conn; 292 | this.sql = sql; 293 | this.handler = handler; 294 | } 295 | 296 | /** 297 | * @return The stored connection 298 | */ 299 | public Connection getConnection() { 300 | return this.connection; 301 | } 302 | 303 | /** 304 | * @return The SQL Query to be made on the {@link Query#getConnection()} 305 | */ 306 | public String getQuery() { 307 | return this.sql; 308 | } 309 | 310 | /** 311 | * @return The {@link DataHandler} that is fed all the data collected 312 | */ 313 | public DataHandler getHandler() { 314 | return this.handler; 315 | } 316 | } 317 | 318 | /** 319 | * The SQL Thread that runs all the {@link Query} from the 320 | * {@link QueryThread#queryPool()} 321 | */ 322 | private static class SQLThread extends Thread { 323 | 324 | /** 325 | * Is thread already created 326 | */ 327 | private static boolean instantiated = false; 328 | 329 | /** 330 | * Has thread started? 331 | */ 332 | private boolean started = false; 333 | 334 | /** 335 | * Should thread wait before running another {@link Query} 336 | */ 337 | private boolean wait = true; 338 | 339 | /** 340 | * Do not allow any outside forces instantiate this class 341 | */ 342 | private SQLThread() { 343 | if (SQLThread.instantiated) { 344 | //if already created do not allow it to be created again 345 | throw new UnsupportedOperationException("The SQL Thread is already running!"); 346 | } 347 | 348 | QueryPool.SQLThread.instantiated = true; 349 | setName("Threaded SQL Querying"); 350 | } 351 | 352 | /** 353 | * Check if thread has started 354 | * 355 | * @return true if thread has started 356 | */ 357 | public boolean hasStarted() { 358 | return this.started; 359 | } 360 | 361 | /** 362 | * Start the {@link SQLThread} 363 | */ 364 | @Override 365 | public void start() { 366 | if (this.started) { 367 | throw new UnsupportedOperationException("The SQLThread is already running!"); 368 | } 369 | 370 | this.started = true; 371 | super.start(); 372 | } 373 | 374 | /** 375 | * The Task that runs all the {@link Query} and waits if told so 376 | */ 377 | @Override 378 | public void run() { 379 | QueryPool.doQuery(); 380 | 381 | if (this.wait) { 382 | try { 383 | sleep(QueryPool.waitTime); 384 | } catch (Exception e) { 385 | e.printStackTrace(); 386 | } 387 | } 388 | } 389 | 390 | } 391 | } 392 | -------------------------------------------------------------------------------- /src/main/java/thread/SimpleTimer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2014 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package thread; 25 | 26 | import org.bukkit.Bukkit; 27 | import org.bukkit.plugin.Plugin; 28 | import org.bukkit.scheduler.BukkitTask; 29 | 30 | /** 31 | * 32 | * @author Goblom 33 | */ 34 | public class SimpleTimer { 35 | 36 | private final int runTime; 37 | private final Plugin plugin; 38 | 39 | private Runner runner; 40 | private BukkitTask runnerTask, endTask; 41 | 42 | public SimpleTimer(Plugin plugin, int runTime) { 43 | this(plugin, runTime, null); 44 | } 45 | 46 | public SimpleTimer(Plugin plugin, int runTime, Runner runner) { 47 | this(plugin, runTime, runner, false); 48 | } 49 | 50 | public SimpleTimer(Plugin plugin, int runTime, Runner runner, boolean start) { 51 | this.runTime = runTime * 20; 52 | this.runner = runner; 53 | this.plugin = plugin; 54 | 55 | if (start) { 56 | try { 57 | startRunning(); 58 | } catch (InvalidRunnerException e) { 59 | e.printStackTrace(); 60 | } 61 | } 62 | } 63 | 64 | public int getRunTime() { 65 | return runTime; 66 | } 67 | 68 | public void setRunner(Runner runner) { 69 | this.runner = runner; 70 | } 71 | 72 | public void startRunning() throws InvalidRunnerException { 73 | if (runner != null) { 74 | if (runnerTask != null) { 75 | getRunningTask().cancel(); 76 | this.runnerTask = null; 77 | } 78 | if (endTask != null) { 79 | endTask.cancel(); 80 | this.endTask = null; 81 | } 82 | 83 | this.runnerTask = Bukkit.getScheduler().runTaskTimer(plugin, 84 | new Runnable() { 85 | public void run() { 86 | getRunner().onRun(); 87 | } 88 | }, 89 | -1, 20); 90 | this.endTask = Bukkit.getScheduler().runTaskLater(plugin, 91 | new Runnable() { 92 | public void run() { 93 | getRunningTask().cancel(); 94 | getRunner().onEnd(); 95 | } 96 | }, runTime); 97 | 98 | } else { 99 | throw new InvalidRunnerException("No runner detected, unable to start running!"); 100 | } 101 | } 102 | 103 | public BukkitTask getRunningTask() { 104 | return runnerTask; 105 | } 106 | 107 | public Runner getRunner() { 108 | return runner; 109 | } 110 | 111 | public void cancelRunning() { 112 | getRunningTask().cancel(); 113 | endTask.cancel(); 114 | } 115 | 116 | public interface Runner { 117 | 118 | void onRun(); 119 | 120 | void onEnd(); 121 | } 122 | 123 | public class InvalidRunnerException extends Exception { 124 | 125 | public InvalidRunnerException(String message) { 126 | super(message); 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/main/java/thread/TestImage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2013 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package thread; 26 | 27 | import java.awt.Image; 28 | import java.io.File; 29 | import java.io.IOException; 30 | import javax.imageio.ImageIO; 31 | 32 | /** 33 | * 34 | * @author Goblom 35 | */ 36 | public class TestImage implements Runnable { 37 | 38 | private final File file; 39 | private boolean isImage = false; 40 | 41 | public TestImage(File file) { 42 | this.file = file; 43 | } 44 | 45 | public void run() { 46 | try { 47 | Image image = ImageIO.read(file); 48 | if (image != null) { isImage = true; } 49 | } catch (IOException e) { e.printStackTrace(); } 50 | } 51 | 52 | public boolean isImage() { 53 | return isImage; 54 | } 55 | 56 | public File getFile() { 57 | return file; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/thread/TextReader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2014 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package thread; 26 | 27 | import com.google.common.collect.Lists; 28 | import java.io.BufferedReader; 29 | import java.io.IOException; 30 | import java.io.InputStreamReader; 31 | import java.net.MalformedURLException; 32 | import java.net.URL; 33 | import java.util.List; 34 | 35 | /** 36 | * 37 | * @author Goblom 38 | */ 39 | public class TextReader { 40 | 41 | public static void read(String url, ReceiveHandler handler) throws MalformedURLException, IOException { 42 | read(new URL(url), handler); 43 | } 44 | 45 | public static void read(final URL url, final ReceiveHandler handler) { 46 | final List lines = Lists.newArrayList(); 47 | 48 | new Thread( 49 | new Runnable() { 50 | public void run() { 51 | BufferedReader reader = null; 52 | 53 | try { 54 | reader = new BufferedReader(new InputStreamReader(url.openStream())); 55 | } catch (Exception e) { 56 | e.printStackTrace(); 57 | } 58 | 59 | if (reader != null) { 60 | try { 61 | while (reader.readLine() != null) { 62 | lines.add(reader.readLine()); 63 | } 64 | 65 | reader.close(); 66 | } catch (Exception e) { 67 | e.printStackTrace(); 68 | } 69 | } 70 | 71 | handler.onRecieve(lines); 72 | } 73 | } 74 | ).start(); 75 | } 76 | 77 | public static interface ReceiveHandler { 78 | public void onRecieve(List lines); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/utils/ChestUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2014 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package utils; 25 | 26 | import com.google.common.collect.Lists; 27 | import java.lang.reflect.Field; 28 | import java.util.List; 29 | import java.util.Random; 30 | import org.bukkit.Bukkit; 31 | import org.bukkit.Chunk; 32 | import org.bukkit.World; 33 | import org.bukkit.block.BlockState; 34 | import org.bukkit.block.Chest; 35 | import org.bukkit.inventory.Inventory; 36 | import org.bukkit.inventory.ItemStack; 37 | 38 | /** 39 | * 40 | * @author Goblom 41 | */ 42 | public class ChestUtils { 43 | 44 | private static Random RANDOM = new Random(); 45 | 46 | private static String getVersion() { 47 | return Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3]; 48 | } 49 | 50 | private static Class getMCClass(String name) throws ClassNotFoundException { 51 | return Class.forName("net.minecraft.server." + getVersion() + "." + name); 52 | } 53 | 54 | private static Class getCraftClass(String name) throws ClassNotFoundException { 55 | return Class.forName("org.bukkit.craftbukkit." + getVersion() + "." + name); 56 | } 57 | 58 | public static void fillChests(World world, ItemStack... items) { 59 | for (Chunk chunk : world.getLoadedChunks()) { 60 | for (BlockState state : chunk.getTileEntities()) { 61 | if (!(state instanceof Chest)) continue; 62 | fillChest((Chest) state, items); 63 | } 64 | } 65 | } 66 | 67 | public static void fillChest(Chest chest, ItemStack[] items) { 68 | List filled = Lists.newArrayList(); 69 | 70 | Inventory inv = chest.getInventory(); 71 | inv.clear(); 72 | 73 | int size = inv.getSize(); 74 | 75 | for (int i = 0; i < items.length; i++) { 76 | int slot = RANDOM.nextInt(size); 77 | 78 | while (filled.contains(slot)) { 79 | slot = RANDOM.nextInt(size); 80 | } 81 | 82 | filled.add(slot); 83 | inv.setItem(slot, items[i]); 84 | } 85 | } 86 | 87 | public static void changeName(Inventory inv, String newName) throws Exception { 88 | Class MinecraftInventory = getCraftClass("inventory.CraftInventoryCustom.MinecraftInventory"); 89 | 90 | Field title = MinecraftInventory.getDeclaredField("title"); 91 | title.setAccessible(true); 92 | 93 | title.set(inv, newName); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/utils/Cooldowns.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2014 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package utils; 26 | 27 | import com.google.common.collect.Maps; 28 | import java.util.Collections; 29 | import java.util.List; 30 | import java.util.Map; 31 | import java.util.UUID; 32 | import net.minecraft.util.com.google.common.collect.Lists; 33 | import org.bukkit.Bukkit; 34 | import org.bukkit.entity.Player; 35 | import org.bukkit.event.Cancellable; 36 | import org.bukkit.event.Event; 37 | import org.bukkit.event.HandlerList; 38 | import org.bukkit.plugin.java.JavaPlugin; 39 | import org.bukkit.scheduler.BukkitRunnable; 40 | 41 | /** 42 | * 43 | * @author Goblom 44 | */ 45 | public class Cooldowns { 46 | 47 | private static final JavaPlugin PLUGIN = JavaPlugin.getProvidingPlugin(Cooldowns.class); 48 | private static final Map> cooldown_holder = Maps.newHashMap(); 49 | 50 | public static Cooldown prepare(Player player, String cooldownName, int seconds) { 51 | Map player_cooldowns = (cooldown_holder.get(player.getUniqueId()) == null ? Maps.newHashMap() : cooldown_holder.get(player.getUniqueId())); 52 | 53 | Cooldown cooldown = new Cooldown(); 54 | cooldown.secondsLeft = seconds; 55 | cooldown.uuid = player.getUniqueId(); 56 | cooldown.name = cooldownName; 57 | cooldown.started = false; 58 | cooldown.onlyOnline = false; 59 | 60 | player_cooldowns.put(cooldownName, cooldown); 61 | cooldown_holder.put(player.getUniqueId(), player_cooldowns); 62 | 63 | return cooldown; 64 | } 65 | 66 | public static void removeCooldown(Player player, String cooldownName) { 67 | Map player_cooldowns = (cooldown_holder.get(player.getUniqueId()) == null ? Maps.newHashMap() : cooldown_holder.get(player.getUniqueId())); 68 | 69 | player_cooldowns.remove(cooldownName); 70 | cooldown_holder.put(player.getUniqueId(), player_cooldowns); 71 | } 72 | 73 | public static Cooldown getCooldown(Player player, String cooldownName) { 74 | Map player_cooldowns = (cooldown_holder.get(player.getUniqueId()) == null ? Maps.newHashMap() : cooldown_holder.get(player.getUniqueId())); 75 | 76 | return player_cooldowns.get(cooldownName); 77 | } 78 | 79 | public static List getCooldowns(Player player) { 80 | List list = Lists.newArrayList(); 81 | Map player_cooldowns = (cooldown_holder.get(player.getUniqueId()) == null ? Maps.newHashMap() : cooldown_holder.get(player.getUniqueId())); 82 | list.addAll(player_cooldowns.values()); 83 | return Collections.unmodifiableList(list); 84 | } 85 | 86 | public static List getCooldownsWithSecondsLeft(Player player) { 87 | List list = Lists.newArrayList(); 88 | for (Cooldown cd : getCooldowns(player)) { 89 | if (cd.hasTimeLeft()) { 90 | list.add(cd); 91 | } 92 | } 93 | 94 | return Collections.unmodifiableList(list); 95 | } 96 | 97 | public static class Cooldown { 98 | 99 | private int secondsLeft; 100 | private UUID uuid; 101 | private boolean started; 102 | private String name; 103 | private CooldownRunner runner; 104 | private boolean onlyOnline; 105 | 106 | private Cooldown() { 107 | } 108 | 109 | public String getName() { 110 | return this.name; 111 | } 112 | 113 | public Player getPlayer() { 114 | return Bukkit.getPlayer(uuid); 115 | } 116 | 117 | public int getSecondsLeft() { 118 | return this.secondsLeft; 119 | } 120 | 121 | public boolean hasTimeLeft() { 122 | return getSecondsLeft() != 0; 123 | } 124 | 125 | public boolean hasStarted() { 126 | return this.started; 127 | } 128 | 129 | public boolean onlyCountdownIfOnline() { 130 | return this.onlyOnline; 131 | } 132 | 133 | public void setSecondsLeft(int secondsLeft) { 134 | this.secondsLeft = secondsLeft; 135 | } 136 | 137 | public void onlyCountdownWhenOnline(boolean b) { 138 | this.onlyOnline = b; 139 | } 140 | 141 | public void delete() { 142 | Cooldowns.removeCooldown(getPlayer(), getName()); 143 | } 144 | 145 | public Cooldown start() { 146 | if (!hasStarted() && this.runner == null) { 147 | CooldownStartEvent event = new CooldownStartEvent(this); 148 | Bukkit.getPluginManager().callEvent(event); 149 | if (!event.isCancelled()) { 150 | this.runner = new CooldownRunner(this); 151 | this.runner.runTaskTimerAsynchronously(PLUGIN, -1, 20); 152 | } 153 | } 154 | 155 | return this; 156 | } 157 | 158 | public void forceStop() { 159 | if (hasStarted() && this.runner != null) { 160 | this.runner.cancel(); 161 | this.runner = null; 162 | } 163 | } 164 | } 165 | 166 | private static class CooldownRunner extends BukkitRunnable { 167 | 168 | private final Cooldown cooldown; 169 | 170 | CooldownRunner(Cooldown cooldown) { 171 | this.cooldown = cooldown; 172 | } 173 | 174 | public void run() { 175 | if (cooldown.secondsLeft == 0) { 176 | Bukkit.getPluginManager().callEvent(new CooldownFinishEvent(cooldown)); 177 | cancel(); 178 | return; 179 | } 180 | 181 | if (cooldown.onlyOnline) { 182 | if (cooldown.getPlayer() == null) { 183 | return; 184 | } 185 | } 186 | 187 | cooldown.secondsLeft--; 188 | } 189 | } 190 | 191 | public static class CooldownStartEvent extends Event implements Cancellable { 192 | 193 | private static final HandlerList handlers = new HandlerList(); 194 | private final Cooldown cooldown; 195 | private boolean cancelled = false; 196 | 197 | CooldownStartEvent(Cooldown cooldown) { 198 | this.cooldown = cooldown; 199 | } 200 | 201 | public Cooldown getCooldown() { 202 | return this.cooldown; 203 | } 204 | 205 | @Override 206 | public HandlerList getHandlers() { 207 | return handlers; 208 | } 209 | 210 | public static HandlerList getHandlerList() { 211 | return handlers; 212 | } 213 | 214 | public boolean isCancelled() { 215 | return this.cancelled; 216 | } 217 | 218 | public void setCancelled(boolean cancel) { 219 | this.cancelled = cancel; 220 | } 221 | } 222 | 223 | public static class CooldownFinishEvent extends Event { 224 | 225 | private static final HandlerList handlers = new HandlerList(); 226 | private final Cooldown cooldown; 227 | 228 | CooldownFinishEvent(Cooldown cooldown) { 229 | this.cooldown = cooldown; 230 | } 231 | 232 | public Cooldown getCooldown() { 233 | return this.cooldown; 234 | } 235 | 236 | @Override 237 | public HandlerList getHandlers() { 238 | return handlers; 239 | } 240 | 241 | public static HandlerList getHandlerList() { 242 | return handlers; 243 | } 244 | } 245 | } 246 | -------------------------------------------------------------------------------- /src/main/java/utils/CooldownsLite.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2014 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package utils; 26 | 27 | import com.google.common.collect.Maps; 28 | import java.util.Collections; 29 | import java.util.List; 30 | import java.util.Map; 31 | import java.util.UUID; 32 | import net.minecraft.util.com.google.common.collect.Lists; 33 | import org.bukkit.Bukkit; 34 | import org.bukkit.entity.Player; 35 | import org.bukkit.plugin.java.JavaPlugin; 36 | import org.bukkit.scheduler.BukkitRunnable; 37 | 38 | /** 39 | * 40 | * @author Goblom 41 | */ 42 | public class CooldownsLite { 43 | 44 | private static final JavaPlugin PLUGIN = JavaPlugin.getProvidingPlugin(CooldownsLite.class); 45 | private static final Map> cooldown_holder = Maps.newHashMap(); 46 | 47 | public static Cooldown prepare(Player player, String cooldownName, int seconds) { 48 | Map player_cooldowns = (cooldown_holder.get(player.getUniqueId()) == null ? Maps.newHashMap() : cooldown_holder.get(player.getUniqueId())); 49 | 50 | Cooldown cooldown = new Cooldown(); 51 | cooldown.secondsLeft = seconds; 52 | cooldown.uuid = player.getUniqueId(); 53 | cooldown.name = cooldownName; 54 | cooldown.started = false; 55 | cooldown.onlyOnline = false; 56 | 57 | player_cooldowns.put(cooldownName, cooldown); 58 | cooldown_holder.put(player.getUniqueId(), player_cooldowns); 59 | 60 | return cooldown; 61 | } 62 | 63 | public static void removeCooldown(Player player, String cooldownName) { 64 | Map player_cooldowns = (cooldown_holder.get(player.getUniqueId()) == null ? Maps.newHashMap() : cooldown_holder.get(player.getUniqueId())); 65 | 66 | player_cooldowns.remove(cooldownName); 67 | cooldown_holder.put(player.getUniqueId(), player_cooldowns); 68 | } 69 | 70 | public static Cooldown getCooldown(Player player, String cooldownName) { 71 | Map player_cooldowns = (cooldown_holder.get(player.getUniqueId()) == null ? Maps.newHashMap() : cooldown_holder.get(player.getUniqueId())); 72 | 73 | return player_cooldowns.get(cooldownName); 74 | } 75 | 76 | public static List getCooldowns(Player player) { 77 | List list = Lists.newArrayList(); 78 | Map player_cooldowns = (cooldown_holder.get(player.getUniqueId()) == null ? Maps.newHashMap() : cooldown_holder.get(player.getUniqueId())); 79 | list.addAll(player_cooldowns.values()); 80 | return Collections.unmodifiableList(list); 81 | } 82 | 83 | public static List getCooldownsWithSecondsLeft(Player player) { 84 | List list = Lists.newArrayList(); 85 | for (Cooldown cd : getCooldowns(player)) { 86 | if (cd.hasTimeLeft()) { 87 | list.add(cd); 88 | } 89 | } 90 | 91 | return Collections.unmodifiableList(list); 92 | } 93 | 94 | public static class Cooldown { 95 | private int secondsLeft; 96 | private UUID uuid; 97 | private boolean started; 98 | private String name; 99 | private CooldownRunner runner; 100 | private boolean onlyOnline; 101 | 102 | private Cooldown() {} 103 | 104 | public String getName() { 105 | return this.name; 106 | } 107 | 108 | public Player getPlayer() { 109 | return Bukkit.getPlayer(uuid); 110 | } 111 | 112 | public int getSecondsLeft() { 113 | return this.secondsLeft; 114 | } 115 | 116 | public boolean hasTimeLeft() { 117 | return getSecondsLeft() != 0; 118 | } 119 | 120 | public boolean hasStarted() { 121 | return this.started; 122 | } 123 | 124 | public boolean onlyCountdownIfOnline() { 125 | return this.onlyOnline; 126 | } 127 | 128 | public void setSecondsLeft(int secondsLeft) { 129 | this.secondsLeft = secondsLeft; 130 | } 131 | 132 | public void onlyCountdownWhenOnline(boolean b) { 133 | this.onlyOnline = b; 134 | } 135 | 136 | public void delete() { 137 | CooldownsLite.removeCooldown(getPlayer(), getName()); 138 | } 139 | 140 | public Cooldown start() { 141 | if (!hasStarted() && this.runner == null) { 142 | this.runner = new CooldownRunner(this); 143 | this.runner.runTaskTimerAsynchronously(PLUGIN, -1, 20); 144 | } 145 | 146 | return this; 147 | } 148 | 149 | public void forceStop() { 150 | if (hasStarted() && this.runner != null) { 151 | this.runner.cancel(); 152 | this.runner = null; 153 | } 154 | } 155 | } 156 | 157 | private static class CooldownRunner extends BukkitRunnable { 158 | 159 | private final Cooldown cooldown; 160 | 161 | CooldownRunner(Cooldown cooldown) { 162 | this.cooldown = cooldown; 163 | } 164 | 165 | public void run() { 166 | if (cooldown.secondsLeft == 0) { 167 | cancel(); 168 | return; 169 | } 170 | 171 | if (cooldown.onlyOnline) { 172 | if (cooldown.getPlayer() == null) { 173 | return; 174 | } 175 | } 176 | 177 | cooldown.secondsLeft--; 178 | } 179 | 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /src/main/java/utils/GeneralUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2014 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package utils; 26 | 27 | /** 28 | * 29 | * @author Goblom 30 | */ 31 | public class GeneralUtils { 32 | 33 | public static V[] mergeArrays(V[] a, V[] b) { 34 | Object[] array = new Object[a.length + b.length]; 35 | System.arraycopy(a, 0, array, 0, a.length); 36 | System.arraycopy(b, 0, array, a.length, b.length); 37 | return (V[]) array; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/utils/Performance.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2014 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package utils; 26 | 27 | import com.google.common.collect.Lists; 28 | import java.lang.reflect.Method; 29 | import java.util.LinkedList; 30 | import java.util.List; 31 | import org.bukkit.Bukkit; 32 | import org.bukkit.plugin.java.JavaPlugin; 33 | import org.bukkit.scheduler.BukkitRunnable; 34 | 35 | /** 36 | * 37 | * @author Goblom 38 | */ 39 | public class Performance { 40 | 41 | private static JavaPlugin PLUGIN = JavaPlugin.getProvidingPlugin(Performance.class); 42 | private static final double TICKS_PER_SECOND = 20; 43 | private static final long MEMORY_BYTES = 1048576; 44 | private static final PerformanceHolder STORED = new PerformanceHolder(); 45 | private static final PerformancePoll POLLER = new PerformancePoll(); 46 | private static boolean started = false; 47 | 48 | public static int POLL_INTERVAL = 40; 49 | 50 | public static void startChecking() { 51 | if (started) return; 52 | Bukkit.getScheduler().scheduleSyncRepeatingTask(PLUGIN, POLLER, 0, POLL_INTERVAL); 53 | started = true; 54 | } 55 | 56 | public static long getTimesPolled() { 57 | return Performance.POLLER.getTimesPolled(); 58 | } 59 | 60 | public enum Stats { 61 | Max { 62 | public double get() { 63 | return Runtime.getRuntime().maxMemory() / MEMORY_BYTES; 64 | } 65 | }, 66 | Used { 67 | public double get() { 68 | long mem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); 69 | return mem / MEMORY_BYTES; 70 | } 71 | }, 72 | Percentage_Free { 73 | public double get() { 74 | return (100 / Stats.Max.get()) * Stats.Free.get(); 75 | } 76 | }, 77 | Free { 78 | public double get() { 79 | return Stats.Max.get() - Stats.Used.get(); 80 | } 81 | }, 82 | TICKS_PER_SECOND { 83 | public double get() { 84 | return TPS; 85 | } 86 | }; 87 | 88 | private static double TPS = Performance.TICKS_PER_SECOND; 89 | public abstract double get(); 90 | } 91 | 92 | private static class PerformanceHolder { 93 | private static int MAX_SIZE = 50; 94 | 95 | private LinkedList list = Lists.newLinkedList(); 96 | 97 | private Double poll() { 98 | return list.poll(); 99 | } 100 | 101 | private void add(double item) { 102 | if (item <= 20) { 103 | this.list.add(item); 104 | 105 | if (size() > MAX_SIZE) { 106 | poll(); 107 | } 108 | } 109 | } 110 | 111 | public int size() { 112 | return this.list.size(); 113 | } 114 | 115 | public double getAverage() { 116 | double total = 0; 117 | for (double d : this.list) { 118 | total += d; 119 | } 120 | 121 | return total / this.list.size(); 122 | } 123 | } 124 | 125 | private static class PerformancePoll implements Runnable { 126 | private long last = System.currentTimeMillis() - 3000; 127 | private long count; 128 | 129 | @Override 130 | public void run() { 131 | long now = System.currentTimeMillis(); 132 | long spent = (now - last) / 1000; 133 | if (spent == 0) { 134 | spent = 1; 135 | } 136 | 137 | double tps = POLL_INTERVAL / spent; 138 | Performance.Stats.TPS = tps; 139 | STORED.add(tps); 140 | 141 | last = now; 142 | count++; 143 | } 144 | 145 | public long getTimesPolled() { 146 | return this.count; 147 | } 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /src/main/java/utils/ReflectionUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2013 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package utils; 25 | 26 | import java.lang.reflect.Field; 27 | import java.lang.reflect.Method; 28 | import org.bukkit.Bukkit; 29 | 30 | /** 31 | * Reflection Utils for getting version dependent Classes... Currently a work in 32 | * progress 33 | * 34 | * @author Goblom 35 | */ 36 | public class ReflectionUtil { 37 | 38 | public static boolean doesClassExist(ClassType type, String name) { 39 | Class clazz; 40 | 41 | try { 42 | clazz = Class.forName(type.getPackage() + "." + name); 43 | } catch (ClassNotFoundException e) { clazz = null; } 44 | 45 | return (clazz != null); 46 | } 47 | 48 | public static Class getClass(ClassType type, String name) { 49 | Class clazz = null; 50 | try { 51 | clazz = Class.forName(type.getPackage() + "." + name); 52 | } catch (ClassNotFoundException e) { e.printStackTrace(); } 53 | return clazz; 54 | } 55 | 56 | public static Class getCraftClass(String name) { 57 | Class clazz = null; 58 | try { 59 | clazz = Class.forName("org.bukkit.craftbukkit." + getVersion() + "." + name); 60 | } catch (ClassNotFoundException e) { e.printStackTrace(); } 61 | return clazz; 62 | } 63 | 64 | public static Class getNMSClass(String name) { 65 | Class clazz = null; 66 | try { 67 | clazz = Class.forName("net.minecraft.server." + getVersion() + "." + name); 68 | } catch (ClassNotFoundException e) { e.printStackTrace(); } 69 | return clazz; 70 | } 71 | 72 | public static T getField(Object o, String fieldName) { 73 | Class checkClass = o.getClass(); 74 | do { 75 | try { 76 | Field field = checkClass.getDeclaredField(fieldName); 77 | field.setAccessible(true); 78 | return (T) field.get(o); 79 | } catch (NoSuchFieldException e) { e.printStackTrace(); 80 | } catch (IllegalAccessException e) { e.printStackTrace(); } 81 | } while (checkClass.getSuperclass() != Object.class && ((checkClass = checkClass.getSuperclass()) != null)); 82 | return null; 83 | } 84 | 85 | public static Method getMethod(Class clazz, String method) { 86 | for (Method m : clazz.getMethods()) { 87 | if (m.getName().equals(method)) { 88 | m.setAccessible(true); 89 | return m; 90 | } 91 | } 92 | return null; 93 | } 94 | 95 | private static String getVersion() { 96 | return Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3]; 97 | } 98 | 99 | public enum ClassType { 100 | 101 | NMS("net.minecraft.server", getVersion()), 102 | CRAFT("org.bukkit.craftbukkit", getVersion()); 103 | 104 | private final String pakage, version; 105 | 106 | private ClassType(String pakage, String version) { 107 | this.pakage = pakage; 108 | this.version = version; 109 | } 110 | 111 | private String getPackage() { 112 | return pakage + "." + version; 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/main/java/utils/SpreadPlayers.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2014 Goblom. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package utils; 25 | 26 | import com.google.common.collect.Maps; 27 | import com.google.common.collect.Sets; 28 | import java.util.List; 29 | import java.util.Map; 30 | import java.util.Random; 31 | import java.util.Set; 32 | import org.bukkit.Location; 33 | import org.bukkit.Material; 34 | import org.bukkit.World; 35 | import org.bukkit.entity.Player; 36 | import org.bukkit.scoreboard.Team; 37 | 38 | /** 39 | * heavily based off of bukkits /spreadplayers command. Only difference is that we load chunk before teleportation and also make sure the player spawns in a AIR block. 40 | */ 41 | public class SpreadPlayers implements Runnable { 42 | private static final Random random = new Random(); 43 | 44 | private final List players; 45 | private double x, z, spreadDistance, maxRange; 46 | private boolean respectTeams; 47 | 48 | public SpreadPlayers(List players) { 49 | this.players = players; 50 | } 51 | 52 | public SpreadPlayers setWillRespectTeams(boolean respectTeams) { 53 | this.respectTeams = respectTeams; 54 | return this; 55 | } 56 | 57 | public SpreadPlayers setX(double x) { 58 | this.x = getDouble(x, -30000000, 30000000); 59 | return this; 60 | } 61 | 62 | public SpreadPlayers setZ(double z) { 63 | this.z = getDouble(z, -30000000, 30000000); 64 | return this; 65 | } 66 | 67 | public SpreadPlayers setSpreadDistance(double spreadDistance) { 68 | this.spreadDistance = spreadDistance; 69 | return this; 70 | } 71 | 72 | public SpreadPlayers setMaxRange(double maxRange) { 73 | this.maxRange = maxRange; 74 | return this; 75 | } 76 | 77 | public void run() { 78 | if (spreadDistance < 0.0D) { 79 | throw new RuntimeException("Distance is too small."); 80 | } 81 | 82 | if (maxRange < spreadDistance + 1.0D) { 83 | throw new RuntimeException("Max range is too small."); 84 | } 85 | 86 | if (players.isEmpty()) { 87 | throw new RuntimeException("There are no players to spread."); 88 | } 89 | 90 | World world = players.get(0).getLocation().getWorld(); 91 | 92 | final double xRangeMin = x - maxRange; 93 | final double zRangeMin = z - maxRange; 94 | final double xRangeMax = x + maxRange; 95 | final double zRangeMax = z + maxRange; 96 | 97 | final int spreadSize = respectTeams ? getTeams(players) : players.size(); 98 | 99 | final Location[] locations = getSpreadLocations(world, spreadSize, xRangeMin, zRangeMin, xRangeMax, zRangeMax); 100 | final int rangeSpread = range(world, spreadDistance, xRangeMin, zRangeMin, xRangeMax, zRangeMax, locations); 101 | 102 | if (rangeSpread == -1) { 103 | throw new RuntimeException(String.format("Could not spread %d %s around %s,%s (too many players for space - try using spread of at most %s)", spreadSize, respectTeams ? "teams" : "players", x, z)); 104 | } 105 | 106 | spread(world, players, locations, respectTeams); 107 | } 108 | 109 | private int range(World world, double distance, double xRangeMin, double zRangeMin, double xRangeMax, double zRangeMax, Location[] locations) { 110 | boolean flag = true; 111 | double max; 112 | 113 | int i; 114 | 115 | for (i = 0; i < 10000 && flag; ++i) { 116 | flag = false; 117 | max = Float.MAX_VALUE; 118 | 119 | Location loc1; 120 | int j; 121 | 122 | for (int k = 0; k < locations.length; ++k) { 123 | Location loc2 = locations[k]; 124 | 125 | j = 0; 126 | loc1 = new Location(world, 0, 0, 0); 127 | 128 | for (int l = 0; l < locations.length; ++l) { 129 | if (k != l) { 130 | Location loc3 = locations[l]; 131 | double dis = loc2.distanceSquared(loc3); 132 | 133 | max = Math.min(dis, max); 134 | if (dis < distance) { 135 | ++j; 136 | loc1.add(loc3.getX() - loc2.getX(), 0, 0); 137 | loc1.add(loc3.getZ() - loc2.getZ(), 0, 0); 138 | } 139 | } 140 | } 141 | 142 | if (j > 0) { 143 | loc2.setX(loc2.getX() / j); 144 | loc2.setZ(loc2.getZ() / j); 145 | double d7 = Math.sqrt(loc1.getX() * loc1.getX() + loc1.getZ() * loc1.getZ()); 146 | 147 | if (d7 > 0.0D) { 148 | loc1.setX(loc1.getX() / d7); 149 | loc2.add(-loc1.getX(), 0, -loc1.getZ()); 150 | } else { 151 | double x = xRangeMin >= xRangeMax ? xRangeMin : random.nextDouble() * (xRangeMax - xRangeMin) + xRangeMin; 152 | double z = zRangeMin >= zRangeMax ? zRangeMin : random.nextDouble() * (zRangeMax - zRangeMin) + zRangeMin; 153 | loc2.setX(x); 154 | loc2.setZ(z); 155 | } 156 | 157 | flag = true; 158 | } 159 | 160 | boolean swap = false; 161 | 162 | if (loc2.getX() < xRangeMin) { 163 | loc2.setX(xRangeMin); 164 | swap = true; 165 | } else if (loc2.getX() > xRangeMax) { 166 | loc2.setX(xRangeMax); 167 | swap = true; 168 | } 169 | 170 | if (loc2.getZ() < zRangeMin) { 171 | loc2.setZ(zRangeMin); 172 | swap = true; 173 | } else if (loc2.getZ() > zRangeMax) { 174 | loc2.setZ(zRangeMax); 175 | swap = true; 176 | } 177 | if (swap) { 178 | flag = true; 179 | } 180 | } 181 | 182 | if (!flag) { 183 | Location[] locs = locations; 184 | int i1 = locations.length; 185 | 186 | for (j = 0; j < i1; ++j) { 187 | loc1 = locs[j]; 188 | if (world.getHighestBlockYAt(loc1) == 0) { 189 | double x = xRangeMin >= xRangeMax ? xRangeMin : random.nextDouble() * (xRangeMax - xRangeMin) + xRangeMin; 190 | double z = zRangeMin >= zRangeMax ? zRangeMin : random.nextDouble() * (zRangeMax - zRangeMin) + zRangeMin; 191 | locations[i] = (new Location(world, x, 0, z)); 192 | loc1.setX(x); 193 | loc1.setZ(z); 194 | flag = true; 195 | } 196 | } 197 | } 198 | } 199 | 200 | if (i >= 10000) { 201 | return -1; 202 | } else { 203 | return i; 204 | } 205 | } 206 | 207 | private double spread(World world, List list, Location[] locations, boolean teams) { 208 | double distance = 0.0D; 209 | int i = 0; 210 | Map hashmap = Maps.newHashMap(); 211 | 212 | for (int j = 0; j < list.size(); ++j) { 213 | Player player = list.get(j); 214 | Location location; 215 | 216 | if (teams) { 217 | Team team = player.getScoreboard().getPlayerTeam(player); 218 | 219 | if (!hashmap.containsKey(team)) { 220 | hashmap.put(team, locations[i++]); 221 | } 222 | 223 | location = hashmap.get(team); 224 | } else { 225 | location = locations[i++]; 226 | } 227 | 228 | player.teleport(new Location(world, Math.floor(location.getX()) + 0.5D, world.getHighestBlockYAt((int) location.getX(), (int) location.getZ()), Math.floor(location.getZ()) + 0.5D)); 229 | double value = Double.MAX_VALUE; 230 | 231 | for (int k = 0; k < locations.length; ++k) { 232 | if (location != locations[k]) { 233 | double d = location.distanceSquared(locations[k]); 234 | value = Math.min(d, value); 235 | } 236 | } 237 | 238 | distance += value; 239 | } 240 | 241 | distance /= list.size(); 242 | return distance; 243 | } 244 | 245 | private int getTeams(List players) { 246 | Set teams = Sets.newHashSet(); 247 | 248 | for (Player player : players) { 249 | teams.add(player.getScoreboard().getPlayerTeam(player)); 250 | } 251 | 252 | return teams.size(); 253 | } 254 | 255 | private Location[] getSpreadLocations(World world, int size, double xRangeMin, double zRangeMin, double xRangeMax, double zRangeMax) { 256 | Location[] locations = new Location[size]; 257 | 258 | for (int i = 0; i < size; ++i) { 259 | double x = xRangeMin >= xRangeMax ? xRangeMin : random.nextDouble() * (xRangeMax - xRangeMin) + xRangeMin; 260 | double z = zRangeMin >= zRangeMax ? zRangeMin : random.nextDouble() * (zRangeMax - zRangeMin) + zRangeMin; 261 | Location loc = new Location(world, x, 0, z); 262 | 263 | //special start 264 | while (loc.getBlock().getType() != Material.AIR) { 265 | loc = loc.add(0, 1, 0); 266 | } 267 | 268 | if (!loc.getChunk().isLoaded()) { 269 | loc.getChunk().load(); 270 | } 271 | //special end 272 | 273 | locations[i] = loc; 274 | } 275 | 276 | return locations; 277 | } 278 | 279 | private static double getDouble(double result, double min, double max) { 280 | if (result < min) { 281 | result = min; 282 | } else if (result > max) { 283 | result = max; 284 | } 285 | 286 | return result; 287 | } 288 | } 289 | --------------------------------------------------------------------------------