mirror of
https://github.com/WiIIiam278/HuskSync.git
synced 2025-12-19 14:59:21 +00:00
Add information command
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
# CrossServerSync
|
# CrossServerSync
|
||||||
**CrossServerSync** is a robust solution for synchronising player data (inventories, health, hunger & status effects) between servers. It was designed as a lightweight alternative to MySQLPlayerDataBridge,
|
**CrossServerSync** is a robust solution for synchronising player data (inventories, health, hunger & status effects) between servers. It was designed as a much faster alternative to MySQLPlayerDataBridge,
|
||||||
|
|
||||||
### Installation
|
### Installation
|
||||||
Install CrossServerSync in the `/plugins/` folder of your Spigot (and derivatives) servers and Proxy (BungeeCord and derivatives) server.
|
Install CrossServerSync in the `/plugins/` folder of your Spigot (and derivatives) servers and Proxy (BungeeCord and derivatives) server.
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ dependencies {
|
|||||||
|
|
||||||
implementation 'org.bstats:bstats-bukkit:2.2.1'
|
implementation 'org.bstats:bstats-bukkit:2.2.1'
|
||||||
implementation 'redis.clients:jedis:3.7.0'
|
implementation 'redis.clients:jedis:3.7.0'
|
||||||
|
implementation 'de.themoep:minedown:1.7.1-SNAPSHOT'
|
||||||
|
|
||||||
compileOnly 'org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT'
|
compileOnly 'org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT'
|
||||||
}
|
}
|
||||||
@@ -11,6 +12,7 @@ dependencies {
|
|||||||
shadowJar {
|
shadowJar {
|
||||||
relocate 'redis.clients', 'me.William278.crossserversync.libraries.jedis'
|
relocate 'redis.clients', 'me.William278.crossserversync.libraries.jedis'
|
||||||
relocate 'org.bstats', 'me.William278.crossserversync.libraries.plan'
|
relocate 'org.bstats', 'me.William278.crossserversync.libraries.plan'
|
||||||
|
relocate 'de.themoep', 'me.William278.crossserversync.libraries.minedown'
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.register('prepareKotlinBuildScriptModel'){}
|
tasks.register('prepareKotlinBuildScriptModel'){}
|
||||||
@@ -27,7 +27,9 @@ public class PlayerSetter {
|
|||||||
player.setMaxHealth(data.getMaxHealth());
|
player.setMaxHealth(data.getMaxHealth());
|
||||||
player.setFoodLevel(data.getHunger());
|
player.setFoodLevel(data.getHunger());
|
||||||
player.setSaturation(data.getSaturation());
|
player.setSaturation(data.getSaturation());
|
||||||
|
player.setExhaustion(data.getSaturationExhaustion());
|
||||||
player.getInventory().setHeldItemSlot(data.getSelectedSlot());
|
player.getInventory().setHeldItemSlot(data.getSelectedSlot());
|
||||||
|
|
||||||
//todo potion effects not working
|
//todo potion effects not working
|
||||||
setPlayerPotionEffects(player, DataSerializer.potionEffectArrayFromBase64(data.getSerializedEffectData()));
|
setPlayerPotionEffects(player, DataSerializer.potionEffectArrayFromBase64(data.getSerializedEffectData()));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package me.william278.crossserversync.bukkit.listener;
|
package me.william278.crossserversync.bukkit.listener;
|
||||||
|
|
||||||
|
import de.themoep.minedown.MineDown;
|
||||||
|
import me.william278.crossserversync.MessageStrings;
|
||||||
import me.william278.crossserversync.PlayerData;
|
import me.william278.crossserversync.PlayerData;
|
||||||
import me.william278.crossserversync.Settings;
|
import me.william278.crossserversync.Settings;
|
||||||
import me.william278.crossserversync.CrossServerSyncBukkit;
|
import me.william278.crossserversync.CrossServerSyncBukkit;
|
||||||
@@ -35,19 +37,33 @@ public class BukkitRedisListener extends RedisListener {
|
|||||||
// Handle the message for the player
|
// Handle the message for the player
|
||||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||||
if (player.getUniqueId().equals(message.getMessageTarget().targetPlayerUUID())) {
|
if (player.getUniqueId().equals(message.getMessageTarget().targetPlayerUUID())) {
|
||||||
if (message.getMessageType().equals(RedisMessage.MessageType.PLAYER_DATA_REPLY)) {
|
switch (message.getMessageType()) {
|
||||||
try {
|
case PLAYER_DATA_SET -> {
|
||||||
// Deserialize the received PlayerData
|
try {
|
||||||
PlayerData data = (PlayerData) RedisMessage.deserialize(message.getMessageData());
|
// Deserialize the received PlayerData
|
||||||
|
PlayerData data = (PlayerData) RedisMessage.deserialize(message.getMessageData());
|
||||||
|
|
||||||
// Set the player's data
|
// Set the player's data
|
||||||
PlayerSetter.setPlayerFrom(player, data);
|
PlayerSetter.setPlayerFrom(player, data);
|
||||||
|
|
||||||
// Update last loaded data UUID
|
// Update last loaded data UUID
|
||||||
CrossServerSyncBukkit.lastDataUpdateUUIDCache.setVersionUUID(player.getUniqueId(), data.getDataVersionUUID());
|
CrossServerSyncBukkit.lastDataUpdateUUIDCache.setVersionUUID(player.getUniqueId(), data.getDataVersionUUID());
|
||||||
} catch (IOException | ClassNotFoundException e) {
|
} catch (IOException | ClassNotFoundException e) {
|
||||||
log(Level.SEVERE, "Failed to deserialize PlayerData when handling a reply from the proxy with PlayerData");
|
log(Level.SEVERE, "Failed to deserialize PlayerData when handling a reply from the proxy with PlayerData");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case SEND_PLUGIN_INFORMATION -> {
|
||||||
|
String proxyBrand = message.getMessageDataElements()[0];
|
||||||
|
String proxyVersion = message.getMessageDataElements()[1];
|
||||||
|
assert plugin.getDescription().getDescription() != null;
|
||||||
|
player.spigot().sendMessage(new MineDown(MessageStrings.PLUGIN_INFORMATION.toString()
|
||||||
|
.replaceAll("%plugin_description%", plugin.getDescription().getDescription())
|
||||||
|
.replaceAll("%proxy_brand%", proxyBrand)
|
||||||
|
.replaceAll("%proxy_version%", proxyVersion)
|
||||||
|
.replaceAll("%bukkit_brand%", Bukkit.getName())
|
||||||
|
.replaceAll("%bukkit_version%", plugin.getDescription().getVersion()))
|
||||||
|
.toComponent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ public class EventListener implements Listener {
|
|||||||
player.getMaxHealth(),
|
player.getMaxHealth(),
|
||||||
player.getFoodLevel(),
|
player.getFoodLevel(),
|
||||||
player.getSaturation(),
|
player.getSaturation(),
|
||||||
|
player.getExhaustion(),
|
||||||
player.getInventory().getHeldItemSlot(),
|
player.getInventory().getHeldItemSlot(),
|
||||||
DataSerializer.getSerializedEffectData(player)));
|
DataSerializer.getSerializedEffectData(player)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ dependencies {
|
|||||||
|
|
||||||
implementation 'redis.clients:jedis:3.7.0'
|
implementation 'redis.clients:jedis:3.7.0'
|
||||||
implementation 'com.zaxxer:HikariCP:5.0.0'
|
implementation 'com.zaxxer:HikariCP:5.0.0'
|
||||||
|
implementation 'de.themoep:minedown:1.7.1-SNAPSHOT'
|
||||||
|
|
||||||
compileOnly 'net.md-5:bungeecord-api:1.16-R0.5-SNAPSHOT'
|
compileOnly 'net.md-5:bungeecord-api:1.16-R0.5-SNAPSHOT'
|
||||||
}
|
}
|
||||||
@@ -12,6 +13,7 @@ shadowJar {
|
|||||||
relocate 'redis.clients', 'me.William278.crossserversync.libraries.jedis'
|
relocate 'redis.clients', 'me.William278.crossserversync.libraries.jedis'
|
||||||
relocate 'com.zaxxer', 'me.William278.crossserversync.libraries.hikari'
|
relocate 'com.zaxxer', 'me.William278.crossserversync.libraries.hikari'
|
||||||
relocate 'org.bstats', 'me.William278.crossserversync.libraries.plan'
|
relocate 'org.bstats', 'me.William278.crossserversync.libraries.plan'
|
||||||
|
relocate 'de.themoep', 'me.William278.crossserversync.libraries.minedown'
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.register('prepareKotlinBuildScriptModel'){}
|
tasks.register('prepareKotlinBuildScriptModel'){}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package me.william278.crossserversync;
|
package me.william278.crossserversync;
|
||||||
|
|
||||||
|
import me.william278.crossserversync.bungeecord.command.CrossServerSyncCommand;
|
||||||
import me.william278.crossserversync.bungeecord.config.ConfigLoader;
|
import me.william278.crossserversync.bungeecord.config.ConfigLoader;
|
||||||
import me.william278.crossserversync.bungeecord.config.ConfigManager;
|
import me.william278.crossserversync.bungeecord.config.ConfigManager;
|
||||||
import me.william278.crossserversync.bungeecord.data.DataManager;
|
import me.william278.crossserversync.bungeecord.data.DataManager;
|
||||||
@@ -51,9 +52,12 @@ public final class CrossServerSyncBungeeCord extends Plugin {
|
|||||||
// Setup player data cache
|
// Setup player data cache
|
||||||
DataManager.playerDataCache = new DataManager.PlayerDataCache();
|
DataManager.playerDataCache = new DataManager.PlayerDataCache();
|
||||||
|
|
||||||
// Initialize PreLoginEvent listener
|
// Register listener
|
||||||
getProxy().getPluginManager().registerListener(this, new BungeeEventListener());
|
getProxy().getPluginManager().registerListener(this, new BungeeEventListener());
|
||||||
|
|
||||||
|
// Register command
|
||||||
|
getProxy().getPluginManager().registerCommand(this, new CrossServerSyncCommand());
|
||||||
|
|
||||||
// Initialize the redis listener
|
// Initialize the redis listener
|
||||||
new BungeeRedisListener();
|
new BungeeRedisListener();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
package me.william278.crossserversync.bungeecord.command;
|
||||||
|
|
||||||
|
import de.themoep.minedown.MineDown;
|
||||||
|
import me.william278.crossserversync.CrossServerSyncBungeeCord;
|
||||||
|
import me.william278.crossserversync.MessageStrings;
|
||||||
|
import me.william278.crossserversync.Settings;
|
||||||
|
import me.william278.crossserversync.redis.RedisMessage;
|
||||||
|
import net.md_5.bungee.api.CommandSender;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
import net.md_5.bungee.api.plugin.Command;
|
||||||
|
import net.md_5.bungee.api.plugin.TabExecutor;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class CrossServerSyncCommand extends Command implements TabExecutor {
|
||||||
|
|
||||||
|
private final static CrossServerSyncBungeeCord plugin = CrossServerSyncBungeeCord.getInstance();
|
||||||
|
private final static String[] COMMAND_TAB_ARGUMENTS = {"about", "reload"};
|
||||||
|
private final static String PERMISSION = "crossserversync.command.csc";
|
||||||
|
|
||||||
|
public CrossServerSyncCommand() { super("csc", PERMISSION, "crossserversync"); }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender sender, String[] args) {
|
||||||
|
if (sender instanceof ProxiedPlayer player) {
|
||||||
|
if (args.length == 1) {
|
||||||
|
switch (args[0].toLowerCase(Locale.ROOT)) {
|
||||||
|
case "about", "info" -> sendAboutInformation(player);
|
||||||
|
|
||||||
|
default -> sender.sendMessage(new MineDown(MessageStrings.ERROR_INVALID_SYNTAX.replaceAll("%1%", "/csc <about>")).toComponent());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sendAboutInformation(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send information about the plugin
|
||||||
|
* @param player The player to send it to
|
||||||
|
*/
|
||||||
|
private void sendAboutInformation(ProxiedPlayer player) {
|
||||||
|
try {
|
||||||
|
new RedisMessage(RedisMessage.MessageType.SEND_PLUGIN_INFORMATION,
|
||||||
|
new RedisMessage.MessageTarget(Settings.ServerType.BUKKIT, player.getUniqueId()),
|
||||||
|
plugin.getProxy().getName(), plugin.getDescription().getVersion()).send();
|
||||||
|
} catch (IOException e) {
|
||||||
|
plugin.getLogger().log(Level.WARNING, "Failed to serialize plugin information to send", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<String> onTabComplete(CommandSender sender, String[] args) {
|
||||||
|
if (sender instanceof ProxiedPlayer player) {
|
||||||
|
if (!player.hasPermission(PERMISSION)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
if (args.length == 1) {
|
||||||
|
return Arrays.stream(COMMAND_TAB_ARGUMENTS).filter(val -> val.startsWith(args[0]))
|
||||||
|
.sorted().collect(Collectors.toList());
|
||||||
|
} else {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -73,12 +73,13 @@ public class DataManager {
|
|||||||
final double maxHealth = resultSet.getDouble("max_health");
|
final double maxHealth = resultSet.getDouble("max_health");
|
||||||
final int hunger = resultSet.getInt("hunger");
|
final int hunger = resultSet.getInt("hunger");
|
||||||
final float saturation = resultSet.getFloat("saturation");
|
final float saturation = resultSet.getFloat("saturation");
|
||||||
|
final float saturationExhaustion = resultSet.getFloat("saturation_exhaustion");
|
||||||
final int selectedSlot = resultSet.getInt("selected_slot");
|
final int selectedSlot = resultSet.getInt("selected_slot");
|
||||||
final String serializedStatusEffects = resultSet.getString("status_effects");
|
final String serializedStatusEffects = resultSet.getString("status_effects");
|
||||||
|
|
||||||
return new PlayerData(playerUUID, dataVersionUUID, serializedInventory, serializedEnderChest, health, maxHealth, hunger, saturation, selectedSlot, serializedStatusEffects);
|
return new PlayerData(playerUUID, dataVersionUUID, serializedInventory, serializedEnderChest, health, maxHealth, hunger, saturation, saturationExhaustion, selectedSlot, serializedStatusEffects);
|
||||||
} else {
|
} else {
|
||||||
return PlayerData.EMPTY_PLAYER_DATA(playerUUID);
|
return PlayerData.DEFAULT_PLAYER_DATA(playerUUID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
@@ -104,7 +105,7 @@ public class DataManager {
|
|||||||
private static void updatePlayerSQLData(PlayerData playerData) {
|
private static void updatePlayerSQLData(PlayerData playerData) {
|
||||||
try (Connection connection = CrossServerSyncBungeeCord.getConnection()) {
|
try (Connection connection = CrossServerSyncBungeeCord.getConnection()) {
|
||||||
try (PreparedStatement statement = connection.prepareStatement(
|
try (PreparedStatement statement = connection.prepareStatement(
|
||||||
"UPDATE " + Database.DATA_TABLE_NAME + " SET `version_uuid`=?, `timestamp`=?, `inventory`=?, `ender_chest`=?, `health`=?, `max_health`=?, `hunger`=?, `saturation`=?, `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`=? WHERE `player_id`=(SELECT `id` FROM " + Database.PLAYER_TABLE_NAME + " WHERE `uuid`=?);")) {
|
||||||
statement.setString(1, playerData.getDataVersionUUID().toString());
|
statement.setString(1, playerData.getDataVersionUUID().toString());
|
||||||
statement.setTimestamp(2, new Timestamp(Instant.now().getEpochSecond()));
|
statement.setTimestamp(2, new Timestamp(Instant.now().getEpochSecond()));
|
||||||
statement.setString(3, playerData.getSerializedInventory());
|
statement.setString(3, playerData.getSerializedInventory());
|
||||||
@@ -113,9 +114,10 @@ public class DataManager {
|
|||||||
statement.setDouble(6, playerData.getMaxHealth()); // Max health
|
statement.setDouble(6, playerData.getMaxHealth()); // Max health
|
||||||
statement.setInt(7, playerData.getHunger()); // Hunger
|
statement.setInt(7, playerData.getHunger()); // Hunger
|
||||||
statement.setFloat(8, playerData.getSaturation()); // Saturation
|
statement.setFloat(8, playerData.getSaturation()); // Saturation
|
||||||
statement.setInt(9, playerData.getSelectedSlot());
|
statement.setFloat(9, playerData.getSaturationExhaustion()); // Saturation exhaustion
|
||||||
statement.setString(10, playerData.getSerializedEffectData()); // Status effects
|
statement.setInt(10, playerData.getSelectedSlot()); // Current selected slot
|
||||||
statement.setString(11, playerData.getPlayerUUID().toString());
|
statement.setString(11, playerData.getSerializedEffectData()); // Status effects
|
||||||
|
statement.setString(12, playerData.getPlayerUUID().toString());
|
||||||
statement.executeUpdate();
|
statement.executeUpdate();
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
@@ -126,7 +128,7 @@ public class DataManager {
|
|||||||
private static void insertPlayerData(PlayerData playerData) {
|
private static void insertPlayerData(PlayerData playerData) {
|
||||||
try (Connection connection = CrossServerSyncBungeeCord.getConnection()) {
|
try (Connection connection = CrossServerSyncBungeeCord.getConnection()) {
|
||||||
try (PreparedStatement statement = connection.prepareStatement(
|
try (PreparedStatement statement = connection.prepareStatement(
|
||||||
"INSERT INTO " + Database.DATA_TABLE_NAME + " (`player_id`,`version_uuid`,`timestamp`,`inventory`,`ender_chest`,`health`,`max_health`,`hunger`,`saturation`,`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`) VALUES((SELECT `id` FROM " + Database.PLAYER_TABLE_NAME + " WHERE `uuid`=?),?,?,?,?,?,?,?,?,?,?,?);")) {
|
||||||
statement.setString(1, playerData.getPlayerUUID().toString());
|
statement.setString(1, playerData.getPlayerUUID().toString());
|
||||||
statement.setString(2, playerData.getDataVersionUUID().toString());
|
statement.setString(2, playerData.getDataVersionUUID().toString());
|
||||||
statement.setTimestamp(3, new Timestamp(Instant.now().getEpochSecond()));
|
statement.setTimestamp(3, new Timestamp(Instant.now().getEpochSecond()));
|
||||||
@@ -136,8 +138,9 @@ public class DataManager {
|
|||||||
statement.setDouble(7, playerData.getMaxHealth()); // Max health
|
statement.setDouble(7, playerData.getMaxHealth()); // Max health
|
||||||
statement.setInt(8, playerData.getHunger()); // Hunger
|
statement.setInt(8, playerData.getHunger()); // Hunger
|
||||||
statement.setFloat(9, playerData.getSaturation()); // Saturation
|
statement.setFloat(9, playerData.getSaturation()); // Saturation
|
||||||
statement.setInt(10, playerData.getSelectedSlot());
|
statement.setFloat(10, playerData.getSaturationExhaustion()); // Saturation exhaustion
|
||||||
statement.setString(11, playerData.getSerializedEffectData()); // Status effects
|
statement.setInt(11, playerData.getSelectedSlot()); // Current selected slot
|
||||||
|
statement.setString(12, playerData.getSerializedEffectData()); // Status effects
|
||||||
|
|
||||||
statement.executeUpdate();
|
statement.executeUpdate();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ public class MySQL extends Database {
|
|||||||
"`max_health` double NOT NULL," +
|
"`max_health` double NOT NULL," +
|
||||||
"`hunger` integer NOT NULL," +
|
"`hunger` integer NOT NULL," +
|
||||||
"`saturation` float NOT NULL," +
|
"`saturation` float NOT NULL," +
|
||||||
|
"`saturation_exhaustion` float NOT NULL," +
|
||||||
"`selected_slot` integer NOT NULL," +
|
"`selected_slot` integer NOT NULL," +
|
||||||
"`status_effects` longtext NOT NULL," +
|
"`status_effects` longtext NOT NULL," +
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ public class SQLite extends Database {
|
|||||||
"`max_health` double NOT NULL," +
|
"`max_health` double NOT NULL," +
|
||||||
"`hunger` integer NOT NULL," +
|
"`hunger` integer NOT NULL," +
|
||||||
"`saturation` float NOT NULL," +
|
"`saturation` float NOT NULL," +
|
||||||
|
"`saturation_exhaustion` float NOT NULL," +
|
||||||
"`selected_slot` integer NOT NULL," +
|
"`selected_slot` integer NOT NULL," +
|
||||||
"`status_effects` longtext NOT NULL," +
|
"`status_effects` longtext NOT NULL," +
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class BungeeRedisListener extends RedisListener {
|
|||||||
ProxyServer.getInstance().getScheduler().runAsync(plugin, () -> {
|
ProxyServer.getInstance().getScheduler().runAsync(plugin, () -> {
|
||||||
try {
|
try {
|
||||||
// Send the reply, serializing the message data
|
// Send the reply, serializing the message data
|
||||||
new RedisMessage(RedisMessage.MessageType.PLAYER_DATA_REPLY,
|
new RedisMessage(RedisMessage.MessageType.PLAYER_DATA_SET,
|
||||||
new RedisMessage.MessageTarget(Settings.ServerType.BUKKIT, requestingPlayerUUID),
|
new RedisMessage.MessageTarget(Settings.ServerType.BUKKIT, requestingPlayerUUID),
|
||||||
RedisMessage.serialize(getPlayerCachedData(requestingPlayerUUID))).send();
|
RedisMessage.serialize(getPlayerCachedData(requestingPlayerUUID))).send();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package me.william278.crossserversync;
|
||||||
|
|
||||||
|
public class MessageStrings {
|
||||||
|
|
||||||
|
public static final StringBuilder PLUGIN_INFORMATION = new StringBuilder().append("[CrossServerSync](#00fb9a bold) [| %proxy_brand% Version %proxy_version% | %bukkit_brand% Version %bukkit_version%](#00fb9a)\n")
|
||||||
|
.append("[%plugin_description%](gray)\n")
|
||||||
|
.append("[• Author:](white) [William278](gray show_text=&7Click to pay a visit open_url=https://youtube.com/William27528)\n")
|
||||||
|
.append("[• Help Wiki:](white) [[Link]](#00fb9a show_text=&7Click to open link open_url=https://github.com/WiIIiam278/CrossServerSync/wiki/)\n")
|
||||||
|
.append("[• Report Issues:](white) [[Link]](#00fb9a show_text=&7Click to open link open_url=https://github.com/WiIIiam278/CrossServerSync/issues)\n")
|
||||||
|
.append("[• Support Discord:](white) [[Link]](#00fb9a show_text=&7Click to join open_url=https://discord.gg/tVYhJfyDWG)");
|
||||||
|
|
||||||
|
public static final String ERROR_INVALID_SYNTAX = "[Error:](#ff3300) [Incorrect syntax. Usage: %1%](#ff7e5e)";
|
||||||
|
|
||||||
|
}
|
||||||
@@ -23,10 +23,10 @@ public class PlayerData implements Serializable {
|
|||||||
private final double maxHealth;
|
private final double maxHealth;
|
||||||
private final int hunger;
|
private final int hunger;
|
||||||
private final float saturation;
|
private final float saturation;
|
||||||
|
private final float saturationExhaustion;
|
||||||
private final int selectedSlot;
|
private final int selectedSlot;
|
||||||
private final String serializedEffectData;
|
private final String serializedEffectData;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new PlayerData object; a random data version UUID will be selected.
|
* Create a new PlayerData object; a random data version UUID will be selected.
|
||||||
* @param playerUUID UUID of the player
|
* @param playerUUID UUID of the player
|
||||||
@@ -39,7 +39,7 @@ public class PlayerData implements Serializable {
|
|||||||
* @param selectedSlot Player selected slot
|
* @param selectedSlot Player selected slot
|
||||||
* @param serializedStatusEffects Serialized status effect data
|
* @param serializedStatusEffects Serialized status effect data
|
||||||
*/
|
*/
|
||||||
public PlayerData(UUID playerUUID, String serializedInventory, String serializedEnderChest, double health, double maxHealth, int hunger, float saturation, 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) {
|
||||||
this.dataVersionUUID = UUID.randomUUID();
|
this.dataVersionUUID = UUID.randomUUID();
|
||||||
this.playerUUID = playerUUID;
|
this.playerUUID = playerUUID;
|
||||||
this.serializedInventory = serializedInventory;
|
this.serializedInventory = serializedInventory;
|
||||||
@@ -48,11 +48,12 @@ public class PlayerData implements Serializable {
|
|||||||
this.maxHealth = maxHealth;
|
this.maxHealth = maxHealth;
|
||||||
this.hunger = hunger;
|
this.hunger = hunger;
|
||||||
this.saturation = saturation;
|
this.saturation = saturation;
|
||||||
|
this.saturationExhaustion = saturationExhaustion;
|
||||||
this.selectedSlot = selectedSlot;
|
this.selectedSlot = selectedSlot;
|
||||||
this.serializedEffectData = serializedStatusEffects;
|
this.serializedEffectData = serializedStatusEffects;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlayerData(UUID playerUUID, UUID dataVersionUUID, String serializedInventory, String serializedEnderChest, double health, double maxHealth, int hunger, float saturation, 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) {
|
||||||
this.playerUUID = playerUUID;
|
this.playerUUID = playerUUID;
|
||||||
this.dataVersionUUID = dataVersionUUID;
|
this.dataVersionUUID = dataVersionUUID;
|
||||||
this.serializedInventory = serializedInventory;
|
this.serializedInventory = serializedInventory;
|
||||||
@@ -61,13 +62,14 @@ public class PlayerData implements Serializable {
|
|||||||
this.maxHealth = maxHealth;
|
this.maxHealth = maxHealth;
|
||||||
this.hunger = hunger;
|
this.hunger = hunger;
|
||||||
this.saturation = saturation;
|
this.saturation = saturation;
|
||||||
|
this.saturationExhaustion = saturationExhaustion;
|
||||||
this.selectedSlot = selectedSlot;
|
this.selectedSlot = selectedSlot;
|
||||||
this.serializedEffectData = serializedStatusEffects;
|
this.serializedEffectData = serializedStatusEffects;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PlayerData EMPTY_PLAYER_DATA(UUID playerUUID) {
|
public static PlayerData DEFAULT_PLAYER_DATA(UUID playerUUID) {
|
||||||
return new PlayerData(playerUUID, "", "", 20,
|
return new PlayerData(playerUUID, "", "", 20,
|
||||||
20, 20, 20, 0, "");
|
20, 20, 10, 1, 0, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
public UUID getPlayerUUID() {
|
public UUID getPlayerUUID() {
|
||||||
@@ -102,6 +104,8 @@ public class PlayerData implements Serializable {
|
|||||||
return saturation;
|
return saturation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float getSaturationExhaustion() { return saturationExhaustion; }
|
||||||
|
|
||||||
public int getSelectedSlot() {
|
public int getSelectedSlot() {
|
||||||
return selectedSlot;
|
return selectedSlot;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,8 @@ public class RedisMessage {
|
|||||||
return messageData;
|
return messageData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String[] getMessageDataElements() { return messageData.split(MESSAGE_DATA_SEPARATOR); }
|
||||||
|
|
||||||
public MessageType getMessageType() {
|
public MessageType getMessageType() {
|
||||||
return messageType;
|
return messageType;
|
||||||
}
|
}
|
||||||
@@ -100,7 +102,12 @@ public class RedisMessage {
|
|||||||
/**
|
/**
|
||||||
* Sent by the Proxy to reply to a {@code MessageType.PLAYER_DATA_REQUEST}, contains the latest {@link PlayerData} for the requester.
|
* Sent by the Proxy to reply to a {@code MessageType.PLAYER_DATA_REQUEST}, contains the latest {@link PlayerData} for the requester.
|
||||||
*/
|
*/
|
||||||
PLAYER_DATA_REPLY
|
PLAYER_DATA_SET,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 174 KiB After Width: | Height: | Size: 182 KiB |
Reference in New Issue
Block a user