diff --git a/bukkit/src/main/java/me/william278/crossserversync/bukkit/PlayerSetter.java b/bukkit/src/main/java/me/william278/crossserversync/bukkit/PlayerSetter.java index 7d874d7b..ced5a97e 100644 --- a/bukkit/src/main/java/me/william278/crossserversync/bukkit/PlayerSetter.java +++ b/bukkit/src/main/java/me/william278/crossserversync/bukkit/PlayerSetter.java @@ -29,6 +29,7 @@ public class PlayerSetter { player.setSaturation(data.getSaturation()); player.setExhaustion(data.getSaturationExhaustion()); player.getInventory().setHeldItemSlot(data.getSelectedSlot()); + player.setTotalExperience(data.getExperience()); //todo potion effects not working setPlayerPotionEffects(player, DataSerializer.potionEffectArrayFromBase64(data.getSerializedEffectData())); diff --git a/bukkit/src/main/java/me/william278/crossserversync/bukkit/listener/EventListener.java b/bukkit/src/main/java/me/william278/crossserversync/bukkit/listener/EventListener.java index 5e1fd87b..7382b6fb 100644 --- a/bukkit/src/main/java/me/william278/crossserversync/bukkit/listener/EventListener.java +++ b/bukkit/src/main/java/me/william278/crossserversync/bukkit/listener/EventListener.java @@ -35,7 +35,8 @@ public class EventListener implements Listener { player.getSaturation(), player.getExhaustion(), player.getInventory().getHeldItemSlot(), - DataSerializer.getSerializedEffectData(player))); + DataSerializer.getSerializedEffectData(player), + player.getTotalExperience())); } @EventHandler diff --git a/bungeecord/src/main/java/me/william278/crossserversync/bungeecord/data/DataManager.java b/bungeecord/src/main/java/me/william278/crossserversync/bungeecord/data/DataManager.java index 29b56db0..a51e3b94 100644 --- a/bungeecord/src/main/java/me/william278/crossserversync/bungeecord/data/DataManager.java +++ b/bungeecord/src/main/java/me/william278/crossserversync/bungeecord/data/DataManager.java @@ -76,8 +76,9 @@ public class DataManager { final float saturationExhaustion = resultSet.getFloat("saturation_exhaustion"); final int selectedSlot = resultSet.getInt("selected_slot"); final String serializedStatusEffects = resultSet.getString("status_effects"); + final int experience = resultSet.getInt("experience"); - return new PlayerData(playerUUID, dataVersionUUID, serializedInventory, serializedEnderChest, health, maxHealth, hunger, saturation, saturationExhaustion, selectedSlot, serializedStatusEffects); + return new PlayerData(playerUUID, dataVersionUUID, serializedInventory, serializedEnderChest, health, maxHealth, hunger, saturation, saturationExhaustion, selectedSlot, serializedStatusEffects, experience); } else { return PlayerData.DEFAULT_PLAYER_DATA(playerUUID); } @@ -105,7 +106,7 @@ public class DataManager { private static void updatePlayerSQLData(PlayerData playerData) { try (Connection connection = CrossServerSyncBungeeCord.getConnection()) { try (PreparedStatement statement = connection.prepareStatement( - "UPDATE " + Database.DATA_TABLE_NAME + " SET `version_uuid`=?, `timestamp`=?, `inventory`=?, `ender_chest`=?, `health`=?, `max_health`=?, `hunger`=?, `saturation`=?, `saturation_exhaustion`=?, `selected_slot`=?, `status_effects`=? WHERE `player_id`=(SELECT `id` FROM " + Database.PLAYER_TABLE_NAME + " WHERE `uuid`=?);")) { + "UPDATE " + Database.DATA_TABLE_NAME + " SET `version_uuid`=?, `timestamp`=?, `inventory`=?, `ender_chest`=?, `health`=?, `max_health`=?, `hunger`=?, `saturation`=?, `saturation_exhaustion`=?, `selected_slot`=?, `status_effects`=?, `experience`=? WHERE `player_id`=(SELECT `id` FROM " + Database.PLAYER_TABLE_NAME + " WHERE `uuid`=?);")) { statement.setString(1, playerData.getDataVersionUUID().toString()); statement.setTimestamp(2, new Timestamp(Instant.now().getEpochSecond())); statement.setString(3, playerData.getSerializedInventory()); @@ -117,7 +118,8 @@ public class DataManager { statement.setFloat(9, playerData.getSaturationExhaustion()); // Saturation exhaustion statement.setInt(10, playerData.getSelectedSlot()); // Current selected slot statement.setString(11, playerData.getSerializedEffectData()); // Status effects - statement.setString(12, playerData.getPlayerUUID().toString()); + statement.setInt(12, playerData.getExperience()); // Experience + statement.setString(13, playerData.getPlayerUUID().toString()); statement.executeUpdate(); } } catch (SQLException e) { @@ -128,7 +130,7 @@ public class DataManager { private static void insertPlayerData(PlayerData playerData) { try (Connection connection = CrossServerSyncBungeeCord.getConnection()) { try (PreparedStatement statement = connection.prepareStatement( - "INSERT INTO " + Database.DATA_TABLE_NAME + " (`player_id`,`version_uuid`,`timestamp`,`inventory`,`ender_chest`,`health`,`max_health`,`hunger`,`saturation`,`saturation_exhaustion`,`selected_slot`,`status_effects`) VALUES((SELECT `id` FROM " + Database.PLAYER_TABLE_NAME + " WHERE `uuid`=?),?,?,?,?,?,?,?,?,?,?,?);")) { + "INSERT INTO " + Database.DATA_TABLE_NAME + " (`player_id`,`version_uuid`,`timestamp`,`inventory`,`ender_chest`,`health`,`max_health`,`hunger`,`saturation`,`saturation_exhaustion`,`selected_slot`,`status_effects`,`experience`) VALUES((SELECT `id` FROM " + Database.PLAYER_TABLE_NAME + " WHERE `uuid`=?),?,?,?,?,?,?,?,?,?,?,?,?);")) { statement.setString(1, playerData.getPlayerUUID().toString()); statement.setString(2, playerData.getDataVersionUUID().toString()); statement.setTimestamp(3, new Timestamp(Instant.now().getEpochSecond())); @@ -141,6 +143,7 @@ public class DataManager { statement.setFloat(10, playerData.getSaturationExhaustion()); // Saturation exhaustion statement.setInt(11, playerData.getSelectedSlot()); // Current selected slot statement.setString(12, playerData.getSerializedEffectData()); // Status effects + statement.setInt(13, playerData.getExperience()); // Experience statement.executeUpdate(); } diff --git a/bungeecord/src/main/java/me/william278/crossserversync/bungeecord/data/sql/MySQL.java b/bungeecord/src/main/java/me/william278/crossserversync/bungeecord/data/sql/MySQL.java index 49ee66f6..28f79148 100644 --- a/bungeecord/src/main/java/me/william278/crossserversync/bungeecord/data/sql/MySQL.java +++ b/bungeecord/src/main/java/me/william278/crossserversync/bungeecord/data/sql/MySQL.java @@ -32,6 +32,7 @@ public class MySQL extends Database { "`saturation_exhaustion` float NOT NULL," + "`selected_slot` integer NOT NULL," + "`status_effects` longtext NOT NULL," + + "`experience` integer NOT NULL," + "PRIMARY KEY (`player_id`,`uuid`)," + "FOREIGN KEY (`player_id`) REFERENCES " + PLAYER_TABLE_NAME + " (`id`)" + diff --git a/bungeecord/src/main/java/me/william278/crossserversync/bungeecord/data/sql/SQLite.java b/bungeecord/src/main/java/me/william278/crossserversync/bungeecord/data/sql/SQLite.java index 953b6efd..8794999b 100644 --- a/bungeecord/src/main/java/me/william278/crossserversync/bungeecord/data/sql/SQLite.java +++ b/bungeecord/src/main/java/me/william278/crossserversync/bungeecord/data/sql/SQLite.java @@ -40,6 +40,7 @@ public class SQLite extends Database { "`saturation_exhaustion` float NOT NULL," + "`selected_slot` integer NOT NULL," + "`status_effects` longtext NOT NULL," + + "`experience` integer NOT NULL," + "PRIMARY KEY (`player_id`,`version_uuid`)" + ");" diff --git a/bungeecord/src/main/java/me/william278/crossserversync/bungeecord/listener/BungeeRedisListener.java b/bungeecord/src/main/java/me/william278/crossserversync/bungeecord/listener/BungeeRedisListener.java index cd098190..3a2ecae1 100644 --- a/bungeecord/src/main/java/me/william278/crossserversync/bungeecord/listener/BungeeRedisListener.java +++ b/bungeecord/src/main/java/me/william278/crossserversync/bungeecord/listener/BungeeRedisListener.java @@ -22,11 +22,12 @@ public class BungeeRedisListener extends RedisListener { } private PlayerData getPlayerCachedData(UUID uuid) { - for (PlayerData data : DataManager.playerDataCache.playerData) { - if (data.getPlayerUUID() == uuid) { - return data; - } + // Get the player data from the cache + PlayerData cachedData = DataManager.playerDataCache.getPlayer(uuid); + if (cachedData != null) { + return cachedData; } + // If the cache does not contain player data: DataManager.ensurePlayerExists(uuid); // Make sure the player is registered on MySQL diff --git a/common/src/main/java/me/william278/crossserversync/PlayerData.java b/common/src/main/java/me/william278/crossserversync/PlayerData.java index 169accc4..36742712 100644 --- a/common/src/main/java/me/william278/crossserversync/PlayerData.java +++ b/common/src/main/java/me/william278/crossserversync/PlayerData.java @@ -26,6 +26,7 @@ public class PlayerData implements Serializable { private final float saturationExhaustion; private final int selectedSlot; private final String serializedEffectData; + private final int experience; /** * Create a new PlayerData object; a random data version UUID will be selected. @@ -39,7 +40,7 @@ public class PlayerData implements Serializable { * @param selectedSlot Player selected slot * @param serializedStatusEffects Serialized status effect data */ - public PlayerData(UUID playerUUID, String serializedInventory, String serializedEnderChest, double health, double maxHealth, int hunger, float saturation, float saturationExhaustion, int selectedSlot, String serializedStatusEffects) { + public PlayerData(UUID playerUUID, String serializedInventory, String serializedEnderChest, double health, double maxHealth, int hunger, float saturation, float saturationExhaustion, int selectedSlot, String serializedStatusEffects, int experience) { this.dataVersionUUID = UUID.randomUUID(); this.playerUUID = playerUUID; this.serializedInventory = serializedInventory; @@ -51,9 +52,10 @@ public class PlayerData implements Serializable { this.saturationExhaustion = saturationExhaustion; this.selectedSlot = selectedSlot; this.serializedEffectData = serializedStatusEffects; + this.experience = experience; } - public PlayerData(UUID playerUUID, UUID dataVersionUUID, String serializedInventory, String serializedEnderChest, double health, double maxHealth, int hunger, float saturation, float saturationExhaustion, int selectedSlot, String serializedStatusEffects) { + public PlayerData(UUID playerUUID, UUID dataVersionUUID, String serializedInventory, String serializedEnderChest, double health, double maxHealth, int hunger, float saturation, float saturationExhaustion, int selectedSlot, String serializedStatusEffects, int experience) { this.playerUUID = playerUUID; this.dataVersionUUID = dataVersionUUID; this.serializedInventory = serializedInventory; @@ -65,11 +67,12 @@ public class PlayerData implements Serializable { this.saturationExhaustion = saturationExhaustion; this.selectedSlot = selectedSlot; this.serializedEffectData = serializedStatusEffects; + this.experience = experience; } public static PlayerData DEFAULT_PLAYER_DATA(UUID playerUUID) { return new PlayerData(playerUUID, "", "", 20, - 20, 20, 10, 1, 0, ""); + 20, 20, 10, 1, 0, "", 0); } public UUID getPlayerUUID() { @@ -113,4 +116,6 @@ public class PlayerData implements Serializable { public String getSerializedEffectData() { return serializedEffectData; } + + public int getExperience() { return experience; } }