diff --git a/pom.xml b/pom.xml index 8c507307..ab2300f0 100644 --- a/pom.xml +++ b/pom.xml @@ -6,12 +6,12 @@ xyz.geik.farmer Farmer - 1.0-SNAPSHOT + v6-b001 org.cas.osd.platform.ciam.shaded - 1.8 - 1.8 + 8 + 8 UTF-8 @@ -21,7 +21,7 @@ org.spigotmc spigot-api - 1.19.3-R0.1-SNAPSHOT + 1.20.1-R0.1-SNAPSHOT provided @@ -33,23 +33,23 @@ - com.github.MilkBowl - VaultAPI - 9520d8847e + com.github.milkbowl + Vault + 1.7.3 provided org.projectlombok lombok - 1.18.22 + 1.18.26 provided - com.github.Son-Hukumdar + com.github.poyrazinan SimplixStorage - 1.0.0-RELOADED + -ae92994823-1 @@ -93,17 +93,24 @@ 3.0.9.4 provided + + + com.palmergames.bukkit.towny + towny + 0.99.5.0 + provided + com.github.cryptomorin XSeries - 9.3.0 + 9.4.0 de.tr7zw item-nbt-api-plugin - 2.11.1 + 2.11.3 @@ -112,6 +119,12 @@ 2022.6 provided + + + com.zaxxer + HikariCP + 5.0.1 + @@ -124,7 +137,7 @@ jitpack.io - https://jitpack.io + https://www.jitpack.io @@ -155,6 +168,11 @@ codemc-repo https://repo.codemc.org/repository/maven-public/ + + + glaremasters repo + https://repo.glaremasters.me/repository/towny/ + @@ -163,7 +181,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.4.1 + 3.5.0 false true @@ -200,6 +218,10 @@ de.tr7zw.nbtapi xyz.geik.farmer.shades.nbtapi + + com.zaxxer.hikari + xyz.geik.farmer.shades.hikari + @@ -211,6 +233,16 @@ + + org.apache.maven.plugins + maven-compiler-plugin + 3.11.0 + + + org.apache.maven.plugins + maven-resources-plugin + 3.3.1 + \ No newline at end of file diff --git a/src/main/java/xyz/geik/farmer/Main.java b/src/main/java/xyz/geik/farmer/Main.java index 891a4023..080dc091 100644 --- a/src/main/java/xyz/geik/farmer/Main.java +++ b/src/main/java/xyz/geik/farmer/Main.java @@ -2,9 +2,9 @@ import de.leonhard.storage.Config; import lombok.Getter; +import net.md_5.bungee.api.ChatColor; import net.milkbowl.vault.economy.Economy; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.event.Listener; import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.java.JavaPlugin; @@ -13,7 +13,9 @@ import xyz.geik.farmer.api.managers.FarmerManager; import xyz.geik.farmer.commands.Commands; import xyz.geik.farmer.commands.FarmerTabComplete; -import xyz.geik.farmer.database.DBQueries; +import xyz.geik.farmer.database.MySQL; +import xyz.geik.farmer.database.SQL; +import xyz.geik.farmer.database.SQLite; import xyz.geik.farmer.helpers.ItemsLoader; import xyz.geik.farmer.helpers.Settings; import xyz.geik.farmer.integrations.Integrations; @@ -28,6 +30,8 @@ import java.util.HashMap; import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Main class of farmer @@ -42,6 +46,11 @@ public class Main extends JavaPlugin { */ public Map listenerList = new HashMap<>(); + /** + * SQL Manager + */ + private SQL sql; + /** * Instance of this class */ @@ -51,7 +60,7 @@ public class Main extends JavaPlugin { * Config files which using SimplixStorage API for it. * Also, you can find usage code of API on helpers#StorageAPI */ - private static Config configFile, itemsFile, langFile; + private static Config configFile, itemsFile, langFile, databaseFile; /** * Main integration of plugin integrations#Integrations @@ -73,6 +82,7 @@ public void onLoad() { configFile = FarmerAPI.getStorageManager().initConfig("config"); itemsFile = FarmerAPI.getStorageManager().initConfig("items"); langFile = FarmerAPI.getStorageManager().initLangFile(getConfigFile().getString("settings.lang")); + databaseFile = FarmerAPI.getStorageManager().initConfig("storage/database"); } /** @@ -91,10 +101,10 @@ public void onEnable() { FarmerLevel.loadLevels(); getCommand("farmer").setExecutor(new Commands()); getCommand("farmer").setTabCompleter(new FarmerTabComplete()); - DBQueries.createTable(); Integrations.registerIntegrations(); sendEnableMessage(); - DBQueries.loadAllFarmers(); + setDatabaseManager(); + this.sql.loadAllFarmers(); new ListenerRegister(); loadMetrics(); registerModules(); @@ -107,7 +117,7 @@ public void onEnable() { * can't handle async tasks while shutting down */ public void onDisable() { - DBQueries.updateAllFarmers(); + this.sql.updateAllFarmers(); } /** @@ -128,12 +138,26 @@ public void onDisable() { */ public static Config getLangFile() { return langFile; } + /** + * Gets database file + * @return Config file + */ + public static Config getDatabaseFile() { return databaseFile; } + /** * Gets instance * @return Main class of main */ public static Main getInstance() { return instance; } + /** + * Gets SQL Manager + * @return SQL Manager + */ + public SQL getSql() { + return this.sql; + } + /** * Gets Integration plugin instance * @return Integrations plugin of integration @@ -161,6 +185,15 @@ public static void setIntegration(Integrations data) { * @return String of replaced text */ public static @NotNull String color(String text) { + final Pattern pattern = Pattern.compile("#[a-fA-F0-9]{6}"); + if (Bukkit.getVersion().contains("1.16") || Bukkit.getVersion().contains("1.17") || Bukkit.getVersion().contains("1.18") || Bukkit.getVersion().contains("1.19") || Bukkit.getVersion().contains("1.20")) { + Matcher matcher = pattern.matcher(text); + while (matcher.find()) { + String color = text.substring(matcher.start(), matcher.end()); + text = text.replace(color, ChatColor.of(color) + ""); + matcher = pattern.matcher(text); + } + } return ChatColor.translateAlternateColorCodes('&', text); } @@ -198,6 +231,20 @@ private void loadMetrics() { })); } + /** + * Registering Database Manager + */ + private void setDatabaseManager() { + String sqlType = getDatabaseFile().getString("database.type"); + sqlType = sqlType.toLowerCase(); + + if (sqlType.equals("sqlite")) { + this.sql = new SQLite(); + } else if (sqlType.equals("mysql")) { + this.sql = new MySQL(); + } + } + /** * Register modules to this plugin */ diff --git a/src/main/java/xyz/geik/farmer/api/managers/DatabaseManager.java b/src/main/java/xyz/geik/farmer/api/managers/DatabaseManager.java index dca28d14..d6d53e2f 100644 --- a/src/main/java/xyz/geik/farmer/api/managers/DatabaseManager.java +++ b/src/main/java/xyz/geik/farmer/api/managers/DatabaseManager.java @@ -1,6 +1,6 @@ package xyz.geik.farmer.api.managers; -import xyz.geik.farmer.database.DBConnection; +import xyz.geik.farmer.Main; import java.sql.Connection; @@ -10,6 +10,8 @@ */ public class DatabaseManager { + // MAYBE NOT WORK WITH NEW SYSTEM + /** * Connects database of farmer. * @@ -17,7 +19,7 @@ public class DatabaseManager { * @see Connection */ public static Connection connectDatabase() { - return DBConnection.connect(); + return (Connection) Main.getInstance().getSql(); } -} +} \ No newline at end of file diff --git a/src/main/java/xyz/geik/farmer/api/managers/FarmerManager.java b/src/main/java/xyz/geik/farmer/api/managers/FarmerManager.java index b3eb18aa..34d166dd 100644 --- a/src/main/java/xyz/geik/farmer/api/managers/FarmerManager.java +++ b/src/main/java/xyz/geik/farmer/api/managers/FarmerManager.java @@ -5,14 +5,11 @@ import org.bukkit.Location; import xyz.geik.farmer.Main; import xyz.geik.farmer.api.FarmerAPI; -import xyz.geik.farmer.database.DBConnection; -import xyz.geik.farmer.database.DBQueries; import xyz.geik.farmer.model.Farmer; import xyz.geik.farmer.model.user.FarmerPerm; import xyz.geik.farmer.model.user.User; import java.util.HashMap; -import java.util.Objects; import java.util.Set; import java.util.UUID; @@ -46,7 +43,7 @@ public class FarmerManager { */ public boolean removeFarmer(String regionId) { if (getFarmers().containsKey(regionId)) { - DBQueries.removeFarmer(getFarmers().get(regionId)); + Main.getInstance().getSql().removeFarmer(getFarmers().get(regionId)); return true; } return false; @@ -67,7 +64,7 @@ public void changeOwner(UUID oldOwner, UUID newOwner, String regionId) { getFarmers().remove(regionId); FarmerAPI.getFarmerManager().removeFarmer(regionId); // Replaces old owner role to coop on db - User.updateRole(oldOwner, 1, newFarmer.getId()); + Main.getInstance().getSql().updateRole(oldOwner, 1, newFarmer.getId()); // Replace old owner role to coop on cache newFarmer.getUsers().stream().filter(user -> user.getUuid().equals(oldOwner)).findFirst().get().setPerm(FarmerPerm.MEMBER); // Adds player if not exists on farmer users @@ -83,10 +80,10 @@ public void changeOwner(UUID oldOwner, UUID newOwner, String regionId) { * * @author WaterArchery */ - newFarmer.addUser(newOwner, Bukkit.getOfflinePlayer(newOwner).getName(), FarmerPerm.OWNER); + farmer.addUser(newOwner, Bukkit.getOfflinePlayer(newOwner).getName(), FarmerPerm.OWNER); else { // Replaces new owner role to owner on db - User.updateRole(newOwner, 2, newFarmer.getId()); + Main.getInstance().getSql().updateRole(newOwner, 2, newFarmer.getId()); // Replaces new owner role to owner on cache newFarmer.getUsers().stream().filter(user -> user.getUuid().equals(newOwner)).findFirst().get().setPerm(FarmerPerm.OWNER); } @@ -95,7 +92,7 @@ public void changeOwner(UUID oldOwner, UUID newOwner, String regionId) { newFarmer.setRegionID(newOwner.toString()); getFarmers().put(newFarmer.getRegionID(), newFarmer); // Saves farmer to db - newFarmer.saveFarmer(Objects.requireNonNull(DBConnection.connect())); + farmer.saveFarmer(); } } diff --git a/src/main/java/xyz/geik/farmer/commands/Commands.java b/src/main/java/xyz/geik/farmer/commands/Commands.java index c4609b6e..1ea5605f 100644 --- a/src/main/java/xyz/geik/farmer/commands/Commands.java +++ b/src/main/java/xyz/geik/farmer/commands/Commands.java @@ -10,7 +10,6 @@ import xyz.geik.farmer.Main; import xyz.geik.farmer.api.FarmerAPI; import xyz.geik.farmer.api.managers.FarmerManager; -import xyz.geik.farmer.database.DBQueries; import xyz.geik.farmer.guis.BuyGui; import xyz.geik.farmer.guis.MainGui; import xyz.geik.farmer.helpers.ItemsLoader; @@ -40,62 +39,114 @@ public class Commands implements CommandExecutor { @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { // Checking if sender instanceof player - if (sender instanceof Player){ + if (sender instanceof Player) { Player player = (Player) sender; - // No arg main command - if (args.length == 0) + if (args.length == 0) { farmerBaseCommand(player); - // 1 arg for 1 arg commands - else if (args.length == 1) + } else if (args.length == 1) { oneArgCommands(player, args[0]); - else if (args.length == 3) + } else if (args.length == 2) { + twoArgCommands(player, args); + } else if (args.length == 3) { VoucherCommand.give(sender, args); - } - // Also console section here for reload command. - else { + } + } else { if (args.length == 1) { if (args[0].equalsIgnoreCase("reload")) reloadCommand(sender); + else if (args[0].equals("fix")) { + int player_count = Bukkit.getOnlinePlayers().size(); + if (player_count == 0) + Main.getInstance().getSql().fixDatabase(); + else + Main.getInstance().getLogger().info("You can run this command only when no player online!"); + } else if (args[0].equalsIgnoreCase("about")) { + aboutCommand(sender); + } } else if (args.length == 3) - VoucherCommand.give(sender, args); + VoucherCommand.give(sender, args); } return false; } + /** - * One arg commands which reload, manage, info and remove commands - * Manage usable by administrator or owner of farmer - * Remove, reload and info are administrator commands + * Base command for coop, member, owner + * It basically open farmer buy gui unless don't have it. + * Open farmer inventory gui if has farmer. * * @param player - * @param arg */ - public void oneArgCommands(@NotNull Player player, String arg) { - // Checking perm if sender is player and if they don't have perm just returns task - if ((!player.hasPermission("farmer.admin") && !player.getName().equalsIgnoreCase("Geyik")) - && !arg.equalsIgnoreCase("manage") && !arg.equalsIgnoreCase("remove")) { - player.sendMessage(Main.getLangFile().getText("noPerm")); - return; - } - // Check world is suitable for farmer - if (!Settings.isWorldAllowed(player.getWorld().getName()) - && !arg.equalsIgnoreCase("reload")) { + private void farmerBaseCommand(@NotNull Player player) { + if (!Settings.isWorldAllowed(player.getWorld().getName())) { player.sendMessage(Main.getLangFile().getText("wrongWorld")); return; } - // Reload command caller - if (arg.equalsIgnoreCase("reload")) - reloadCommand(player); - // Manage command caller - else if (arg.equalsIgnoreCase("manage")) - farmerBaseCommand(player); - // Info command caller - else if (arg.equalsIgnoreCase("info")) - infoCommand(player); - // Remove command caller - else if (arg.equalsIgnoreCase("remove")) - removeFarmerCommand(player); + String regionID = getRegionID(player); + if (regionID == null) + player.sendMessage(Main.getLangFile().getText("noRegion")); + else if (!FarmerManager.getFarmers().containsKey(regionID)) { + // Using this uuid for owner check + UUID owner = Main.getIntegration().getOwnerUUID(regionID); + // Owner check for buy + if (owner.equals(player.getUniqueId())) { + if (Settings.buyFarmer) + BuyGui.showGui(player); + else { + Titles.sendTitle(player, Main.getLangFile().getText("buyDisabled.title"), + Main.getLangFile().getText("buyDisabled.subtitle")); + } + } + else + player.sendMessage(Main.getLangFile().getText("mustBeOwner")); + } else { + // Perm && user check + if (FarmerManager.getFarmers().get(regionID).getUsers().stream() + .anyMatch(usr -> (usr.getUuid().equals(player.getUniqueId())))) + MainGui.showGui(player, FarmerManager.getFarmers().get(regionID)); + else + player.sendMessage(Main.getLangFile().getText("noPerm")); + } + } + + /** + * Removes farmer from command sender. + * + * @param player + */ + private void selfRemoveCommand(@NotNull Player player) { + String regionID = getRegionID(player); + if (regionID == null) + player.sendMessage(Main.getLangFile().getText("noRegion")); + + UUID ownerUUID = Main.getIntegration().getOwnerUUID(regionID); + // Custom perm check for remove command + if (player.hasPermission("farmer.remove") && ownerUUID.equals(player.getUniqueId()) || player.hasPermission("farmer.admin")) { + // Removing by #FarmerAPI and sending message by result + boolean result = FarmerAPI.getFarmerManager().removeFarmer(regionID); + if (result) + player.sendMessage(Main.getLangFile().getText("removedFarmer")); + } else + player.sendMessage(Main.getLangFile().getText("noPerm")); + } + + /** + * Sends the player information about the Farmer plugin + * + * @param player + */ + private void aboutCommand(@NotNull CommandSender player) { + player.sendMessage(Main.color("&7&m----------------------------------------")); + player.sendMessage(Main.color("#FFA500 FARMER &7- &6v" + Main.getInstance().getDescription().getVersion())); + player.sendMessage(Main.color("#3CB371Author: #90EE90Geik")); + player.sendMessage(Main.color("#FF7F50Contributors: #FFA07A" + Main.getInstance().getDescription().getAuthors().stream().toArray())); + player.sendMessage(Main.color("#7289DADiscord: &7&ohttps://discord.geik.xyz")); + player.sendMessage(Main.color("#FFD700Website: &7&ohttps://geik.xyz")); + player.sendMessage(Main.color("&7&m----------------------------------------")); + player.sendMessage(Main.color("&aAPI: &7" + Main.getIntegration().getClass().getName())); + player.sendMessage(Main.color("&aActive Farmer: &7" + FarmerManager.getFarmers().size() )); + player.sendMessage(Main.color("&7&m----------------------------------------")); } /** @@ -106,22 +157,19 @@ else if (arg.equalsIgnoreCase("remove")) * @param player */ private void infoCommand(@NotNull Player player) { - // My debug command for bug reports - if (player.getName().equalsIgnoreCase("Geyik")) { - player.sendMessage(Main.color("&aVersion: &7" + Main.getInstance().getDescription().getVersion())); - player.sendMessage(Main.color("&aAPI: &7" + Main.getIntegration().getClass().getName())); - player.sendMessage(Main.color("&aActive Farmer: &7" + FarmerManager.getFarmers().size() )); - } - // Catching region id and checking is it null or don't have farmer - String regionID = Main.getIntegration().getRegionID(player.getLocation()); + String regionID = getRegionID(player); if (regionID == null) player.sendMessage(Main.getLangFile().getText("noRegion")); else if (!FarmerManager.getFarmers().containsKey(regionID)) player.sendMessage(Main.getLangFile().getText("noFarmer")); else { - // After all the checks loading farmer Farmer farmer = FarmerManager.getFarmers().get(regionID); player.sendMessage(Main.color("&c----------------------")); + player.sendMessage(Main.color("&bRegion ID: &f" + regionID)); + player.sendMessage(Main.color("&bID: &f" + farmer.getId())); + player.sendMessage(Main.color("&bOwner: &f" + Bukkit.getOfflinePlayer(farmer.getOwnerUUID()).getName())); + player.sendMessage(Main.color("&bLevel: &f" + FarmerLevel.getAllLevels().indexOf(farmer.getLevel()))); + player.sendMessage(Main.color("&c----------------------")); farmer.getUsers().stream().forEach(key -> { player.sendMessage(Main.color("&b" + Bukkit.getOfflinePlayer(key.getUuid()).getName() + " &f- &3" + key.getPerm().name())); @@ -143,11 +191,14 @@ else if (!FarmerManager.getFarmers().containsKey(regionID)) * @param sender */ private void reloadCommand(@NotNull CommandSender sender) { - // Creating time long for calculating time it takes. + if (!sender.hasPermission("farmer.admin")) { + sender.sendMessage(Main.getLangFile().getText("noPerm")); + return; + } Bukkit.getScheduler().runTaskAsynchronously(Main.getInstance(), () -> { long time = System.currentTimeMillis(); // Saves all farmer - DBQueries.updateAllFarmers(); + Main.getInstance().getSql().updateAllFarmers(); // Clears cached farmers FarmerManager.getFarmers().clear(); // Regenerates settings @@ -157,7 +208,7 @@ private void reloadCommand(@NotNull CommandSender sender) { // Reloading levels it also clears old list FarmerLevel.loadLevels(); // Reloading farmers again. - DBQueries.loadAllFarmers(); + Main.getInstance().getSql().loadAllFarmers(); FarmerAPI.getModuleManager().getModuleList().forEach(FarmerModule::onReload); // Sends message to sender who send this command and also calculating millisecond difference. sender.sendMessage(Main.getLangFile().getText("reloadSuccess").replace("%ms%", @@ -165,31 +216,75 @@ private void reloadCommand(@NotNull CommandSender sender) { }); } + /** + * One arg commands which about, info, reload and remove commands + * Manage usable by administrator or owner of farmer + * Remove, reload, about and info are administrator commands + * + * @param player + * @param arg + */ + public void oneArgCommands(@NotNull Player player, String arg) { + // Checking perm if sender is player and if they don't have perm just returns task + if ((!player.hasPermission("farmer.admin") && !player.getName().equalsIgnoreCase("Geyik")) && !arg.equalsIgnoreCase("remove")) { + player.sendMessage(Main.getLangFile().getText("noPerm")); + return; + } + // Check world is suitable for farmer + if (!Settings.isWorldAllowed(player.getWorld().getName()) + && !arg.equalsIgnoreCase("reload")) { + player.sendMessage(Main.getLangFile().getText("wrongWorld")); + return; + } + // About command caller + if (arg.equalsIgnoreCase("about")) { + aboutCommand(player); + // Info command caller + } else if (arg.equalsIgnoreCase("info")) { + infoCommand(player); + // Reload command caller + } else if (arg.equalsIgnoreCase("reload")) { + reloadCommand(player); + // Remove command caller + } else if (arg.equalsIgnoreCase("remove")) { + selfRemoveCommand(player); + } + } /** - * Removes farmer where command sender at. + * Two arg commands which open and remove commands + * Manage usable by administrator + * Remove and open are administrator commands * * @param player + * @param arg */ - private void removeFarmerCommand(Player player) { - // Checks if region id suitable for farmer - String regionID = getRegionID(player); - if (regionID == null) { - player.sendMessage(Main.getLangFile().getText("noRegion")); + public void twoArgCommands(@NotNull Player player, String @NotNull ... arg) { + if ((!player.hasPermission("farmer.admin"))) { + player.sendMessage(Main.getLangFile().getText("noPerm")); return; } + // Check world is suitable for farmer + if (!Settings.isWorldAllowed(player.getWorld().getName())) { + player.sendMessage(Main.getLangFile().getText("wrongWorld")); + return; + } + // Open command caller + if (arg[0].equalsIgnoreCase("open")) { + Player target = Bukkit.getOfflinePlayer(arg[1]).getPlayer(); + + String regionID = getRegionID(target); + if (regionID == null) + player.sendMessage(Main.getLangFile().getText("noRegion")); + + if (!FarmerManager.getFarmers().containsKey(regionID)) + player.sendMessage(Main.getLangFile().getText("noFarmer")); + else { + if (FarmerManager.getFarmers().get(regionID).getUsers().stream().anyMatch(usr -> (usr.getUuid().equals(target.getUniqueId())))) + MainGui.showGui(player, FarmerManager.getFarmers().get(regionID)); + } - UUID ownerUUID = Main.getIntegration().getOwnerUUID(regionID); - // Custom perm check for remove command - if ((player.hasPermission("farmer.remove") && ownerUUID.equals(player.getUniqueId())) - || player.hasPermission("farmer.admin")) { - // Removing by #FarmerAPI and sending message by result - boolean result = FarmerAPI.getFarmerManager().removeFarmer(regionID); - if (result) - player.sendMessage(Main.getLangFile().getText("removedFarmer")); } - else - player.sendMessage(Main.getLangFile().getText("noPerm")); } /** @@ -212,47 +307,4 @@ private String getRegionID(Player player) { return regionID; } - /** - * Base command for coop, member, owner - * and ofc for administrator. It basically - * open farmer buy gui unless don't have it. - * Open farmer inventory gui if has farmer. - * - * @param player - */ - private void farmerBaseCommand(Player player) { - // There is another world check - if (!Settings.isWorldAllowed(player.getWorld().getName())) { - player.sendMessage(Main.getLangFile().getText("wrongWorld")); - return; - } - // and also one more region check - String regionID = getRegionID(player); - if (regionID == null) - player.sendMessage(Main.getLangFile().getText("noRegion")); - else if (!FarmerManager.getFarmers().containsKey(regionID)) { - // Using this uuid for owner check - UUID owner = Main.getIntegration().getOwnerUUID(regionID); - // Owner check for buy - if (owner.equals(player.getUniqueId()) || player.hasPermission("farmer.admin")) { - if (Settings.buyFarmer) - BuyGui.showGui(player); - else { - Titles.sendTitle(player, Main.getLangFile().getText("buyDisabled.title"), - Main.getLangFile().getText("buyDisabled.subtitle")); - } - } - else - player.sendMessage(Main.getLangFile().getText("mustBeOwner")); - } - else { - // Perm && user check - if (player.hasPermission("farmer.admin") || - FarmerManager.getFarmers().get(regionID).getUsers().stream() - .anyMatch(usr -> (usr.getUuid().equals(player.getUniqueId())))) - MainGui.showGui(player, FarmerManager.getFarmers().get(regionID)); - else - player.sendMessage(Main.getLangFile().getText("noPerm")); - } - } } \ No newline at end of file diff --git a/src/main/java/xyz/geik/farmer/commands/FarmerTabComplete.java b/src/main/java/xyz/geik/farmer/commands/FarmerTabComplete.java index 80072d33..0092a700 100644 --- a/src/main/java/xyz/geik/farmer/commands/FarmerTabComplete.java +++ b/src/main/java/xyz/geik/farmer/commands/FarmerTabComplete.java @@ -4,20 +4,15 @@ import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabCompleter; -import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import xyz.geik.farmer.Main; -import xyz.geik.farmer.api.FarmerAPI; -import xyz.geik.farmer.api.managers.FarmerManager; -import xyz.geik.farmer.helpers.Settings; import xyz.geik.farmer.model.FarmerLevel; import xyz.geik.farmer.modules.voucher.Voucher; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; /** * Tab complete class which shown on up @@ -34,42 +29,37 @@ public class FarmerTabComplete implements TabCompleter { @Nullable @Override public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) { - List completes = new ArrayList<>(); - // if player has farmer.admin perm or player name is Geyik adding info and reload hover - // I probably should see this ^.^ - if (sender.hasPermission("farmer.admin") || sender.getName().equals("Geyik")) - completes.addAll(Arrays.asList("info", "reload", "give")); - try { - if (args.length > 1) - completes.clear(); - // checking if sender player - if (sender instanceof Player) { - Player player = (Player) sender; - if (args.length > 1 && Voucher.getInstance().isEnabled() && args[0].equalsIgnoreCase("give")) { - completes.clear(); - if (args.length == 2) - completes.addAll(Bukkit.getServer().getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toList())); - else if (args.length == 3) - for (int i = 1; i <= FarmerLevel.getAllLevels().size(); i++) - completes.add(String.valueOf(i)); - return completes; + if (sender.hasPermission("farmer.admin") || sender.getName().equals("Geyik")) { + if (args.length == 1) { + return Arrays.asList("about", "info", "reload", "give", "open", "remove", "fix"); + } + if (args.length > 1 && Voucher.getInstance().isEnabled() && args[0].equalsIgnoreCase("give")) { + if (args.length == 2) { + return online_players(); + } + else if (args.length == 3) { + for (int i = 1; i <= FarmerLevel.getAllLevels().size(); i++) { + return Arrays.asList(String.valueOf(i)); + } } - String regionID = Main.getIntegration().getRegionID(player.getLocation()); - // First creating a true object if world and region exists - boolean manage = Settings.isWorldAllowed(player.getWorld().getName()) - && regionID != null; - // Checks region id is valid, checks allowed worlds contain world which player in, - // Farmer exists and player has farmer.admin perm or owner of farmer. - if ((manage && FarmerManager.getFarmers().containsKey(regionID)) - && (player.hasPermission("farmer.admin") || FarmerManager.getFarmers().get(regionID).getOwnerUUID().equals(player.getUniqueId()))) - completes.add("manage"); - // returning object of complete. - return completes; } - return Arrays.asList(""); - } - catch (Exception e) { - return Arrays.asList(""); + if (args.length == 2 && args[0].equalsIgnoreCase("open")) { + return online_players(); + } else if (args.length == 2 && args[0].equalsIgnoreCase("remove")) { + return online_players(); + } + } else { + if (args.length == 1) { + return Collections.singletonList("remove"); + } } + return null; + } + + private static List online_players(){ + List online = new ArrayList<>(); + Bukkit.getOnlinePlayers().forEach((player -> online.add(player.getDisplayName()))); + return online; } + } diff --git a/src/main/java/xyz/geik/farmer/database/DBConnection.java b/src/main/java/xyz/geik/farmer/database/DBConnection.java deleted file mode 100644 index bf450d3b..00000000 --- a/src/main/java/xyz/geik/farmer/database/DBConnection.java +++ /dev/null @@ -1,38 +0,0 @@ -package xyz.geik.farmer.database; - -import org.jetbrains.annotations.Nullable; -import xyz.geik.farmer.Main; - -import java.io.File; -import java.sql.Connection; -import java.sql.DriverManager; - -/** - * Creates basic connection to SQLite database. - */ -public class DBConnection { - - /** - * Connects database of Farmer. - * - * @return - */ - public static @Nullable Connection connect() { - try { - // JDBC Class for SQLite - Class.forName("org.sqlite.JDBC"); - // Getting plugin name for folder destination - String pluginName = Main.getInstance().getDescription().getName(); - // Getting file - File databaseFile = new File("plugins/" + pluginName + "/storage/database.db"); - // Going in - databaseFile.getParentFile().mkdirs(); - // Catching absolute path - String absolutePath = databaseFile.getParentFile().getAbsolutePath(); - // Then using driver and return it. - return DriverManager.getConnection("jdbc:sqlite:" + absolutePath + "/database.db"); - } - catch (Exception e) { return null; } - } - -} diff --git a/src/main/java/xyz/geik/farmer/database/DBQueries.java b/src/main/java/xyz/geik/farmer/database/DBQueries.java deleted file mode 100644 index 5be54ef1..00000000 --- a/src/main/java/xyz/geik/farmer/database/DBQueries.java +++ /dev/null @@ -1,227 +0,0 @@ -package xyz.geik.farmer.database; - -import org.bukkit.Bukkit; -import org.jetbrains.annotations.NotNull; -import xyz.geik.farmer.Main; -import xyz.geik.farmer.api.FarmerAPI; -import xyz.geik.farmer.api.handlers.FarmerBoughtEvent; -import xyz.geik.farmer.api.handlers.FarmerRemoveEvent; -import xyz.geik.farmer.api.managers.FarmerManager; -import xyz.geik.farmer.model.Farmer; -import xyz.geik.farmer.model.FarmerLevel; -import xyz.geik.farmer.model.inventory.FarmerInv; -import xyz.geik.farmer.model.inventory.FarmerItem; -import xyz.geik.farmer.model.user.FarmerPerm; -import xyz.geik.farmer.model.user.User; -import xyz.geik.farmer.modules.FarmerModule; - -import java.sql.*; -import java.util.*; - -/** - * Database Queries for - * database updating. - */ -public class DBQueries { - - /** - * Create table if not exists. - *

