Add ability to update PlayerData back to cache and add more javadoc comments

feat/data-edit-commands
William 3 years ago
parent 014e325751
commit bf6032d6f0

@ -180,6 +180,20 @@ ItemStack[] inventoryItems = DataSerializer.serializeInventory(playerData.getSer
ItemStack[] enderChestItems = DataSerializer.serializeInventory(playerData.getSerializedEnderChest()); ItemStack[] enderChestItems = DataSerializer.serializeInventory(playerData.getSerializedEnderChest());
``` ```
#### Updating PlayerData
You can then update PlayerData back to the central cache using the `HuskSyncAPI#updatePlayerData(playerData)` method. For example:
```
// Update a value in the player data object
playerData.setHealth(20);
try {
// Update the player data to the cache
huskSyncApi.updatePlayerData(playerData);
} catch (IOException e) {
Bukkit.getLogger().severe("An error occurred updating player data!");
}
```
### Contributing ### Contributing
A code bounty program is in place for HuskSync, where developers making significant code contributions to HuskSync may be entitled to a discretionary license to use HuskSync in commercial contexts without having to purchase the resource, so please feel free to submit pull requests with improvements, fixes and features! A code bounty program is in place for HuskSync, where developers making significant code contributions to HuskSync may be entitled to a discretionary license to use HuskSync in commercial contexts without having to purchase the resource, so please feel free to submit pull requests with improvements, fixes and features!
@ -207,4 +221,4 @@ You can turn metric collection off by navigating to `plugins/bStats/config.yml`
## Support ## Support
* Report bugs: [Click here](https://github.com/WiIIiam278/HuskSync/issues) * Report bugs: [Click here](https://github.com/WiIIiam278/HuskSync/issues)
* Discord support: Join the [HuskHelp Discord](https://discord.gg/tVYhJfyDWG)! * Discord support: Join the [HuskHelp Discord](https://discord.gg/tVYhJfyDWG)!
* Proof of purchase is required for support. * Proof of purchase is required for support.

@ -57,4 +57,17 @@ public class HuskSyncAPI {
return playerDataCompletableFuture; return playerDataCompletableFuture;
} }
/**
* Updates a player's {@link PlayerData} to the central cache and database. If the player is online on the Proxy network, they will be updated and overwritten with this data.
*
* @param playerData The {@link PlayerData} (which contains the {@link UUID}) of the player data to update to the central cache and database
* @throws IOException If an exception occurs with serializing during processing of the update
*/
public void updatePlayerData(PlayerData playerData) throws IOException {
final String serializedPlayerData = RedisMessage.serialize(playerData);
new RedisMessage(RedisMessage.MessageType.PLAYER_DATA_UPDATE,
new RedisMessage.MessageTarget(Settings.ServerType.PROXY, null, Settings.cluster),
serializedPlayerData).send();
}
} }

@ -142,7 +142,7 @@ public class PlayerSetter {
} }
// If the data is flagged as being default data, skip setting // If the data is flagged as being default data, skip setting
if (data.isUseDefaultData()) { if (data.useDefaultData) {
HuskSyncBukkit.bukkitCache.removeAwaitingDataFetch(player.getUniqueId()); HuskSyncBukkit.bukkitCache.removeAwaitingDataFetch(player.getUniqueId());
return; return;
} }

