9
0
mirror of https://github.com/WiIIiam278/HuskSync.git synced 2025-12-23 08:39:19 +00:00
Files
HuskSync/bukkit/src/main/java/net/william278/husksync/BukkitHuskSync.java

321 lines
14 KiB
Java

package net.william278.husksync;
import dev.dejvokep.boostedyaml.YamlDocument;
import dev.dejvokep.boostedyaml.dvs.versioning.BasicVersioning;
import dev.dejvokep.boostedyaml.settings.dumper.DumperSettings;
import dev.dejvokep.boostedyaml.settings.general.GeneralSettings;
import dev.dejvokep.boostedyaml.settings.loader.LoaderSettings;
import dev.dejvokep.boostedyaml.settings.updater.UpdaterSettings;
import net.william278.husksync.command.BukkitCommand;
import net.william278.husksync.command.BukkitCommandType;
import net.william278.husksync.command.Permission;
import net.william278.husksync.config.Locales;
import net.william278.husksync.config.Settings;
import net.william278.husksync.data.CompressedDataAdapter;
import net.william278.husksync.data.DataAdapter;
import net.william278.husksync.data.JsonDataAdapter;
import net.william278.husksync.database.Database;
import net.william278.husksync.database.MySqlDatabase;
import net.william278.husksync.editor.DataEditor;
import net.william278.husksync.event.BukkitEventCannon;
import net.william278.husksync.event.EventCannon;
import net.william278.husksync.hook.PlanHook;
import net.william278.husksync.listener.BukkitEventListener;
import net.william278.husksync.listener.EventListener;
import net.william278.husksync.migrator.LegacyMigrator;
import net.william278.husksync.migrator.Migrator;
import net.william278.husksync.migrator.MpdbMigrator;
import net.william278.husksync.player.BukkitPlayer;
import net.william278.husksync.player.OnlineUser;
import net.william278.husksync.redis.RedisManager;
import net.william278.husksync.util.*;
import org.bukkit.Bukkit;
import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Player;
import org.bukkit.permissions.PermissionDefault;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.logging.Level;
import java.util.stream.Collectors;
public class BukkitHuskSync extends JavaPlugin implements HuskSync {
private Database database;
private RedisManager redisManager;
private Logger logger;
private ResourceReader resourceReader;
private EventListener eventListener;
private DataAdapter dataAdapter;
private DataEditor dataEditor;
private EventCannon eventCannon;
private Settings settings;
private Locales locales;
private List<Migrator> availableMigrators;
private static BukkitHuskSync instance;
/**
* (<b>Internal use only)</b> Returns the instance of the implementing Bukkit plugin
*
* @return the instance of the Bukkit plugin
*/
public static BukkitHuskSync getInstance() {
return instance;
}
@Override
public void onLoad() {
instance = this;
}
@Override
public void onEnable() {
// Process initialization stages
CompletableFuture.supplyAsync(() -> {
// Set the logging adapter and resource reader
this.logger = new BukkitLogger(this.getLogger());
this.resourceReader = new BukkitResourceReader(this);
// Load settings and locales
getLoggingAdapter().log(Level.INFO, "Loading plugin configuration settings & locales...");
return reload().thenApply(loadedSettings -> {
if (loadedSettings) {
logger.showDebugLogs(settings.getBooleanValue(Settings.ConfigOption.DEBUG_LOGGING));
getLoggingAdapter().log(Level.INFO, "Successfully loaded plugin configuration settings & locales");
} else {
getLoggingAdapter().log(Level.SEVERE, "Failed to load plugin configuration settings and/or locales");
}
return loadedSettings;
}).join();
}).thenApply(succeeded -> {
// Prepare data adapter
if (succeeded) {
if (settings.getBooleanValue(Settings.ConfigOption.SYNCHRONIZATION_COMPRESS_DATA)) {
dataAdapter = new CompressedDataAdapter();
} else {
dataAdapter = new JsonDataAdapter();
}
}
return succeeded;
}).thenApply(succeeded -> {
// Prepare event cannon
if (succeeded) {
eventCannon = new BukkitEventCannon();
}
return succeeded;
}).thenApply(succeeded -> {
// Prepare data editor
if (succeeded) {
dataEditor = new DataEditor(locales);
}
return succeeded;
}).thenApply(succeeded -> {
// Prepare migrators
if (succeeded) {
logger.debug("m0");
availableMigrators = new ArrayList<>();
logger.debug("m1");
availableMigrators.add(new LegacyMigrator(this));
logger.debug("m2");
final Plugin mySqlPlayerDataBridge = Bukkit.getPluginManager().getPlugin("MySqlPlayerDataBridge");
logger.debug("m3");
if (mySqlPlayerDataBridge != null) {
logger.debug("m4");
availableMigrators.add(new MpdbMigrator(this, mySqlPlayerDataBridge));
logger.debug("m5");
}
logger.debug("m6 - Successfully prepared migrators");
}
return succeeded;
}).thenApply(succeeded -> {
// Establish connection to the database
if (succeeded) {
this.database = new MySqlDatabase(settings, resourceReader, logger, dataAdapter, eventCannon);
getLoggingAdapter().log(Level.INFO, "Attempting to establish connection to the database...");
final CompletableFuture<Boolean> databaseConnectFuture = new CompletableFuture<>();
Bukkit.getScheduler().runTask(this, () -> {
final boolean initialized = this.database.initialize();
if (!initialized) {
getLoggingAdapter().log(Level.SEVERE, "Failed to establish a connection to the database. " + "Please check the supplied database credentials in the config file");
databaseConnectFuture.completeAsync(() -> false);
return;
}
getLoggingAdapter().log(Level.INFO, "Successfully established a connection to the database");
databaseConnectFuture.completeAsync(() -> true);
});
return databaseConnectFuture.join();
}
return false;
}).thenApply(succeeded -> {
// Establish connection to the Redis server
if (succeeded) {
this.redisManager = new RedisManager(this);
getLoggingAdapter().log(Level.INFO, "Attempting to establish connection to the Redis server...");
return this.redisManager.initialize().thenApply(initialized -> {
if (!initialized) {
getLoggingAdapter().log(Level.SEVERE, "Failed to establish a connection to the Redis server. " + "Please check the supplied Redis credentials in the config file");
return false;
}
getLoggingAdapter().log(Level.INFO, "Successfully established a connection to the Redis server");
return true;
}).join();
}
return false;
}).thenApply(succeeded -> {
// Register events
if (succeeded) {
getLoggingAdapter().log(Level.INFO, "Registering events...");
this.eventListener = new BukkitEventListener(this);
getLoggingAdapter().log(Level.INFO, "Successfully registered events listener");
}
return succeeded;
}).thenApply(succeeded -> {
// Register permissions
if (succeeded) {
getLoggingAdapter().log(Level.INFO, "Registering permissions & commands...");
Arrays.stream(Permission.values()).forEach(permission -> getServer().getPluginManager().addPermission(new org.bukkit.permissions.Permission(permission.node, switch (permission.defaultAccess) {
case EVERYONE -> PermissionDefault.TRUE;
case NOBODY -> PermissionDefault.FALSE;
case OPERATORS -> PermissionDefault.OP;
})));
// Register commands
for (final BukkitCommandType bukkitCommandType : BukkitCommandType.values()) {
final PluginCommand pluginCommand = getCommand(bukkitCommandType.commandBase.command);
if (pluginCommand != null) {
new BukkitCommand(bukkitCommandType.commandBase, this).register(pluginCommand);
}
}
getLoggingAdapter().log(Level.INFO, "Successfully registered permissions & commands");
}
return succeeded;
}).thenApply(succeeded -> {
if (succeeded && Bukkit.getPluginManager().getPlugin("Plan") != null) {
getLoggingAdapter().log(Level.INFO, "Enabling Plan integration...");
new PlanHook(database, logger).hookIntoPlan();
getLoggingAdapter().log(Level.INFO, "Plan integration enabled!");
}
return succeeded;
}).thenApply(succeeded -> {
// Check for updates
if (succeeded && settings.getBooleanValue(Settings.ConfigOption.CHECK_FOR_UPDATES)) {
getLoggingAdapter().log(Level.INFO, "Checking for updates...");
new UpdateChecker(getPluginVersion(), getLoggingAdapter()).logToConsole();
}
return succeeded;
}).thenAccept(succeeded -> {
// Handle failed initialization
if (!succeeded) {
getLoggingAdapter().log(Level.SEVERE, "Failed to initialize HuskSync. The plugin will now be disabled");
getServer().getPluginManager().disablePlugin(this);
} else {
getLoggingAdapter().log(Level.INFO, "Successfully enabled HuskSync v" + getPluginVersion());
}
}).exceptionally(exception -> {
getLoggingAdapter().log(Level.SEVERE, "An exception occurred initializing HuskSync. (" + exception.getMessage() + ") The plugin will now be disabled.");
exception.printStackTrace();
getServer().getPluginManager().disablePlugin(this);
return null;
});
}
@Override
public void onDisable() {
if (this.eventListener != null) {
this.eventListener.handlePluginDisable();
}
getLoggingAdapter().log(Level.INFO, "Successfully disabled HuskSync v" + getPluginVersion());
}
@Override
public @NotNull Set<OnlineUser> getOnlineUsers() {
return Bukkit.getOnlinePlayers().stream().map(BukkitPlayer::adapt).collect(Collectors.toSet());
}
@Override
public @NotNull Optional<OnlineUser> getOnlineUser(@NotNull UUID uuid) {
final Player player = Bukkit.getPlayer(uuid);
if (player == null) {
return Optional.empty();
}
return Optional.of(BukkitPlayer.adapt(player));
}
@Override
public @NotNull Database getDatabase() {
return database;
}
@Override
public @NotNull RedisManager getRedisManager() {
return redisManager;
}
@Override
public @NotNull DataAdapter getDataAdapter() {
return dataAdapter;
}
@Override
public @NotNull DataEditor getDataEditor() {
return dataEditor;
}
@Override
public @NotNull EventCannon getEventCannon() {
return eventCannon;
}
@NotNull
@Override
public List<Migrator> getAvailableMigrators() {
return availableMigrators;
}
@Override
public @NotNull Settings getSettings() {
return settings;
}
@Override
public @NotNull Locales getLocales() {
return locales;
}
@Override
public @NotNull Logger getLoggingAdapter() {
return logger;
}
@Override
public @NotNull Version getPluginVersion() {
return Version.pluginVersion(getDescription().getVersion());
}
@Override
public @NotNull Version getMinecraftVersion() {
return Version.minecraftVersion(Bukkit.getBukkitVersion());
}
@Override
public CompletableFuture<Boolean> reload() {
return CompletableFuture.supplyAsync(() -> {
try {
this.settings = Settings.load(YamlDocument.create(new File(getDataFolder(), "config.yml"), Objects.requireNonNull(resourceReader.getResource("config.yml")), GeneralSettings.builder().setUseDefaults(false).build(), LoaderSettings.builder().setAutoUpdate(true).build(), DumperSettings.builder().setEncoding(DumperSettings.Encoding.UNICODE).build(), UpdaterSettings.builder().setVersioning(new BasicVersioning("config_version")).build()));
this.locales = Locales.load(YamlDocument.create(new File(getDataFolder(), "messages-" + settings.getStringValue(Settings.ConfigOption.LANGUAGE) + ".yml"), Objects.requireNonNull(resourceReader.getResource("locales/" + settings.getStringValue(Settings.ConfigOption.LANGUAGE) + ".yml"))));
return true;
} catch (IOException | NullPointerException e) {
getLoggingAdapter().log(Level.SEVERE, "Failed to load data from the config", e);
return false;
}
});
}
}