├── .gitignore ├── .travis.yml ├── LICENSE.md ├── README.md ├── pom.xml └── src └── main ├── java └── com │ └── codelanx │ └── codelanxlib │ ├── CodelanxLib.java │ ├── command │ ├── CommandNode.java │ ├── CommandStatus.java │ ├── HelpCommand.java │ ├── ReloadCommand.java │ └── TabInfo.java │ ├── config │ ├── Config.java │ ├── Configs.java │ ├── DefaultLang.java │ ├── Lang.java │ ├── PluginClass.java │ └── PluginConfig.java │ ├── econ │ ├── CEconomy.java │ ├── ChargeStatus.java │ ├── EconomyChangePacket.java │ ├── EconomyObserver.java │ ├── VaultProxy.java │ └── VaultProxyListener.java │ ├── events │ ├── EconomyChangeEvent.java │ └── ReloadEvent.java │ ├── implementers │ ├── Economics.java │ ├── Formatted.java │ └── Reloadable.java │ ├── internal │ ├── InternalLang.java │ └── InternalPerms.java │ ├── inventory │ ├── Inventories.java │ ├── InventoryState.java │ ├── ItemStackBuilder.java │ ├── PlayerInventoryState.java │ └── iinterface │ │ ├── Execution.java │ │ ├── InterfaceListener.java │ │ ├── InventoryInterface.java │ │ ├── InventoryPanel.java │ │ └── MenuIcon.java │ ├── listener │ ├── ListenerManager.java │ └── SubListener.java │ ├── logging │ └── PluginDebugOpts.java │ ├── permission │ └── Permissions.java │ ├── serialize │ ├── SInventory.java │ ├── SLocation.java │ ├── SPlayerInventory.java │ └── SerializationFactory.java │ └── util │ ├── BScheduler.java │ ├── BlockData.java │ ├── Blocks.java │ ├── Countdown.java │ ├── NMS.java │ ├── Paginator.java │ ├── Players.java │ ├── Protections.java │ ├── ReflectBukkit.java │ ├── RuntimeCommandSender.java │ ├── auth │ ├── UUIDFetcher.java │ └── UserInfo.java │ └── coverage │ └── CoverageUtil.java └── resources └── plugin.yml /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | /example/ 3 | /log.txt 4 | /.idea 5 | dependency-reduced-pom.xml 6 | nbactions.xml 7 | nb-configuration.xml -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - oraclejdk8 4 | notifications: 5 | email: false 6 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | com.codelanx 5 | codelanxlib 6 | 0.3.2-SNAPSHOT 7 | jar 8 | CodelanxLib 9 | External plugin library for simplified plugin making 10 | 11 | CL-Lib 12 | http://codelanx.com/ 13 | UTF-8 14 | 1.8 15 | 1.8 16 | 17 | 18 | 19 | 20 | spigot-repo 21 | http://hub.spigotmc.org/nexus/content/repositories/public/ 22 | 23 | 24 | codelanx-repo 25 | http://repo.codelanx.com/content/repositories/public/ 26 | 27 | 28 | Plugin Metrics 29 | http://repo.mcstats.org/content/repositories/public 30 | 31 | 32 | vault-repo 33 | http://nexus.theyeticave.net/content/repositories/pub_releases 34 | 35 | 36 | 37 | 38 | 39 | Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International 40 | https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode 41 | repo 42 | 43 | 44 | 45 | 46 | 47 | cl-deployment 48 | Internal Releases 49 | http://repo.codelanx.com/content/repositories/releases/ 50 | false 51 | 52 | 53 | cl-deployment 54 | Internal Releases 55 | http://repo.codelanx.com/content/repositories/snapshots/ 56 | false 57 | 58 | 59 | 60 | 61 | 62 | 63 | org.apache.maven.plugins 64 | maven-shade-plugin 65 | 2.3 66 | 67 | 68 | package 69 | 70 | shade 71 | 72 | 73 | 74 | 75 | org.mcstats.bukkit:metrics 76 | com.codelanx:commons 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | org.apache.maven.plugins 85 | maven-javadoc-plugin 86 | 2.10.3 87 | 88 | 89 | http://docs.codelanx.com/Bukkit/1.8/ 90 | https://docs.oracle.com/javase/8/docs/api/ 91 | 92 | 93 | 94 | 95 | attach-javadocs 96 | 97 | jar 98 | 99 | 100 | 101 | 102 | 103 | org.apache.maven.plugins 104 | maven-source-plugin 105 | 2.2.1 106 | 107 | 108 | attach-sources 109 | 110 | jar 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | . 119 | ${basedir}/src/main/resources 120 | true 121 | 122 | 123 | ${project.name}-v${project.version} 124 | 125 | 126 | 127 | 128 | com.codelanx 129 | commons 130 | 0.3.2-SNAPSHOT 131 | 132 | 133 | org.bukkit 134 | bukkit 135 | 1.8-R0.1-SNAPSHOT 136 | jar 137 | 138 | 139 | org.mcstats.bukkit 140 | metrics 141 | LATEST 142 | compile 143 | 144 | 145 | net.milkbowl.vault 146 | Vault 147 | LATEST 148 | jar 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/CodelanxLib.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib; 21 | 22 | import com.codelanx.commons.logging.Debugger; 23 | import com.codelanx.commons.logging.Logging; 24 | import com.codelanx.commons.util.Reflections; 25 | import com.codelanx.commons.util.Scheduler; 26 | import com.codelanx.codelanxlib.econ.VaultProxyListener; 27 | import com.codelanx.codelanxlib.listener.ListenerManager; 28 | import com.codelanx.codelanxlib.logging.PluginDebugOpts; 29 | import com.codelanx.codelanxlib.serialize.SerializationFactory; 30 | import com.codelanx.codelanxlib.util.ReflectBukkit; 31 | import org.bukkit.plugin.java.JavaPlugin; 32 | import org.mcstats.Metrics; 33 | 34 | import java.io.IOException; 35 | 36 | /** 37 | * Main class. Ensures any services are initialized properly 38 | * 39 | * @since 0.0.1 40 | * @author 1Rogue 41 | * @version 0.1.0 42 | */ 43 | public class CodelanxLib extends JavaPlugin { 44 | 45 | static { 46 | SerializationFactory.registerClasses(SerializationFactory.getNativeSerializables()); 47 | } 48 | 49 | /** 50 | * Reports metrics to MCStats, and hooks 51 | * the plugin loggers for {@link Debugger} 52 | *

