From 45c51492a3469c7a79844f793d15c90db1ad579d Mon Sep 17 00:00:00 2001 From: HeroBrineGoat <76707404+MasterOfTheFish@users.noreply.github.com> Date: Sat, 22 Jan 2022 01:10:59 -0500 Subject: [PATCH] Fixed database --- .../fisher2911/hmccosmetics/HMCCosmetics.java | 21 +++++++++ .../command/CosmeticsCommand.java | 9 ++-- .../hmccosmetics/concurrent/Threads.java | 39 ++++++++++++++++ .../hmccosmetics/database/Database.java | 46 ++++++++++++------- .../database/dao/ArmorItemDAO.java | 46 ++++++++++++++----- .../hmccosmetics/database/dao/UserDAO.java | 17 ++----- .../hmccosmetics/gui/CosmeticGui.java | 2 +- .../hmccosmetics/inventory/PlayerArmor.java | 10 ++++ .../hmccosmetics/listener/JoinListener.java | 7 +-- .../fisher2911/hmccosmetics/user/User.java | 21 ++++++--- .../hmccosmetics/user/UserManager.java | 8 +++- 11 files changed, 164 insertions(+), 62 deletions(-) create mode 100644 src/main/java/io/github/fisher2911/hmccosmetics/concurrent/Threads.java diff --git a/src/main/java/io/github/fisher2911/hmccosmetics/HMCCosmetics.java b/src/main/java/io/github/fisher2911/hmccosmetics/HMCCosmetics.java index e01c3e3d..59ffc421 100644 --- a/src/main/java/io/github/fisher2911/hmccosmetics/HMCCosmetics.java +++ b/src/main/java/io/github/fisher2911/hmccosmetics/HMCCosmetics.java @@ -4,6 +4,7 @@ import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolManager; import io.github.fisher2911.hmccosmetics.command.CosmeticsCommand; +import io.github.fisher2911.hmccosmetics.concurrent.Threads; import io.github.fisher2911.hmccosmetics.cosmetic.CosmeticManager; import io.github.fisher2911.hmccosmetics.database.Database; import io.github.fisher2911.hmccosmetics.database.DatabaseFactory; @@ -18,7 +19,9 @@ import io.github.fisher2911.hmccosmetics.user.UserManager; import me.mattstudios.mf.base.CommandManager; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; +import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitTask; import java.sql.SQLException; import java.util.Arrays; @@ -36,6 +39,8 @@ public class HMCCosmetics extends JavaPlugin { private CommandManager commandManager; private Database database; + private BukkitTask saveTask; + @Override public void onEnable() { final int pluginId = 13873; @@ -63,13 +68,29 @@ public class HMCCosmetics extends JavaPlugin { } HookManager.getInstance().registerListeners(this); + + this.saveTask = Bukkit.getScheduler().runTaskTimerAsynchronously( + this, + () -> { + for (final Player player : Bukkit.getOnlinePlayers()) { + this.userManager.get(player.getUniqueId()).ifPresent( + this.database::saveUser + ); + } + }, + 20, + 20 * 60 + ); } @Override public void onDisable() { + this.saveTask.cancel(); + this.database.saveAll(); this.messageHandler.close(); this.userManager.cancelTeleportTask(); this.userManager.removeAll(); + Threads.getInstance().onDisable(); this.database.close(); } diff --git a/src/main/java/io/github/fisher2911/hmccosmetics/command/CosmeticsCommand.java b/src/main/java/io/github/fisher2911/hmccosmetics/command/CosmeticsCommand.java index 5f0970b7..15351b75 100644 --- a/src/main/java/io/github/fisher2911/hmccosmetics/command/CosmeticsCommand.java +++ b/src/main/java/io/github/fisher2911/hmccosmetics/command/CosmeticsCommand.java @@ -85,12 +85,9 @@ public class CosmeticsCommand extends CommandBase { @SubCommand("help") // WORK IN PROGRESS (WIP) @Permission(io.github.fisher2911.hmccosmetics.message.Permission.HELP_COMMAND) public void helpCommand(final CommandSender sender) { - Bukkit.getScheduler().runTaskAsynchronously( - this.plugin, - () -> this.messageHandler.sendMessage( - sender, - Messages.HELP_COMMAND - ) + this.messageHandler.sendMessage( + sender, + Messages.HELP_COMMAND ); } diff --git a/src/main/java/io/github/fisher2911/hmccosmetics/concurrent/Threads.java b/src/main/java/io/github/fisher2911/hmccosmetics/concurrent/Threads.java new file mode 100644 index 00000000..54cf18fa --- /dev/null +++ b/src/main/java/io/github/fisher2911/hmccosmetics/concurrent/Threads.java @@ -0,0 +1,39 @@ +package io.github.fisher2911.hmccosmetics.concurrent; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class Threads { + + private static final Threads INSTANCE; + + static { + INSTANCE = new Threads(); + } + + public static Threads getInstance() { + return INSTANCE; + } + + private final ExecutorService service; + private boolean running; + + private Threads() { + this.service = Executors.newCachedThreadPool(); + } + + public void submit(final Runnable runnable) { + this.service.submit(() -> { + try { + runnable.run(); + } catch (final Exception exception) { + exception.printStackTrace(); + } + }); + } + + public void onDisable() { + this.service.shutdownNow().forEach(Runnable::run); + } + +} diff --git a/src/main/java/io/github/fisher2911/hmccosmetics/database/Database.java b/src/main/java/io/github/fisher2911/hmccosmetics/database/Database.java index cff47e58..b6207b49 100644 --- a/src/main/java/io/github/fisher2911/hmccosmetics/database/Database.java +++ b/src/main/java/io/github/fisher2911/hmccosmetics/database/Database.java @@ -4,19 +4,28 @@ import com.j256.ormlite.dao.BaseForeignCollection; import com.j256.ormlite.dao.Dao; import com.j256.ormlite.dao.DaoManager; import com.j256.ormlite.dao.ForeignCollection; +import com.j256.ormlite.logger.ConsoleLogBackend; +import com.j256.ormlite.logger.Level; +import com.j256.ormlite.logger.Logger; +import com.j256.ormlite.stmt.UpdateBuilder; +import com.j256.ormlite.stmt.Where; import com.j256.ormlite.support.ConnectionSource; import com.j256.ormlite.table.TableUtils; import io.github.fisher2911.hmccosmetics.HMCCosmetics; +import io.github.fisher2911.hmccosmetics.concurrent.Threads; import io.github.fisher2911.hmccosmetics.database.dao.ArmorItemDAO; import io.github.fisher2911.hmccosmetics.database.dao.UserDAO; import io.github.fisher2911.hmccosmetics.gui.ArmorItem; import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor; import io.github.fisher2911.hmccosmetics.user.User; import org.bukkit.Bukkit; +import org.bukkit.entity.Player; import java.sql.Connection; import java.sql.SQLException; +import java.util.ArrayList; import java.util.Collection; +import java.util.List; import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; @@ -46,7 +55,7 @@ public class Database { private final DatabaseType databaseType; final Dao userDao; - final Dao armorItemDao; + final Dao armorItemDao; public Database( final HMCCosmetics plugin, @@ -57,6 +66,8 @@ public class Database { this.userDao = DaoManager.createDao(this.dataSource, UserDAO.class); this.armorItemDao = DaoManager.createDao(this.dataSource, ArmorItemDAO.class); this.databaseType = databaseType; + Logger.setGlobalLogLevel(Level.DEBUG); + } public void load() { @@ -74,22 +85,21 @@ public class Database { public void loadUser(final UUID uuid) { final int armorStandId = ARMOR_STAND_ID.getAndDecrement(); - Bukkit.getScheduler().runTaskAsynchronously(this.plugin, + Threads.getInstance().submit( () -> { try { UserDAO user = this.userDao.queryForId(uuid); if (user == null) { user = this.userDao.createIfNotExists(new UserDAO(uuid)); - this.plugin.getLogger().severe("Created New: " + user); - this.userDao.assignEmptyForeignCollection(user, "armorItems"); - this.plugin.getLogger().severe("Initializing Collection: " + user); } + final List armorItems = this.armorItemDao.queryForEq("uuid", uuid.toString()); + final UserDAO finalUser = user; Bukkit.getScheduler().runTask(this.plugin, () -> this.plugin.getUserManager().add( - finalUser.toUser(this.plugin.getCosmeticManager(), armorStandId) + finalUser.toUser(this.plugin.getCosmeticManager(), armorItems, armorStandId) ) ); @@ -105,24 +115,28 @@ public class Database { public void saveUser(final User user) { try { final UserDAO userDAO = new UserDAO(user.getUuid()); - this.userDao.assignEmptyForeignCollection(userDAO, "armorItems"); + this.userDao.createOrUpdate(userDAO); + final String uuid = user.getUuid().toString(); for (final ArmorItem armorItem : user.getPlayerArmor().getArmorItems()) { final ArmorItemDAO dao = ArmorItemDAO.fromArmorItem(armorItem); - dao.setUser(userDAO); - final ForeignCollection armorItems = userDAO.getArmorItems(); - if (armorItems.contains(dao)) { - armorItems.update(dao); - } else { - armorItems.add(dao); - } + dao.setUuid(uuid); + this.armorItemDao.createOrUpdate(dao); } - this.userDao.createOrUpdate(userDAO); + } catch (final SQLException exception) { exception.printStackTrace(); } } + public void saveAll() { + for (final Player player : Bukkit.getOnlinePlayers()) { + this.plugin.getUserManager().get(player.getUniqueId()).ifPresent( + this::saveUser + ); + } + } + public void close() { try { this.dataSource.close(); @@ -143,7 +157,7 @@ public class Database { return userDao; } - public Dao getArmorItemDao() { + public Dao getArmorItemDao() { return armorItemDao; } diff --git a/src/main/java/io/github/fisher2911/hmccosmetics/database/dao/ArmorItemDAO.java b/src/main/java/io/github/fisher2911/hmccosmetics/database/dao/ArmorItemDAO.java index 146a6fcb..2d43de77 100644 --- a/src/main/java/io/github/fisher2911/hmccosmetics/database/dao/ArmorItemDAO.java +++ b/src/main/java/io/github/fisher2911/hmccosmetics/database/dao/ArmorItemDAO.java @@ -8,16 +8,19 @@ import org.jetbrains.annotations.Nullable; import java.util.Objects; -@DatabaseTable(tableName = "armor_item") +@DatabaseTable(tableName = "armor_items") public class ArmorItemDAO { - @DatabaseField(foreign = true, foreignAutoRefresh = true, columnName = "user", uniqueCombo = true) - private UserDAO user; + @DatabaseField(columnName = "uuid", useGetSet = true, uniqueCombo = true) + private String uuid; @DatabaseField private String id; - @DatabaseField(id = true, uniqueCombo = true) + @DatabaseField(id = true, useGetSet = true, columnName = "artificial_id") + private String artificialId; + + @DatabaseField(uniqueCombo = true) private String type; @DatabaseField(columnName = "color") @@ -25,6 +28,7 @@ public class ArmorItemDAO { public ArmorItemDAO(final String id, final String type, final int rgbDye) { this.id = id; + this.artificialId = this.getArtificialId(); this.type = type; this.rgbDye = rgbDye; } @@ -45,16 +49,24 @@ public class ArmorItemDAO { public ArmorItemDAO() { } - public UserDAO getUser() { - return user; + public String getUuid() { + return uuid; } - public void setUser(final UserDAO user) { - this.user = user; + public void setUuid(final String uuid) { + this.uuid = uuid; } - public String getId() { - return id; + /** + * ORMLite does not allow more than one primary key (WHYYYY???????????) + * @return + */ + public String getArtificialId() { + return this.uuid + "-" + this.type; + } + + public void setArtificialId(final String artificialId) { + this.artificialId = artificialId; } public void setId(final String id) { @@ -82,11 +94,21 @@ public class ArmorItemDAO { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; final ArmorItemDAO that = (ArmorItemDAO) o; - return Objects.equals(getUser(), that.getUser()) && Objects.equals(getType(), that.getType()); + return Objects.equals(getUuid(), that.getUuid()) && Objects.equals(getType(), that.getType()); } @Override public int hashCode() { - return Objects.hash(getUser(), getType()); + return Objects.hash(getUuid(), getType()); + } + + @Override + public String toString() { + return "ArmorItemDAO{" + + "uuid='" + uuid + '\'' + + ", id='" + id + '\'' + + ", type='" + type + '\'' + + ", rgbDye=" + rgbDye + + '}'; } } diff --git a/src/main/java/io/github/fisher2911/hmccosmetics/database/dao/UserDAO.java b/src/main/java/io/github/fisher2911/hmccosmetics/database/dao/UserDAO.java index 81c649c9..a1108416 100644 --- a/src/main/java/io/github/fisher2911/hmccosmetics/database/dao/UserDAO.java +++ b/src/main/java/io/github/fisher2911/hmccosmetics/database/dao/UserDAO.java @@ -11,6 +11,7 @@ import io.github.fisher2911.hmccosmetics.user.User; import java.util.ArrayList; import java.util.Collection; +import java.util.List; import java.util.Objects; import java.util.UUID; @@ -20,9 +21,6 @@ public class UserDAO { @DatabaseField(id = true) private UUID uuid; - @ForeignCollectionField(eager = true) - private ForeignCollection armorItems; - public UserDAO() { } @@ -34,18 +32,10 @@ public class UserDAO { this.uuid = uuid; } - public ForeignCollection getArmorItems() { - return armorItems; - } - - public void setArmorItems(final ForeignCollection armorItems) { - this.armorItems = armorItems; - } - - public User toUser(final CosmeticManager cosmeticManager, final int armorStandId) { + public User toUser(final CosmeticManager cosmeticManager, final List armorItems, final int armorStandId) { final PlayerArmor playerArmor = PlayerArmor.empty(); - for (final ArmorItemDAO armorItemDao : this.armorItems) { + for (final ArmorItemDAO armorItemDao : armorItems) { final ArmorItem armorItem = armorItemDao.toArmorItem(cosmeticManager); if (armorItem == null) continue; playerArmor.setItem(armorItem); @@ -58,7 +48,6 @@ public class UserDAO { public String toString() { return "UserDAO{" + "uuid=" + uuid + - ", armorItems=" + armorItems + '}'; } diff --git a/src/main/java/io/github/fisher2911/hmccosmetics/gui/CosmeticGui.java b/src/main/java/io/github/fisher2911/hmccosmetics/gui/CosmeticGui.java index 36efc4d1..ac062fec 100644 --- a/src/main/java/io/github/fisher2911/hmccosmetics/gui/CosmeticGui.java +++ b/src/main/java/io/github/fisher2911/hmccosmetics/gui/CosmeticGui.java @@ -174,7 +174,7 @@ public class CosmeticGui { return; } - this.setUserArmor(player, user, armorItem, event, armorItem.getAction()); + this.setUserArmor(player, user, new ArmorItem(armorItem), event, armorItem.getAction()); } ); } diff --git a/src/main/java/io/github/fisher2911/hmccosmetics/inventory/PlayerArmor.java b/src/main/java/io/github/fisher2911/hmccosmetics/inventory/PlayerArmor.java index c2f6a47c..ea974fa7 100644 --- a/src/main/java/io/github/fisher2911/hmccosmetics/inventory/PlayerArmor.java +++ b/src/main/java/io/github/fisher2911/hmccosmetics/inventory/PlayerArmor.java @@ -3,7 +3,9 @@ package io.github.fisher2911.hmccosmetics.inventory; import io.github.fisher2911.hmccosmetics.gui.ArmorItem; import java.util.Collection; +import java.util.Collections; import java.util.EnumMap; +import java.util.HashMap; import java.util.Map; public class PlayerArmor { @@ -25,6 +27,10 @@ public class PlayerArmor { ); } + public PlayerArmor(final Map armorItems) { + this.armorItems = armorItems; + } + public ArmorItem getHat() { return this.armorItems.get(ArmorItem.Type.HAT); } @@ -48,4 +54,8 @@ public class PlayerArmor { public Collection getArmorItems() { return this.armorItems.values(); } + + public PlayerArmor copy() { + return new PlayerArmor(new HashMap<>(this.armorItems)); + } } diff --git a/src/main/java/io/github/fisher2911/hmccosmetics/listener/JoinListener.java b/src/main/java/io/github/fisher2911/hmccosmetics/listener/JoinListener.java index c869dc73..5d684926 100644 --- a/src/main/java/io/github/fisher2911/hmccosmetics/listener/JoinListener.java +++ b/src/main/java/io/github/fisher2911/hmccosmetics/listener/JoinListener.java @@ -32,10 +32,7 @@ public class JoinListener implements Listener { @EventHandler public void onQuit(final PlayerQuitEvent event) { - this.userManager.remove(event.getPlayer().getUniqueId()); - this.userManager.get(event.getPlayer().getUniqueId()). - ifPresent( - this.database::saveUser - ); + final Player player = event.getPlayer(); + this.userManager.remove(player.getUniqueId()); } } diff --git a/src/main/java/io/github/fisher2911/hmccosmetics/user/User.java b/src/main/java/io/github/fisher2911/hmccosmetics/user/User.java index 5448f474..d643557c 100644 --- a/src/main/java/io/github/fisher2911/hmccosmetics/user/User.java +++ b/src/main/java/io/github/fisher2911/hmccosmetics/user/User.java @@ -54,8 +54,9 @@ public class User { } protected void setPlayerArmor(final PlayerArmor playerArmor) { - this.playerArmor.setItem(playerArmor.getBackpack()); - this.playerArmor.setItem(playerArmor.getHat()); + for (final ArmorItem armorItem : playerArmor.getArmorItems()) { + this.playerArmor.setItem(armorItem); + } } protected void removeAllCosmetics() { @@ -115,8 +116,8 @@ public class User { try { protocolManager.sendServerPacket(other, packet); protocolManager.sendServerPacket(other, ridingPacket); - } catch (InvocationTargetException e) { - e.printStackTrace(); + } catch (final InvocationTargetException exception) { + exception.printStackTrace(); } } @@ -177,9 +178,15 @@ public class User { final ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager(); - protocolManager.broadcastServerPacket(armorPacket); - protocolManager.broadcastServerPacket(metaContainer); - protocolManager.broadcastServerPacket(rotationPacket); + try { + for (final Player p : Bukkit.getOnlinePlayers()) { + protocolManager.sendServerPacket(p, armorPacket); + protocolManager.sendServerPacket(p, metaContainer); + protocolManager.sendServerPacket(p, rotationPacket); + } + } catch (final InvocationTargetException exception) { + exception.printStackTrace(); + } } public void despawnAttached() { diff --git a/src/main/java/io/github/fisher2911/hmccosmetics/user/UserManager.java b/src/main/java/io/github/fisher2911/hmccosmetics/user/UserManager.java index 231aeff7..6d7a8901 100644 --- a/src/main/java/io/github/fisher2911/hmccosmetics/user/UserManager.java +++ b/src/main/java/io/github/fisher2911/hmccosmetics/user/UserManager.java @@ -10,6 +10,7 @@ import com.comphenix.protocol.wrappers.EnumWrappers; import com.comphenix.protocol.wrappers.Pair; import com.google.common.xml.XmlEscapers; import io.github.fisher2911.hmccosmetics.HMCCosmetics; +import io.github.fisher2911.hmccosmetics.concurrent.Threads; import io.github.fisher2911.hmccosmetics.database.dao.UserDAO; import io.github.fisher2911.hmccosmetics.gui.ArmorItem; import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor; @@ -71,9 +72,15 @@ public class UserManager { this.armorStandIdMap.remove(user.getArmorStandId()); + final PlayerArmor copy = user.getPlayerArmor().copy(); + user.removeAllCosmetics(); this.updateCosmetics(user); user.despawnAttached(); + + user.setPlayerArmor(copy); + + Threads.getInstance().submit(() -> this.plugin.getDatabase().saveUser(user)); } public void startTeleportTask() { @@ -214,7 +221,6 @@ public class UserManager { switch (armorItem.getType()) { case HAT, OFF_HAND -> this.updateCosmetics(user); } - Bukkit.getScheduler().runTaskAsynchronously(this.plugin, () -> this.plugin.getDatabase().saveUser(user)); } public void removeItem(final User user, final ArmorItem.Type type) {