Attempt at implementing NBT

This commit is contained in:
Checkium Folf 2020-01-27 23:46:29 +00:00
parent 12ffd41184
commit 72db20b4ae
6 changed files with 91 additions and 270 deletions

View File

@ -5,8 +5,12 @@ import net.minecraft.server.v1_15_R1.*;
import net.seanomik.tamablefoxes.io.Config; import net.seanomik.tamablefoxes.io.Config;
import net.seanomik.tamablefoxes.versions.version_1_15.pathfinding.*; import net.seanomik.tamablefoxes.versions.version_1_15.pathfinding.*;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.NamespacedKey;
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack; 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.entity.Item;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -188,7 +192,7 @@ public class EntityTamableFox extends EntityFox {
item.setCount(1); item.setCount(1);
setSlot(EnumItemSlot.MAINHAND, item); setSlot(EnumItemSlot.MAINHAND, item);
TamableFoxes.getPlugin().sqLiteSetterGetter.saveFox(this); save();
} }
public void setMouthItem(org.bukkit.inventory.ItemStack item) { public void setMouthItem(org.bukkit.inventory.ItemStack item) {
@ -464,4 +468,26 @@ public class EntityTamableFox extends EntityFox {
return groupdataentity; 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);
}
} }

View File

@ -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.versions.version_1_15.command.CommandSpawnTamableFox;
import net.seanomik.tamablefoxes.io.Config; import net.seanomik.tamablefoxes.io.Config;
import net.seanomik.tamablefoxes.io.LanguageConfig; 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 net.wesjd.anvilgui.AnvilGUI;
import org.bukkit.*; import org.bukkit.*;
import org.bukkit.Material; import org.bukkit.Material;
@ -47,9 +45,6 @@ public final class TamableFoxes extends JavaPlugin implements Listener {
private static TamableFoxes plugin; private static TamableFoxes plugin;
public List<EntityTamableFox> spawnedFoxes = new ArrayList<>(); public List<EntityTamableFox> spawnedFoxes = new ArrayList<>();
public SQLiteSetterGetter sqLiteSetterGetter = new SQLiteSetterGetter();
public SQLiteHandler sqLiteHandler = new SQLiteHandler();
private boolean versionSupported = true; private boolean versionSupported = true;
@Override @Override
@ -98,7 +93,6 @@ public final class TamableFoxes extends JavaPlugin implements Listener {
getServer().getPluginManager().registerEvents(this, this); getServer().getPluginManager().registerEvents(this, this);
this.getCommand("spawntamablefox").setExecutor(new CommandSpawnTamableFox(this)); this.getCommand("spawntamablefox").setExecutor(new CommandSpawnTamableFox(this));
sqLiteSetterGetter.createTablesIfNotExist();
this.saveDefaultConfig(); this.saveDefaultConfig();
getConfig().options().copyDefaults(true); getConfig().options().copyDefaults(true);
saveConfig(); saveConfig();
@ -107,18 +101,18 @@ public final class TamableFoxes extends JavaPlugin implements Listener {
@Override @Override
public void onDisable() { public void onDisable() {
getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.YELLOW + LanguageConfig.getSavingFoxMessage()); getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.YELLOW + LanguageConfig.getSavingFoxMessage());
sqLiteSetterGetter.saveFoxes(spawnedFoxes); spawnedFoxes.forEach(EntityTamableFox::save);
} }
@EventHandler @EventHandler
public void onWorldSaveEvent(WorldSaveEvent event) { public void onWorldSaveEvent(WorldSaveEvent event) {
sqLiteSetterGetter.saveFoxes(spawnedFoxes); spawnedFoxes.forEach(EntityTamableFox::save);
} }
@EventHandler @EventHandler
public void onChunkLoad(ChunkLoadEvent event) { public void onChunkLoad(ChunkLoadEvent event) {
Bukkit.getScheduler().runTaskLaterAsynchronously(this, ()-> { Bukkit.getScheduler().runTaskLaterAsynchronously(this, ()-> {
spawnedFoxes.addAll(sqLiteSetterGetter.loadFoxes(event.getChunk())); spawnedFoxes.addAll(Utils.loadFoxesInChunk(event.getChunk()));
}, 5L); }, 5L);
} }
@ -203,8 +197,7 @@ public final class TamableFoxes extends JavaPlugin implements Listener {
if(!text.equals("")) { if(!text.equals("")) {
tamableFox.setChosenName(text); tamableFox.setChosenName(text);
plr.sendMessage(Utils.getPrefix() + ChatColor.GREEN + LanguageConfig.getTamingChosenPerfect(text)); plr.sendMessage(Utils.getPrefix() + ChatColor.GREEN + LanguageConfig.getTamingChosenPerfect(text));
tamableFox.save();
TamableFoxes.getPlugin().sqLiteSetterGetter.saveFox(tamableFox);
} }
return AnvilGUI.Response.close(); return AnvilGUI.Response.close();

View File

@ -1,16 +1,19 @@
package net.seanomik.tamablefoxes; package net.seanomik.tamablefoxes;
import org.bukkit.Bukkit; import net.minecraft.server.v1_15_R1.EntityLiving;
import org.bukkit.ChatColor; import org.bukkit.*;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity; 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.entity.Entity;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors;
public class Utils { public class Utils {
@ -63,14 +66,14 @@ public class Utils {
try { try {
Class<?> innerClass = getPrivateInnerClass(outer, innerName); Class<?> innerClass = getPrivateInnerClass(outer, innerName);
Object[] argObjects = new Object[args.size()+1]; Object[] argObjects = new Object[args.size() + 1];
Class<?>[] argClasses = new Class<?>[argTypes.size()+1]; Class<?>[] argClasses = new Class<?>[argTypes.size() + 1];
// Needed due to how List#toArray() converts the classes to objects // Needed due to how List#toArray() converts the classes to objects
for (int i = 0; i < argClasses.length; i++) { for (int i = 0; i < argClasses.length; i++) {
if (i == argClasses.length-1) continue; if (i == argClasses.length - 1) continue;
argObjects[i+1] = args.get(i); argObjects[i + 1] = args.get(i);
argClasses[i+1] = argTypes.get(i); argClasses[i + 1] = argTypes.get(i);
} }
argObjects[0] = outerObject; argObjects[0] = outerObject;
argClasses[0] = outer; argClasses[0] = outer;
@ -110,4 +113,50 @@ public class Utils {
return null; return null;
} }
public static List<EntityTamableFox> 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());
}
} }

View File

@ -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;
}
}