- * Farmers: - * id (INTEGER PK AI), // Primary key, auto increment - * RegionID (varchar(30), No Null, Unique), // Region id of farmer - * State (smallint(1), default 1), // Gather state 1 farmer work, 0 they don't - * items (text, default null), // items formatted info - * level (int, default 0) // level of farmer - *

- * FarmerUsers: - * farmerId (int not null), // Farmers#id for primary key of it - * name (varchar(30) DEFAULT User), // Display User as username if something goes wrong - * uuid (char(36) default 0), // uuid of player - * role (smallint(1) default 0) // role of player [COOP: 0, MEMBER: 1, OWNER: 2] - */ - public static void createTable() { - // Creating connection and statement - try (Connection connection = DBConnection.connect(); - Statement statement = connection.createStatement()) { - // Adding batch of table creation to the statement - statement.addBatch("CREATE TABLE IF NOT EXISTS `Farmers`\n" + "(\n" - + " `id` INTEGER PRIMARY KEY AUTOINCREMENT,\n" - + " `regionID` varchar(30) NOT NULL UNIQUE,\n" - + " `state` smallint(1) DEFAULT 1,\n" - + " `items` text DEFAULT NULL,\n" - + " `attributes` text DEFAULT NULL,\n" - + " `level` int DEFAULT 0);"); - // Adding batch of table creation to the statement - statement.addBatch("CREATE TABLE IF NOT EXISTS `FarmerUsers`\n" + "(\n" - + " `farmerId` int NOT NULL,\n" - + " `name` varchar(30) DEFAULT User,\n" - + " `uuid` char(36) DEFAULT 0,\n" - + " `role` smallint(1) DEFAULT 0);"); - // executing batch - statement.executeBatch(); - } - catch (Exception e) { e.printStackTrace(); } - } - - /** - * Synchronized saves all cached farmer values to database. - */ - public static void updateAllFarmers() { - // Connection - try (Connection con = DBConnection.connect()) { - // foreach for all farmers - for (Farmer farmer : FarmerManager.getFarmers().values()) { - // quick save method written on farmer class - farmer.saveFarmer(con); - FarmerAPI.getModuleManager().databaseUpdateAttribute(con, farmer); - } - } - catch (Exception e) { e.printStackTrace(); } - } - - /** - * Asynchronized saves all cached farmer values to database. - */ - public static void updateAllFarmersAsync() { - Bukkit.getScheduler().runTaskAsynchronously(Main.getInstance(), () -> updateAllFarmers()); - } - - /** - * Loads all the farmers and users to the RAM. - */ - public static void loadAllFarmers() { - // Query of farmer - final String FARMER_QUERY = "SELECT * FROM Farmers;"; - // Query of farmer users - final String USERS_QUERY = "SELECT * FROM FarmerUsers WHERE farmerId = ?"; - // Connection - try (Connection con = DBConnection.connect()) { - // statement for farmer query - PreparedStatement pst = con.prepareStatement(FARMER_QUERY); - ResultSet resultSet = pst.executeQuery(); - // Gets all data - while (resultSet.next()) { - int farmerID = resultSet.getInt("id"); - String regionID = resultSet.getString("regionID"); - int state = resultSet.getInt("state"); - int levelID = resultSet.getInt("level"); - // Fixes if there is issue - if (levelID < 0) - levelID = 0; - FarmerLevel level = (FarmerLevel.getAllLevels().size()-1 >= levelID ) - ? FarmerLevel.getAllLevels().get(levelID) - : FarmerLevel.getAllLevels().get(FarmerLevel.getAllLevels().size()-1); - // Items set - List items = FarmerItem.deserializeItems(resultSet.getString("items")); - // Inventory model - FarmerInv inv = new FarmerInv(items, level.getCapacity()); - - // Creating users statement here - PreparedStatement userState = con.prepareStatement(USERS_QUERY); - userState.setInt(1, farmerID); - ResultSet userSet = userState.executeQuery(); - Set users = new LinkedHashSet<>(); - // Gets all users of the farmer - while (userSet.next()) { - String name = userSet.getString("name"); - String uuid = userSet.getString("uuid"); - // FarmerPerm model for role calculating - FarmerPerm role = FarmerPerm.getRole(userSet.getInt("role")); - users.add(new User(farmerID, name, UUID.fromString(uuid), role)); - } - // After all this task creating farmer model - Farmer farmer = new Farmer(farmerID, regionID, users, inv, level, state); - FarmerAPI.getModuleManager().databaseGetAttributes(con, farmer); - // Adding it to cache - FarmerManager.getFarmers().put(regionID, farmer); - // Closing user resultset and statement - userSet.close(); - userState.close(); - } - // Closing farmer resultset and statement - resultSet.close(); - pst.close(); - } - catch (Exception e1) { - e1.printStackTrace(); - } - } - - /** - * Creates new farmer to database - * - * @param farmer - * @param ownerUUID - */ - public static void createFarmer(Farmer farmer) { - // Query - final String SQL_QUERY = "INSERT INTO Farmers (regionID, state, level) VALUES (?, ?, ?)"; - // Asynchronously task scheduler for running this task for async without delay - Bukkit.getScheduler().runTaskAsynchronously(Main.getInstance(), () -> { - // Makes connect async and all the task because of the scheduler - try (Connection con = DBConnection.connect()) { - // Statement runs query - PreparedStatement pst = con.prepareStatement(SQL_QUERY); - pst.setString(1, farmer.getRegionID()); - pst.setInt(2, farmer.getState()); - pst.setInt(3, FarmerLevel.getAllLevels().indexOf(farmer.getLevel())); - pst.executeUpdate(); - pst.close(); - - // Gets id from SQL with same async task for updating farmer id - // Because it created just now. - PreparedStatement idGetter = con.prepareStatement("SELECT id FROM Farmers WHERE regionID = ?"); - idGetter.setString(1, farmer.getRegionID()); - int id = idGetter.executeQuery().getInt("id"); - idGetter.close(); - - // Calls event of farmer creation - Bukkit.getScheduler().runTask(Main.getInstance(), () -> { - farmer.setId(id); - // Event of listener - FarmerBoughtEvent boughtEvent = new FarmerBoughtEvent(farmer); - Bukkit.getPluginManager().callEvent(boughtEvent); - }); - } catch (Exception e) { e.printStackTrace(); } - }); - } - - /** - * Removes farmer on database - * - * @param farmer - */ - public static void removeFarmer(Farmer farmer) { - // An async scheduler for running this task async. (no delay) - Bukkit.getScheduler().runTaskAsynchronously(Main.getInstance(), () -> { - // two query for farmer and farmer users. - String DELETE_FARMER = "DELETE FROM Farmers WHERE id = ?"; - String DELETE_USERS = "DELETE FROM FarmerUsers WHERE farmerId = ?"; - try (Connection con = DBConnection.connect()) { - // Removes farmer - PreparedStatement pst = con.prepareStatement(DELETE_FARMER); - pst.setInt(1, farmer.getId()); - pst.executeUpdate(); - pst.close(); - - // Removes users - PreparedStatement removeUsers = con.prepareStatement(DELETE_USERS); - removeUsers.setInt(1, farmer.getId()); - removeUsers.executeUpdate(); - removeUsers.close(); - - Bukkit.getScheduler().runTask(Main.getInstance(), () -> { - // Calls remove farmer event - FarmerRemoveEvent removeEvent = new FarmerRemoveEvent(farmer); - Bukkit.getPluginManager().callEvent(removeEvent); - }); - - // Removes from cached farmers - if (FarmerManager.getFarmers().containsKey(farmer.getRegionID())) - FarmerManager.getFarmers().remove(farmer.getRegionID()); - } - catch (Exception e) { e.printStackTrace(); } - }); - } -} diff --git a/src/main/java/xyz/geik/farmer/database/DatabaseType.java b/src/main/java/xyz/geik/farmer/database/DatabaseType.java new file mode 100644 index 00000000..5283ceb5 --- /dev/null +++ b/src/main/java/xyz/geik/farmer/database/DatabaseType.java @@ -0,0 +1,11 @@ +package xyz.geik.farmer.database; + +/** + * DatabaseType enum class + * @since b000 + * @author Amowny + */ +public enum DatabaseType { + SQLITE, + MYSQL; +} diff --git a/src/main/java/xyz/geik/farmer/database/HikariCP.java b/src/main/java/xyz/geik/farmer/database/HikariCP.java new file mode 100644 index 00000000..f6297180 --- /dev/null +++ b/src/main/java/xyz/geik/farmer/database/HikariCP.java @@ -0,0 +1,82 @@ +package xyz.geik.farmer.database; + +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; + +/** + * HikariCP main configuration class + * @since b000 + * @author Amowny + */ +public class HikariCP { + + /** + * DataSource object of HikariCP + */ + private HikariDataSource hikariDataSource; + + /** + * MySQL auth information + */ + protected String hostname, database, username, password; + + /** + * MySQL port for connection + */ + protected int port; + + /** + * Constructor of HikariCP for MySQL + * + * @param hostname of mysql + * @param port of mysql + * @param username of mysql + * @param password of mysql + * @param database of mysql + */ + public HikariCP(String hostname, int port, String username, String password, String database) { + this.hostname = hostname; + this.port = port; + this.username = username; + this.password = password; + this.database = database; + } + + /** + * Constructor of HikariCP for SQLite + * Empty on SQLite because there is no auth protection. + */ + public HikariCP() {} + + /** + * Sets property of mysql/sqlite + * @param sql + */ + public void setProperties(SQL sql) { + HikariConfig hikariConfig = new HikariConfig(); + if (sql.getDatabaseType() == DatabaseType.MYSQL) { + String jdbcUrl = "jdbc:mysql://" + this.hostname + ":" + this.port + "/" + this.database; + hikariConfig.setJdbcUrl(jdbcUrl); + hikariConfig.setUsername(this.username); + hikariConfig.setPassword(this.password); + hikariConfig.addDataSourceProperty("cachePrepStmts", "true"); + hikariConfig.addDataSourceProperty("prepStmtCacheSize", "250"); + hikariConfig.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); + hikariConfig.setDriverClassName("com.mysql.cj.jdbc.Driver"); + } else { + String jdbcUrl = "jdbc:sqlite:" + ((SQLite)sql).getSqlFile(); + hikariConfig.setJdbcUrl(jdbcUrl); + hikariConfig.setDriverClassName("org.sqlite.JDBC"); + } + this.hikariDataSource = new HikariDataSource(hikariConfig); + } + + /** + * Data source of hikariCP + * @return HikariDataSource configuration + */ + public HikariDataSource getHikariDataSource() { + return this.hikariDataSource; + } + +} diff --git a/src/main/java/xyz/geik/farmer/database/MySQL.java b/src/main/java/xyz/geik/farmer/database/MySQL.java new file mode 100644 index 00000000..fbcaaa2a --- /dev/null +++ b/src/main/java/xyz/geik/farmer/database/MySQL.java @@ -0,0 +1,58 @@ +package xyz.geik.farmer.database; + +import lombok.Getter; +import xyz.geik.farmer.Main; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +/** + * @since b000 + * @author Amowny + */ +@Getter +public class MySQL extends SQL { + + /** + * Main constructor of MySQL init configurations + */ + public MySQL() { + String hostname = Main.getDatabaseFile().getString("database.host"); + int port = Main.getDatabaseFile().getInt("database.port"); + String username = Main.getDatabaseFile().getString("database.username"); + String password = Main.getDatabaseFile().getString("database.password"); + String database = Main.getDatabaseFile().getString("database.database"); + this.hikariCP = new HikariCP(hostname, port, username, password, database); + this.hikariCP.setProperties(this); + createTable(); + } + + /** + * Crates table of MySQL + */ + public void createTable() { + Connection connection = null; + PreparedStatement preparedStatement = null; + try { + connection = this.hikariCP.getHikariDataSource().getConnection(); + preparedStatement = connection.prepareStatement("CREATE TABLE IF NOT EXISTS Farmers (id INT AUTO_INCREMENT, regionID varchar(36) NOT NULL UNIQUE, `state` smallint(1) DEFAULT 1, `items` text DEFAULT NULL, `attributes` text DEFAULT NULL, `level` int DEFAULT 0, PRIMARY KEY (id))"); + preparedStatement.executeUpdate(); + preparedStatement = connection.prepareStatement("CREATE TABLE IF NOT EXISTS FarmerUsers (`farmerId` int NOT NULL, `name` varchar(30) DEFAULT 'User', `uuid` char(36) DEFAULT '0', `role` smallint(1) DEFAULT 0)"); + preparedStatement.executeUpdate(); + this.plugin.getLogger().info("MySQL tables created successfully!"); + } catch (SQLException throwables) { + this.plugin.getLogger().info("Error while creating table: " + throwables.getMessage()); + } finally { + closeConnections(preparedStatement, connection, null); + } + } + + /** + * Gets type of database + * @return DatabaseType#MYSQL + */ + public DatabaseType getDatabaseType() { + return DatabaseType.MYSQL; + } +} diff --git a/src/main/java/xyz/geik/farmer/database/SQL.java b/src/main/java/xyz/geik/farmer/database/SQL.java new file mode 100644 index 00000000..c7bf7f2b --- /dev/null +++ b/src/main/java/xyz/geik/farmer/database/SQL.java @@ -0,0 +1,421 @@ +package xyz.geik.farmer.database; + +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.jetbrains.annotations.NotNull; +import xyz.geik.farmer.Main; +import xyz.geik.farmer.api.FarmerAPI; +import xyz.geik.farmer.api.handlers.FarmerBoughtEvent; +import xyz.geik.farmer.api.handlers.FarmerRemoveEvent; +import xyz.geik.farmer.api.managers.FarmerManager; +import xyz.geik.farmer.model.Farmer; +import xyz.geik.farmer.model.FarmerLevel; +import xyz.geik.farmer.model.inventory.FarmerInv; +import xyz.geik.farmer.model.inventory.FarmerItem; +import xyz.geik.farmer.model.user.FarmerPerm; +import xyz.geik.farmer.model.user.User; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import java.util.UUID; + +/** + * SQL Queries and abstracted methods exist in this class + * + * @since b000 + * @author Amowny + */ +public abstract class SQL { + + /** + * Instance of main + */ + protected Main plugin = Main.getInstance(); + + /** + * Library which used for connection and pooling queries + */ + protected HikariCP hikariCP; + + /** + * Creates table on db + */ + public abstract void createTable(); + + /** + * Updates all farmers which saves all data of farmers on cache + */ + public void updateAllFarmers() { + Connection connection = null; + try { + connection = this.hikariCP.getHikariDataSource().getConnection(); + for (Farmer farmer : FarmerManager.getFarmers().values()) { + farmer.saveFarmer(); + FarmerAPI.getModuleManager().databaseUpdateAttribute(connection, farmer); + } + } catch (SQLException throwables) { + this.plugin.getLogger().info("Error while updating Farmers: " + throwables.getMessage()); + } finally { + closeConnections(null, connection, null); + } + } + + /** + * Does same thing with #updateAllFarmers async + */ + public void updateAllFarmersAsync() { + Bukkit.getScheduler().runTaskAsynchronously(Main.getInstance(), this::updateAllFarmers); + } + + /** + * Loads all farmer data from sql to cache + */ + public void loadAllFarmers() { + Connection connection = null; + PreparedStatement preparedStatement = null; + ResultSet resultSet = null; + // Query of farmer + final String FARMER_QUERY = "SELECT * FROM Farmers;"; + // Query of farmer users + final String USERS_QUERY = "SELECT * FROM FarmerUsers WHERE farmerId = ?"; + try { + connection = this.hikariCP.getHikariDataSource().getConnection(); + preparedStatement = connection.prepareStatement(FARMER_QUERY); + resultSet = preparedStatement.executeQuery(); + while (resultSet.next()) { + int farmerID = resultSet.getInt("id"); + String regionID = resultSet.getString("regionID"); + int state = resultSet.getInt("state"); + int levelID = resultSet.getInt("level"); + + if (levelID < 0) + levelID = 0; + FarmerLevel level = (FarmerLevel.getAllLevels().size()-1 >= levelID ) + ? FarmerLevel.getAllLevels().get(levelID) + : FarmerLevel.getAllLevels().get(FarmerLevel.getAllLevels().size()-1); + + List items = FarmerItem.deserializeItems(resultSet.getString("items")); + + FarmerInv inv = new FarmerInv(items, level.getCapacity()); + + PreparedStatement userStatement = connection.prepareStatement(USERS_QUERY); + userStatement.setInt(1, farmerID); + ResultSet userSet = userStatement.executeQuery(); + Set users = new LinkedHashSet<>(); + + while (userSet.next()) { + String name = userSet.getString("name"); + String uuid = userSet.getString("uuid"); + + FarmerPerm role = FarmerPerm.getRole(userSet.getInt("role")); + users.add(new User(farmerID, name, UUID.fromString(uuid), role)); + } + Farmer farmer = new Farmer(farmerID, regionID, users, inv, level, state); + FarmerAPI.getModuleManager().databaseGetAttributes(connection, farmer); + FarmerManager.getFarmers().put(regionID, farmer); + } + } catch (SQLException throwables) { + this.plugin.getLogger().info("Error while loading Farmers: " + throwables.getMessage()); + } finally { + closeConnections(preparedStatement, connection, resultSet); + } + } + + /** + * Creates farmer on sql + * @param farmer temp farmer + */ + public void createFarmer(@NotNull Farmer farmer) { + Connection connection = null; + PreparedStatement saveStatement = null; + PreparedStatement selectStatement = null; + ResultSet resultSet = null; + final String SQL_QUERY = "INSERT INTO Farmers (regionID, state, level) VALUES (?, ?, ?)"; + try { + connection = this.hikariCP.getHikariDataSource().getConnection(); + saveStatement = connection.prepareStatement(SQL_QUERY); + saveStatement.setString(1, farmer.getRegionID()); + saveStatement.setInt(2, farmer.getState()); + saveStatement.setInt(3, FarmerLevel.getAllLevels().indexOf(farmer.getLevel())); + saveStatement.executeUpdate(); + + selectStatement = connection.prepareStatement("SELECT id FROM Farmers WHERE regionID = ?"); + selectStatement.setString(1, farmer.getRegionID()); + resultSet = selectStatement.executeQuery(); + if (resultSet.next()) { + int id = resultSet.getInt("id"); + Bukkit.getScheduler().runTask(Main.getInstance(), () -> { + farmer.setId(id); + FarmerBoughtEvent boughtEvent = new FarmerBoughtEvent(farmer); + Bukkit.getPluginManager().callEvent(boughtEvent); + }); + } + } catch (SQLException throwables) { + this.plugin.getLogger().info("Error while creating Farmer: " + throwables.getMessage()); + } finally { + closeConnections(saveStatement, connection, resultSet); + closeConnections(selectStatement, connection, resultSet); + } + } + + /** + * Removes farmer from sql + * @param farmer object of farmer + */ + public void removeFarmer(@NotNull Farmer farmer) { + Connection connection = null; + PreparedStatement removeFarmerStatement = null; + PreparedStatement removeUsersStatement = null; + String DELETE_FARMER = "DELETE FROM Farmers WHERE id = ?"; + String DELETE_USERS = "DELETE FROM FarmerUsers WHERE farmerId = ?"; + try { + connection = this.hikariCP.getHikariDataSource().getConnection(); + removeFarmerStatement = connection.prepareStatement(DELETE_FARMER); + removeFarmerStatement.setInt(1, farmer.getId()); + removeFarmerStatement.executeUpdate(); + + removeUsersStatement = connection.prepareStatement(DELETE_USERS); + removeUsersStatement.setInt(1, farmer.getId()); + removeUsersStatement.executeUpdate(); + + Bukkit.getScheduler().runTask(Main.getInstance(), () -> { + FarmerRemoveEvent removeEvent = new FarmerRemoveEvent(farmer); + Bukkit.getPluginManager().callEvent(removeEvent); + }); + + if (FarmerManager.getFarmers().containsKey(farmer.getRegionID())) + FarmerManager.getFarmers().remove(farmer.getRegionID()); + + } catch (SQLException throwables) { + this.plugin.getLogger().info("Error while removing Farmer: " + throwables.getMessage()); + } finally { + closeConnections(removeFarmerStatement, connection, null); + closeConnections(removeUsersStatement, connection, null); + } + } + + /** + * Saves farmer sync + * @param farmer farmer object + */ + public void saveFarmer(@NotNull Farmer farmer) { + Connection connection = null; + PreparedStatement preparedStatement = null; + final String SQL_QUERY = "UPDATE Farmers SET regionID = ?, state = ?, items = ?, level = ? WHERE id = ?"; + try { + connection = this.hikariCP.getHikariDataSource().getConnection(); + preparedStatement = connection.prepareStatement(SQL_QUERY); + preparedStatement.setString(1, farmer.getRegionID()); + preparedStatement.setInt(2, farmer.getState()); + String serializedItems = FarmerItem.serializeItems(farmer.getInv().getItems()); + preparedStatement.setString(3, (serializedItems == "") ? null : serializedItems); + preparedStatement.setInt(4, FarmerLevel.getAllLevels().indexOf(farmer.getLevel())); + preparedStatement.setInt(5, farmer.getId()); + preparedStatement.executeUpdate(); + } catch (SQLException throwables) { + this.plugin.getLogger().info("Error while save Farmer: " + throwables.getMessage()); + } finally { + closeConnections(preparedStatement, connection, null); + } + } + + /** + * Adds user to farmer in sql + * + * @param uuid uuid of player + * @param name name of player + * @param perm perm of player + */ + public void addUser(UUID uuid, String name, FarmerPerm perm, @NotNull Farmer farmer) { + farmer.getUsers().add(new User(farmer.getId(), name, uuid, perm)); + addUser(uuid, name, perm, farmer.getId()); + } + + /** + * Adds user to farmer in sql only + */ + public void addUser(@NotNull UUID uuid, String name, FarmerPerm perm, int farmerId) { + Bukkit.getScheduler().runTaskAsynchronously(Main.getInstance(), () -> { + Connection connection = null; + PreparedStatement preparedStatement = null; + final String SQL_QUERY = "INSERT INTO FarmerUsers (farmerId, name, uuid, role) VALUES (?, ?, ?, ?)"; + try { + connection = this.hikariCP.getHikariDataSource().getConnection(); + preparedStatement = connection.prepareStatement(SQL_QUERY); + preparedStatement.setInt(1, farmerId); + preparedStatement.setString(2, name); + preparedStatement.setString(3, uuid.toString()); + preparedStatement.setInt(4, FarmerPerm.getRoleId(perm)); + preparedStatement.executeUpdate(); + } catch (SQLException throwables) { + this.plugin.getLogger().info("Error while adding User: " + throwables.getMessage()); + } finally { + closeConnections(preparedStatement, connection, null); + } + }); + } + + /** + * Removes user from farmer in sql + * + * @param user user object + * @return status of task + */ + public boolean removeUser(@NotNull User user, Farmer farmer) { + if (user.getPerm().equals(FarmerPerm.OWNER)) + return false; + farmer.getUsers().remove(user); + Bukkit.getScheduler().runTaskAsynchronously(Main.getInstance(), () -> { + Connection connection = null; + PreparedStatement preparedStatement = null; + final String QUERY = "DELETE FROM FarmerUsers WHERE uuid = ? AND farmerId = ?"; + try { + connection = this.hikariCP.getHikariDataSource().getConnection(); + preparedStatement = connection.prepareStatement(QUERY); + preparedStatement.setString(1, user.getUuid().toString()); + preparedStatement.setInt(2, farmer.getId()); + preparedStatement.executeUpdate(); + } catch (SQLException throwables) { + this.plugin.getLogger().info("Error while remove User: " + throwables.getMessage()); + } finally { + closeConnections(preparedStatement, connection, null); + } + }); + return true; + } + + /** + * Updates role of player + * @param uuid uuid of player + * @param roleId roleId of player (FarmerPerm#getRole) + * @param farmerId id of farmer + */ + public void updateRole(UUID uuid, int roleId, int farmerId) { + Bukkit.getScheduler().runTaskAsynchronously(Main.getInstance(), () -> { + Connection connection = null; + PreparedStatement preparedStatement = null; + final String QUERY = "UPDATE FarmerUsers SET role = ? WHERE uuid = ? AND farmerId = ?"; + try { + connection = this.hikariCP.getHikariDataSource().getConnection(); + preparedStatement = connection.prepareStatement(QUERY); + preparedStatement.setInt(1, roleId); + preparedStatement.setString(2, uuid.toString()); + preparedStatement.setInt(3, farmerId); + preparedStatement.executeUpdate(); + } catch (SQLException throwables) { + this.plugin.getLogger().info("Error while remove User: " + throwables.getMessage()); + } finally { + closeConnections(preparedStatement, connection, null); + } + }); + } + + /** + * Database type of sql + * @return DatabaseType object + */ + public abstract DatabaseType getDatabaseType(); + + /** + * Closes connection of sql + * + * @param preparedStatement statement + * @param connection connection + * @param resultSet resultset + */ + protected void closeConnections(PreparedStatement preparedStatement, Connection connection, ResultSet resultSet) { + if (connection == null) + return; + try { + if (connection.isClosed()) + return; + if (resultSet != null) + resultSet.close(); + if (preparedStatement != null) + preparedStatement.close(); + connection.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + /** + * Fix database method + *