53 | * {@inheritDoc} 54 | * 55 | * @since 0.0.1 56 | * @version 0.1.0 57 | */ 58 | @Override 59 | public void onEnable() { 60 | Logging.setNab(() -> ReflectBukkit.getCallingPlugin(2).getLogger()); 61 | Debugger.DebugUtil.setOps(PluginDebugOpts::getPluginOpts); 62 | PluginDebugOpts.hookBukkit(); 63 | if (Reflections.findPluginJarfile("Vault") != null) { 64 | new VaultProxyListener(this).register(); 65 | } 66 | try { 67 | new Metrics(this).start(); 68 | } catch (IOException ex) { 69 | Debugger.error(ex, "Error reporting metrics"); 70 | } 71 | } 72 | 73 | /** 74 | * Releases all currently registered listeners and cancels all Scheduler 75 | * tasks 76 | *

77 | * {@inheritDoc} 78 | * 79 | * @since 0.1.0 80 | * @version 0.1.0 81 | */ 82 | @Override 83 | public void onDisable() { 84 | ListenerManager.release(); 85 | Scheduler.cancelAllTasks(); 86 | Scheduler.getService().shutdown(); 87 | } 88 | 89 | /** 90 | * Returns the instance in use of this class as held interally by Bukkit 91 | * 92 | * @since 0.1.0 93 | * @version 0.1.0 94 | * 95 | * @return The relevant {@link CodelanxLib} instance 96 | */ 97 | public static CodelanxLib get() { 98 | return JavaPlugin.getPlugin(CodelanxLib.class); 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/command/CommandStatus.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.command; 21 | 22 | import com.codelanx.commons.config.LangFile; 23 | import com.codelanx.codelanxlib.config.Lang; 24 | import com.codelanx.codelanxlib.internal.InternalLang; 25 | import org.bukkit.command.BlockCommandSender; 26 | import org.bukkit.command.CommandSender; 27 | import org.bukkit.command.ConsoleCommandSender; 28 | import org.bukkit.command.RemoteConsoleCommandSender; 29 | import org.bukkit.entity.Player; 30 | import org.bukkit.entity.minecart.CommandMinecart; 31 | import org.bukkit.plugin.Plugin; 32 | 33 | import java.util.List; 34 | 35 | /** 36 | * Represents the status of an executed command, and is returned upon the 37 | * completion of the command's execution 38 | * 39 | * @since 0.1.0 40 | * @author 1Rogue 41 | * @version 0.1.0 42 | */ 43 | public enum CommandStatus { 44 | 45 | /** The command executed successfully */ 46 | SUCCESS, 47 | /** The command did not execute correctly */ 48 | FAILED, 49 | /** User supplied bad command arguments */ 50 | BAD_ARGS, 51 | /** Command is intended to be run by players only */ 52 | PLAYER_ONLY("players"), 53 | /** Command is intended to be run by the console only */ 54 | CONSOLE_ONLY("the console"), 55 | /** Command is intended to be run by remote consoles (rcon) only */ 56 | RCON_ONLY("remote consoles"), 57 | /** Command is intended to be run by command blocks only */ 58 | COMMAND_BLOCK_ONLY("command blocks"), 59 | /** Command is intended to be run by a CommandMinecart only */ 60 | MINECART_ONLY("minecarts"), 61 | /** Command should not be executed by a proxied sender */ 62 | NO_PROXIES, 63 | /** The user does not have the appropriate permissions to execute this */ 64 | NO_PERMISSION, 65 | /** The command is not meant to be an endpoint */ 66 | NOT_EXECUTABLE; 67 | 68 | /** Formatter arguments for output */ 69 | private final Object[] args; 70 | 71 | /** 72 | * Private enum constructor. Assigns formatter arguments to be used later if 73 | * any are present 74 | * 75 | * @since 0.1.0 76 | * @version 0.1.0 77 | * 78 | * @param args The formatter arguments to store 79 | */ 80 | private CommandStatus(Object... args) { 81 | this.args = args; 82 | } 83 | 84 | /** 85 | * Handles output to a {@link CommandSender} upon the execution of a command 86 | * 87 | * @since 0.1.0 88 | * @version 0.1.0 89 | * 90 | * @param sender The {@link CommandSender} object that executed the command 91 | * @param format The {@link LangFile} being used as a format string 92 | * @param cmd The {@link CommandNode} that was executed 93 | */ 94 | public void handle(CommandSender sender, Lang format, CommandNode cmd) { 95 | switch (this) { 96 | case FAILED: 97 | Lang.sendMessage(sender, format, InternalLang.COMMAND_STATUS_FAILED); 98 | break; 99 | case BAD_ARGS: 100 | Lang.sendMessage(sender, format, InternalLang.COMMAND_STATUS_USAGE, cmd.getUsage()); 101 | Lang.sendMessage(sender, format, cmd.info()); 102 | break; 103 | case PLAYER_ONLY: 104 | case CONSOLE_ONLY: 105 | case RCON_ONLY: 106 | case COMMAND_BLOCK_ONLY: 107 | case MINECART_ONLY: 108 | Lang.sendMessage(sender, format, InternalLang.COMMAND_STATUS_RESTRICTED, this.args); 109 | break; 110 | case NO_PERMISSION: 111 | Lang.sendMessage(sender, format, InternalLang.COMMAND_STATUS_NOPERM); 112 | break; 113 | case NOT_EXECUTABLE: 114 | List> cmds = cmd.closestCommands(); 115 | if (cmds.size() > 3) { 116 | cmds = cmds.subList(0, 2); 117 | } 118 | StringBuilder sb = new StringBuilder(); 119 | cmds.forEach(c -> sb.append('\n').append('/').append(c.getUsage())); 120 | Lang.sendMessage(sender, format, InternalLang.COMMAND_STATUS_NOTEXEC, sb.toString()); 121 | break; 122 | } 123 | } 124 | 125 | //Returns true if the sender is okay to use 126 | boolean verifySender(CommandSender sender) { 127 | switch (this) { 128 | case PLAYER_ONLY: 129 | return sender instanceof Player; 130 | case CONSOLE_ONLY: 131 | return sender instanceof ConsoleCommandSender; 132 | case RCON_ONLY: 133 | return sender instanceof RemoteConsoleCommandSender; 134 | case COMMAND_BLOCK_ONLY: 135 | return sender instanceof BlockCommandSender; 136 | case MINECART_ONLY: 137 | return sender instanceof CommandMinecart; 138 | default: 139 | return true; 140 | } 141 | } 142 | 143 | } 144 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/command/HelpCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.command; 21 | 22 | import com.codelanx.commons.util.cache.Cache; 23 | import com.codelanx.codelanxlib.internal.InternalLang; 24 | import com.codelanx.codelanxlib.util.Paginator; 25 | import org.bukkit.command.CommandSender; 26 | import org.bukkit.entity.Player; 27 | import org.bukkit.plugin.Plugin; 28 | 29 | import java.util.ArrayList; 30 | import java.util.Collections; 31 | import java.util.HashMap; 32 | import java.util.List; 33 | import java.util.Map; 34 | import java.util.UUID; 35 | import java.util.concurrent.TimeUnit; 36 | import java.util.stream.Collectors; 37 | import java.util.stream.IntStream; 38 | 39 | /** 40 | * Provides a listing of help information derived from all {@link CommandNode} 41 | * objects that are returned from a call to a parent's 42 | * {@link CommandNode#traverse} method 43 | * 44 | * @since 0.0.1 45 | * @author 1Rogue 46 | * @version 0.2.0 47 | * 48 | * @param The {@link Plugin} that caused this class to be instantiated 49 | */ 50 | public final class HelpCommand extends CommandNode { 51 | 52 | /** Stores a {@link Paginator} cache per player */ 53 | private final Map> pages = new HashMap<>(); //TODO: Use IdentityMap 54 | /** Internal {@link Paginator} cache per {@link CommandSender}, used to pre-render and output pages */ 55 | private final Map, Cache> oddSenders = new HashMap<>(); 56 | /** The number of commands to show per page */ 57 | private int factor = 5; 58 | 59 | /** 60 | * {@link HelpCommand} constructor. 61 | * 62 | * @since 0.0.1 63 | * @version 0.1.0 64 | * 65 | * @param plugin {@inheritDoc} 66 | */ 67 | protected HelpCommand(E plugin) { 68 | super(plugin); 69 | } 70 | 71 | /** 72 | * Displays help information from all linked child {@link CommandNode} nodes 73 | * for the parent {@link CommandNode} relevant to this {@link HelpCommand} 74 | * instance 75 | * 76 | * @since 0.0.1 77 | * @version 0.1.0 78 | * 79 | * @param sender {@inheritDoc} 80 | * @param args {@inheritDoc} 81 | * @return {@inheritDoc} 82 | */ 83 | @Override 84 | public CommandStatus execute(CommandSender sender, String... args) { 85 | if (args.length < 1) { 86 | args = new String[]{"1"}; 87 | } 88 | int select; 89 | try { 90 | select = Integer.parseInt(args[0]); 91 | } catch (NumberFormatException ex) { 92 | return CommandStatus.BAD_ARGS; 93 | } 94 | sender.sendMessage(this.getPages(sender).getPage(select)); 95 | return CommandStatus.SUCCESS; 96 | } 97 | 98 | /** 99 | * {@inheritDoc} 100 | * 101 | * @since 0.1.0 102 | * @version 0.2.0 103 | * 104 | * @param sender {@inheritDoc} 105 | * @param args {@inheritDoc} 106 | * @return {@inheritDoc} 107 | */ 108 | @Override 109 | public List tabComplete(CommandSender sender, String... args) { 110 | if (args.length < 1) { 111 | return IntStream.range(1, this.getPages(sender).size() + 1).boxed() 112 | .map(String::valueOf).collect(Collectors.toList()); 113 | } 114 | int size = this.getPages(sender).size(); 115 | int curr; 116 | try { 117 | curr = Integer.parseInt(args[0]); 118 | } catch (NumberFormatException ex) { 119 | return TabInfo.BLANK_TAB_COMPLETE; 120 | } 121 | if (curr > size || curr * 10 > size) { 122 | return TabInfo.BLANK_TAB_COMPLETE; 123 | } 124 | List back = new ArrayList<>(); 125 | back.add(args[0]); 126 | for (int i = curr * 10; i < size; i++) { //awful, spawns too many strings 127 | String s = i + ""; 128 | if (s.startsWith(args[0])) { 129 | back.add(s); 130 | } 131 | } 132 | return back; 133 | } 134 | 135 | /** 136 | * Returns a new {@link Paginator} instance according to the current state 137 | * of the {@link CommandNode} command map and the set page factor for 138 | * this {@link HelpCommand} 139 | * 140 | * @since 0.1.0 141 | * @version 0.2.0 142 | * 143 | * @return A new {@link Paginator} instance containing help information 144 | */ 145 | private Paginator newPaginator(CommandSender sender) { 146 | List> cmds = new ArrayList<>(this.getParent().traverse(sender, true)); 147 | Map> aliases = new HashMap<>(); 148 | cmds.forEach(c -> aliases.putAll(c.getAliases())); 149 | Collections.sort(cmds); 150 | String usage; 151 | String title = InternalLang.COMMAND_HELP_TITLEFORMAT.formatAndColor( 152 | filterUsage(this.getParent().getUsage())); 153 | List out = cmds.stream().map(this::toHelpInfo).collect(Collectors.toList()); 154 | if (!aliases.isEmpty()) { 155 | int blanks = this.getItemsPerPage() - (cmds.size() % this.getItemsPerPage()); 156 | for (; blanks > 0; blanks--) { 157 | out.add(""); 158 | } 159 | out.add(InternalLang.COMMAND_HELP_ALIASES.formatAndColor()); 160 | List aliasInfo = this.aliasInfo(aliases); 161 | Collections.sort(aliasInfo); 162 | out.addAll(aliasInfo); 163 | } 164 | return new Paginator(title, this.factor, out); 165 | } 166 | 167 | 168 | /** 169 | * Formats a mapping of aliases to {@link CommandNode} objects 170 | * 171 | * @since 0.1.0 172 | * @version 0.1.0 173 | * 174 | * @param aliases The aliases to format 175 | * @return A {@link List} of the formatted aliases 176 | */ 177 | private List aliasInfo(Map> aliases) { 178 | List back = new ArrayList<>(); 179 | aliases.entrySet().forEach(ent -> back.add(InternalLang.COMMAND_HELP_ITEMFORMAT.formatAndColor( 180 | ent.getKey(), "Aliased from " + ent.getValue().getUsage()))); 181 | return back; 182 | } 183 | 184 | /** 185 | * Converts a {@link CommandNode} into a readable format for help output 186 | * 187 | * @since 0.1.0 188 | * @version 0.1.0 189 | * 190 | * @param cmd The {@link CommandNode} to convert 191 | * @return The human-readable output of the command information 192 | */ 193 | private String toHelpInfo(CommandNode cmd) { 194 | return InternalLang.COMMAND_HELP_ITEMFORMAT.formatAndColor(cmd.getUsage(), cmd.info() == null ? "" : cmd.info().formatAndColor()); 195 | } 196 | 197 | /** 198 | * Sets the number of commands to show information for per page. This will 199 | * forcefully refresh the {@link Paginator} cache 200 | * 201 | * @since 0.1.0 202 | * @version 0.2.0 203 | * 204 | * @param factor The number of commands per page 205 | */ 206 | public void setItemsPerPage(int factor) { 207 | this.factor = factor; 208 | this.pages.values().forEach(Cache::forceRefresh); 209 | } 210 | 211 | /** 212 | * Returns the number of commands displayed per page 213 | * 214 | * @since 0.1.0 215 | * @version 0.1.0 216 | * 217 | * @return The number of commands shown per page 218 | */ 219 | public int getItemsPerPage() { 220 | return this.factor; 221 | } 222 | 223 | /** 224 | * {@inheritDoc} 225 | * 226 | * @since 0.0.1 227 | * @version 0.0.1 228 | * 229 | * @return {@inheritDoc} 230 | */ 231 | @Override 232 | public String usage() { 233 | return super.usage() + " [page-number]"; 234 | } 235 | 236 | /** 237 | * Subcommand name: "help" 238 | *

{@inheritDoc} 239 | * 240 | * @since 0.0.1 241 | * @version 0.0.1 242 | * 243 | * @return {@inheritDoc} 244 | */ 245 | @Override 246 | public String getName() { 247 | return "help"; 248 | } 249 | 250 | /** 251 | * {@inheritDoc} 252 | * 253 | * @since 0.0.1 254 | * @version 0.0.1 255 | * 256 | * @return {@inheritDoc} 257 | */ 258 | @Override 259 | public InternalLang info() { 260 | return InternalLang.COMMAND_HELP_INFO; 261 | } 262 | 263 | private Paginator getPages(CommandSender sender) { 264 | UUID uuid = null; 265 | if (sender instanceof Player) { 266 | return this.pages.computeIfAbsent(uuid, uid -> new Cache(TimeUnit.MINUTES.toMillis(5)) { 267 | @Override 268 | protected void update() { 269 | this.setCurrentValue(HelpCommand.this.newPaginator(sender)); 270 | } 271 | }).get(); 272 | } else { 273 | return this.oddSenders.computeIfAbsent(sender.getClass(), uid -> new Cache(TimeUnit.MINUTES.toMillis(5)) { 274 | @Override 275 | protected void update() { 276 | this.setCurrentValue(HelpCommand.this.newPaginator(sender)); 277 | } 278 | }).get(); 279 | } 280 | } 281 | 282 | } 283 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/command/ReloadCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.command; 21 | 22 | import com.codelanx.codelanxlib.config.Lang; 23 | import com.codelanx.codelanxlib.events.ReloadEvent; 24 | import com.codelanx.codelanxlib.implementers.Reloadable; 25 | import com.codelanx.codelanxlib.internal.InternalLang; 26 | import org.bukkit.command.CommandSender; 27 | import org.bukkit.plugin.Plugin; 28 | 29 | import java.util.List; 30 | 31 | /** 32 | * Fires a {@link ReloadEvent} and, if applicable, calls 33 | * {@link Reloadable#reload()} of a relevant {@link Plugin} instance 34 | * 35 | * @since 0.0.1 36 | * @author 1Rogue 37 | * @version 0.0.1 38 | * 39 | * @param The {@link Plugin} type 40 | */ 41 | public class ReloadCommand extends CommandNode { 42 | 43 | /** 44 | * {@link ReloadCommand} constructor 45 | * 46 | * @since 0.0.1 47 | * @version 0.0.1 48 | * 49 | * @param plugin {@inheritDoc} 50 | */ 51 | public ReloadCommand(E plugin) { 52 | super(plugin); 53 | } 54 | 55 | /** 56 | * Fires the {@link ReloadEvent} and calls any relevant reload methods for 57 | * the {@link Plugin} instance passed 58 | * 59 | * @since 0.0.1 60 | * @version 0.0.1 61 | * 62 | * @param sender {@inheritDoc} 63 | * @param args {@inheritDoc} 64 | * @return {@inheritDoc} 65 | */ 66 | @Override 67 | public CommandStatus execute(CommandSender sender, String... args) { 68 | this.plugin.getServer().getPluginManager().callEvent(new ReloadEvent<>(this.plugin)); 69 | if (this.plugin instanceof Reloadable) { 70 | ((Reloadable) this.plugin).reload(); 71 | Lang.sendMessage(sender, InternalLang.COMMAND_RELOAD_DONE, 72 | this.plugin.getName(), this.plugin.getDescription().getVersion()); 73 | } else { 74 | Lang.sendMessage(sender, InternalLang.COMMAND_RELOAD_UNSUPPORTED); 75 | } 76 | return CommandStatus.SUCCESS; 77 | } 78 | 79 | @Override 80 | public List tabComplete(CommandSender sender, String... args) { 81 | return TabInfo.BLANK_TAB_COMPLETE; 82 | } 83 | 84 | /** 85 | * Subcommand name: "reload" 86 | *

{@inheritDoc} 87 | * 88 | * @since 0.0.1 89 | * @version 0.0.1 90 | * 91 | * @return {@inheritDoc} 92 | */ 93 | @Override 94 | public String getName() { 95 | return "reload"; 96 | } 97 | 98 | /** 99 | * {@inheritDoc} 100 | * 101 | * @since 0.0.1 102 | * @version 0.0.1 103 | * 104 | * @return {@inheritDoc} 105 | */ 106 | @Override 107 | public Lang info() { 108 | return InternalLang.COMMAND_RELOAD_INFO; 109 | } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/config/Config.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.config; 21 | 22 | import com.codelanx.commons.config.ConfigFile; 23 | import com.codelanx.commons.config.InfoFile; 24 | import com.codelanx.commons.config.RelativePath; 25 | import com.codelanx.commons.util.Reflections; 26 | import com.codelanx.commons.util.exception.Exceptions; 27 | 28 | import java.io.File; 29 | 30 | /** 31 | * Created by Rogue on 11/17/2015. 32 | */ 33 | public interface Config extends ConfigFile { 34 | 35 | @Override 36 | default public File getFileLocation() { 37 | Class clazz = this.getClass(); 38 | Exceptions.illegalState(Reflections.hasAnnotation(clazz, PluginClass.class) 39 | && Reflections.hasAnnotation(clazz, RelativePath.class), 40 | "'" + clazz.getName() + "' is missing either PluginClass or RelativePath annotations"); 41 | File folder = Configs.getPlugin(clazz).getDataFolder(); 42 | if (!folder.exists()) { 43 | folder.mkdirs(); 44 | } 45 | return new File(folder, clazz.getAnnotation(RelativePath.class).value()); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/config/Configs.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.config; 21 | 22 | import com.codelanx.commons.util.exception.Exceptions; 23 | import org.bukkit.configuration.ConfigurationSection; 24 | import org.bukkit.plugin.java.JavaPlugin; 25 | 26 | import java.lang.annotation.Annotation; 27 | import java.util.Map; 28 | 29 | /** 30 | * Created by Rogue on 11/6/2015. 31 | */ 32 | public class Configs { 33 | 34 | /** 35 | * Returns the relevant {@link JavaPlugin} that is specified by a 36 | * class-level {@link PluginClass} annotation if it is loaded, otherwise 37 | * {@code null} 38 | * 39 | * @since 0.1.0 40 | * @version 0.1.0 41 | * 42 | * @param clazz The {@link Class} that holds the {@link Annotation} 43 | * @return The relevant {@link JavaPlugin}, or {@code null} if not found 44 | */ 45 | public static JavaPlugin getPlugin(Class clazz) { 46 | PluginClass pc = clazz.getAnnotation(PluginClass.class); 47 | Exceptions.illegalState(pc != null, "'" + clazz.getName() + "' is missing PluginClass annotation"); 48 | return JavaPlugin.getPlugin(pc.value()); 49 | } 50 | 51 | /** 52 | * Returns a {@link Map} representative of the passed Object that represents 53 | * a section of a YAML file. This method neglects the implementation of the 54 | * section (whether it be {@link ConfigurationSection} or just a 55 | * {@link Map}), and returns the appropriate value. 56 | * 57 | * @since 0.1.0 58 | * @version 0.1.0 59 | * 60 | * @param o The object to interpret 61 | * @return A {@link Map} representing the section 62 | */ 63 | public static Map getConfigSectionValue(Object o) { 64 | return Configs.getConfigSectionValue(o, false); 65 | } 66 | 67 | /** 68 | * Returns a {@link Map} representative of the passed Object that represents 69 | * a section of a YAML file. This method neglects the implementation of the 70 | * section (whether it be {@link ConfigurationSection} or just a 71 | * {@link Map}), and returns the appropriate value. 72 | * 73 | * @since 0.1.0 74 | * @version 0.1.0 75 | * 76 | * @param o The object to interpret 77 | * @param deep If an object is a {@link ConfigurationSection}, {@code true} to do a deep search 78 | * @return A {@link Map} representing the section 79 | */ 80 | @SuppressWarnings("unchecked") 81 | public static Map getConfigSectionValue(Object o, boolean deep) { 82 | if (o == null) { 83 | return null; 84 | } 85 | Map map; 86 | if (o instanceof ConfigurationSection) { 87 | map = ((ConfigurationSection) o).getValues(deep); 88 | } else if (o instanceof Map) { 89 | map = (Map) o; 90 | } else { 91 | return null; 92 | } 93 | return map; 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/config/DefaultLang.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.config; 21 | 22 | import com.codelanx.commons.config.DataHolder; 23 | import com.codelanx.commons.config.RelativePath; 24 | import com.codelanx.commons.data.types.Yaml; 25 | import com.codelanx.codelanxlib.internal.InternalLang; 26 | 27 | /** 28 | * Default lang messages used for plugins 29 | * 30 | * @since 1.0.0 31 | * @author 1Rogue 32 | * @version 1.0.0 33 | */ 34 | @RelativePath("lang-defaults.yml") 35 | public enum DefaultLang implements Lang { 36 | 37 | PLAYER_NOT_ONLINE("player.not-online", "&9%s&f is not online!"), 38 | PLAYER_NEVER_PLAYED("player.never-played", "&9%s&f has not played on this server before!"), 39 | UNKNOWN_PLAYER("player.unknown", "Unknown player: %s"), 40 | NOT_A_NUMBER("math.not-a-number", "&9%s&f is not a number!"), 41 | NOT_POSITIVE("math.not-positive", "&9%d&f is not a positive number"), 42 | ; 43 | 44 | private static final DataHolder DATA = new DataHolder<>(Yaml.class); 45 | private final String path; 46 | private final String def; 47 | 48 | private DefaultLang(String path, String def) { 49 | this.path = path; 50 | this.def = def; 51 | } 52 | 53 | @Override 54 | public Lang getFormat() { 55 | return InternalLang.FORMAT.getFormat(); 56 | } 57 | 58 | @Override 59 | public String getPath() { 60 | return this.path; 61 | } 62 | 63 | @Override 64 | public String getDefault() { 65 | return this.def; 66 | } 67 | 68 | @Override 69 | public DataHolder getData() { 70 | return DefaultLang.DATA; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/config/PluginClass.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.config; 21 | 22 | import org.bukkit.plugin.java.JavaPlugin; 23 | 24 | import java.lang.annotation.Retention; 25 | import java.lang.annotation.RetentionPolicy; 26 | 27 | /** 28 | * An annotation for relaying the primary class of the {@link JavaPlugin} 29 | * responsible for the element. 30 | * 31 | * @since 0.1.0 32 | * @author 1Rogue 33 | * @version 0.1.0 34 | */ 35 | @Retention(RetentionPolicy.RUNTIME) 36 | public @interface PluginClass { 37 | 38 | /** 39 | * Returns the value for the relevant {@link JavaPlugin} class 40 | * 41 | * @since 0.1.0 42 | * @version 0.1.0 43 | * 44 | * @return The relevant {@link JavaPlugin} class 45 | */ 46 | Class value(); 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/config/PluginConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.config; 21 | 22 | import com.codelanx.codelanxlib.util.ReflectBukkit; 23 | import com.codelanx.commons.config.DataHolder; 24 | import com.codelanx.commons.config.RelativePath; 25 | import com.codelanx.commons.data.FileDataType; 26 | import com.codelanx.commons.data.types.Yaml; 27 | import com.codelanx.commons.util.Reflections; 28 | import com.codelanx.commons.util.exception.Exceptions; 29 | import org.bukkit.plugin.Plugin; 30 | 31 | import java.io.File; 32 | import java.util.ArrayList; 33 | import java.util.stream.Stream; 34 | 35 | //TODO: Finish, just testing wates atm 36 | @RelativePath("clconfig.yml") 37 | public enum PluginConfig implements Config { 38 | 39 | DISABLED_COMMANDS("disabled-commands", new ArrayList<>()), 40 | ; 41 | 42 | private static final DataHolder DATA = new DataHolder<>(Yaml.class); 43 | private final String key; 44 | private final Object def; 45 | 46 | private PluginConfig(String key, Object def) { 47 | this.key = key; 48 | this.def = def; 49 | } 50 | 51 | @Override 52 | public String getPath() { 53 | return this.key; 54 | } 55 | 56 | @Override 57 | public Object getDefault() { 58 | return this.def; 59 | } 60 | 61 | @Override 62 | public DataHolder getData() { 63 | return DATA; 64 | } 65 | 66 | @Override 67 | public File getFileLocation() { 68 | Plugin p = ReflectBukkit.getCallingPlugin(PluginConfig.getOffset()); 69 | Exceptions.illegalState(Reflections.hasAnnotation(PluginConfig.class, RelativePath.class), 70 | "'" + PluginConfig.class.getName() + "' is missing RelativePath annotation"); 71 | File folder = p.getDataFolder(); 72 | if (!folder.exists()) { 73 | folder.mkdirs(); 74 | } 75 | return new File(folder, PluginConfig.class.getAnnotation(RelativePath.class).value()); 76 | } 77 | 78 | //TODO: Implement 79 | private static int getOffset() { 80 | StackTraceElement[] elems = Thread.currentThread().getStackTrace(); 81 | StackTraceElement elem = null; 82 | int offset = 1; 83 | for (int i = 0; i < elems.length; i++) { 84 | //search for the first non-config / non-java class 85 | if (Stream.of(elems[i].getClassName()) 86 | .filter(k -> !k.startsWith("java")) 87 | .filter(k -> !k.startsWith("com.codelanx.codelanxlib.config")) 88 | .filter(k -> !k.startsWith("com.codelanx.commons.config")) 89 | .findFirst().isPresent()) { 90 | elem = elems[i]; 91 | offset = i; 92 | break; 93 | } 94 | } 95 | if (elem == null) { 96 | System.out.println("No match found, getting most recent caller"); 97 | elem = Reflections.getCaller(1); 98 | } 99 | System.out.println("Caller: " + elem); 100 | /* 101 | int offset; 102 | if (!elem.getClassName().equals(InfoFile.class.getName())) { //wrong, but left as an example of the idea 103 | offset = 0; 104 | } else if (elem.getMethodName().equals("save")) { 105 | offset = 2; 106 | } else { 107 | //assume it's through a config #get call etc 108 | }*/ 109 | System.out.println("Offset: " + offset + " (from file: " + (offset - 1) + ")"); 110 | return 0; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/econ/ChargeStatus.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.econ; 21 | 22 | /** 23 | * Represents the result of a call to 24 | * {@link CEconomy#canCharge(org.bukkit.OfflinePlayer, double) CEconomy#canCharge} 25 | * 26 | * @since 0.0.1 27 | * @author 1Rogue 28 | * @version 0.0.1 29 | */ 30 | public class ChargeStatus { 31 | 32 | /** Whether or not the transaction is capable of being done */ 33 | private final boolean status; 34 | /** The amount being charged */ 35 | private final double amount; 36 | 37 | /** 38 | * Constructor. Assigns parameters to fields 39 | * 40 | * @since 0.0.1 41 | * @version 0.0.1 42 | * 43 | * @param status {@code true} if the charge can be made 44 | * @param amount The actual amount being charged (accounts for taxes, etc) 45 | */ 46 | protected ChargeStatus(boolean status, double amount) { 47 | this.status = status; 48 | this.amount = amount; 49 | } 50 | 51 | /** 52 | * Returns whether or not the player is capable of paying the charge 53 | * 54 | * @since 0.0.1 55 | * @version 0.0.1 56 | * 57 | * @return {@code true} if the player can pay the charge 58 | */ 59 | public boolean getStatus() { 60 | return this.status; 61 | } 62 | 63 | /** 64 | * The actual amount being charged, including any modifications such as 65 | * taxes. Outputs to the player about balance should use this return value 66 | * 67 | * @since 0.0.1 68 | * @version 0.0.1 69 | * 70 | * @return The amount being charged 71 | */ 72 | public double getAmount() { 73 | return this.amount; 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/econ/EconomyChangePacket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.econ; 21 | 22 | import org.bukkit.OfflinePlayer; 23 | 24 | /** 25 | * Packet used to describe a change in balance from a transaction with Vault 26 | * 27 | * @since 0.0.1 28 | * @author 1Rogue 29 | * @version 0.1.0 30 | */ 31 | public class EconomyChangePacket { 32 | 33 | /** The relevant {@link OfflinePlayer} to this packet */ 34 | private final OfflinePlayer p; 35 | /** The new balance */ 36 | private final double amount; 37 | 38 | /** 39 | * Constructor. Assigns parameters to fields 40 | * 41 | * @since 0.0.1 42 | * @version 0.1.0 43 | * 44 | * @param p The {@link OfflinePlayer} whose balance changed 45 | * @param amount The new balance 46 | */ 47 | public EconomyChangePacket(OfflinePlayer p, double amount) { 48 | this.p = p; 49 | this.amount = amount; 50 | } 51 | 52 | /** 53 | * The {@link OfflinePlayer} whose balance changed 54 | * 55 | * @since 0.0.1 56 | * @version 0.1.0 57 | * 58 | * @return The relevant {@link OfflinePlayer} object 59 | */ 60 | public OfflinePlayer getPlayer() { 61 | return this.p; 62 | } 63 | 64 | /** 65 | * Returns the new balance 66 | * 67 | * @since 0.0.1 68 | * @version 0.0.1 69 | * 70 | * @return The new balance 71 | */ 72 | public double getAmount() { 73 | return this.amount; 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/econ/EconomyObserver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.econ; 21 | 22 | import java.util.Observable; 23 | import java.util.Observer; 24 | 25 | /** 26 | * Provides a type to {@link Observer} for ease-of-use 27 | * 28 | * @since 0.2.0 29 | * @author 1Rogue 30 | * @version 0.2.0 31 | */ 32 | @FunctionalInterface 33 | public interface EconomyObserver extends Observer { 34 | 35 | /** 36 | * Called whenever the economy state changes 37 | * 38 | * @since 0.2.0 39 | * @version 0.2.0 40 | * 41 | * @param o The {@link CEconomy} object being observed 42 | * @param arg The {@link EconomyChangePacket} of the economy change 43 | */ 44 | void update(CEconomy o, EconomyChangePacket arg); 45 | 46 | /** 47 | * {@inheritDoc} 48 | * 49 | * @since 0.2.0 50 | * @version 0.2.0 51 | * 52 | * @param o {@inheritDoc} 53 | * @param arg {@inheritDoc} 54 | */ 55 | default void update(Observable o, Object arg) { 56 | if (!(o instanceof CEconomy) || !(arg instanceof EconomyChangePacket)) { 57 | return; 58 | } 59 | update((CEconomy) o, (EconomyChangePacket) arg); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/econ/VaultProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.econ; 21 | 22 | import com.codelanx.codelanxlib.events.EconomyChangeEvent; 23 | import com.codelanx.commons.logging.Debugger; 24 | import net.milkbowl.vault.Vault; 25 | import net.milkbowl.vault.economy.Economy; 26 | import org.bukkit.Bukkit; 27 | import org.bukkit.OfflinePlayer; 28 | import org.bukkit.Server; 29 | import org.bukkit.entity.Player; 30 | import org.bukkit.plugin.RegisteredServiceProvider; 31 | import org.bukkit.plugin.ServicePriority; 32 | import org.bukkit.plugin.java.JavaPlugin; 33 | 34 | import java.lang.reflect.InvocationHandler; 35 | import java.lang.reflect.Method; 36 | import java.lang.reflect.Proxy; 37 | import java.util.Arrays; 38 | import java.util.LinkedHashSet; 39 | import java.util.Set; 40 | import java.util.logging.Level; 41 | 42 | /** 43 | * A proxy {@link InvocationHandler} class for Vault's {@link Economy} class, 44 | * used to make it possible to observe changes in the {@link Economy} status 45 | * without modifying the original class 46 | * 47 | * @since 0.0.1 48 | * @author 1Rogue 49 | * @version 0.1.0 50 | */ 51 | public final class VaultProxy implements InvocationHandler { 52 | 53 | /** The cached {@link Economy} class that Vault registered */ 54 | private final Economy econ; 55 | /** The registered {@link CEconomy} classes listening to changes */ 56 | private final static Set econs = new LinkedHashSet<>(); 57 | /** Known methods that do not need to be listened to */ 58 | private final static Set blackListed = new LinkedHashSet() {{ 59 | addAll(Arrays.asList( 60 | "getBalance", 61 | "bankBalance", 62 | "bankHas", 63 | "currencyNameSingular", 64 | "currencyNamePlural", 65 | "format", 66 | "fractionalDigits", 67 | "getBanks", 68 | "getName", 69 | "has", 70 | "hasAccount", 71 | "hasBankSupport", 72 | "isBankMember", 73 | "isBankOwner", 74 | "isEnabled" 75 | )); 76 | }}; 77 | 78 | /** 79 | * Constructor. Holds the {@link Economy} object registered from Vault 80 | * 81 | * @since 0.0.1 82 | * @version 0.0.1 83 | * 84 | * @param econ The {@link Economy} object 85 | */ 86 | private VaultProxy(Economy econ) { 87 | this.econ = econ; 88 | } 89 | 90 | /** 91 | * {@inheritDoc} 92 | * 93 | * @since 0.0.1 94 | * @version 0.1.0 95 | * 96 | * @param proxy {@inheritDoc} 97 | * @param m {@inheritDoc} 98 | * @param args {@inheritDoc} 99 | * @return {@inheritDoc} 100 | * @throws Throwable Any relevant errors resulting from a method call 101 | */ 102 | @Override 103 | public Object invoke(Object proxy, Method m, Object[] args) throws Throwable { 104 | Object back = m.invoke(this.econ, args); 105 | if (args != null && args.length > 0 && !VaultProxy.blackListed.contains(m.getName())) { 106 | OfflinePlayer o; 107 | if (args[0] instanceof String) { 108 | String s = (String) args[0]; 109 | o = Bukkit.getOfflinePlayer(s); 110 | } else if (args[0] instanceof OfflinePlayer) { 111 | o = (OfflinePlayer) args[0]; 112 | } else { 113 | return back; 114 | } 115 | if (o.isOnline()) { 116 | Player p = (Player) o; 117 | double bal = this.econ.getBalance(p); 118 | Bukkit.getServer().getPluginManager().callEvent( 119 | new EconomyChangeEvent(p, bal)); 120 | EconomyChangePacket packet = new EconomyChangePacket(p, bal); 121 | VaultProxy.econs.forEach(e -> { 122 | e.setChanged(); 123 | e.notifyObservers(packet); 124 | }); 125 | } 126 | } 127 | return back; 128 | } 129 | 130 | /** 131 | * Proxies the Vault {@link Economy} class and replaces it with a 132 | * {@link VaultProxy} instance to handle method invocation, allowing 133 | * {@link CEconomy} objects to be notified upon money updates 134 | * 135 | * @since 0.0.1 136 | * @version 0.0.1 137 | */ 138 | static void proxyVault() { 139 | try { 140 | Server server = Bukkit.getServer(); 141 | RegisteredServiceProvider rsp = server.getServicesManager().getRegistration(Economy.class); 142 | if (rsp == null) { 143 | Debugger.print(Level.SEVERE, "No economy found, will not proxy Vault"); 144 | return; 145 | } 146 | ServicePriority priority = rsp.getPriority(); 147 | Economy e = rsp.getProvider(); 148 | if (e == null) { 149 | Debugger.print(Level.SEVERE, "Error proxying vault economy! No responsive updating"); 150 | return; 151 | } 152 | if (Proxy.isProxyClass(e.getClass())) { 153 | return; 154 | } 155 | ClassLoader l = Economy.class.getClassLoader(); 156 | Vault v = JavaPlugin.getPlugin(Vault.class); 157 | if (v == null) { 158 | Debugger.print(Level.SEVERE, "Vault not found even after retrieving economy class. Wizardry!"); 159 | return; 160 | } 161 | if (l == null) { 162 | l = v.getClass().getClassLoader(); 163 | if (l == null) { 164 | Debugger.print(Level.SEVERE, "Unable to retrieve economy classloader"); 165 | return; 166 | } 167 | } 168 | server.getServicesManager().unregister(Economy.class); 169 | server.getServicesManager().register(Economy.class, 170 | (Economy) Proxy.newProxyInstance(l, new Class[]{Economy.class}, new VaultProxy(e)), 171 | v, 172 | priority); 173 | } catch (SecurityException | IllegalArgumentException ex) { 174 | Debugger.error(ex, "Error proxying vault economy class"); 175 | } 176 | } 177 | 178 | /** 179 | * Registers a {@link CEconomy} object to the {@link VaultProxy} 180 | * {@link InvocationHandler}. 181 | * 182 | * @since 0.0.1 183 | * @version 0.0.1 184 | * 185 | * @param The type of the {@link CEconomy} class 186 | * @param econ The {@link CEconomy} instance 187 | * @return {@code true} if the class was registered and cached 188 | */ 189 | public static boolean register(T econ) { 190 | return VaultProxy.econs.add(econ); 191 | } 192 | 193 | } 194 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/econ/VaultProxyListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.econ; 21 | 22 | import com.codelanx.codelanxlib.listener.ListenerManager; 23 | import com.codelanx.codelanxlib.listener.SubListener; 24 | import com.codelanx.commons.util.Reflections; 25 | import com.codelanx.commons.util.exception.Exceptions; 26 | import com.codelanx.codelanxlib.CodelanxLib; 27 | import net.milkbowl.vault.economy.Economy; 28 | import org.bukkit.event.EventHandler; 29 | import org.bukkit.event.EventPriority; 30 | import org.bukkit.event.server.ServiceRegisterEvent; 31 | import org.bukkit.plugin.RegisteredServiceProvider; 32 | 33 | /** 34 | * Listens for when Vault registers its {@link Economy} service provider and 35 | * replaces it with a {@link VaultProxy} 36 | * 37 | * @since 0.1.0 38 | * @author 1Rogue 39 | * @version 0.1.0 40 | */ 41 | public class VaultProxyListener extends SubListener { 42 | 43 | /** 44 | * Useless, just follows contract for {@link SubListener} 45 | * 46 | * @since 0.1.0 47 | * @version 0.1.0 48 | * 49 | * @param plugin The {@link CodelanxLib} plugin 50 | */ 51 | public VaultProxyListener(CodelanxLib plugin) { 52 | super(plugin); 53 | Exceptions.illegalInvocation(Reflections.accessedFrom(CodelanxLib.class)); 54 | } 55 | 56 | /** 57 | * Listens for registration of Vault's {@link Economy} class and replaces it 58 | * with a {@link VaultProxy} 59 | * 60 | * @since 0.1.0 61 | * @version 0.1.0 62 | * 63 | * @param event The relevant {@link ServiceRegisterEvent} 64 | */ 65 | @EventHandler(priority = EventPriority.HIGHEST) 66 | public void onEconomy(ServiceRegisterEvent event) { 67 | RegisteredServiceProvider rsp = event.getProvider(); 68 | if (Economy.class.isAssignableFrom(rsp.getProvider().getClass())) { 69 | VaultProxy.proxyVault(); 70 | ListenerManager.unregisterListener(VaultProxyListener.class); 71 | } 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/events/EconomyChangeEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.events; 21 | 22 | import org.bukkit.OfflinePlayer; 23 | import org.bukkit.event.Event; 24 | import org.bukkit.event.HandlerList; 25 | 26 | /** 27 | * Fired when a player balance changes via Vault 28 | * 29 | * @since 0.0.1 30 | * @author 1Rogue 31 | * @version 0.1.0 32 | */ 33 | public class EconomyChangeEvent extends Event { 34 | 35 | /** {@link HandlerList} for this event */ 36 | protected static final HandlerList handlers = new HandlerList(); 37 | /** The new balance */ 38 | private final double money; 39 | /** The {@link OfflinePlayer} whose money changed */ 40 | private final OfflinePlayer p; 41 | 42 | /** 43 | * Constructor. Assigns the {@link OfflinePlayer} and money to fields 44 | * 45 | * @since 0.0.1 46 | * @version 0.1.0 47 | * 48 | * @param p The {@link OfflinePlayer} whose balance changed 49 | * @param money The new balance 50 | */ 51 | public EconomyChangeEvent(OfflinePlayer p, double money) { 52 | this.p = p; 53 | this.money = money; 54 | } 55 | 56 | /** 57 | * The {@link OfflinePlayer} whose balance changed 58 | * 59 | * @since 0.0.1 60 | * @version 0.1.0 61 | * 62 | * @return The relevant {@link OfflinePlayer} object 63 | */ 64 | public OfflinePlayer getPlayer() { 65 | return this.p; 66 | } 67 | 68 | /** 69 | * Returns the new balance for the {@link OfflinePlayer} 70 | * 71 | * @since 0.0.1 72 | * @version 0.0.1 73 | * 74 | * @return The new balance 75 | */ 76 | public double getNewBalance() { 77 | return this.money; 78 | } 79 | 80 | /** 81 | * {@inheritDoc} 82 | * 83 | * @since 0.0.1 84 | * @version 0.0.1 85 | * 86 | * @return {@inheritDoc} 87 | */ 88 | @Override 89 | public HandlerList getHandlers() { 90 | return handlers; 91 | } 92 | 93 | /** 94 | * Returns the {@link HandlerList} that Bukkit uses to register plugins 95 | * for events 96 | * 97 | * @since 0.0.1 98 | * @version 0.0.1 99 | * 100 | * @return The internal {@link HandlerList} for this event 101 | */ 102 | public static HandlerList getHandlerList() { 103 | return handlers; 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/events/ReloadEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.events; 21 | 22 | import com.codelanx.codelanxlib.command.ReloadCommand; 23 | import org.bukkit.event.Event; 24 | import org.bukkit.event.HandlerList; 25 | import org.bukkit.plugin.Plugin; 26 | 27 | /** 28 | * Event fired upon the use of a 29 | * {@link ReloadCommand ReloadCommand} 30 | * 31 | * @since 0.0.1 32 | * @author 1Rogue 33 | * @version 0.0.1 34 | * 35 | * @param The {@link Plugin} being reloaded 36 | */ 37 | public class ReloadEvent extends Event { 38 | 39 | /** {@link HandlerList} for this event */ 40 | protected static final HandlerList handlers = new HandlerList(); 41 | /** {@link Plugin} that is reloaded */ 42 | private final E plugin; 43 | 44 | /** 45 | * Constructor. Assigns the passed {@link Plugin} to a field 46 | * 47 | * @since 0.0.1 48 | * @version 0.0.1 49 | * 50 | * @param plugin The {@link Plugin} that fired this {@link ReloadEvent} 51 | */ 52 | public ReloadEvent(E plugin) { 53 | this.plugin = plugin; 54 | } 55 | 56 | /** 57 | * Returns the {@link Plugin} involved with this event 58 | * 59 | * @since 0.0.1 60 | * @version 0.0.1 61 | * 62 | * @return The relevant {@link Plugin} 63 | */ 64 | public E getPlugin() { 65 | return this.plugin; 66 | } 67 | 68 | /** 69 | * {@inheritDoc} 70 | * 71 | * @since 0.0.1 72 | * @version 0.0.1 73 | * 74 | * @return {@inheritDoc} 75 | */ 76 | @Override 77 | public HandlerList getHandlers() { 78 | return handlers; 79 | } 80 | 81 | /** 82 | * Returns the {@link HandlerList} that Bukkit uses to register plugins 83 | * for events 84 | * 85 | * @since 0.0.1 86 | * @version 0.0.1 87 | * 88 | * @return The internal {@link HandlerList} for this event 89 | */ 90 | public static HandlerList getHandlerList() { 91 | return handlers; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/implementers/Economics.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.implementers; 21 | 22 | import com.codelanx.codelanxlib.econ.CEconomy; 23 | 24 | /** 25 | * Represents a plugin that utilizes the {@link CEconomy} class 26 | * 27 | * @since 0.0.1 28 | * @author 1Rogue 29 | * @version 0.0.1 30 | */ 31 | public interface Economics extends Formatted { 32 | 33 | /** 34 | * Gets the {@link CEconomy} for the plugin, which represents a facade 35 | * interface for charging players money 36 | * 37 | * @since 0.0.1 38 | * @version 0.0.1 39 | * 40 | * @return The {@link CEconomy} instance 41 | */ 42 | public CEconomy getEconomy(); 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/implementers/Formatted.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.implementers; 21 | 22 | import com.codelanx.commons.config.LangFile; 23 | import com.codelanx.codelanxlib.config.Lang; 24 | 25 | /** 26 | * Describes a plugin with a message format 27 | * 28 | * @since 0.1.0 29 | * @author 1Rogue 30 | * @version 0.1.0 31 | */ 32 | public interface Formatted { 33 | 34 | /** 35 | * The {@link LangFile} format to use for any plugin output 36 | * 37 | * @since 0.1.0 38 | * @version 0.1.0 39 | * 40 | * @return The {@link LangFile} object to use for plugin output as a format 41 | */ 42 | public Lang getFormat(); 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/implementers/Reloadable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.implementers; 21 | 22 | /** 23 | * Represents a plugin that is capable of being reloaded 24 | * 25 | * @since 0.1.0 26 | * @author 1Rogue 27 | * @version 0.1.0 28 | */ 29 | public interface Reloadable { 30 | 31 | /** 32 | * Method that is called upon reloading of the plugin. If using a 33 | * ReloadEvent, then this method is not required 34 | * 35 | * @since 0.1.0 36 | * @version 0.1.0 37 | */ 38 | public void reload(); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/internal/InternalLang.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.internal; 21 | 22 | import com.codelanx.codelanxlib.CodelanxLib; 23 | import com.codelanx.codelanxlib.command.HelpCommand; 24 | import com.codelanx.codelanxlib.command.ReloadCommand; 25 | import com.codelanx.codelanxlib.config.Lang; 26 | import com.codelanx.codelanxlib.config.PluginClass; 27 | import com.codelanx.codelanxlib.util.Paginator; 28 | import com.codelanx.commons.config.DataHolder; 29 | import com.codelanx.commons.config.LangFile; 30 | import com.codelanx.commons.config.RelativePath; 31 | import com.codelanx.commons.data.types.Yaml; 32 | 33 | /** 34 | * Internal {@link LangFile} enum for CodelanxLib 35 | * 36 | * @since 0.1.0 37 | * @author 1Rogue 38 | * @version 0.1.0 39 | */ 40 | @PluginClass(CodelanxLib.class) 41 | @RelativePath("lang.yml") 42 | public enum InternalLang implements Lang { 43 | 44 | /** 45 | * Used to relay the usage of a command 46 | */ 47 | COMMAND_STATUS_USAGE("command.status.usage", "Usage: /%s"), 48 | /** 49 | * Displayed when a non-executable command is run 50 | */ 51 | COMMAND_STATUS_NOTEXEC("command.status.not-executable", "Did you mean?:%s"), 52 | /** 53 | * Relayed if a CommandSender does not have permissions to use the command 54 | */ 55 | COMMAND_STATUS_NOPERM("command.status.noperm", "&cYou do not have permission for this!"), 56 | /** 57 | * Relayed when a command execution fail (exceptions or the like) 58 | */ 59 | COMMAND_STATUS_FAILED("command.status.failed", "Command execution failed :("), 60 | /** 61 | * Relayed upon an unknown/unsupported command 62 | */ 63 | COMMAND_STATUS_UNSUPPORTED("command.status.unsupported", "Unknown commmand."), 64 | /** 65 | * Relayed when an inappropriate CommandSender is used for a command 66 | */ 67 | COMMAND_STATUS_RESTRICTED("command.status.restricted", "This command should only be used by %s!"), 68 | /** 69 | * Relayed when a proxied CommandSender attempts executing a command 70 | */ 71 | COMMAND_STATUS_NOPROXIES("command.status.no-proxies", "This command cannot be executed by a proxied sender!"), 72 | /** 73 | * Title for the {@link HelpCommand}'s internal {@link Paginator} 74 | */ 75 | COMMAND_HELP_TITLEFORMAT("command.help.format.title", "/%s help"), 76 | /** 77 | * Format for listing a command in {@link HelpCommand} 78 | */ 79 | COMMAND_HELP_ITEMFORMAT("command.help.format.item", "&9%s &f- &7%s"), 80 | /** 81 | * Help information for {@link HelpCommand} 82 | */ 83 | COMMAND_HELP_INFO("command.help.info", "Displays help information about this plugin"), 84 | /** 85 | * What to title command aliases as 86 | */ 87 | COMMAND_HELP_ALIASES("command.help.format.aliases-title", "Aliases:"), 88 | /** 89 | * Relayed if reloading is not supported 90 | */ 91 | COMMAND_RELOAD_UNSUPPORTED("command.reload.unsupported", "This plugin does not support reloading!"), 92 | /** 93 | * Output of a finished {@link ReloadCommand} 94 | */ 95 | COMMAND_RELOAD_DONE("command.reload.done", "&9%s&f v&9%s&f reloaded!"), 96 | /** 97 | * Info for {@link ReloadCommand} 98 | */ 99 | COMMAND_RELOAD_INFO("command.reload.info", "Reloads the plugin"), 100 | /** 101 | * Relayed if funds for an economy transaction are insufficient 102 | */ 103 | ECONOMY_INSUFF("economy.insufficient", "You do not have enough money for this! (Required: %.2f)"), 104 | /** 105 | * Relayed if a player is refunded money 106 | */ 107 | ECONOMY_REFUND("economy.refund", "Refunded amount &7.2f&9"), 108 | /** 109 | * Relayed if an economy transaction failed 110 | */ 111 | ECONOMY_FAILED("economy.trans-failed", "&cError:&7 Failed to charge your account!"), 112 | /** 113 | * Character to use for the {@link Paginator} bars 114 | */ 115 | PAGINATOR_BARCHAR("utils.paginator.barchar", "-"), 116 | /** 117 | * Bar color for the {@link Paginator} class 118 | */ 119 | PAGINATOR_BARCOLOR("utils.paginator.barcolor", "&f"), 120 | /** 121 | * Color of the title for the {@link Paginator} class 122 | */ 123 | PAGINATOR_TITLECOLOR("utils.paginator.titlecolor", "&c"), 124 | /** 125 | * Accept a bar color first, title color second, then the title itself third 126 | */ 127 | PAGINATOR_TITLECONTAINER("utils.paginator.title-container", "%1$s[ %2$s%3$s %1$s]"), 128 | /** 129 | * The format specified for displaying page count 130 | */ 131 | PAGINATOR_PAGEFORMAT("utils.paginator.page-format", "Page (%d/%d)"), 132 | /** 133 | * Format for CodelanxLib 134 | */ 135 | FORMAT("format", "&f[&9CL-Lib&f] %s"); 136 | 137 | private static final DataHolder DATA = new DataHolder<>(Yaml.class); 138 | private final String def; 139 | private final String path; 140 | 141 | /** 142 | * {@link InternalLang} private constructor 143 | * 144 | * @since 0.1.0 145 | * @version 0.1.0 146 | * 147 | * @param path The path to the value 148 | * @param def The default value 149 | */ 150 | private InternalLang(String path, String def) { 151 | this.path = path; 152 | this.def = def; 153 | } 154 | 155 | @Override 156 | public String getPath() { 157 | return this.path; 158 | } 159 | 160 | @Override 161 | public String getDefault() { 162 | return this.def; 163 | } 164 | 165 | @Override 166 | public Lang getFormat() { 167 | return InternalLang.FORMAT; 168 | } 169 | 170 | @Override 171 | public DataHolder getData() { 172 | return InternalLang.DATA; 173 | } 174 | 175 | } 176 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/internal/InternalPerms.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.internal; 21 | 22 | import com.codelanx.codelanxlib.permission.Permissions; 23 | import com.codelanx.codelanxlib.util.Protections; 24 | 25 | /** 26 | * Internal {@link Permissions} enum for CodelanxLib 27 | * 28 | * @since 0.1.0 29 | * @author 1Rogue 30 | * @version 0.1.0 31 | */ 32 | public enum InternalPerms implements Permissions { 33 | 34 | /** 35 | * Allows bypassing protection provided by the 36 | * {@link Protections Protections} class 37 | * 38 | * @since 0.1.0 39 | * @version 0.1.0 40 | */ 41 | PROTECTION_OVERRIDE("protect.override"); 42 | 43 | private final String permission; 44 | 45 | private InternalPerms(String permission) { 46 | this.permission = permission; 47 | } 48 | 49 | @Override 50 | public String getBase() { 51 | return "commons"; 52 | } 53 | 54 | @Override 55 | public String getNode() { 56 | return this.permission; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/inventory/Inventories.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.inventory; 21 | 22 | import com.codelanx.commons.util.RNG; 23 | import com.sun.org.apache.xerces.internal.impl.dv.util.Base64; 24 | import org.bukkit.entity.Item; 25 | import org.bukkit.entity.Player; 26 | import org.bukkit.event.inventory.InventoryClickEvent; 27 | import org.bukkit.inventory.Inventory; 28 | import org.bukkit.inventory.ItemStack; 29 | 30 | import java.util.ArrayList; 31 | import java.util.Arrays; 32 | import java.util.List; 33 | import java.util.Map; 34 | 35 | /** 36 | * Utility methods for simplifying the use of Bukkit's inventory API, or 37 | * providing methods that can accomplish tasks that have obscure or complicated 38 | * solutions. 39 | * 40 | * @since 0.0.1 41 | * @author 1Rogue 42 | * @version 0.1.0 43 | */ 44 | public final class Inventories { 45 | 46 | private Inventories() { 47 | } 48 | 49 | /** 50 | * Returns whether or not the player clicked the top or bottom inventory 51 | * 52 | * @since 0.0.1 53 | * @version 0.0.1 54 | * 55 | * @param event The relevant {@link InventoryClickEvent} 56 | * @return {@code true} for clicking the top, {@code false} otherwise 57 | */ 58 | public static boolean hasClickedTop(InventoryClickEvent event) { 59 | return event.getRawSlot() == event.getSlot(); 60 | } 61 | 62 | /** 63 | * Returns the slot(s) that an {@link Item} would be placed into. 64 | * 65 | * @since 0.1.0 66 | * @version 0.1.0 67 | * 68 | * @param item The {@link Item} being placed into an {@link Inventory} 69 | * @param inv The {@link Inventory} being placed into 70 | * @return The slot(s) that would be affected by this placement 71 | */ 72 | public static Integer[] findPlacement(Item item, Inventory inv) { 73 | ItemStack stack = item.getItemStack(); 74 | int amount = stack.getAmount(); 75 | List back = new ArrayList<>(); 76 | Map items = inv.all(stack.getType()); 77 | for (Map.Entry ent : items.entrySet()) { 78 | if (amount <= 0) { 79 | break; 80 | } 81 | back.add(ent.getKey()); 82 | ItemStack i = ent.getValue(); 83 | amount -= i.getMaxStackSize() - i.getAmount(); 84 | } 85 | if (amount > 0) { 86 | ItemStack[] inventory = inv.getContents(); 87 | for (int i = 0; i < inventory.length; i++) { 88 | if (inventory[i] == null) { 89 | amount -= stack.getMaxStackSize(); 90 | back.add(i); 91 | } 92 | } 93 | } 94 | return back.toArray(new Integer[back.size()]); 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/inventory/InventoryState.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.inventory; 21 | 22 | import org.bukkit.inventory.Inventory; 23 | import org.bukkit.inventory.InventoryHolder; 24 | import org.bukkit.inventory.ItemStack; 25 | 26 | import java.util.Arrays; 27 | 28 | /** 29 | * An immutable class that represents the state of an {@link Inventory} 30 | * 31 | * @since 0.1.0 32 | * @author 1Rogue 33 | * @version 0.1.0 34 | */ 35 | public class InventoryState { 36 | 37 | private final ItemStack[] contents; 38 | 39 | /** 40 | * Constructor. Copies the contents of the passed inventory 41 | * 42 | * @since 0.1.0 43 | * @version 0.1.0 44 | * 45 | * @param i The {@link Inventory} to copy 46 | */ 47 | public InventoryState(Inventory i) { 48 | ItemStack[] arr = i.getContents(); 49 | this.contents = Arrays.copyOf(arr, arr.length); 50 | } 51 | 52 | /** 53 | * Returns a copy of the underlying array from the inventory contents. 54 | * 55 | * @since 0.1.0 56 | * @version 0.1.0 57 | * 58 | * @deprecated Returns an array copy, should not be used heavily 59 | * @return A copy of the inventory contents 60 | */ 61 | public ItemStack[] getContents() { 62 | return Arrays.copyOf(this.contents, this.contents.length); 63 | } 64 | 65 | /** 66 | * Returns the {@link ItemStack} in the given inventory slot 67 | * 68 | * @since 0.1.0 69 | * @version 0.1.0 70 | * 71 | * @param index The index or "slot" to retrieve from 72 | * @return The {@link ItemStack} in the relevant index 73 | * @throws ArrayIndexOutOfBoundsException {@code 0 <= index < size()} 74 | */ 75 | public ItemStack getItem(int index) { 76 | return this.contents[index]; 77 | } 78 | 79 | /** 80 | * Returns the length of the underlying {@link ItemStack} array 81 | * 82 | * @since 0.1.0 83 | * @version 0.1.0 84 | * 85 | * @return The length of the underlying contents array 86 | */ 87 | public int size() { 88 | return this.contents.length; 89 | } 90 | 91 | /** 92 | * Sets the contents of this state into an {@link InventoryHolder} 93 | * 94 | * @since 0.1.0 95 | * @version 0.1.0 96 | * 97 | * @param holder The {@link InventoryHolder} to set the contents of 98 | */ 99 | public void setContents(InventoryHolder holder) { 100 | holder.getInventory().setContents(this.getContents()); 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/inventory/ItemStackBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.inventory; 21 | 22 | import com.codelanx.codelanxlib.config.Lang; 23 | import org.bukkit.Bukkit; 24 | import org.bukkit.ChatColor; 25 | import org.bukkit.Material; 26 | import org.bukkit.enchantments.Enchantment; 27 | import org.bukkit.inventory.ItemStack; 28 | import org.bukkit.inventory.meta.ItemMeta; 29 | 30 | import java.util.ArrayList; 31 | import java.util.HashMap; 32 | import java.util.List; 33 | import java.util.Map; 34 | import java.util.stream.Collectors; 35 | 36 | /** 37 | * Allows for the full creation of an {@link ItemStack} within a static context. 38 | * All color codes using '{@code &}' can be automatically converted 39 | * 40 | * @since 0.0.1 41 | * @author 1Rogue 42 | * @version 0.0.1 43 | */ 44 | public class ItemStackBuilder { 45 | 46 | /** Prefix for lore items because purple is ugly */ 47 | public static final String DEFAULT_PREFIX = ChatColor.RESET + "" + ChatColor.BLUE + "" + ChatColor.BOLD; 48 | /** A prefix that can be set for all lore */ 49 | protected String lorePrefix = ItemStackBuilder.DEFAULT_PREFIX; 50 | /** The name for the {@link ItemStack} */ 51 | protected String name; 52 | /** The lore for the {@link ItemStack} */ 53 | protected List lore = new ArrayList<>(); 54 | /** A mapping of {@link Enchantment Enchantments} to their levels */ 55 | protected Map enchantments = new HashMap<>(); 56 | /** The {@link Material type} for the {@link ItemStack} */ 57 | protected Material type; 58 | /** The amount of items in the {@link ItemStack} */ 59 | protected int amount; 60 | /** The durability of the {@link ItemStack} */ 61 | protected short durability; 62 | /** Specifies whether or not to automatically translate color codes */ 63 | protected boolean autoTranslate = true; 64 | 65 | /** 66 | * Sets the display name for the {@link ItemStack} 67 | * 68 | * @since 0.0.1 69 | * @version 0.0.1 70 | * 71 | * @param name The display name 72 | * @return This instance (chained) 73 | */ 74 | public ItemStackBuilder name(String name) { 75 | this.name = Lang.color(name); 76 | return this; 77 | } 78 | 79 | /** 80 | * Adds lore to the {@link ItemStack} 81 | * 82 | * @since 0.0.1 83 | * @version 0.1.0 84 | * 85 | * @param lore The lore to add 86 | * @return This instance (chained) 87 | */ 88 | public ItemStackBuilder addLore(String lore) { 89 | this.lore.add(Lang.color(lore)); 90 | return this; 91 | } 92 | 93 | /** 94 | * Sets the prefix to use for all lore items 95 | * 96 | * @since 0.1.0 97 | * @version 0.l.0 98 | * 99 | * @param prefix The prefix to set 100 | * @return This instance (chained) 101 | */ 102 | public ItemStackBuilder lorePrefix(String prefix) { 103 | this.lorePrefix = prefix; 104 | return this; 105 | } 106 | 107 | /** 108 | * Sets the durability to apply to the {@link ItemStack} 109 | * 110 | * @since 0.1.0 111 | * @version 0.1.0 112 | * 113 | * @param durability The durability to use (can also be a data value) 114 | * @return This instance (chained) 115 | */ 116 | public ItemStackBuilder durability(short durability) { 117 | this.durability = durability; 118 | return this; 119 | } 120 | 121 | /** 122 | * Sets whether or not to automatically translate color codes 123 | * 124 | * @since 0.1.0 125 | * @version 0.1.0 126 | * 127 | * @param autoTranslate {@code true} to automatically translate '{@code &}' 128 | * @return This instance (chained) 129 | */ 130 | public ItemStackBuilder autoTranslateColors(boolean autoTranslate) { 131 | this.autoTranslate = autoTranslate; 132 | return this; 133 | } 134 | 135 | /** 136 | * Adds an enchantment to the {@link ItemStack} 137 | * 138 | * @since 0.0.1 139 | * @version 0.0.1 140 | * 141 | * @param ench The {@link Enchantment} to add 142 | * @param level The level of the enchantment 143 | * @return This instance (chained) 144 | */ 145 | public ItemStackBuilder addEnchantment(Enchantment ench, int level) { 146 | this.enchantments.put(ench, level); 147 | return this; 148 | } 149 | 150 | /** 151 | * Sets the {@link Material} type for the {@link ItemStack} 152 | * 153 | * @since 0.0.1 154 | * @version 0.0.1 155 | * 156 | * @param type The {@link Material} type to set 157 | * @return This instance (chained) 158 | */ 159 | public ItemStackBuilder type(Material type) { 160 | this.type = type; 161 | return this; 162 | } 163 | 164 | /** 165 | * Sets the amount of items in the {@link ItemStack} 166 | * 167 | * @since 0.0.1 168 | * @version 0.0.1 169 | * 170 | * @param amount The amount to set 171 | * @return This instance (chained) 172 | */ 173 | public ItemStackBuilder amount(int amount) { 174 | this.amount = amount; 175 | return this; 176 | } 177 | 178 | /** 179 | * Builds the {@link ItemStack} object and returns it 180 | * 181 | * @since 0.0.1 182 | * @version 0.0.1 183 | * 184 | * @return The new {@link ItemStack} 185 | * @throws IllegalArgumentException If type is {@code null}, 186 | * {@code amount <= 0}, or 187 | * {@code amount > } 188 | * {@link Material#getMaxStackSize} 189 | */ 190 | public ItemStack build() { 191 | if (this.type == null || this.amount <= 0 || this.amount > this.type.getMaxStackSize()) { 192 | throw new IllegalArgumentException("Illegal fields in " + this.getClass().getSimpleName()); 193 | } 194 | String name; 195 | List lore = new ArrayList<>(this.lore).stream().map(l -> this.lorePrefix + l).collect(Collectors.toList()); 196 | if (this.autoTranslate) { 197 | name = Lang.color(this.name); 198 | lore = lore.stream().map(l -> Lang.color(l)).collect(Collectors.toList()); 199 | } else { 200 | name = this.name; 201 | } 202 | ItemStack back = new ItemStack(this.type); 203 | back.setAmount(this.amount); 204 | ItemMeta meta = Bukkit.getItemFactory().getItemMeta(this.type); 205 | meta.setDisplayName(name); 206 | meta.setLore(lore); 207 | back.setItemMeta(meta); 208 | back.addEnchantments(this.enchantments); 209 | back.setDurability(this.durability); 210 | return back; 211 | } 212 | 213 | } 214 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/inventory/PlayerInventoryState.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.inventory; 21 | 22 | import org.apache.commons.lang.Validate; 23 | import org.bukkit.entity.HumanEntity; 24 | import org.bukkit.inventory.InventoryHolder; 25 | import org.bukkit.inventory.ItemStack; 26 | import org.bukkit.inventory.PlayerInventory; 27 | 28 | /** 29 | * An immutable class that represents the state of a {@link PlayerInventory} 30 | * 31 | * @since 0.1.0 32 | * @author 1Rogue 33 | * @version 0.1.0 34 | */ 35 | public class PlayerInventoryState extends InventoryState { 36 | 37 | private final ItemStack helmet; 38 | private final ItemStack chestplate; 39 | private final ItemStack leggings; 40 | private final ItemStack boots; 41 | 42 | /** 43 | * Copies the contents of the passed {@link PlayerInventory} 44 | * 45 | * @since 0.1.0 46 | * @version 0.1.0 47 | * 48 | * @param i The {@link PlayerInventory} to copy 49 | */ 50 | public PlayerInventoryState(PlayerInventory i) { 51 | super(i); 52 | this.helmet = i.getHelmet(); 53 | this.chestplate = i.getChestplate(); 54 | this.leggings = i.getLeggings(); 55 | this.boots = i.getBoots(); 56 | } 57 | 58 | /** 59 | * Returns the item in the helmet slot of the {@link PlayerInventory} 60 | * 61 | * @since 0.1.0 62 | * @version 0.1.0 63 | * 64 | * @return The helmet in the {@link PlayerInventory} 65 | */ 66 | public ItemStack getHelmet() { 67 | return this.helmet; 68 | } 69 | 70 | /** 71 | * Returns the item in the torso slot of the {@link PlayerInventory} 72 | * 73 | * @since 0.1.0 74 | * @version 0.1.0 75 | * 76 | * @return The torso in the {@link PlayerInventory} 77 | */ 78 | public ItemStack getChestplate() { 79 | return this.chestplate; 80 | } 81 | 82 | /** 83 | * Returns the item in the pants slot of the {@link PlayerInventory} 84 | * 85 | * @since 0.1.0 86 | * @version 0.1.0 87 | * 88 | * @return The pants in the {@link PlayerInventory} 89 | */ 90 | public ItemStack getLeggings() { 91 | return this.leggings; 92 | } 93 | 94 | /** 95 | * Returns the item in the boots slot of the {@link PlayerInventory} 96 | * 97 | * @since 0.1.0 98 | * @version 0.1.0 99 | * 100 | * @return The boots in the {@link PlayerInventory} 101 | */ 102 | public ItemStack getBoots() { 103 | return this.boots; 104 | } 105 | 106 | /** 107 | * {@inheritDoc} 108 | * 109 | * @since 0.1.0 110 | * @version 0.1.0 111 | * 112 | * @param holder {@inheritDoc} 113 | * @throws IllegalArgumentException If the {@link InventoryHolder} is not a 114 | * {@link HumanEntity} 115 | */ 116 | @Override 117 | public void setContents(InventoryHolder holder) { 118 | Validate.isTrue(holder instanceof HumanEntity, "InventoryHolder is not a HumanEntity"); 119 | super.setContents(holder); 120 | HumanEntity e = (HumanEntity) holder; 121 | e.getInventory().setHelmet(this.helmet); 122 | e.getInventory().setChestplate(this.chestplate); 123 | e.getInventory().setLeggings(this.leggings); 124 | e.getInventory().setBoots(this.boots); 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/inventory/iinterface/Execution.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.inventory.iinterface; 21 | 22 | import org.bukkit.entity.Player; 23 | 24 | /** 25 | * Represents the actions to be taken upon clicking a {@link MenuIcon} 26 | * 27 | * @since 0.0.1 28 | * @author 1Rogue 29 | * @version 0.0.1 30 | */ 31 | @FunctionalInterface 32 | public interface Execution { 33 | 34 | /** 35 | * Called when a {@link MenuIcon} is clicked 36 | * 37 | * @since 0.0.1 38 | * @version 0.0.1 39 | * 40 | * @param p The {@link Player} who clicked the icon 41 | * @param ii The {@link InventoryInterface} this icon belongs to 42 | * @param icon The {@link MenuIcon} that was clicked 43 | */ 44 | public void onExec(Player p, InventoryInterface ii, MenuIcon icon); 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/inventory/iinterface/InterfaceListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.inventory.iinterface; 21 | 22 | import com.codelanx.codelanxlib.CodelanxLib; 23 | import com.codelanx.codelanxlib.inventory.Inventories; 24 | import org.bukkit.Bukkit; 25 | import org.bukkit.entity.EntityType; 26 | import org.bukkit.entity.Player; 27 | import org.bukkit.event.EventHandler; 28 | import org.bukkit.event.Listener; 29 | import org.bukkit.event.inventory.InventoryClickEvent; 30 | import org.bukkit.inventory.Inventory; 31 | 32 | import java.util.HashMap; 33 | import java.util.Map; 34 | 35 | /** 36 | * Listens for inventory clicks and conveys information to any appropriate and 37 | * registered {@link InventoryInterface} 38 | * 39 | * @since 0.0.1 40 | * @author 1Rogue 41 | * @version 0.1.0 42 | */ 43 | public final class InterfaceListener implements Listener { 44 | 45 | private final Map interfaces = new HashMap<>(); 46 | 47 | /** 48 | * Constructs the listener instance and registers it to Bukkit 49 | * 50 | * @since 0.1.0 51 | * @version 0.1.0 52 | */ 53 | @SuppressWarnings("LeakingThisInConstructor") 54 | public InterfaceListener() { 55 | Bukkit.getServer().getPluginManager().registerEvents(this, CodelanxLib.get()); 56 | } 57 | 58 | /** 59 | * Listens to inventory clicks, and conveys said information to an 60 | * appropriate {@link InventoryInterface} 61 | * 62 | * @since 0.0.1 63 | * @version 0.1.0 64 | * 65 | * @param event The fired {@link InventoryClickEvent} 66 | */ 67 | @EventHandler 68 | public void onClick(InventoryClickEvent event) { 69 | if (event.getWhoClicked().getType() != EntityType.PLAYER) { 70 | return; 71 | } 72 | if (Inventories.hasClickedTop(event)) { 73 | String title = event.getInventory().getTitle(); 74 | title = title.substring(title.length() - (InventoryInterface.SEED_LENGTH * 2)); 75 | InventoryInterface ii = this.interfaces.get(title); 76 | if (ii != null) { 77 | Inventory i = event.getInventory(); 78 | InventoryPanel ip = ii.getPanelBySeed(i.getTitle()); 79 | if (ip != null) { 80 | ip.click((Player) event.getWhoClicked(), event.getSlot()); 81 | event.setCancelled(true); 82 | } 83 | } 84 | } 85 | } 86 | 87 | /** 88 | * Registers an {@link InventoryInterface} to this listener 89 | * 90 | * @since 0.1.0 91 | * @version 0.1.0 92 | * 93 | * @param ii The {@link InventoryInterface} to register 94 | */ 95 | public void register(InventoryInterface ii) { 96 | this.interfaces.put(ii.getSeed(), ii); 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/inventory/iinterface/InventoryPanel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.inventory.iinterface; 21 | 22 | import com.codelanx.commons.util.Lambdas; 23 | import com.codelanx.codelanxlib.config.Configs; 24 | import org.apache.commons.lang.Validate; 25 | import org.bukkit.Bukkit; 26 | import org.bukkit.entity.Player; 27 | import org.bukkit.inventory.Inventory; 28 | import org.bukkit.inventory.ItemStack; 29 | 30 | import java.util.ArrayList; 31 | import java.util.HashMap; 32 | import java.util.List; 33 | import java.util.Map; 34 | import java.util.stream.Collectors; 35 | 36 | /** 37 | * A single inventory that represents a menu 38 | * 39 | * @since 0.0.1 40 | * @author 1Rogue 41 | * @version 0.1.0 42 | */ 43 | public final class InventoryPanel { 44 | 45 | static final int SEED_LENGTH = 4; 46 | private int index = 0; 47 | private final String seed; 48 | private final String name; 49 | private String serializer; 50 | private final InventoryInterface ii; 51 | private final int rows; 52 | private final List icons = new ArrayList<>(); 53 | private final Map locations = new HashMap<>(); 54 | 55 | InventoryPanel(InventoryInterface ii, String name, int rows) { 56 | Validate.notNull(ii, "InventoryInterface cannot be null"); 57 | if (name == null) { 58 | name = "Choose an option!"; 59 | } 60 | this.ii = ii; 61 | this.name = name; 62 | this.seed = this.ii.generateSeed(InventoryPanel.SEED_LENGTH); 63 | this.rows = rows; 64 | } 65 | 66 | /** 67 | * Returns a new {@link MenuIcon} stored in this panel 68 | * 69 | * @since 0.0.1 70 | * @version 0.1.0 71 | * 72 | * @param item The {@link ItemStack} to use for displaying the icon 73 | * @param onExec The {@link Execution} to use when the icon is clicked 74 | * @param options A mapping of metadata options for the icon 75 | * @return The new {@link MenuIcon} 76 | */ 77 | public MenuIcon newIcon(ItemStack item, Execution onExec, Map options) { 78 | MenuIcon icon = new MenuIcon(item, onExec, options); 79 | this.locations.put(this.index++, icon); 80 | return icon; 81 | } 82 | 83 | /** 84 | * Returns a new {@link MenuIcon} stored in this panel 85 | * 86 | * @since 0.0.1 87 | * @version 0.1.0 88 | * 89 | * @param item The {@link ItemStack} to use for displaying the icon 90 | * @param onExec The {@link Execution} to use when the icon is clicked 91 | * @return The new {@link MenuIcon} 92 | */ 93 | public MenuIcon newIcon(ItemStack item, Execution onExec) { 94 | return this.newIcon(item, onExec, new HashMap<>()); 95 | } 96 | 97 | /** 98 | * Links this panel to the passed {@link MenuIcon} such that clicking it 99 | * will open this panel 100 | * 101 | * @since 0.0.1 102 | * @version 0.0.1 103 | * 104 | * @see InventoryInterface#linkPanel(MenuIcon, InventoryPanel) 105 | * @param icon The {@link MenuIcon} to link 106 | */ 107 | public void linkIcon(MenuIcon icon) { 108 | this.ii.linkPanel(icon, this); 109 | } 110 | 111 | /** 112 | * Sets the {@link Execution} for all {@link MenuIcon} objects held in this 113 | * panel 114 | * 115 | * @since 0.1.0 116 | * @version 0.1.0 117 | * 118 | * @param onExec The {@link Execution} to set 119 | */ 120 | public void setAllExecutions(Execution onExec) { 121 | this.locations.values().forEach(i -> i.setExecutable(onExec)); 122 | } 123 | 124 | /** 125 | * Returns the seed relevant to this specific panel 126 | * 127 | * @since 0.0.1 128 | * @version 0.0.1 129 | * 130 | * @return The seed for this panel 131 | */ 132 | public String getSeed() { 133 | return this.seed; 134 | } 135 | 136 | /** 137 | * Called when a player clicks a {@link MenuIcon} inside of an 138 | * {@link InventoryPanel} 139 | * 140 | * @since 0.0.1 141 | * @version 0.1.0 142 | * 143 | * @param p The {@link Player} who clicked 144 | * @param slot The slot that was clicked 145 | */ 146 | public void click(Player p, int slot) { 147 | MenuIcon icon = this.locations.get(slot); 148 | if (icon != null && icon.hasPermission(p)) { 149 | if (this.ii.isLinked(icon)) { 150 | InventoryPanel next = this.ii.getLinkedPanel(icon); 151 | if (next != null) { 152 | next.open(p); 153 | } 154 | } else { 155 | icon.execute(p, this.ii); 156 | p.closeInventory(); 157 | } 158 | } 159 | } 160 | 161 | static InventoryPanel valueOf(InventoryInterface ii, Object o) { 162 | Map map = Configs.getConfigSectionValue(o); 163 | if (map == null || map.isEmpty()) { 164 | return null; 165 | } 166 | List objs = (List) map.get("icons"); 167 | Boolean root = Boolean.valueOf(String.valueOf(map.get("root"))); 168 | String name = String.valueOf(map.get("name")); 169 | if (objs != null && root != null) { 170 | List icons = objs.stream() 171 | .map(obj -> MenuIcon.valueOf(ii, obj)) 172 | .filter(Lambdas::notNull) 173 | .collect(Collectors.toList()); 174 | int rows; 175 | if (map.get("rows") == null) { 176 | rows = (icons.size() / 9) + 1; 177 | } else { 178 | rows = Integer.valueOf(String.valueOf(map.get("rows"))); 179 | } 180 | InventoryPanel ip = ii.newPanel(name, rows); 181 | ip.icons.addAll(icons); 182 | ip.icons.forEach(i -> ip.locations.put(ip.index++, i)); 183 | if (root) { 184 | ii.setRootPanel(ip); 185 | } 186 | return ip; 187 | } else { 188 | return null; 189 | } 190 | } 191 | 192 | /** 193 | * Opens this {@link InventoryPanel} for the passed {@link Player} 194 | * 195 | * @since 0.0.1 196 | * @version 0.1.0 197 | * 198 | * @param p The {@link Player} to open this panel for 199 | */ 200 | public void open(Player p) { 201 | String name = this.name; 202 | int maxLength = 32 - (InventoryInterface.SEED_LENGTH * 2) - (InventoryPanel.SEED_LENGTH * 2); 203 | if (name.length() > maxLength) { 204 | name = name.substring(0, maxLength); 205 | } 206 | Inventory back = Bukkit.getServer().createInventory(null, this.rows * 9, name + this.seed + this.ii.getSeed()); 207 | this.locations.entrySet().stream().filter(ent -> ent.getValue().hasPermission(p)).forEach(ent -> { 208 | back.setItem(ent.getKey(), ent.getValue().getItem()); 209 | }); 210 | p.openInventory(back); 211 | } 212 | 213 | /** 214 | * Sets the serialized name for this panel 215 | * 216 | * @since 0.0.1 217 | * @version 0.0.1 218 | * 219 | * @param name The name to set 220 | * @return The current instance (chained) 221 | */ 222 | public InventoryPanel setSerializedName(String name) { 223 | this.serializer = name; 224 | return this; 225 | } 226 | 227 | /** 228 | * Returns the serialized name for this panel 229 | * 230 | * @since 0.0.1 231 | * @version 0.0.1 232 | * 233 | * @return The serialized name 234 | */ 235 | public String getSerializedName() { 236 | return this.serializer; 237 | } 238 | 239 | Map toMap() { 240 | Map back = new HashMap<>(); 241 | back.put("icons", this.icons.stream().map(i -> i.toMap(this.ii)).collect(Collectors.toList())); 242 | back.put("root", this.ii.isRoot(this)); 243 | back.put("name", this.name); 244 | back.put("rows", this.rows); 245 | return back; 246 | } 247 | 248 | /** 249 | * Returns the name/title used for the {@link Inventory} in this panel 250 | * 251 | * @since 0.0.1 252 | * @version 0.0.1 253 | * 254 | * @return The name for this panel 255 | */ 256 | public String getName() { 257 | return this.name; 258 | } 259 | 260 | } 261 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/inventory/iinterface/MenuIcon.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.inventory.iinterface; 21 | 22 | import com.codelanx.commons.util.RNG; 23 | import com.codelanx.codelanxlib.config.Configs; 24 | import org.bukkit.entity.Player; 25 | import org.bukkit.inventory.ItemStack; 26 | 27 | import java.util.ArrayList; 28 | import java.util.Collections; 29 | import java.util.HashMap; 30 | import java.util.List; 31 | import java.util.Map; 32 | import java.util.Objects; 33 | import java.util.Timer; 34 | import java.util.TimerTask; 35 | 36 | /** 37 | * Represents an {@link ItemStack} in an {@link InventoryPanel}'s inventory that 38 | * will execute code when clicked. 39 | * 40 | * @since 0.0.1 41 | * @author 1Rogue 42 | * @version 0.1.0 43 | */ 44 | public class MenuIcon { 45 | 46 | /** A mapping of metadata options */ 47 | protected Map options; 48 | /** A seed representing this {@link MenuIcon object} */ 49 | protected final long seed; 50 | /** The {@link ItemStack} that this instance uses */ 51 | protected final ItemStack item; 52 | /** The {@link Execution} function to run when clicked */ 53 | protected Execution onExec; 54 | /** Permissions required to see this icon */ 55 | protected final List perms = new ArrayList<>(); 56 | 57 | /** 58 | * Initializes fields 59 | * 60 | * @since 0.1.0 61 | * @version 0.1.0 62 | * 63 | * @param item The {@link ItemStack} to use for display in the inventory 64 | * @param onExec The {@link Execution} to use when clicked 65 | * @param options A mapping of metadata options 66 | */ 67 | MenuIcon(ItemStack item, Execution onExec, Map options) { 68 | if (item == null || options == null) { 69 | throw new IllegalArgumentException("Constructor parameters cannot be null"); 70 | } 71 | this.item = item; 72 | this.seed = RNG.THREAD_LOCAL().nextLong(); 73 | this.onExec = onExec; 74 | this.options = options; 75 | } 76 | 77 | /** 78 | * Returns the {@link ItemStack} that is displayed when a user opens the 79 | * {@link InventoryInterface} 80 | * 81 | * @since 0.1.0 82 | * @version 0.1.0 83 | * 84 | * @return The {@link ItemStack} to display 85 | */ 86 | public ItemStack getItem() { 87 | return this.item; 88 | } 89 | 90 | /** 91 | * Sets the {@link Execution} function that is called when this icon is 92 | * clicked. Can be set to {@code null} to not execute anything 93 | * 94 | * @since 0.1.0 95 | * @version 0.1.0 96 | * 97 | * @param onExec The {@link Execution} to be used 98 | */ 99 | public void setExecutable(Execution onExec) { 100 | this.onExec = onExec; 101 | } 102 | 103 | /** 104 | * {@inheritDoc} 105 | * 106 | * @since 0.1.0 107 | * @version 0.1.0 108 | * 109 | * @return {@inheritDoc} 110 | */ 111 | @Override 112 | public int hashCode() { 113 | int hash = 7; 114 | hash = 53 * hash + (int) (this.seed ^ (this.seed >>> 32)); 115 | hash = 53 * hash + Objects.hashCode(this.item); 116 | return hash; 117 | } 118 | 119 | /** 120 | * Returns a {@link Map} of all the metadata options 121 | * 122 | * @since 0.1.0 123 | * @version 0.1.0 124 | * 125 | * @return A {@link Map} of metadata values 126 | */ 127 | public Map getOptions() { 128 | return Collections.unmodifiableMap(this.options); 129 | } 130 | 131 | /** 132 | * Adds a metadata option 133 | * 134 | * @since 0.1.0 135 | * @version 0.1.0 136 | * 137 | * @param key The {@link String} key to retrieve the option 138 | * @param value The value of the option 139 | * @return The previous value associated with the key, or {@code null} if 140 | * there was no previous mapping using the key 141 | */ 142 | public Object addOption(String key, Object value) { 143 | return this.options.put(key, value); 144 | } 145 | 146 | /** 147 | * Returns a metadata option 148 | * 149 | * @since 0.1.0 150 | * @version 0.1.0 151 | * 152 | * @param key The key that maps to the value 153 | * @return The stored metadata value, or {@code null} if none is set 154 | */ 155 | public Object getOption(String key) { 156 | return this.options.get(key); 157 | } 158 | 159 | /** 160 | * {@inheritDoc} 161 | * 162 | * @since 0.1.0 163 | * @version 0.1.0 164 | * 165 | * @param obj {@inheritDoc} 166 | * @return {@inheritDoc} 167 | */ 168 | @Override 169 | public boolean equals(Object obj) { 170 | if (obj == null) { 171 | return false; 172 | } 173 | if (!(obj instanceof MenuIcon)) { 174 | return false; 175 | } 176 | final MenuIcon other = (MenuIcon) obj; 177 | if (this.seed != other.seed) { 178 | return false; 179 | } 180 | return Objects.equals(this.item, other.item); 181 | } 182 | 183 | /** 184 | * Runs the {@link Execution} associated with this icon if one is set 185 | * 186 | * @since 0.1.0 187 | * @version 0.1.0 188 | * 189 | * @param p The {@link Player} that clicked the icon 190 | * @param ii The {@link InventoryInterface} associated with this icon 191 | */ 192 | void execute(Player p, InventoryInterface ii) { 193 | if (this.onExec != null) { 194 | this.onExec.onExec(p, ii, this); 195 | } 196 | } 197 | 198 | /** 199 | * Manually deserializes a YAML mapping and returns the appropriate 200 | * {@link MenuIcon}. This method is permitted to fail, if values are missing 201 | * or malformed from the yaml file, it will throw an exception (Most like a 202 | * {@link NullPointerException} 203 | * 204 | * @since 0.1.0 205 | * @version 0.1.0 206 | * 207 | * @param ii The {@link InventoryInterface} to serialize for 208 | * @param o The YAML mapping to deserialize 209 | * @return A new {@link MenuIcon} instance 210 | */ 211 | static MenuIcon valueOf(InventoryInterface ii, Object o) { 212 | Map map = Configs.getConfigSectionValue(o); 213 | if (map == null || map.isEmpty()) { 214 | return null; 215 | } 216 | ItemStack item = (ItemStack) map.get("item"); 217 | Map opts = Configs.getConfigSectionValue(map.get("options")); 218 | List perm = (List) map.get("permissions"); 219 | String link = String.valueOf(map.get("link")); 220 | if (item != null && opts != null) { 221 | MenuIcon back = new MenuIcon(item, null, opts); 222 | if (perm != null && !perm.isEmpty()) { 223 | back.perms.addAll(perm); 224 | } 225 | if (link != null) { 226 | new Timer().schedule(new TimerTask() { 227 | @Override 228 | public void run() { 229 | InventoryPanel ip = ii.find(p -> link.equalsIgnoreCase(p.getSerializedName())); 230 | if (ip != null) { 231 | ip.linkIcon(back); 232 | } 233 | } 234 | }, 3000); 235 | } 236 | return back; 237 | } else { 238 | return null; 239 | } 240 | } 241 | 242 | /** 243 | * Converts the current instance into a {@link Map} for serialization 244 | * 245 | * @since 0.1.0 246 | * @version 0.1.0 247 | * 248 | * @param ii The relevant {@link InventoryInterface} for this serialization 249 | * @return A mapping of this object's values 250 | */ 251 | Map toMap(InventoryInterface ii) { 252 | Map back = new HashMap<>(); 253 | back.put("item", this.item); 254 | back.put("options", this.options); 255 | if (!this.perms.isEmpty()) { 256 | back.put("permissions", this.perms); 257 | } 258 | if (ii.isLinked(this)) { 259 | back.put("link", ii.getLinkedPanel(this).getSerializedName()); 260 | } 261 | return back; 262 | } 263 | 264 | /** 265 | * Adds a permission node that a player will need in order to see this icon. 266 | * If no permissions are set, everyone is capable of seeing the icon. If 267 | * multiple permissions are set, only one of the permission nodes is needed 268 | * 269 | * @since 0.1.0 270 | * @version 0.1.0 271 | * 272 | * @param permission A string representing a permission node 273 | */ 274 | public void addPermission(String permission) { 275 | this.perms.add(permission); 276 | } 277 | 278 | /** 279 | * Returns {@code true} if any permissions are required to see this icon 280 | * 281 | * @since 0.1.0 282 | * @version 0.1.0 283 | * 284 | * @return {@code true} if a permission is needed to see the icon 285 | */ 286 | public boolean requiresPerms() { 287 | return !this.perms.isEmpty(); 288 | } 289 | 290 | /** 291 | * Returns whether or not a {@link Player} has permission to view this icon 292 | * 293 | * @since 0.1.0 294 | * @version 0.1.0 295 | * 296 | * @param p The {@link Player} to check 297 | * @return {@code true} if the player has permission to view the icon 298 | */ 299 | public boolean hasPermission(Player p) { 300 | return this.requiresPerms() ? this.perms.stream().anyMatch(p::hasPermission) : true; 301 | } 302 | 303 | } 304 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/listener/ListenerManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.listener; 21 | 22 | import com.codelanx.codelanxlib.CodelanxLib; 23 | import com.codelanx.commons.logging.Logging; 24 | import com.codelanx.commons.util.Reflections; 25 | import com.codelanx.commons.util.exception.Exceptions; 26 | import com.codelanx.commons.util.exception.IllegalInvocationException; 27 | import com.codelanx.codelanxlib.util.ReflectBukkit; 28 | import org.apache.commons.lang.Validate; 29 | import org.bukkit.event.Event; 30 | import org.bukkit.event.EventHandler; 31 | import org.bukkit.event.HandlerList; 32 | import org.bukkit.event.Listener; 33 | import org.bukkit.plugin.Plugin; 34 | import org.bukkit.plugin.java.JavaPlugin; 35 | 36 | import java.util.HashMap; 37 | import java.util.Map; 38 | import java.util.function.Consumer; 39 | import java.util.logging.Level; 40 | 41 | /** 42 | * Centrally holds references to different Listener classes to allow for 43 | * retrieval of {@link SubListener} references 44 | * 45 | * @since 0.0.1 46 | * @author 1Rogue 47 | * @version 0.1.0 48 | */ 49 | public final class ListenerManager { 50 | 51 | /** 52 | * Private constructor to prevent instantiation 53 | * 54 | * @since 0.1.0 55 | * @version 0.1.0 56 | */ 57 | private ListenerManager() { 58 | } 59 | 60 | /** 61 | * Maps {@link SubListener} class types to a {@link SubListener} instance 62 | * 63 | * @since 0.1.0 64 | * @version 0.1.0 65 | */ 66 | @SuppressWarnings("rawtypes") 67 | private static final Map, SubListener> listeners = new HashMap<>(); 68 | 69 | /** 70 | * Gets a listener by its string name. Returns null if the listener is 71 | * disabled or not registered. 72 | * 73 | * @since 0.0.1 74 | * @version 0.1.0 75 | * 76 | * @param The {@link SubListener} type 77 | * @param listener An instance of the class type to retrieve 78 | * @return The listener class, null if disabled or not registered 79 | * @throws IllegalArgumentException If the listener isn't registered 80 | */ 81 | public static > S getListener(Class listener) { 82 | Validate.isTrue(ListenerManager.isRegistered(listener), "Class is not registered with listener manager"); 83 | return (S) ListenerManager.listeners.get(listener); 84 | } 85 | 86 | /** 87 | * Returns the {@link Plugin} relevant to the passed {@link SubListener} 88 | * class 89 | * 90 | * @since 0.1.0 91 | * @version 0.1.0 92 | * 93 | * @param

The {@link Plugin} type 94 | * @param The {@link SubListener} type 95 | * @param listener The {@link SubListener} class that was registered 96 | * @return The {@link Plugin} that registered the {@link SubListener} 97 | * @throws IllegalArgumentException If the listener isn't registered 98 | */ 99 | public static

> P getRegisteringPlugin(Class listener) { 100 | return ListenerManager.getListener(listener).getPlugin(); 101 | } 102 | 103 | /** 104 | * Returns whether or not a listener is registered under the relevant 105 | * listener key 106 | * 107 | * @since 0.0.1 108 | * @version 0.1.0 109 | * 110 | * @param The {@link SubListener} class to get 111 | * @param listener The listener class to look for 112 | * @return {@code true} if registered, {@code false} otherwise 113 | */ 114 | public static > boolean isRegistered(Class listener) { 115 | return ListenerManager.listeners.containsKey(listener); 116 | } 117 | 118 | /** 119 | * Returns {@code true} if the passed {@link Listener} has another Listener 120 | * of the same class type already registered for bukkit. This should not be 121 | * used with any listeners that are from an anonymous class, as this will 122 | * return {@code true} for any other anonymous classes as well 123 | * 124 | * @since 0.1.0 125 | * @version 0.1.0 126 | * 127 | * @param p The {@link Plugin} that registers this {@link Listener} 128 | * @param l The {@link Listener} to check 129 | * @return {@code true} if registered to bukkit 130 | */ 131 | public static boolean isRegisteredToBukkit(Plugin p, Listener l) { 132 | if (l.getClass().isAnonymousClass()) { 133 | StackTraceElement t = Reflections.getCaller(); 134 | Logging.simple().here().print(Level.WARNING, "Passed an anonymous class from %s:%d", t.getClass().getName(), t.getLineNumber()); 135 | } 136 | return HandlerList.getRegisteredListeners(p).stream().anyMatch(r -> r.getListener().getClass() == l.getClass()); 137 | } 138 | 139 | /** 140 | * Registers a listener through Bukkit and {@link ListenerManager} 141 | * 142 | * @since 0.0.1 143 | * @version 0.1.0 144 | * 145 | * @param The {@link SubListener} class to register 146 | * @param listener The listener to register 147 | * @throws IllegalArgumentException Attempted to register a Listener twice 148 | * @return The listener that was registered 149 | */ 150 | public static > S registerListener(S listener) { 151 | Validate.isTrue(!ListenerManager.isRegistered(listener.getClass()), 152 | "Listener Map already contains key: " + listener.getClass().getName()); 153 | ListenerManager.listeners.put(listener.getClass(), listener); 154 | if (!ListenerManager.isRegisteredToBukkit(listener.getPlugin(), listener)) { 155 | listener.getPlugin().getServer().getPluginManager().registerEvents(listener, listener.getPlugin()); 156 | } 157 | return listener; 158 | } 159 | 160 | /** 161 | * Calls {@link ListenerManager#registerListener(SubListener)} for every 162 | * passed listener. Any exception thrown will be re-thrown after all 163 | * listeners are registered 164 | * 165 | * @since 0.0.1 166 | * @version 0.1.0 167 | * 168 | * @param The {@link SubListener} class to register 169 | * @param listeners The listeners to register 170 | * @throws IllegalArgumentException Attempted to register a Listener twice 171 | */ 172 | public static > void registerListeners(T... listeners) { 173 | IllegalArgumentException ex = null; 174 | for (T listener : listeners) { 175 | try { 176 | ListenerManager.registerListener(listener); 177 | } catch (IllegalArgumentException e) { 178 | if (ex != null) { 179 | ex = e; 180 | } 181 | } 182 | } 183 | if (ex != null) { 184 | throw ex; 185 | } 186 | } 187 | 188 | /** 189 | * Unregisters a specific {@link SubListener} from both CodelanxLib and 190 | * Bukkit 191 | * 192 | * @since 0.1.0 193 | * @version 0.1.0 194 | * 195 | * @param listener The {@link SubListener} class to unregister 196 | */ 197 | public static void unregisterListener(Class> listener) { 198 | if (ListenerManager.isRegistered(listener)) { 199 | HandlerList.unregisterAll(ListenerManager.listeners.remove(listener)); 200 | } 201 | } 202 | 203 | /** 204 | * Unregisters all the listeners attached to this {@link ListenerManager}. 205 | * Can only be called from {@link CodelanxLib} 206 | * 207 | * @since 0.0.1 208 | * @version 0.1.0 209 | * 210 | * @throws IllegalInvocationException Only {@link CodelanxLib} can use 211 | */ 212 | public static void release() { 213 | Exceptions.illegalInvocation(Reflections.accessedFrom(CodelanxLib.class), 214 | "ListenerManager#release may only be called by CodelanxLib"); 215 | ListenerManager.listeners.values().forEach((l) -> { 216 | l.onDisable(); 217 | HandlerList.unregisterAll(l); 218 | }); 219 | ListenerManager.listeners.clear(); 220 | } 221 | 222 | /** 223 | * Allows registering an anonymous listener for any bukkit listeners using 224 | * Java 8's function API, useful for listening to events in one-liner solutions 225 | * 226 | * @since 0.2.0 227 | * @version 0.2.0 228 | * 229 | * @param clazz The {@link Event} fired within Bukkit to listen to 230 | * @param event A {@link Consumer} of the event, called when the event is fired 231 | * @param The type of the {@link Event} 232 | */ 233 | public static void listen(Class clazz, Consumer event) { 234 | ListenerManager.registerListener(new SubListener(ReflectBukkit.getCallingPlugin()) { 235 | 236 | @EventHandler 237 | public void handle(T bukkitEvent) { 238 | event.accept(bukkitEvent); 239 | } 240 | }); 241 | } 242 | 243 | } 244 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/listener/SubListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.listener; 21 | 22 | import org.bukkit.event.Listener; 23 | import org.bukkit.plugin.Plugin; 24 | 25 | /** 26 | * Handles events that are called by Bukkit's event system. On an implementation 27 | * level, this is relatively the same as Bukkit's {@link Listener} class (and 28 | * even implements said interface), however it also provides methods for simpler 29 | * registration as well as a simple constructor to ensure a plugin instance is 30 | * available 31 | * 32 | * @since 0.0.1 33 | * @author 1Rogue 34 | * @version 0.1.0 35 | * 36 | * @param The specific {@link Plugin} to use 37 | */ 38 | public abstract class SubListener implements Listener { 39 | 40 | /** 41 | * The stored {@link Plugin} reference relevant to this {@link SubListener} 42 | * 43 | * @since 0.0.1 44 | * @version 0.0.1 45 | */ 46 | protected final T plugin; 47 | 48 | /** 49 | * Stores the {@link Plugin} reference 50 | * 51 | * @since 0.0.1 52 | * @version 0.1.0 53 | * 54 | * @param plugin The {@link Plugin} relevant to this {@link SubListener} 55 | */ 56 | public SubListener(T plugin) { 57 | this.plugin = plugin; 58 | } 59 | 60 | /** 61 | * Called when the plugin is being disabled. This is a convenience method to 62 | * allow simple cleanup of any resources 63 | * 64 | * @since 0.1.0 65 | * @version 0.1.0 66 | */ 67 | public void onDisable() {} 68 | 69 | /** 70 | * Returns the {@link Plugin} used for this {@link SubListener} 71 | * 72 | * @since 0.1.0 73 | * @version 0.1.0 74 | * 75 | * @return The {@link Plugin} that registered this {@link SubListener} 76 | */ 77 | public T getPlugin() { 78 | return this.plugin; 79 | } 80 | 81 | /** 82 | * Registers the listener to the {@link ListenerManager}. If the listener 83 | * class is already registered, this method will do nothing. 84 | * 85 | * @since 0.1.0 86 | * @version 0.1.0 87 | */ 88 | public final void register() { 89 | if (!ListenerManager.isRegistered(this.getClass())) { 90 | ListenerManager.registerListener(this); 91 | } 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/permission/Permissions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.permission; 21 | 22 | import org.apache.commons.lang.Validate; 23 | import org.bukkit.Bukkit; 24 | import org.bukkit.permissions.Permissible; 25 | import org.bukkit.permissions.Permission; 26 | import org.bukkit.plugin.PluginManager; 27 | 28 | /** 29 | * Represents a single permission value for use with checking whether or not a 30 | * {@link org.bukkit.permissions.Permissible Permissible} has a specific 31 | * permission or not. Meant for use on enum types 32 | * 33 | * @since 0.1.0 34 | * @author 1Rogue 35 | * @version 0.1.0 36 | */ 37 | public interface Permissions { 38 | 39 | /** 40 | * Returns the base permission node for the plugin. e.g. "commons". 41 | * 42 | * @since 0.1.0 43 | * @version 0.1.0 44 | * 45 | * @return The base permission node to prefix all permissions 46 | */ 47 | public String getBase(); 48 | 49 | /** 50 | * Returns the raw node for the specified enum constant without prefixing 51 | * 52 | * @since 0.1.0 53 | * @version 0.1.0 54 | * 55 | * @return The permission suffix supplied by the enum 56 | */ 57 | public String getNode(); 58 | 59 | /** 60 | * Builds the full permission string 61 | * 62 | * @since 0.1.0 63 | * @version 0.1.0 64 | * 65 | * @return The full permission string 66 | */ 67 | default public String build() { 68 | String median = "."; 69 | if (this.getBase().endsWith(median)) { 70 | median = ""; 71 | } 72 | return this.getBase().toLowerCase() + median + this.getNode().toLowerCase(); 73 | } 74 | 75 | /** 76 | * Determines whether or not the {@link Permissible} has this permission 77 | * 78 | * @since 0.1.0 79 | * @version 0.1.0 80 | * 81 | * @param p The {@link Permissible} to check permissions for 82 | * @return {@code true} if the {@link Permissible} has the permissions 83 | */ 84 | default public boolean has(Permissible p) { 85 | Validate.notNull(p, "Player cannot be null"); 86 | //Register permission to conform to Bukkit API 87 | String fullPerm = this.build(); 88 | PluginManager pm = Bukkit.getServer().getPluginManager(); 89 | if (pm.getPermission(fullPerm) == null) { 90 | pm.addPermission(new Permission(fullPerm)); 91 | } 92 | //end register 93 | return p.hasPermission(fullPerm); 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/serialize/SInventory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.serialize; 21 | 22 | import org.bukkit.configuration.serialization.ConfigurationSerializable; 23 | import org.bukkit.configuration.serialization.SerializableAs; 24 | import org.bukkit.inventory.ItemStack; 25 | 26 | import java.util.ArrayList; 27 | import java.util.Arrays; 28 | import java.util.Collection; 29 | import java.util.Collections; 30 | import java.util.HashMap; 31 | import java.util.List; 32 | import java.util.Map; 33 | import java.util.stream.Collectors; 34 | 35 | /** 36 | * Represents an Inventory which is ready to be serialized 37 | * 38 | * @since 0.0.1 39 | * @author 1Rogue 40 | * @version 0.0.1 41 | */ 42 | @SerializableAs("Inventory") 43 | public class SInventory implements ConfigurationSerializable { 44 | 45 | /** 46 | * Represents a collection of the relevant inventory items 47 | * 48 | * @since 0.0.1 49 | * @version 0.0.1 50 | */ 51 | protected final List items = new ArrayList<>(); 52 | 53 | /** 54 | * Copies the passed {@link ItemStack} objects 55 | * 56 | * @since 0.0.1 57 | * @version 0.0.1 58 | * 59 | * @param contents The {@link ItemStack}s to copy 60 | */ 61 | public SInventory(ItemStack... contents) { 62 | this.items.addAll(Arrays.asList(contents).stream() 63 | .map(i -> i.clone()).collect(Collectors.toList())); 64 | } 65 | 66 | /** 67 | * {@link ConfigurationSerializable} constructor. Should not be used by 68 | * anything other than Bukkit. 69 | * 70 | * @since 0.0.1 71 | * @version 0.0.1 72 | * 73 | * @param config A serialized {@link Map} of this object 74 | */ 75 | @SuppressWarnings("unchecked") 76 | public SInventory(Map config) { 77 | this.items.addAll((Collection) config.get("items")); 78 | } 79 | 80 | /** 81 | * Returns a copy of this instance's stored {@link ItemStack ItemStacks} 82 | * 83 | * @since 0.0.1 84 | * @version 0.0.1 85 | * 86 | * @return A copy of the relevant {@link ItemStack ItemStacks} 87 | */ 88 | public List getContents() { 89 | return Collections.unmodifiableList(this.items.stream().map(i -> i.clone()) 90 | .collect(Collectors.toList())); 91 | } 92 | 93 | /** 94 | * Returns a copy of this instance's stored {@link ItemStack ItemStacks} 95 | * 96 | * @since 0.0.1 97 | * @version 0.0.1 98 | * 99 | * @return A copy of the relevant {@link ItemStack ItemStacks} 100 | */ 101 | public ItemStack[] getContentsAsArray() { 102 | return this.getContents().toArray(new ItemStack[this.items.size()]); 103 | } 104 | 105 | /** 106 | * {@inheritDoc} 107 | * 108 | * @since 0.0.1 109 | * @version 0.0.1 110 | * 111 | * @return {@inheritDoc} 112 | */ 113 | @Override 114 | public Map serialize() { 115 | Map back = new HashMap<>(); 116 | back.put("items", this.items); 117 | return back; 118 | } 119 | 120 | /** 121 | * Creates a new {@link SInventory} object and returns it. Should only be 122 | * used by Bukkit 123 | * 124 | * @since 0.0.1 125 | * @version 0.0.1 126 | * 127 | * @param config A serialized {@link Map} of this object 128 | * @return A new {@link SInventory} object 129 | */ 130 | public static SInventory valueOf(Map config) { 131 | return new SInventory(config); 132 | } 133 | 134 | /** 135 | * Creates a new {@link SInventory} object and returns it. Should only be 136 | * used by Bukkit 137 | * 138 | * @since 0.0.1 139 | * @version 0.0.1 140 | * 141 | * @param config A serialized {@link Map} of this object 142 | * @return A new {@link SInventory} object 143 | */ 144 | public static SInventory deserialize(Map config) { 145 | return new SInventory(config); 146 | } 147 | 148 | } 149 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/serialize/SLocation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.serialize; 21 | 22 | import org.bukkit.Bukkit; 23 | import org.bukkit.Location; 24 | import org.bukkit.World; 25 | import org.bukkit.configuration.serialization.ConfigurationSerializable; 26 | import org.bukkit.configuration.serialization.SerializableAs; 27 | import org.bukkit.util.Vector; 28 | 29 | import java.util.HashMap; 30 | import java.util.Map; 31 | import java.util.UUID; 32 | 33 | /** 34 | * Represents a {@link ConfigurationSerializable} {@link Location} with a lazily 35 | * initialized world 36 | * 37 | * @since 0.0.1 38 | * @author 1Rogue 39 | * @version 0.0.1 40 | */ 41 | @SerializableAs("Location") 42 | public class SLocation implements ConfigurationSerializable { 43 | 44 | private final Vector loc; 45 | private final float yaw; 46 | private final float pitch; 47 | private final UUID uuid; 48 | private World world; 49 | 50 | static { 51 | 52 | } 53 | 54 | /** 55 | * Creates a new {@link SLocation} object from the passed {@link Location} 56 | * 57 | * @since 0.0.1 58 | * @version 0.0.1 59 | * 60 | * @param loc The {@link Location} to serialize 61 | */ 62 | public SLocation(Location loc) { 63 | this.loc = loc.toVector(); 64 | this.yaw = loc.getYaw(); 65 | this.pitch = loc.getPitch(); 66 | this.uuid = loc.getWorld().getUID(); 67 | } 68 | 69 | /** 70 | * Allows constructing an {@link SLocation} from serialized parts 71 | * 72 | * @since 0.1.0 73 | * @version 0.1.0 74 | * 75 | * @param loc The relevant {@link Vector} 76 | * @param worldUUID The {@link UUID} of the world for this {@link SLocation} 77 | * @param pitch The pitch 78 | * @param yaw The yaw 79 | */ 80 | public SLocation(Vector loc, UUID worldUUID, float pitch, float yaw) { 81 | this.loc = loc; 82 | this.uuid = worldUUID; 83 | this.pitch = pitch; 84 | this.yaw = yaw; 85 | } 86 | 87 | /** 88 | * {@link ConfigurationSerializable} constructor. Should not be used by 89 | * anything other than Bukkit. 90 | * 91 | * @since 0.0.1 92 | * @version 0.0.1 93 | * 94 | * @param config A serialized {@link Map} of this object 95 | */ 96 | public SLocation(Map config) { 97 | this.loc = (Vector) config.get("location"); 98 | this.uuid = UUID.fromString((String) config.get("world")); 99 | this.pitch = config.containsKey("pitch") ? ((Number) config.get("pitch")).floatValue() : 0F; 100 | this.yaw = config.containsKey("yaw") ? ((Number) config.get("yaw")).floatValue() : 0F; 101 | } 102 | 103 | /** 104 | * {@inheritDoc} 105 | * 106 | * @since 0.0.1 107 | * @version 0.0.1 108 | * 109 | * @return {@inheritDoc} 110 | */ 111 | @Override 112 | public Map serialize() { 113 | Map back = new HashMap<>(); 114 | back.put("location", this.loc); 115 | back.put("world", this.uuid.toString()); 116 | back.put("pitch", this.pitch); 117 | back.put("yaw", this.yaw); 118 | return back; 119 | } 120 | 121 | /** 122 | * Creates a new {@link SLocation} object and returns it. Should only be 123 | * used by Bukkit 124 | * 125 | * @since 0.0.1 126 | * @version 0.0.1 127 | * 128 | * @param config A serialized {@link Map} of this object 129 | * @return A new {@link SLocation} object 130 | */ 131 | public static SLocation valueOf(Map config) { 132 | return new SLocation(config); 133 | } 134 | 135 | /** 136 | * Creates a new {@link SLocation} object and returns it. Should only be 137 | * used by Bukkit 138 | * 139 | * @since 0.0.1 140 | * @version 0.0.1 141 | * 142 | * @param config A serialized {@link Map} of this object 143 | * @return A new {@link SLocation} object 144 | */ 145 | public static SLocation deserialize(Map config) { 146 | return new SLocation(config); 147 | } 148 | 149 | /** 150 | * Retrieves the {@link World} object relevant to this instance. This is 151 | * lazily-initialized, so until this method is called the class will not 152 | * attempt to retrieve the {@link World} value 153 | * 154 | * @since 0.0.1 155 | * @version 0.0.1 156 | * 157 | * @return The relevant {@link World} object, or {@code null} if not found 158 | */ 159 | public World getWorld() { 160 | if (this.world == null) { 161 | this.world = Bukkit.getWorld(this.uuid); 162 | } 163 | return this.world; 164 | } 165 | 166 | /** 167 | * Returns the relevant {@link Vector} object to this instance 168 | * 169 | * @since 0.0.1 170 | * @version 0.0.1 171 | * 172 | * @return The relevant {@link Vector} object 173 | */ 174 | public Vector getVector() { 175 | return this.loc; 176 | } 177 | 178 | /** 179 | * Converts this instance into a {@link Location} object. This method will 180 | * fail if called before Bukkit has loaded any worlds 181 | * 182 | * @since 0.0.1 183 | * @version 0.0.1 184 | * 185 | * @return This instance in the context of a {@link Location} object 186 | */ 187 | public Location toLocation() { 188 | return this.getVector().toLocation(this.getWorld(), this.yaw, this.pitch); 189 | } 190 | 191 | } -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/serialize/SPlayerInventory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.serialize; 21 | 22 | import org.apache.commons.lang3.Validate; 23 | import org.bukkit.configuration.serialization.ConfigurationSerializable; 24 | import org.bukkit.configuration.serialization.SerializableAs; 25 | import org.bukkit.inventory.ItemStack; 26 | import org.bukkit.inventory.PlayerInventory; 27 | 28 | import java.util.HashMap; 29 | import java.util.Map; 30 | 31 | /** 32 | * Represents a {@link PlayerInventory} that is capable of being serialized 33 | * 34 | * @since 0.0.1 35 | * @author 1Rogue 36 | * @version 0.0.1 37 | */ 38 | @SerializableAs("PlayerInventory") 39 | public class SPlayerInventory implements ConfigurationSerializable { 40 | 41 | /** The {@link ItemStack} stored on the player's head */ 42 | protected final ItemStack helmet; 43 | /** The {@link ItemStack} stored on the player's torso */ 44 | protected final ItemStack chest; 45 | /** The {@link ItemStack} stored on the player's legs */ 46 | protected final ItemStack legs; 47 | /** The {@link ItemStack} stored on the player's feet */ 48 | protected final ItemStack boots; 49 | /** The general contents of the player's inventory */ 50 | protected final SInventory inv; 51 | 52 | /** 53 | * Copies the contents of the passed {@link PlayerInventory} 54 | * 55 | * @since 0.0.1 56 | * @version 0.0.1 57 | * 58 | * @param inv The {@link PlayerInventory} to copy 59 | */ 60 | public SPlayerInventory(PlayerInventory inv) { 61 | Validate.notNull(inv, "PlayerInventory cannot be null"); 62 | this.helmet = inv.getHelmet(); 63 | this.chest = inv.getChestplate(); 64 | this.legs = inv.getLeggings(); 65 | this.boots = inv.getBoots(); 66 | this.inv = new SInventory(inv.getContents()); 67 | } 68 | 69 | /** 70 | * {@link ConfigurationSerializable} constructor. Should not be used by 71 | * anything other than Bukkit. 72 | * 73 | * @since 0.0.1 74 | * @version 0.0.1 75 | * 76 | * @param config A serialized {@link Map} of this object 77 | */ 78 | public SPlayerInventory(Map config) { 79 | if (config.isEmpty()) { 80 | this.helmet = this.chest = this.legs = this.boots = null; 81 | this.inv = null; 82 | } else { 83 | this.helmet = (ItemStack) config.get("helmet"); 84 | this.chest = (ItemStack) config.get("chest"); 85 | this.legs = (ItemStack) config.get("legs"); 86 | this.boots = (ItemStack) config.get("boots"); 87 | this.inv = (SInventory) config.get("contents"); 88 | } 89 | } 90 | 91 | /** 92 | * Returns the item in the helmet slot of the {@link PlayerInventory} 93 | * 94 | * @since 0.1.0 95 | * @version 0.1.0 96 | * 97 | * @return The helmet in the {@link PlayerInventory} 98 | */ 99 | public ItemStack getHelmet() { 100 | return this.helmet; 101 | } 102 | 103 | /** 104 | * Returns the item in the torso slot of the {@link PlayerInventory} 105 | * 106 | * @since 0.1.0 107 | * @version 0.1.0 108 | * 109 | * @return The torso in the {@link PlayerInventory} 110 | */ 111 | public ItemStack getChestplate() { 112 | return this.chest; 113 | } 114 | 115 | /** 116 | * Returns the item in the pants slot of the {@link PlayerInventory} 117 | * 118 | * @since 0.1.0 119 | * @version 0.1.0 120 | * 121 | * @return The pants in the {@link PlayerInventory} 122 | */ 123 | public ItemStack getLeggings() { 124 | return this.legs; 125 | } 126 | 127 | /** 128 | * Returns the item in the boots slot of the {@link PlayerInventory} 129 | * 130 | * @since 0.1.0 131 | * @version 0.1.0 132 | * 133 | * @return The boots in the {@link PlayerInventory} 134 | */ 135 | public ItemStack getBoots() { 136 | return this.boots; 137 | } 138 | 139 | /** 140 | * Returns the underlying {@link SInventory} object that stores normal 141 | * inventory items 142 | * 143 | * @since 0.0.1 144 | * @version 0.0.1 145 | * 146 | * @return The underlying {@link SInventory} object 147 | */ 148 | public SInventory getInventory() { 149 | return this.inv; 150 | } 151 | 152 | /** 153 | * Sets the current contents of this class into a passed 154 | * {@link PlayerInventory} 155 | * 156 | * @since 0.0.1 157 | * @version 0.0.1 158 | * 159 | * @param inv The {@link PlayerInventory} to store into 160 | */ 161 | public void set(PlayerInventory inv) { 162 | inv.setContents(this.getInventory().getContentsAsArray()); 163 | inv.setHelmet(this.getHelmet()); 164 | inv.setChestplate(this.getChestplate()); 165 | inv.setLeggings(this.getLeggings()); 166 | inv.setBoots(this.getBoots()); 167 | } 168 | 169 | /** 170 | * {@inheritDoc} 171 | * 172 | * @since 0.0.1 173 | * @version 0.0.1 174 | * 175 | * @return {@inheritDoc} 176 | */ 177 | @Override 178 | public Map serialize() { 179 | Map back = new HashMap<>(); 180 | back.put("helmet", this.helmet); 181 | back.put("chest", this.chest); 182 | back.put("legs", this.legs); 183 | back.put("boots", this.boots); 184 | back.put("contents", this.inv); 185 | return back; 186 | } 187 | 188 | /** 189 | * Creates a new {@link SPlayerInventory} object and returns it. Should only 190 | * be used by Bukkit 191 | * 192 | * @since 0.0.1 193 | * @version 0.0.1 194 | * 195 | * @param config A serialized {@link Map} of this object 196 | * @return A new {@link SPlayerInventory} object 197 | */ 198 | public static SPlayerInventory valueOf(Map config) { 199 | return new SPlayerInventory(config); 200 | } 201 | 202 | /** 203 | * Creates a new {@link SPlayerInventory} object and returns it. Should only 204 | * be used by Bukkit 205 | * 206 | * @since 0.0.1 207 | * @version 0.0.1 208 | * 209 | * @param config A serialized {@link Map} of this object 210 | * @return A new {@link SPlayerInventory} object 211 | */ 212 | public static SPlayerInventory deserialize(Map config) { 213 | return new SPlayerInventory(config); 214 | } 215 | 216 | } 217 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/serialize/SerializationFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.serialize; 21 | 22 | import org.bukkit.configuration.serialization.ConfigurationSerializable; 23 | import org.bukkit.configuration.serialization.ConfigurationSerialization; 24 | 25 | /** 26 | * Façade for registering {@link ConfigurationSerializable} classes to Bukkit 27 | * 28 | * @since 0.0.1 29 | * @author 1Rogue 30 | * @version 0.1.0 31 | */ 32 | public class SerializationFactory { 33 | 34 | /** 35 | * Registers a single {@link ConfigurationSerializable} class to Bukkit 36 | * 37 | * @since 0.0.1 38 | * @version 0.1.0 39 | * 40 | * @param clazz The class to register 41 | */ 42 | public static void registerClass(Class clazz) { 43 | ConfigurationSerialization.registerClass(clazz); 44 | } 45 | 46 | /** 47 | * Registers multiple {@link ConfigurationSerializable} class to Bukkit 48 | * 49 | * @since 0.0.1 50 | * @version 0.1.0 51 | * 52 | * @param clazz The classes to register 53 | */ 54 | public static void registerClasses(Class... clazz) { 55 | for (Class c : clazz) { 56 | SerializationFactory.registerClass(c); 57 | } 58 | } 59 | 60 | /** 61 | * Registers multiple {@link ConfigurationSerializable} class to Bukkit 62 | * 63 | * @since 0.1.0 64 | * @version 0.1.0 65 | * 66 | * @param clazz The classes to register 67 | */ 68 | public static void registerClasses(Iterable> clazz) { 69 | clazz.forEach(SerializationFactory::registerClass); 70 | } 71 | 72 | /** 73 | * Returns the native {@link ConfigurationSerializable} classes that are 74 | * provided by CodelanxLib 75 | * 76 | * @since 0.0.1 77 | * @version 0.0.1 78 | * 79 | * @return The native serializable types 80 | */ 81 | @SuppressWarnings("rawtypes") 82 | public static Class[] getNativeSerializables() { 83 | return new Class[] { 84 | SInventory.class, 85 | SPlayerInventory.class, 86 | SLocation.class 87 | }; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/util/BScheduler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.util; 21 | 22 | import com.codelanx.codelanxlib.CodelanxLib; 23 | import com.codelanx.commons.util.Scheduler; 24 | import org.bukkit.Bukkit; 25 | 26 | import java.util.concurrent.ScheduledFuture; 27 | 28 | public class BScheduler { 29 | 30 | /** 31 | * Runs a task after a specified delay on Bukkit's main thread 32 | * 33 | * @since 0.1.0 34 | * @version 0.1.0 35 | * 36 | * @param r The {@link Runnable} to execute 37 | * @param delay Time (in seconds) to wait before execution 38 | * @return The scheduled task that will execute the provided runnable 39 | */ 40 | public static ScheduledFuture runSyncTask(Runnable r, long delay) { 41 | //TODO: hook bukkit's scheduler directly for this operation 42 | return Scheduler.runAsyncTask(() -> { 43 | Bukkit.getServer().getScheduler().callSyncMethod(CodelanxLib.get(), () -> { 44 | r.run(); 45 | return null; 46 | }); 47 | }, delay); 48 | } 49 | 50 | /** 51 | * Runs a task after a specified time on Bukkit's main thread, and repeats 52 | * it in intervals as specified by the {@code delay} parameter 53 | * 54 | * @since 0.1.0 55 | * @version 0.1.0 56 | * 57 | * @param r The {@link Runnable} to execute 58 | * @param startAfter Time (in seconds) to wait before executing at all 59 | * @param delay Time (in seconds) to wait in between executions 60 | * @return The scheduled task that will execute the provided runnable 61 | */ 62 | public static ScheduledFuture runSyncTaskRepeat(Runnable r, long startAfter, long delay) { 63 | return Scheduler.runAsyncTaskRepeat(() -> { 64 | Bukkit.getServer().getScheduler().callSyncMethod(CodelanxLib.get(), () -> { 65 | r.run(); 66 | return null; 67 | }); 68 | }, startAfter, delay); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/util/BlockData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.util; 21 | 22 | import org.apache.commons.lang.Validate; 23 | import org.bukkit.Material; 24 | import org.bukkit.block.Block; 25 | import org.bukkit.inventory.ItemStack; 26 | import org.bukkit.material.MaterialData; 27 | 28 | import java.util.Objects; 29 | 30 | /** 31 | * Allows for representing material and it's data counterpart as a single string 32 | * 33 | * @since 0.2.0 34 | * @author 1Rogue 35 | * @version 0.3.1 36 | */ 37 | public class BlockData implements Comparable { 38 | 39 | private final Material mat; 40 | private final byte data; 41 | 42 | /** 43 | * Creates a {@link BlockData} instance 44 | * 45 | * @since 0.2.0 46 | * @version 0.2.0 47 | * 48 | * @param mat The {@link Material} value 49 | * @param data A {@code byte} representing an internal data value, set to 50 | * negative to match all data values 51 | */ 52 | public BlockData(Material mat, Number data) { 53 | this.mat = mat; 54 | this.data = data.byteValue(); 55 | } 56 | 57 | public BlockData(Block b) { 58 | this(b.getType(), b.getData()); 59 | } 60 | 61 | public BlockData(ItemStack stack) { 62 | this(stack.getType(), stack.getData().getData()); 63 | } 64 | 65 | public BlockData(MaterialData data) { 66 | this(data.getItemType(), data.getData()); 67 | } 68 | 69 | public Material getMaterial() { 70 | return this.mat; 71 | } 72 | 73 | public byte getData() { 74 | return this.data; 75 | } 76 | 77 | /** 78 | * Converts this {@link BlockData} to an {@link ItemStack}, which can then 79 | * be assigned to a block 80 | * 81 | * @since 0.2.0 82 | * @version 0.2.0 83 | * 84 | * @return This {@link BlockData} in {@link ItemStack} form 85 | */ 86 | public ItemStack toItemStack() { 87 | ItemStack back = new ItemStack(this.mat); 88 | if (this.data > 0) { 89 | back.getData().setData(this.data); 90 | } 91 | return back; 92 | } 93 | 94 | public MaterialData toMaterialData() { 95 | return new MaterialData(this.mat, this.data > 0 ? this.data : 0); 96 | } 97 | 98 | public void toBlock(Block toChange) { 99 | toChange.setType(this.mat); 100 | toChange.setData(this.data > 0 ? this.data : 0); 101 | } 102 | 103 | public boolean matches(ItemStack stack) { 104 | return this.matches(stack.getData()); 105 | } 106 | 107 | public boolean matches(Block b) { 108 | return this.mat == b.getType() 109 | && (this.data < 0 || b.getData() == this.data); 110 | } 111 | 112 | public boolean matches(MaterialData data) { 113 | return this.mat == data.getItemType() 114 | && (this.data < 0 || data.getData() == this.data); 115 | } 116 | 117 | @Override 118 | public String toString() { 119 | return this.mat.toString() + (this.data != 0 ? ":" + (this.data < 0 ? "*" : this.data) : ""); 120 | } 121 | 122 | /** 123 | * Converts a {@link BlockData} string back into an object instance 124 | * 125 | * @since 0.2.0 126 | * @version 0.2.0 127 | * 128 | * @param in The string to parse 129 | * @return The relevant {@link BlockData} 130 | */ 131 | public static BlockData fromString(String in) { 132 | String[] raw = in.split(":"); 133 | byte data = 0; 134 | Material mat; 135 | switch (raw.length) { 136 | case 2: 137 | if (raw[1].equals("*")) { 138 | data = -1; 139 | } else { 140 | data = Byte.valueOf(raw[1]); 141 | } 142 | case 1: 143 | mat = Material.matchMaterial(raw[0].toUpperCase()); 144 | Validate.notNull(mat); 145 | break; 146 | default: 147 | throw new IllegalArgumentException("Malformed string passed to BlockData#fromString: '" + in + "'"); 148 | } 149 | return new BlockData(mat, data); 150 | } 151 | 152 | @Override 153 | public int hashCode() { 154 | int hash = 3; 155 | hash = 41 * hash + Objects.hashCode(this.mat); 156 | hash = 41 * hash + this.data; 157 | return hash; 158 | } 159 | 160 | @Override 161 | public boolean equals(Object obj) { 162 | if (obj == null) { 163 | return false; 164 | } 165 | if (getClass() != obj.getClass()) { 166 | return false; 167 | } 168 | final BlockData other = (BlockData) obj; 169 | if (this.mat != other.mat) { 170 | return false; 171 | } 172 | return this.data == other.data || this.data < 0 || other.data < 0; //TODO: remove comparison exception? 173 | } 174 | 175 | @Override 176 | public int compareTo(BlockData o) { 177 | if (this.mat.ordinal() != o.mat.ordinal()) { 178 | return this.mat.ordinal() - o.mat.ordinal(); 179 | } else { 180 | if (this.data < 0 || o.data < 0) { 181 | return 0; 182 | } 183 | return this.data - o.data; 184 | } 185 | } 186 | 187 | } 188 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/util/Blocks.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.util; 21 | 22 | import org.bukkit.Material; 23 | import org.bukkit.block.Sign; 24 | 25 | /** 26 | * Utility class for working with any {@link org.bukkit.block.Block Block} 27 | * objects and their derivatives 28 | * 29 | * @since 0.1.0 30 | * @author 1Rogue 31 | * @version 0.1.0 32 | */ 33 | public final class Blocks { 34 | 35 | private Blocks() { 36 | } 37 | 38 | /** 39 | * Forcibly sends an update of sign text to any players within a close 40 | * enough range of the sign to render its text 41 | * 42 | * @since 0.1.0 43 | * @version 0.1.0 44 | * 45 | * @param s The {@link Sign} to update 46 | */ 47 | public static void updatePlayersInRange(Sign s) { 48 | //Seems to be that entities within ~60 block radius are not sent/updated 49 | Players.getPlayersInRange(65, s.getLocation()).keySet().forEach(p -> { 50 | p.sendSignChange(s.getLocation(), s.getLines()); 51 | }); 52 | } 53 | 54 | /** 55 | * Returns whether or not a {@link Material} will harm a 56 | * {@link org.bukkit.entity.Player Player} who comes into contact with it 57 | * 58 | * @since 0.1.0 59 | * @version 0.1.0 60 | * 61 | * @param mat The {@link Material} to compare 62 | * @return {@code true} if the material will harm the player 63 | */ 64 | public static boolean isHarmful(Material mat) { 65 | switch(mat) { 66 | case LAVA: 67 | case CACTUS: 68 | case FIRE: 69 | case STATIONARY_LAVA: 70 | return true; 71 | default: 72 | return false; 73 | } 74 | } 75 | 76 | /** 77 | * Determines if a material will be liquid when placed 78 | * 79 | * @since 0.1.0 80 | * @version 0.1.0 81 | * 82 | * @param mat The {@link Material} to check 83 | * @return {@code true} if lava or water (non-contained of any kind) 84 | */ 85 | public static boolean isLiquid(Material mat) { 86 | switch(mat) { 87 | case LAVA: 88 | case STATIONARY_LAVA: 89 | case WATER: 90 | case STATIONARY_WATER: 91 | return true; 92 | default: 93 | return false; 94 | } 95 | } 96 | 97 | /** 98 | * Determines if a block would be dangerous if above a player's head with 99 | * nothing but air inbetween, assuming no movement on part of the player 100 | * 101 | * @since 0.1.0 102 | * @version 0.1.0 103 | * 104 | * @param mat The {@link Material} to check 105 | * @return {@code true} if a player could be harmed 106 | */ 107 | public static boolean isDangerousFromAbove(Material mat) { 108 | switch(mat) { 109 | case LAVA: 110 | case STATIONARY_LAVA: 111 | case SAND: 112 | case GRAVEL: 113 | case ANVIL: 114 | return true; 115 | default: 116 | return false; 117 | } 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/util/NMS.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.util; 21 | 22 | import org.bukkit.potion.PotionEffectType; 23 | 24 | /** 25 | * Represents utility methods for either dealing with or fixing issues with 26 | * minecraft's internal server implementation 27 | * 28 | * @since 0.1.0 29 | * @author 1Rogue 30 | * @version 0.1.0 31 | */ 32 | public final class NMS { 33 | 34 | private NMS() { 35 | 36 | } 37 | 38 | /** 39 | * This method returns a duration that is constant-time based upon the given 40 | * {@link PotionEffectType}. Due to NMS internals with "MobEffectType", 41 | * some effects are abstractly divided by 2, to which this method undoes 42 | * that division for the relevant effects. Note this is a hardcoded method 43 | * which is up-to-date for Minecraft 1.8.* 44 | * 45 | * @param type The {@link PotionEffectType} to check 46 | * @param duration The duration for the effect 47 | * @return The same duration provided, multiplied by 2 for "flagged" effects 48 | */ 49 | public int fixPotionEffectDuration(PotionEffectType type, int duration) { 50 | if (type == PotionEffectType.SLOW 51 | || type == PotionEffectType.SLOW_DIGGING 52 | || type == PotionEffectType.HARM 53 | || type == PotionEffectType.CONFUSION 54 | || type == PotionEffectType.BLINDNESS 55 | || type == PotionEffectType.HUNGER 56 | || type == PotionEffectType.WEAKNESS 57 | || type == PotionEffectType.POISON 58 | || type == PotionEffectType.WITHER) { 59 | return duration << 1; 60 | } 61 | return duration; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/util/Paginator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.util; 21 | 22 | import com.codelanx.codelanxlib.config.Lang; 23 | import com.codelanx.codelanxlib.internal.InternalLang; 24 | import org.bukkit.ChatColor; 25 | 26 | import java.util.ArrayList; 27 | import java.util.Arrays; 28 | import java.util.Collections; 29 | import java.util.List; 30 | 31 | /** 32 | * Wraps text in formatted bars with a title, and allows for paging through 33 | * text content 34 | * 35 | * @since 0.1.0 36 | * @author 1Rogue 37 | * @version 0.1.0 38 | */ 39 | public class Paginator { 40 | 41 | private final String BAR; 42 | private final List pages = new ArrayList<>(); 43 | 44 | /** 45 | * Constructor. Splits the {@code wholeText} parameter by a newline 46 | * character ({@code \n}) and forwards it to 47 | * {@link Paginator#Paginator(String, int, List)} 48 | * 49 | * @since 0.1.0 50 | * @version 0.1.0 51 | * 52 | * @see Paginator#Paginator(String, int, List) 53 | * @param title The title for the pages 54 | * @param itemsPerPage The number of items from the content parameter to 55 | * display on a page 56 | * @param wholeText A string to be split by the newline character {@code \n} 57 | */ 58 | public Paginator(String title, int itemsPerPage, String wholeText) { 59 | this(title, itemsPerPage, wholeText.split("\n")); 60 | } 61 | 62 | /** 63 | * Constructor. Converts the passed {@code itr} parameter into a 64 | * {@link List} and forwards it to 65 | * {@link Paginator#Paginator(String, int, List)} 66 | * 67 | * @since 0.1.0 68 | * @version 0.1.0 69 | * 70 | * @see Paginator#Paginator(String, int, List) 71 | * @param title The title for the pages 72 | * @param itemsPerPage The number of items from the content parameter to 73 | * display on a page 74 | * @param itr An iterable collection of strings 75 | */ 76 | public Paginator(String title, int itemsPerPage, String... itr) { 77 | this(title, itemsPerPage, Arrays.asList(itr)); 78 | } 79 | 80 | /** 81 | * Constructor. Takes a {@link List} of strings and creates formatted 82 | * pages which can be output to a 83 | * {@link org.bukkit.command.CommandSender CommandSender}. These pages 84 | * should be considered immutable as they are only rendered once and then 85 | * subsequently stored. 86 | * 87 | * @since 0.1.0 88 | * @version 0.1.0 89 | * 90 | * @param title The title for the pages 91 | * @param itemsPerPage The number of items from the content parameter to 92 | * display on a page 93 | * @param content A {@link List} of strings to display 94 | */ 95 | public Paginator(String title, int itemsPerPage, List content) { 96 | String s = InternalLang.PAGINATOR_BARCHAR.formatAndColor(); 97 | if (s.isEmpty()) { 98 | this.BAR = "------------------------------" 99 | + "------------------------------"; 100 | } else { 101 | char[] barr = new char[60]; 102 | char c = s.toCharArray()[0]; 103 | for (int i = barr.length - 1; i >= 0; i--) { 104 | barr[i] = c; 105 | } 106 | this.BAR = new String(barr); 107 | } 108 | //divide into pages 109 | int pageCount = content.size() / itemsPerPage + ((content.size() % itemsPerPage) == 0 ? 0 : 1); 110 | for (int i = 0; i < pageCount; i++) { 111 | StringBuilder sb = new StringBuilder(); 112 | sb.append(this.formatTitle(title, 113 | InternalLang.PAGINATOR_BARCOLOR.formatAndColor(), 114 | InternalLang.PAGINATOR_TITLECOLOR.formatAndColor())); 115 | sb.append('\n'); 116 | sb.append(InternalLang.PAGINATOR_PAGEFORMAT.formatAndColor(i + 1, pageCount)); 117 | sb.append('\n'); 118 | int stop = (i + 1) * itemsPerPage; 119 | if (stop > content.size()) { 120 | stop = content.size(); 121 | } 122 | for (int w = i * itemsPerPage; w < stop; w++) { 123 | sb.append(content.get(w)).append('\n'); 124 | } 125 | sb.append(this.formatFooter(InternalLang.PAGINATOR_BARCOLOR.formatAndColor())); 126 | sb.append('\n'); 127 | this.pages.add(sb.toString()); 128 | } 129 | } 130 | 131 | /** 132 | * Returns the appropriately formatted page for this {@link Paginator} 133 | * 134 | * @since 0.1.0 135 | * @version 0.1.0 136 | * 137 | * @param page The page to retrieve 138 | * @return The page in the form of a string 139 | */ 140 | public String getPage(int page) { 141 | page--; 142 | if (page < 0 || page > this.pages.size()) { 143 | throw new IndexOutOfBoundsException("Page " + ++page + " does not exist"); 144 | } 145 | return this.pages.get(page); 146 | } 147 | 148 | /** 149 | * Formats the title-bar for displaying help information 150 | * 151 | * @since 0.1.0 152 | * @version 0.1.0 153 | * 154 | * @param title The title to use 155 | * @param barcolor The color of the bar (ref: {@link ChatColor}) 156 | * @param titlecolor The color of the title (ref: {@link ChatColor}) 157 | * @return A formatted header 158 | */ 159 | private String formatTitle(String title, String barcolor, String titlecolor) { 160 | String line = barcolor + this.BAR; 161 | int pivot = line.length() / 2; 162 | String center = InternalLang.PAGINATOR_TITLECONTAINER.formatAndColor(barcolor, titlecolor, title); 163 | return Lang.color(line.substring(0, pivot - center.length() / 2) 164 | + center 165 | + line.substring(0, pivot - center.length() / 2)); 166 | } 167 | 168 | /** 169 | * Formats the footer-bar of the help information. 170 | * 171 | * @since 0.1.0 172 | * @version 0.1.0 173 | * 174 | * @param barcolor The color of the footer-bar 175 | * @return A formatted footer 176 | */ 177 | private String formatFooter(String barcolor) { 178 | String back = barcolor + this.BAR; 179 | return Lang.color(back.substring(0, back.length() - 11)); 180 | } 181 | 182 | /** 183 | * Returns the number of pages in this instance 184 | * 185 | * @since 0.1.0 186 | * @version 0.1.0 187 | * 188 | * @return The number of pages 189 | */ 190 | public int size() { 191 | return this.pages.size(); 192 | } 193 | 194 | /** 195 | * Returns a copy of all the pages in this instance 196 | * 197 | * @since 0.1.0 198 | * @version 0.1.0 199 | * 200 | * @return A copy of the pages 201 | */ 202 | public List getPages() { 203 | return Collections.unmodifiableList(this.pages); 204 | } 205 | 206 | } 207 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/util/Players.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.util; 21 | 22 | import com.codelanx.codelanxlib.util.auth.UUIDFetcher; 23 | import org.bukkit.Bukkit; 24 | import org.bukkit.Location; 25 | import org.bukkit.Material; 26 | import org.bukkit.OfflinePlayer; 27 | import org.bukkit.entity.Player; 28 | import org.json.simple.parser.ParseException; 29 | 30 | import java.io.IOException; 31 | import java.util.HashMap; 32 | import java.util.Map; 33 | import java.util.UUID; 34 | import java.util.function.BiPredicate; 35 | 36 | /** 37 | * Represents utility functions to simplify or clarify common operations 38 | * with Bukkit's {@link Player} object 39 | * 40 | * @since 0.0.1 41 | * @author 1Rogue 42 | * @version 0.1.0 43 | */ 44 | public final class Players { 45 | 46 | private Players() { 47 | } 48 | 49 | /** 50 | * Gets any players within range of a specific location 51 | * 52 | * @since 0.0.1 53 | * @version 0.0.1 54 | * 55 | * @param range The range in which to look for players 56 | * @param origin The {@link Location} representing the center of the circle 57 | * @return Any players within the radius range of the origin, mapped to 58 | * the distance away they are 59 | */ 60 | public static Map getPlayersInRange(int range, Location origin) { 61 | Map back = new HashMap<>(); 62 | int frange = range * range; 63 | origin.getWorld().getPlayers().forEach((p) -> { 64 | double d = p.getLocation().distanceSquared(origin); 65 | if (d <= frange) { 66 | back.put(p, d); 67 | } 68 | }); 69 | return back; 70 | } 71 | 72 | /** 73 | * Gets any players within range of a specific player, exclusive of the 74 | * player themselves. 75 | * 76 | * @since 0.0.1 77 | * @version 0.0.1 78 | * 79 | * @param range The range in which to look for players 80 | * @param origin The {@link Player} representing the center of the circle 81 | * @return Any players within the radius range of the origin, mapped to 82 | * the distance away they are 83 | */ 84 | public static Map getPlayersInRange(int range, Player origin) { 85 | Map back = Players.getPlayersInRange(range, origin.getLocation()); 86 | back.remove(origin); 87 | return back; 88 | } 89 | 90 | /** 91 | * Returns the closest {@link Player} adjacent to another {@link Player} 92 | * 93 | * @since 0.1.0 94 | * @version 0.1.0 95 | * 96 | * @param p The {@link Player} at the origin to search around 97 | * @return The closest {@link Player}, or {@code null} if no one else is in 98 | * the world 99 | */ 100 | public static Player getClosestPlayer(Player p) { 101 | Location loc = p.getLocation(); 102 | return p.getWorld().getPlayers().stream() 103 | .filter((o) -> !p.equals(o)) 104 | .min((p1, p2) -> { 105 | return Double.compare(p1.getLocation().distanceSquared(loc), p2.getLocation().distanceSquared(loc)); 106 | }) 107 | .orElse(null); 108 | } 109 | 110 | /** 111 | * Returns the closest {@link Player} to a specific {@link Location} 112 | * 113 | * @since 0.1.0 114 | * @version 0.1.0 115 | * 116 | * @param loc The {@link Location} representing the origin to search from 117 | * @return The closest {@link Player}, or {@code null} if no one is in the 118 | * world 119 | */ 120 | public static Player getClosestPlayer(Location loc) { 121 | return loc.getWorld().getPlayers().stream().min((o1, o2) -> { 122 | return Double.compare(o1.getLocation().distanceSquared(loc), o2.getLocation().distanceSquared(loc)); 123 | }).orElse(null); 124 | } 125 | 126 | /** 127 | * Determines whether or not a location is harmful if a player was to be 128 | * located there in the current instant of time (such as a teleport) 129 | * 130 | * @since 0.1.0 131 | * @version 0.1.0 132 | * 133 | * @param in The {@link Location} to check 134 | * @return {@code true} if the location is safe 135 | */ 136 | public static boolean isSafeLocation(final Location in) { 137 | Location l = in.clone(); 138 | boolean hole = false; 139 | BiPredicate fallDmg = (i, m) -> i > 3 && m.isBlock(); 140 | int count = 0; 141 | while (l.getBlockY() > 0) { 142 | l.add(0, -1, 0); 143 | count++; 144 | Material type = l.getBlock().getType(); 145 | if (fallDmg.test(count, type)) { 146 | return false; 147 | } 148 | if (Blocks.isHarmful(type)) { 149 | return false; 150 | } 151 | if (type != Material.AIR && (type.isBlock() || type == Material.WATER || type == Material.STATIONARY_WATER)) { 152 | break; 153 | } 154 | } 155 | l = in.clone(); 156 | for (int i = 0; i < 2; i++) { 157 | Material type = l.getBlock().getType(); 158 | if (Blocks.isHarmful(type) || type.isBlock() || Blocks.isLiquid(type)) { 159 | return false; 160 | } 161 | l.add(0, 1, 0); 162 | } 163 | while (l.getBlockY() < 255) { 164 | Material type = l.getBlock().getType(); 165 | if (Blocks.isDangerousFromAbove(type)) { 166 | return false; 167 | } else if (type.isBlock()) { 168 | break; 169 | } 170 | l.add(0, 1, 0); 171 | } 172 | return true; 173 | } 174 | 175 | /** 176 | * Gets the most correct UUID for the {@link Player} in the least expensive 177 | * way possible. Note however, if there is no UUID information about the 178 | * player on the server (e.g., they never played before), it will send a 179 | * blocking web request to Mojang's servers 180 | * 181 | * @since 0.1.0 182 | * @version 0.1.0 183 | * 184 | * @param name The name of the {@link Player} 185 | * @return The {@link UUID} for that player 186 | */ 187 | public static UUID getUUID(String name) { 188 | if (Bukkit.getServer().getOnlineMode()) { 189 | OfflinePlayer op = Bukkit.getOfflinePlayer(name); 190 | if (op.hasPlayedBefore() || op.isOnline()) { 191 | return op.getUniqueId(); 192 | } 193 | } 194 | try { 195 | return UUIDFetcher.getUUIDOf(name); 196 | } catch (IOException | ParseException | InterruptedException ex) { 197 | throw new IllegalArgumentException("Cannot determine UUID of player '" + name + "'", ex); 198 | } 199 | } 200 | 201 | /** 202 | * Returns whether or not a player by the specified {@code name} parameter 203 | * has played on this server before, or is currently online, thus resulting 204 | * in having a correct {@link UUID} 205 | * 206 | * @since 0.1.0 207 | * @version 0.1.0 208 | * 209 | * @param name The player name to look for 210 | * @return {@code true} if the UUID will be correct 211 | */ 212 | public static boolean hasCorrectOfflineUUID(String name) { 213 | OfflinePlayer op = Bukkit.getOfflinePlayer(name); 214 | return op.hasPlayedBefore() || op.isOnline(); 215 | } 216 | 217 | } 218 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/util/Protections.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.util; 21 | 22 | import com.codelanx.codelanxlib.CodelanxLib; 23 | import com.codelanx.codelanxlib.internal.InternalPerms; 24 | import org.bukkit.Bukkit; 25 | import org.bukkit.Location; 26 | import org.bukkit.Material; 27 | import org.bukkit.block.Block; 28 | import org.bukkit.block.BlockFace; 29 | import org.bukkit.entity.Player; 30 | import org.bukkit.event.EventHandler; 31 | import org.bukkit.event.Listener; 32 | import org.bukkit.event.block.BlockBreakEvent; 33 | import org.bukkit.event.block.BlockBurnEvent; 34 | import org.bukkit.event.block.BlockPistonExtendEvent; 35 | import org.bukkit.event.block.BlockPistonRetractEvent; 36 | import org.bukkit.event.block.BlockPlaceEvent; 37 | import org.bukkit.event.entity.EntityChangeBlockEvent; 38 | import org.bukkit.event.entity.EntityExplodeEvent; 39 | import org.bukkit.plugin.java.JavaPlugin; 40 | 41 | import java.util.LinkedHashSet; 42 | import java.util.Set; 43 | 44 | /** 45 | * Adds protection to specific locations. This should not be used for large 46 | * areas, but rather indiscriminate points. Large-area protection will be added 47 | * later. Note that this will not protect from plugins dynamically modifying 48 | * the block themselves, such as WorldEdit 49 | * 50 | * @since 0.1.0 51 | * @author 1Rogue 52 | * @version 0.1.0 53 | */ 54 | public final class Protections { 55 | 56 | private static final Set protect = new LinkedHashSet<>(); 57 | private static boolean listenerRegistered = false; 58 | 59 | private Protections() { 60 | 61 | } 62 | 63 | /** 64 | * Protects a single {@link Location} from being altered 65 | * 66 | * @since 0.1.0 67 | * @version 0.1.0 68 | * 69 | * @param loc The {@link Location} to protect 70 | */ 71 | public static void protect(Location loc) { 72 | if (!Protections.listenerRegistered) { 73 | Bukkit.getServer().getPluginManager().registerEvents(new ProtectionListener(), JavaPlugin.getPlugin(CodelanxLib.class)); 74 | Protections.listenerRegistered = true; 75 | } 76 | Protections.protect.add(loc); 77 | } 78 | 79 | /** 80 | * Removes protection from a single {@link Location}. Does nothing if the 81 | * location was not protected in the first place. 82 | * 83 | * @since 0.1.0 84 | * @version 0.1.0 85 | * 86 | * @param loc The {@link Location} to unprotect 87 | */ 88 | public static void unprotect(Location loc) { 89 | Protections.protect.remove(loc); 90 | } 91 | 92 | /** 93 | * Returns {@code true} if the passed {@link Location} is protected 94 | * 95 | * @since 0.1.0 96 | * @version 0.1.0 97 | * 98 | * @param loc The {@link Location} to check 99 | * @return {@code true} if protected 100 | */ 101 | public static boolean isProtected(Location loc) { 102 | return Protections.protect.contains(loc); 103 | } 104 | 105 | /** 106 | * Provides total protection for blocks cached in {@link Protections} 107 | * 108 | * @since 0.1.0 109 | * @author 1Rogue 110 | * @version 0.1.0 111 | */ 112 | public static class ProtectionListener implements Listener { 113 | 114 | private boolean doCancel(Location loc, Player p, boolean cancelled) { 115 | if (Protections.isProtected(loc)) { 116 | if (p == null) { 117 | return true; 118 | } 119 | return !InternalPerms.PROTECTION_OVERRIDE.has(p) ? true : cancelled; 120 | } 121 | return cancelled; 122 | } 123 | 124 | /** 125 | * Prevents pistons from pushing protected blocks 126 | * 127 | * @since 0.1.0 128 | * @version 0.1.0 129 | * 130 | * @param event The relevant {@link BlockPistonExtendEvent} 131 | */ 132 | @EventHandler 133 | public void onPistonExtend(BlockPistonExtendEvent event) { 134 | if (!this.handlePiston(event.getBlock(), event.getDirection(), 12)) { 135 | event.setCancelled(true); 136 | } 137 | } 138 | 139 | /** 140 | * Prevents sticky pistons from pulling protected blocks 141 | * 142 | * @since 0.1.0 143 | * @version 0.1.0 144 | * 145 | * @param event The relevant {@link BlockPistonRetractEvent} 146 | */ 147 | @EventHandler 148 | public void onPistonRetract(BlockPistonRetractEvent event) { 149 | if (event.isSticky()) { 150 | if (!this.handlePiston(event.getBlock(), event.getDirection(), 1)) { 151 | event.setCancelled(true); 152 | } 153 | } 154 | } 155 | 156 | /** 157 | * Determines if a protected block will be affected by a piston 158 | * movement in a specific direction 159 | * 160 | * @since 0.1.0 161 | * @version 0.1.0 162 | * 163 | * @param b The starting piston block 164 | * @param dir The {@link BlockFace} direction to search in 165 | * @param amount The amount of blocks to check 166 | * @return {@code true} if no protected blocks will be affected 167 | */ 168 | private boolean handlePiston(Block b, BlockFace dir, int amount) { 169 | for (int i = amount; i > 0; i--) { 170 | b = b.getRelative(dir); 171 | if (b == null || b.getType() == Material.AIR) { 172 | return true; 173 | } 174 | if (Protections.isProtected(b.getLocation())) { 175 | return false; 176 | } 177 | } 178 | return true; 179 | } 180 | 181 | /** 182 | * Prevents protected blocks from being broken 183 | * 184 | * @since 0.1.0 185 | * @version 0.1.0 186 | * 187 | * @param event The relevant {@link BlockBreakEvent} 188 | */ 189 | @EventHandler 190 | public void onBlockBreak(BlockBreakEvent event) { 191 | event.setCancelled(this.doCancel(event.getBlock().getLocation(), 192 | event.getPlayer(), event.isCancelled())); 193 | } 194 | 195 | /** 196 | * Prevents blocks from being burned 197 | * 198 | * @since 0.1.0 199 | * @version 0.1.0 200 | * 201 | * @param event The relevant {@link BlockBurnEvent} 202 | */ 203 | @EventHandler 204 | public void onBurn(BlockBurnEvent event) { 205 | event.setCancelled(this.doCancel(event.getBlock().getLocation(), 206 | null, event.isCancelled())); 207 | } 208 | 209 | /** 210 | * Prevents blocks from being turned into entities (e.g. falling sand) 211 | * 212 | * @since 0.1.0 213 | * @version 0.1.0 214 | * 215 | * @param event The relevant {@link EntityChangeBlockEvent} 216 | */ 217 | @EventHandler 218 | public void onEntityBlock(EntityChangeBlockEvent event) { 219 | event.setCancelled(this.doCancel(event.getBlock().getLocation(), 220 | null, event.isCancelled())); 221 | } 222 | 223 | /** 224 | * Prevents people from placing a block in the protected location 225 | * 226 | * @since 0.1.0 227 | * @version 0.1.0 228 | * 229 | * @param event The relevant {@link BlockPlaceEvent} 230 | */ 231 | @EventHandler 232 | public void onPlace(BlockPlaceEvent event) { 233 | event.setCancelled(this.doCancel(event.getBlock().getLocation(), 234 | event.getPlayer(), event.isCancelled())); 235 | } 236 | 237 | /** 238 | * Prevents the block from exploding 239 | * 240 | * @since 0.1.0 241 | * @version 0.1.0 242 | * 243 | * @param event The relevant {@link EntityExplodeEvent} 244 | */ 245 | @EventHandler 246 | public void onExplode(EntityExplodeEvent event) { 247 | event.blockList().removeIf(b -> Protections.isProtected(b.getLocation())); 248 | } 249 | 250 | } 251 | 252 | } 253 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/util/ReflectBukkit.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.util; 21 | 22 | import com.codelanx.commons.logging.Debugger; 23 | import com.codelanx.commons.util.Reflections; 24 | import com.codelanx.commons.util.exception.Exceptions; 25 | import org.bukkit.Bukkit; 26 | import org.bukkit.World; 27 | import org.bukkit.plugin.java.JavaPlugin; 28 | 29 | import java.io.BufferedReader; 30 | import java.io.File; 31 | import java.io.FileInputStream; 32 | import java.io.IOException; 33 | import java.io.InputStream; 34 | import java.io.InputStreamReader; 35 | import java.util.zip.ZipEntry; 36 | import java.util.zip.ZipFile; 37 | import java.util.zip.ZipInputStream; 38 | 39 | /** 40 | * Created by Rogue on 11/17/2015. 41 | */ 42 | public class ReflectBukkit { //blergh, save me from this classname 43 | 44 | /** 45 | * Gets the default {@link World} loaded by Bukkit 46 | * 47 | * @since 0.1.0 48 | * @version 0.1.0 49 | * 50 | * @return Bukkit's default {@link World} object 51 | */ 52 | public static World getDefaultWorld() { 53 | Exceptions.illegalState(!Bukkit.getServer().getWorlds().isEmpty(), "No worlds loaded"); 54 | return Bukkit.getServer().getWorlds().get(0); 55 | } 56 | 57 | 58 | /** 59 | * Returns the {@link JavaPlugin} that immediately called the method in the 60 | * current context. Useful for finding out which plugins accessed static API 61 | * methods. This method is equivalent to calling 62 | * {@code Reflections.getCallingPlugin(0)} 63 | * 64 | * @since 0.1.0 65 | * @version 0.1.0 66 | * 67 | * @see ReflectBukkit#getCallingPlugin(int) 68 | * @return The relevant {@link JavaPlugin} 69 | * @throws UnsupportedOperationException If not called from a 70 | * {@link JavaPlugin} class (either through an alternative ClassLoader, 71 | * executing code directly, or some voodoo magic) 72 | */ 73 | public static JavaPlugin getCallingPlugin() { 74 | return ReflectBukkit.getCallingPlugin(1); 75 | } 76 | 77 | 78 | /** 79 | * Façade method for determining if Bukkit is the invoker of the method 80 | * 81 | * @since 0.1.0 82 | * @version 0.1.0 83 | * 84 | * @return {@code true} if Bukkit is the direct invoker of the method 85 | */ 86 | public static boolean accessedFromBukkit() { 87 | return Reflections.getCaller(1).getClassName().startsWith("org.bukkit."); 88 | } 89 | 90 | /** 91 | * Returns the {@link JavaPlugin} that immediately called the method in the 92 | * current context. Useful for finding out which plugins accessed static API 93 | * methods 94 | * 95 | * @since 0.1.0 96 | * @version 0.1.0 97 | * 98 | * @param offset The number of additional methods to look back 99 | * @return The relevant {@link JavaPlugin} 100 | * @throws UnsupportedOperationException If not called from a 101 | * {@link JavaPlugin} class (either through an alternative ClassLoader, 102 | * executing code directly, or some voodoo magic) 103 | */ 104 | public static JavaPlugin getCallingPlugin(int offset) { 105 | try { 106 | Class cl = Class.forName(Reflections.getCaller(1 + offset).getClassName()); 107 | JavaPlugin back = JavaPlugin.getProvidingPlugin(cl); 108 | if (back == null) { 109 | throw new UnsupportedOperationException("Must be called from a class loaded from a plugin"); 110 | } 111 | return back; 112 | } catch (ClassNotFoundException ex) { 113 | //Potentially dangerous (Stackoverflow) 114 | Debugger.error(ex, "Error reflecting for plugin class"); 115 | throw new IllegalStateException("Could not load from called class (Classloader issue?)", ex); 116 | } 117 | } 118 | 119 | /** 120 | * Checks whether or not there is a plugin on the server with the name of 121 | * the passed {@code name} paramater. This method achieves this by scanning 122 | * the plugins folder and reading the {@code plugin.yml} files of any 123 | * respective jarfiles in the directory. 124 | * 125 | * @since 0.1.0 126 | * @version 0.2.0 127 | * 128 | * @param name The name of the plugin as specified in the {@code plugin.yml} 129 | * @return The {@link File} for the plugin jarfile, or {@code null} if not 130 | * found 131 | */ 132 | public static File findPluginJarfile(String name) { 133 | File plugins = new File("plugins"); 134 | Exceptions.illegalState(plugins.isDirectory(), "'plugins' isn't a directory! (wat)"); 135 | for (File f : plugins.listFiles((File pathname) -> { 136 | return pathname.getPath().endsWith(".jar"); 137 | })) { 138 | try (InputStream is = new FileInputStream(f); ZipInputStream zi = new ZipInputStream(is)) { 139 | ZipEntry ent = null; 140 | while ((ent = zi.getNextEntry()) != null) { 141 | if (ent.getName().equalsIgnoreCase("plugin.yml")) { 142 | break; 143 | } 144 | } 145 | if (ent == null) { 146 | continue; //no plugin.yml found 147 | } 148 | ZipFile z = new ZipFile(f); 149 | try (InputStream fis = z.getInputStream(ent); 150 | InputStreamReader fisr = new InputStreamReader(fis); 151 | BufferedReader scan = new BufferedReader(fisr)) { 152 | String in; 153 | while ((in = scan.readLine()) != null) { 154 | if (in.startsWith("name: ")) { 155 | if (in.substring(6).equalsIgnoreCase(name)) { 156 | return f; 157 | } 158 | } 159 | } 160 | } 161 | } catch (IOException ex) { 162 | Debugger.error(ex, "Error reading plugin jarfiles"); 163 | } 164 | } 165 | return null; 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/util/RuntimeCommandSender.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.util; 21 | 22 | import org.bukkit.Server; 23 | import org.bukkit.command.CommandSender; 24 | import org.bukkit.permissions.Permission; 25 | import org.bukkit.permissions.PermissionAttachment; 26 | import org.bukkit.permissions.PermissionAttachmentInfo; 27 | import org.bukkit.plugin.Plugin; 28 | 29 | import java.util.Set; 30 | import java.util.logging.Logger; 31 | 32 | /** 33 | * Represents a {@link CommandSender} which outputs to a {@link Logger}. This is 34 | * specifically made with the intention of unit testing without running a Bukkit 35 | * environment 36 | * 37 | * @since 0.1.0 38 | * @author 1Rogue 39 | * @version 0.1.0 40 | */ 41 | public class RuntimeCommandSender implements CommandSender { 42 | 43 | private static final Logger LOG = Logger.getLogger(RuntimeCommandSender.class.getName()); 44 | 45 | @Override 46 | public void sendMessage(String message) { 47 | LOG.info(message); 48 | } 49 | 50 | @Override 51 | public void sendMessage(String[] messages) { 52 | for (String s : messages) { 53 | LOG.info(s); 54 | } 55 | } 56 | 57 | @Override 58 | public Server getServer() { 59 | throw new UnsupportedOperationException(this.getClass().getSimpleName() + " is not attached to any server instance"); 60 | } 61 | 62 | @Override 63 | public String getName() { 64 | return "RUNTIME"; 65 | } 66 | 67 | @Override 68 | public boolean isPermissionSet(String name) { 69 | return true; 70 | } 71 | 72 | @Override 73 | public boolean isPermissionSet(Permission perm) { 74 | return true; 75 | } 76 | 77 | @Override 78 | public boolean hasPermission(String name) { 79 | return true; 80 | } 81 | 82 | @Override 83 | public boolean hasPermission(Permission perm) { 84 | return true; 85 | } 86 | 87 | @Override 88 | public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value) { 89 | throw new UnsupportedOperationException(this.getClass().getSimpleName() + " cannot have permission attachments"); 90 | } 91 | 92 | @Override 93 | public PermissionAttachment addAttachment(Plugin plugin) { 94 | throw new UnsupportedOperationException(this.getClass().getSimpleName() + " cannot have permission attachments"); 95 | } 96 | 97 | @Override 98 | public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks) { 99 | throw new UnsupportedOperationException(this.getClass().getSimpleName() + " cannot have permission attachments"); 100 | } 101 | 102 | @Override 103 | public PermissionAttachment addAttachment(Plugin plugin, int ticks) { 104 | throw new UnsupportedOperationException(this.getClass().getSimpleName() + " cannot have permission attachments"); 105 | } 106 | 107 | @Override 108 | public void removeAttachment(PermissionAttachment attachment) {} 109 | 110 | @Override 111 | public void recalculatePermissions() {} 112 | 113 | @Override 114 | public Set getEffectivePermissions() { 115 | throw new UnsupportedOperationException(this.getClass().getSimpleName() + " cannot have permission attachments"); 116 | } 117 | 118 | @Override 119 | public boolean isOp() { 120 | return true; 121 | } 122 | 123 | @Override 124 | public void setOp(boolean value) {} 125 | 126 | } 127 | -------------------------------------------------------------------------------- /src/main/java/com/codelanx/codelanxlib/util/auth/UserInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Codelanx, All Rights Reserved 3 | * 4 | * This work is licensed under a Creative Commons 5 | * Attribution-NonCommercial-NoDerivs 3.0 Unported License. 6 | * 7 | * This program is protected software: You are free to distrubute your 8 | * own use of this software under the terms of the Creative Commons BY-NC-ND 9 | * license as published by Creative Commons in the year 2015 or as published 10 | * by a later date. You may not provide the source files or provide a means 11 | * of running the software outside of those licensed to use it. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * You should have received a copy of the Creative Commons BY-NC-ND license 18 | * long with this program. If not, see . 19 | */ 20 | package com.codelanx.codelanxlib.util.auth; 21 | 22 | import java.util.UUID; 23 | 24 | /** 25 | * Represents information about a player 26 | * 27 | * @since 0.1.0 28 | * @author 1Rogue 29 | * @version 0.1.0 30 | */ 31 | public class UserInfo { 32 | 33 | private final String name; 34 | private final UUID uuid; 35 | 36 | /** 37 | * Stores the passed fields 38 | * 39 | * @since 0.1.0 40 | * @version 0.1.0 41 | * 42 | * @param name The player name 43 | * @param uuid The player {@link UUID} 44 | */ 45 | public UserInfo(String name, UUID uuid) { 46 | this.name = name; 47 | this.uuid = uuid; 48 | } 49 | 50 | /** 51 | * Returns the name of this player 52 | * 53 | * @since 0.1.0 54 | * @version 0.1.0 55 | * 56 | * @return The player name 57 | */ 58 | public String getName() { 59 | return this.name; 60 | } 61 | 62 | /** 63 | * Returns the {@link UUID} of this player 64 | * 65 | * @since 0.1.0 66 | * @version 0.1.0 67 | * 68 | * @return The player {@link UUID} 69 | */ 70 | public UUID getUUID() { 71 | return this.uuid; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: ${project.name} 2 | version: ${project.version} 3 | description: ${project.description} 4 | load: STARTUP 5 | author: 1Rogue 6 | website: ${website} 7 | main: ${project.groupId}.${project.artifactId}.${project.name} 8 | loadbefore: [Vault] 9 | softdepend: [Vault] 10 | prefix: ${prefix} --------------------------------------------------------------------------------