View File

@ -41,7 +41,7 @@ public class CommandSpawnTamableFox implements TabExecutor {
case "red": case "red":
try { try {
EntityTamableFox fox = plugin.spawnTamableFox(player.getLocation(), EntityFox.Type.RED); 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)); player.sendMessage(Utils.getPrefix() + ChatColor.RESET + LanguageConfig.getSpawnedFoxMessage(EntityFox.Type.RED));
} catch (Exception e) { } catch (Exception e) {
@ -52,7 +52,7 @@ public class CommandSpawnTamableFox implements TabExecutor {
case "snow": case "snow":
try { try {
EntityTamableFox spawnedFox = plugin.spawnTamableFox(player.getLocation(), EntityFox.Type.SNOW); 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)); player.sendMessage(Utils.getPrefix() + ChatColor.RESET + LanguageConfig.getSpawnedFoxMessage(EntityFox.Type.SNOW));
} catch (Exception e) { } catch (Exception e) {

View File

@ -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<EntityTamableFox> foxes) { // @TODO: Optimize?
if (foxes == null || foxes.size() == 0) return;
for (EntityTamableFox fox : foxes) {
saveFox(fox);
}
}
public List<EntityTamableFox> loadFoxes(Chunk chunk) {
plugin = TamableFoxes.getPlugin(TamableFoxes.class);
// If there are no foxes then don't even start
List<EntityTamableFox> 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<EntityTamableFox> 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());
}
}