Refactor name to be HuskSync

feat/data-edit-commands
William 3 years ago
parent 520f1ea1d7
commit f842afac1e

@ -1,20 +1,20 @@
# CrossServerSync # HuskSync
**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, **HuskSync** 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 HuskSync in the `/plugins/` folder of your Spigot (and derivatives) servers and Proxy (BungeeCord and derivatives) server.
Start your servers, then stop them again to allow the configuration files to generate. Start your servers, then stop them again to allow the configuration files to generate.
Navigate to the generated config.yml files on your Spigot server and Proxy (located in `/plugins/CrossServerSync/`) and fill in the credentials of your redis server. On the Proxy server, you can additionally configure a MySQL database to save player data in, as by default the plugin will create a SQLite database for this. Navigate to the generated config.yml files on your Spigot server and Proxy (located in `/plugins/HuskSync/`) and fill in the credentials of your redis server. On the Proxy server, you can additionally configure a MySQL database to save player data in, as by default the plugin will create a SQLite database for this.
If you have multiple proxy servers (i.e. via RedisBungee), you need to install the plugin on all of them and make use of the MySQL option and ensure the proxies are using the same database. If you have multiple proxy servers (i.e. via RedisBungee), you need to install the plugin on all of them and make use of the MySQL option and ensure the proxies are using the same database.
### How it works ## How it works
![Flow chart showing different processes of how the plugin works](images/flow-chart.png) ![Flow chart showing different processes of how the plugin works](images/flow-chart.png)
CrossServerSync synchronises player data between servers using Redis to transfer cached data, loaded from a central database as necessary. HuskSync synchronises player data between servers using Redis to transfer cached data, loaded from a central database as necessary.
### Building ## Building
To build CrossServerSync, run the following in the root of the repository: To build HuskSync, run the following in the root of the repository:
``` ```
./gradlew clean build ./gradlew clean build
``` ```

@ -18,7 +18,7 @@ allprojects {
javadoc { options.encoding = 'UTF-8' } javadoc { options.encoding = 'UTF-8' }
} }
logger.lifecycle('Building CrossServerSync v' + version.toString()) logger.lifecycle('Building HuskSync v' + version.toString())
subprojects { subprojects {
apply plugin: 'com.github.johnrengelman.shadow' apply plugin: 'com.github.johnrengelman.shadow'

@ -10,9 +10,9 @@ dependencies {
} }
shadowJar { shadowJar {
relocate 'redis.clients', 'me.William278.crossserversync.libraries.jedis' relocate 'redis.clients', 'me.William278.husksync.libraries.jedis'
relocate 'org.bstats', 'me.William278.crossserversync.libraries.plan' relocate 'org.bstats', 'me.William278.husksync.libraries.plan'
relocate 'de.themoep', 'me.William278.crossserversync.libraries.minedown' relocate 'de.themoep', 'me.William278.husksync.libraries.minedown'
} }
tasks.register('prepareKotlinBuildScriptModel'){} tasks.register('prepareKotlinBuildScriptModel'){}

@ -1,15 +1,15 @@
package me.william278.crossserversync; package me.william278.husksync;
import me.william278.crossserversync.bukkit.config.ConfigLoader; import me.william278.husksync.bukkit.config.ConfigLoader;
import me.william278.crossserversync.bukkit.data.BukkitDataCache; import me.william278.husksync.bukkit.data.BukkitDataCache;
import me.william278.crossserversync.bukkit.listener.BukkitRedisListener; import me.william278.husksync.bukkit.listener.BukkitRedisListener;
import me.william278.crossserversync.bukkit.listener.EventListener; import me.william278.husksync.bukkit.listener.EventListener;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
public final class CrossServerSyncBukkit extends JavaPlugin { public final class HuskSyncBukkit extends JavaPlugin {
private static CrossServerSyncBukkit instance; private static HuskSyncBukkit instance;
public static CrossServerSyncBukkit getInstance() { public static HuskSyncBukkit getInstance() {
return instance; return instance;
} }
@ -41,12 +41,12 @@ public final class CrossServerSyncBukkit extends JavaPlugin {
new BukkitRedisListener(); new BukkitRedisListener();
// Log to console // Log to console
getLogger().info("Enabled CrossServerSync (" + getServer().getName() + ") v" + getDescription().getVersion()); getLogger().info("Enabled HuskSync (" + getServer().getName() + ") v" + getDescription().getVersion());
} }
@Override @Override
public void onDisable() { public void onDisable() {
// Plugin shutdown logic // Plugin shutdown logic
getLogger().info("Disabled CrossServerSync (" + getServer().getName() + ") v" + getDescription().getVersion()); getLogger().info("Disabled HuskSync (" + getServer().getName() + ") v" + getDescription().getVersion());
} }
} }