Fixes users and owners if there is any corruption occurred in older versions or blackouts.

+ */ + public void fixDatabase() { + Main.getInstance().getSql().updateAllFarmers(); + this.plugin.getLogger().info("Preparing data for fix please wait..."); + Bukkit.getScheduler().runTaskLater(Main.getInstance(), () -> { + long ms = System.currentTimeMillis(); + FarmerManager.getFarmers().clear(); + fixUsersInDatabase(ms); + }, 200L); + } + + /** + * Check users if something exceptional in db + */ + private void fixUsersInDatabase(long ms) { + this.plugin.getLogger().info("Farmer fixing users in progress.."); + final String QUERY = "DELETE FROM FarmerUsers\n" + + "WHERE (farmerId, uuid, role) NOT IN (\n" + + " SELECT farmerId, uuid, MAX(role) AS max_role\n" + + " FROM FarmerUsers\n" + + " GROUP BY farmerId, uuid\n" + + ");"; + Connection connection = null; + PreparedStatement statement = null; + try { + connection = this.hikariCP.getHikariDataSource().getConnection(); + statement = connection.prepareStatement(QUERY); + statement.executeUpdate(); + } catch (SQLException throwables) { + this.plugin.getLogger().info("Error while trying to fix database: " + throwables.getMessage()); + } finally { + closeConnections(statement, connection, null); + this.plugin.getLogger().info("Farmer fixing users completed."); + // Next step + fixOwnersInDatabase(ms); + } + } + + /** + * Checks farmers if there is no owner on farmer in db + */ + private void fixOwnersInDatabase(long ms) { + this.plugin.getLogger().info("Farmer fixing owners in progress.."); + final String QUERY = "SELECT * FROM Farmers WHERE id NOT IN (\n" + + " SELECT farmerId FROM FarmerUsers WHERE role = 2\n" + + ");"; + Connection connection = null; + PreparedStatement statement = null; + ResultSet resultSet; + try { + connection = this.hikariCP.getHikariDataSource().getConnection(); + statement = connection.prepareStatement(QUERY); + resultSet = statement.executeQuery(); + while (resultSet.next()) { + int farmerID = resultSet.getInt("id"); + String regionID = resultSet.getString("regionID"); + OfflinePlayer owner = Bukkit.getOfflinePlayer(Main.getIntegration().getOwnerUUID(regionID)); + this.addUser(owner.getUniqueId(), owner.getName(), FarmerPerm.OWNER, farmerID); + this.plugin.getLogger().info("Fixed owner in database " + owner.getName()); + } + } catch (SQLException throwables) { + this.plugin.getLogger().info("Error while trying to fix database: " + throwables.getMessage()); + } finally { + closeConnections(statement, connection, null); + this.plugin.getLogger().info("Farmer fixing owners completed."); + Bukkit.getScheduler().runTaskLaterAsynchronously(Main.getInstance(), () -> { + Main.getInstance().getSql().loadAllFarmers(); + this.plugin.getLogger().info("Fixing database task has completed in " + (System.currentTimeMillis() - ms) + "ms"); + }, 200L); + } + } +} \ No newline at end of file diff --git a/src/main/java/xyz/geik/farmer/database/SQLite.java b/src/main/java/xyz/geik/farmer/database/SQLite.java new file mode 100644 index 00000000..be1db5eb --- /dev/null +++ b/src/main/java/xyz/geik/farmer/database/SQLite.java @@ -0,0 +1,70 @@ +package xyz.geik.farmer.database; + +import java.io.File; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +/** + * SQLite query class + * + * @since b000 + * @author Amowny + */ +public class SQLite extends SQL { + + /** + * SQLite file + */ + private final File sqlFile; + + /** + * Main constructor of SQLite + */ + public SQLite() { + // HikariCP library object + this.hikariCP = new HikariCP(); + // File of sqlite + this.sqlFile = new File(this.plugin.getDataFolder() + "/storage/", "database.db"); + // Configuration setter of hikaricp + this.hikariCP.setProperties(this); + // Crates tables + createTable(); + } + + /** + * Create tables if there is no any + */ + public void createTable() { + Connection connection = null; + PreparedStatement preparedStatement = null; + try { + connection = this.hikariCP.getHikariDataSource().getConnection(); + preparedStatement = connection.prepareStatement("CREATE TABLE IF NOT EXISTS Farmers (id INTEGER PRIMARY KEY AUTOINCREMENT, regionID varchar(36) NOT NULL UNIQUE, `state` smallint(1) DEFAULT 1, `items` text DEFAULT NULL, `attributes` text DEFAULT NULL, `level` int DEFAULT 0)"); + preparedStatement.executeUpdate(); + preparedStatement = connection.prepareStatement("CREATE TABLE IF NOT EXISTS FarmerUsers (farmerId int NOT NULL, `name` varchar(30) DEFAULT User, uuid char(36) DEFAULT 0, `role` smallint(1) DEFAULT 0)"); + preparedStatement.executeUpdate(); + this.plugin.getLogger().info("SQLite tables created successfully"); + } catch (SQLException throwables) { + this.plugin.getLogger().info("Error while creating table: " + throwables.getMessage()); + } finally { + closeConnections(preparedStatement, connection, null); + } + } + + /** + * Returns type of database + * @return DatabaseType enum #SQLITE / #MYSQL + */ + public DatabaseType getDatabaseType() { + return DatabaseType.SQLITE; + } + + /** + * Gets file of SQLite + * @return File of .db file + */ + public File getSqlFile() { + return this.sqlFile; + } +} diff --git a/src/main/java/xyz/geik/farmer/guis/BuyGui.java b/src/main/java/xyz/geik/farmer/guis/BuyGui.java index 3493ae05..82d186a7 100644 --- a/src/main/java/xyz/geik/farmer/guis/BuyGui.java +++ b/src/main/java/xyz/geik/farmer/guis/BuyGui.java @@ -39,7 +39,7 @@ public static void showGui(Player player) { Main.getEcon().withdrawPlayer(player, Settings.farmerPrice); // Creates new farmer Farmer farmer = new Farmer(Main.getIntegration() - .getRegionID(player.getLocation()), Main.getIntegration().getOwnerUUID(player.getLocation()), 0); + .getRegionID(player.getLocation()), 0); XSound.ENTITY_PLAYER_LEVELUP.play(player); // Opens farmer gui to buyer MainGui.showGui(player, farmer); diff --git a/src/main/java/xyz/geik/farmer/integrations/Integrations.java b/src/main/java/xyz/geik/farmer/integrations/Integrations.java index 4270a57a..17470cbc 100644 --- a/src/main/java/xyz/geik/farmer/integrations/Integrations.java +++ b/src/main/java/xyz/geik/farmer/integrations/Integrations.java @@ -2,6 +2,7 @@ import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.entity.Player; import org.bukkit.event.Listener; import xyz.geik.farmer.Main; import xyz.geik.farmer.integrations.askyblock.Askyblock; @@ -9,6 +10,7 @@ import xyz.geik.farmer.integrations.fabledskyblock.FabledSkyblock; import xyz.geik.farmer.integrations.grief.GriefPrevent; import xyz.geik.farmer.integrations.superior.SuperiorSkyblock; +import xyz.geik.farmer.integrations.townyadvanced.TownyAdvanced; import java.util.UUID; @@ -69,5 +71,7 @@ else if (Bukkit.getPluginManager().isPluginEnabled("ASkyBlock")) Main.setIntegration(new Askyblock()); else if(Bukkit.getPluginManager().isPluginEnabled("FabledSkyBlock")) Main.setIntegration(new FabledSkyblock()); + else if (Bukkit.getPluginManager().isPluginEnabled("Towny")) + Main.setIntegration(new TownyAdvanced()); } } diff --git a/src/main/java/xyz/geik/farmer/integrations/askyblock/ASkyblockListener.java b/src/main/java/xyz/geik/farmer/integrations/askyblock/ASkyblockListener.java index 41bc0adb..b5907fd0 100644 --- a/src/main/java/xyz/geik/farmer/integrations/askyblock/ASkyblockListener.java +++ b/src/main/java/xyz/geik/farmer/integrations/askyblock/ASkyblockListener.java @@ -5,6 +5,7 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.jetbrains.annotations.NotNull; +import xyz.geik.farmer.Main; import xyz.geik.farmer.api.FarmerAPI; import xyz.geik.farmer.api.managers.FarmerManager; import xyz.geik.farmer.model.Farmer; diff --git a/src/main/java/xyz/geik/farmer/integrations/askyblock/Askyblock.java b/src/main/java/xyz/geik/farmer/integrations/askyblock/Askyblock.java index 6020a394..c3fc16e7 100644 --- a/src/main/java/xyz/geik/farmer/integrations/askyblock/Askyblock.java +++ b/src/main/java/xyz/geik/farmer/integrations/askyblock/Askyblock.java @@ -47,4 +47,5 @@ public UUID getOwnerUUID(Location location) { public String getRegionID(Location location) { return ASkyBlockAPI.getInstance().getOwner(location).toString(); } + } diff --git a/src/main/java/xyz/geik/farmer/integrations/bentobox/BentoListener.java b/src/main/java/xyz/geik/farmer/integrations/bentobox/BentoListener.java index b2e3ce86..ad4b582b 100644 --- a/src/main/java/xyz/geik/farmer/integrations/bentobox/BentoListener.java +++ b/src/main/java/xyz/geik/farmer/integrations/bentobox/BentoListener.java @@ -124,7 +124,7 @@ public void islandCreateEvent(@NotNull IslandCreatedEvent e) { */ private void autoCreate(String regionId, UUID owner) { if (Settings.autoCreateFarmer) { - new Farmer(regionId, owner, 0); + new Farmer(regionId, 0); Bukkit.getPlayer(owner).sendMessage(Main.getLangFile().getText("boughtFarmer")); } } diff --git a/src/main/java/xyz/geik/farmer/integrations/fabledskyblock/FabledSkyListener.java b/src/main/java/xyz/geik/farmer/integrations/fabledskyblock/FabledSkyListener.java index b9f99534..2de64de1 100644 --- a/src/main/java/xyz/geik/farmer/integrations/fabledskyblock/FabledSkyListener.java +++ b/src/main/java/xyz/geik/farmer/integrations/fabledskyblock/FabledSkyListener.java @@ -29,7 +29,7 @@ public class FabledSkyListener implements Listener { @EventHandler public void onIslandCreate(IslandCreateEvent event) { if (Settings.autoCreateFarmer) { - new Farmer(event.getIsland().getIslandUUID().toString(), event.getIsland().getOwnerUUID(), 0); + new Farmer(event.getIsland().getIslandUUID().toString(), 0); Player player = Bukkit.getPlayer(event.getIsland().getOwnerUUID()); if (player != null) player.sendMessage(Main.getLangFile().getText("boughtFarmer")); } diff --git a/src/main/java/xyz/geik/farmer/integrations/grief/GriefPrevent.java b/src/main/java/xyz/geik/farmer/integrations/grief/GriefPrevent.java index b20baa71..1fe58a6b 100644 --- a/src/main/java/xyz/geik/farmer/integrations/grief/GriefPrevent.java +++ b/src/main/java/xyz/geik/farmer/integrations/grief/GriefPrevent.java @@ -1,7 +1,6 @@ package xyz.geik.farmer.integrations.grief; import me.ryanhamshire.GriefPrevention.GriefPrevention; -import org.bukkit.Bukkit; import org.bukkit.Location; import xyz.geik.farmer.Main; import xyz.geik.farmer.integrations.Integrations; diff --git a/src/main/java/xyz/geik/farmer/integrations/superior/SuperiorListener.java b/src/main/java/xyz/geik/farmer/integrations/superior/SuperiorListener.java index 527fa057..c7d11755 100644 --- a/src/main/java/xyz/geik/farmer/integrations/superior/SuperiorListener.java +++ b/src/main/java/xyz/geik/farmer/integrations/superior/SuperiorListener.java @@ -44,7 +44,7 @@ public void disbandEvent(@NotNull IslandDisbandEvent e) { @EventHandler public void createIslandEvent(IslandCreateEvent e) { if (Settings.autoCreateFarmer) { - Farmer farmer = new Farmer(e.getIsland().getUniqueId().toString(), e.getIsland().getOwner().getUniqueId(), 0); + Farmer farmer = new Farmer(e.getIsland().getUniqueId().toString(), 0); e.getIsland().getOwner().asPlayer().sendMessage(Main.getLangFile().getText("boughtFarmer")); } } diff --git a/src/main/java/xyz/geik/farmer/integrations/townyadvanced/TownyAdvanced.java b/src/main/java/xyz/geik/farmer/integrations/townyadvanced/TownyAdvanced.java new file mode 100644 index 00000000..7f77dffc --- /dev/null +++ b/src/main/java/xyz/geik/farmer/integrations/townyadvanced/TownyAdvanced.java @@ -0,0 +1,30 @@ +package xyz.geik.farmer.integrations.townyadvanced; + +import com.palmergames.bukkit.towny.TownyAPI; +import org.bukkit.Location; +import xyz.geik.farmer.integrations.Integrations; + +import java.util.UUID; + +public class TownyAdvanced extends Integrations { + public TownyAdvanced() { + super(new TownyListener()); + } + + @Override + public UUID getOwnerUUID(String regionID) { + return TownyAPI.getInstance().getTown(UUID.fromString(regionID)).getMayor().getUUID(); + } + + @Override + public UUID getOwnerUUID(Location location) { + return TownyAPI.getInstance().getTown(location).getMayor().getUUID(); + } + + @Override + public String getRegionID(Location location) { + if (TownyAPI.getInstance().getTown(location) == null) + return null; + return TownyAPI.getInstance().getTown(location).getUUID().toString(); + } +} diff --git a/src/main/java/xyz/geik/farmer/integrations/townyadvanced/TownyListener.java b/src/main/java/xyz/geik/farmer/integrations/townyadvanced/TownyListener.java new file mode 100644 index 00000000..2868a658 --- /dev/null +++ b/src/main/java/xyz/geik/farmer/integrations/townyadvanced/TownyListener.java @@ -0,0 +1,69 @@ +package xyz.geik.farmer.integrations.townyadvanced; + +import com.palmergames.bukkit.towny.event.DeleteTownEvent; +import com.palmergames.bukkit.towny.event.NewTownEvent; +import com.palmergames.bukkit.towny.event.player.PlayerEntersIntoTownBorderEvent; +import com.palmergames.bukkit.towny.event.town.TownKickEvent; +import com.palmergames.bukkit.towny.event.town.TownLeaveEvent; +import com.palmergames.bukkit.towny.event.town.TownMayorChangeEvent; +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.jetbrains.annotations.NotNull; +import xyz.geik.farmer.Main; +import xyz.geik.farmer.api.FarmerAPI; +import xyz.geik.farmer.api.managers.FarmerManager; +import xyz.geik.farmer.helpers.Settings; +import xyz.geik.farmer.model.Farmer; +import xyz.geik.farmer.model.user.FarmerPerm; + +import java.util.UUID; + +public class TownyListener implements Listener { + @EventHandler + public void disbandEvent(@NotNull DeleteTownEvent e) { + FarmerAPI.getFarmerManager().removeFarmer(e.getTownUUID().toString()); + } + + @EventHandler + public void createTownEvent(@NotNull NewTownEvent e) { + if (Settings.autoCreateFarmer) { + Farmer farmer = new Farmer(e.getTown().getUUID().toString(),0); + e.getTown().getMayor().getPlayer().sendMessage(Main.getLangFile().getText("boughtFarmer")); + } + } + + @EventHandler + public void transferTown(@NotNull TownMayorChangeEvent e) { + FarmerAPI.getFarmerManager().changeOwner(e.getOldMayor().getUUID(), e.getNewMayor().getUUID(), e.getTown().getUUID().toString()); + } + + @EventHandler + public void townJoinEvent(@NotNull PlayerEntersIntoTownBorderEvent e) { + String townID = e.getEnteredTown().getUUID().toString(); + if (!FarmerManager.getFarmers().containsKey(townID)) + return; + UUID member = e.getPlayer().getUniqueId(); + Farmer farmer = FarmerManager.getFarmers().get(townID); + if (farmer.getUsers().stream().noneMatch(user -> user.getUuid().equals(member))) + farmer.addUser(member, Bukkit.getOfflinePlayer(member).getName(), FarmerPerm.COOP); + } + + @EventHandler + public void townLeaveEvent(@NotNull TownLeaveEvent e) { + kickAndLeaveEvent(e.getTown().getUUID().toString(), e.getResident().getPlayer().getUniqueId()); + } + + @EventHandler + public void townKickEvent(@NotNull TownKickEvent e) { + kickAndLeaveEvent(e.getTown().getUUID().toString(), e.getKickedResident().getPlayer().getUniqueId()); + } + + private void kickAndLeaveEvent(String townID, UUID member) { + if (!FarmerManager.getFarmers().containsKey(townID)) + return; + Farmer farmer = FarmerManager.getFarmers().get(townID); + if (farmer.getUsers().stream().anyMatch(user -> user.getUuid().equals(member))) + farmer.removeUser(farmer.getUsers().stream().filter(user -> user.getUuid().equals(member)).findFirst().get()); + } +} diff --git a/src/main/java/xyz/geik/farmer/listeners/backend/BuyFarmerEvent.java b/src/main/java/xyz/geik/farmer/listeners/backend/BuyFarmerEvent.java index 76a83177..1398c403 100644 --- a/src/main/java/xyz/geik/farmer/listeners/backend/BuyFarmerEvent.java +++ b/src/main/java/xyz/geik/farmer/listeners/backend/BuyFarmerEvent.java @@ -2,6 +2,7 @@ import org.bukkit.Bukkit; import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.jetbrains.annotations.NotNull; import xyz.geik.farmer.api.handlers.FarmerBoughtEvent; @@ -26,7 +27,7 @@ public class BuyFarmerEvent implements Listener { * * @param e FarmerBoughtEvent listener */ - @EventHandler + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void farmerBoughtEvent(@NotNull FarmerBoughtEvent e) { Farmer farmer = e.getFarmer(); // Adds owner uuid to farmer diff --git a/src/main/java/xyz/geik/farmer/listeners/backend/ItemEvent.java b/src/main/java/xyz/geik/farmer/listeners/backend/ItemEvent.java index 51a0eeb2..d02739e9 100644 --- a/src/main/java/xyz/geik/farmer/listeners/backend/ItemEvent.java +++ b/src/main/java/xyz/geik/farmer/listeners/backend/ItemEvent.java @@ -2,6 +2,7 @@ import com.cryptomorin.xseries.XMaterial; import org.bukkit.Bukkit; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; diff --git a/src/main/java/xyz/geik/farmer/listeners/backend/QuitEvent.java b/src/main/java/xyz/geik/farmer/listeners/backend/QuitEvent.java index 21c8101e..8e7c5692 100644 --- a/src/main/java/xyz/geik/farmer/listeners/backend/QuitEvent.java +++ b/src/main/java/xyz/geik/farmer/listeners/backend/QuitEvent.java @@ -7,13 +7,10 @@ import org.bukkit.event.player.PlayerQuitEvent; import org.jetbrains.annotations.NotNull; import xyz.geik.farmer.Main; -import xyz.geik.farmer.api.FarmerAPI; import xyz.geik.farmer.api.managers.FarmerManager; import xyz.geik.farmer.helpers.Settings; import xyz.geik.farmer.model.Farmer; -import java.util.UUID; - /** * Player quit event basically save farmer when player quits */ diff --git a/src/main/java/xyz/geik/farmer/model/Farmer.java b/src/main/java/xyz/geik/farmer/model/Farmer.java index d29fda32..38b0cff8 100644 --- a/src/main/java/xyz/geik/farmer/model/Farmer.java +++ b/src/main/java/xyz/geik/farmer/model/Farmer.java @@ -3,23 +3,15 @@ import lombok.Getter; import lombok.Setter; import org.bukkit.Bukkit; -import org.bukkit.scheduler.BukkitRunnable; import org.jetbrains.annotations.NotNull; import xyz.geik.farmer.Main; -import xyz.geik.farmer.api.managers.FarmerManager; -import xyz.geik.farmer.database.DBConnection; -import xyz.geik.farmer.database.DBQueries; import xyz.geik.farmer.model.inventory.FarmerInv; -import xyz.geik.farmer.model.inventory.FarmerItem; import xyz.geik.farmer.model.user.FarmerPerm; import xyz.geik.farmer.model.user.User; import xyz.geik.farmer.modules.autoharvest.AutoHarvest; import xyz.geik.farmer.modules.autoseller.AutoSeller; import xyz.geik.farmer.modules.spawnerkiller.SpawnerKiller; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.SQLException; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.Set; @@ -128,14 +120,14 @@ public Farmer(int id, String regionID, Set users, * @param ownerUUID uuid of owner * @param level level of farmer */ - public Farmer(String regionID, UUID ownerUUID, int level) { + public Farmer(String regionID, int level) { this.regionID = regionID; Set users = new LinkedHashSet<>(); this.users = users; this.inv = new FarmerInv(); this.level = FarmerLevel.getAllLevels().get(level); this.state = 1; - DBQueries.createFarmer(this); + Main.getInstance().getSql().createFarmer(this); } /** @@ -176,41 +168,6 @@ private boolean isUserNotOwner(@NotNull User user) { return !user.getPerm().equals(FarmerPerm.OWNER); } - /** - * Saves farmer to the database - */ - public void saveFarmerAsync() { - Bukkit.getScheduler().runTaskAsynchronously(Main.getInstance(), () -> { - // Save farmer to db - try (Connection con = DBConnection.connect()) { - // It requires sync on another methods splitting it - // to another method because of that - saveFarmer(con); - } - catch (Exception e) { e.printStackTrace(); } - }); - } - - /** - * Saves farmer to the database requires connection - * Because of multiple requirements can use one connection - * - * @param con - * @throws SQLException - */ - public void saveFarmer(@NotNull Connection con) throws SQLException { - final String query = "UPDATE Farmers SET regionID = ?, state = ?, items = ?, level = ? WHERE id = ?"; - PreparedStatement statement = con.prepareStatement(query); - statement.setString(1, getRegionID()); - statement.setInt(2, getState()); - String serializedItems = FarmerItem.serializeItems(getInv().getItems()); - statement.setString(3, (serializedItems == "") ? null : serializedItems); - statement.setInt(4, FarmerLevel.getAllLevels().indexOf(getLevel())); - statement.setInt(5, getId()); - statement.executeUpdate(); - // closing statement - statement.close(); - } /** * Adds user to farmer with COOP role @@ -225,25 +182,12 @@ public void addUser(UUID uuid, String name) { /** * Adds user to farmer with desired role * - * @param uuid - * @param name - * @param perm + * @param uuid uuid of player + * @param name name of player + * @param perm perm of player */ public void addUser(UUID uuid, String name, FarmerPerm perm) { - this.getUsers().add(new User(this.getId(), name, uuid, perm)); - Bukkit.getScheduler().runTaskAsynchronously(Main.getInstance(), () -> { - final String QUERY = "INSERT INTO FarmerUsers (farmerId, name, uuid, role) VALUES (?, ?, ?, ?)"; - try (Connection con = DBConnection.connect()) { - PreparedStatement statement = con.prepareStatement(QUERY); - statement.setInt(1, this.getId()); - statement.setString(2, name); - statement.setString(3, uuid.toString()); - statement.setInt(4, FarmerPerm.getRoleId(perm)); - statement.executeUpdate(); - statement.close(); - } - catch (Exception e) { e.printStackTrace(); } - }); + Main.getInstance().getSql().addUser(uuid, name, perm, this); } /** @@ -253,21 +197,21 @@ public void addUser(UUID uuid, String name, FarmerPerm perm) { * @return */ public boolean removeUser(@NotNull User user) { - if (user.getPerm().equals(FarmerPerm.OWNER)) - return false; - this.getUsers().remove(user); - Bukkit.getScheduler().runTaskAsynchronously(Main.getInstance(), () -> { - final String QUERY = "DELETE FROM FarmerUsers WHERE uuid = ? AND farmerId = ?"; - try (Connection con = DBConnection.connect()) { - PreparedStatement statement = con.prepareStatement(QUERY); - statement.setString(1, user.getUuid().toString()); - statement.setInt(2, this.getId()); - statement.executeUpdate(); - statement.close(); - } - catch (Exception e) { e.printStackTrace(); } - }); - return true; + return Main.getInstance().getSql().removeUser(user, this); + } + + /** + * Saves farmer async + */ + public void saveFarmerAsync() { + Bukkit.getScheduler().runTaskAsynchronously(Main.getInstance(), this::saveFarmer); + } + + /** + * Saves farmer sync + */ + public void saveFarmer() { + Main.getInstance().getSql().saveFarmer(this); } /** @@ -283,4 +227,4 @@ public Farmer clone() { throw new AssertionError(); } } -} +} \ No newline at end of file diff --git a/src/main/java/xyz/geik/farmer/model/user/User.java b/src/main/java/xyz/geik/farmer/model/user/User.java index 40a68479..87ce84fe 100644 --- a/src/main/java/xyz/geik/farmer/model/user/User.java +++ b/src/main/java/xyz/geik/farmer/model/user/User.java @@ -6,7 +6,6 @@ import org.bukkit.entity.Player; import org.bukkit.permissions.PermissionAttachmentInfo; import xyz.geik.farmer.Main; -import xyz.geik.farmer.database.DBConnection; import xyz.geik.farmer.model.Farmer; import java.sql.Connection; @@ -78,20 +77,10 @@ else if (user.getPerm().equals(FarmerPerm.MEMBER)) { * @param farmerId */ public static void updateRole(UUID uuid, int roleId, int farmerId) { - Bukkit.getScheduler().runTaskAsynchronously(Main.getInstance(), () -> { - final String QUERY = "UPDATE FarmerUsers SET role = ? WHERE uuid = ? AND farmerId = ?"; - try (Connection con = DBConnection.connect()) { - PreparedStatement statement = con.prepareStatement(QUERY); - statement.setInt(1, roleId); - statement.setString(2, uuid.toString()); - statement.setInt(3, farmerId); - statement.executeUpdate(); - statement.close(); - } - catch (Exception e) {} - }); + Main.getInstance().getSql().updateRole(uuid, roleId, farmerId); } + /** * How many user can player add to farmer. * diff --git a/src/main/java/xyz/geik/farmer/modules/voucher/VoucherEvent.java b/src/main/java/xyz/geik/farmer/modules/voucher/VoucherEvent.java index c546bcec..dfaf5c67 100644 --- a/src/main/java/xyz/geik/farmer/modules/voucher/VoucherEvent.java +++ b/src/main/java/xyz/geik/farmer/modules/voucher/VoucherEvent.java @@ -33,8 +33,10 @@ public class VoucherEvent implements Listener { */ @EventHandler public void onVoucherUseEvent(@NotNull PlayerInteractEvent event) { - if (event.getItem() == null) return; - if (event.getItem().getItemMeta() == null) return; + if (event.getItem() == null) + return; + if (event.getItem().getItemMeta() == null) + return; Player player = event.getPlayer(); int voucherLevel = NBT.get(event.getItem(), voucher -> (voucher.getInteger("farmerLevel"))); ItemStack voucherBase = VoucherItem.getVoucherItem(voucherLevel); @@ -43,7 +45,7 @@ public void onVoucherUseEvent(@NotNull PlayerInteractEvent event) { return; event.setCancelled(true); if (!Settings.isWorldAllowed(player.getWorld().getName())) { - player.sendMessage(Voucher.getInstance().getInstance().getLang().getText("wrongWorld")); + player.sendMessage(Voucher.getInstance().getLang().getText("wrongWorld")); return; } if (!Main.getIntegration().getOwnerUUID(player.getLocation()).equals(player.getUniqueId())) { @@ -70,7 +72,7 @@ public void onVoucherUseEvent(@NotNull PlayerInteractEvent event) { } // Creates new farmer Farmer farmer = new Farmer(Main.getIntegration() - .getRegionID(player.getLocation()), Main.getIntegration().getOwnerUUID(player.getLocation()), voucherLevel-1); + .getRegionID(player.getLocation()), voucherLevel-1); // Opens farmer gui to buyer MainGui.showGui(player, farmer); // Sends message to player diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 041a9a9d..0351a1be 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -21,6 +21,8 @@ settings: - SuperiorWorld - bskyblock_world - island_normal_world + # This need because bentobox api is not working properly + bentoboxWorld: ASkyBlock # Tax rate # If you set it 0 then it useless diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 711b5cc6..2243637c 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,7 +1,7 @@ name: Farmer -author: Geik +author: [Geik, Amowny, WaterArchery, mehmet-27] main: xyz.geik.farmer.Main -version: v6-b000 +version: v6-b001 api-version: 1.13 softdepend: [BentoBox, Vault, ASkyBlock, SuperiorSkyblock2, GriefPrevention, FabledSkyBlock] loadbefore: [AutoPickup, WildStacker] diff --git a/src/main/resources/storage/database.yml b/src/main/resources/storage/database.yml new file mode 100644 index 00000000..95d3d43c --- /dev/null +++ b/src/main/resources/storage/database.yml @@ -0,0 +1,15 @@ +# Database configurations +# If you don't want to setup this plugin to MySQL then leave it default +database: + # type of sql (mysql | sqlite) default: sqlite + type: sqlite # mysql or sqlite + # ip of mysql default: 127.0.0.1 + host: 127.0.0.1 + # port of mysql default: 3306 + port: 3306 + # username of sql default: root + username: root + # password of sql default: + password: "ilovegeikplugins" + # database name of mysql default: + database: geik_farmer \ No newline at end of file