implement core library

This commit is contained in:
jascotty2 2019-09-03 15:38:00 -05:00
parent d7aef463d1
commit d5139cd5e0
50 changed files with 846 additions and 3798 deletions

View File

@ -1,58 +1,74 @@
package com.songoda.ultimatestacker;
import com.songoda.ultimatestacker.command.CommandManager;
import com.songoda.ultimatestacker.database.*;
import com.songoda.core.SongodaCore;
import com.songoda.core.SongodaPlugin;
import com.songoda.core.commands.CommandManager;
import com.songoda.core.compatibility.LegacyMaterials;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.core.configuration.Config;
import com.songoda.core.database.DataMigrationManager;
import com.songoda.core.database.DatabaseConnector;
import com.songoda.core.database.MySQLConnector;
import com.songoda.core.database.SQLiteConnector;
import com.songoda.core.gui.GuiManager;
import com.songoda.core.hooks.HologramManager;
import com.songoda.core.utils.TextUtils;
import com.songoda.ultimatestacker.commands.CommandConvert;
import com.songoda.ultimatestacker.commands.CommandGiveSpawner;
import com.songoda.ultimatestacker.commands.CommandReload;
import com.songoda.ultimatestacker.commands.CommandRemoveAll;
import com.songoda.ultimatestacker.commands.CommandSettings;
import com.songoda.ultimatestacker.commands.CommandUltimateStacker;
import com.songoda.ultimatestacker.database.DataManager;
import com.songoda.ultimatestacker.database.migrations._1_InitialMigration;
import com.songoda.ultimatestacker.entity.EntityStack;
import com.songoda.ultimatestacker.entity.EntityStackManager;
import com.songoda.ultimatestacker.hologram.Hologram;
import com.songoda.ultimatestacker.hologram.HologramHolographicDisplays;
import com.songoda.ultimatestacker.hook.StackerHook;
import com.songoda.ultimatestacker.hook.hooks.JobsHook;
import com.songoda.ultimatestacker.listeners.*;
import com.songoda.ultimatestacker.lootables.LootablesManager;
import com.songoda.ultimatestacker.settings.Setting;
import com.songoda.ultimatestacker.spawner.SpawnerStack;
import com.songoda.ultimatestacker.spawner.SpawnerStackManager;
import com.songoda.ultimatestacker.storage.Storage;
import com.songoda.ultimatestacker.storage.StorageRow;
import com.songoda.ultimatestacker.storage.types.StorageYaml;
import com.songoda.ultimatestacker.tasks.StackingTask;
import com.songoda.ultimatestacker.utils.*;
import com.songoda.ultimatestacker.utils.locale.Locale;
import com.songoda.ultimatestacker.utils.settings.Setting;
import com.songoda.ultimatestacker.utils.settings.SettingsManager;
import com.songoda.ultimatestacker.utils.updateModules.LocaleModule;
import com.songoda.update.Plugin;
import com.songoda.update.SongodaUpdate;
import org.apache.commons.lang.ArrayUtils;
import com.songoda.ultimatestacker.utils.EntityUtils;
import com.songoda.ultimatestacker.utils.Methods;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.block.Block;
import org.bukkit.block.CreatureSpawner;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class UltimateStacker extends JavaPlugin {
public class UltimateStacker extends SongodaPlugin {
private static UltimateStacker INSTANCE;
private static List<String> whitelist;
private static List<String> blacklist;
private ConfigWrapper mobFile = new ConfigWrapper(this, "", "mobs.yml");
private ConfigWrapper itemFile = new ConfigWrapper(this, "", "items.yml");
private ConfigWrapper spawnerFile = new ConfigWrapper(this, "", "spawners.yml");
private final Config mobFile = new Config(this, "mobs.yml");
private final Config itemFile = new Config(this, "items.yml");
private final Config spawnerFile = new Config(this, "spawners.yml");
private Locale locale;
private SettingsManager settingsManager;
private final GuiManager guiManager = new GuiManager(this);
private EntityStackManager entityStackManager;
private SpawnerStackManager spawnerStackManager;
private LootablesManager lootablesManager;
private CommandManager commandManager;
private StackingTask stackingTask;
private Hologram hologram;
private DatabaseConnector databaseConnector;
private DataMigrationManager dataMigrationManager;
@ -62,35 +78,40 @@ public class UltimateStacker extends JavaPlugin {
private List<StackerHook> stackerHooks = new ArrayList<>();
private ServerVersion serverVersion = ServerVersion.fromPackageName(Bukkit.getServer().getClass().getPackage().getName());
public static UltimateStacker getInstance() {
return INSTANCE;
}
public void onDisable() {
@Override
public void onPluginLoad() {
INSTANCE = this;
}
@Override
public void onPluginDisable() {
this.dataManager.bulkUpdateSpawners(this.spawnerStackManager.getStacks());
ConsoleCommandSender console = Bukkit.getConsoleSender();
console.sendMessage(Methods.formatText("&a============================="));
console.sendMessage(Methods.formatText("&7UltimateStacker " + this.getDescription().getVersion() + " by &5Songoda <3!"));
console.sendMessage(Methods.formatText("&7Action: &cDisabling&7..."));
console.sendMessage(Methods.formatText("&a============================="));
HologramManager.removeAllHolograms();
}
@Override
public void onEnable() {
INSTANCE = this;
ConsoleCommandSender console = Bukkit.getConsoleSender();
console.sendMessage(Methods.formatText("&a============================="));
console.sendMessage(Methods.formatText("&7UltimateStacker " + this.getDescription().getVersion() + " by &5Songoda <3&7!"));
console.sendMessage(Methods.formatText("&7Action: &aEnabling&7..."));
this.settingsManager = new SettingsManager(this);
this.settingsManager.setupConfig();
public void onPluginEnable() {
// Run Songoda Updater
SongodaCore.registerPlugin(this, 16, LegacyMaterials.IRON_INGOT);
// Setup Config
Setting.setupConfig();
this.setLocale(Setting.LANGUGE_MODE.getString(), false);
whitelist = Setting.ITEM_WHITELIST.getStringList();
blacklist = Setting.ITEM_BLACKLIST.getStringList();
// Setup plugin commands
this.commandManager = new CommandManager(this);
this.commandManager.addCommand(new CommandUltimateStacker())
.addSubCommand(new CommandSettings())
.addSubCommand(new CommandRemoveAll())
.addSubCommand(new CommandReload())
.addSubCommand(new CommandGiveSpawner())
.addSubCommand(new CommandConvert());
this.entityUtils = new EntityUtils();
@ -98,49 +119,41 @@ public class UltimateStacker extends JavaPlugin {
this.lootablesManager.createDefaultLootables();
this.getLootablesManager().getLootManager().loadLootables();
for (EntityType value : EntityType.values()) {
if (value.isSpawnable() && value.isAlive() && !value.toString().contains("ARMOR")) {
mobFile.getConfig().addDefault("Mobs." + value.name() + ".Enabled", true);
mobFile.getConfig().addDefault("Mobs." + value.name() + ".Display Name", Methods.formatText(value.name().toLowerCase().replace("_", " "), true));
mobFile.getConfig().addDefault("Mobs." + value.name() + ".Max Stack Size", -1);
mobFile.getConfig().addDefault("Mobs." + value.name() + ".Kill Whole Stack", false);
mobFile.addDefault("Mobs." + value.name() + ".Enabled", true);
mobFile.addDefault("Mobs." + value.name() + ".Display Name", Methods.formatText(value.name().toLowerCase().replace("_", " "), true));
mobFile.addDefault("Mobs." + value.name() + ".Max Stack Size", -1);
mobFile.addDefault("Mobs." + value.name() + ".Kill Whole Stack", false);
}
}
mobFile.getConfig().options().copyDefaults(true);
mobFile.saveConfig();
mobFile.load();
mobFile.saveChanges();
for (Material value : Material.values()) {
itemFile.getConfig().addDefault("Items." + value.name() + ".Has Hologram", true);
itemFile.getConfig().addDefault("Items." + value.name() + ".Max Stack Size", -1);
itemFile.getConfig().addDefault("Items." + value.name() + ".Display Name", Methods.formatText(value.name().toLowerCase().replace("_", " "), true));
itemFile.addDefault("Items." + value.name() + ".Has Hologram", true);
itemFile.addDefault("Items." + value.name() + ".Max Stack Size", -1);
itemFile.addDefault("Items." + value.name() + ".Display Name", Methods.formatText(value.name().toLowerCase().replace("_", " "), true));
}
itemFile.getConfig().options().copyDefaults(true);
itemFile.saveConfig();
itemFile.load();
itemFile.saveChanges();
for (EntityType value : EntityType.values()) {
if (value.isSpawnable() && value.isAlive() && !value.toString().contains("ARMOR")) {
spawnerFile.getConfig().addDefault("Spawners." + value.name() + ".Max Stack Size", -1);
spawnerFile.getConfig().addDefault("Spawners." + value.name() + ".Display Name", Methods.formatText(value.name().toLowerCase().replace("_", " "), true));
spawnerFile.addDefault("Spawners." + value.name() + ".Max Stack Size", -1);
spawnerFile.addDefault("Spawners." + value.name() + ".Display Name", Methods.formatText(value.name().toLowerCase().replace("_", " "), true));
}
}
spawnerFile.getConfig().options().copyDefaults(true);
spawnerFile.saveConfig();
new Locale(this, "en_US");
this.locale = Locale.getLocale(getConfig().getString("System.Language Mode"));
//Running Songoda Updater
Plugin plugin = new Plugin(this, 16);
plugin.addModule(new LocaleModule());
SongodaUpdate.load(plugin);
spawnerFile.load();
spawnerFile.saveChanges();
this.spawnerStackManager = new SpawnerStackManager();
this.entityStackManager = new EntityStackManager();
this.stackingTask = new StackingTask(this);
guiManager.init();
PluginManager pluginManager = Bukkit.getPluginManager();
if (isServerVersionAtLeast(ServerVersion.V1_10))
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_10))
pluginManager.registerEvents(new BreedListeners(this), this);
pluginManager.registerEvents(new BlockListeners(this), this);
pluginManager.registerEvents(new DeathListeners(this), this);
@ -155,20 +168,11 @@ public class UltimateStacker extends JavaPlugin {
if (Setting.CLEAR_LAG.getBoolean() && pluginManager.isPluginEnabled("ClearLag"))
pluginManager.registerEvents(new ClearLagListeners(this), this);
// Register Hologram Plugin
if (Setting.SPAWNER_HOLOGRAMS.getBoolean()) {
if (pluginManager.isPluginEnabled("HolographicDisplays"))
hologram = new HologramHolographicDisplays(this);
}
// Register Hooks
if (pluginManager.isPluginEnabled("Jobs")) {
stackerHooks.add(new JobsHook());
}
// Starting Metrics
new Metrics(this);
// Legacy Data
Bukkit.getScheduler().runTaskLater(this, () -> {
File folder = getDataFolder();
@ -218,18 +222,18 @@ public class UltimateStacker extends JavaPlugin {
}
this.dataManager = new DataManager(this.databaseConnector, this);
this.dataMigrationManager = new DataMigrationManager(this.databaseConnector, this.dataManager);
this.dataMigrationManager = new DataMigrationManager(this.databaseConnector, this.dataManager,
new _1_InitialMigration());
this.dataMigrationManager.runMigrations();
Bukkit.getScheduler().runTaskLater(this, () -> {
final boolean useHolo = Setting.SPAWNER_HOLOGRAMS.getBoolean();
this.dataManager.getSpawners((spawners) -> {
this.spawnerStackManager.addSpawners(spawners);
if (hologram != null)
this.hologram.loadHolograms();
if (useHolo)
loadHolograms();
});
}, 20L);
console.sendMessage(Methods.formatText("&a============================="));
}
public void addExp(Player player, EntityStack stack) {
@ -238,8 +242,21 @@ public class UltimateStacker extends JavaPlugin {
}
}
public void reload() {
this.locale = Locale.getLocale(getConfig().getString("System.Language Mode"));
public GuiManager getGuiManager() {
return guiManager;
}
@Override
public List<Config> getExtraConfig() {
return Arrays.asList(mobFile, itemFile, spawnerFile);
}
@Override
public void onConfigReload() {
whitelist = Setting.ITEM_WHITELIST.getStringList();
blacklist = Setting.ITEM_BLACKLIST.getStringList();
this.setLocale(getConfig().getString("System.Language Mode"), true);
this.locale.reloadMessages();
this.entityUtils = new EntityUtils();
@ -247,10 +264,9 @@ public class UltimateStacker extends JavaPlugin {
this.stackingTask.cancel();
this.stackingTask = new StackingTask(this);
this.mobFile = new ConfigWrapper(this, "", "mobs.yml");
this.itemFile = new ConfigWrapper(this, "", "items.yml");
this.spawnerFile = new ConfigWrapper(this, "", "spawners.yml");
this.settingsManager.reloadConfig();
this.mobFile.load();
this.itemFile.load();
this.spawnerFile.load();
this.getLootablesManager().getLootManager().loadLootables();
}
@ -258,30 +274,6 @@ public class UltimateStacker extends JavaPlugin {
return !this.getServer().getPluginManager().isPluginEnabled("EpicSpawners") && Setting.SPAWNERS_ENABLED.getBoolean();
}
public Hologram getHologram() {
return hologram;
}
public ServerVersion getServerVersion() {
return serverVersion;
}
public boolean isServerVersion(ServerVersion version) {
return serverVersion == version;
}
public boolean isServerVersion(ServerVersion... versions) {
return ArrayUtils.contains(versions, serverVersion);
}
public boolean isServerVersionAtLeast(ServerVersion version) {
return serverVersion.ordinal() >= version.ordinal();
}
public Locale getLocale() {
return locale;
}
public CommandManager getCommandManager() {
return commandManager;
}
@ -302,19 +294,15 @@ public class UltimateStacker extends JavaPlugin {
return stackingTask;
}
public SettingsManager getSettingsManager() {
return settingsManager;
}
public ConfigWrapper getMobFile() {
public Config getMobFile() {
return mobFile;
}
public ConfigWrapper getItemFile() {
public Config getItemFile() {
return itemFile;
}
public ConfigWrapper getSpawnerFile() {
public Config getSpawnerFile() {
return spawnerFile;
}
@ -329,4 +317,161 @@ public class UltimateStacker extends JavaPlugin {
public DataManager getDataManager() {
return dataManager;
}
void loadHolograms() {
Collection<SpawnerStack> spawners = getSpawnerStackManager().getStacks();
if (spawners.isEmpty()) return;
for (SpawnerStack spawner : spawners) {
if (spawner.getLocation().getWorld() != null) {
updateHologram(spawner);
}
}
}
public void clearHologram(SpawnerStack stack) {
HologramManager.removeHologram(stack.getLocation());
}
public void updateHologram(SpawnerStack stack) {
// are holograms enabled?
if(!Setting.SPAWNER_HOLOGRAMS.getBoolean() || !HologramManager.getManager().isEnabled()) return;
// verify that this is a spawner stack
if (stack.getLocation().getBlock().getType() != LegacyMaterials.SPAWNER.getMaterial()) return;
// grab the spawner block
CreatureSpawner creatureSpawner = (CreatureSpawner) stack.getLocation().getBlock().getState();
String name = Methods.compileSpawnerName(creatureSpawner.getSpawnedType(), stack.getAmount());
// create the hologram
HologramManager.updateHologram(stack.getLocation(), name);
}
public void updateHologram(Block block) {
// verify that this is a spawner
if (block.getType() != LegacyMaterials.SPAWNER.getMaterial()) return;
// are holograms enabled?
if(!Setting.SPAWNER_HOLOGRAMS.getBoolean() || !HologramManager.getManager().isEnabled()) return;
// update this hologram in a tick
SpawnerStack spawner = getSpawnerStackManager().getSpawner(block);
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(this, () -> updateHologram(spawner), 10L);
}
//////// Convenient API //////////
/**
* Change the stacked amount for this item
*
* @param item item entity to update
* @param newAmount number of items this item represents
*/
public static void updateItemAmount(Item item, int newAmount) {
updateItemAmount(item, item.getItemStack(), newAmount);
}
/**
* Change the stacked amount for this item
*
* @param item item entity to update
* @param itemStack ItemStack that will represent this item
* @param newAmount number of items this item represents
*/
public static void updateItemAmount(Item item, ItemStack itemStack, int newAmount) {
Material material = itemStack.getType();
String name = TextUtils.convertToInvisibleString("IS") + Methods.compileItemName(itemStack, newAmount);
boolean blacklisted = isMaterialBlacklisted(itemStack);
//boolean blacklisted = ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)
// ? isMaterialBlacklisted(material) : isMaterialBlacklisted(material, itemStack.getData().getData());
if (newAmount > 32 && !blacklisted) {
item.setMetadata("US_AMT", new FixedMetadataValue(INSTANCE, newAmount));
itemStack.setAmount(32);
} else {
item.removeMetadata("US_AMT", INSTANCE);
itemStack.setAmount(newAmount);
}
item.setItemStack(itemStack);
if ((blacklisted && !Setting.ITEM_HOLOGRAM_BLACKLIST.getBoolean())
|| !INSTANCE.getItemFile().getBoolean("Items." + material + ".Has Hologram")
|| !Setting.ITEM_HOLOGRAMS.getBoolean()
|| newAmount == 1 && !Setting.ITEM_HOLOGRAM_SINGLE.getBoolean())
return;
item.setCustomName(name);
item.setCustomNameVisible(true);
}
/**
* Lookup the stacked size of this item
*
* @param item item to check
* @return stacker-corrected value for the stack size
*/
public static int getActualItemAmount(Item item) {
int amount = item.getItemStack().getAmount();
if (amount >= 32 && item.hasMetadata("US_AMT")) {
return item.getMetadata("US_AMT").get(0).asInt();
} else {
return amount;
}
}
/**
* Check to see if the amount stored in this itemstack is not the stacked
* amount
*
* @param item item to check
* @return true if Item.getItemStack().getAmount() is different from the
* stacked amount
*/
public static boolean hasCustomAmount(Item item) {
if (item.hasMetadata("US_AMT")) {
return item.getItemStack().getAmount() != item.getMetadata("US_AMT").get(0).asInt();
}
return false;
}
/**
* Check to see if this material is not permitted to stack
*
* @param type Material to check
* @return true if this material will not stack
*/
public static boolean isMaterialBlacklisted(Material type) {
return !whitelist.isEmpty() && !whitelist.contains(type.name())
|| !blacklist.isEmpty() && blacklist.contains(type.name());
}
/**
* Check to see if this material is not permitted to stack
*
* @param item Item material to check
* @return true if this material will not stack
*/
public static boolean isMaterialBlacklisted(ItemStack item) {
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)) {
return isMaterialBlacklisted(item.getType());
} else {
LegacyMaterials mat = LegacyMaterials.getMaterial(item);
if (mat.usesData()) {
return isMaterialBlacklisted(mat.getMaterial(), mat.getData());
} else {
return isMaterialBlacklisted(mat.getMaterial());
}
}
}
/**
* Check to see if this material is not permitted to stack
*
* @param type Material to check
* @param data daya value for this item (for 1.12 and older servers)
* @return true if this material will not stack
*/
public static boolean isMaterialBlacklisted(Material type, byte data) {
String combined = type.toString() + ":" + data;
return !whitelist.isEmpty() && !whitelist.contains(combined)
|| !blacklist.isEmpty() && blacklist.contains(combined);
}
}

View File

@ -1,72 +0,0 @@
package com.songoda.ultimatestacker.command;
import com.songoda.ultimatestacker.UltimateStacker;
import org.bukkit.command.CommandSender;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public abstract class AbstractCommand {
private final boolean noConsole;
private AbstractCommand parent = null;
private boolean hasArgs = false;
private String command;
private List<String> subCommand = new ArrayList<>();
protected AbstractCommand(AbstractCommand parent, boolean noConsole, String... command) {
if (parent != null) {
this.subCommand = Arrays.asList(command);
} else {
this.command = Arrays.asList(command).get(0);
}
this.parent = parent;
this.noConsole = noConsole;
}
protected AbstractCommand(boolean noConsole, boolean hasArgs, String... command) {
this.command = Arrays.asList(command).get(0);
this.hasArgs = hasArgs;
this.noConsole = noConsole;
}
public AbstractCommand getParent() {
return parent;
}
public String getCommand() {
return command;
}
public List<String> getSubCommand() {
return subCommand;
}
public void addSubCommand(String command) {
subCommand.add(command);
}
protected abstract ReturnType runCommand(UltimateStacker instance, CommandSender sender, String... args);
protected abstract List<String> onTab(UltimateStacker instance, CommandSender sender, String... args);
public abstract String getPermissionNode();
public abstract String getSyntax();
public abstract String getDescription();
public boolean hasArgs() {
return hasArgs;
}
public boolean isNoConsole() {
return noConsole;
}
public enum ReturnType {SUCCESS, FAILURE, SYNTAX_ERROR}
}

View File

@ -1,87 +0,0 @@
package com.songoda.ultimatestacker.command;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.command.commands.*;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CommandManager implements CommandExecutor {
private static final List<AbstractCommand> commands = new ArrayList<>();
private UltimateStacker plugin;
private TabManager tabManager;
public CommandManager(UltimateStacker plugin) {
this.plugin = plugin;
this.tabManager = new TabManager(this);
plugin.getCommand("UltimateStacker").setExecutor(this);
AbstractCommand commandUltimateStacker = addCommand(new CommandUltimateStacker());
addCommand(new CommandSettings(commandUltimateStacker));
addCommand(new CommandRemoveAll(commandUltimateStacker));
addCommand(new CommandReload(commandUltimateStacker));
addCommand(new CommandGiveSpawner(commandUltimateStacker));
addCommand(new CommandConvert(commandUltimateStacker));
for (AbstractCommand abstractCommand : commands) {
if (abstractCommand.getParent() != null) continue;
plugin.getCommand(abstractCommand.getCommand()).setTabCompleter(tabManager);
}
}
private AbstractCommand addCommand(AbstractCommand abstractCommand) {
commands.add(abstractCommand);
return abstractCommand;
}
@Override
public boolean onCommand(CommandSender commandSender, Command command, String s, String[] strings) {
for (AbstractCommand abstractCommand : commands) {
if (abstractCommand.getCommand() != null && abstractCommand.getCommand().equalsIgnoreCase(command.getName().toLowerCase())) {
if (strings.length == 0 || abstractCommand.hasArgs()) {
processRequirements(abstractCommand, commandSender, strings);
return true;
}
} else if (strings.length != 0 && abstractCommand.getParent() != null && abstractCommand.getParent().getCommand().equalsIgnoreCase(command.getName())) {
String cmd = strings[0];
String cmd2 = strings.length >= 2 ? String.join(" ", strings[0], strings[1]) : null;
for (String cmds : abstractCommand.getSubCommand()) {
if (cmd.equalsIgnoreCase(cmds) || (cmd2 != null && cmd2.equalsIgnoreCase(cmds))) {
processRequirements(abstractCommand, commandSender, strings);
return true;
}
}
}
}
plugin.getLocale().newMessage("&7The command you entered does not exist or is spelt incorrectly.").sendPrefixedMessage(commandSender);
return true;
}
private void processRequirements(AbstractCommand command, CommandSender sender, String[] strings) {
if (!(sender instanceof Player) && command.isNoConsole()) {
sender.sendMessage("You must be a player to use this command.");
return;
}
if (command.getPermissionNode() == null || sender.hasPermission(command.getPermissionNode())) {
AbstractCommand.ReturnType returnType = command.runCommand(plugin, sender, strings);
if (returnType == AbstractCommand.ReturnType.SYNTAX_ERROR) {
plugin.getLocale().newMessage("&cInvalid Syntax!").sendPrefixedMessage(sender);
plugin.getLocale().newMessage("&7The valid syntax is: &6" + command.getSyntax() + "&7.").sendPrefixedMessage(sender);
}
return;
}
plugin.getLocale().getMessage("event.general.nopermission").sendPrefixedMessage(sender);
}
public List<AbstractCommand> getCommands() {
return Collections.unmodifiableList(commands);
}
}

View File

@ -1,64 +0,0 @@
package com.songoda.ultimatestacker.command;
import com.songoda.ultimatestacker.UltimateStacker;
import org.apache.commons.lang.ArrayUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import java.util.ArrayList;
import java.util.List;
public class TabManager implements TabCompleter {
private final CommandManager commandManager;
TabManager(CommandManager commandManager) {
this.commandManager = commandManager;
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] strings) {
for (AbstractCommand abstractCommand : commandManager.getCommands()) {
if (abstractCommand.getCommand() != null && abstractCommand.getCommand().equalsIgnoreCase(command.getName()) && !abstractCommand.hasArgs()) {
if (strings.length == 1) {
List<String> subs = new ArrayList<>();
for (AbstractCommand ac : commandManager.getCommands()) {
if (ac.getSubCommand() == null) continue;
subs.addAll(ac.getSubCommand());
}
subs.removeIf(s -> !s.toLowerCase().startsWith(strings[0].toLowerCase()));
return subs;
}
} else if (strings.length != 0 && abstractCommand.getParent() != null && abstractCommand.getParent().getCommand().equalsIgnoreCase(command.getName())
|| abstractCommand.hasArgs() && abstractCommand.getCommand().equalsIgnoreCase(command.getName())) {
String[] args = abstractCommand.hasArgs() ? (String[]) ArrayUtils.add(strings, 0, command.getName()) : strings;
String cmd = abstractCommand.hasArgs() ? command.getName() : args[0];
String cmd2 = args.length >= 2 ? String.join(" ", args[0], args[1]) : null;
if (!abstractCommand.hasArgs()) {
for (String cmds : abstractCommand.getSubCommand()) {
if (cmd.equalsIgnoreCase(cmds) || (cmd2 != null && cmd2.equalsIgnoreCase(cmds))) {
return fetchList(abstractCommand, args, sender);
}
}
} else {
return fetchList(abstractCommand, args, sender);
}
}
}
return new ArrayList<>();
}
private List<String> fetchList(AbstractCommand abstractCommand, String[] args, CommandSender sender) {
List<String> list = abstractCommand.onTab(UltimateStacker.getInstance(), sender, args);
String str = args[args.length - 1];
if (list != null && str != null && str.length() >= 1) {
try {
list.removeIf(s -> !s.toLowerCase().startsWith(str.toLowerCase()));
} catch (UnsupportedOperationException ignored) {
}
}
return list;
}
}

View File

@ -1,7 +1,7 @@
package com.songoda.ultimatestacker.command.commands;
package com.songoda.ultimatestacker.commands;
import com.songoda.core.commands.AbstractCommand;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.command.AbstractCommand;
import com.songoda.ultimatestacker.gui.GUIConvert;
import com.songoda.ultimatestacker.utils.Methods;
import org.bukkit.Bukkit;
@ -12,15 +12,18 @@ import java.util.List;
public class CommandConvert extends AbstractCommand {
public CommandConvert(AbstractCommand parent) {
super(parent, true, "convert");
UltimateStacker instance;
public CommandConvert() {
super(true, "convert");
instance = UltimateStacker.getInstance();
}
@Override
protected ReturnType runCommand(UltimateStacker instance, CommandSender sender, String... args) {
protected ReturnType runCommand(CommandSender sender, String... args) {
if (Bukkit.getPluginManager().isPluginEnabled("WildStacker")
|| Bukkit.getPluginManager().isPluginEnabled("StackMob")) {
new GUIConvert(instance, (Player) sender);
instance.getGuiManager().showGUI((Player) sender, new GUIConvert());
} else {
sender.sendMessage(Methods.formatText("&cYou need to have the plugin &4WildStacker &cor &4StackMob &cenabled " +
"in order to convert data."));
@ -29,7 +32,7 @@ public class CommandConvert extends AbstractCommand {
}
@Override
protected List<String> onTab(UltimateStacker instance, CommandSender sender, String... args) {
protected List<String> onTab(CommandSender sender, String... args) {
return null;
}

View File

@ -1,7 +1,7 @@
package com.songoda.ultimatestacker.command.commands;
package com.songoda.ultimatestacker.commands;
import com.songoda.core.commands.AbstractCommand;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.command.AbstractCommand;
import com.songoda.ultimatestacker.utils.Methods;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
@ -16,29 +16,32 @@ import java.util.stream.Collectors;
public class CommandGiveSpawner extends AbstractCommand {
public CommandGiveSpawner(AbstractCommand abstractCommand) {
super(abstractCommand, false, "givespawner");
UltimateStacker instance;
public CommandGiveSpawner() {
super(false, "givespawner");
instance = UltimateStacker.getInstance();
}
@Override
protected ReturnType runCommand(UltimateStacker instance, CommandSender sender, String... args) {
if (args.length < 3) return ReturnType.SYNTAX_ERROR;
protected ReturnType runCommand(CommandSender sender, String... args) {
if (args.length < 2) return ReturnType.SYNTAX_ERROR;
if (Bukkit.getPlayer(args[1]) == null && !args[1].trim().toLowerCase().equals("all")) {
sender.sendMessage("Not a player...");
if (Bukkit.getPlayer(args[0]) == null && !args[0].trim().toLowerCase().equals("all")) {
sender.sendMessage(args[0] + " is not a player...");
return ReturnType.SYNTAX_ERROR;
}
EntityType type = null;
for (EntityType types : EntityType.values()) {
String input = args[2].toUpperCase().replace("_", "").replace(" ", "");
String input = args[1].toUpperCase().replace("_", "").replace(" ", "");
String compare = types.name().toUpperCase().replace("_", "").replace(" ", "");
if (input.equals(compare))
type = types;
}
if (type == null) {
instance.getLocale().newMessage("&7The entity StackType &6" + args[2] + " &7does not exist. Try one of these:").sendPrefixedMessage(sender);
instance.getLocale().newMessage("&7The entity StackType &6" + args[1] + " &7does not exist. Try one of these:").sendPrefixedMessage(sender);
StringBuilder list = new StringBuilder();
for (EntityType types : EntityType.values()) {
@ -48,10 +51,10 @@ public class CommandGiveSpawner extends AbstractCommand {
sender.sendMessage(Methods.formatText("&6" + list));
} else {
int amt = args.length == 4 ? Integer.parseInt(args[3]) : 1;
int amt = args.length == 3 ? Integer.parseInt(args[2]) : 1;
ItemStack itemStack = Methods.getSpawnerItem(type, amt);
if (!args[1].trim().toLowerCase().equals("all")) {
Player player = Bukkit.getOfflinePlayer(args[1]).getPlayer();
if (!args[0].trim().toLowerCase().equals("all")) {
Player player = Bukkit.getOfflinePlayer(args[0]).getPlayer();
player.getInventory().addItem(itemStack);
instance.getLocale().getMessage("command.give.success")
.processPlaceholder("type", Methods.compileSpawnerName(type, amt))
@ -69,17 +72,17 @@ public class CommandGiveSpawner extends AbstractCommand {
}
@Override
protected List<String> onTab(UltimateStacker instance, CommandSender sender, String... args) {
if (args.length == 2) {
protected List<String> onTab(CommandSender sender, String... args) {
if (args.length == 1) {
List<String> players = new ArrayList<>();
players.add("all");
players.addAll(Bukkit.getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toList()));
return players;
} else if (args.length == 3) {
} else if (args.length == 2) {
return Arrays.stream(EntityType.values())
.filter(types -> types.isSpawnable() && types.isAlive() && !types.toString().contains("ARMOR"))
.map(Enum::name).collect(Collectors.toList());
} else if (args.length == 4) {
} else if (args.length == 3) {
return Arrays.asList("1", "2", "3", "4", "5");
}
return null;

View File

@ -1,26 +1,29 @@
package com.songoda.ultimatestacker.command.commands;
package com.songoda.ultimatestacker.commands;
import com.songoda.core.commands.AbstractCommand;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.command.AbstractCommand;
import org.bukkit.command.CommandSender;
import java.util.List;
public class CommandReload extends AbstractCommand {
public CommandReload(AbstractCommand parent) {
super(parent, false, "reload");
UltimateStacker instance;
public CommandReload() {
super(false, "reload");
instance = UltimateStacker.getInstance();
}
@Override
protected ReturnType runCommand(UltimateStacker instance, CommandSender sender, String... args) {
instance.reload();
protected ReturnType runCommand(CommandSender sender, String... args) {
instance.reloadConfig();
instance.getLocale().getMessage("&7Configuration and Language files reloaded.").sendPrefixedMessage(sender);
return ReturnType.SUCCESS;
}
@Override
protected List<String> onTab(UltimateStacker instance, CommandSender sender, String... args) {
protected List<String> onTab(CommandSender sender, String... args) {
return null;
}
@ -38,4 +41,5 @@ public class CommandReload extends AbstractCommand {
public String getDescription() {
return "Reload the Configuration and Language files.";
}
}

View File

@ -1,7 +1,8 @@
package com.songoda.ultimatestacker.command.commands;
package com.songoda.ultimatestacker.commands;
import com.songoda.core.commands.AbstractCommand;
import com.songoda.core.utils.TextUtils;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.command.AbstractCommand;
import com.songoda.ultimatestacker.entity.EntityStackManager;
import com.songoda.ultimatestacker.utils.Methods;
import org.bukkit.Bukkit;
@ -9,9 +10,7 @@ import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.Arrays;
import java.util.Collections;
@ -19,17 +18,20 @@ import java.util.List;
public class CommandRemoveAll extends AbstractCommand {
public CommandRemoveAll(AbstractCommand parent) {
super(parent, false, "removeall");
UltimateStacker instance;
public CommandRemoveAll() {
super(false, "removeall");
instance = UltimateStacker.getInstance();
}
@Override
protected ReturnType runCommand(UltimateStacker instance, CommandSender sender, String... args) {
if (args.length < 2) return ReturnType.SYNTAX_ERROR;
protected ReturnType runCommand(CommandSender sender, String... args) {
if (args.length < 1) return ReturnType.SYNTAX_ERROR;
String type = args[1];
String type = args[0];
boolean all = args.length == 3;
boolean all = args.length == 2;
if (!type.equalsIgnoreCase("entities")
&& !type.equalsIgnoreCase("items")) {
@ -46,7 +48,7 @@ public class CommandRemoveAll extends AbstractCommand {
entityO.remove();
amountRemoved++;
} else if (entityO.getType() == EntityType.DROPPED_ITEM && type.equalsIgnoreCase("items")) {
if (entityO.isCustomNameVisible() && !entityO.getCustomName().contains(Methods.convertToInvisibleString("IS")) || all)
if (entityO.isCustomNameVisible() && !entityO.getCustomName().contains(TextUtils.convertToInvisibleString("IS")) || all)
continue;
entityO.remove();
amountRemoved++;
@ -58,18 +60,20 @@ public class CommandRemoveAll extends AbstractCommand {
if (type.equalsIgnoreCase("items") && amountRemoved == 1) type = "Item";
if (amountRemoved == 0) {
instance.getLocale().newMessage("&7No" + (all ? " " : " stacked ") + type + " exist that could be removed.").sendPrefixedMessage(sender);
instance.getLocale().newMessage("&7No" + (all ? " " : " stacked ")
+ type + " exist that could be removed.").sendPrefixedMessage(sender);
} else {
instance.getLocale().newMessage("&7Removed &6" + amountRemoved + (all ? " " : " stacked ") + Methods.formatText(type.toLowerCase(), true) + " &7Successfully.").sendPrefixedMessage(sender);
instance.getLocale().newMessage("&7Removed &6" + amountRemoved + (all ? " " : " stacked ")
+ Methods.formatText(type.toLowerCase(), true) + " &7Successfully.").sendPrefixedMessage(sender);
}
return ReturnType.SUCCESS;
}
@Override
protected List<String> onTab(UltimateStacker instance, CommandSender sender, String... args) {
if (args.length == 2)
protected List<String> onTab(CommandSender sender, String... args) {
if (args.length == 1)
return Arrays.asList("entities", "items");
else if (args.length == 3)
else if (args.length == 2)
return Collections.singletonList("all");
return null;
}
@ -88,4 +92,5 @@ public class CommandRemoveAll extends AbstractCommand {
public String getDescription() {
return "Remove all stacked entites or items from the world.";
}
}

View File

@ -1,7 +1,8 @@
package com.songoda.ultimatestacker.command.commands;
package com.songoda.ultimatestacker.commands;
import com.songoda.core.commands.AbstractCommand;
import com.songoda.core.configuration.editor.PluginConfigGui;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.command.AbstractCommand;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -9,18 +10,21 @@ import java.util.List;
public class CommandSettings extends AbstractCommand {
public CommandSettings(AbstractCommand parent) {
super(parent, true, "Settings");
UltimateStacker instance;
public CommandSettings() {
super(true, "Settings");
instance = UltimateStacker.getInstance();
}
@Override
protected ReturnType runCommand(UltimateStacker instance, CommandSender sender, String... args) {
instance.getSettingsManager().openSettingsManager((Player) sender);
protected ReturnType runCommand(CommandSender sender, String... args) {
instance.getGuiManager().showGUI((Player) sender, new PluginConfigGui(instance));
return ReturnType.SUCCESS;
}
@Override
protected List<String> onTab(UltimateStacker instance, CommandSender sender, String... args) {
protected List<String> onTab(CommandSender sender, String... args) {
return null;
}

View File

@ -1,7 +1,7 @@
package com.songoda.ultimatestacker.command.commands;
package com.songoda.ultimatestacker.commands;
import com.songoda.core.commands.AbstractCommand;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.command.AbstractCommand;
import com.songoda.ultimatestacker.utils.Methods;
import org.bukkit.command.CommandSender;
@ -9,17 +9,20 @@ import java.util.List;
public class CommandUltimateStacker extends AbstractCommand {
UltimateStacker instance;
public CommandUltimateStacker() {
super(null, false, "UltimateStacker");
super(false, "UltimateStacker");
instance = UltimateStacker.getInstance();
}
@Override
protected ReturnType runCommand(UltimateStacker instance, CommandSender sender, String... args) {
protected ReturnType runCommand(CommandSender sender, String... args) {
sender.sendMessage("");
instance.getLocale().newMessage("&7Version " + instance.getDescription().getVersion()
+ " Created with <3 by &5&l&oSongoda").sendPrefixedMessage(sender);
for (AbstractCommand command : instance.getCommandManager().getCommands()) {
for (AbstractCommand command : instance.getCommandManager().getAllCommands()) {
if (command.getPermissionNode() == null || sender.hasPermission(command.getPermissionNode())) {
sender.sendMessage(Methods.formatText("&8 - &a" + command.getSyntax() + "&7 - " + command.getDescription()));
}
@ -30,7 +33,7 @@ public class CommandUltimateStacker extends AbstractCommand {
}
@Override
protected List<String> onTab(UltimateStacker instance, CommandSender sender, String... args) {
protected List<String> onTab(CommandSender cs, String... strings) {
return null;
}

View File

@ -14,8 +14,8 @@ public class StackMobConvert implements Convert {
private final StackMob stackMob;
public StackMobConvert(UltimateStacker plugin) {
this.plugin = plugin;
public StackMobConvert() {
this.plugin = UltimateStacker.getInstance();
stackMob = (StackMob) Bukkit.getPluginManager().getPlugin("StackMob");
}

View File

@ -16,8 +16,8 @@ public class WildStackerConvert implements Convert {
private final UltimateStacker plugin;
public WildStackerConvert(UltimateStacker plugin) {
this.plugin = plugin;
public WildStackerConvert() {
this.plugin = UltimateStacker.getInstance();
}
@Override
@ -60,8 +60,7 @@ public class WildStackerConvert implements Convert {
stack.setAmount(WildStackerAPI
.getSpawnersAmount((CreatureSpawner) spawner.getLocation().getBlock().getState()));
if (plugin.getHologram() != null)
plugin.getHologram().add(stack);
plugin.updateHologram(stack);
}
}

View File

@ -1,32 +1,24 @@
package com.songoda.ultimatestacker.database;
import com.songoda.core.database.DataManagerAbstract;
import com.songoda.core.database.DatabaseConnector;
import com.songoda.ultimatestacker.spawner.SpawnerStack;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.plugin.Plugin;
import java.sql.*;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.plugin.Plugin;
public class DataManager {
private final DatabaseConnector databaseConnector;
private final Plugin plugin;
public class DataManager extends DataManagerAbstract {
public DataManager(DatabaseConnector databaseConnector, Plugin plugin) {
this.databaseConnector = databaseConnector;
this.plugin = plugin;
}
/**
* @return the prefix to be used by all table names
*/
public String getTablePrefix() {
return this.plugin.getDescription().getName().toLowerCase() + '_';
super(databaseConnector, plugin);
}
public void bulkUpdateSpawners(Collection<SpawnerStack> spawnerStacks) {
@ -44,7 +36,6 @@ public class DataManager {
});
}
public void updateSpawner(SpawnerStack spawnerStack) {
this.async(() -> this.databaseConnector.connect(connection -> {
String updateSpawner = "UPDATE " + this.getTablePrefix() + "spawners SET amount = ? WHERE id = ?";
@ -119,31 +110,4 @@ public class DataManager {
this.sync(() -> callback.accept(spawners));
}));
}
private int lastInsertedId(Connection connection) {
String query;
if (this.databaseConnector instanceof SQLiteConnector) {
query = "SELECT last_insert_rowid()";
} else {
query = "SELECT LAST_INSERT_ID()";
}
try (Statement statement = connection.createStatement()) {
ResultSet result = statement.executeQuery(query);
result.next();
return result.getInt(1);
} catch (SQLException e) {
e.printStackTrace();
return -1;
}
}
public void async(Runnable runnable) {
Bukkit.getScheduler().runTaskAsynchronously(this.plugin, runnable);
}
public void sync(Runnable runnable) {
Bukkit.getScheduler().runTask(this.plugin, runnable);
}
}

View File

@ -1,23 +0,0 @@
package com.songoda.ultimatestacker.database;
import java.sql.Connection;
import java.sql.SQLException;
public abstract class DataMigration {
private final int revision;
public DataMigration(int revision) {
this.revision = revision;
}
public abstract void migrate(Connection connection, String tablePrefix) throws SQLException;
/**
* @return the revision number of this migration
*/
public int getRevision() {
return this.revision;
}
}

View File

@ -1,108 +0,0 @@
package com.songoda.ultimatestacker.database;
import com.songoda.ultimatestacker.database.migrations._1_InitialMigration;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
public class DataMigrationManager {
private List<DataMigration> migrations;
private DatabaseConnector databaseConnector;
private DataManager dataManager;
public DataMigrationManager(DatabaseConnector databaseConnector, DataManager dataManager) {
this.databaseConnector = databaseConnector;
this.dataManager = dataManager;
this.migrations = Arrays.asList(
new _1_InitialMigration()
);
}
/**
* Runs any needed data migrations
*/
public void runMigrations() {
this.databaseConnector.connect((connection -> {
int currentMigration = -1;
boolean migrationsExist;
String query;
if (this.databaseConnector instanceof SQLiteConnector) {
query = "SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?";
} else {
query = "SHOW TABLES LIKE ?";
}
try (PreparedStatement statement = connection.prepareStatement(query)) {
statement.setString(1, this.getMigrationsTableName());
migrationsExist = statement.executeQuery().next();
}
if (!migrationsExist) {
// No migration table exists, create one
String createTable = "CREATE TABLE " + this.getMigrationsTableName() + " (migration_version INT NOT NULL)";
try (PreparedStatement statement = connection.prepareStatement(createTable)) {
statement.execute();
}
// Insert primary row into migration table
String insertRow = "INSERT INTO " + this.getMigrationsTableName() + " VALUES (?)";
try (PreparedStatement statement = connection.prepareStatement(insertRow)) {
statement.setInt(1, -1);
statement.execute();
}
} else {
// Grab the current migration version
String selectVersion = "SELECT migration_version FROM " + this.getMigrationsTableName();
try (PreparedStatement statement = connection.prepareStatement(selectVersion)) {
ResultSet result = statement.executeQuery();
result.next();
currentMigration = result.getInt("migration_version");
}
}
// Grab required migrations
int finalCurrentMigration = currentMigration;
List<DataMigration> requiredMigrations = this.migrations
.stream()
.filter(x -> x.getRevision() > finalCurrentMigration)
.sorted(Comparator.comparingInt(DataMigration::getRevision))
.collect(Collectors.toList());
// Nothing to migrate, abort
if (requiredMigrations.isEmpty())
return;
// Migrate the data
for (DataMigration dataMigration : requiredMigrations)
dataMigration.migrate(connection, this.dataManager.getTablePrefix());
// Set the new current migration to be the highest migrated to
currentMigration = requiredMigrations
.stream()
.map(DataMigration::getRevision)
.max(Integer::compareTo)
.orElse(-1);
String updateVersion = "UPDATE " + this.getMigrationsTableName() + " SET migration_version = ?";
try (PreparedStatement statement = connection.prepareStatement(updateVersion)) {
statement.setInt(1, currentMigration);
statement.execute();
}
}));
}
/**
* @return the name of the migrations table
*/
private String getMigrationsTableName() {
return this.dataManager.getTablePrefix() + "migrations";
}
}

View File

@ -1,34 +0,0 @@
package com.songoda.ultimatestacker.database;
import java.sql.Connection;
import java.sql.SQLException;
public interface DatabaseConnector {
/**
* Checks if the connection to the database has been created
*
* @return true if the connection is created, otherwise false
*/
boolean isInitialized();
/**
* Closes all open connections to the database
*/
void closeConnection();
/**
* Executes a callback with a Connection passed and automatically closes it when finished
*
* @param callback The callback to execute once the connection is retrieved
*/
void connect(ConnectionCallback callback);
/**
* Wraps a connection in a callback which will automagically handle catching sql errors
*/
interface ConnectionCallback {
void accept(Connection connection) throws SQLException;
}
}

View File

@ -1,50 +0,0 @@
package com.songoda.ultimatestacker.database;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.bukkit.plugin.Plugin;
import java.sql.Connection;
import java.sql.SQLException;
public class MySQLConnector implements DatabaseConnector {
private final Plugin plugin;
private HikariDataSource hikari;
private boolean initializedSuccessfully;
public MySQLConnector(Plugin plugin, String hostname, int port, String database, String username, String password, boolean useSSL) {
this.plugin = plugin;
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://" + hostname + ":" + port + "/" + database + "?useSSL=" + useSSL);
config.setUsername(username);
config.setPassword(password);
config.setMaximumPoolSize(3);
try {
this.hikari = new HikariDataSource(config);
this.initializedSuccessfully = true;
} catch (Exception ex) {
this.initializedSuccessfully = false;
}
}
public boolean isInitialized() {
return this.initializedSuccessfully;
}
public void closeConnection() {
this.hikari.close();
}
public void connect(ConnectionCallback callback) {
try (Connection connection = this.hikari.getConnection()) {
callback.accept(connection);
} catch (SQLException ex) {
this.plugin.getLogger().severe("An error occurred executing a MySQL query: " + ex.getMessage());
ex.printStackTrace();
}
}
}

View File

@ -1,58 +0,0 @@
package com.songoda.ultimatestacker.database;
import org.bukkit.plugin.Plugin;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class SQLiteConnector implements DatabaseConnector {
private final Plugin plugin;
private final String connectionString;
private Connection connection;
public SQLiteConnector(Plugin plugin) {
this.plugin = plugin;
this.connectionString = "jdbc:sqlite:" + plugin.getDataFolder() + File.separator + plugin.getDescription().getName().toLowerCase() + ".db";
try {
Class.forName("org.sqlite.JDBC"); // This is required to put here for Spigot 1.10 and below for some reason
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public boolean isInitialized() {
return true; // Always available
}
public void closeConnection() {
try {
if (this.connection != null) {
this.connection.close();
}
} catch (SQLException ex) {
this.plugin.getLogger().severe("An error occurred closing the SQLite database connection: " + ex.getMessage());
}
}
public void connect(ConnectionCallback callback) {
if (this.connection == null) {
try {
this.connection = DriverManager.getConnection(this.connectionString);
} catch (SQLException ex) {
this.plugin.getLogger().severe("An error occurred retrieving the SQLite database connection: " + ex.getMessage());
}
}
try {
callback.accept(this.connection);
} catch (Exception ex) {
this.plugin.getLogger().severe("An error occurred executing an SQLite query: " + ex.getMessage());
ex.printStackTrace();
}
}
}

View File

@ -1,7 +1,7 @@
package com.songoda.ultimatestacker.database.migrations;
import com.songoda.core.database.DataMigration;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.database.DataMigration;
import com.songoda.ultimatestacker.database.MySQLConnector;
import java.sql.Connection;

View File

@ -1,14 +1,14 @@
package com.songoda.ultimatestacker.entity;
import com.songoda.core.compatibility.LegacyMaterials;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.lootables.loot.Drop;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.utils.DropUtils;
import com.songoda.ultimatestacker.utils.Methods;
import com.songoda.ultimatestacker.utils.ServerVersion;
import com.songoda.ultimatestacker.utils.settings.Setting;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
@ -94,7 +94,7 @@ public class EntityStack {
}
private LivingEntity getEntityByUniqueId(UUID uniqueId) {
if (UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_12))
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_12))
return (LivingEntity) Bukkit.getEntity(uniqueId);
for (World world : Bukkit.getWorlds()) {
@ -140,8 +140,7 @@ public class EntityStack {
newEntity.getEquipment().clear();
if (killed.getType() == EntityType.PIG_ZOMBIE)
newEntity.getEquipment().setItemInHand(new ItemStack(plugin.isServerVersionAtLeast(ServerVersion.V1_13)
? Material.GOLDEN_SWORD : Material.valueOf("GOLD_SWORD")));
newEntity.getEquipment().setItemInHand(LegacyMaterials.GOLDEN_SWORD.getItem());
if (Setting.CARRY_OVER_METADATA_ON_DEATH.getBoolean()) {
if (killed.hasMetadata("ES"))
@ -171,7 +170,7 @@ public class EntityStack {
killed.setCustomName(Methods.formatText("&7"));
boolean killWholeStack = Setting.KILL_WHOLE_STACK_ON_DEATH.getBoolean()
|| plugin.getMobFile().getConfig().getBoolean("Mobs." + killed.getType().name() + ".Kill Whole Stack");
|| plugin.getMobFile().getBoolean("Mobs." + killed.getType().name() + ".Kill Whole Stack");
if (killWholeStack && getAmount() != 1) {
handleWholeStackDeath(killed, drops, custom, droppedExp);

View File

@ -1,50 +1,29 @@
package com.songoda.ultimatestacker.gui;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.core.compatibility.LegacyMaterials;
import com.songoda.core.gui.Gui;
import com.songoda.core.gui.GuiUtils;
import com.songoda.ultimatestacker.convert.StackMobConvert;
import com.songoda.ultimatestacker.convert.WildStackerConvert;
import com.songoda.ultimatestacker.utils.gui.AbstractGUI;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.ChatColor;
public class GUIConvert extends AbstractGUI {
public class GUIConvert extends Gui {
private final UltimateStacker plugin;
public GUIConvert(UltimateStacker plugin, Player player) {
super(player);
this.plugin = plugin;
init("Convert", 9);
}
@Override
public void constructGUI() {
public GUIConvert() {
setTitle("Convert");
setRows(1);
int current = 0;
if (Bukkit.getPluginManager().isPluginEnabled("WildStacker")) {
createButton(current, Material.STONE, "&6WildStacker");
registerClickable(current, ((player1, inventory1, cursor, slot, type) ->
new GUIConvertWhat(plugin, player, new WildStackerConvert(plugin))));
current ++;
this.setButton(current++, GuiUtils.createButtonItem(LegacyMaterials.STONE, ChatColor.GRAY + "WildStacker"),
(event) -> event.manager.showGUI(event.player, new GUIConvertWhat(new WildStackerConvert(), this)));
}
if (Bukkit.getPluginManager().isPluginEnabled("StackMob")) {
createButton(current, Material.STONE, "&6StackMob");
registerClickable(current, ((player1, inventory1, cursor, slot, type) ->
new GUIConvertWhat(plugin, player, new StackMobConvert(plugin))));
this.setButton(current++, GuiUtils.createButtonItem(LegacyMaterials.STONE, ChatColor.GRAY + "StackMob"),
(event) -> event.manager.showGUI(event.player, new GUIConvertWhat(new StackMobConvert(), this)));
}
}
@Override
protected void registerClickables() {
}
@Override
protected void registerOnCloses() {
}
}

View File

@ -1,75 +1,65 @@
package com.songoda.ultimatestacker.gui;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.core.compatibility.LegacyMaterials;
import com.songoda.core.gui.Gui;
import com.songoda.core.gui.GuiUtils;
import com.songoda.ultimatestacker.convert.Convert;
import com.songoda.ultimatestacker.utils.Methods;
import com.songoda.ultimatestacker.utils.gui.AbstractGUI;
import org.bukkit.Material;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
public class GUIConvertWhat extends AbstractGUI {
private final UltimateStacker plugin;
public class GUIConvertWhat extends Gui {
private Convert convertFrom = null;
private boolean entities = true;
private boolean spawners = true;
public GUIConvertWhat(UltimateStacker plugin, Player player, Convert convertFrom) {
super(player);
this.plugin = plugin;
public GUIConvertWhat(Convert convertFrom, Gui returnTo) {
super(returnTo);
this.setRows(1);
this.setTitle("What Do You Want To Convert?");
this.convertFrom = convertFrom;
init("What Do You Want To Convert?", 9);
}
@Override
public void constructGUI() {
inventory.clear();
if (convertFrom.canEntities())
createButton(0, Material.STONE, "&7Stacked Entities", entities ? "&aYes" : "&cNo");
if (convertFrom.canSpawners())
createButton(1, Material.STONE, "&7Stacked Spawners", spawners ? "&aYes" : "&cNo");
createButton(8, Material.STONE, "&aRun");
}
@Override
protected void registerClickables() {
if (convertFrom.canSpawners()) {
registerClickable(0, ((player1, inventory1, cursor, slot, type) -> {
entities = !entities;
constructGUI();
}));
if (convertFrom.canEntities()) {
this.setButton(0, GuiUtils.createButtonItem(LegacyMaterials.STONE,
ChatColor.GRAY + "Stacked Entities",
entities ? ChatColor.GREEN + "Yes" : ChatColor.RED + "No"),
(event) -> toggleEntities());
}
if (convertFrom.canSpawners()) {
registerClickable(1, ((player1, inventory1, cursor, slot, type) -> {
spawners = !spawners;
constructGUI();
}));
this.setButton(1, GuiUtils.createButtonItem(LegacyMaterials.STONE,
ChatColor.GRAY + "Stacked Spawners",
spawners ? ChatColor.GREEN + "Yes" : ChatColor.RED + "No"),
(event) -> toggleSpawners());
}
registerClickable(8, ((player1, inventory1, cursor, slot, type) -> {
if (entities)
convertFrom.convertEntities();
if (spawners)
convertFrom.convertSpawners();
convertFrom.disablePlugin();
player.closeInventory();
player.sendMessage(Methods.formatText("&7Data converted successfully. Remove &6" + convertFrom.getName() + " &7and restart your server to continue."));
}));
this.setButton(8, GuiUtils.createButtonItem(LegacyMaterials.GREEN_WOOL, ChatColor.GREEN + "Run"),
(event) -> run(event.player));
}
@Override
protected void registerOnCloses() {
void toggleEntities() {
entities = !entities;
this.updateItem(0, ChatColor.GRAY + "Stacked Entities", entities ? ChatColor.GREEN + "Yes" : ChatColor.RED + "No");
}
void toggleSpawners() {
spawners = !spawners;
this.updateItem(1, ChatColor.GRAY + "Stacked Spawners", spawners ? ChatColor.GREEN + "Yes" : ChatColor.RED + "No");
}
void run(Player player) {
if (entities) {
convertFrom.convertEntities();
}
if (spawners) {
convertFrom.convertSpawners();
}
convertFrom.disablePlugin();
exit();
player.sendMessage(Methods.formatText("&7Data converted successfully. Remove &6" + convertFrom.getName() + " &7and restart your server to continue."));
}
}

View File

@ -1,80 +0,0 @@
package com.songoda.ultimatestacker.hologram;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.spawner.SpawnerStack;
import com.songoda.ultimatestacker.utils.Methods;
import com.songoda.ultimatestacker.utils.ServerVersion;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.CreatureSpawner;
import java.util.Collection;
public abstract class Hologram {
protected final UltimateStacker instance;
Hologram(UltimateStacker instance) {
this.instance = instance;
}
public void loadHolograms() {
Collection<SpawnerStack> spawners = instance.getSpawnerStackManager().getStacks();
if (spawners.size() == 0) return;
for (SpawnerStack spawner : spawners) {
if (spawner.getLocation().getWorld() == null) continue;
add(spawner);
}
}
public void unloadHolograms() {
Collection<SpawnerStack> spawners = instance.getSpawnerStackManager().getStacks();
if (spawners.size() == 0) return;
for (SpawnerStack spawner : spawners) {
if (spawner.getLocation().getWorld() == null) continue;
remove(spawner);
}
}
public void add(SpawnerStack spawner) {
int amount = spawner.getAmount();
if (spawner.getLocation().getBlock().getType() != (instance.isServerVersionAtLeast(ServerVersion.V1_13) ? Material.SPAWNER : Material.valueOf("MOB_SPAWNER"))) return;
CreatureSpawner creatureSpawner = (CreatureSpawner) spawner.getLocation().getBlock().getState();
String name = Methods.compileSpawnerName(creatureSpawner.getSpawnedType(), amount);
add(spawner.getLocation(), name);
}
public void remove(SpawnerStack spawner) {
remove(spawner.getLocation());
}
public void update(SpawnerStack spawner) {
int amount = spawner.getAmount();
if (spawner.getLocation().getBlock().getType() != (instance.isServerVersionAtLeast(ServerVersion.V1_13) ? Material.SPAWNER : Material.valueOf("MOB_SPAWNER"))) return;
CreatureSpawner creatureSpawner = (CreatureSpawner) spawner.getLocation().getBlock().getState();
String name = Methods.compileSpawnerName(creatureSpawner.getSpawnedType(), amount);
update(spawner.getLocation(), name);
}
protected abstract void add(Location location, String line);
protected abstract void remove(Location location);
protected abstract void update(Location location, String line);
public void processChange(Block block) {
if (block.getType() != (instance.isServerVersionAtLeast(ServerVersion.V1_13) ? Material.SPAWNER : Material.valueOf("MOB_SPAWNER"))) return;
SpawnerStack spawner = instance.getSpawnerStackManager().getSpawner(block);
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(instance, () ->
update(spawner), 1L);
}
}

View File

@ -1,47 +0,0 @@
package com.songoda.ultimatestacker.hologram;
import com.gmail.filoghost.holographicdisplays.api.HologramsAPI;
import com.songoda.ultimatestacker.UltimateStacker;
import org.bukkit.Location;
public class HologramHolographicDisplays extends Hologram {
public HologramHolographicDisplays(UltimateStacker instance) {
super(instance);
}
@Override
public void add(Location location, String line) {
fixLocation(location);
com.gmail.filoghost.holographicdisplays.api.Hologram hologram = HologramsAPI.createHologram(instance, location);
hologram.appendTextLine(line);
}
@Override
public void remove(Location location) {
fixLocation(location);
for (com.gmail.filoghost.holographicdisplays.api.Hologram hologram : HologramsAPI.getHolograms(instance)) {
if (hologram.getX() != location.getX()
|| hologram.getY() != location.getY()
|| hologram.getZ() != location.getZ()) continue;
hologram.delete();
}
}
@Override
public void update(Location location, String line) {
fixLocation(location);
for (com.gmail.filoghost.holographicdisplays.api.Hologram hologram : HologramsAPI.getHolograms(instance)) {
if (hologram.getX() != location.getX()
|| hologram.getY() != location.getY()
|| hologram.getZ() != location.getZ()) continue;
hologram.clearLines();
hologram.appendTextLine(line);
}
}
private void fixLocation(Location location) {
location.add(0.5, 1.52, 0.5);
}
}

View File

@ -1,11 +1,11 @@
package com.songoda.ultimatestacker.listeners;
import com.songoda.core.compatibility.LegacyMaterials;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.events.SpawnerBreakEvent;
import com.songoda.ultimatestacker.events.SpawnerPlaceEvent;
import com.songoda.ultimatestacker.spawner.SpawnerStack;
import com.songoda.ultimatestacker.utils.Methods;
import com.songoda.ultimatestacker.utils.ServerVersion;
import com.songoda.ultimatestacker.utils.settings.Setting;
import org.apache.commons.lang.math.NumberUtils;
import org.bukkit.Bukkit;
@ -42,8 +42,8 @@ public class BlockListeners implements Listener {
ItemStack item = event.getPlayer().getInventory().getItemInHand();
if (block == null
|| block.getType() != (plugin.isServerVersionAtLeast(ServerVersion.V1_13) ? Material.SPAWNER : Material.valueOf("MOB_SPAWNER"))
|| item.getType() != (plugin.isServerVersionAtLeast(ServerVersion.V1_13) ? Material.SPAWNER : Material.valueOf("MOB_SPAWNER"))
|| block.getType() != LegacyMaterials.SPAWNER.getMaterial()
|| item.getType() != LegacyMaterials.SPAWNER.getMaterial()
|| event.getAction() == Action.LEFT_CLICK_BLOCK) return;
List<String> disabledWorlds = Setting.DISABLED_WORLDS.getStringList();
@ -57,7 +57,7 @@ public class BlockListeners implements Listener {
EntityType itemType = cs.getSpawnedType();
int itemAmount = getSpawnerAmount(item);
int specific = plugin.getSpawnerFile().getConfig().getInt("Spawners." + cs.getSpawnedType().name() + ".Max Stack Size");
int specific = plugin.getSpawnerFile().getInt("Spawners." + cs.getSpawnedType().name() + ".Max Stack Size");
int maxStackSize = specific == -1 ? Setting.MAX_STACK_SPAWNERS.getInt() : specific;
cs = (CreatureSpawner) block.getState();
@ -93,15 +93,12 @@ public class BlockListeners implements Listener {
}
stack.setAmount(stack.getAmount() + itemAmount);
if (plugin.getHologram() != null) {
plugin.getHologram().update(stack);
}
plugin.updateHologram(stack);
Methods.takeItem(player, itemAmount);
}
}
if (plugin.getHologram() != null)
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> plugin.getHologram().processChange(block), 10L);
plugin.updateHologram(block);
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
@ -110,7 +107,7 @@ public class BlockListeners implements Listener {
Player player = event.getPlayer();
if (!event.isCancelled()) {
if (block.getType() != (plugin.isServerVersionAtLeast(ServerVersion.V1_13) ? Material.SPAWNER : Material.valueOf("MOB_SPAWNER"))
if (block.getType() != LegacyMaterials.SPAWNER.getMaterial()
|| !plugin.spawnersEnabled())
return;
@ -131,18 +128,16 @@ public class BlockListeners implements Listener {
cs.setSpawnedType(cs2.getSpawnedType());
cs.update();
if (plugin.getHologram() != null)
plugin.getHologram().add(stack);
plugin.updateHologram(stack);
}
if (plugin.getHologram() != null)
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> plugin.getHologram().processChange(block), 1L);
plugin.updateHologram(block);
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBlockBreak(BlockBreakEvent event) {
Block block = event.getBlock();
if (block.getType() != (plugin.isServerVersionAtLeast(ServerVersion.V1_13) ? Material.SPAWNER : Material.valueOf("MOB_SPAWNER"))) return;
if (block.getType() != LegacyMaterials.SPAWNER.getMaterial()) return;
if (!plugin.spawnersEnabled()) return;
event.setExpToDrop(0);
@ -175,14 +170,12 @@ public class BlockListeners implements Listener {
if (remove) {
event.setCancelled(false);
if (plugin.getHologram() != null)
plugin.getHologram().remove(stack);
plugin.clearHologram(stack);
SpawnerStack spawnerStack = plugin.getSpawnerStackManager().removeSpawner(block.getLocation());
plugin.getDataManager().deleteSpawner(spawnerStack);
} else {
stack.setAmount(stack.getAmount() - 1);
if (plugin.getHologram() != null)
plugin.getHologram().update(stack);
plugin.updateHologram(stack);
}
if (player.hasPermission("ultimatestacker.spawner.nosilkdrop") || item != null && item.getEnchantments().containsKey(Enchantment.SILK_TOUCH) && player.hasPermission("ultimatestacker.spawner.silktouch"))

View File

@ -1,18 +1,25 @@
package com.songoda.ultimatestacker.listeners;
import com.songoda.core.compatibility.LegacyMaterials;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.entity.EntityStack;
import com.songoda.ultimatestacker.entity.EntityStackManager;
import com.songoda.ultimatestacker.spawner.SpawnerStack;
import com.songoda.ultimatestacker.utils.Methods;
import com.songoda.ultimatestacker.utils.ServerVersion;
import com.songoda.ultimatestacker.utils.settings.Setting;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.CreatureSpawner;
import org.bukkit.entity.*;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
@ -22,10 +29,6 @@ import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class EntityListeners implements Listener {
private final UltimateStacker plugin;
@ -80,7 +83,7 @@ public class EntityListeners implements Listener {
List<Block> toCancel = new ArrayList<>();
while (it.hasNext()) {
Block block = it.next();
if (block.getType() != (plugin.isServerVersionAtLeast(ServerVersion.V1_13) ? Material.SPAWNER : Material.valueOf("MOB_SPAWNER")))
if (block.getType() != LegacyMaterials.SPAWNER.getMaterial())
continue;
Location spawnLocation = block.getLocation();
@ -105,8 +108,7 @@ public class EntityListeners implements Listener {
SpawnerStack spawnerStack = plugin.getSpawnerStackManager().removeSpawner(spawnLocation);
plugin.getDataManager().deleteSpawner(spawnerStack);
if (plugin.getHologram() != null)
plugin.getHologram().remove(spawner);
plugin.updateHologram(spawner);
}
}

View File

@ -1,14 +1,20 @@
package com.songoda.ultimatestacker.listeners;
import com.songoda.core.compatibility.LegacyMaterials;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.entity.EntityStack;
import com.songoda.ultimatestacker.entity.Split;
import com.songoda.ultimatestacker.utils.Methods;
import com.songoda.ultimatestacker.utils.ServerVersion;
import com.songoda.ultimatestacker.utils.settings.Setting;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.*;
import org.bukkit.entity.Ageable;
import org.bukkit.entity.Cat;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Horse;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Wolf;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
@ -69,44 +75,43 @@ public class InteractListeners implements Listener {
}
private boolean correctFood(ItemStack is, Entity entity) {
boolean is13 = plugin.isServerVersionAtLeast(ServerVersion.V1_13);
Material type = is.getType();
switch (entity.getType().name()) {
case "COW":
case "SHEEP":
return type == Material.WHEAT;
case "PIG":
return type == Material.CARROT || (plugin.isServerVersionAtLeast(ServerVersion.V1_9) && type == Material.BEETROOT) || type == Material.POTATO;
return type == Material.CARROT || (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_9) && type == Material.BEETROOT) || type == Material.POTATO;
case "CHICKEN":
return type == (is13 ? Material.WHEAT_SEEDS : Material.valueOf("SEEDS"))
return type == LegacyMaterials.WHEAT_SEEDS.getMaterial()
|| type == Material.MELON_SEEDS
|| type == Material.BEETROOT_SEEDS
|| type == Material.PUMPKIN_SEEDS;
case "HORSE":
return (type == Material.GOLDEN_APPLE || type == Material.GOLDEN_CARROT) && ((Horse)entity).isTamed();
case "WOLF":
return type == (is13 ? Material.BEEF : Material.valueOf("RAW_BEEF"))
|| type == (is13 ? Material.CHICKEN : Material.valueOf("RAW_CHICKEN"))
|| (is13 && type == Material.COD)
|| type == Material.MUTTON
|| type == (is13 ? Material.PORKCHOP : Material.valueOf("PORK"))
|| type == Material.RABBIT
|| (is13 && type == Material.SALMON)
|| type == Material.COOKED_BEEF
|| type == Material.COOKED_CHICKEN
|| (is13 && type == Material.COOKED_COD)
|| type == Material.COOKED_MUTTON
|| type == (is13 ? Material.COOKED_PORKCHOP : Material.valueOf("GRILLED_PORK"))
|| type == Material.COOKED_RABBIT
|| (is13 && type == Material.COOKED_SALMON)
return type == LegacyMaterials.BEEF.getMaterial()
|| type == LegacyMaterials.CHICKEN.getMaterial()
|| type == LegacyMaterials.COD.getMaterial()
|| type == LegacyMaterials.MUTTON.getMaterial()
|| type == LegacyMaterials.PORKCHOP.getMaterial()
|| type == LegacyMaterials.RABBIT.getMaterial()
|| LegacyMaterials.SALMON.matches(is)
|| type == LegacyMaterials.COOKED_BEEF.getMaterial()
|| type == LegacyMaterials.COOKED_CHICKEN.getMaterial()
|| type == LegacyMaterials.COOKED_COD.getMaterial()
|| type == LegacyMaterials.COOKED_MUTTON.getMaterial()
|| type == LegacyMaterials.COOKED_PORKCHOP.getMaterial()
|| type == LegacyMaterials.COOKED_RABBIT.getMaterial()
|| LegacyMaterials.COOKED_SALMON.matches(is)
&& ((Wolf) entity).isTamed();
case "OCELOT":
return (is13 ? type == Material.SALMON
return (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)
? type == Material.SALMON
|| type == Material.COD
|| type == Material.PUFFERFISH
|| type == Material.TROPICAL_FISH
: type == Material.valueOf("RAW_FISH")); // Now broken in 1.13 ((Ocelot) entity).isTamed()
: type == LegacyMaterials.COD.getMaterial()); // Now broken in 1.13 ((Ocelot) entity).isTamed()
case "PANDA":
return (type == Material.BAMBOO);
case "FOX":

View File

@ -1,13 +1,13 @@
package com.songoda.ultimatestacker.listeners;
import com.songoda.core.compatibility.CompatibleSounds;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.core.utils.BlockUtils;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.utils.Methods;
import com.songoda.ultimatestacker.utils.ServerVersion;
import com.songoda.ultimatestacker.utils.settings.Setting;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.Sound;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Item;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@ -18,9 +18,6 @@ import org.bukkit.event.inventory.InventoryPickupItemEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.inventory.ItemStack;
import java.util.List;
import org.bukkit.block.BlockState;
public class ItemListeners implements Listener {
private final UltimateStacker instance;
@ -39,13 +36,13 @@ public class ItemListeners implements Listener {
event.setCancelled(true);
int specific = instance.getItemFile().getConfig().getInt("Items." + itemStack.getType().name() + ".Max Stack Size");
int specific = instance.getItemFile().getInt("Items." + itemStack.getType().name() + ".Max Stack Size");
int max = specific == -1 && new ItemStack(itemStack.getType()).getMaxStackSize() != 1 ? maxItemStackSize : specific;
if (instance.isServerVersionAtLeast(ServerVersion.V1_13) && Methods.isMaterialBlacklisted(itemStack.getType()))
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13) && Methods.isMaterialBlacklisted(itemStack.getType()))
max = new ItemStack(itemStack.getType()).getMaxStackSize();
if (!instance.isServerVersionAtLeast(ServerVersion.V1_13) && Methods.isMaterialBlacklisted(itemStack.getType(), itemStack.getData().getData()))
if (!ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13) && Methods.isMaterialBlacklisted(itemStack.getType(), itemStack.getData().getData()))
max = new ItemStack(itemStack.getType()).getMaxStackSize();
if (max == -1) max = 1;
@ -66,7 +63,7 @@ public class ItemListeners implements Listener {
Methods.updateInventory(event.getItem(), event.getInventory());
if (event.getInventory().getHolder() instanceof BlockState)
Methods.updateAdjacentComparators(((BlockState)event.getInventory().getHolder()).getLocation());
BlockUtils.updateAdjacentComparators(((BlockState)event.getInventory().getHolder()).getLocation());
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
@ -89,9 +86,7 @@ public class ItemListeners implements Listener {
if (event.getItem().getItemStack().getAmount() < 32) return;
event.setCancelled(true);
event.getPlayer().playSound(event.getPlayer().getLocation(),
instance.isServerVersionAtLeast(ServerVersion.V1_9) ? Sound.ENTITY_ITEM_PICKUP
: Sound.valueOf("ITEM_PICKUP"), .2f, (float) (1 + Math.random()));
event.getPlayer().playSound(event.getPlayer().getLocation(), CompatibleSounds.ENTITY_ITEM_PICKUP.getSound(), .2f, (float) (1 + Math.random()));
Methods.updateInventory(event.getItem(), event.getPlayer().getInventory());
}

View File

@ -1,14 +1,13 @@
package com.songoda.ultimatestacker.listeners;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.entity.EntityStack;
import com.songoda.ultimatestacker.spawner.SpawnerStack;
import com.songoda.ultimatestacker.spawner.SpawnerStackManager;
import com.songoda.ultimatestacker.utils.Methods;
import com.songoda.ultimatestacker.utils.Reflection;
import com.songoda.ultimatestacker.utils.ServerVersion;
import com.songoda.ultimatestacker.utils.settings.Setting;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.block.Block;
@ -62,8 +61,8 @@ public class SpawnerListeners implements Listener {
if (block == null || itemType == Material.AIR) return;
if (block.getType() != (plugin.isServerVersionAtLeast(ServerVersion.V1_13) ? Material.SPAWNER : Material.valueOf("MOB_SPAWNER"))
|| !itemType.toString().contains(plugin.isServerVersionAtLeast(ServerVersion.V1_13) ? "SPAWN_EGG" : "MONSTER_EGG"))
if (block.getType() != (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13) ? Material.SPAWNER : Material.valueOf("MOB_SPAWNER"))
|| !itemType.toString().contains(ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13) ? "SPAWN_EGG" : "MONSTER_EGG"))
return;
event.setCancelled(true);
@ -82,9 +81,9 @@ public class SpawnerListeners implements Listener {
int amt = player.getInventory().getItemInHand().getAmount();
EntityType entityType;
if (plugin.isServerVersionAtLeast(ServerVersion.V1_13))
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13))
entityType = EntityType.valueOf(itemType.name().replace("_SPAWN_EGG", "").replace("MOOSHROOM", "MUSHROOM_COW"));
else if (plugin.isServerVersionAtLeast(ServerVersion.V1_12)) {
else if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_12)) {
String str = Reflection.getNBTTagCompound(Reflection.getNMSItemStack(event.getItem())).toString();
if (str.contains("minecraft:"))
entityType = EntityType.fromName(str.substring(str.indexOf("minecraft:") + 10, str.indexOf("\"}")));
@ -117,8 +116,7 @@ public class SpawnerListeners implements Listener {
creatureSpawner.setSpawnedType(entityType);
creatureSpawner.update();
if (plugin.getHologram() != null)
plugin.getHologram().update(spawner);
plugin.updateHologram(spawner);
if (player.getGameMode() != GameMode.CREATIVE) {
Methods.takeItem(player, stackSize - 1);
}

View File

@ -1,10 +1,11 @@
package com.songoda.ultimatestacker.lootables;
import com.songoda.core.compatibility.LegacyMaterials;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.lootables.Lootables;
import com.songoda.lootables.Modify;
import com.songoda.lootables.loot.*;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.utils.ServerVersion;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.*;
@ -90,7 +91,7 @@ public class LootablesManager {
public void createDefaultLootables() {
UltimateStacker plugin = UltimateStacker.getInstance();
if (plugin.isServerVersionAtLeast(ServerVersion.V1_14)) {
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_14)) {
// Add Trader Llama.
lootManager.addLootable(new Lootable("TRADER_LLAMA",
new LootBuilder()
@ -123,7 +124,7 @@ public class LootablesManager {
.setMax(2).build()));
}
if (plugin.isServerVersionAtLeast(ServerVersion.V1_13)) {
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)) {
// Add Phantom.
@ -201,7 +202,7 @@ public class LootablesManager {
.addOnlyDropFors(EntityType.PLAYER).build()));
}
if (plugin.isServerVersionAtLeast(ServerVersion.V1_12)) {
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_12)) {
// Add Parrot.
lootManager.addLootable(new Lootable("PARROT",
new LootBuilder()
@ -211,7 +212,7 @@ public class LootablesManager {
}
Loot fish1 = plugin.isServerVersionAtLeast(ServerVersion.V1_13) ? new LootBuilder()
Loot fish1 = ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13) ? new LootBuilder()
.addChildLoot(new LootBuilder()
.setMaterial(Material.COD)
.setBurnedMaterial(Material.COOKED_COD)
@ -231,7 +232,7 @@ public class LootablesManager {
.setChance(33).build())
.build();
Loot fish2 = plugin.isServerVersionAtLeast(ServerVersion.V1_13) ? new LootBuilder()
Loot fish2 = ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13) ? new LootBuilder()
.setChance(2.5)
.addChildLoot(new LootBuilder()
.setMaterial(Material.COD)
@ -274,7 +275,7 @@ public class LootablesManager {
.setAllowLootingEnchant(false).build())
.addOnlyDropFors(EntityType.PLAYER).build();
if (plugin.isServerVersionAtLeast(ServerVersion.V1_11)) {
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_11)) {
// Add Zombie Villager.
lootManager.addLootable(new Lootable("ZOMBIE_VILLAGER",
new LootBuilder()
@ -337,7 +338,7 @@ public class LootablesManager {
.setMin(0)
.setMax(2).build()));
Loot witherSkull = plugin.isServerVersionAtLeast(ServerVersion.V1_13) ?
Loot witherSkull = ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13) ?
new LootBuilder()
.setMaterial(Material.WITHER_SKELETON_SKULL)
.setChance(2.5)
@ -383,8 +384,7 @@ public class LootablesManager {
// Add Evoker.
lootManager.addLootable(new Lootable("EVOKER",
new LootBuilder()
.setMaterial(plugin.isServerVersionAtLeast(ServerVersion.V1_13)
? Material.TOTEM_OF_UNDYING : Material.valueOf("TOTEM"))
.setMaterial(LegacyMaterials.TOTEM_OF_UNDYING.getMaterial())
.setAllowLootingEnchant(false).build(),
new LootBuilder()
.setMaterial(Material.EMERALD)
@ -392,7 +392,7 @@ public class LootablesManager {
.addOnlyDropFors(EntityType.PLAYER).build()));
}
if (plugin.isServerVersionAtLeast(ServerVersion.V1_11)) {
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_11)) {
// Shulker.
@ -403,7 +403,7 @@ public class LootablesManager {
.setLootingIncrease(6.25).build()));
}
if (plugin.isServerVersionAtLeast(ServerVersion.V1_13)) {
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)) {
// Add Polar Bear.
lootManager.addLootable(new Lootable("POLAR_BEAR",
new LootBuilder()
@ -416,17 +416,17 @@ public class LootablesManager {
.setChance(25)
.setMin(0)
.setMax(2).build()));
} else if (plugin.isServerVersionAtLeast(ServerVersion.V1_10)) {
} else if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_10)) {
// Add Polar Bear.
lootManager.addLootable(new Lootable("POLAR_BEAR",
new LootBuilder()
.setMaterial(Material.valueOf("RAW_FISH"))
.setMaterial(LegacyMaterials.COD.getMaterial())
.setChance(75)
.setMin(0)
.setMax(2).build(),
new LootBuilder()
.setMaterial(Material.valueOf("RAW_FISH"))
.setData(1)
.setMaterial(LegacyMaterials.COD.getMaterial())
.setData(LegacyMaterials.COD.getData())
.setChance(25)
.setMin(0)
.setMax(2).build()));
@ -435,10 +435,8 @@ public class LootablesManager {
// Add Pig.
lootManager.addLootable(new Lootable("PIG",
new LootBuilder()
.setMaterial(plugin.isServerVersionAtLeast(ServerVersion.V1_13)
? Material.PORKCHOP : Material.valueOf("PORK"))
.setBurnedMaterial(plugin.isServerVersionAtLeast(ServerVersion.V1_13)
? Material.COOKED_PORKCHOP : Material.valueOf("GRILLED_PORK"))
.setMaterial(LegacyMaterials.PORKCHOP.getMaterial())
.setBurnedMaterial(LegacyMaterials.COOKED_PORKCHOP.getMaterial())
.setMin(1)
.setMax(3).build()));
@ -450,9 +448,8 @@ public class LootablesManager {
.setMin(0)
.setMax(2).build(),
new LootBuilder()
.setMaterial(plugin.isServerVersionAtLeast(ServerVersion.V1_13)
? Material.BEEF : Material.valueOf("RAW_BEEF"))
.setBurnedMaterial(Material.COOKED_BEEF)
.setMaterial(LegacyMaterials.BEEF.getMaterial())
.setBurnedMaterial(LegacyMaterials.COOKED_BEEF.getMaterial())
.setMin(1)
.setMax(3).build()));
@ -463,9 +460,8 @@ public class LootablesManager {
.setMin(0)
.setMax(2).build(),
new LootBuilder()
.setMaterial(plugin.isServerVersionAtLeast(ServerVersion.V1_13)
? Material.BEEF : Material.valueOf("RAW_BEEF"))
.setBurnedMaterial(Material.COOKED_BEEF)
.setMaterial(LegacyMaterials.BEEF.getMaterial())
.setBurnedMaterial(LegacyMaterials.COOKED_BEEF.getMaterial())
.setMin(1)
.setMax(3).build()));
@ -476,9 +472,8 @@ public class LootablesManager {
.setMin(0)
.setMax(2).build(),
new LootBuilder()
.setMaterial(plugin.isServerVersionAtLeast(ServerVersion.V1_13)
? Material.CHICKEN : Material.valueOf("RAW_CHICKEN"))
.setBurnedMaterial(Material.COOKED_CHICKEN).build()));
.setMaterial(LegacyMaterials.CHICKEN.getMaterial())
.setBurnedMaterial(LegacyMaterials.COOKED_CHICKEN.getMaterial()).build()));
// Add Zombie.
lootManager.addLootable(new Lootable("ZOMBIE",
new LootBuilder()
@ -518,7 +513,7 @@ public class LootablesManager {
.build()));
Loot discs;
if (plugin.isServerVersionAtLeast(ServerVersion.V1_13)) {
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)) {
discs = new LootBuilder()
.setChildDropCount(1)
.addOnlyDropFors(EntityType.SKELETON,
@ -536,7 +531,7 @@ public class LootablesManager {
new LootBuilder().setMaterial(Material.MUSIC_DISC_WAIT).build(),
new LootBuilder().setMaterial(Material.MUSIC_DISC_WARD).build())
.build();
} else if (plugin.isServerVersionAtLeast(ServerVersion.V1_11)) {
} else if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_11)) {
discs = new LootBuilder()
.setChildDropCount(1)
.addOnlyDropFors(EntityType.SKELETON,
@ -576,8 +571,7 @@ public class LootablesManager {
// Add Creeper.
lootManager.addLootable(new Lootable("CREEPER",
new LootBuilder()
.setMaterial(plugin.isServerVersionAtLeast(ServerVersion.V1_13)
? Material.GUNPOWDER : Material.valueOf("SULPHUR"))
.setMaterial(LegacyMaterials.GUNPOWDER.getMaterial())
.setMin(0)
.setMax(2).build(),
discs));
@ -622,8 +616,7 @@ public class LootablesManager {
.setMin(0)
.setMax(2).build(),
new LootBuilder()
.setMaterial(plugin.isServerVersionAtLeast(ServerVersion.V1_13)
? Material.GUNPOWDER : Material.valueOf("SULPHUR"))
.setMaterial(LegacyMaterials.GUNPOWDER.getMaterial())
.setChance(12.5)
.setMin(0)
.setMax(2).build(),
@ -642,16 +635,14 @@ public class LootablesManager {
.setMin(1)
.setMax(2).build(),
new LootBuilder()
.setMaterial(plugin.isServerVersionAtLeast(ServerVersion.V1_13)
? Material.WHITE_WOOL : Material.valueOf("WOOL"))
.setMaterial(LegacyMaterials.WHITE_WOOL.getMaterial())
.setMin(2)
.setMax(2).build()));
// Add Squid.
lootManager.addLootable(new Lootable("SQUID",
new LootBuilder()
.setMaterial(plugin.isServerVersionAtLeast(ServerVersion.V1_13)
? Material.INK_SAC : Material.valueOf("INK_SACK"))
.setMaterial(LegacyMaterials.INK_SAC.getMaterial())
.setMin(1)
.setMax(3).build()));
@ -718,8 +709,7 @@ public class LootablesManager {
// Add Snowman.
lootManager.addLootable(new Lootable("SNOWMAN",
new LootBuilder()
.setMaterial(plugin.isServerVersionAtLeast(ServerVersion.V1_13)
? Material.SNOWBALL : Material.valueOf("SNOW_BALL"))
.setMaterial(LegacyMaterials.SNOWBALL.getMaterial())
.setMin(0)
.setMax(15).build()));
@ -738,8 +728,7 @@ public class LootablesManager {
// Add Iron Golem.
lootManager.addLootable(new Lootable("IRON_GOLEM",
new LootBuilder()
.setMaterial(plugin.isServerVersionAtLeast(ServerVersion.V1_13)
? Material.POPPY : Material.valueOf("RED_ROSE"))
.setMaterial(LegacyMaterials.POPPY.getMaterial())
.setMin(0)
.setMax(2).build(),
new LootBuilder()
@ -761,8 +750,7 @@ public class LootablesManager {
.setMin(0)
.setMax(1).build(),
new LootBuilder()
.setMaterial(plugin.isServerVersionAtLeast(ServerVersion.V1_13)
? Material.GUNPOWDER : Material.valueOf("SULPHUR"))
.setMaterial(LegacyMaterials.GUNPOWDER.getMaterial())
.setMin(0)
.setMax(2).build()));

View File

@ -0,0 +1,249 @@
package com.songoda.ultimatestacker.settings;
import com.songoda.core.configuration.Config;
import com.songoda.core.configuration.ConfigSetting;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.entity.Check;
import com.songoda.ultimatestacker.entity.Split;
import java.util.Arrays;
import java.util.Collections;
import java.util.stream.Collectors;
public class Setting {
static final Config config = UltimateStacker.getInstance().getConfig().getCoreConfig();
public static final ConfigSetting STACK_SEARCH_TICK_SPEED = new ConfigSetting(config, "Main.Stack Search Tick Speed", 5,
"The speed in which a new stacks will be created.",
"It is advised to keep this number low.");
public static final ConfigSetting DISABLED_WORLDS = new ConfigSetting(config, "Main.Disabled Worlds", Arrays.asList("World1", "World2", "World3"),
"Worlds that stacking doesn't happen in.");
public static final ConfigSetting STACK_ENTITIES = new ConfigSetting(config, "Entities.Enabled", true,
"Should entities be stacked?");
public static final ConfigSetting NAME_FORMAT_ENTITY = new ConfigSetting(config, "Entities.Name Format", "&f{TYPE} &6{AMT}x",
"The text displayed above an entities head where {TYPE} refers to",
"The entities type and {AMT} is the amount currently stacked.");
public static final ConfigSetting SEARCH_RADIUS = new ConfigSetting(config, "Entities.Search Radius", 5,
"The distance entities must be to each other in order to stack.");
public static final ConfigSetting MAX_STACK_ENTITIES = new ConfigSetting(config, "Entities.Max Stack Size", 15,
"The max amount of entities in a single stack.");
public static final ConfigSetting MIN_STACK_ENTITIES = new ConfigSetting(config, "Entities.Min Stack Amount", 5,
"The minimum amount required before a stack can be formed.",
"Do not set this to lower than 2.");
public static final ConfigSetting MAX_PER_TYPE_STACKS_PER_CHUNK = new ConfigSetting(config, "Entities.Max Per Type Stacks Per Chunk", -1,
"The maximum amount of each entity type stack allowed in a chunk.");
public static final ConfigSetting STACK_WHOLE_CHUNK = new ConfigSetting(config, "Entities.Stack Whole Chunk", false,
"Should all qualifying entities in each chunk be stacked?",
"This will override the stacking radius.");
public static final ConfigSetting ENTITY_HOLOGRAMS = new ConfigSetting(config, "Entities.Holograms Enabled", true,
"Should holograms be displayed above stacked entities?");
public static final ConfigSetting HOLOGRAMS_ON_LOOK_ENTITY = new ConfigSetting(config, "Entities.Only Show Holograms On Look", false,
"Only show nametags above an entities head when looking directly at them.");
public static final ConfigSetting CUSTOM_DROPS = new ConfigSetting(config, "Entities.Custom Drops.Enabled", true,
"Should custom drops be enabled?");
public static final ConfigSetting REROLL = new ConfigSetting(config, "Entities.Custom Drops.Reroll", true,
"Increases chance of uncommon drops by making a second attempt to",
"drop if the original attempt failed (Requires the looting enchantment).",
"This is a default Minecraft mechanic.");
public static final ConfigSetting KILL_WHOLE_STACK_ON_DEATH = new ConfigSetting(config, "Entities.Kill Whole Stack On Death", false,
"Should killing a stack of entities kill the whole stack or",
"just one out of the stack? If you want only certain entities to be",
"effected by this you can configure it in the entities.yml");
public static final ConfigSetting CLEAR_LAG = new ConfigSetting(config, "Entities.Clear Lag", false,
"When enabled, the plugin will hook into ClearLag and extend the",
"clear task to include stacked entities from this plugin. If this is enabled",
"the built in task will not run.");
public static final ConfigSetting INSTANT_KILL = new ConfigSetting(config, "Entities.Instant Kill", Arrays.asList("FALL", "DROWNING", "LAVA", "VOID"),
"Events that will trigger an entire stack to be killed.",
"It should be noted that this is useless if the above setting is true.",
"Any of the following can be added to the list:",
"CONTACT, ENTITY_ATTACK, ENTITY_SWEEP_ATTACK, PROJECTILE",
"SUFFOCATION, FALL, FIRE, FIRE_TICK",
"MELTING, LAVA, DROWNING, BLOCK_EXPLOSION",
"ENTITY_EXPLOSION, VOID, LIGHTNING, SUICIDE",
"STARVATION, POISON, MAGIC, WITHER",
"FALLING_BLOCK, THORNS, DRAGON_BREATH, CUSTOM",
"FLY_INTO_WALL, HOT_FLOOR, CRAMMING, DRYOUT");
public static final ConfigSetting NO_EXP_INSTANT_KILL = new ConfigSetting(config, "Entities.No Exp For Instant Kills", false,
"Should no experience be dropped when an instant kill is performed?");
public static final ConfigSetting STACK_CHECKS = new ConfigSetting(config, "Entities.Stack Checks", Arrays.asList(Check.values()).stream()
.filter(Check::isEnabledByDefault).map(Check::name).collect(Collectors.toList()),
"These are checks that are processed before an entity is stacked.",
"You can add and remove from the list at will.",
"The acceptable check options are:",
"SPAWN_REASON, NERFED, AGE, TICK_AGE, PHANTOM_SIZE",
"IS_TAMED, ANIMAL_OWNER, SKELETON_TYPE",
"ZOMBIE_BABY, SLIME_SIZE, PIG_SADDLE, SHEEP_SHEERED",
"SHEEP_COLOR, WOLF_COLLAR_COLOR, OCELOT_TYPE, HORSE_COLOR",
"HORSE_STYLE, HORSE_CARRYING_CHEST, HORSE_HAS_ARMOR",
"HORSE_HAS_SADDLE, HORSE_JUMP, RABBIT_TYPE, VILLAGER_PROFESSION",
"LLAMA_COLOR, LLAMA_STRENGTH, PARROT_TYPE, PUFFERFISH_STATE",
"TROPICALFISH_PATTERN, TROPICALFISH_BODY_COLOR, TROPICALFISH_PATTERN_COLOR");
public static final ConfigSetting SPLIT_CHECKS = new ConfigSetting(config, "Entities.Split Checks", Arrays.asList(Split.values()).stream()
.map(Split::name).collect(Collectors.toList()),
"These are checks that when achieved will break separate a single entity",
"from a stack.");
public static final ConfigSetting KEEP_FIRE = new ConfigSetting(config, "Entities.Keep Fire", true,
"Should fire ticks persist to the next entity when an entity dies?");
public static final ConfigSetting KEEP_POTION = new ConfigSetting(config, "Entities.Keep Potion Effects", true,
"Should potion effects persist to the next entity when an entity dies?");
public static final ConfigSetting CARRY_OVER_LOWEST_HEALTH = new ConfigSetting(config, "Entities.Carry Over Lowest Health", false,
"Should the lowest health be carried over when stacked?",
"This should not be used in collaboration with 'Stack Entity Health'.",
"If it is used this setting will be overrode.");
public static final ConfigSetting ONLY_STACK_FROM_SPAWNERS = new ConfigSetting(config, "Entities.Only Stack From Spawners", false,
"Should entities only be stacked if they originate from a spawner?",
"It should be noted that the identifier that tells the plugin",
"if the entity originated from a spawner or not is wiped on",
"server restart.");
public static final ConfigSetting STACK_REASONS = new ConfigSetting(config, "Entities.Stack Reasons", Arrays.asList(),
"This will limit mob stacking to mobs who spawned via the listed reasons.",
"This list is ignored if Only Stack From Spawners = true.",
"The following reasons can be added to the list:",
"NATURAL, JOCKEY, CHUNK_GEN, SPAWNER, EGG, SPAWNER_EGG, LIGHTNING, BUILD_SNOWMAN, ",
"BUILD_IRONGOLEM, BUILD_WITHER, VILLAGE_DEFENSE, VILLAGE_INVASION, BREEDING,",
"SLIME_SPLIT, REINFORCEMENTS, NETHER_PORTAL, DISPENSE_EGG, INFECTION,",
"CURED, OCELOT_BABY, SILVERFISH_BLOCK, MOUNT, TRAP, ENDER_PEARL, ",
"SHOULDER_ENTITY, DROWNED, SHEARED, EXPLOSION"
);
public static final ConfigSetting CARRY_OVER_METADATA_ON_DEATH = new ConfigSetting(config, "Entities.Carry Over Metadata On Death", true,
"With this enabled any metadata assigned from supported plugins such",
"as EpicSpawners and mcMMO will be preserved when the entity is killed.");
public static final ConfigSetting ONLY_STACK_ON_SURFACE = new ConfigSetting(config, "Entities.Only Stack On Surface", true,
"Should entities only be stacked if they are touching the ground",
"or swimming? This does not effect flying entities.");
public static final ConfigSetting STACK_ENTITY_HEALTH = new ConfigSetting(config, "Entities.Stack Entity Health", true,
"Should entity health be stacked? When enabled Entity stacks will",
"remember the health of all entities inside of the stack. This",
"works the best with 'Only Stack On Surface enabled' as entities",
"falling out of grinders may stack before hitting the ground.");
public static final ConfigSetting ONLY_STACK_FLYING_DOWN = new ConfigSetting(config, "Entities.Only Stack Flying Down", true,
"Should entities that fly only stack with entities that are lower on the",
"Y axis. This is important for grinders so that flying entities don't continuously",
"stack upwards to a higher up entity.");
public static final ConfigSetting REALISTIC_DAMAGE = new ConfigSetting(config, "Entities.Use Realistic Weapon Damage", true,
"Should weapons take damage based on the amount of entites in the stack?");
public static final ConfigSetting STACK_ITEMS = new ConfigSetting(config, "Items.Enabled", true,
"Should items be stacked?");
public static final ConfigSetting ITEM_HOLOGRAMS = new ConfigSetting(config, "Items.Holograms Enabled", true,
"Should holograms be displayed above stacked items?");
public static final ConfigSetting ITEM_HOLOGRAM_SINGLE = new ConfigSetting(config, "Items.Show Hologram For Single", true,
"Should holograms be displayed above items when there is only a single",
"item in the stack?");
public static final ConfigSetting ITEM_HOLOGRAM_BLACKLIST = new ConfigSetting(config, "Items.Show Holograms For Blacklisted Items", true,
"Should items that are blacklisted display holograms?");
public static final ConfigSetting MAX_STACK_ITEMS = new ConfigSetting(config, "Items.Max Stack Size", 512,
"The max stack size for items.",
"Currently this can only be set to a max of 120.");
public static final ConfigSetting NAME_FORMAT_ITEM = new ConfigSetting(config, "Items.Name Format", "&f{TYPE} &r[&6{AMT}x]",
"The text displayed above a dropped item.");
public static final ConfigSetting NAME_FORMAT_RESET = new ConfigSetting(config, "Items.Name Format Reset", true,
"Should color codes in dropped item names be removed?",
"This is added only because it looks smoother in game. This is only visual and",
"doesn't actually effect the item.");
public static final ConfigSetting ITEM_BLACKLIST = new ConfigSetting(config, "Items.Blacklist", Collections.singletonList("EGG"),
"Items included in this list will stack to default Minecraft amounts.",
"Material list: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html",
"Leave this empty by using \"blacklist: []\" if you do not wish to disable",
"stacking for any items.");
public static final ConfigSetting ITEM_WHITELIST = new ConfigSetting(config, "Items.Whitelist", Collections.EMPTY_LIST,
"Items included in this whitelist will be stacked.",
"Material list: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html",
"Leave this empty by using \"whitelist: []\" if you want everything to be stacked.",
"Items not in this list will act as if they are blacklisted.");
public static final ConfigSetting SHOW_STACK_SIZE_SINGLE = new ConfigSetting(config, "Items.Show Stack Size For Single", false,
"When enabled stack sizes for a stack with a single item will",
"not display the stack size. The stack size will be added",
"for stacks containing two or more items.");
public static final ConfigSetting SPAWNERS_ENABLED = new ConfigSetting(config, "Spawners.Enabled", true,
"Should spawners be stacked?");
public static final ConfigSetting SPAWNER_HOLOGRAMS = new ConfigSetting(config, "Spawners.Holograms Enabled", true,
"Should holograms be displayed above stacked spawners?");
public static final ConfigSetting EGGS_CONVERT_SPAWNERS = new ConfigSetting(config, "Spawners.Eggs Convert Spawners", true,
"Should eggs convert spawners? If enabled you will",
"still need to give perms for it to work.");
public static final ConfigSetting MAX_STACK_SPAWNERS = new ConfigSetting(config, "Spawners.Max Stack Size", 5,
"What should the max a spawner can stack to be?");
public static final ConfigSetting SNEAK_FOR_STACK = new ConfigSetting(config, "Spawners.Sneak To Receive A Stacked Spawner", true,
"Toggle ability to receive a stacked spawner when breaking a spawner while sneaking.");
public static final ConfigSetting SPAWNERS_DONT_EXPLODE = new ConfigSetting(config, "Spawners.Prevent Spawners From Exploding", false,
"Should spawners not break when blown up?");
public static final ConfigSetting EXPLOSION_DROP_CHANCE_TNT = new ConfigSetting(config, "Spawners.Chance On TNT Explosion", "100%",
"Chance of a TNT explosion dropping a spawner.");
public static final ConfigSetting EXPLOSION_DROP_CHANCE_CREEPER = new ConfigSetting(config, "Spawners.Chance On Creeper Explosion", "100%",
"Chance of a creeper explosion dropping a spawner.");
public static final ConfigSetting NAME_FORMAT_SPAWNER = new ConfigSetting(config, "Spawners.Name Format", "&f{TYPE} Spawner &6{AMT}x",
"The text displayed above a stacked spawner where {TYPE} refers to",
"The entities type and {AMT} is the amount currently stacked.");
public static final ConfigSetting LANGUGE_MODE = new ConfigSetting(config, "System.Language Mode", "en_US",
"The enabled language file.",
"More language files (if available) can be found in the plugins data folder.");
public static final ConfigSetting MYSQL_ENABLED = new ConfigSetting(config, "MySQL.Enabled", false,
"Set to 'true' to use MySQL instead of SQLite for data storage.");
public static final ConfigSetting MYSQL_HOSTNAME = new ConfigSetting(config, "MySQL.Hostname", "localhost");
public static final ConfigSetting MYSQL_PORT = new ConfigSetting(config, "MySQL.Port", 3306);
public static final ConfigSetting MYSQL_DATABASE = new ConfigSetting(config, "MySQL.Database", "your-database");
public static final ConfigSetting MYSQL_USERNAME = new ConfigSetting(config, "MySQL.Username", "user");
public static final ConfigSetting MYSQL_PASSWORD = new ConfigSetting(config, "MySQL.Password", "pass");
public static final ConfigSetting MYSQL_USE_SSL = new ConfigSetting(config, "MySQL.Use SSL", false);
/**
* In order to set dynamic economy comment correctly, this needs to be
* called after EconomyManager load
*/
public static void setupConfig() {
config.load();
config.setAutoremove(true).setAutosave(true);
config.saveChanges();
}
}

View File

@ -1,8 +1,8 @@
package com.songoda.ultimatestacker.spawner;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.utils.Reflection;
import com.songoda.ultimatestacker.utils.ServerVersion;
import com.songoda.ultimatestacker.utils.settings.Setting;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -10,7 +10,6 @@ import org.bukkit.World;
import org.bukkit.block.CreatureSpawner;
import java.util.Random;
import java.util.logging.Level;
public class SpawnerStack {
@ -39,7 +38,7 @@ public class SpawnerStack {
&& !plugin.getStackingTask().isWorldDisabled(location.getWorld()) ? 1 : calculateSpawnCount();
int maxNearby = amount > 6 ? amount + 3 : 6;
CreatureSpawner creatureSpawner = (CreatureSpawner) location.getBlock().getState();
if (UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_12)) {
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_12)) {
creatureSpawner.setMaxNearbyEntities(maxNearby);
creatureSpawner.setSpawnCount(count);
} else {

View File

@ -21,7 +21,7 @@ public class StackingTask extends BukkitRunnable {
private EntityStackManager stackManager;
ConfigurationSection configurationSection = UltimateStacker.getInstance().getMobFile().getConfig();
ConfigurationSection configurationSection = UltimateStacker.getInstance().getMobFile();
private List<UUID> processed = new ArrayList<>();

View File

@ -1,67 +0,0 @@
package com.songoda.ultimatestacker.utils;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
/**
* ConfigWrapper made by @clip
*/
public class ConfigWrapper {
private final JavaPlugin plugin;
private final String folderName, fileName;
private FileConfiguration config;
private File configFile;
public ConfigWrapper(final JavaPlugin instance, final String folderName, final String fileName) {
this.plugin = instance;
this.folderName = folderName;
this.fileName = fileName;
}
public void createNewFile(final String message, final String header) {
reloadConfig();
saveConfig();
loadConfig(header);
if (message != null) {
plugin.getLogger().info(message);
}
}
public FileConfiguration getConfig() {
if (config == null) {
reloadConfig();
}
return config;
}
public void loadConfig(final String header) {
config.options().header(header);
config.options().copyDefaults(true);
saveConfig();
}
public void reloadConfig() {
if (configFile == null) {
configFile = new File(plugin.getDataFolder() + folderName, fileName);
}
config = YamlConfiguration.loadConfiguration(configFile);
}
public void saveConfig() {
if (config == null || configFile == null) {
return;
}
try {
getConfig().save(configFile);
} catch (final IOException ex) {
plugin.getLogger().log(Level.SEVERE, "Could not save config to " + configFile, ex);
}
}
}

View File

@ -1,5 +1,6 @@
package com.songoda.ultimatestacker.utils;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.entity.Check;
import com.songoda.ultimatestacker.entity.EntityStack;
@ -96,7 +97,7 @@ public class EntityUtils {
break;
}
case NERFED: {
if (!plugin.isServerVersionAtLeast(ServerVersion.V1_9)) break;
if (!ServerVersion.isServerVersionAtLeast(ServerVersion.V1_9)) break;
if (!toClone.hasAI()) newEntity.setAI(false);
}
case IS_TAMED: {
@ -109,7 +110,7 @@ public class EntityUtils {
}
case SKELETON_TYPE: {
if (!(toClone instanceof Skeleton)
|| plugin.isServerVersionAtLeast(ServerVersion.V1_11)) break;
|| ServerVersion.isServerVersionAtLeast(ServerVersion.V1_11)) break;
((Skeleton) newEntity).setSkeletonType(((Skeleton) toClone).getSkeletonType());
break;
}
@ -124,13 +125,13 @@ public class EntityUtils {
break;
}
case LLAMA_COLOR: {
if (!plugin.isServerVersionAtLeast(ServerVersion.V1_11)
if (!ServerVersion.isServerVersionAtLeast(ServerVersion.V1_11)
|| !(toClone instanceof Llama)) break;
((Llama) newEntity).setColor(((Llama) toClone).getColor());
break;
}
case LLAMA_STRENGTH: {
if (!plugin.isServerVersionAtLeast(ServerVersion.V1_11)
if (!ServerVersion.isServerVersionAtLeast(ServerVersion.V1_11)
|| !(toClone instanceof Llama)) break;
((Llama) newEntity).setStrength(((Llama) toClone).getStrength());
break;
@ -146,7 +147,7 @@ public class EntityUtils {
break;
}
case HORSE_JUMP: {
if (!plugin.isServerVersionAtLeast(ServerVersion.V1_11)
if (!ServerVersion.isServerVersionAtLeast(ServerVersion.V1_11)
|| !(toClone instanceof AbstractHorse)) break;
((AbstractHorse) newEntity).setJumpStrength(((AbstractHorse) toClone).getJumpStrength());
break;
@ -173,11 +174,11 @@ public class EntityUtils {
}
case OCELOT_TYPE: {
if (!(toClone instanceof Ocelot)
|| plugin.isServerVersionAtLeast(ServerVersion.V1_14)) break;
|| ServerVersion.isServerVersionAtLeast(ServerVersion.V1_14)) break;
((Ocelot) newEntity).setCatType(((Ocelot) toClone).getCatType());
}
case CAT_TYPE: {
if (!plugin.isServerVersionAtLeast(ServerVersion.V1_14)
if (!ServerVersion.isServerVersionAtLeast(ServerVersion.V1_14)
|| !(toClone instanceof Cat)) break;
((Cat) newEntity).setCatType(((Cat) toClone).getCatType());
break;
@ -188,37 +189,37 @@ public class EntityUtils {
break;
}
case PARROT_TYPE: {
if (!plugin.isServerVersionAtLeast(ServerVersion.V1_12)
if (!ServerVersion.isServerVersionAtLeast(ServerVersion.V1_12)
|| !(toClone instanceof Parrot)) break;
((Parrot) newEntity).setVariant(((Parrot) toClone).getVariant());
break;
}
case PUFFERFISH_STATE: {
if (!plugin.isServerVersionAtLeast(ServerVersion.V1_13)
if (!ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)
|| !(toClone instanceof PufferFish)) break;
((PufferFish) newEntity).setPuffState(((PufferFish) toClone).getPuffState());
break;
}
case TROPICALFISH_PATTERN: {
if (!plugin.isServerVersionAtLeast(ServerVersion.V1_13)
if (!ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)
|| !(toClone instanceof TropicalFish)) break;
((TropicalFish) newEntity).setPattern(((TropicalFish) toClone).getPattern());
break;
}
case TROPICALFISH_PATTERN_COLOR: {
if (!plugin.isServerVersionAtLeast(ServerVersion.V1_13)
if (!ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)
|| !(toClone instanceof TropicalFish)) break;
((TropicalFish) newEntity).setPatternColor(((TropicalFish) toClone).getPatternColor());
break;
}
case TROPICALFISH_BODY_COLOR: {
if (!plugin.isServerVersionAtLeast(ServerVersion.V1_13)
if (!ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)
|| !(toClone instanceof TropicalFish)) break;
((TropicalFish) newEntity).setBodyColor(((TropicalFish) toClone).getBodyColor());
break;
}
case PHANTOM_SIZE: {
if (!plugin.isServerVersionAtLeast(ServerVersion.V1_13)
if (!ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)
|| !(toClone instanceof Phantom)) break;
((Phantom) newEntity).setSize(((Phantom) toClone).getSize());
break;
@ -261,7 +262,7 @@ public class EntityUtils {
break;
}
case NERFED: {
if (!plugin.isServerVersionAtLeast(ServerVersion.V1_9)) break;
if (!ServerVersion.isServerVersionAtLeast(ServerVersion.V1_9)) break;
entityList.removeIf(entity -> entity.hasAI() != initalEntity.hasAI());
}
case IS_TAMED: {
@ -309,14 +310,14 @@ public class EntityUtils {
break;
}
case LLAMA_COLOR: {
if (!plugin.isServerVersionAtLeast(ServerVersion.V1_11)
if (!ServerVersion.isServerVersionAtLeast(ServerVersion.V1_11)
|| !(initalEntity instanceof Llama)) break;
Llama llama = ((Llama) initalEntity);
entityList.removeIf(entity -> ((Llama) entity).getColor() != llama.getColor());
break;
}
case LLAMA_STRENGTH: {
if (!plugin.isServerVersionAtLeast(ServerVersion.V1_11)
if (!ServerVersion.isServerVersionAtLeast(ServerVersion.V1_11)
|| !(initalEntity instanceof Llama)) break;
Llama llama = ((Llama) initalEntity);
entityList.removeIf(entity -> ((Llama) entity).getStrength() != llama.getStrength());
@ -335,7 +336,7 @@ public class EntityUtils {
break;
}
case HORSE_CARRYING_CHEST: {
if (plugin.isServerVersionAtLeast(ServerVersion.V1_11)) {
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_11)) {
if (!(initalEntity instanceof ChestedHorse)) break;
entityList.removeIf(entity -> ((ChestedHorse) entity).isCarryingChest());
} else {
@ -350,7 +351,7 @@ public class EntityUtils {
break;
}
case HORSE_HAS_SADDLE: {
if (plugin.isServerVersionAtLeast(ServerVersion.V1_13)
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)
&& initalEntity instanceof AbstractHorse) {
entityList.removeIf(entity -> ((AbstractHorse) entity).getInventory().getSaddle() != null);
break;
@ -360,7 +361,7 @@ public class EntityUtils {
break;
}
case HORSE_JUMP: {
if (plugin.isServerVersionAtLeast(ServerVersion.V1_11)) {
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_11)) {
if (!(initalEntity instanceof AbstractHorse)) break;
AbstractHorse horse = ((AbstractHorse) initalEntity);
entityList.removeIf(entity -> ((AbstractHorse) entity).getJumpStrength() != horse.getJumpStrength());
@ -402,7 +403,7 @@ public class EntityUtils {
entityList.removeIf(entity -> ((Ocelot) entity).getCatType() != ocelot.getCatType());
}
case CAT_TYPE: {
if (!plugin.isServerVersionAtLeast(ServerVersion.V1_14)
if (!ServerVersion.isServerVersionAtLeast(ServerVersion.V1_14)
|| !(initalEntity instanceof Cat)) break;
Cat cat = (Cat) initalEntity;
entityList.removeIf(entity -> ((Cat) entity).getCatType() != cat.getCatType());
@ -415,42 +416,42 @@ public class EntityUtils {
break;
}
case PARROT_TYPE: {
if (!plugin.isServerVersionAtLeast(ServerVersion.V1_12)
if (!ServerVersion.isServerVersionAtLeast(ServerVersion.V1_12)
|| !(initalEntity instanceof Parrot)) break;
Parrot parrot = (Parrot) initalEntity;
entityList.removeIf(entity -> ((Parrot) entity).getVariant() != parrot.getVariant());
break;
}
case PUFFERFISH_STATE: {
if (!plugin.isServerVersionAtLeast(ServerVersion.V1_13)
if (!ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)
|| !(initalEntity instanceof PufferFish)) break;
PufferFish pufferFish = (PufferFish) initalEntity;
entityList.removeIf(entity -> ((PufferFish) entity).getPuffState() != pufferFish.getPuffState());
break;
}
case TROPICALFISH_PATTERN: {
if (!plugin.isServerVersionAtLeast(ServerVersion.V1_13)
if (!ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)
|| !(initalEntity instanceof TropicalFish)) break;
TropicalFish tropicalFish = (TropicalFish) initalEntity;
entityList.removeIf(entity -> ((TropicalFish) entity).getPattern() != tropicalFish.getPattern());
break;
}
case TROPICALFISH_PATTERN_COLOR: {
if (!plugin.isServerVersionAtLeast(ServerVersion.V1_13)
if (!ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)
|| !(initalEntity instanceof TropicalFish)) break;
TropicalFish tropicalFish = (TropicalFish) initalEntity;
entityList.removeIf(entity -> ((TropicalFish) entity).getPatternColor() != tropicalFish.getPatternColor());
break;
}
case TROPICALFISH_BODY_COLOR: {
if (!plugin.isServerVersionAtLeast(ServerVersion.V1_13)
if (!ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)
|| !(initalEntity instanceof TropicalFish)) break;
TropicalFish tropicalFish = (TropicalFish) initalEntity;
entityList.removeIf(entity -> ((TropicalFish) entity).getBodyColor() != tropicalFish.getBodyColor());
break;
}
case PHANTOM_SIZE: {
if (!plugin.isServerVersionAtLeast(ServerVersion.V1_13)
if (!ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)
|| !(initalEntity instanceof Phantom)) break;
Phantom phantom = (Phantom) initalEntity;
entityList.removeIf(entity -> ((Phantom) entity).getSize() != phantom.getSize());

View File

@ -1,24 +1,33 @@
package com.songoda.ultimatestacker.utils;
import com.songoda.core.compatibility.LegacyMaterials;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.core.utils.TextUtils;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.utils.settings.Setting;
import java.lang.reflect.Method;
import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.block.CreatureSpawner;
import org.bukkit.entity.*;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BlockStateMeta;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.util.Vector;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.CreatureSpawner;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BlockStateMeta;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.util.Vector;
public class Methods {
@ -45,111 +54,45 @@ public class Methods {
Methods.updateItemAmount(item, itemStack, amount);
}
private static Class<?> clazzCraftWorld, clazzCraftBlock, clazzBlockPosition;
private static Method getHandle, updateAdjacentComparators, getNMSBlock;
public static void updateAdjacentComparators(Location location) {
try {
// Cache reflection.
if (clazzCraftWorld == null) {
String ver = Bukkit.getServer().getClass().getPackage().getName().substring(23);
clazzCraftWorld = Class.forName("org.bukkit.craftbukkit." + ver + ".CraftWorld");
clazzCraftBlock = Class.forName("org.bukkit.craftbukkit." + ver + ".block.CraftBlock");
clazzBlockPosition = Class.forName("net.minecraft.server." + ver + ".BlockPosition");
Class<?> clazzWorld = Class.forName("net.minecraft.server." + ver + ".World");
Class<?> clazzBlock = Class.forName("net.minecraft.server." + ver + ".Block");
getHandle = clazzCraftWorld.getMethod("getHandle");
updateAdjacentComparators = clazzWorld.getMethod("updateAdjacentComparators", clazzBlockPosition, clazzBlock);
getNMSBlock = clazzCraftBlock.getDeclaredMethod("getNMSBlock");
getNMSBlock.setAccessible(true);
}
// invoke and cast objects.
Object craftWorld = clazzCraftWorld.cast(location.getWorld());
Object world = getHandle.invoke(craftWorld);
Object craftBlock = clazzCraftBlock.cast(location.getBlock());
// Invoke final method.
updateAdjacentComparators
.invoke(world, clazzBlockPosition.getConstructor(double.class, double.class, double.class)
.newInstance(location.getX(), location.getY(), location.getZ()),
getNMSBlock.invoke(craftBlock));
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
}
// Do not touch! API for older plugins
@Deprecated
public static boolean isMaterialBlacklisted(Material type) {
List<String> whitelist = Setting.ITEM_WHITELIST.getStringList();
List<String> blacklist = Setting.ITEM_BLACKLIST.getStringList();
return !whitelist.isEmpty() && !whitelist.contains(type.name())
|| !blacklist.isEmpty() && blacklist.contains(type.name());
return UltimateStacker.isMaterialBlacklisted(type);
}
// Do not touch! API for older plugins
@Deprecated
public static boolean isMaterialBlacklisted(Material type, byte data) {
List<String> whitelist = Setting.ITEM_WHITELIST.getStringList();
List<String> blacklist = Setting.ITEM_BLACKLIST.getStringList();
String combined = type.toString() + ":" + data;
return !whitelist.isEmpty() && !whitelist.contains(combined)
|| !blacklist.isEmpty() && blacklist.contains(combined);
return UltimateStacker.isMaterialBlacklisted(type, data);
}
// This function shouldn't change! This is the API that many plugins hook into!
// Do not touch! API for older plugins
@Deprecated
public static void updateItemAmount(Item item, int newAmount) {
item.getItemStack().setAmount(Math.min(32, newAmount));
updateItemAmount(item, item.getItemStack(), newAmount);
UltimateStacker.updateItemAmount(item, newAmount);
}
// Do not touch! API for older plugins
@Deprecated
public static void updateItemAmount(Item item, ItemStack itemStack, int newAmount) {
UltimateStacker plugin = UltimateStacker.getInstance();
Material material = itemStack.getType();
String name = Methods.convertToInvisibleString("IS") +
compileItemName(itemStack, newAmount);
boolean blacklisted = UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) ?
isMaterialBlacklisted(itemStack.getType()) : isMaterialBlacklisted(itemStack.getType(), itemStack.getData().getData());
if (newAmount > 32 && !blacklisted) {
item.setMetadata("US_AMT", new FixedMetadataValue(plugin, newAmount));
itemStack.setAmount(32);
} else {
item.removeMetadata("US_AMT", plugin);
itemStack.setAmount(newAmount);
}
item.setItemStack(itemStack);
if ((blacklisted && !Setting.ITEM_HOLOGRAM_BLACKLIST.getBoolean())
|| !plugin.getItemFile().getConfig().getBoolean("Items." + material + ".Has Hologram")
|| !Setting.ITEM_HOLOGRAMS.getBoolean()
|| newAmount == 1 && !Setting.ITEM_HOLOGRAM_SINGLE.getBoolean()) return;
item.setCustomName(name);
item.setCustomNameVisible(true);
UltimateStacker.updateItemAmount(item, itemStack, newAmount);
}
// Do not touch! API for older plugins
@Deprecated
public static int getActualItemAmount(Item item) {
int amount = item.getItemStack().getAmount();
if (amount >= 32 && item.hasMetadata("US_AMT")) {
return item.getMetadata("US_AMT").get(0).asInt();
} else {
return amount;
}
return UltimateStacker.getActualItemAmount(item);
}
// Do not touch! API for older plugins
@Deprecated
public static boolean hasCustomAmount(Item item) {
if (item.hasMetadata("US_AMT")) {
return item.getItemStack().getAmount() != item.getMetadata("US_AMT").get(0).asInt();
}
return false;
return UltimateStacker.hasCustomAmount(item);
}
public static String compileItemName(ItemStack item, int amount) {
String nameFormat = Setting.NAME_FORMAT_ITEM.getString();
String displayName = Methods.formatText(UltimateStacker.getInstance().getItemFile().getConfig()
String displayName = Methods.formatText(UltimateStacker.getInstance().getItemFile()
.getString("Items." + item.getType().name() + ".Display Name"));
if (item.hasItemMeta() && item.getItemMeta().hasDisplayName())
@ -165,7 +108,7 @@ public class Methods {
nameFormat = nameFormat.replace("[", "").replace("]", "");
}
String info = Methods.convertToInvisibleString(Methods.insertSemicolon(String.valueOf(amount)) + ":");
String info = TextUtils.convertToInvisibleString(Methods.insertSemicolon(String.valueOf(amount)) + ":");
return info + Methods.formatText(nameFormat).trim();
}
@ -188,23 +131,23 @@ public class Methods {
public static String compileSpawnerName(EntityType entityType, int amount) {
String nameFormat = UltimateStacker.getInstance().getConfig().getString("Spawners.Name Format");
String displayName = Methods.formatText(UltimateStacker.getInstance().getSpawnerFile().getConfig().getString("Spawners." + entityType.name() + ".Display Name"));
String displayName = Methods.formatText(UltimateStacker.getInstance().getSpawnerFile().getString("Spawners." + entityType.name() + ".Display Name"));
nameFormat = nameFormat.replace("{TYPE}", displayName);
nameFormat = nameFormat.replace("{AMT}", Integer.toString(amount));
String info = Methods.convertToInvisibleString(insertSemicolon(String.valueOf(amount)) + ":");
String info = TextUtils.convertToInvisibleString(insertSemicolon(String.valueOf(amount)) + ":");
return info + Methods.formatText(nameFormat).trim();
}
public static String compileEntityName(Entity entity, int amount) {
String nameFormat = Setting.NAME_FORMAT_ENTITY.getString();
String displayName = Methods.formatText(UltimateStacker.getInstance().getMobFile().getConfig().getString("Mobs." + entity.getType().name() + ".Display Name"));
String displayName = Methods.formatText(UltimateStacker.getInstance().getMobFile().getString("Mobs." + entity.getType().name() + ".Display Name"));
nameFormat = nameFormat.replace("{TYPE}", displayName);
nameFormat = nameFormat.replace("{AMT}", Integer.toString(amount));
String info = Methods.convertToInvisibleString(insertSemicolon(String.valueOf(amount)) + ":");
String info = TextUtils.convertToInvisibleString(insertSemicolon(String.valueOf(amount)) + ":");
return info + Methods.formatText(nameFormat).trim();
}
@ -221,7 +164,7 @@ public class Methods {
}
public static ItemStack getSpawnerItem(EntityType entityType, int amount) {
ItemStack item = new ItemStack((UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) ? Material.SPAWNER : Material.valueOf("MOB_SPAWNER")), 1);
ItemStack item = LegacyMaterials.SPAWNER.getItem();
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(Methods.compileSpawnerName(entityType, amount));
CreatureSpawner cs = (CreatureSpawner) ((BlockStateMeta) meta).getBlockState();
@ -231,39 +174,10 @@ public class Methods {
return item;
}
public static ItemStack getGlass() {
UltimateStacker instance = UltimateStacker.getInstance();
return Methods.getGlass(instance.getConfig().getBoolean("Interfaces.Replace Glass Type 1 With Rainbow Glass"), instance.getConfig().getInt("Interfaces.Glass Type 1"));
}
public static ItemStack getBackgroundGlass(boolean type) {
UltimateStacker instance = UltimateStacker.getInstance();
if (type)
return getGlass(false, instance.getConfig().getInt("Interfaces.Glass Type 2"));
else
return getGlass(false, instance.getConfig().getInt("Interfaces.Glass Type 3"));
}
private static ItemStack getGlass(Boolean rainbow, int type) {
int randomNum = 1 + (int) (Math.random() * 6);
ItemStack glass;
if (rainbow) {
glass = new ItemStack(UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) ?
Material.LEGACY_STAINED_GLASS_PANE : Material.valueOf("STAINED_GLASS_PANE"), 1, (short) randomNum);
} else {
glass = new ItemStack(UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) ?
Material.LEGACY_STAINED_GLASS_PANE : Material.valueOf("STAINED_GLASS_PANE"), 1, (short) type);
}
ItemMeta glassmeta = glass.getItemMeta();
glassmeta.setDisplayName("§l");
glass.setItemMeta(glassmeta);
return glass;
}
public static String formatTitle(String text) {
if (text == null || text.equals(""))
return "";
if (!UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_9)) {
if (!ServerVersion.isServerVersionAtLeast(ServerVersion.V1_9)) {
if (text.length() > 31)
text = text.substring(0, 29) + "...";
}
@ -338,15 +252,6 @@ public class Methods {
return location;
}
public static String convertToInvisibleString(String s) {
if (s == null || s.equals(""))
return "";
StringBuilder hidden = new StringBuilder();
for (char c : s.toCharArray()) hidden.append(ChatColor.COLOR_CHAR + "").append(c);
return hidden.toString();
}
public static String insertSemicolon(String s) {
if (s == null || s.equals(""))
return "";

View File

@ -1,695 +0,0 @@
package com.songoda.ultimatestacker.utils;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.ServicePriority;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.zip.GZIPOutputStream;
/**
* bStats collects some data for plugin authors.
* <p>
* Check out https://bStats.org/ to learn more about bStats!
*/
@SuppressWarnings({"WeakerAccess", "unused"})
public class Metrics {
static {
// You can use the property to disable the check in your test environment
if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false")) {
// Maven's Relocate is clever and changes strings, too. So we have to use this little "trick" ... :D
final String defaultPackage = new String(
new byte[]{'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't'});
final String examplePackage = new String(new byte[]{'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
// We want to make sure nobody just copy & pastes the example and use the wrong package names
if (Metrics.class.getPackage().getName().equals(defaultPackage) || Metrics.class.getPackage().getName().equals(examplePackage)) {
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
}
}
}
// The version of this bStats class
public static final int B_STATS_VERSION = 1;
// The url to which the data is sent
private static final String URL = "https://bStats.org/submitData/bukkit";
// Is bStats enabled on this server?
private boolean enabled;
// Should failed requests be logged?
private static boolean logFailedRequests;
// Should the sent data be logged?
private static boolean logSentData;
// Should the response text be logged?
private static boolean logResponseStatusText;
// The uuid of the server
private static String serverUUID;
// The plugin
private final Plugin plugin;
// A list with all custom charts
private final List<CustomChart> charts = new ArrayList<>();
/**
* Class constructor.
*
* @param plugin The plugin which stats should be submitted.
*/
public Metrics(Plugin plugin) {
if (plugin == null) {
throw new IllegalArgumentException("Plugin cannot be null!");
}
this.plugin = plugin;
// Get the config file
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
File configFile = new File(bStatsFolder, "config.yml");
YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
// Check if the config file exists
if (!config.isSet("serverUuid")) {
// Add default values
config.addDefault("enabled", true);
// Every server gets it's unique random id.
config.addDefault("serverUuid", UUID.randomUUID().toString());
// Should failed request be logged?
config.addDefault("logFailedRequests", false);
// Should the sent data be logged?
config.addDefault("logSentData", false);
// Should the response text be logged?
config.addDefault("logResponseStatusText", false);
// Inform the server owners about bStats
config.options().header(
"bStats collects some data for plugin authors like how many servers are using their plugins.\n" +
"To honor their work, you should not disable it.\n" +
"This has nearly no effect on the server performance!\n" +
"Check out https://bStats.org/ to learn more :)"
).copyDefaults(true);
try {
config.save(configFile);
} catch (IOException ignored) { }
}
// Load the data
enabled = config.getBoolean("enabled", true);
serverUUID = config.getString("serverUuid");
logFailedRequests = config.getBoolean("logFailedRequests", false);
logSentData = config.getBoolean("logSentData", false);
logResponseStatusText = config.getBoolean("logResponseStatusText", false);
if (enabled) {
boolean found = false;
// Search for all other bStats Metrics classes to see if we are the first one
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
try {
service.getField("B_STATS_VERSION"); // Our identifier :)
found = true; // We aren't the first
break;
} catch (NoSuchFieldException ignored) { }
}
// Register our service
Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal);
if (!found) {
// We are the first!
startSubmitting();
}
}
}
/**
* Checks if bStats is enabled.
*
* @return Whether bStats is enabled or not.
*/
public boolean isEnabled() {
return enabled;
}
/**
* Adds a custom chart.
*
* @param chart The chart to add.
*/
public void addCustomChart(CustomChart chart) {
if (chart == null) {
throw new IllegalArgumentException("Chart cannot be null!");
}
charts.add(chart);
}
/**
* Starts the Scheduler which submits our data every 30 minutes.
*/
private void startSubmitting() {
final Timer timer = new Timer(true); // We use a timer cause the Bukkit scheduler is affected by server lags
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
if (!plugin.isEnabled()) { // Plugin was disabled
timer.cancel();
return;
}
// Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler
// Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;)
Bukkit.getScheduler().runTask(plugin, () -> submitData());
}
}, 1000 * 60 * 5, 1000 * 60 * 30);
// Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start
// WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted!
// WARNING: Just don't do it!
}
/**
* Gets the plugin specific data.
* This method is called using Reflection.
*
* @return The plugin specific data.
*/
public JSONObject getPluginData() {
JSONObject data = new JSONObject();
String pluginName = plugin.getDescription().getName();
String pluginVersion = plugin.getDescription().getVersion();
data.put("pluginName", pluginName); // Append the name of the plugin
data.put("pluginVersion", pluginVersion); // Append the version of the plugin
JSONArray customCharts = new JSONArray();
for (CustomChart customChart : charts) {
// Add the data of the custom charts
JSONObject chart = customChart.getRequestJsonObject();
if (chart == null) { // If the chart is null, we skip it
continue;
}
customCharts.add(chart);
}
data.put("customCharts", customCharts);
return data;
}
/**
* Gets the server specific data.
*
* @return The server specific data.
*/
private JSONObject getServerData() {
// Minecraft specific data
int playerAmount;
try {
// Around MC 1.8 the return type was changed to a collection from an array,
// This fixes java.lang.NoSuchMethodError: org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection;
Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers");
playerAmount = onlinePlayersMethod.getReturnType().equals(Collection.class)
? ((Collection<?>) onlinePlayersMethod.invoke(Bukkit.getServer())).size()
: ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length;
} catch (Exception e) {
playerAmount = Bukkit.getOnlinePlayers().size(); // Just use the new method if the Reflection failed
}
int onlineMode = Bukkit.getOnlineMode() ? 1 : 0;
String bukkitVersion = Bukkit.getVersion();
// OS/Java specific data
String javaVersion = System.getProperty("java.version");
String osName = System.getProperty("os.name");
String osArch = System.getProperty("os.arch");
String osVersion = System.getProperty("os.version");
int coreCount = Runtime.getRuntime().availableProcessors();
JSONObject data = new JSONObject();
data.put("serverUUID", serverUUID);
data.put("playerAmount", playerAmount);
data.put("onlineMode", onlineMode);
data.put("bukkitVersion", bukkitVersion);
data.put("javaVersion", javaVersion);
data.put("osName", osName);
data.put("osArch", osArch);
data.put("osVersion", osVersion);
data.put("coreCount", coreCount);
return data;
}
/**
* Collects the data and sends it afterwards.
*/
private void submitData() {
final JSONObject data = getServerData();
JSONArray pluginData = new JSONArray();
// Search for all other bStats Metrics classes to get their plugin data
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
try {
service.getField("B_STATS_VERSION"); // Our identifier :)
for (RegisteredServiceProvider<?> provider : Bukkit.getServicesManager().getRegistrations(service)) {
try {
pluginData.add(provider.getService().getMethod("getPluginData").invoke(provider.getProvider()));
} catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { }
}
} catch (NoSuchFieldException ignored) { }
}
data.put("plugins", pluginData);
// Create a new thread for the connection to the bStats server
new Thread(new Runnable() {
@Override
public void run() {
try {
// Send the data
sendData(plugin, data);
} catch (Exception e) {
// Something went wrong! :(
if (logFailedRequests) {
plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), e);
}
}
}
}).start();
}
/**
* Sends the data to the bStats server.
*
* @param plugin Any plugin. It's just used to get a logger instance.
* @param data The data to send.
* @throws Exception If the request failed.
*/
private static void sendData(Plugin plugin, JSONObject data) throws Exception {
if (data == null) {
throw new IllegalArgumentException("Data cannot be null!");
}
if (Bukkit.isPrimaryThread()) {
throw new IllegalAccessException("This method must not be called from the main thread!");
}
if (logSentData) {
plugin.getLogger().info("Sending data to bStats: " + data.toString());
}
HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection();
// Compress the data to save bandwidth
byte[] compressedData = compress(data.toString());
// Add headers
connection.setRequestMethod("POST");
connection.addRequestProperty("Accept", "application/json");
connection.addRequestProperty("Connection", "close");
connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format
connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION);
// Send data
connection.setDoOutput(true);
DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
outputStream.write(compressedData);
outputStream.flush();
outputStream.close();
InputStream inputStream = connection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder builder = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
builder.append(line);
}
bufferedReader.close();
if (logResponseStatusText) {
plugin.getLogger().info("Sent data to bStats and received response: " + builder.toString());
}
}
/**
* Gzips the given String.
*
* @param str The string to gzip.
* @return The gzipped String.
* @throws IOException If the compression failed.
*/
private static byte[] compress(final String str) throws IOException {
if (str == null) {
return null;
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(outputStream);
gzip.write(str.getBytes(StandardCharsets.UTF_8));
gzip.close();
return outputStream.toByteArray();
}
/**
* Represents a custom chart.
*/
public static abstract class CustomChart {
// The id of the chart
final String chartId;
/**
* Class constructor.
*
* @param chartId The id of the chart.
*/
CustomChart(String chartId) {
if (chartId == null || chartId.isEmpty()) {
throw new IllegalArgumentException("ChartId cannot be null or empty!");
}
this.chartId = chartId;
}
private JSONObject getRequestJsonObject() {
JSONObject chart = new JSONObject();
chart.put("chartId", chartId);
try {
JSONObject data = getChartData();
if (data == null) {
// If the data is null we don't send the chart.
return null;
}
chart.put("data", data);
} catch (Throwable t) {
if (logFailedRequests) {
Bukkit.getLogger().log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, t);
}
return null;
}
return chart;
}
protected abstract JSONObject getChartData() throws Exception;
}
/**
* Represents a custom simple pie.
*/
public static class SimplePie extends CustomChart {
private final Callable<String> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public SimplePie(String chartId, Callable<String> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
String value = callable.call();
if (value == null || value.isEmpty()) {
// Null = skip the chart
return null;
}
data.put("value", value);
return data;
}
}
/**
* Represents a custom advanced pie.
*/
public static class AdvancedPie extends CustomChart {
private final Callable<Map<String, Integer>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public AdvancedPie(String chartId, Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
JSONObject values = new JSONObject();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean allSkipped = true;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
if (entry.getValue() == 0) {
continue; // Skip this invalid
}
allSkipped = false;
values.put(entry.getKey(), entry.getValue());
}
if (allSkipped) {
// Null = skip the chart
return null;
}
data.put("values", values);
return data;
}
}
/**
* Represents a custom drilldown pie.
*/
public static class DrilldownPie extends CustomChart {
private final Callable<Map<String, Map<String, Integer>>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public DrilldownPie(String chartId, Callable<Map<String, Map<String, Integer>>> callable) {
super(chartId);
this.callable = callable;
}
@Override
public JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
JSONObject values = new JSONObject();
Map<String, Map<String, Integer>> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean reallyAllSkipped = true;
for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) {
JSONObject value = new JSONObject();
boolean allSkipped = true;
for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) {
value.put(valueEntry.getKey(), valueEntry.getValue());
allSkipped = false;
}
if (!allSkipped) {
reallyAllSkipped = false;
values.put(entryValues.getKey(), value);
}
}
if (reallyAllSkipped) {
// Null = skip the chart
return null;
}
data.put("values", values);
return data;
}
}
/**
* Represents a custom single line chart.
*/
public static class SingleLineChart extends CustomChart {
private final Callable<Integer> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public SingleLineChart(String chartId, Callable<Integer> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
int value = callable.call();
if (value == 0) {
// Null = skip the chart
return null;
}
data.put("value", value);
return data;
}
}
/**
* Represents a custom multi line chart.
*/
public static class MultiLineChart extends CustomChart {
private final Callable<Map<String, Integer>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public MultiLineChart(String chartId, Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
JSONObject values = new JSONObject();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean allSkipped = true;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
if (entry.getValue() == 0) {
continue; // Skip this invalid
}
allSkipped = false;
values.put(entry.getKey(), entry.getValue());
}
if (allSkipped) {
// Null = skip the chart
return null;
}
data.put("values", values);
return data;
}
}
/**
* Represents a custom simple bar chart.
*/
public static class SimpleBarChart extends CustomChart {
private final Callable<Map<String, Integer>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public SimpleBarChart(String chartId, Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
JSONObject values = new JSONObject();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
for (Map.Entry<String, Integer> entry : map.entrySet()) {
JSONArray categoryValues = new JSONArray();
categoryValues.add(entry.getValue());
values.put(entry.getKey(), categoryValues);
}
data.put("values", values);
return data;
}
}
/**
* Represents a custom advanced bar chart.
*/
public static class AdvancedBarChart extends CustomChart {
private final Callable<Map<String, int[]>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public AdvancedBarChart(String chartId, Callable<Map<String, int[]>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
JSONObject values = new JSONObject();
Map<String, int[]> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean allSkipped = true;
for (Map.Entry<String, int[]> entry : map.entrySet()) {
if (entry.getValue().length == 0) {
continue; // Skip this invalid
}
allSkipped = false;
JSONArray categoryValues = new JSONArray();
for (int categoryValue : entry.getValue()) {
categoryValues.add(categoryValue);
}
values.put(entry.getKey(), categoryValues);
}
if (allSkipped) {
// Null = skip the chart
return null;
}
data.put("values", values);
return data;
}
}
}

View File

@ -1,27 +0,0 @@
package com.songoda.ultimatestacker.utils;
public enum ServerVersion {
UNKNOWN("unknown_server_version"),
V1_7("org.bukkit.craftbukkit.v1_7"),
V1_8("org.bukkit.craftbukkit.v1_8"),
V1_9("org.bukkit.craftbukkit.v1_9"),
V1_10("org.bukkit.craftbukkit.v1_10"),
V1_11("org.bukkit.craftbukkit.v1_11"),
V1_12("org.bukkit.craftbukkit.v1_12"),
V1_13("org.bukkit.craftbukkit.v1_13"),
V1_14("org.bukkit.craftbukkit.v1_14");
private final String packagePrefix;
private ServerVersion(String packagePrefix) {
this.packagePrefix = packagePrefix;
}
public static ServerVersion fromPackageName(String packageName) {
for (ServerVersion version : values())
if (packageName.startsWith(version.packagePrefix)) return version;
return ServerVersion.UNKNOWN;
}
}

View File

@ -1,289 +0,0 @@
package com.songoda.ultimatestacker.utils.gui;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.utils.version.NMSUtil;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
public class AbstractAnvilGUI {
private static Class<?> BlockPositionClass;
private static Class<?> PacketPlayOutOpenWindowClass;
private static Class<?> IChatBaseComponentClass;
private static Class<?> ICraftingClass;
private static Class<?> ContainerAnvilClass;
private static Class<?> ChatMessageClass;
private static Class<?> EntityHumanClass;
private static Class<?> ContainerClass;
private static Class<?> ContainerAccessClass;
private static Class<?> WorldClass;
private static Class<?> PlayerInventoryClass;
private static Class<?> ContainersClass;
private static Class<?> CraftPlayerClass;
private Player player;
private Map<AnvilSlot, ItemStack> items = new HashMap<>();
private OnClose onClose = null;
private Inventory inv;
private Listener listener;
static {
BlockPositionClass = NMSUtil.getNMSClass("BlockPosition");
PacketPlayOutOpenWindowClass = NMSUtil.getNMSClass("PacketPlayOutOpenWindow");
IChatBaseComponentClass = NMSUtil.getNMSClass("IChatBaseComponent");
ICraftingClass = NMSUtil.getNMSClass("ICrafting");
ContainerAnvilClass = NMSUtil.getNMSClass("ContainerAnvil");
EntityHumanClass = NMSUtil.getNMSClass("EntityHuman");
ChatMessageClass = NMSUtil.getNMSClass("ChatMessage");
ContainerClass = NMSUtil.getNMSClass("Container");
WorldClass = NMSUtil.getNMSClass("World");
PlayerInventoryClass = NMSUtil.getNMSClass("PlayerInventory");
CraftPlayerClass = NMSUtil.getCraftClass("entity.CraftPlayer");
if (NMSUtil.getVersionNumber() > 13) {
ContainerAccessClass = NMSUtil.getNMSClass("ContainerAccess");
ContainersClass = NMSUtil.getNMSClass("Containers");
}
}
public AbstractAnvilGUI(Player player, AnvilClickEventHandler handler) {
UltimateStacker instance = UltimateStacker.getInstance();
this.player = player;
this.listener = new Listener() {
@EventHandler(priority = EventPriority.HIGHEST)
public void onInventoryClick(InventoryClickEvent event) {
if (event.getWhoClicked() instanceof Player && event.getInventory().equals(AbstractAnvilGUI.this.inv)) {
event.setCancelled(true);
ItemStack item = event.getCurrentItem();
int slot = event.getRawSlot();
if (item == null || item.getType().equals(Material.AIR) || slot != 2)
return;
String name = "";
ItemMeta meta = item.getItemMeta();
if (meta != null && meta.hasDisplayName())
name = meta.getDisplayName();
AnvilClickEvent clickEvent = new AnvilClickEvent(AnvilSlot.bySlot(slot), name);
handler.onAnvilClick(clickEvent);
if (clickEvent.getWillClose())
event.getWhoClicked().closeInventory();
if (clickEvent.getWillDestroy())
AbstractAnvilGUI.this.destroy();
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onInventoryClose(InventoryCloseEvent event) {
if (event.getPlayer() instanceof Player && AbstractAnvilGUI.this.inv.equals(event.getInventory())) {
Inventory inv = event.getInventory();
player.setLevel(player.getLevel() - 1);
inv.clear();
Bukkit.getScheduler().scheduleSyncDelayedTask(instance, () -> {
if (AbstractAnvilGUI.this.onClose != null)
AbstractAnvilGUI.this.onClose.onClose(player, inv);
AbstractAnvilGUI.this.destroy();
}, 1L);
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerQuit(PlayerQuitEvent event) {
if (event.getPlayer().equals(AbstractAnvilGUI.this.player)) {
player.setLevel(player.getLevel() - 1);
AbstractAnvilGUI.this.destroy();
}
}
};
Bukkit.getPluginManager().registerEvents(this.listener, instance);
}
public Player getPlayer() {
return this.player;
}
public void setSlot(AnvilSlot slot, ItemStack item) {
this.items.put(slot, item);
}
public void open() {
this.player.setLevel(this.player.getLevel() + 1);
try {
Object craftPlayer = CraftPlayerClass.cast(this.player);
Method getHandleMethod = CraftPlayerClass.getMethod("getHandle");
Object entityPlayer = getHandleMethod.invoke(craftPlayer);
Object playerInventory = NMSUtil.getFieldObject(entityPlayer, NMSUtil.getField(entityPlayer.getClass(), "inventory", false));
Object world = NMSUtil.getFieldObject(entityPlayer, NMSUtil.getField(entityPlayer.getClass(), "world", false));
Object blockPosition = BlockPositionClass.getConstructor(int.class, int.class, int.class).newInstance(0, 0, 0);
Object container;
if (NMSUtil.getVersionNumber() > 13) {
container = ContainerAnvilClass
.getConstructor(int.class, PlayerInventoryClass, ContainerAccessClass)
.newInstance(7, playerInventory, ContainerAccessClass.getMethod("at", WorldClass, BlockPositionClass).invoke(null, world, blockPosition));
} else {
container = ContainerAnvilClass
.getConstructor(PlayerInventoryClass, WorldClass, BlockPositionClass, EntityHumanClass)
.newInstance(playerInventory, world, blockPosition, entityPlayer);
}
NMSUtil.getField(ContainerClass, "checkReachable", true).set(container, false);
Method getBukkitViewMethod = container.getClass().getMethod("getBukkitView");
Object bukkitView = getBukkitViewMethod.invoke(container);
Method getTopInventoryMethod = bukkitView.getClass().getMethod("getTopInventory");
this.inv = (Inventory) getTopInventoryMethod.invoke(bukkitView);
for (AnvilSlot slot : this.items.keySet()) {
this.inv.setItem(slot.getSlot(), this.items.get(slot));
}
Method nextContainerCounterMethod = entityPlayer.getClass().getMethod("nextContainerCounter");
int c = (int) nextContainerCounterMethod.invoke(entityPlayer);
Constructor<?> chatMessageConstructor = ChatMessageClass.getConstructor(String.class, Object[].class);
Object inventoryTitle = chatMessageConstructor.newInstance("Repairing", new Object[]{});
Object packet;
if (NMSUtil.getVersionNumber() > 13) {
packet = PacketPlayOutOpenWindowClass
.getConstructor(int.class, ContainersClass, IChatBaseComponentClass)
.newInstance(c, ContainersClass.getField("ANVIL").get(null), inventoryTitle);
} else {
packet = PacketPlayOutOpenWindowClass
.getConstructor(int.class, String.class, IChatBaseComponentClass, int.class)
.newInstance(c, "minecraft:anvil", inventoryTitle, 0);
}
NMSUtil.sendPacket(this.player, packet);
Field activeContainerField = NMSUtil.getField(EntityHumanClass, "activeContainer", true);
if (activeContainerField != null) {
activeContainerField.set(entityPlayer, container);
NMSUtil.getField(ContainerClass, "windowId", true).set(activeContainerField.get(entityPlayer), c);
Method addSlotListenerMethod = activeContainerField.get(entityPlayer).getClass().getMethod("addSlotListener", ICraftingClass);
addSlotListenerMethod.invoke(activeContainerField.get(entityPlayer), entityPlayer);
if (NMSUtil.getVersionNumber() > 13) {
ContainerClass.getMethod("setTitle", IChatBaseComponentClass).invoke(container, inventoryTitle);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void destroy() {
this.player = null;
this.items = null;
HandlerList.unregisterAll(this.listener);
this.listener = null;
}
private OnClose getOnClose() {
return this.onClose;
}
public void setOnClose(OnClose onClose) {
this.onClose = onClose;
}
public enum AnvilSlot {
INPUT_LEFT(0),
INPUT_RIGHT(1),
OUTPUT(2);
private int slot;
AnvilSlot(int slot) {
this.slot = slot;
}
public static AnvilSlot bySlot(int slot) {
for (AnvilSlot anvilSlot : values()) {
if (anvilSlot.getSlot() == slot) {
return anvilSlot;
}
}
return null;
}
public int getSlot() {
return this.slot;
}
}
@FunctionalInterface
public interface AnvilClickEventHandler {
void onAnvilClick(AnvilClickEvent event);
}
public class AnvilClickEvent {
private AnvilSlot slot;
private String name;
private boolean close = true;
private boolean destroy = true;
public AnvilClickEvent(AnvilSlot slot, String name) {
this.slot = slot;
this.name = name;
}
public AnvilSlot getSlot() {
return this.slot;
}
public String getName() {
return this.name;
}
public boolean getWillClose() {
return this.close;
}
public void setWillClose(boolean close) {
this.close = close;
}
public boolean getWillDestroy() {
return this.destroy;
}
public void setWillDestroy(boolean destroy) {
this.destroy = destroy;
}
}
}

View File

@ -1,226 +0,0 @@
package com.songoda.ultimatestacker.utils.gui;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.utils.Methods;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public abstract class AbstractGUI implements Listener {
private static boolean listenersInitialized = false;
protected Player player;
protected Inventory inventory = null;
protected String setTitle = null;
protected boolean cancelBottom = false;
private Map<Range, Clickable> clickables = new HashMap<>();
private List<OnClose> onCloses = new ArrayList<>();
private Map<Range, Boolean> draggableRanges = new HashMap<>();
public AbstractGUI(Player player) {
this.player = player;
}
public static void initializeListeners(JavaPlugin plugin) {
if (listenersInitialized) return;
Bukkit.getPluginManager().registerEvents(new Listener() {
@EventHandler
public void onClickGUI(InventoryClickEvent event) {
Inventory inventory = event.getClickedInventory();
if (inventory == null) return;
AbstractGUI gui = getGUIFromInventory(inventory);
Player player = (Player) event.getWhoClicked();
boolean bottom = false;
InventoryType type = event.getClickedInventory().getType();
if (type != InventoryType.CHEST && type != InventoryType.PLAYER) return;
if (gui == null && event.getWhoClicked().getOpenInventory().getTopInventory() != null) {
Inventory top = event.getWhoClicked().getOpenInventory().getTopInventory();
gui = getGUIFromInventory(top);
if (gui != null && gui.cancelBottom) event.setCancelled(true);
bottom = true;
}
if (gui == null) return;
if (!bottom) event.setCancelled(true);
if (!gui.draggableRanges.isEmpty() && !bottom) {
for (Map.Entry<Range, Boolean> entry : gui.draggableRanges.entrySet()) {
Range range = entry.getKey();
if (range.getMax() == range.getMin() && event.getSlot() == range.getMin()
|| event.getSlot() >= range.getMin() && event.getSlot() <= range.getMax()) {
event.setCancelled(!entry.getValue());
if (!entry.getValue()) break;
}
}
}
Map<Range, Clickable> entries = new HashMap<>(gui.clickables);
for (Map.Entry<Range, Clickable> entry : entries.entrySet()) {
Range range = entry.getKey();
if (range.isBottom() && !bottom || !range.isBottom() && bottom || range.getClickType() != null && range.getClickType() != event.getClick())
continue;
if (event.getSlot() >= range.getMin() && event.getSlot() <= range.getMax()) {
entry.getValue().Clickable(player, inventory, event.getCursor(), event.getSlot(), event.getClick());
player.playSound(player.getLocation(), entry.getKey().getOnClickSound(), 1F, 1F);
}
}
}
@EventHandler
public void onCloseGUI(InventoryCloseEvent event) {
Inventory inventory = event.getInventory();
AbstractGUI gui = getGUIFromInventory(inventory);
if (gui == null || gui.inventory == null) return;
for (OnClose onClose : gui.onCloses) {
onClose.onClose((Player) event.getPlayer(), inventory);
}
}
private AbstractGUI getGUIFromInventory(Inventory inventory) {
if (inventory.getHolder() == null) return null;
InventoryHolder holder = inventory.getHolder();
if (!(holder instanceof GUIHolder)) return null;
return ((AbstractGUI.GUIHolder) holder).getGUI();
}
}, plugin);
listenersInitialized = true;
}
public void init(String title, int slots) {
if (inventory == null
|| inventory.getSize() != slots
|| ChatColor.translateAlternateColorCodes('&', title) != player.getOpenInventory().getTitle()) {
this.inventory = Bukkit.getServer().createInventory(new GUIHolder(), slots, Methods.formatTitle(title));
this.setTitle = Methods.formatText(title);
if (this.clickables.size() == 0)
registerClickables();
if (this.onCloses.size() == 0)
registerOnCloses();
}
constructGUI();
initializeListeners(UltimateStacker.getInstance());
player.openInventory(inventory);
}
public abstract void constructGUI();
protected void addDraggable(Range range, boolean option) {
this.draggableRanges.put(range, option);
}
protected void removeDraggable() {
this.draggableRanges.clear();
}
protected abstract void registerClickables();
protected abstract void registerOnCloses();
protected ItemStack createButton(int slot, Inventory inventory, ItemStack item, String name, String... lore) {
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', name));
if (lore != null && lore.length != 0) {
List<String> newLore = new ArrayList<>();
for (String line : lore) newLore.add(ChatColor.translateAlternateColorCodes('&', line));
meta.setLore(newLore);
}
item.setItemMeta(meta);
inventory.setItem(slot, item);
return item;
}
protected ItemStack createButton(int slot, ItemStack item, String name, String... lore) {
return createButton(slot, inventory, item, name, lore);
}
protected ItemStack createButton(int slot, Inventory inventory, Material material, String name, String... lore) {
return createButton(slot, inventory, new ItemStack(material), name, lore);
}
protected ItemStack createButton(int slot, Material material, String name, String... lore) {
return createButton(slot, inventory, new ItemStack(material), name, lore);
}
protected ItemStack createButton(int slot, Material material, String name, ArrayList<String> lore) {
return createButton(slot, material, name, lore.toArray(new String[0]));
}
protected void registerClickable(int min, int max, ClickType clickType, boolean bottom, Clickable clickable) {
clickables.put(new Range(min, max, clickType, bottom), clickable);
}
protected void registerClickable(int min, int max, ClickType clickType, Clickable clickable) {
registerClickable(min, max, clickType, false, clickable);
}
protected void registerClickable(int slot, ClickType clickType, Clickable clickable) {
registerClickable(slot, slot, clickType, false, clickable);
}
protected void registerClickable(int min, int max, Clickable clickable) {
registerClickable(min, max, null, false, clickable);
}
protected void registerClickable(int slot, boolean bottom, Clickable clickable) {
registerClickable(slot, slot, null, bottom, clickable);
}
protected void registerClickable(int slot, Clickable clickable) {
registerClickable(slot, slot, null, false, clickable);
}
protected void resetClickables() {
clickables.clear();
}
protected void registerOnClose(OnClose onClose) {
onCloses.add(onClose);
}
public Inventory getInventory() {
return inventory;
}
public class GUIHolder implements InventoryHolder {
@Override
public Inventory getInventory() {
return inventory;
}
public AbstractGUI getGUI() {
return AbstractGUI.this;
}
}
public String getSetTitle() {
return setTitle;
}
}

View File

@ -1,11 +0,0 @@
package com.songoda.ultimatestacker.utils.gui;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
public interface Clickable {
void Clickable(Player player, Inventory inventory, ItemStack cursor, int slot, ClickType type);
}

View File

@ -1,10 +0,0 @@
package com.songoda.ultimatestacker.utils.gui;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
public interface OnClose {
void onClose(Player player, Inventory inventory);
}

View File

@ -1,51 +0,0 @@
package com.songoda.ultimatestacker.utils.gui;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.utils.ServerVersion;
import org.bukkit.Sound;
import org.bukkit.event.inventory.ClickType;
public class Range {
private int min;
private int max;
private ClickType clickType;
private boolean bottom;
private Sound onClickSound;
public Range(int min, int max, ClickType clickType, boolean bottom) {
this.min = min;
this.max = max;
this.clickType = clickType;
this.bottom = bottom;
if (UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_9)) onClickSound = Sound.UI_BUTTON_CLICK;
}
public Range(int min, int max, Sound onClickSound, ClickType clickType, boolean bottom) {
this.min = min;
this.max = max;
this.onClickSound = onClickSound;
this.clickType = clickType;
this.bottom = bottom;
}
public int getMin() {
return min;
}
public int getMax() {
return max;
}
public ClickType getClickType() {
return clickType;
}
public boolean isBottom() {
return bottom;
}
public Sound getOnClickSound() {
return onClickSound;
}
}

View File

@ -1,302 +0,0 @@
package com.songoda.ultimatestacker.utils.locale;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* Assists in the utilization of localization files.
* Created to be used by the Songoda Team.
*
* @author Brianna O'Keefe - Songoda
*/
public class Locale {
private static final List<Locale> LOCALES = new ArrayList<>();
private static final Pattern NODE_PATTERN = Pattern.compile("(\\w+(?:\\.{1}\\w+)*)\\s*=\\s*\"(.*)\"");
private static final String FILE_EXTENSION = ".lang";
private static JavaPlugin plugin;
private static File localeFolder;
private final Map<String, String> nodes = new HashMap<>();
private static String defaultLocale;
private File file;
private String name;
/**
* Instantiate the Locale class for future use
*
* @param name the name of the instantiated language
*/
private Locale(String name) {
if (plugin == null)
return;
this.name = name;
String fileName = name + FILE_EXTENSION;
this.file = new File(localeFolder, fileName);
if (!this.reloadMessages()) return;
plugin.getLogger().info("Loaded locale \"" + fileName + "\"");
}
/**
* Initialize the class to load all existing language files and update them.
* This must be called before any other methods in this class as otherwise
* the methods will fail to invoke
*
* @param plugin the plugin instance
* @param defaultLocale the default language
*/
public Locale(JavaPlugin plugin, String defaultLocale) {
Locale.plugin = plugin;
Locale.localeFolder = new File(plugin.getDataFolder(), "locales/");
if (!localeFolder.exists()) localeFolder.mkdirs();
//Save the default locale file.
Locale.defaultLocale = defaultLocale;
saveLocale(defaultLocale);
for (File file : localeFolder.listFiles()) {
String fileName = file.getName();
if (!fileName.endsWith(FILE_EXTENSION)) continue;
String name = fileName.substring(0, fileName.lastIndexOf('.'));
if (name.split("_").length != 2) continue;
if (localeLoaded(name)) continue;
LOCALES.add(new Locale(name));
}
}
/**
* Save a locale file from the InputStream, to the locale folder
*
* @param fileName the name of the file to save
* @return true if the operation was successful, false otherwise
*/
public static boolean saveLocale(String fileName) {
return saveLocale(plugin.getResource(defaultLocale + FILE_EXTENSION), fileName);
}
/**
* Save a locale file from the InputStream, to the locale folder
*
* @param in file to save
* @param fileName the name of the file to save
* @return true if the operation was successful, false otherwise
*/
public static boolean saveLocale(InputStream in, String fileName) {
if (!localeFolder.exists()) localeFolder.mkdirs();
if (!fileName.endsWith(FILE_EXTENSION))
fileName = (fileName.lastIndexOf(".") == -1 ? fileName : fileName.substring(0, fileName.lastIndexOf('.'))) + FILE_EXTENSION;
File destinationFile = new File(localeFolder, fileName);
if (destinationFile.exists())
return compareFiles(in, destinationFile);
try (OutputStream outputStream = new FileOutputStream(destinationFile)) {
copy(in, outputStream);
fileName = fileName.substring(0, fileName.lastIndexOf('.'));
if (fileName.split("_").length != 2) return false;
LOCALES.add(new Locale(fileName));
if (defaultLocale == null) defaultLocale = fileName;
return true;
} catch (IOException e) {
return false;
}
}
// Write new changes to existing files, if any at all
private static boolean compareFiles(InputStream in, File existingFile) {
InputStream defaultFile =
in == null ? plugin.getResource((defaultLocale != null ? defaultLocale : "en_US") + FILE_EXTENSION) : in;
boolean changed = false;
List<String> defaultLines, existingLines;
try (BufferedReader defaultReader = new BufferedReader(new InputStreamReader(defaultFile));
BufferedReader existingReader = new BufferedReader(new FileReader(existingFile));
BufferedWriter writer = new BufferedWriter(new FileWriter(existingFile, true))) {
defaultLines = defaultReader.lines().collect(Collectors.toList());
existingLines = existingReader.lines().map(s -> s.split("\\s*=")[0]).collect(Collectors.toList());
for (String defaultValue : defaultLines) {
if (defaultValue.isEmpty() || defaultValue.startsWith("#")) continue;
String key = defaultValue.split("\\s*=")[0];
if (!existingLines.contains(key)) {
if (!changed) {
writer.newLine();
writer.newLine();
// Leave a note alerting the user of the newly added messages.
writer.write("# New messages for " + plugin.getName() + " v" + plugin.getDescription().getVersion() + ".");
// If changes were found outside of the default file leave a note explaining that.
if (in == null) {
writer.newLine();
writer.write("# These translations were found untranslated, join");
writer.newLine();
writer.write("# our translation Discord https://discord.gg/f7fpZEf");
writer.newLine();
writer.write("# to request an official update!");
}
}
writer.newLine();
writer.write(defaultValue);
changed = true;
}
}
if (in != null && !changed) compareFiles(null, existingFile);
} catch (IOException e) {
return false;
}
return changed;
}
/**
* Check whether a locale exists and is registered or not
*
* @param name the whole language tag (i.e. "en_US")
* @return true if it exists
*/
public static boolean localeLoaded(String name) {
for (Locale locale : LOCALES)
if (locale.getName().equals(name)) return true;
return false;
}
/**
* Get a locale by its entire proper name (i.e. "en_US")
*
* @param name the full name of the locale
* @return locale of the specified name
*/
public static Locale getLocale(String name) {
for (Locale locale : LOCALES)
if (locale.getName().equalsIgnoreCase(name)) return locale;
return null;
}
/**
* Clear the previous message cache and load new messages directly from file
*
* @return reload messages from file
*/
public boolean reloadMessages() {
if (!this.file.exists()) {
plugin.getLogger().warning("Could not find file for locale \"" + this.name + "\"");
return false;
}
this.nodes.clear(); // Clear previous data (if any)
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
for (int lineNumber = 0; (line = reader.readLine()) != null; lineNumber++) {
if (line.trim().isEmpty() || line.startsWith("#") /* Comment */) continue;
Matcher matcher = NODE_PATTERN.matcher(line);
if (!matcher.find()) {
System.err.println("Invalid locale syntax at (line=" + lineNumber + ")");
continue;
}
nodes.put(matcher.group(1), matcher.group(2));
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* Supply the Message object with the plugins prefix.
*
* @param message message to be applied
* @return applied message
*/
private Message supplyPrefix(Message message) {
return message.setPrefix(this.nodes.getOrDefault("general.nametag.prefix", "[Plugin]"));
}
/**
* Create a new unsaved Message
*
* @param message the message to create
* @return the created message
*/
public Message newMessage(String message) {
return supplyPrefix(new Message(message));
}
/**
* Get a message set for a specific node.
*
* @param node the node to get
* @return the message for the specified node
*/
public Message getMessage(String node) {
return this.getMessageOrDefault(node, node);
}
/**
* Get a message set for a specific node
*
* @param node the node to get
* @param defaultValue the default value given that a value for the node was not found
* @return the message for the specified node. Default if none found
*/
public Message getMessageOrDefault(String node, String defaultValue) {
return supplyPrefix(new Message(this.nodes.getOrDefault(node, defaultValue)));
}
/**
* Return the locale name (i.e. "en_US")
*
* @return the locale name
*/
public String getName() {
return name;
}
private static void copy(InputStream input, OutputStream output) {
int n;
byte[] buffer = new byte[1024 * 4];
try {
while ((n = input.read(buffer)) != -1) {
output.write(buffer, 0, n);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -1,115 +0,0 @@
package com.songoda.ultimatestacker.utils.locale;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
/**
* The Message object. This holds the message to be sent
* as well as the plugins prefix so that they can both be
* easily manipulated then deployed
*/
public class Message {
private String prefix = null;
private String message;
/**
* create a new message
*
* @param message the message text
*/
public Message(String message) {
this.message = message;
}
/**
* Format and send the held message to a player
*
* @param player player to send the message to
*/
public void sendMessage(Player player) {
player.sendMessage(this.getMessage());
}
/**
* Format and send the held message with the
* appended plugin prefix to a player
*
* @param player player to send the message to
*/
public void sendPrefixedMessage(Player player) {
player.sendMessage(this.getPrefixedMessage());
}
/**
* Format and send the held message to a player
*
* @param sender command sender to send the message to
*/
public void sendMessage(CommandSender sender) {
sender.sendMessage(this.getMessage());
}
/**
* Format and send the held message with the
* appended plugin prefix to a command sender
*
* @param sender command sender to send the message to
*/
public void sendPrefixedMessage(CommandSender sender) {
sender.sendMessage(this.getPrefixedMessage());
}
/**
* Format the held message and append the plugins
* prefix
*
* @return the prefixed message
*/
public String getPrefixedMessage() {
return ChatColor.translateAlternateColorCodes('&',(prefix == null ? "" : this.prefix)
+ " " + this.message);
}
/**
* Get and format the held message
*
* @return the message
*/
public String getMessage() {
return ChatColor.translateAlternateColorCodes('&', this.message);
}
/**
* Get the held message
*
* @return the message
*/
public String getUnformattedMessage() {
return this.message;
}
/**
* Replace the provided placeholder with the
* provided object
*
* @param placeholder the placeholder to replace
* @param replacement the replacement object
* @return the modified Message
*/
public Message processPlaceholder(String placeholder, Object replacement) {
this.message = message.replace("%" + placeholder + "%", replacement.toString());
return this;
}
Message setPrefix(String prefix) {
this.prefix = prefix;
return this;
}
@Override
public String toString() {
return this.message;
}
}

View File

@ -1,31 +0,0 @@
package com.songoda.ultimatestacker.utils.settings;
public enum Category {
MAIN("General settings and options."),
INTERFACES("These settings allow you to alter the way interfaces look.",
"They are used in GUI's to make paterns, change them up then open up a",
"GUI to see how it works."),
ENTITIES("Stacked Entity Settings."),
ITEMS("Stacked Item Settings."),
SPAWNERS("Stacked Spawner Settings."),
MySQL("Settings regarding the Database."),
SYSTEM("System related settings.");
private String[] comments;
Category(String... comments) {
this.comments = comments;
}
public String[] getComments() {
return comments;
}
}

View File

@ -1,295 +0,0 @@
package com.songoda.ultimatestacker.utils.settings;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.entity.Check;
import com.songoda.ultimatestacker.entity.Split;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
public enum Setting {
STACK_SEARCH_TICK_SPEED("Main.Stack Search Tick Speed", 5,
"The speed in which a new stacks will be created.",
"It is advised to keep this number low."),
DISABLED_WORLDS("Main.Disabled Worlds", Arrays.asList("World1", "World2", "World3"),
"Worlds that stacking doesn't happen in."),
STACK_ENTITIES("Entities.Enabled", true,
"Should entities be stacked?"),
NAME_FORMAT_ENTITY("Entities.Name Format", "&f{TYPE} &6{AMT}x",
"The text displayed above an entities head where {TYPE} refers to",
"The entities type and {AMT} is the amount currently stacked."),
SEARCH_RADIUS("Entities.Search Radius", 5,
"The distance entities must be to each other in order to stack."),
MAX_STACK_ENTITIES("Entities.Max Stack Size", 15,
"The max amount of entities in a single stack."),
MIN_STACK_ENTITIES("Entities.Min Stack Amount", 5,
"The minimum amount required before a stack can be formed.",
"Do not set this to lower than 2."),
MAX_PER_TYPE_STACKS_PER_CHUNK("Entities.Max Per Type Stacks Per Chunk", -1,
"The maximum amount of each entity type stack allowed in a chunk."),
STACK_WHOLE_CHUNK("Entities.Stack Whole Chunk", false,
"Should all qualifying entities in each chunk be stacked?",
"This will override the stacking radius."),
ENTITY_HOLOGRAMS("Entities.Holograms Enabled", true,
"Should holograms be displayed above stacked entities?"),
HOLOGRAMS_ON_LOOK_ENTITY("Entities.Only Show Holograms On Look", false,
"Only show nametags above an entities head when looking directly at them."),
CUSTOM_DROPS("Entities.Custom Drops", true,
"Should custom drops be enabled?"),
KILL_WHOLE_STACK_ON_DEATH("Entities.Kill Whole Stack On Death", false,
"Should killing a stack of entities kill the whole stack or",
"just one out of the stack? If you want only certain entities to be",
"effected by this you can configure it in the entities.yml"),
CLEAR_LAG("Entities.Clear Lag", false,
"When enabled, the plugin will hook into ClearLag and extend the",
"clear task to include stacked entities from this plugin. If this is enabled",
"the built in task will not run."),
INSTANT_KILL("Entities.Instant Kill", Arrays.asList("FALL", "DROWNING", "LAVA", "VOID"),
"Events that will trigger an entire stack to be killed.",
"It should be noted that this is useless if the above setting is true.",
"Any of the following can be added to the list:",
"CONTACT, ENTITY_ATTACK, ENTITY_SWEEP_ATTACK, PROJECTILE",
"SUFFOCATION, FALL, FIRE, FIRE_TICK",
"MELTING, LAVA, DROWNING, BLOCK_EXPLOSION",
"ENTITY_EXPLOSION, VOID, LIGHTNING, SUICIDE",
"STARVATION, POISON, MAGIC, WITHER",
"FALLING_BLOCK, THORNS, DRAGON_BREATH, CUSTOM",
"FLY_INTO_WALL, HOT_FLOOR, CRAMMING, DRYOUT"),
NO_EXP_INSTANT_KILL("Entities.No Exp For Instant Kills", false,
"Should no experience be dropped when an instant kill is performed?"),
STACK_CHECKS("Entities.Stack Checks", Arrays.asList(Check.values()).stream()
.filter(Check::isEnabledByDefault).map(Check::name).collect(Collectors.toList()),
"These are checks that are processed before an entity is stacked.",
"You can add and remove from the list at will.",
"The acceptable check options are:",
"SPAWN_REASON, NERFED, AGE, TICK_AGE, PHANTOM_SIZE",
"IS_TAMED, ANIMAL_OWNER, SKELETON_TYPE",
"ZOMBIE_BABY, SLIME_SIZE, PIG_SADDLE, SHEEP_SHEERED",
"SHEEP_COLOR, WOLF_COLLAR_COLOR, OCELOT_TYPE, HORSE_COLOR",
"HORSE_STYLE, HORSE_CARRYING_CHEST, HORSE_HAS_ARMOR",
"HORSE_HAS_SADDLE, HORSE_JUMP, RABBIT_TYPE, VILLAGER_PROFESSION",
"LLAMA_COLOR, LLAMA_STRENGTH, PARROT_TYPE, PUFFERFISH_STATE",
"TROPICALFISH_PATTERN, TROPICALFISH_BODY_COLOR, TROPICALFISH_PATTERN_COLOR"),
SPLIT_CHECKS("Entities.Split Checks", Arrays.asList(Split.values()).stream()
.map(Split::name).collect(Collectors.toList()),
"These are checks that when achieved will break separate a single entity",
"from a stack."),
KEEP_FIRE("Entities.Keep Fire", true,
"Should fire ticks persist to the next entity when an entity dies?"),
KEEP_POTION("Entities.Keep Potion Effects", true,
"Should potion effects persist to the next entity when an entity dies?"),
CARRY_OVER_LOWEST_HEALTH("Entities.Carry Over Lowest Health", false,
"Should the lowest health be carried over when stacked?",
"This should not be used in collaboration with 'Stack Entity Health'.",
"If it is used this setting will be overrode."),
ONLY_STACK_FROM_SPAWNERS("Entities.Only Stack From Spawners", false,
"Should entities only be stacked if they originate from a spawner?",
"It should be noted that the identifier that tells the plugin",
"if the entity originated from a spawner or not is wiped on",
"server restart."),
STACK_REASONS("Entities.Stack Reasons", Arrays.asList(),
"This will limit mob stacking to mobs who spawned via the listed reasons.",
"This list is ignored if Only Stack From Spawners = true.",
"The following reasons can be added to the list:",
"NATURAL, JOCKEY, CHUNK_GEN, SPAWNER, EGG, SPAWNER_EGG, LIGHTNING, BUILD_SNOWMAN, ",
"BUILD_IRONGOLEM, BUILD_WITHER, VILLAGE_DEFENSE, VILLAGE_INVASION, BREEDING,",
"SLIME_SPLIT, REINFORCEMENTS, NETHER_PORTAL, DISPENSE_EGG, INFECTION,",
"CURED, OCELOT_BABY, SILVERFISH_BLOCK, MOUNT, TRAP, ENDER_PEARL, ",
"SHOULDER_ENTITY, DROWNED, SHEARED, EXPLOSION"
),
CARRY_OVER_METADATA_ON_DEATH("Entities.Carry Over Metadata On Death", true,
"With this enabled any metadata assigned from supported plugins such",
"as EpicSpawners and mcMMO will be preserved when the entity is killed."),
ONLY_STACK_ON_SURFACE("Entities.Only Stack On Surface", true,
"Should entities only be stacked if they are touching the ground",
"or swimming? This does not effect flying entities."),
STACK_ENTITY_HEALTH("Entities.Stack Entity Health", true,
"Should entity health be stacked? When enabled Entity stacks will",
"remember the health of all entities inside of the stack. This",
"works the best with 'Only Stack On Surface enabled' as entities",
"falling out of grinders may stack before hitting the ground."),
ONLY_STACK_FLYING_DOWN("Entities.Only Stack Flying Down", true,
"Should entities that fly only stack with entities that are lower on the",
"Y axis. This is important for grinders so that flying entities don't continuously",
"stack upwards to a higher up entity."),
STACK_ITEMS("Items.Enabled", true,
"Should items be stacked?"),
ITEM_HOLOGRAMS("Items.Holograms Enabled", true,
"Should holograms be displayed above stacked items?"),
ITEM_HOLOGRAM_SINGLE("Items.Show Hologram For Single", true,
"Should holograms be displayed above items when there is only a single",
"item in the stack?"),
ITEM_HOLOGRAM_BLACKLIST("Items.Show Holograms For Blacklisted Items", true,
"Should items that are blacklisted display holograms?"),
MAX_STACK_ITEMS("Items.Max Stack Size", 512,
"The max stack size for items.",
"Currently this can only be set to a max of 120."),
NAME_FORMAT_ITEM("Items.Name Format", "&f{TYPE} &r[&6{AMT}x]",
"The text displayed above a dropped item."),
NAME_FORMAT_RESET("Items.Name Format Reset", true,
"Should color codes in dropped item names be removed?",
"This is added only because it looks smoother in game. This is only visual and",
"doesn't actually effect the item."),
ITEM_BLACKLIST("Items.Blacklist", Collections.singletonList("EGG"),
"Items included in this list will stack to default Minecraft amounts.",
"Material list: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html",
"Leave this empty by using \"blacklist: []\" if you do not wish to disable",
"stacking for any items."),
ITEM_WHITELIST("Items.Whitelist", new ArrayList(),
"Items included in this whitelist will be stacked.",
"Material list: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html",
"Leave this empty by using \"whitelist: []\" if you want everything to be stacked.",
"Items not in this list will act as if they are blacklisted."),
SHOW_STACK_SIZE_SINGLE("Items.Show Stack Size For Single", false,
"When enabled stack sizes for a stack with a single item will",
"not display the stack size. The stack size will be added",
"for stacks containing two or more items."),
SPAWNERS_ENABLED("Spawners.Enabled", true,
"Should spawners be stacked?"),
SPAWNER_HOLOGRAMS("Spawners.Holograms Enabled", true,
"Should holograms be displayed above stacked spawners?"),
EGGS_CONVERT_SPAWNERS("Spawners.Eggs Convert Spawners", true,
"Should eggs convert spawners? If enabled you will",
"still need to give perms for it to work."),
MAX_STACK_SPAWNERS("Spawners.Max Stack Size", 5,
"What should the max a spawner can stack to be?"),
SNEAK_FOR_STACK("Spawners.Sneak To Receive A Stacked Spawner", true,
"Toggle ability to receive a stacked spawner when breaking a spawner while sneaking."),
SPAWNERS_DONT_EXPLODE("Spawners.Prevent Spawners From Exploding", false,
"Should spawners not break when blown up?"),
EXPLOSION_DROP_CHANCE_TNT("Spawners.Chance On TNT Explosion", "100%",
"Chance of a TNT explosion dropping a spawner."),
EXPLOSION_DROP_CHANCE_CREEPER("Spawners.Chance On Creeper Explosion", "100%",
"Chance of a creeper explosion dropping a spawner."),
NAME_FORMAT_SPAWNER("Spawners.Name Format", "&f{TYPE} Spawner &6{AMT}x",
"The text displayed above a stacked spawner where {TYPE} refers to",
"The entities type and {AMT} is the amount currently stacked."),
LANGUGE_MODE("System.Language Mode", "en_US",
"The enabled language file.",
"More language files (if available) can be found in the plugins data folder."),
MYSQL_ENABLED("MySQL.Enabled", false, "Set to 'true' to use MySQL instead of SQLite for data storage."),
MYSQL_HOSTNAME("MySQL.Hostname", "localhost"),
MYSQL_PORT("MySQL.Port", 3306),
MYSQL_DATABASE("MySQL.Database", "your-database"),
MYSQL_USERNAME("MySQL.Username", "user"),
MYSQL_PASSWORD("MySQL.Password", "pass"),
MYSQL_USE_SSL("MySQL.Use SSL", false);
private String setting;
private Object option;
private String[] comments;
Setting(String setting, Object option, String... comments) {
this.setting = setting;
this.option = option;
this.comments = comments;
}
Setting(String setting, Object option) {
this.setting = setting;
this.option = option;
this.comments = null;
}
public static Setting getSetting(String setting) {
List<Setting> settings = Arrays.stream(values()).filter(setting1 -> setting1.setting.equals(setting)).collect(Collectors.toList());
if (settings.isEmpty()) return null;
return settings.get(0);
}
public String getSetting() {
return setting;
}
public Object getOption() {
return option;
}
public String[] getComments() {
return comments;
}
public List<Integer> getIntegerList() {
return UltimateStacker.getInstance().getConfig().getIntegerList(setting);
}
public List<String> getStringList() {
return UltimateStacker.getInstance().getConfig().getStringList(setting);
}
public boolean getBoolean() {
return UltimateStacker.getInstance().getConfig().getBoolean(setting);
}
public int getInt() {
return UltimateStacker.getInstance().getConfig().getInt(setting);
}
public long getLong() {
return UltimateStacker.getInstance().getConfig().getLong(setting);
}
public String getString() {
return UltimateStacker.getInstance().getConfig().getString(setting);
}
public char getChar() {
return UltimateStacker.getInstance().getConfig().getString(setting).charAt(0);
}
public double getDouble() {
return UltimateStacker.getInstance().getConfig().getDouble(setting);
}
}

View File

@ -1,311 +0,0 @@
package com.songoda.ultimatestacker.utils.settings;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.utils.Methods;
import com.songoda.ultimatestacker.utils.ServerVersion;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.io.*;
import java.util.*;
/**
* Created by songoda on 6/4/2017.
*/
public class SettingsManager implements Listener {
private final UltimateStacker plugin;
private Map<Player, String> cat = new HashMap<>();
private Map<Player, String> current = new HashMap<>();
public SettingsManager(UltimateStacker plugin) {
this.plugin = plugin;
Bukkit.getPluginManager().registerEvents(this, plugin);
}
@EventHandler
public void onInventoryClick(InventoryClickEvent event) {
if (event.getView().getType() != InventoryType.CHEST) return;
ItemStack clickedItem = event.getCurrentItem();
if (event.getInventory() != event.getWhoClicked().getOpenInventory().getTopInventory()
|| clickedItem == null || !clickedItem.hasItemMeta()
|| !clickedItem.getItemMeta().hasDisplayName()) {
return;
}
if (event.getView().getTitle().equals(plugin.getName() + " Settings Manager")) {
event.setCancelled(true);
if (clickedItem.getType().name().contains("STAINED_GLASS")) return;
String type = ChatColor.stripColor(clickedItem.getItemMeta().getDisplayName());
this.cat.put((Player) event.getWhoClicked(), type);
this.openEditor((Player) event.getWhoClicked());
} else if (event.getView().getTitle().equals(plugin.getName() + " Settings Editor")) {
event.setCancelled(true);
if (clickedItem.getType().name().contains("STAINED_GLASS")) return;
Player player = (Player) event.getWhoClicked();
String key = cat.get(player) + "." + ChatColor.stripColor(clickedItem.getItemMeta().getDisplayName());
if (plugin.getConfig().get(key).getClass().getName().equals("java.lang.Boolean")) {
this.plugin.getConfig().set(key, !plugin.getConfig().getBoolean(key));
this.finishEditing(player);
} else {
this.editObject(player, key);
}
}
}
@EventHandler
public void onChat(AsyncPlayerChatEvent event) {
Player player = event.getPlayer();
if (!current.containsKey(player)) return;
String value = current.get(player);
FileConfiguration config = plugin.getConfig();
if (config.isLong(value)) {
config.set(value, Long.parseLong(event.getMessage()));
} else if (config.isInt(value)) {
config.set(value, Integer.parseInt(event.getMessage()));
} else if (config.isDouble(value)) {
config.set(value, Double.parseDouble(event.getMessage()));
} else if (config.isString(value)) {
config.set(value, event.getMessage());
}
Bukkit.getScheduler().scheduleSyncDelayedTask(UltimateStacker.getInstance(), () ->
this.finishEditing(player), 0L);
event.setCancelled(true);
}
private void finishEditing(Player player) {
this.current.remove(player);
this.saveConfig();
this.openEditor(player);
}
private void editObject(Player player, String current) {
this.current.put(player, ChatColor.stripColor(current));
player.closeInventory();
player.sendMessage("");
player.sendMessage(Methods.formatText("&7Please enter a value for &6" + current + "&7."));
if (plugin.getConfig().isInt(current) || plugin.getConfig().isDouble(current)) {
player.sendMessage(Methods.formatText("&cUse only numbers."));
}
player.sendMessage("");
}
public void openSettingsManager(Player player) {
Inventory inventory = Bukkit.createInventory(null, 27, plugin.getName() + " Settings Manager");
ItemStack glass = Methods.getGlass();
for (int i = 0; i < inventory.getSize(); i++) {
inventory.setItem(i, glass);
}
int slot = 10;
for (String key : plugin.getConfig().getDefaultSection().getKeys(false)) {
ItemStack item = new ItemStack(plugin.isServerVersionAtLeast(ServerVersion.V1_13) ? Material.LEGACY_WOOL : Material.valueOf("WOOL"), 1, (byte) (slot - 9));
ItemMeta meta = item.getItemMeta();
meta.setLore(Collections.singletonList(Methods.formatText("&6Click To Edit This Category.")));
meta.setDisplayName(Methods.formatText("&f&l" + key));
item.setItemMeta(meta);
inventory.setItem(slot, item);
slot++;
}
player.openInventory(inventory);
}
private void openEditor(Player player) {
Inventory inventory = Bukkit.createInventory(null, 54, plugin.getName() + " Settings Editor");
FileConfiguration config = plugin.getConfig();
int slot = 0;
for (String key : config.getConfigurationSection(cat.get(player)).getKeys(true)) {
String fKey = cat.get(player) + "." + key;
ItemStack item = new ItemStack(Material.DIAMOND_HELMET);
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(Methods.formatText("&6" + key));
List<String> lore = new ArrayList<>();
if (config.isBoolean(fKey)) {
item.setType(Material.LEVER);
lore.add(Methods.formatText(config.getBoolean(fKey) ? "&atrue" : "&cfalse"));
} else if (config.isString(fKey)) {
item.setType(Material.PAPER);
lore.add(Methods.formatText("&7" + config.getString(fKey)));
} else if (config.isInt(fKey)) {
item.setType(plugin.isServerVersionAtLeast(ServerVersion.V1_13) ? Material.CLOCK : Material.valueOf("WATCH"));
lore.add(Methods.formatText("&7" + config.getInt(fKey)));
} else if (config.isLong(fKey)) {
item.setType(plugin.isServerVersionAtLeast(ServerVersion.V1_13) ? Material.CLOCK : Material.valueOf("WATCH"));
lore.add(Methods.formatText("&7" + config.getLong(fKey)));
} else if (config.isDouble(fKey)) {
item.setType(plugin.isServerVersionAtLeast(ServerVersion.V1_13) ? Material.CLOCK : Material.valueOf("WATCH"));
lore.add(Methods.formatText("&7" + config.getDouble(fKey)));
}
Setting setting = Setting.getSetting(fKey);
if (setting != null && setting.getComments() != null) {
lore.add("");
String comment = String.join(" ", setting.getComments());
int lastIndex = 0;
for (int n = 0; n < comment.length(); n++) {
if (n - lastIndex < 30)
continue;
if (comment.charAt(n) == ' ') {
lore.add(Methods.formatText("&8" + comment.substring(lastIndex, n).trim()));
lastIndex = n;
}
}
if (lastIndex - comment.length() < 30)
lore.add(Methods.formatText("&8" + comment.substring(lastIndex).trim()));
}
meta.setLore(lore);
item.setItemMeta(meta);
inventory.setItem(slot, item);
slot++;
}
player.openInventory(inventory);
}
public void reloadConfig() {
plugin.reloadConfig();
this.setupConfig();
}
public void setupConfig() {
FileConfiguration config = plugin.getConfig();
for (Setting setting : Setting.values()) {
config.addDefault(setting.getSetting(), setting.getOption());
}
plugin.getConfig().options().copyDefaults(true);
saveConfig();
}
private void saveConfig() {
String dump = plugin.getConfig().saveToString();
StringBuilder config = new StringBuilder();
BufferedReader bufReader = new BufferedReader(new StringReader(dump));
try {
boolean first = true;
String line;
int currentTab = 0;
String category = "";
while ((line = bufReader.readLine()) != null) {
if (line.trim().startsWith("#")) continue;
int tabChange = line.length() - line.trim().length();
if (currentTab != tabChange) {
category = category.contains(".") && tabChange != 0 ? category.substring(0, category.indexOf(".")) : "";
currentTab = tabChange;
}
if (line.endsWith(":")) {
bufReader.mark(1000);
String found = bufReader.readLine();
bufReader.reset();
if (!found.trim().startsWith("-")) {
String newCategory = line.substring(0, line.length() - 1).trim();
if (category.equals(""))
category = newCategory;
else
category += "." + newCategory;
currentTab = tabChange + 2;
if (!first) {
config.append("\n\n");
} else {
first = false;
}
if (!category.contains("."))
config.append("#").append("\n");
try {
Category categoryObj = Category.valueOf(category.toUpperCase()
.replace(" ", "_")
.replace(".", "_"));
config.append(new String(new char[tabChange]).replace('\0', ' '));
for (String l : categoryObj.getComments())
config.append("# ").append(l).append("\n");
} catch (IllegalArgumentException e) {
config.append("# ").append(category).append("\n");
}
if (!category.contains("."))
config.append("#").append("\n");
config.append(line).append("\n");
continue;
}
}
if (line.trim().startsWith("-")) {
config.append(line).append("\n");
continue;
}
String key = category + "." + (line.split(":")[0].trim());
for (Setting setting : Setting.values()) {
if (!setting.getSetting().equals(key) || setting.getComments() == null) continue;
config.append(" ").append("\n");
for (String l : setting.getComments()) {
config.append(new String(new char[currentTab]).replace('\0', ' '));
config.append("# ").append(l).append("\n");
}
}
config.append(line).append("\n");
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (!plugin.getDataFolder().exists())
plugin.getDataFolder().mkdir();
BufferedWriter writer =
new BufferedWriter(new FileWriter(new File(plugin.getDataFolder() + File.separator + "config.yml")));
writer.write(config.toString());
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -1,32 +0,0 @@
package com.songoda.ultimatestacker.utils.updateModules;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.update.Module;
import com.songoda.update.Plugin;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
public class LocaleModule implements Module {
@Override
public void run(Plugin plugin) {
JSONObject json = plugin.getJson();
try {
JSONArray files = (JSONArray) json.get("neededFiles");
for (Object o : files) {
JSONObject file = (JSONObject) o;
if (file.get("type").equals("locale")) {
InputStream in = new URL((String) file.get("link")).openStream();
UltimateStacker.getInstance().getLocale().saveLocale(in, (String) file.get("name"));
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -1,100 +0,0 @@
package com.songoda.ultimatestacker.utils.version;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.lang.reflect.Field;
public class NMSUtil {
public static String getVersion() {
String name = Bukkit.getServer().getClass().getPackage().getName();
return name.substring(name.lastIndexOf('.') + 1) + ".";
}
public static int getVersionNumber() {
String name = getVersion().substring(3);
return Integer.valueOf(name.substring(0, name.length() - 4));
}
public static int getVersionReleaseNumber() {
String NMSVersion = getVersion();
return Integer.valueOf(NMSVersion.substring(NMSVersion.length() - 2).replace(".", ""));
}
public static Class<?> getNMSClass(String className) {
try {
String fullName = "net.minecraft.server." + getVersion() + className;
Class<?> clazz = Class.forName(fullName);
return clazz;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static Class<?> getCraftClass(String className) {
try {
String fullName = "org.bukkit.craftbukkit." + getVersion() + className;
Class<?> clazz = Class.forName(fullName);
return clazz;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static Field getField(Class<?> clazz, String name, boolean declared) {
try {
Field field;
if (declared) {
field = clazz.getDeclaredField(name);
} else {
field = clazz.getField(name);
}
field.setAccessible(true);
return field;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static Object getFieldObject(Object object, Field field) {
try {
return field.get(object);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void setField(Object object, String fieldName, Object fieldValue, boolean declared) {
try {
Field field;
if (declared) {
field = object.getClass().getDeclaredField(fieldName);
} else {
field = object.getClass().getField(fieldName);
}
field.setAccessible(true);
field.set(object, fieldValue);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void sendPacket(Player player, Object packet) {
try {
Object handle = player.getClass().getMethod("getHandle").invoke(player);
Object playerConnection = handle.getClass().getField("playerConnection").get(handle);
playerConnection.getClass().getMethod("sendPacket", getNMSClass("Packet")).invoke(playerConnection, packet);
} catch (Exception e) {
e.printStackTrace();
}
}
}