diff --git a/src/main/java/net/seanomik/tamablefoxes/EntityTamableFox.java b/src/main/java/net/seanomik/tamablefoxes/EntityTamableFox.java index 439290b..2e3dc68 100644 --- a/src/main/java/net/seanomik/tamablefoxes/EntityTamableFox.java +++ b/src/main/java/net/seanomik/tamablefoxes/EntityTamableFox.java @@ -5,8 +5,12 @@ import net.minecraft.server.v1_15_R1.*; import net.seanomik.tamablefoxes.io.Config; import net.seanomik.tamablefoxes.versions.version_1_15.pathfinding.*; import org.bukkit.ChatColor; +import org.bukkit.NamespacedKey; import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack; +import org.bukkit.craftbukkit.v1_15_R1.persistence.CraftPersistentDataContainer; import org.bukkit.entity.Item; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; import org.bukkit.scheduler.BukkitRunnable; import javax.annotation.Nullable; @@ -188,7 +192,7 @@ public class EntityTamableFox extends EntityFox { item.setCount(1); setSlot(EnumItemSlot.MAINHAND, item); - TamableFoxes.getPlugin().sqLiteSetterGetter.saveFox(this); + save(); } public void setMouthItem(org.bukkit.inventory.ItemStack item) { @@ -464,4 +468,26 @@ public class EntityTamableFox extends EntityFox { return groupdataentity; } + + public void save() { + NamespacedKey rootKey = new NamespacedKey(TamableFoxes.getPlugin(), "tamableFoxes"); + CraftPersistentDataContainer persistentDataContainer = getBukkitEntity().getPersistentDataContainer(); + PersistentDataContainer tamableFoxesData; + if (persistentDataContainer.has(rootKey, PersistentDataType.TAG_CONTAINER)) { + tamableFoxesData = persistentDataContainer.get(rootKey, PersistentDataType.TAG_CONTAINER); + } else { + tamableFoxesData = persistentDataContainer.getAdapterContext().newPersistentDataContainer(); + } + + NamespacedKey ownerKey = new NamespacedKey(TamableFoxes.getPlugin(), "owner"); + NamespacedKey chosenNameKey = new NamespacedKey(TamableFoxes.getPlugin(), "chosenName"); + NamespacedKey sittingKey = new NamespacedKey(TamableFoxes.getPlugin(), "sitting"); + NamespacedKey sleepingKey = new NamespacedKey(TamableFoxes.getPlugin(), "sleeping"); + tamableFoxesData.set(ownerKey, PersistentDataType.STRING, getOwner() == null ? "none" : getOwner().getUniqueID().toString()); + tamableFoxesData.set(chosenNameKey, PersistentDataType.STRING, getChosenName()); + tamableFoxesData.set(sittingKey, PersistentDataType.BYTE, (byte) (isSitting() ? 1 : 0)); + tamableFoxesData.set(sleepingKey, PersistentDataType.BYTE, (byte) (isSleeping() ? 1 : 0)); + + persistentDataContainer.set(rootKey, PersistentDataType.TAG_CONTAINER, tamableFoxesData); + } } diff --git a/src/main/java/net/seanomik/tamablefoxes/TamableFoxes.java b/src/main/java/net/seanomik/tamablefoxes/TamableFoxes.java index baba50f..16005aa 100644 --- a/src/main/java/net/seanomik/tamablefoxes/TamableFoxes.java +++ b/src/main/java/net/seanomik/tamablefoxes/TamableFoxes.java @@ -4,8 +4,6 @@ import net.minecraft.server.v1_15_R1.*; import net.seanomik.tamablefoxes.versions.version_1_15.command.CommandSpawnTamableFox; import net.seanomik.tamablefoxes.io.Config; import net.seanomik.tamablefoxes.io.LanguageConfig; -import net.seanomik.tamablefoxes.sqlite.SQLiteHandler; -import net.seanomik.tamablefoxes.versions.version_1_15.sqlite.SQLiteSetterGetter; import net.wesjd.anvilgui.AnvilGUI; import org.bukkit.*; import org.bukkit.Material; @@ -47,9 +45,6 @@ public final class TamableFoxes extends JavaPlugin implements Listener { private static TamableFoxes plugin; public List spawnedFoxes = new ArrayList<>(); - public SQLiteSetterGetter sqLiteSetterGetter = new SQLiteSetterGetter(); - public SQLiteHandler sqLiteHandler = new SQLiteHandler(); - private boolean versionSupported = true; @Override @@ -98,7 +93,6 @@ public final class TamableFoxes extends JavaPlugin implements Listener { getServer().getPluginManager().registerEvents(this, this); this.getCommand("spawntamablefox").setExecutor(new CommandSpawnTamableFox(this)); - sqLiteSetterGetter.createTablesIfNotExist(); this.saveDefaultConfig(); getConfig().options().copyDefaults(true); saveConfig(); @@ -107,18 +101,18 @@ public final class TamableFoxes extends JavaPlugin implements Listener { @Override public void onDisable() { getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.YELLOW + LanguageConfig.getSavingFoxMessage()); - sqLiteSetterGetter.saveFoxes(spawnedFoxes); + spawnedFoxes.forEach(EntityTamableFox::save); } @EventHandler public void onWorldSaveEvent(WorldSaveEvent event) { - sqLiteSetterGetter.saveFoxes(spawnedFoxes); + spawnedFoxes.forEach(EntityTamableFox::save); } @EventHandler public void onChunkLoad(ChunkLoadEvent event) { Bukkit.getScheduler().runTaskLaterAsynchronously(this, ()-> { - spawnedFoxes.addAll(sqLiteSetterGetter.loadFoxes(event.getChunk())); + spawnedFoxes.addAll(Utils.loadFoxesInChunk(event.getChunk())); }, 5L); } @@ -203,8 +197,7 @@ public final class TamableFoxes extends JavaPlugin implements Listener { if(!text.equals("")) { tamableFox.setChosenName(text); plr.sendMessage(Utils.getPrefix() + ChatColor.GREEN + LanguageConfig.getTamingChosenPerfect(text)); - - TamableFoxes.getPlugin().sqLiteSetterGetter.saveFox(tamableFox); + tamableFox.save(); } return AnvilGUI.Response.close(); diff --git a/src/main/java/net/seanomik/tamablefoxes/Utils.java b/src/main/java/net/seanomik/tamablefoxes/Utils.java index b794a71..4873f01 100644 --- a/src/main/java/net/seanomik/tamablefoxes/Utils.java +++ b/src/main/java/net/seanomik/tamablefoxes/Utils.java @@ -1,16 +1,19 @@ package net.seanomik.tamablefoxes; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Chunk; -import org.bukkit.World; +import net.minecraft.server.v1_15_R1.EntityLiving; +import org.bukkit.*; import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_15_R1.persistence.CraftPersistentDataContainer; import org.bukkit.entity.Entity; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; import java.lang.reflect.Constructor; import java.lang.reflect.Field; +import java.util.Arrays; import java.util.List; import java.util.UUID; +import java.util.stream.Collectors; public class Utils { @@ -63,14 +66,14 @@ public class Utils { try { Class innerClass = getPrivateInnerClass(outer, innerName); - Object[] argObjects = new Object[args.size()+1]; - Class[] argClasses = new Class[argTypes.size()+1]; + Object[] argObjects = new Object[args.size() + 1]; + Class[] argClasses = new Class[argTypes.size() + 1]; // Needed due to how List#toArray() converts the classes to objects for (int i = 0; i < argClasses.length; i++) { - if (i == argClasses.length-1) continue; - argObjects[i+1] = args.get(i); - argClasses[i+1] = argTypes.get(i); + if (i == argClasses.length - 1) continue; + argObjects[i + 1] = args.get(i); + argClasses[i + 1] = argTypes.get(i); } argObjects[0] = outerObject; argClasses[0] = outer; @@ -110,4 +113,50 @@ public class Utils { return null; } + + public static List loadFoxesInChunk(Chunk chunk) { + return Arrays.stream(chunk.getEntities()).filter(Utils::isTamableFox) + .map(entity -> (EntityTamableFox) ((CraftEntity) entity).getHandle()) + .peek(tamableFox -> { + NamespacedKey rootKey = new NamespacedKey(TamableFoxes.getPlugin(), "tamableFoxes"); + CraftPersistentDataContainer persistentDataContainer = tamableFox.getBukkitEntity().getPersistentDataContainer(); + if (persistentDataContainer.has(rootKey, PersistentDataType.TAG_CONTAINER)) { + PersistentDataContainer tamableFoxesData = persistentDataContainer.get(rootKey, PersistentDataType.TAG_CONTAINER); + NamespacedKey ownerKey = new NamespacedKey(TamableFoxes.getPlugin(), "owner"); + NamespacedKey chosenNameKey = new NamespacedKey(TamableFoxes.getPlugin(), "chosenName"); + NamespacedKey sittingKey = new NamespacedKey(TamableFoxes.getPlugin(), "sitting"); + NamespacedKey sleepingKey = new NamespacedKey(TamableFoxes.getPlugin(), "sleeping"); + + String ownerUUIDString = tamableFoxesData.get(ownerKey, PersistentDataType.STRING); + String chosenName = tamableFoxesData.get(chosenNameKey, PersistentDataType.STRING); + boolean sitting = ((byte) 1) == tamableFoxesData.get(sittingKey, PersistentDataType.BYTE); + boolean sleeping = ((byte) 1) == tamableFoxesData.get(sleepingKey, PersistentDataType.BYTE); + + boolean tamed = false; + if (!ownerUUIDString.equals("none")) { + tamed = true; + + OfflinePlayer owner = TamableFoxes.getPlugin().getServer().getOfflinePlayer(UUID.fromString(ownerUUIDString)); + if (owner.isOnline()) { + EntityLiving livingOwner = (EntityLiving) ((CraftEntity) owner).getHandle(); + tamableFox.setOwner(livingOwner); + } + + tamableFox.setOwnerUUID(owner.getUniqueId()); + tamableFox.setTamed(true); + tamableFox.setChosenName(chosenName); + } + + if (sitting && tamed) { + tamableFox.setHardSitting(true); + } else if (sleeping) { + tamableFox.setSleeping(true); + } else { // Avoid the foxes getting stuck sitting down. + tamableFox.setSitting(false); + tamableFox.setSleeping(false); + } + } + }).collect(Collectors.toList()); + } + } diff --git a/src/main/java/net/seanomik/tamablefoxes/sqlite/SQLiteHandler.java b/src/main/java/net/seanomik/tamablefoxes/sqlite/SQLiteHandler.java deleted file mode 100644 index 6caa8f4..0000000 --- a/src/main/java/net/seanomik/tamablefoxes/sqlite/SQLiteHandler.java +++ /dev/null @@ -1,47 +0,0 @@ -package net.seanomik.tamablefoxes.sqlite; - -import net.seanomik.tamablefoxes.TamableFoxes; - -import java.io.File; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.util.Properties; - -public class SQLiteHandler { - private Connection connection; - - public void connect() { - try { - String url = "jdbc:sqlite:" + TamableFoxes.getPlugin().getDataFolder() + "/foxes.db"; - connection = DriverManager.getConnection(url); - } catch (SQLException e) { - e.printStackTrace(); - } - } - - public Connection getConnection() { - return connection; - } - - public void closeConnection() { - try { - connection.close(); - } catch (SQLException e) { - e.printStackTrace(); - } - } - - public void newConnection() { - try { - connection.close(); - connect(); - } catch (SQLException e) { - e.printStackTrace(); - } - } - - public void setConnection(Connection connection) { - this.connection = connection; - } -} diff --git a/src/main/java/net/seanomik/tamablefoxes/versions/version_1_15/command/CommandSpawnTamableFox.java b/src/main/java/net/seanomik/tamablefoxes/versions/version_1_15/command/CommandSpawnTamableFox.java index 0d4f7f5..cf9e93d 100644 --- a/src/main/java/net/seanomik/tamablefoxes/versions/version_1_15/command/CommandSpawnTamableFox.java +++ b/src/main/java/net/seanomik/tamablefoxes/versions/version_1_15/command/CommandSpawnTamableFox.java @@ -41,7 +41,7 @@ public class CommandSpawnTamableFox implements TabExecutor { case "red": try { EntityTamableFox fox = plugin.spawnTamableFox(player.getLocation(), EntityFox.Type.RED); - plugin.sqLiteSetterGetter.saveFox(fox); + fox.save(); player.sendMessage(Utils.getPrefix() + ChatColor.RESET + LanguageConfig.getSpawnedFoxMessage(EntityFox.Type.RED)); } catch (Exception e) { @@ -52,7 +52,7 @@ public class CommandSpawnTamableFox implements TabExecutor { case "snow": try { EntityTamableFox spawnedFox = plugin.spawnTamableFox(player.getLocation(), EntityFox.Type.SNOW); - plugin.sqLiteSetterGetter.saveFox(spawnedFox); + spawnedFox.save(); player.sendMessage(Utils.getPrefix() + ChatColor.RESET + LanguageConfig.getSpawnedFoxMessage(EntityFox.Type.SNOW)); } catch (Exception e) { diff --git a/src/main/java/net/seanomik/tamablefoxes/versions/version_1_15/sqlite/SQLiteSetterGetter.java b/src/main/java/net/seanomik/tamablefoxes/versions/version_1_15/sqlite/SQLiteSetterGetter.java deleted file mode 100644 index fb7ac87..0000000 --- a/src/main/java/net/seanomik/tamablefoxes/versions/version_1_15/sqlite/SQLiteSetterGetter.java +++ /dev/null @@ -1,200 +0,0 @@ -package net.seanomik.tamablefoxes.versions.version_1_15.sqlite; - -import net.minecraft.server.v1_15_R1.EntityLiving; -import net.seanomik.tamablefoxes.EntityTamableFox; -import net.seanomik.tamablefoxes.TamableFoxes; -import net.seanomik.tamablefoxes.Utils; -import net.seanomik.tamablefoxes.io.LanguageConfig; -import net.seanomik.tamablefoxes.sqlite.SQLiteHandler; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Chunk; -import org.bukkit.OfflinePlayer; -import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity; -import org.bukkit.entity.Entity; - -import java.sql.DatabaseMetaData; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; - -// @TODO: Use try-with-resource instead of try-catch-finally - -public class SQLiteSetterGetter { - public static TamableFoxes plugin; - public static SQLiteHandler sqLiteHandler; - - public void createTablesIfNotExist() { - plugin = TamableFoxes.getPlugin(TamableFoxes.class); - sqLiteHandler = plugin.sqLiteHandler; - - String foxesTable = - "CREATE TABLE IF NOT EXISTS `foxes` ( " + - "`ENTITY_UUID` TEXT PRIMARY KEY , " + - "`OWNER_UUID` TEXT NOT NULL , " + - "`NAME` TEXT, " + - "`SITTING` INTEGER NOT NULL , " + - "`SLEEPING` INTEGER NOT NULL);"; - - try { - sqLiteHandler.connect(); - // Create previous bans table - DatabaseMetaData dbm = sqLiteHandler.getConnection().getMetaData(); - ResultSet tables = dbm.getTables(null, null, "foxes", null); - if (!tables.next()) { - PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement(foxesTable); - statement.executeUpdate(); - - plugin.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.GREEN + LanguageConfig.getCreatedSQLDatabase()); - } - } catch (SQLException e) { - e.printStackTrace(); - } finally { - if (sqLiteHandler.getConnection() != null) { - sqLiteHandler.closeConnection(); - } - } - } - - public void saveFox(EntityTamableFox fox) { - plugin = TamableFoxes.getPlugin(TamableFoxes.class); - - // If the fox is null or not alive, delete it from the database - if (fox == null || !fox.isAlive()) { - removeFox(fox); - return; - } - - try { - sqLiteHandler.connect(); - - PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement("INSERT INTO foxes (ENTITY_UUID,OWNER_UUID,NAME,SITTING,SLEEPING) VALUES (?,?,?,?,?)"); - - // If the database does contain this fox, then change the statement to an update statement instead of insert. - PreparedStatement hasFoxStatement = sqLiteHandler.getConnection().prepareStatement("SELECT * FROM foxes WHERE ENTITY_UUID=?"); - hasFoxStatement.setString(1, fox.getUniqueID().toString()); - ResultSet results = hasFoxStatement.executeQuery(); - if (results.next()) { - statement = sqLiteHandler.getConnection().prepareStatement("UPDATE foxes SET OWNER_UUID=?, NAME=?, SITTING=?, SLEEPING=? WHERE ENTITY_UUID='" + fox.getUniqueID().toString() + "'"); - statement.setString(1, (fox.getOwner() == null) ? "none" : fox.getOwner().getUniqueID().toString()); - statement.setString(2, fox.getChosenName()); - statement.setInt(3, (fox.isSitting()) ? 1 : 0); - statement.setInt(4, (fox.isSleeping()) ? 1 : 0); - } else { - statement.setString(1, fox.getUniqueID().toString()); - statement.setString(2, (fox.getOwner() == null) ? "none" : fox.getOwner().getUniqueID().toString()); - statement.setString(3, fox.getChosenName()); - statement.setInt(4, (fox.isSitting()) ? 1 : 0); - statement.setInt(5, (fox.isSleeping()) ? 1 : 0); - } - - statement.executeUpdate(); - } catch (SQLException e) { - e.printStackTrace(); - } finally { - if (sqLiteHandler.getConnection() != null) { - sqLiteHandler.closeConnection(); - } - } - } - - public void saveFoxes(List foxes) { // @TODO: Optimize? - if (foxes == null || foxes.size() == 0) return; - - for (EntityTamableFox fox : foxes) { - saveFox(fox); - } - } - - public List loadFoxes(Chunk chunk) { - plugin = TamableFoxes.getPlugin(TamableFoxes.class); - - // If there are no foxes then don't even start - List foxesInChunk = new ArrayList<>(); - for (Entity entity : chunk.getEntities()) { - if (Utils.isTamableFox(entity)) { - foxesInChunk.add((EntityTamableFox) ((CraftEntity) entity).getHandle()); - } - } - - if (foxesInChunk.size() == 0) { - return new ArrayList<>(); - } - - try { - sqLiteHandler.connect(); - - List spawnedFoxes = new ArrayList<>(); - - for (EntityTamableFox tamableFox : foxesInChunk) { - PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement("SELECT * FROM foxes WHERE ENTITY_UUID=?"); - statement.setString(1, tamableFox.getUniqueID().toString()); - ResultSet results = statement.executeQuery(); - - if (results.next()) { - String ownerUUIDString = results.getString("OWNER_UUID"); - String name = results.getString("NAME"); - boolean sitting = results.getInt("SITTING") == 1; - boolean sleeping = results.getInt("SLEEPING") == 1; - - boolean tamed = false; - if (!ownerUUIDString.equals("none")) { - tamed = true; - - OfflinePlayer owner = plugin.getServer().getOfflinePlayer(UUID.fromString(ownerUUIDString)); - if (owner.isOnline()) { - EntityLiving livingOwner = (EntityLiving) ((CraftEntity) owner).getHandle(); - tamableFox.setOwner(livingOwner); - } - - tamableFox.setOwnerUUID(owner.getUniqueId()); - tamableFox.setTamed(true); - tamableFox.setChosenName(name); - } - - if (sitting && tamed) { - tamableFox.setHardSitting(true); - } else if (sleeping) { - tamableFox.setSleeping(true); - } else { // Avoid the foxes getting stuck sitting down. - tamableFox.setSitting(false); - tamableFox.setSleeping(false); - } - - - spawnedFoxes.add(tamableFox); - } - } - - return spawnedFoxes; - } catch (SQLException e) { - e.printStackTrace(); - } finally { - if (sqLiteHandler.getConnection() != null) { - sqLiteHandler.closeConnection(); - } - } - return null; - } - - public void removeFox(UUID uuid) { - plugin = TamableFoxes.getPlugin(TamableFoxes.class); - try { - sqLiteHandler.connect(); - - PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement("DELETE FROM foxes WHERE ENTITY_UUID='" + uuid.toString() + "'"); - statement.executeUpdate(); - } catch (SQLException e) { - e.printStackTrace(); - } finally { - if (sqLiteHandler.getConnection() != null) { - sqLiteHandler.closeConnection(); - } - } - } - - public void removeFox(EntityTamableFox fox) { - removeFox(fox.getUniqueID()); - } -}