You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
HuskSync/velocity/src/main/java/me/william278/husksync/HuskSyncVelocity.java

225 lines
7.6 KiB
Java

package me.william278.husksync;
import com.google.inject.Inject;
import com.google.inject.Provides;
import com.velocitypowered.api.command.CommandManager;
import com.velocitypowered.api.command.CommandMeta;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
import com.velocitypowered.api.event.proxy.ProxyShutdownEvent;
import com.velocitypowered.api.plugin.Plugin;
import com.velocitypowered.api.plugin.annotation.DataDirectory;
import com.velocitypowered.api.proxy.ProxyServer;
import me.william278.husksync.migrator.MPDBMigrator;
import me.william278.husksync.proxy.data.DataManager;
import me.william278.husksync.redis.RedisMessage;
import me.william278.husksync.velocity.util.VelocityUpdateChecker;
import me.william278.husksync.velocity.command.VelocityCommand;
import me.william278.husksync.velocity.config.ConfigLoader;
import me.william278.husksync.velocity.config.ConfigManager;
import me.william278.husksync.velocity.listener.VelocityEventListener;
import me.william278.husksync.velocity.listener.VelocityRedisListener;
import me.william278.husksync.velocity.util.VelocityLogger;
import net.byteflux.libby.Library;
import net.byteflux.libby.VelocityLibraryManager;
import org.bstats.velocity.Metrics;
import org.slf4j.Logger;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.HashSet;
import java.util.Objects;
import java.util.logging.Level;
import static me.william278.husksync.HuskSyncVelocity.VERSION;
@Plugin(
id = "husksync",
name = "HuskSync",
version = VERSION,
description = "HuskSync for velocity",
authors = {"William278"}
)
public class HuskSyncVelocity {
// Plugin version
public static final String VERSION = "1.2-dev";
// Velocity bStats ID (different from Bukkit and BungeeCord)
private static final int METRICS_ID = 13489;
private final Metrics.Factory metricsFactory;
private static HuskSyncVelocity instance;
public static HuskSyncVelocity getInstance() {
return instance;
}
// Whether the plugin is ready to accept redis messages
public static boolean readyForRedis = false;
// Whether the plugin is in the process of disabling and should skip responding to handshake confirmations
public static boolean isDisabling = false;
/**
* Set of all the {@link Server}s that have completed the synchronisation handshake with HuskSync on the proxy
*/
public static HashSet<Server> synchronisedServers;
public static DataManager dataManager;
public static MPDBMigrator mpdbMigrator;
private final Logger logger;
private final ProxyServer server;
private final Path dataDirectory;
private final VelocityLibraryManager<HuskSyncVelocity> manager;
// Get the data folder
public File getDataFolder() {
return dataDirectory.toFile();
}
// Get the proxy server
public ProxyServer getProxyServer() {
return server;
}
// Velocity logger handling
private VelocityLogger velocityLogger;
public VelocityLogger getVelocityLogger() {
return velocityLogger;
}
@Inject
public HuskSyncVelocity(ProxyServer server, Logger logger, @DataDirectory Path dataDirectory, Metrics.Factory metricsFactory, VelocityLibraryManager<HuskSyncVelocity> manager) {
this.server = server;
this.logger = logger;
this.dataDirectory = dataDirectory;
this.metricsFactory = metricsFactory;
this.manager = manager;
fetchDependencies();
}
@Subscribe
public void onProxyInitialization(ProxyInitializeEvent event) {
// Set instance
instance = this;
// Setup logger
velocityLogger = new VelocityLogger(logger);
// Prepare synchronised servers tracker
synchronisedServers = new HashSet<>();
// Load config
ConfigManager.loadConfig();
// Load settings from config
ConfigLoader.loadSettings(Objects.requireNonNull(ConfigManager.getConfig()));
// Load messages
ConfigManager.loadMessages();
// Load locales from messages
ConfigLoader.loadMessageStrings(Objects.requireNonNull(ConfigManager.getMessages()));
// Do update checker
if (Settings.automaticUpdateChecks) {
new VelocityUpdateChecker(VERSION).logToConsole();
}
// Setup data manager
dataManager = new DataManager(getVelocityLogger(), getDataFolder());
// Ensure the data manager initialized correctly
if (dataManager.hasFailedInitialization) {
getVelocityLogger().severe("Failed to initialize the HuskSync database(s).\n" +
"HuskSync will now abort loading itself (Velocity) v" + VERSION);
}
// Setup player data cache
for (Settings.SynchronisationCluster cluster : Settings.clusters) {
dataManager.playerDataCache.put(cluster, new DataManager.PlayerDataCache());
}
// Initialize the redis listener
if (!new VelocityRedisListener().isActiveAndEnabled) {
getVelocityLogger().severe("Failed to initialize Redis; HuskSync will now abort loading itself (Velocity) v" + VERSION);
return;
}
// Register listener
server.getEventManager().register(this, new VelocityEventListener());
// Register command
CommandManager commandManager = getProxyServer().getCommandManager();
CommandMeta meta = commandManager.metaBuilder("husksync")
.aliases("hs")
.build();
commandManager.register(meta, new VelocityCommand());
// Prepare the migrator for use if needed
mpdbMigrator = new MPDBMigrator(getVelocityLogger());
// Initialize bStats metrics
try {
metricsFactory.make(this, METRICS_ID);
} catch (Exception e) {
getVelocityLogger().info("Skipped metrics initialization");
}
// Log to console
getVelocityLogger().info("Enabled HuskSync (Velocity) v" + VERSION);
// Mark as ready for redis message processing
readyForRedis = true;
}
@Subscribe
public void onProxyShutdown(ProxyShutdownEvent event) {
// Plugin shutdown logic
isDisabling = true;
// Send terminating handshake message
for (Server server : synchronisedServers) {
try {
new RedisMessage(RedisMessage.MessageType.TERMINATE_HANDSHAKE,
new RedisMessage.MessageTarget(Settings.ServerType.BUKKIT, null, server.clusterId()),
server.serverUUID().toString(),
"Velocity").send();
} catch (IOException e) {
getVelocityLogger().log(Level.SEVERE, "Failed to serialize Redis message for handshake termination", e);
}
}
// Close database connections
dataManager.closeDatabases();
// Log to console
getVelocityLogger().info("Disabled HuskSync (Velocity) v" + VERSION);
}
// Load dependencies
private void fetchDependencies() {
Library mySqlLib = Library.builder()
.groupId("mysql")
.artifactId("mysql-connector-java")
.version("8.0.25")
.build();
Library sqLiteLib = Library.builder()
.groupId("org.xerial")
.artifactId("sqlite-jdbc")
.version("3.36.0.3")
.build();
manager.addMavenCentral();
manager.loadLibrary(mySqlLib);
manager.loadLibrary(sqLiteLib);
}
}