@ -1,6 +1,6 @@
package me.william278.crossserversync.bukkit; package me.william278.husksync.bukkit;
import me.william278.crossserversync.redis.RedisMessage; import me.william278.husksync.redis.RedisMessage;
import org.bukkit.*; import org.bukkit.*;
import org.bukkit.advancement.Advancement; import org.bukkit.advancement.Advancement;
import org.bukkit.advancement.AdvancementProgress; import org.bukkit.advancement.AdvancementProgress;
@ -175,7 +175,7 @@ public final class DataSerializer {
return null; return null;
} }
try { try {
return (PlayerLocation) RedisMessage.deserialize(serializedLocationData); return (PlayerLocation) me.william278.husksync.redis.RedisMessage.deserialize(serializedLocationData);
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
throw new IOException("Unable to decode class type.", e); throw new IOException("Unable to decode class type.", e);
} }
@ -183,7 +183,7 @@ public final class DataSerializer {
public static String getSerializedLocation(Player player) throws IOException { public static String getSerializedLocation(Player player) throws IOException {
final Location playerLocation = player.getLocation(); final Location playerLocation = player.getLocation();
return RedisMessage.serialize(new PlayerLocation(playerLocation.getX(), playerLocation.getY(), playerLocation.getZ(), return me.william278.husksync.redis.RedisMessage.serialize(new PlayerLocation(playerLocation.getX(), playerLocation.getY(), playerLocation.getZ(),
playerLocation.getYaw(), playerLocation.getPitch(), player.getWorld().getName(), player.getWorld().getEnvironment())); playerLocation.getYaw(), playerLocation.getPitch(), player.getWorld().getName(), player.getWorld().getEnvironment()));
} }
@ -197,7 +197,7 @@ public final class DataSerializer {
return new ArrayList<>(); return new ArrayList<>();
} }
try { try {
return (ArrayList<AdvancementRecord>) RedisMessage.deserialize(serializedAdvancementData); return (ArrayList<AdvancementRecord>) me.william278.husksync.redis.RedisMessage.deserialize(serializedAdvancementData);
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
throw new IOException("Unable to decode class type.", e); throw new IOException("Unable to decode class type.", e);
} }
@ -214,7 +214,7 @@ public final class DataSerializer {
advancementData.add(new AdvancementRecord(advancementKey.getNamespace() + ":" + advancementKey.getKey(), awardedCriteria)); advancementData.add(new AdvancementRecord(advancementKey.getNamespace() + ":" + advancementKey.getKey(), awardedCriteria));
} }
return RedisMessage.serialize(advancementData); return me.william278.husksync.redis.RedisMessage.serialize(advancementData);
} }
public record AdvancementRecord(String advancementKey, public record AdvancementRecord(String advancementKey,
@ -226,7 +226,7 @@ public final class DataSerializer {
return new StatisticData(new HashMap<>(), new HashMap<>(), new HashMap<>(), new HashMap<>()); return new StatisticData(new HashMap<>(), new HashMap<>(), new HashMap<>(), new HashMap<>());
} }
try { try {
return (StatisticData) RedisMessage.deserialize(serializedStatisticData); return (StatisticData) me.william278.husksync.redis.RedisMessage.deserialize(serializedStatisticData);
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
throw new IOException("Unable to decode class type.", e); throw new IOException("Unable to decode class type.", e);
} }

@ -1,10 +1,10 @@
package me.william278.crossserversync.bukkit; package me.william278.husksync.bukkit;
import de.themoep.minedown.MineDown; import de.themoep.minedown.MineDown;
import me.william278.crossserversync.CrossServerSyncBukkit; import me.william278.husksync.HuskSyncBukkit;
import me.william278.crossserversync.MessageStrings; import me.william278.husksync.MessageStrings;
import me.william278.crossserversync.PlayerData; import me.william278.husksync.PlayerData;
import me.william278.crossserversync.Settings; import me.william278.husksync.Settings;
import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.ChatMessageType;
import org.bukkit.*; import org.bukkit.*;
import org.bukkit.advancement.Advancement; import org.bukkit.advancement.Advancement;
@ -23,7 +23,7 @@ import java.util.logging.Level;
public class PlayerSetter { public class PlayerSetter {
private static final CrossServerSyncBukkit plugin = CrossServerSyncBukkit.getInstance(); private static final HuskSyncBukkit plugin = HuskSyncBukkit.getInstance();
/** /**
* Set a player from their PlayerData, based on settings * Set a player from their PlayerData, based on settings

@ -1,6 +1,6 @@
package me.william278.crossserversync.bukkit.config; package me.william278.husksync.bukkit.config;
import me.william278.crossserversync.Settings; import me.william278.husksync.Settings;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
public class ConfigLoader { public class ConfigLoader {

@ -1,34 +1,19 @@
package me.william278.crossserversync.bukkit.data; package me.william278.husksync.bukkit.data;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.UUID; import java.util.UUID;
public class BukkitDataCache { public class BukkitDataCache {
/**
* Map of Player UUIDs to last-updated PlayerData version UUIDs
*/
private static HashMap<UUID, UUID> bukkitDataCache;
/** /**
* Map of Player UUIDs to request on join * Map of Player UUIDs to request on join
*/ */
private static HashSet<UUID> requestOnJoin; private static HashSet<UUID> requestOnJoin;
public BukkitDataCache() { public BukkitDataCache() {
bukkitDataCache = new HashMap<>();
requestOnJoin = new HashSet<>(); requestOnJoin = new HashSet<>();
} }
public UUID getVersionUUID(UUID playerUUID) {
return bukkitDataCache.get(playerUUID);
}
public void setVersionUUID(UUID playerUUID, UUID dataVersionUUID) {
bukkitDataCache.put(playerUUID, dataVersionUUID);
}
public boolean isPlayerRequestingOnJoin(UUID uuid) { public boolean isPlayerRequestingOnJoin(UUID uuid) {
return requestOnJoin.contains(uuid); return requestOnJoin.contains(uuid);
} }

@ -1,13 +1,13 @@
package me.william278.crossserversync.bukkit.listener; package me.william278.husksync.bukkit.listener;
import de.themoep.minedown.MineDown; import de.themoep.minedown.MineDown;
import me.william278.crossserversync.MessageStrings; import me.william278.husksync.PlayerData;
import me.william278.crossserversync.PlayerData; import me.william278.husksync.HuskSyncBukkit;
import me.william278.crossserversync.Settings; import me.william278.husksync.bukkit.PlayerSetter;
import me.william278.crossserversync.CrossServerSyncBukkit; import me.william278.husksync.redis.RedisListener;
import me.william278.crossserversync.bukkit.PlayerSetter; import me.william278.husksync.MessageStrings;
import me.william278.crossserversync.redis.RedisListener; import me.william278.husksync.Settings;
import me.william278.crossserversync.redis.RedisMessage; import me.william278.husksync.redis.RedisMessage;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -17,7 +17,7 @@ import java.util.logging.Level;
public class BukkitRedisListener extends RedisListener { public class BukkitRedisListener extends RedisListener {
private static final CrossServerSyncBukkit plugin = CrossServerSyncBukkit.getInstance(); private static final HuskSyncBukkit plugin = HuskSyncBukkit.getInstance();
// Initialize the listener on the bukkit server // Initialize the listener on the bukkit server
public BukkitRedisListener() { public BukkitRedisListener() {
@ -25,12 +25,12 @@ public class BukkitRedisListener extends RedisListener {
} }
/** /**
* Handle an incoming {@link RedisMessage} * Handle an incoming {@link me.william278.husksync.redis.RedisMessage}
* *
* @param message The {@link RedisMessage} to handle * @param message The {@link me.william278.husksync.redis.RedisMessage} to handle
*/ */
@Override @Override
public void handleMessage(RedisMessage message) { public void handleMessage(me.william278.husksync.redis.RedisMessage message) {
// Ignore messages for proxy servers // Ignore messages for proxy servers
if (!message.getMessageTarget().targetServerType().equals(Settings.ServerType.BUKKIT)) { if (!message.getMessageTarget().targetServerType().equals(Settings.ServerType.BUKKIT)) {
return; return;
@ -39,11 +39,11 @@ public class BukkitRedisListener extends RedisListener {
// Handle the message for the player // Handle the message for the player
if (message.getMessageTarget().targetPlayerUUID() == null) { if (message.getMessageTarget().targetPlayerUUID() == null) {
if (message.getMessageType() == RedisMessage.MessageType.REQUEST_DATA_ON_JOIN) { if (message.getMessageType() == me.william278.husksync.redis.RedisMessage.MessageType.REQUEST_DATA_ON_JOIN) {
UUID playerUUID = UUID.fromString(message.getMessageDataElements()[1]); UUID playerUUID = UUID.fromString(message.getMessageDataElements()[1]);
switch (RedisMessage.RequestOnJoinUpdateType.valueOf(message.getMessageDataElements()[0])) { switch (me.william278.husksync.redis.RedisMessage.RequestOnJoinUpdateType.valueOf(message.getMessageDataElements()[0])) {
case ADD_REQUESTER -> CrossServerSyncBukkit.bukkitCache.setRequestOnJoin(playerUUID); case ADD_REQUESTER -> HuskSyncBukkit.bukkitCache.setRequestOnJoin(playerUUID);
case REMOVE_REQUESTER -> CrossServerSyncBukkit.bukkitCache.removeRequestOnJoin(playerUUID); case REMOVE_REQUESTER -> HuskSyncBukkit.bukkitCache.removeRequestOnJoin(playerUUID);
} }
} }
} else { } else {
@ -55,9 +55,6 @@ public class BukkitRedisListener extends RedisListener {
// Deserialize the received PlayerData // Deserialize the received PlayerData
PlayerData data = (PlayerData) RedisMessage.deserialize(message.getMessageData()); PlayerData data = (PlayerData) RedisMessage.deserialize(message.getMessageData());
// Update last loaded data UUID
CrossServerSyncBukkit.bukkitCache.setVersionUUID(player.getUniqueId(), data.getDataVersionUUID());
// Set the player's data // Set the player's data
PlayerSetter.setPlayerFrom(player, data); PlayerSetter.setPlayerFrom(player, data);
} catch (IOException | ClassNotFoundException e) { } catch (IOException | ClassNotFoundException e) {

@ -1,10 +1,10 @@
package me.william278.crossserversync.bukkit.listener; package me.william278.husksync.bukkit.listener;
import me.william278.crossserversync.CrossServerSyncBukkit; import me.william278.husksync.HuskSyncBukkit;
import me.william278.crossserversync.PlayerData; import me.william278.husksync.PlayerData;
import me.william278.crossserversync.Settings; import me.william278.husksync.Settings;
import me.william278.crossserversync.bukkit.DataSerializer; import me.william278.husksync.bukkit.DataSerializer;
import me.william278.crossserversync.redis.RedisMessage; import me.william278.husksync.redis.RedisMessage;
import org.bukkit.attribute.Attribute; import org.bukkit.attribute.Attribute;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
@ -18,7 +18,7 @@ import java.util.logging.Level;
public class EventListener implements Listener { public class EventListener implements Listener {
private static final CrossServerSyncBukkit plugin = CrossServerSyncBukkit.getInstance(); private static final HuskSyncBukkit plugin = HuskSyncBukkit.getInstance();
/** /**
* Returns the new serialized PlayerData for a player. * Returns the new serialized PlayerData for a player.
@ -28,7 +28,7 @@ public class EventListener implements Listener {
* @throws IOException If the serialization fails * @throws IOException If the serialization fails
*/ */
private static String getNewSerializedPlayerData(Player player) throws IOException { private static String getNewSerializedPlayerData(Player player) throws IOException {
return RedisMessage.serialize(new PlayerData(player.getUniqueId(), return me.william278.husksync.redis.RedisMessage.serialize(new PlayerData(player.getUniqueId(),
DataSerializer.getSerializedInventoryContents(player), DataSerializer.getSerializedInventoryContents(player),
DataSerializer.getSerializedEnderChestContents(player), DataSerializer.getSerializedEnderChestContents(player),
player.getHealth(), player.getHealth(),
@ -53,15 +53,11 @@ public class EventListener implements Listener {
// When a player leaves a Bukkit server // When a player leaves a Bukkit server
final Player player = event.getPlayer(); final Player player = event.getPlayer();
// Send a redis message with the player's last updated PlayerData version UUID and their new PlayerData
try { try {
// Get the player's last updated PlayerData version UUID
//final UUID lastUpdatedDataVersion = CrossServerSyncBukkit.bukkitCache.getVersionUUID(player.getUniqueId());
//if (lastUpdatedDataVersion == null) return; // Return if the player has not been properly updated.
// Send a redis message with the player's last updated PlayerData version UUID and their new PlayerData
final String serializedPlayerData = getNewSerializedPlayerData(player); final String serializedPlayerData = getNewSerializedPlayerData(player);
new RedisMessage(RedisMessage.MessageType.PLAYER_DATA_UPDATE, new me.william278.husksync.redis.RedisMessage(me.william278.husksync.redis.RedisMessage.MessageType.PLAYER_DATA_UPDATE,
new RedisMessage.MessageTarget(Settings.ServerType.BUNGEECORD, null), new me.william278.husksync.redis.RedisMessage.MessageTarget(Settings.ServerType.BUNGEECORD, null),
serializedPlayerData).send(); serializedPlayerData).send();
} catch (IOException e) { } catch (IOException e) {
plugin.getLogger().log(Level.SEVERE, "Failed to send a PlayerData update to the proxy", e); plugin.getLogger().log(Level.SEVERE, "Failed to send a PlayerData update to the proxy", e);
@ -70,9 +66,6 @@ public class EventListener implements Listener {
// Clear player inventory and ender chest // Clear player inventory and ender chest
player.getInventory().clear(); player.getInventory().clear();
player.getEnderChest().clear(); player.getEnderChest().clear();
// Set data version ID to null
CrossServerSyncBukkit.bukkitCache.setVersionUUID(player.getUniqueId(), null);
} }
@EventHandler @EventHandler
@ -84,10 +77,10 @@ public class EventListener implements Listener {
player.getInventory().clear(); player.getInventory().clear();
player.getEnderChest().clear(); player.getEnderChest().clear();
if (CrossServerSyncBukkit.bukkitCache.isPlayerRequestingOnJoin(player.getUniqueId())) { if (HuskSyncBukkit.bukkitCache.isPlayerRequestingOnJoin(player.getUniqueId())) {
try { try {
// Send a redis message requesting the player data // Send a redis message requesting the player data
new RedisMessage(RedisMessage.MessageType.PLAYER_DATA_REQUEST, new me.william278.husksync.redis.RedisMessage(me.william278.husksync.redis.RedisMessage.MessageType.PLAYER_DATA_REQUEST,
new RedisMessage.MessageTarget(Settings.ServerType.BUNGEECORD, null), new RedisMessage.MessageTarget(Settings.ServerType.BUNGEECORD, null),
player.getUniqueId().toString()).send(); player.getUniqueId().toString()).send();
} catch (IOException e) { } catch (IOException e) {

@ -10,10 +10,10 @@ dependencies {
} }
shadowJar { shadowJar {
relocate 'redis.clients', 'me.William278.crossserversync.libraries.jedis' relocate 'redis.clients', 'me.William278.husksync.libraries.jedis'
relocate 'com.zaxxer', 'me.William278.crossserversync.libraries.hikari' relocate 'com.zaxxer', 'me.William278.husksync.libraries.hikari'
relocate 'org.bstats', 'me.William278.crossserversync.libraries.plan' relocate 'org.bstats', 'me.William278.husksync.libraries.plan'
relocate 'de.themoep', 'me.William278.crossserversync.libraries.minedown' relocate 'de.themoep', 'me.William278.husksync.libraries.minedown'
} }
tasks.register('prepareKotlinBuildScriptModel'){} tasks.register('prepareKotlinBuildScriptModel'){}

@ -1,33 +0,0 @@
package me.william278.crossserversync.bungeecord.data.sql;
import me.william278.crossserversync.Settings;
import me.william278.crossserversync.CrossServerSyncBungeeCord;
import java.sql.Connection;
import java.sql.SQLException;
public abstract class Database {
protected CrossServerSyncBungeeCord plugin;
public final static String DATA_POOL_NAME = "CrossServerSyncHikariPool";
public final static String PLAYER_TABLE_NAME = "crossserversync_players";
public final static String DATA_TABLE_NAME = "crossserversync_data";
public Database(CrossServerSyncBungeeCord instance) {
plugin = instance;
}
public abstract Connection getConnection() throws SQLException;
public abstract void load();
public abstract void backup();
public abstract void close();
public final int hikariMaximumPoolSize = Settings.hikariMaximumPoolSize;
public final int hikariMinimumIdle = Settings.hikariMinimumIdle;
public final long hikariMaximumLifetime = Settings.hikariMaximumLifetime;
public final long hikariKeepAliveTime = Settings.hikariKeepAliveTime;
public final long hikariConnectionTimeOut = Settings.hikariConnectionTimeOut;
}

@ -1,24 +1,24 @@
package me.william278.crossserversync; package me.william278.husksync;
import me.william278.crossserversync.bungeecord.command.CrossServerSyncCommand; import me.william278.husksync.bungeecord.command.HuskSyncCommand;
import me.william278.crossserversync.bungeecord.config.ConfigLoader; import me.william278.husksync.bungeecord.config.ConfigLoader;
import me.william278.crossserversync.bungeecord.config.ConfigManager; import me.william278.husksync.bungeecord.config.ConfigManager;
import me.william278.crossserversync.bungeecord.data.DataManager; import me.william278.husksync.bungeecord.data.DataManager;
import me.william278.crossserversync.bungeecord.data.sql.Database; import me.william278.husksync.bungeecord.data.sql.Database;
import me.william278.crossserversync.bungeecord.data.sql.MySQL; import me.william278.husksync.bungeecord.data.sql.MySQL;
import me.william278.crossserversync.bungeecord.data.sql.SQLite; import me.william278.husksync.bungeecord.data.sql.SQLite;
import me.william278.crossserversync.bungeecord.listener.BungeeEventListener; import me.william278.husksync.bungeecord.listener.BungeeEventListener;
import me.william278.crossserversync.bungeecord.listener.BungeeRedisListener; import me.william278.husksync.bungeecord.listener.BungeeRedisListener;
import net.md_5.bungee.api.plugin.Plugin; import net.md_5.bungee.api.plugin.Plugin;
import java.sql.Connection; import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Objects; import java.util.Objects;
public final class CrossServerSyncBungeeCord extends Plugin { public final class HuskSyncBungeeCord extends Plugin {
private static CrossServerSyncBungeeCord instance; private static HuskSyncBungeeCord instance;
public static CrossServerSyncBungeeCord getInstance() { public static HuskSyncBungeeCord getInstance() {
return instance; return instance;
} }
@ -56,13 +56,13 @@ public final class CrossServerSyncBungeeCord extends Plugin {
getProxy().getPluginManager().registerListener(this, new BungeeEventListener()); getProxy().getPluginManager().registerListener(this, new BungeeEventListener());
// Register command // Register command
getProxy().getPluginManager().registerCommand(this, new CrossServerSyncCommand()); getProxy().getPluginManager().registerCommand(this, new HuskSyncCommand());
// Initialize the redis listener // Initialize the redis listener
new BungeeRedisListener(); new BungeeRedisListener();
// Log to console // Log to console
getLogger().info("Enabled CrossServerSync (" + getProxy().getName() + ") v" + getDescription().getVersion()); getLogger().info("Enabled HuskSync (" + getProxy().getName() + ") v" + getDescription().getVersion());
} }
@Override @Override
@ -73,6 +73,6 @@ public final class CrossServerSyncBungeeCord extends Plugin {
database.close(); database.close();
// Log to console // Log to console
getLogger().info("Disabled CrossServerSync (" + getProxy().getName() + ") v" + getDescription().getVersion()); getLogger().info("Disabled HuskSync (" + getProxy().getName() + ") v" + getDescription().getVersion());
} }
} }

@ -1,10 +1,10 @@
package me.william278.crossserversync.bungeecord.command; package me.william278.husksync.bungeecord.command;
import de.themoep.minedown.MineDown; import de.themoep.minedown.MineDown;
import me.william278.crossserversync.CrossServerSyncBungeeCord; import me.william278.husksync.HuskSyncBungeeCord;
import me.william278.crossserversync.MessageStrings; import me.william278.husksync.MessageStrings;
import me.william278.crossserversync.Settings; import me.william278.husksync.Settings;
import me.william278.crossserversync.redis.RedisMessage; import me.william278.husksync.redis.RedisMessage;
import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.plugin.Command; import net.md_5.bungee.api.plugin.Command;
@ -17,14 +17,14 @@ import java.util.Locale;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class CrossServerSyncCommand extends Command implements TabExecutor { public class HuskSyncCommand extends Command implements TabExecutor {
private final static CrossServerSyncBungeeCord plugin = CrossServerSyncBungeeCord.getInstance(); private final static HuskSyncBungeeCord plugin = HuskSyncBungeeCord.getInstance();
private final static String[] COMMAND_TAB_ARGUMENTS = {"about", "reload"}; private final static String[] COMMAND_TAB_ARGUMENTS = {"about", "reload"};
private final static String PERMISSION = "crossserversync.command.csc"; private final static String PERMISSION = "husksync.command.csc";
//public CrossServerSyncCommand() { super("csc", PERMISSION, "crossserversync"); } //public HuskSyncCommand() { super("husksync", PERMISSION, "hs"); }
public CrossServerSyncCommand() { super("csc"); } public HuskSyncCommand() { super("husksync"); }
@Override @Override
public void execute(CommandSender sender, String[] args) { public void execute(CommandSender sender, String[] args) {
@ -47,7 +47,7 @@ public class CrossServerSyncCommand extends Command implements TabExecutor {
*/ */
private void sendAboutInformation(ProxiedPlayer player) { private void sendAboutInformation(ProxiedPlayer player) {
try { try {
new RedisMessage(RedisMessage.MessageType.SEND_PLUGIN_INFORMATION, new me.william278.husksync.redis.RedisMessage(me.william278.husksync.redis.RedisMessage.MessageType.SEND_PLUGIN_INFORMATION,
new RedisMessage.MessageTarget(Settings.ServerType.BUKKIT, player.getUniqueId()), new RedisMessage.MessageTarget(Settings.ServerType.BUKKIT, player.getUniqueId()),
plugin.getProxy().getName(), plugin.getDescription().getVersion()).send(); plugin.getProxy().getName(), plugin.getDescription().getVersion()).send();
} catch (IOException e) { } catch (IOException e) {

@ -1,6 +1,6 @@
package me.william278.crossserversync.bungeecord.config; package me.william278.husksync.bungeecord.config;
import me.william278.crossserversync.Settings; import me.william278.husksync.Settings;
import net.md_5.bungee.config.Configuration; import net.md_5.bungee.config.Configuration;
public class ConfigLoader { public class ConfigLoader {
@ -15,16 +15,16 @@ public class ConfigLoader {
if (Settings.dataStorageType == Settings.DataStorageType.MYSQL) { if (Settings.dataStorageType == Settings.DataStorageType.MYSQL) {
Settings.mySQLHost = config.getString("data_storage_settings.mysql_settings.host", "localhost"); Settings.mySQLHost = config.getString("data_storage_settings.mysql_settings.host", "localhost");
Settings.mySQLPort = config.getInt("data_storage_settings.mysql_settings.port", 8123); Settings.mySQLPort = config.getInt("data_storage_settings.mysql_settings.port", 8123);
Settings.mySQLDatabase = config.getString("data_storage_settings.mysql_settings.database", "CrossServerSync"); Settings.mySQLDatabase = config.getString("data_storage_settings.mysql_settings.database", "HuskSync");
Settings.mySQLUsername = config.getString("data_storage_settings.mysql_settings.username", "CrossServerSync"); Settings.mySQLUsername = config.getString("data_storage_settings.mysql_settings.username", "root");
Settings.mySQLPassword = config.getString("data_storage_settings.mysql_settings.password", "CrossServerSync"); Settings.mySQLPassword = config.getString("data_storage_settings.mysql_settings.password", "pa55w0rd");
Settings.mySQLParams = config.getString("data_storage_settings.mysql_settings.params", "CrossServerSync"); Settings.mySQLParams = config.getString("data_storage_settings.mysql_settings.params", "?autoReconnect=true&useSSL=false");
} }
Settings.hikariMaximumPoolSize = config.getInt("data_storage_settings.hikari_pool_settings.maximum_pool_size", 10); Settings.hikariMaximumPoolSize = config.getInt("data_storage_settings.hikari_pool_settings.maximum_pool_size", 10);
Settings.hikariMinimumIdle = config.getInt("data_storage_settings.hikari_pool_settings.minimum_idle", 10); Settings.hikariMinimumIdle = config.getInt("data_storage_settings.hikari_pool_settings.minimum_idle", 10);
Settings.hikariMaximumLifetime = config.getLong("data_storage_settings.hikari_pool_settings.maximum_lifetime", 1800000); Settings.hikariMaximumLifetime = config.getLong("data_storage_settings.hikari_pool_settings.maximum_lifetime", 1800000);
Settings.hikariKeepAliveTime = config.getLong("data_storage_settings.hikari_pool_settings.keepalive_time", 10); Settings.hikariKeepAliveTime = config.getLong("data_storage_settings.hikari_pool_settings.keepalive_time", 0);
Settings.hikariConnectionTimeOut = config.getLong("data_storage_settings.hikari_pool_settings.connection_timeout", 5000); Settings.hikariConnectionTimeOut = config.getLong("data_storage_settings.hikari_pool_settings.connection_timeout", 5000);
} }

@ -1,6 +1,6 @@
package me.william278.crossserversync.bungeecord.config; package me.william278.husksync.bungeecord.config;
import me.william278.crossserversync.CrossServerSyncBungeeCord; import me.william278.husksync.HuskSyncBungeeCord;
import net.md_5.bungee.config.Configuration; import net.md_5.bungee.config.Configuration;
import net.md_5.bungee.config.ConfigurationProvider; import net.md_5.bungee.config.ConfigurationProvider;
import net.md_5.bungee.config.YamlConfiguration; import net.md_5.bungee.config.YamlConfiguration;
@ -12,19 +12,19 @@ import java.util.logging.Level;
public class ConfigManager { public class ConfigManager {
private static final CrossServerSyncBungeeCord plugin = CrossServerSyncBungeeCord.getInstance(); private static final HuskSyncBungeeCord plugin = HuskSyncBungeeCord.getInstance();
public static void loadConfig() { public static void loadConfig() {
try { try {
if (!plugin.getDataFolder().exists()) { if (!plugin.getDataFolder().exists()) {
if (plugin.getDataFolder().mkdir()) { if (plugin.getDataFolder().mkdir()) {
plugin.getLogger().info("Created CrossServerSync data folder"); plugin.getLogger().info("Created HuskSync data folder");
} }
} }
File configFile = new File(plugin.getDataFolder(), "config.yml"); File configFile = new File(plugin.getDataFolder(), "config.yml");
if (!configFile.exists()) { if (!configFile.exists()) {
Files.copy(plugin.getResourceAsStream("bungee-config.yml"), configFile.toPath()); Files.copy(plugin.getResourceAsStream("bungee-config.yml"), configFile.toPath());
plugin.getLogger().info("Created CrossServerSync bungee-config.yml file"); plugin.getLogger().info("Created HuskSync bungee-config.yml file");
} }
} catch (Exception e) { } catch (Exception e) {
plugin.getLogger().log(Level.CONFIG, "An exception occurred loading the configuration file", e); plugin.getLogger().log(Level.CONFIG, "An exception occurred loading the configuration file", e);

@ -1,8 +1,8 @@
package me.william278.crossserversync.bungeecord.data; package me.william278.husksync.bungeecord.data;
import me.william278.crossserversync.PlayerData; import me.william278.husksync.PlayerData;
import me.william278.crossserversync.CrossServerSyncBungeeCord; import me.william278.husksync.HuskSyncBungeeCord;
import me.william278.crossserversync.bungeecord.data.sql.Database; import me.william278.husksync.bungeecord.data.sql.Database;
import java.sql.*; import java.sql.*;
import java.time.Instant; import java.time.Instant;
@ -12,7 +12,7 @@ import java.util.logging.Level;
public class DataManager { public class DataManager {
private static final CrossServerSyncBungeeCord plugin = CrossServerSyncBungeeCord.getInstance(); private static final HuskSyncBungeeCord plugin = HuskSyncBungeeCord.getInstance();
public static PlayerDataCache playerDataCache; public static PlayerDataCache playerDataCache;
/** /**
@ -33,7 +33,7 @@ public class DataManager {
* @return {@code true} if the player is on the player table * @return {@code true} if the player is on the player table
*/ */
private static boolean playerExists(UUID playerUUID) { private static boolean playerExists(UUID playerUUID) {
try (Connection connection = CrossServerSyncBungeeCord.getConnection()) { try (Connection connection = HuskSyncBungeeCord.getConnection()) {
try (PreparedStatement statement = connection.prepareStatement( try (PreparedStatement statement = connection.prepareStatement(
"SELECT * FROM " + Database.PLAYER_TABLE_NAME + " WHERE `uuid`=?;")) { "SELECT * FROM " + Database.PLAYER_TABLE_NAME + " WHERE `uuid`=?;")) {
statement.setString(1, playerUUID.toString()); statement.setString(1, playerUUID.toString());
@ -47,7 +47,7 @@ public class DataManager {
} }
private static void createPlayerEntry(UUID playerUUID) { private static void createPlayerEntry(UUID playerUUID) {
try (Connection connection = CrossServerSyncBungeeCord.getConnection()) { try (Connection connection = HuskSyncBungeeCord.getConnection()) {
try (PreparedStatement statement = connection.prepareStatement( try (PreparedStatement statement = connection.prepareStatement(
"INSERT INTO " + Database.PLAYER_TABLE_NAME + " (`uuid`) VALUES(?);")) { "INSERT INTO " + Database.PLAYER_TABLE_NAME + " (`uuid`) VALUES(?);")) {
statement.setString(1, playerUUID.toString()); statement.setString(1, playerUUID.toString());
@ -59,7 +59,7 @@ public class DataManager {
} }
public static PlayerData getPlayerData(UUID playerUUID) { public static PlayerData getPlayerData(UUID playerUUID) {
try (Connection connection = CrossServerSyncBungeeCord.getConnection()) { try (Connection connection = HuskSyncBungeeCord.getConnection()) {
try (PreparedStatement statement = connection.prepareStatement( try (PreparedStatement statement = connection.prepareStatement(
"SELECT * FROM " + Database.DATA_TABLE_NAME + " WHERE `player_id`=(SELECT `id` FROM " + Database.PLAYER_TABLE_NAME + " WHERE `uuid`=?);")) { "SELECT * FROM " + Database.DATA_TABLE_NAME + " WHERE `player_id`=(SELECT `id` FROM " + Database.PLAYER_TABLE_NAME + " WHERE `uuid`=?);")) {
statement.setString(1, playerUUID.toString()); statement.setString(1, playerUUID.toString());
@ -115,7 +115,7 @@ public class DataManager {
} }
private static void updatePlayerSQLData(PlayerData playerData) { private static void updatePlayerSQLData(PlayerData playerData) {
try (Connection connection = CrossServerSyncBungeeCord.getConnection()) { try (Connection connection = HuskSyncBungeeCord.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`=?, `saturation_exhaustion`=?, `selected_slot`=?, `status_effects`=?, `total_experience`=?, `exp_level`=?, `exp_progress`=?, `game_mode`=?, `statistics`=?, `is_flying`=?, `advancements`=?, `location`=? 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`=?, `total_experience`=?, `exp_level`=?, `exp_progress`=?, `game_mode`=?, `statistics`=?, `is_flying`=?, `advancements`=?, `location`=? WHERE `player_id`=(SELECT `id` FROM " + Database.PLAYER_TABLE_NAME + " WHERE `uuid`=?);")) {
statement.setString(1, playerData.getDataVersionUUID().toString()); statement.setString(1, playerData.getDataVersionUUID().toString());
@ -147,7 +147,7 @@ public class DataManager {
} }
private static void insertPlayerData(PlayerData playerData) { private static void insertPlayerData(PlayerData playerData) {
try (Connection connection = CrossServerSyncBungeeCord.getConnection()) { try (Connection connection = HuskSyncBungeeCord.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`,`saturation_exhaustion`,`selected_slot`,`status_effects`,`total_experience`,`exp_level`,`exp_progress`,`game_mode`,`statistics`,`is_flying`,`advancements`,`location`) 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`,`total_experience`,`exp_level`,`exp_progress`,`game_mode`,`statistics`,`is_flying`,`advancements`,`location`) VALUES((SELECT `id` FROM " + Database.PLAYER_TABLE_NAME + " WHERE `uuid`=?),?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);")) {
statement.setString(1, playerData.getPlayerUUID().toString()); statement.setString(1, playerData.getPlayerUUID().toString());
@ -185,7 +185,7 @@ public class DataManager {
* @return {@code true} if the player has an entry in the data table * @return {@code true} if the player has an entry in the data table
*/ */
private static boolean playerHasCachedData(UUID playerUUID) { private static boolean playerHasCachedData(UUID playerUUID) {
try (Connection connection = CrossServerSyncBungeeCord.getConnection()) { try (Connection connection = HuskSyncBungeeCord.getConnection()) {
try (PreparedStatement statement = connection.prepareStatement( try (PreparedStatement statement = connection.prepareStatement(
"SELECT * FROM " + Database.DATA_TABLE_NAME + " WHERE `player_id`=(SELECT `id` FROM " + Database.PLAYER_TABLE_NAME + " WHERE `uuid`=?);")) { "SELECT * FROM " + Database.DATA_TABLE_NAME + " WHERE `player_id`=(SELECT `id` FROM " + Database.PLAYER_TABLE_NAME + " WHERE `uuid`=?);")) {
statement.setString(1, playerUUID.toString()); statement.setString(1, playerUUID.toString());

@ -0,0 +1,33 @@
package me.william278.husksync.bungeecord.data.sql;
import me.william278.husksync.HuskSyncBungeeCord;
import me.william278.husksync.Settings;
import java.sql.Connection;
import java.sql.SQLException;
public abstract class Database {
protected HuskSyncBungeeCord plugin;
public final static String DATA_POOL_NAME = "HuskSyncHikariPool";
public final static String PLAYER_TABLE_NAME = "husksync_players";
public final static String DATA_TABLE_NAME = "husksync_data";
public Database(HuskSyncBungeeCord instance) {
plugin = instance;
}
public abstract Connection getConnection() throws SQLException;
public abstract void load();
public abstract void backup();
public abstract void close();
public final int hikariMaximumPoolSize = me.william278.husksync.Settings.hikariMaximumPoolSize;
public final int hikariMinimumIdle = me.william278.husksync.Settings.hikariMinimumIdle;
public final long hikariMaximumLifetime = me.william278.husksync.Settings.hikariMaximumLifetime;
public final long hikariKeepAliveTime = me.william278.husksync.Settings.hikariKeepAliveTime;
public final long hikariConnectionTimeOut = Settings.hikariConnectionTimeOut;
}

@ -1,8 +1,8 @@
package me.william278.crossserversync.bungeecord.data.sql; package me.william278.husksync.bungeecord.data.sql;
import com.zaxxer.hikari.HikariDataSource; import com.zaxxer.hikari.HikariDataSource;
import me.william278.crossserversync.Settings; import me.william278.husksync.HuskSyncBungeeCord;
import me.william278.crossserversync.CrossServerSyncBungeeCord; import me.william278.husksync.Settings;
import java.sql.Connection; import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
@ -47,16 +47,16 @@ public class MySQL extends Database {
}; };
final String host = Settings.mySQLHost; final String host = me.william278.husksync.Settings.mySQLHost;
final int port = Settings.mySQLPort; final int port = me.william278.husksync.Settings.mySQLPort;
final String database = Settings.mySQLDatabase; final String database = me.william278.husksync.Settings.mySQLDatabase;
final String username = Settings.mySQLUsername; final String username = me.william278.husksync.Settings.mySQLUsername;
final String password = Settings.mySQLPassword; final String password = me.william278.husksync.Settings.mySQLPassword;
final String params = Settings.mySQLParams; final String params = Settings.mySQLParams;
private HikariDataSource dataSource; private HikariDataSource dataSource;
public MySQL(CrossServerSyncBungeeCord instance) { public MySQL(HuskSyncBungeeCord instance) {
super(instance); super(instance);
} }

@ -1,7 +1,7 @@
package me.william278.crossserversync.bungeecord.data.sql; package me.william278.husksync.bungeecord.data.sql;
import com.zaxxer.hikari.HikariDataSource; import com.zaxxer.hikari.HikariDataSource;
import me.william278.crossserversync.CrossServerSyncBungeeCord; import me.william278.husksync.HuskSyncBungeeCord;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -53,11 +53,11 @@ public class SQLite extends Database {
");" ");"
}; };
private static final String DATABASE_NAME = "CrossServerSyncData"; private static final String DATABASE_NAME = "HuskSyncData";
private HikariDataSource dataSource; private HikariDataSource dataSource;
public SQLite(CrossServerSyncBungeeCord instance) { public SQLite(HuskSyncBungeeCord instance) {
super(instance); super(instance);
} }
@ -127,7 +127,7 @@ public class SQLite extends Database {
.format(Instant.now()).replaceAll(" ", "-") + ".db"; .format(Instant.now()).replaceAll(" ", "-") + ".db";
final File databaseFile = new File(plugin.getDataFolder(), DATABASE_NAME + ".db"); final File databaseFile = new File(plugin.getDataFolder(), DATABASE_NAME + ".db");
if (new File(plugin.getDataFolder(), BACKUPS_FOLDER_NAME).mkdirs()) { if (new File(plugin.getDataFolder(), BACKUPS_FOLDER_NAME).mkdirs()) {
plugin.getLogger().info("Created backups directory in CrossServerSync plugin data folder."); plugin.getLogger().info("Created backups directory in HuskSync plugin data folder.");
} }
final File backUpFile = new File(plugin.getDataFolder(), BACKUPS_FOLDER_NAME + File.separator + backupFileName); final File backUpFile = new File(plugin.getDataFolder(), BACKUPS_FOLDER_NAME + File.separator + backupFileName);
try { try {

@ -1,10 +1,10 @@
package me.william278.crossserversync.bungeecord.listener; package me.william278.husksync.bungeecord.listener;
import me.william278.crossserversync.CrossServerSyncBungeeCord; import me.william278.husksync.HuskSyncBungeeCord;
import me.william278.crossserversync.PlayerData; import me.william278.husksync.PlayerData;
import me.william278.crossserversync.Settings; import me.william278.husksync.bungeecord.data.DataManager;
import me.william278.crossserversync.bungeecord.data.DataManager; import me.william278.husksync.Settings;
import me.william278.crossserversync.redis.RedisMessage; import me.william278.husksync.redis.RedisMessage;
import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.event.PostLoginEvent; import net.md_5.bungee.api.event.PostLoginEvent;
@ -16,7 +16,7 @@ import java.util.logging.Level;
public class BungeeEventListener implements Listener { public class BungeeEventListener implements Listener {
private static final CrossServerSyncBungeeCord plugin = CrossServerSyncBungeeCord.getInstance(); private static final HuskSyncBungeeCord plugin = HuskSyncBungeeCord.getInstance();
@EventHandler @EventHandler
public void onPostLogin(PostLoginEvent event) { public void onPostLogin(PostLoginEvent event) {
@ -33,8 +33,8 @@ public class BungeeEventListener implements Listener {
// Send a message asking the bukkit to request data on join // Send a message asking the bukkit to request data on join
try { try {
new RedisMessage(RedisMessage.MessageType.REQUEST_DATA_ON_JOIN, new me.william278.husksync.redis.RedisMessage(me.william278.husksync.redis.RedisMessage.MessageType.REQUEST_DATA_ON_JOIN,
new RedisMessage.MessageTarget(Settings.ServerType.BUKKIT, null), new me.william278.husksync.redis.RedisMessage.MessageTarget(Settings.ServerType.BUKKIT, null),
RedisMessage.RequestOnJoinUpdateType.ADD_REQUESTER.toString(), player.getUniqueId().toString()).send(); RedisMessage.RequestOnJoinUpdateType.ADD_REQUESTER.toString(), player.getUniqueId().toString()).send();
} catch (IOException e) { } catch (IOException e) {
plugin.getLogger().log(Level.SEVERE, "Failed to serialize request data on join message data"); plugin.getLogger().log(Level.SEVERE, "Failed to serialize request data on join message data");

@ -1,11 +1,11 @@
package me.william278.crossserversync.bungeecord.listener; package me.william278.husksync.bungeecord.listener;
import me.william278.crossserversync.CrossServerSyncBungeeCord; import me.william278.husksync.HuskSyncBungeeCord;
import me.william278.crossserversync.PlayerData; import me.william278.husksync.PlayerData;
import me.william278.crossserversync.Settings; import me.william278.husksync.bungeecord.data.DataManager;
import me.william278.crossserversync.bungeecord.data.DataManager; import me.william278.husksync.redis.RedisListener;
import me.william278.crossserversync.redis.RedisListener; import me.william278.husksync.Settings;
import me.william278.crossserversync.redis.RedisMessage; import me.william278.husksync.redis.RedisMessage;
import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.connection.ProxiedPlayer;
@ -15,7 +15,7 @@ import java.util.logging.Level;
public class BungeeRedisListener extends RedisListener { public class BungeeRedisListener extends RedisListener {
private static final CrossServerSyncBungeeCord plugin = CrossServerSyncBungeeCord.getInstance(); private static final HuskSyncBungeeCord plugin = HuskSyncBungeeCord.getInstance();
// Initialize the listener on the bungee // Initialize the listener on the bungee
public BungeeRedisListener() { public BungeeRedisListener() {
@ -38,14 +38,14 @@ public class BungeeRedisListener extends RedisListener {
} }
/** /**
* Handle an incoming {@link RedisMessage} * Handle an incoming {@link me.william278.husksync.redis.RedisMessage}
* *
* @param message The {@link RedisMessage} to handle * @param message The {@link me.william278.husksync.redis.RedisMessage} to handle
*/ */
@Override @Override
public void handleMessage(RedisMessage message) { public void handleMessage(me.william278.husksync.redis.RedisMessage message) {
// Ignore messages destined for Bukkit servers // Ignore messages destined for Bukkit servers
if (message.getMessageTarget().targetServerType() != Settings.ServerType.BUNGEECORD) { if (message.getMessageTarget().targetServerType() != me.william278.husksync.Settings.ServerType.BUNGEECORD) {
return; return;
} }
@ -56,15 +56,15 @@ 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_SET, new me.william278.husksync.redis.RedisMessage(me.william278.husksync.redis.RedisMessage.MessageType.PLAYER_DATA_SET,
new RedisMessage.MessageTarget(Settings.ServerType.BUKKIT, requestingPlayerUUID), new me.william278.husksync.redis.RedisMessage.MessageTarget(me.william278.husksync.Settings.ServerType.BUKKIT, requestingPlayerUUID),
RedisMessage.serialize(getPlayerCachedData(requestingPlayerUUID))) me.william278.husksync.redis.RedisMessage.serialize(getPlayerCachedData(requestingPlayerUUID)))
.send(); .send();
// Send an update to all bukkit servers removing the player from the requester cache // Send an update to all bukkit servers removing the player from the requester cache
new RedisMessage(RedisMessage.MessageType.REQUEST_DATA_ON_JOIN, new me.william278.husksync.redis.RedisMessage(me.william278.husksync.redis.RedisMessage.MessageType.REQUEST_DATA_ON_JOIN,
new RedisMessage.MessageTarget(Settings.ServerType.BUKKIT, null), new me.william278.husksync.redis.RedisMessage.MessageTarget(me.william278.husksync.Settings.ServerType.BUKKIT, null),
RedisMessage.RequestOnJoinUpdateType.REMOVE_REQUESTER.toString(), requestingPlayerUUID.toString()) me.william278.husksync.redis.RedisMessage.RequestOnJoinUpdateType.REMOVE_REQUESTER.toString(), requestingPlayerUUID.toString())
.send(); .send();
} catch (IOException e) { } catch (IOException e) {
log(Level.SEVERE, "Failed to serialize data when replying to a data request"); log(Level.SEVERE, "Failed to serialize data when replying to a data request");
@ -77,7 +77,7 @@ public class BungeeRedisListener extends RedisListener {
PlayerData playerData; PlayerData playerData;
final String serializedPlayerData = message.getMessageData(); final String serializedPlayerData = message.getMessageData();
try { try {
playerData = (PlayerData) RedisMessage.deserialize(serializedPlayerData); playerData = (PlayerData) me.william278.husksync.redis.RedisMessage.deserialize(serializedPlayerData);
} catch (IOException | ClassNotFoundException e) { } catch (IOException | ClassNotFoundException e) {
log(Level.SEVERE, "Failed to deserialize PlayerData when handling a player update request"); log(Level.SEVERE, "Failed to deserialize PlayerData when handling a player update request");
e.printStackTrace(); e.printStackTrace();
@ -92,8 +92,8 @@ public class BungeeRedisListener extends RedisListener {
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(playerData.getPlayerUUID()); ProxiedPlayer player = ProxyServer.getInstance().getPlayer(playerData.getPlayerUUID());
if (player != null) { if (player != null) {
if (player.isConnected()) { if (player.isConnected()) {
new RedisMessage(RedisMessage.MessageType.PLAYER_DATA_SET, new me.william278.husksync.redis.RedisMessage(me.william278.husksync.redis.RedisMessage.MessageType.PLAYER_DATA_SET,
new RedisMessage.MessageTarget(Settings.ServerType.BUKKIT, playerData.getPlayerUUID()), new me.william278.husksync.redis.RedisMessage.MessageTarget(Settings.ServerType.BUKKIT, playerData.getPlayerUUID()),
RedisMessage.serialize(playerData)) RedisMessage.serialize(playerData))
.send(); .send();
} }

@ -7,10 +7,10 @@ data_storage_settings:
mysql_settings: mysql_settings:
host: 'localhost' host: 'localhost'
port: 8123 port: 8123
database: 'CrossServerSync' database: 'HuskSync'
username: 'root' username: 'root'
password: 'pa55w0rd' password: 'pa55w0rd'
params: '' params: '?autoReconnect=true&useSSL=false'
hikari_pool_settings: hikari_pool_settings:
maximum_pool_size: 10 maximum_pool_size: 10
minimum_idle: 10 minimum_idle: 10

@ -26,5 +26,5 @@ shadowJar {
exclude "module-info.class" exclude "module-info.class"
// Relocations // Relocations
relocate 'redis.clients', 'me.William278.crossserversync.libraries.jedis' relocate 'redis.clients', 'me.William278.husksync.libraries.jedis'
} }

@ -1,12 +1,12 @@
package me.william278.crossserversync; package me.william278.husksync;
public class MessageStrings { public class MessageStrings {
public static final StringBuilder PLUGIN_INFORMATION = new StringBuilder().append("[CrossServerSync](#00fb9a bold) [| %proxy_brand% Version %proxy_version% (%bukkit_brand% v%bukkit_version%)](#00fb9a)\n") public static final StringBuilder PLUGIN_INFORMATION = new StringBuilder().append("[HuskSync](#00fb9a bold) [| %proxy_brand% Version %proxy_version% (%bukkit_brand% v%bukkit_version%)](#00fb9a)\n")
.append("[%plugin_description%](gray)\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("[• 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("[• Help Wiki:](white) [[Link]](#00fb9a show_text=&7Click to open link open_url=https://github.com/WiIIiam278/HuskSync/wiki/)\n")
.append("[• Report Issues:](white) [[Link]](#00fb9a show_text=&7Click to open link open_url=https://github.com/WiIIiam278/CrossServerSync/issues)\n") .append("[• Report Issues:](white) [[Link]](#00fb9a show_text=&7Click to open link open_url=https://github.com/WiIIiam278/HuskSync/issues)\n")
.append("[• Support Discord:](white) [[Link]](#00fb9a show_text=&7Click to join open_url=https://discord.gg/tVYhJfyDWG)"); .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)"; public static final String ERROR_INVALID_SYNTAX = "[Error:](#ff3300) [Incorrect syntax. Usage: %1%](#ff7e5e)";

@ -1,4 +1,4 @@
package me.william278.crossserversync; package me.william278.husksync;
import java.io.*; import java.io.*;
import java.util.UUID; import java.util.UUID;

@ -1,5 +1,8 @@
package me.william278.crossserversync; package me.william278.husksync;
/**
* Settings class, holds values loaded from the plugin config (either Bukkit or Bungee)
*/
public class Settings { public class Settings {
/* /*

@ -1,6 +1,6 @@
package me.william278.crossserversync.redis; package me.william278.husksync.redis;
import me.william278.crossserversync.Settings; import me.william278.husksync.Settings;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub; import redis.clients.jedis.JedisPubSub;
@ -37,7 +37,7 @@ public abstract class RedisListener {
new Thread(() -> jedis.subscribe(new JedisPubSub() { new Thread(() -> jedis.subscribe(new JedisPubSub() {
@Override @Override
public void onMessage(String channel, String message) { public void onMessage(String channel, String message) {
// Only accept messages to the CrossServerSync channel // Only accept messages to the HuskSync channel
if (!channel.equals(RedisMessage.REDIS_CHANNEL)) { if (!channel.equals(RedisMessage.REDIS_CHANNEL)) {
return; return;
} }

@ -1,7 +1,7 @@
package me.william278.crossserversync.redis; package me.william278.husksync.redis;
import me.william278.crossserversync.PlayerData; import me.william278.husksync.PlayerData;
import me.william278.crossserversync.Settings; import me.william278.husksync.Settings;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import java.io.*; import java.io.*;
@ -11,7 +11,7 @@ import java.util.UUID;
public class RedisMessage { public class RedisMessage {
public static String REDIS_CHANNEL = "CrossServerSync"; public static String REDIS_CHANNEL = "HuskSync";
public static String MESSAGE_META_SEPARATOR = "♦"; public static String MESSAGE_META_SEPARATOR = "♦";
public static String MESSAGE_DATA_SEPARATOR = "♣"; public static String MESSAGE_DATA_SEPARATOR = "♣";

@ -1,6 +1,6 @@
name: CrossServerSync name: HuskSync
version: @version@ version: @version@
main: me.william278.crossserversync.CrossServerSyncBungeeCord main: me.william278.husksync.HuskSyncBungeeCord
author: William278 author: William278
description: 'Synchronize data cross-server' description: 'Synchronize data cross-server'
libraries: libraries:

@ -1,6 +1,6 @@
name: CrossServerSync name: CrossServerSync
version: @version@ version: @version@
main: me.william278.crossserversync.CrossServerSyncBukkit main: me.william278.husksync.HuskSyncBukkit
api-version: 1.16 api-version: 1.16
author: William278 author: William278
description: 'Synchronize data cross-server' description: 'Synchronize data cross-server'

@ -6,7 +6,7 @@ dependencies {
shadowJar { shadowJar {
destinationDirectory.set(file("$rootDir/target/")) destinationDirectory.set(file("$rootDir/target/"))
archiveBaseName.set('CrossServerSync') archiveBaseName.set('HuskSync')
archiveClassifier.set('') archiveClassifier.set('')
build { build {
@ -18,7 +18,7 @@ publishing {
publications { publications {
mavenJava(MavenPublication) { mavenJava(MavenPublication) {
groupId = 'me.William278' groupId = 'me.William278'
artifactId = 'CrossServerSync-plugin' artifactId = 'HuskSync-plugin'
version = "$project.version" version = "$project.version"
artifact shadowJar artifact shadowJar

@ -4,7 +4,7 @@ pluginManagement {
} }
} }
rootProject.name = 'CrossServerSync' rootProject.name = 'HuskSync'
include 'common' include 'common'
include 'bukkit' include 'bukkit'

Loading…
Cancel
Save