@ -3,6 +3,9 @@ package me.william278.husksync;
import java.io.*; import java.io.*;
import java.util.UUID; import java.util.UUID;
/**
* Cross-platform class used to represent a player's data. Data from this can be deserialized using the DataSerializer class on Bukkit platforms.
*/
public class PlayerData implements Serializable { public class PlayerData implements Serializable {
/** /**
@ -15,10 +18,14 @@ public class PlayerData implements Serializable {
*/ */
private final UUID dataVersionUUID; private final UUID dataVersionUUID;
// Flag to indicate if the Bukkit server should use default data /**
* A special flag that will be {@code true} if the player is new to the network and should not have their data set when joining the Bukkit
*/
public boolean useDefaultData = false; public boolean useDefaultData = false;
// Player data /*
* Player data records
*/
private String serializedInventory; private String serializedInventory;
private String serializedEnderChest; private String serializedEnderChest;
private double health; private double health;
@ -55,7 +62,7 @@ public class PlayerData implements Serializable {
* @param totalExperience Their total experience points ("Score") * @param totalExperience Their total experience points ("Score")
* @param expLevel Their exp level * @param expLevel Their exp level
* @param expProgress Their exp progress to the next level * @param expProgress Their exp progress to the next level
* @param gameMode Their game mode ({@code SURVIVAL}, {@code CREATIVE}, etc) * @param gameMode Their game mode ({@code SURVIVAL}, {@code CREATIVE}, etc.)
* @param serializedStatistics Their serialized statistics data (Displayed in Statistics menu in ESC menu) * @param serializedStatistics Their serialized statistics data (Displayed in Statistics menu in ESC menu)
*/ */
public PlayerData(UUID playerUUID, String serializedInventory, String serializedEnderChest, double health, double maxHealth, public PlayerData(UUID playerUUID, String serializedInventory, String serializedEnderChest, double health, double maxHealth,
@ -147,156 +154,344 @@ public class PlayerData implements Serializable {
return data; return data;
} }
/**
* Get the {@link UUID} of the player whose data this is
*
* @return the player's {@link UUID}
*/
public UUID getPlayerUUID() { public UUID getPlayerUUID() {
return playerUUID; return playerUUID;
} }
/**
* Get the unique version {@link UUID} of the PlayerData
*
* @return The unique data version
*/
public UUID getDataVersionUUID() { public UUID getDataVersionUUID() {
return dataVersionUUID; return dataVersionUUID;
} }
/**
* Returns the serialized player {@code ItemStack[]} inventory
*
* @return The player's serialized inventory
*/
public String getSerializedInventory() { public String getSerializedInventory() {
return serializedInventory; return serializedInventory;
} }
/**
* Returns the serialized player {@code ItemStack[]} ender chest
*
* @return The player's serialized ender chest
*/
public String getSerializedEnderChest() { public String getSerializedEnderChest() {
return serializedEnderChest; return serializedEnderChest;
} }
/**
* Returns the player's health value
*
* @return the player's health
*/
public double getHealth() { public double getHealth() {
return health; return health;
} }
/**
* Returns the player's max health value
*
* @return the player's max health
*/
public double getMaxHealth() { public double getMaxHealth() {
return maxHealth; return maxHealth;
} }
public double getHealthScale() { return healthScale; } /**
* Returns the player's health scale value {@see https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/entity/Player.html#getHealthScale()}
*
* @return the player's health scaling value
*/
public double getHealthScale() {
return healthScale;
}
/**
* Returns the player's hunger points
*
* @return the player's hunger level
*/
public int getHunger() { public int getHunger() {
return hunger; return hunger;
} }
/**
* Returns the player's saturation points
*
* @return the player's saturation level
*/
public float getSaturation() { public float getSaturation() {
return saturation; return saturation;
} }
/**
* Returns the player's saturation exhaustion value {@see https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/entity/HumanEntity.html#getExhaustion()}
*
* @return the player's saturation exhaustion
*/
public float getSaturationExhaustion() { public float getSaturationExhaustion() {
return saturationExhaustion; return saturationExhaustion;
} }
/**
* Returns the number of the player's currently selected hotbar slot
*
* @return the player's selected hotbar slot
*/
public int getSelectedSlot() { public int getSelectedSlot() {
return selectedSlot; return selectedSlot;
} }
/**
* Returns a serialized {@link String} of the player's current status effects
*
* @return the player's serialized status effect data
*/
public String getSerializedEffectData() { public String getSerializedEffectData() {
return serializedEffectData; return serializedEffectData;
} }
/**
* Returns the player's total experience score (used for presenting the death screen score value)
*
* @return the player's total experience score
*/
public int getTotalExperience() { public int getTotalExperience() {
return totalExperience; return totalExperience;
} }
/**
* Returns a serialized {@link String} of the player's statistics
*
* @return the player's serialized statistic records
*/
public String getSerializedStatistics() { public String getSerializedStatistics() {
return serializedStatistics; return serializedStatistics;
} }
/**
* Returns the player's current experience level
*
* @return the player's exp level
*/
public int getExpLevel() { public int getExpLevel() {
return expLevel; return expLevel;
} }
/**
* Returns the player's progress to the next experience level
*
* @return the player's exp progress
*/
public float getExpProgress() { public float getExpProgress() {
return expProgress; return expProgress;
} }
/**
* Returns the player's current game mode as a string ({@code SURVIVAL}, {@code CREATIVE}, etc.)
*
* @return the player's game mode
*/
public String getGameMode() { public String getGameMode() {
return gameMode; return gameMode;
} }
/**
* Returns if the player is currently flying
*
* @return {@code true} if the player is in flight; {@code false} otherwise
*/
public boolean isFlying() { public boolean isFlying() {
return isFlying; return isFlying;
} }
/**
* Returns a serialized {@link String} of the player's advancements
*
* @return the player's serialized advancement data
*/
public String getSerializedAdvancements() { public String getSerializedAdvancements() {
return serializedAdvancements; return serializedAdvancements;
} }
/**
* Returns a serialized {@link String} of the player's current location
*
* @return the player's serialized location
*/
public String getSerializedLocation() { public String getSerializedLocation() {
return serializedLocation; return serializedLocation;
} }
public boolean isUseDefaultData() { /**
return useDefaultData; * Update the player's inventory data
} *
* @param serializedInventory A serialized {@code String}; new inventory data
*/
public void setSerializedInventory(String serializedInventory) { public void setSerializedInventory(String serializedInventory) {
this.serializedInventory = serializedInventory; this.serializedInventory = serializedInventory;
} }
/**
* Update the player's ender chest data
*
* @param serializedEnderChest A serialized {@code String}; new ender chest inventory data
*/
public void setSerializedEnderChest(String serializedEnderChest) { public void setSerializedEnderChest(String serializedEnderChest) {
this.serializedEnderChest = serializedEnderChest; this.serializedEnderChest = serializedEnderChest;
} }
/**
* Update the player's health
*
* @param health new health value
*/
public void setHealth(double health) { public void setHealth(double health) {
this.health = health; this.health = health;
} }
/**
* Update the player's max health
*
* @param maxHealth new maximum health value
*/
public void setMaxHealth(double maxHealth) { public void setMaxHealth(double maxHealth) {
this.maxHealth = maxHealth; this.maxHealth = maxHealth;
} }
/**
* Update the player's health scale
*
* @param healthScale new health scaling value
*/
public void setHealthScale(double healthScale) { public void setHealthScale(double healthScale) {
this.healthScale = healthScale; this.healthScale = healthScale;
} }
/**
* Update the player's hunger meter
*
* @param hunger new hunger value
*/
public void setHunger(int hunger) { public void setHunger(int hunger) {
this.hunger = hunger; this.hunger = hunger;
} }
/**
* Update the player's saturation level
*
* @param saturation new saturation value
*/
public void setSaturation(float saturation) { public void setSaturation(float saturation) {
this.saturation = saturation; this.saturation = saturation;
} }
/**
* Update the player's saturation exhaustion value
*
* @param saturationExhaustion new exhaustion value
*/
public void setSaturationExhaustion(float saturationExhaustion) { public void setSaturationExhaustion(float saturationExhaustion) {
this.saturationExhaustion = saturationExhaustion; this.saturationExhaustion = saturationExhaustion;
} }
/**
* Update the player's selected hotbar slot
*
* @param selectedSlot new hotbar slot number (0-9)
*/
public void setSelectedSlot(int selectedSlot) { public void setSelectedSlot(int selectedSlot) {
this.selectedSlot = selectedSlot; this.selectedSlot = selectedSlot;
} }
/**
* Update the player's status effect data
*
* @param serializedEffectData A serialized {@code String} of the player's new status effect data
*/
public void setSerializedEffectData(String serializedEffectData) { public void setSerializedEffectData(String serializedEffectData) {
this.serializedEffectData = serializedEffectData; this.serializedEffectData = serializedEffectData;
} }
/**
* Set the player's total experience points (used to display score on death screen)
*
* @param totalExperience the player's new total experience score
*/
public void setTotalExperience(int totalExperience) { public void setTotalExperience(int totalExperience) {
this.totalExperience = totalExperience; this.totalExperience = totalExperience;
} }
/**
* Set the player's exp level
*
* @param expLevel the player's new exp level
*/
public void setExpLevel(int expLevel) { public void setExpLevel(int expLevel) {
this.expLevel = expLevel; this.expLevel = expLevel;
} }
/**
* Set the player's progress to their next exp level
*
* @param expProgress the player's new experience progress
*/
public void setExpProgress(float expProgress) { public void setExpProgress(float expProgress) {
this.expProgress = expProgress; this.expProgress = expProgress;
} }
/**
* Set the player's game mode
*
* @param gameMode the player's new game mode ({@code SURVIVAL}, {@code CREATIVE}, etc.)
*/
public void setGameMode(String gameMode) { public void setGameMode(String gameMode) {
this.gameMode = gameMode; this.gameMode = gameMode;
} }
/**
* Update the player's statistics data
*
* @param serializedStatistics A serialized {@code String}; new statistic data
*/
public void setSerializedStatistics(String serializedStatistics) { public void setSerializedStatistics(String serializedStatistics) {
this.serializedStatistics = serializedStatistics; this.serializedStatistics = serializedStatistics;
} }
/**
* Set if the player is flying
*
* @param flying whether the player is flying
*/
public void setFlying(boolean flying) { public void setFlying(boolean flying) {
isFlying = flying; isFlying = flying;
} }
/**
* Update the player's advancement data
*
* @param serializedAdvancements A serialized {@code String}; new advancement data
*/
public void setSerializedAdvancements(String serializedAdvancements) { public void setSerializedAdvancements(String serializedAdvancements) {
this.serializedAdvancements = serializedAdvancements; this.serializedAdvancements = serializedAdvancements;
} }
/**
* Update the player's location data
*
* @param serializedLocation A serialized {@code String}; new location data
*/
public void setSerializedLocation(String serializedLocation) { public void setSerializedLocation(String serializedLocation) {
this.serializedLocation = serializedLocation; this.serializedLocation = serializedLocation;
} }

@ -90,7 +90,7 @@ public class RedisMessage {
*/ */
public enum MessageType implements Serializable { public enum MessageType implements Serializable {
/** /**
* Sent by Bukkit servers to proxy when a player disconnects with a player's updated data, alongside the UUID of the last loaded {@link PlayerData} for the user * Sent by Bukkit servers to proxy when a user disconnects with that player's updated {@link PlayerData}.
*/ */
PLAYER_DATA_UPDATE, PLAYER_DATA_UPDATE,
@ -105,12 +105,12 @@ public class RedisMessage {
PLAYER_DATA_SET, PLAYER_DATA_SET,
/** /**
* Sent by Bukkit servers to proxy to request {@link PlayerData} from the proxy via the API * Sent by Bukkit servers to proxy to request {@link PlayerData} from the proxy via the API.
*/ */
API_DATA_REQUEST, API_DATA_REQUEST,
/** /**
* Sent by the Proxy to fulfill an {@code MessageType.API_DATA_REQUEST}, containing the latest {@link PlayerData} for the requested UUID * Sent by the Proxy to fulfill an {@code MessageType.API_DATA_REQUEST}, containing the latest {@link PlayerData} for the requested UUID.
*/ */
API_DATA_RETURN, API_DATA_RETURN,
@ -120,47 +120,47 @@ public class RedisMessage {
API_DATA_CANCEL, API_DATA_CANCEL,
/** /**
* Sent by the proxy to a Bukkit server to have them request data on join; contains no data otherwise * Sent by the proxy to a Bukkit server to have them request data on join; contains no data otherwise.
*/ */
REQUEST_DATA_ON_JOIN, REQUEST_DATA_ON_JOIN,
/** /**
* Sent by the proxy to ask the Bukkit server to send the full plugin information, contains information about the proxy brand and version * Sent by the proxy to ask the Bukkit server to send the full plugin information, contains information about the proxy brand and version.
*/ */
SEND_PLUGIN_INFORMATION, SEND_PLUGIN_INFORMATION,
/** /**
* Sent by the proxy to show a player the contents of another player's inventory, contains their username and {@link PlayerData} * Sent by the proxy to show a player the contents of another player's inventory, contains their username and {@link PlayerData}.
*/ */
OPEN_INVENTORY, OPEN_INVENTORY,
/** /**
* Sent by the proxy to show a player the contents of another player's ender chest, contains their username and {@link PlayerData} * Sent by the proxy to show a player the contents of another player's ender chest, contains their username and {@link PlayerData}.
*/ */
OPEN_ENDER_CHEST, OPEN_ENDER_CHEST,
/** /**
* Sent by both the proxy and bukkit servers to confirm cross-server communication has been established * Sent by both the proxy and bukkit servers to confirm cross-server communication has been established.
*/ */
CONNECTION_HANDSHAKE, CONNECTION_HANDSHAKE,
/** /**
* Sent by both the proxy and bukkit servers to terminate communications (if a bukkit / the proxy goes offline) * Sent by both the proxy and bukkit servers to terminate communications (if a bukkit / the proxy goes offline).
*/ */
TERMINATE_HANDSHAKE, TERMINATE_HANDSHAKE,
/** /**
* Sent by a proxy to a bukkit server to decode MPDB data * Sent by a proxy to a bukkit server to decode MPDB data.
*/ */
DECODE_MPDB_DATA, DECODE_MPDB_DATA,
/** /**
* Sent by a bukkit server back to the proxy with the correctly decoded MPDB data * Sent by a bukkit server back to the proxy with the correctly decoded MPDB data.
*/ */
DECODED_MPDB_DATA_SET, DECODED_MPDB_DATA_SET,
/** /**
* Sent by the proxy to a bukkit server to initiate a reload * Sent by the proxy to a bukkit server to initiate a reload.
*/ */
RELOAD_CONFIG RELOAD_CONFIG
} }
@ -171,8 +171,7 @@ public class RedisMessage {
} }
/** /**
* A record that defines the target of a plugin message; a spigot server or the proxy server(s). * A record that defines the target of a plugin message; a spigot server or the proxy server(s). For Bukkit servers, the name of the server must also be specified
* For Bukkit servers, the name of the server must also be specified
*/ */
public record MessageTarget(Settings.ServerType targetServerType, UUID targetPlayerUUID, String targetClusterId) implements Serializable { } public record MessageTarget(Settings.ServerType targetServerType, UUID targetPlayerUUID, String targetClusterId) implements Serializable { }

Loading…
Cancel
Save