diff --git a/build.gradle b/build.gradle index 4706fbc6..c6e91735 100644 --- a/build.gradle +++ b/build.gradle @@ -8,6 +8,11 @@ group = 'org.mvplugins.multiverse.inventories' description = 'Multiverse-Inventories' repositories { + maven { + name = 'codemc' + url = uri('https://repo.codemc.org/repository/maven-releases') + } + maven { name = 'benwoo1110' url = uri('https://repo.c0ding.party/multiverse-beta') @@ -15,7 +20,7 @@ repositories { } configure(apiDependencies) { - serverApiVersion = '1.21.4-R0.1-SNAPSHOT' + serverApiVersion = '1.21.3-R0.1-SNAPSHOT' mockBukkitServerApiVersion = '1.21' mockBukkitVersion = '4.31.1' } @@ -35,10 +40,14 @@ dependencies { } // Other plugins for import - externalPlugin('uk.co:MultiInv:3.0.6') { + compileOnly('uk.co:MultiInv:3.0.6') { + exclude group: '*', module: '*' + } + compileOnly('me.drayshak:WorldInventories:1.0.2') { exclude group: '*', module: '*' } - externalPlugin('me.drayshak:WorldInventories:1.0.2') { + // perworldinventory is weird and has snakeyaml included in the jar, so we can only use compileOnly for build to work properly + compileOnly('me.ebonjaeger:perworldinventory-kt:2.3.2') { exclude group: '*', module: '*' } diff --git a/src/main/java/org/mvplugins/multiverse/inventories/MultiverseInventories.java b/src/main/java/org/mvplugins/multiverse/inventories/MultiverseInventories.java index 5113bbbe..c666d2bf 100644 --- a/src/main/java/org/mvplugins/multiverse/inventories/MultiverseInventories.java +++ b/src/main/java/org/mvplugins/multiverse/inventories/MultiverseInventories.java @@ -11,12 +11,13 @@ import org.mvplugins.multiverse.core.utils.StringFormatter; import org.mvplugins.multiverse.inventories.commands.InventoriesCommand; import org.mvplugins.multiverse.inventories.config.InventoriesConfig; +import org.mvplugins.multiverse.inventories.dataimport.DataImportManager; +import org.mvplugins.multiverse.inventories.dataimport.DataImporter; import org.mvplugins.multiverse.inventories.listeners.InventoriesListener; import org.mvplugins.multiverse.inventories.listeners.SpawnChangeListener; import org.mvplugins.multiverse.inventories.locale.Message; import org.mvplugins.multiverse.inventories.locale.Messager; import org.mvplugins.multiverse.inventories.locale.Messaging; -import org.mvplugins.multiverse.inventories.migration.ImportManager; import org.mvplugins.multiverse.inventories.profile.PersistingProfile; import org.mvplugins.multiverse.inventories.profile.ProfileDataSource; import org.mvplugins.multiverse.inventories.profile.container.ContainerType; @@ -24,17 +25,13 @@ import org.mvplugins.multiverse.inventories.profile.group.WorldGroupManager; import org.mvplugins.multiverse.inventories.share.Sharables; import org.mvplugins.multiverse.inventories.util.Perm; -import me.drayshak.WorldInventories.WorldInventories; import org.bukkit.Bukkit; -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.PluginManager; import org.mvplugins.multiverse.core.commandtools.MVCommandManager; import org.mvplugins.multiverse.core.inject.PluginServiceLocator; import org.mvplugins.multiverse.external.jakarta.inject.Inject; import org.mvplugins.multiverse.external.jakarta.inject.Provider; import org.jvnet.hk2.annotations.Service; import org.mvplugins.multiverse.external.vavr.control.Try; -import uk.co.tggl.pluckerpluck.multiinv.MultiInv; /** * Multiverse-Inventories plugin main class. @@ -59,7 +56,7 @@ public class MultiverseInventories extends MultiversePlugin implements Messaging @Inject private Provider profileContainerStoreProvider; @Inject - private Provider importManager; + private Provider dataImportManager; private PluginServiceLocator serviceLocator; private Messager messager = new DefaultMessager(this); @@ -86,9 +83,9 @@ public void onLoad() { public final void onEnable() { super.onEnable(); initializeDependencyInjection(); + Logging.setDebugLevel(mvCoreConfig.get().getGlobalDebug()); inventoriesConfig.get().load().onFailure(e -> Logging.severe(e.getMessage())); - Logging.setDebugLevel(mvCoreConfig.get().getGlobalDebug()); this.onMVPluginEnable(); Logging.config("Version %s (API v%s) Enabled - By %s", this.getDescription().getVersion(), getTargetCoreProtocolVersion(), StringFormatter.joinAnd(this.getDescription().getAuthors())); @@ -174,15 +171,9 @@ private void registerCommands() { } private void hookImportables() { - final PluginManager pm = Bukkit.getPluginManager(); - Plugin plugin = pm.getPlugin("MultiInv"); - if (plugin != null) { - importManager.get().hookMultiInv((MultiInv) plugin); - } - plugin = pm.getPlugin("WorldInventories"); - if (plugin != null) { - importManager.get().hookWorldInventories((WorldInventories) plugin); - } + serviceLocator.getAllServices(DataImporter.class).forEach(dataImporter -> { + dataImportManager.get().register(dataImporter); + }); } /** @@ -207,6 +198,8 @@ public PluginServiceLocator getServiceLocator() { @Override public void reloadConfig() { try { + Logging.setDebugLevel(mvCoreConfig.get().getGlobalDebug()); + inventoriesConfig.get().load().onFailure(e -> { Logging.severe("Failed to load config file!"); Logging.severe(e.getMessage()); diff --git a/src/main/java/org/mvplugins/multiverse/inventories/commands/ImportCommand.java b/src/main/java/org/mvplugins/multiverse/inventories/commands/ImportCommand.java new file mode 100644 index 00000000..f7c2e6eb --- /dev/null +++ b/src/main/java/org/mvplugins/multiverse/inventories/commands/ImportCommand.java @@ -0,0 +1,74 @@ +package org.mvplugins.multiverse.inventories.commands; + +import org.jetbrains.annotations.NotNull; +import org.jvnet.hk2.annotations.Service; +import org.mvplugins.multiverse.core.commandtools.MVCommandIssuer; +import org.mvplugins.multiverse.core.commandtools.MVCommandManager; +import org.mvplugins.multiverse.core.commandtools.queue.CommandQueueManager; +import org.mvplugins.multiverse.core.commandtools.queue.CommandQueuePayload; +import org.mvplugins.multiverse.core.locale.message.Message; +import org.mvplugins.multiverse.external.acf.commands.annotation.CommandAlias; +import org.mvplugins.multiverse.external.acf.commands.annotation.CommandCompletion; +import org.mvplugins.multiverse.external.acf.commands.annotation.CommandPermission; +import org.mvplugins.multiverse.external.acf.commands.annotation.Description; +import org.mvplugins.multiverse.external.acf.commands.annotation.Single; +import org.mvplugins.multiverse.external.acf.commands.annotation.Subcommand; +import org.mvplugins.multiverse.external.acf.commands.annotation.Syntax; +import org.mvplugins.multiverse.external.jakarta.inject.Inject; +import org.mvplugins.multiverse.inventories.dataimport.DataImportManager; +import org.mvplugins.multiverse.inventories.dataimport.DataImporter; + +import static org.mvplugins.multiverse.core.locale.message.MessageReplacement.replace; + +@Service +@CommandAlias("mvinv") +final class ImportCommand extends InventoriesCommand { + + private final DataImportManager dataImportManager; + private final CommandQueueManager commandQueueManager; + + @Inject + ImportCommand( + @NotNull MVCommandManager commandManager, + @NotNull DataImportManager dataImportManager, + @NotNull CommandQueueManager commandQueueManager) { + super(commandManager); + this.dataImportManager = dataImportManager; + this.commandQueueManager = commandQueueManager; + } + + @Subcommand("import") + @Syntax("") + @CommandPermission("multiverse.inventories.import") + @CommandCompletion("MultiInv|WorldInventories|PerWorldInventory") + @Description("Import inventories from MultiInv/WorldInventories/PerWorldInventory plugin.") + public void onImportCommand( + MVCommandIssuer issuer, + + @Single + @Syntax("") + String pluginName) { + + dataImportManager.getImporter(pluginName) + .onEmpty(() -> issuer.sendMessage("No importer found for " + pluginName)) + .peek(dataImporter -> { + if (!dataImporter.isEnabled()) { + issuer.sendMessage("Plugin " + pluginName + " is not running on your server!"); + return; + } + commandQueueManager.addToQueue(CommandQueuePayload.issuer(issuer) + .prompt(Message.of("Are you sure you want to import data from {plugin}? " + + "This will override existing Multiverse-Inventories playerdata!!!", + replace("{plugin}").with(pluginName))) + .action(() -> doDataImport(issuer, dataImporter))); + }); + } + + void doDataImport(MVCommandIssuer issuer, DataImporter dataImporter) { + if (dataImporter.importData()) { + issuer.sendMessage("Successfully to imported data from " + dataImporter.getPluginName() + "!"); + } else { + issuer.sendMessage("Failed to import data from " + dataImporter.getPluginName() + "."); + } + } +} diff --git a/src/main/java/org/mvplugins/multiverse/inventories/dataimport/AbstractDataImporter.java b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/AbstractDataImporter.java new file mode 100644 index 00000000..a399506d --- /dev/null +++ b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/AbstractDataImporter.java @@ -0,0 +1,124 @@ +package org.mvplugins.multiverse.inventories.dataimport; + +import com.dumptruckman.minecraft.util.Logging; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; +import org.jvnet.hk2.annotations.Contract; + +/** + * Abstract implementation of {@link DataImporter} without actual import logic. + */ +@Contract +public abstract class AbstractDataImporter implements DataImporter { + + protected Plugin importer = null; + + public AbstractDataImporter() { + } + + /** + * Logic that does the actual importing data. + * + * @throws DataImportException Errors occurred that caused import to fail. + */ + protected abstract void doDataImport() throws DataImportException; + + /** + * {@inheritDoc} + */ + @Override + public boolean importData(boolean disableOnSuccess) { + if (!isEnabled()) { + Logging.severe("Data importer %s not enabled. No data is imported.", this.getPluginName()); + return false; + } + + try { + doDataImport(); + } catch (DataImportException e) { + Logging.severe(e.getMessage()); + if(e.getCauseException() != null) { + Logging.severe("Cause: %s", e.getCauseException().getMessage()); + } + e.printStackTrace(); + return false; + } + + Logging.info("Successfully imported data from %s!", this.getPluginName()); + if (disableOnSuccess) { + Logging.info("Disabling %s...", this.getPluginName()); + Bukkit.getPluginManager().disablePlugin(this.importer); + } + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean importData() { + return importData(true); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean enable(Plugin importerPlugin) { + if (isEnabled()) { + return false; + } + if (!importerPlugin.getClass().equals(this.getPluginClass())) { + Logging.warning("Plugin '%s' is not data importer for '%s'.", + importerPlugin.getClass().getName(), getPluginName()); + return false; + } + try { + this.importer = importerPlugin; + } catch (ClassCastException | NoClassDefFoundError e) { + Logging.warning("Error while enabling data importer for '%s'.", getPluginName()); + return false; + } + Logging.info("Successfully enabled data importer for '%s'.", getPluginName()); + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean enable() { + Plugin importerPlugin = Bukkit.getPluginManager().getPlugin(this.getPluginName()); + if (importerPlugin == null) { + Logging.finer("Unable to get plugin '%s' for import hook.", this.getPluginName()); + return false; + } + return enable(importerPlugin); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean disable() { + this.importer = null; + Logging.info("Successfully disabled data importer for '%s'.", getPluginName()); + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isEnabled() { + return importer != null; + } + + /** + * {@inheritDoc} + */ + @Override + public Plugin getPlugin() { + return importer; + } +} diff --git a/src/main/java/org/mvplugins/multiverse/inventories/dataimport/DataImportException.java b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/DataImportException.java new file mode 100644 index 00000000..13cc563b --- /dev/null +++ b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/DataImportException.java @@ -0,0 +1,56 @@ +package org.mvplugins.multiverse.inventories.dataimport; + +import org.mvplugins.multiverse.core.exceptions.MultiverseException; +import org.mvplugins.multiverse.core.locale.message.Message; +import org.mvplugins.multiverse.external.jetbrains.annotations.Nullable; + +/** + * Exception thrown when migration doesn't go well. + */ +public class DataImportException extends MultiverseException { + + private Exception causeException = null; + + public DataImportException(@Nullable String message) { + super(message); + } + + public DataImportException(@Nullable String message, Exception causeException) { + super(message); + this.causeException = causeException; + } + + public DataImportException(@Nullable Message message, Exception causeException) { + super(message); + this.causeException = causeException; + } + + public DataImportException(@Nullable String message, @Nullable Throwable cause, Exception causeException) { + super(message, cause); + this.causeException = causeException; + } + + public DataImportException(@Nullable Message message, @Nullable Throwable cause, Exception causeException) { + super(message, cause); + this.causeException = causeException; + } + + /** + * Sets what the causing exception was, if any. + * + * @param exception The cause exception. + * @return This exception for easy chainability. + */ + public DataImportException setCauseException(Exception exception) { + this.causeException = exception; + return this; + } + + /** + * @return The causing exception or null if none. + */ + public Exception getCauseException() { + return this.causeException; + } +} + diff --git a/src/main/java/org/mvplugins/multiverse/inventories/dataimport/DataImportManager.java b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/DataImportManager.java new file mode 100644 index 00000000..4925b847 --- /dev/null +++ b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/DataImportManager.java @@ -0,0 +1,107 @@ +package org.mvplugins.multiverse.inventories.dataimport; + +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.server.PluginDisableEvent; +import org.bukkit.event.server.PluginEnableEvent; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginManager; +import org.jetbrains.annotations.NotNull; +import org.jvnet.hk2.annotations.Service; +import org.mvplugins.multiverse.external.jakarta.inject.Inject; +import org.mvplugins.multiverse.external.vavr.control.Option; +import org.mvplugins.multiverse.inventories.MultiverseInventories; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * Manager class for importing data from other inventory plugins or similar, e.g. PerWorldInventory. + */ +@Service +public final class DataImportManager implements Listener { + + final private Map dataImporters; + + @Inject + DataImportManager(@NotNull MultiverseInventories inventories, @NotNull PluginManager pluginManager) { + this.dataImporters = new HashMap<>(); + pluginManager.registerEvents(this, inventories); + } + + /** + * Register a Data Importer and optionally try to enable to it as well. + * + * @param dataImporter The Data Importer to register. + * @param tryEnable Whether to try and {@link DataImporter#enable(Plugin)} the Data Importer. + */ + public void register(DataImporter dataImporter, boolean tryEnable) { + this.dataImporters.put(dataImporter.getPluginName().toLowerCase(), dataImporter); + if (tryEnable) { + dataImporter.enable(); + } + } + + /** + * Register a Data Importer and try to enable to it as well. + * + * @param dataImporter The Data Importer to register. + */ + public void register(DataImporter dataImporter) { + this.register(dataImporter, true); + } + + /** + * Gets a {@link DataImporter} based on an importable plugin name. + * + * @param pluginName The plugin name you want to import data from. + * @return The {@link DataImporter} if Data Importer present for that plugin, else null. + */ + public Option getImporter(String pluginName) { + return Option.of(this.dataImporters.get(pluginName.toLowerCase())); + } + + /** + * Gets a {@link DataImporter} based on an importable {@link Plugin}. + * + * @param plugin The plugin you want to import data from. + * @return The {@link DataImporter} if Data Importer present for that plugin, else null. + */ + public Option getImporter(Plugin plugin) { + return getImporter(plugin.getName()); + } + + /** + * Gets all the Data Importer names that are enabled. + * + * @return A collection of Data Importer names that are enabled. + */ + public Collection getEnabledImporterNames() { + return this.dataImporters.values().stream() + .filter(DataImporter::isEnabled) + .map(DataImporter::getPluginName) + .collect(Collectors.toList()); + } + + /** + * Called when a plugin is enabled. + * + * @param event The plugin enable event. + */ + @EventHandler + private void pluginEnable(PluginEnableEvent event) { + getImporter(event.getPlugin()).peek(dataImporter -> dataImporter.enable(event.getPlugin())); + } + + /** + * Called when a plugin is disabled. + * + * @param event The plugin disable event. + */ + @EventHandler + private void pluginDisable(PluginDisableEvent event) { + getImporter(event.getPlugin()).peek(DataImporter::disable); + } +} diff --git a/src/main/java/org/mvplugins/multiverse/inventories/dataimport/DataImporter.java b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/DataImporter.java new file mode 100644 index 00000000..40d540f7 --- /dev/null +++ b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/DataImporter.java @@ -0,0 +1,73 @@ +package org.mvplugins.multiverse.inventories.dataimport; + +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jvnet.hk2.annotations.Contract; + +/** + * Interface for data migration importers. + */ +@Contract +public interface DataImporter { + + /** + * Imports the data from another plugin and optionally disable it after successful import. + * + * @param disableOnSuccess Whether to disable the importer plugin after a successful import. + * @return True if data import is successful, else false. + */ + boolean importData(boolean disableOnSuccess); + + /** + * Imports the data from another plugin and disabled it upon success so Multiverse inventories + * can work without conflicts. + * + * @return True if data import is successful, else false. + */ + boolean importData(); + + /** + * Hooks plugin for importing its data. Needs plugin class of {@link #getPluginClass()}. + * + * @param plugin The target plugin instance to hook. + * @return True if successfully enabled, else false. + */ + boolean enable(Plugin plugin); + + /** + * Hooks plugin for importing its data. Needs plugin class of {@link #getPluginClass()}. + * + * @return True if successfully enabled, else false. + */ + boolean enable(); + + /** + * Unhook plugin from this Data Importer. + * + * @return True if successfully disabled, else false. + */ + boolean disable(); + + /** + * Checks if this Data Importer has been {@link #enable(Plugin)} successfully. + * + * @return True if is enabled, else false. + */ + boolean isEnabled(); + + /** + * @return The plugin associated with this Data Importer, null if not enabled. + */ + @Nullable Plugin getPlugin(); + + /** + * @return The plugin name associated with this Data Importer. + */ + @NotNull String getPluginName(); + + /** + * @return The plugin class associated with this Data Importer. + */ + @NotNull Class getPluginClass(); +} diff --git a/src/main/java/org/mvplugins/multiverse/inventories/migration/multiinv/MIInventoryConverter.java b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/multiinv/MIInventoryConverter.java similarity index 89% rename from src/main/java/org/mvplugins/multiverse/inventories/migration/multiinv/MIInventoryConverter.java rename to src/main/java/org/mvplugins/multiverse/inventories/dataimport/multiinv/MIInventoryConverter.java index d4180de6..2cc77354 100644 --- a/src/main/java/org/mvplugins/multiverse/inventories/migration/multiinv/MIInventoryConverter.java +++ b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/multiinv/MIInventoryConverter.java @@ -1,4 +1,4 @@ -package org.mvplugins.multiverse.inventories.migration.multiinv; +package org.mvplugins.multiverse.inventories.dataimport.multiinv; import org.mvplugins.multiverse.inventories.util.MinecraftTools; import org.bukkit.inventory.ItemStack; @@ -7,7 +7,7 @@ /** * Utility class for converting proprietary shit from MultiInv. */ -public class MIInventoryConverter { +final class MIInventoryConverter { /** * @param oldContents Proprietary shiet from MultiInv. diff --git a/src/main/java/org/mvplugins/multiverse/inventories/migration/multiinv/MIInventoryInterface.java b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/multiinv/MIInventoryInterface.java similarity index 67% rename from src/main/java/org/mvplugins/multiverse/inventories/migration/multiinv/MIInventoryInterface.java rename to src/main/java/org/mvplugins/multiverse/inventories/dataimport/multiinv/MIInventoryInterface.java index 9259bd90..980e649b 100644 --- a/src/main/java/org/mvplugins/multiverse/inventories/migration/multiinv/MIInventoryInterface.java +++ b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/multiinv/MIInventoryInterface.java @@ -1,11 +1,11 @@ -package org.mvplugins.multiverse.inventories.migration.multiinv; +package org.mvplugins.multiverse.inventories.dataimport.multiinv; import org.bukkit.inventory.ItemStack; /** * A little interface for retrieving normal ItemStack from the MultiInv inventory classes. */ -public interface MIInventoryInterface { +sealed interface MIInventoryInterface permits MIInventoryWrapper, MIInventoryOldWrapper { /** * @return The inventory contents. diff --git a/src/main/java/org/mvplugins/multiverse/inventories/migration/multiinv/MIInventoryOldWrapper.java b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/multiinv/MIInventoryOldWrapper.java similarity index 78% rename from src/main/java/org/mvplugins/multiverse/inventories/migration/multiinv/MIInventoryOldWrapper.java rename to src/main/java/org/mvplugins/multiverse/inventories/dataimport/multiinv/MIInventoryOldWrapper.java index 89b3b614..8f5d90d1 100644 --- a/src/main/java/org/mvplugins/multiverse/inventories/migration/multiinv/MIInventoryOldWrapper.java +++ b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/multiinv/MIInventoryOldWrapper.java @@ -1,4 +1,4 @@ -package org.mvplugins.multiverse.inventories.migration.multiinv; +package org.mvplugins.multiverse.inventories.dataimport.multiinv; import org.bukkit.inventory.ItemStack; import uk.co.tggl.pluckerpluck.multiinv.inventory.MIInventoryOld; @@ -6,7 +6,7 @@ /** * Wraps MIInventoryOld to provide a way of accessing the inventory/armor contents. */ -public class MIInventoryOldWrapper extends MIInventoryOld implements MIInventoryInterface { +final class MIInventoryOldWrapper extends MIInventoryOld implements MIInventoryInterface { public MIInventoryOldWrapper(String inventoryString) { super(inventoryString); diff --git a/src/main/java/org/mvplugins/multiverse/inventories/migration/multiinv/MIInventoryWrapper.java b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/multiinv/MIInventoryWrapper.java similarity index 79% rename from src/main/java/org/mvplugins/multiverse/inventories/migration/multiinv/MIInventoryWrapper.java rename to src/main/java/org/mvplugins/multiverse/inventories/dataimport/multiinv/MIInventoryWrapper.java index 7dadff75..b333eece 100644 --- a/src/main/java/org/mvplugins/multiverse/inventories/migration/multiinv/MIInventoryWrapper.java +++ b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/multiinv/MIInventoryWrapper.java @@ -1,4 +1,4 @@ -package org.mvplugins.multiverse.inventories.migration.multiinv; +package org.mvplugins.multiverse.inventories.dataimport.multiinv; import org.bukkit.inventory.ItemStack; import uk.co.tggl.pluckerpluck.multiinv.inventory.MIInventory; @@ -6,7 +6,7 @@ /** * Wraps MIInventory to provide a way of accessing the inventory/armor contents. */ -public class MIInventoryWrapper extends MIInventory implements MIInventoryInterface { +final class MIInventoryWrapper extends MIInventory implements MIInventoryInterface { public MIInventoryWrapper(String inventoryString) { super(inventoryString); diff --git a/src/main/java/org/mvplugins/multiverse/inventories/migration/multiinv/MIPlayerFileLoader.java b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/multiinv/MIPlayerFileLoader.java similarity index 97% rename from src/main/java/org/mvplugins/multiverse/inventories/migration/multiinv/MIPlayerFileLoader.java rename to src/main/java/org/mvplugins/multiverse/inventories/dataimport/multiinv/MIPlayerFileLoader.java index 03988746..97dc42de 100644 --- a/src/main/java/org/mvplugins/multiverse/inventories/migration/multiinv/MIPlayerFileLoader.java +++ b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/multiinv/MIPlayerFileLoader.java @@ -1,4 +1,4 @@ -package org.mvplugins.multiverse.inventories.migration.multiinv; +package org.mvplugins.multiverse.inventories.dataimport.multiinv; import org.mvplugins.multiverse.inventories.util.PlayerStats; import org.bukkit.OfflinePlayer; @@ -10,7 +10,7 @@ /** * A replacement for MultiInv's MIPlayerFile class so that it may accept an OfflinePlayer instead of Player. */ -public class MIPlayerFileLoader { +final class MIPlayerFileLoader { private final YamlConfiguration playerFile; private final File file; diff --git a/src/main/java/org/mvplugins/multiverse/inventories/migration/multiinv/MultiInvImporter.java b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/multiinv/MultiInvImportHelper.java similarity index 63% rename from src/main/java/org/mvplugins/multiverse/inventories/migration/multiinv/MultiInvImporter.java rename to src/main/java/org/mvplugins/multiverse/inventories/dataimport/multiinv/MultiInvImportHelper.java index 8770201a..b0639d94 100644 --- a/src/main/java/org/mvplugins/multiverse/inventories/migration/multiinv/MultiInvImporter.java +++ b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/multiinv/MultiInvImportHelper.java @@ -1,24 +1,21 @@ -package org.mvplugins.multiverse.inventories.migration.multiinv; +package org.mvplugins.multiverse.inventories.dataimport.multiinv; import com.dumptruckman.minecraft.util.Logging; -import org.mvplugins.multiverse.inventories.MultiverseInventories; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.OfflinePlayer; +import org.bukkit.World; +import org.jetbrains.annotations.NotNull; import org.mvplugins.multiverse.inventories.config.InventoriesConfig; +import org.mvplugins.multiverse.inventories.dataimport.DataImportException; +import org.mvplugins.multiverse.inventories.profile.PlayerProfile; import org.mvplugins.multiverse.inventories.profile.ProfileDataSource; -import org.mvplugins.multiverse.inventories.profile.container.ProfileContainerStore; -import org.mvplugins.multiverse.inventories.profile.container.ProfileContainerStoreProvider; -import org.mvplugins.multiverse.inventories.profile.group.WorldGroup; import org.mvplugins.multiverse.inventories.profile.ProfileTypes; import org.mvplugins.multiverse.inventories.profile.container.ContainerType; -import org.mvplugins.multiverse.inventories.profile.PlayerProfile; +import org.mvplugins.multiverse.inventories.profile.container.ProfileContainerStoreProvider; +import org.mvplugins.multiverse.inventories.profile.group.WorldGroup; import org.mvplugins.multiverse.inventories.profile.group.WorldGroupManager; import org.mvplugins.multiverse.inventories.share.Sharables; -import org.mvplugins.multiverse.inventories.migration.DataImporter; -import org.mvplugins.multiverse.inventories.migration.MigrationException; -import org.bukkit.Bukkit; -import org.bukkit.GameMode; -import org.bukkit.OfflinePlayer; -import org.bukkit.World; -import org.bukkit.plugin.Plugin; import uk.co.tggl.pluckerpluck.multiinv.MIYamlFiles; import uk.co.tggl.pluckerpluck.multiinv.MultiInv; @@ -26,52 +23,33 @@ import java.util.HashMap; import java.util.Map; -/** - * A class to help with importing data from MultiInv. - */ -public class MultiInvImporter implements DataImporter { +final class MultiInvImportHelper { - private final MultiInv miPlugin; - private final InventoriesConfig config; + @NotNull + private final MultiInv multiInv; private final WorldGroupManager worldGroupManager; + private final InventoriesConfig inventoriesConfig; + private final ProfileContainerStoreProvider profileContainerStoreProvider; private final ProfileDataSource profileDataSource; - private final ProfileContainerStore worldProfileContainerStore; - public MultiInvImporter(MultiverseInventories inventories, MultiInv miPlugin) { - this.miPlugin = miPlugin; - this.config = inventories.getServiceLocator().getService(InventoriesConfig.class); - this.worldGroupManager = inventories.getServiceLocator().getService(WorldGroupManager.class); - this.profileDataSource = inventories.getServiceLocator().getService(ProfileDataSource.class); - this.worldProfileContainerStore = inventories.getServiceLocator() - .getService(ProfileContainerStoreProvider.class) - .getStore(ContainerType.WORLD); + MultiInvImportHelper( + @NotNull MultiInv multiInv, + @NotNull WorldGroupManager worldGroupManager, + @NotNull InventoriesConfig inventoriesConfig, + @NotNull ProfileContainerStoreProvider profileContainerStoreProvider, + @NotNull ProfileDataSource profileDataSource) { + super(); + this.multiInv = multiInv; + this.worldGroupManager = worldGroupManager; + this.inventoriesConfig = inventoriesConfig; + this.profileContainerStoreProvider = profileContainerStoreProvider; + this.profileDataSource = profileDataSource; } - /** - * @return The MultiInv plugin hooked to the importer. - */ - public MultiInv getMIPlugin() { - return this.miPlugin; - } - - /** - * {@inheritDoc} - */ - @Override - public Plugin getPlugin() { - return this.getMIPlugin(); - } - - /** - * Imports the data from MultiInv. - * - * @throws MigrationException If there was any MAJOR issue loading the data. - */ - @Override - public void importData() throws MigrationException { + void importData() throws DataImportException { HashMap miGroupMap = this.getGroupMap(); if (miGroupMap == null) { - throw new MigrationException("There is no data to import from MultiInv!"); + throw new DataImportException("There is no data to import from MultiInv!"); } if (!miGroupMap.isEmpty()) { WorldGroup defaultWorldGroup = worldGroupManager.getDefaultGroup(); @@ -90,15 +68,14 @@ public void importData() throws MigrationException { } worldGroup.addWorld(groupEntry.getValue()); } - config.save(); + inventoriesConfig.save(); for (OfflinePlayer player : Bukkit.getServer().getOfflinePlayers()) { Logging.info("Processing MultiInv data for player: " + player.getName()); for (Map.Entry entry : miGroupMap.entrySet()) { String worldName = entry.getKey(); String groupName = entry.getValue(); - MIPlayerFileLoader playerFileLoader = - new MIPlayerFileLoader(this.getMIPlugin(), player, groupName); + MIPlayerFileLoader playerFileLoader = new MIPlayerFileLoader(multiInv, player, groupName); if (!playerFileLoader.load()) { continue; } @@ -108,8 +85,7 @@ public void importData() throws MigrationException { } for (World world : Bukkit.getWorlds()) { String worldName = world.getName(); - MIPlayerFileLoader playerFileLoader = - new MIPlayerFileLoader(this.getMIPlugin(), player, worldName); + MIPlayerFileLoader playerFileLoader = new MIPlayerFileLoader(multiInv, player, worldName); if (!playerFileLoader.load()) { continue; } @@ -118,24 +94,22 @@ public void importData() throws MigrationException { mergeData(player, playerFileLoader, worldName, ContainerType.WORLD); } } - - Logging.info("Import from MultiInv finished. Disabling MultiInv."); - Bukkit.getPluginManager().disablePlugin(this.getMIPlugin()); } private void mergeData(OfflinePlayer player, MIPlayerFileLoader playerFileLoader, String dataName, ContainerType type) { PlayerProfile playerProfile; if (type.equals(ContainerType.GROUP)) { - WorldGroup group = worldGroupManager.getGroup(dataName); + WorldGroup group = worldGroupManager + .getGroup(dataName); if (group == null) { Logging.warning("Could not import player data for group: " + dataName); return; } playerProfile = group.getGroupProfileContainer().getPlayerData(ProfileTypes.SURVIVAL, player); } else { - playerProfile = worldProfileContainerStore.getContainer(dataName) - .getPlayerData(ProfileTypes.SURVIVAL, player); + playerProfile = profileContainerStoreProvider.getStore(type) + .getContainer(dataName).getPlayerData(ProfileTypes.SURVIVAL, player); } MIInventoryInterface inventoryInterface = playerFileLoader.getInventory(GameMode.SURVIVAL.toString()); @@ -152,28 +126,24 @@ private void mergeData(OfflinePlayer player, MIPlayerFileLoader playerFileLoader /** * @return The group mapping from MultiInv, where worldName -> groupName. - * @throws MigrationException If there was any issues getting the data through reflection. + * @throws DataImportException If there was any issues getting the data through reflection. */ - private HashMap getGroupMap() throws MigrationException { + private HashMap getGroupMap() throws DataImportException { Field field; try { field = MIYamlFiles.class.getDeclaredField("groups"); } catch (NoSuchFieldException nsfe) { - throw new MigrationException("The running version of MultiInv is " + throw new DataImportException("The running version of MultiInv is " + "incompatible with the import feature.").setCauseException(nsfe); } field.setAccessible(true); HashMap miGroupMap = null; try { miGroupMap = (HashMap) field.get(null); - } catch (IllegalAccessException iae) { - throw new MigrationException("The running version of MultiInv is " + } catch (IllegalAccessException | ClassCastException iae) { + throw new DataImportException("The running version of MultiInv is " + "incompatible with the import feature.").setCauseException(iae); - } catch (ClassCastException cce) { - throw new MigrationException("The running version of MultiInv is " - + "incompatible with the import feature.").setCauseException(cce); } return miGroupMap; } } - diff --git a/src/main/java/org/mvplugins/multiverse/inventories/dataimport/multiinv/MultiInvImporter.java b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/multiinv/MultiInvImporter.java new file mode 100644 index 00000000..3fd3b292 --- /dev/null +++ b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/multiinv/MultiInvImporter.java @@ -0,0 +1,63 @@ +package org.mvplugins.multiverse.inventories.dataimport.multiinv; + +import org.jetbrains.annotations.NotNull; +import org.jvnet.hk2.annotations.Service; +import org.mvplugins.multiverse.external.jakarta.inject.Inject; +import org.mvplugins.multiverse.inventories.config.InventoriesConfig; +import org.mvplugins.multiverse.inventories.dataimport.AbstractDataImporter; +import org.mvplugins.multiverse.inventories.dataimport.DataImportException; +import org.mvplugins.multiverse.inventories.profile.ProfileDataSource; +import org.mvplugins.multiverse.inventories.profile.container.ProfileContainerStoreProvider; +import org.mvplugins.multiverse.inventories.profile.group.WorldGroupManager; +import uk.co.tggl.pluckerpluck.multiinv.MultiInv; + +@Service +final class MultiInvImporter extends AbstractDataImporter { + + private final WorldGroupManager worldGroupManager; + private final InventoriesConfig inventoriesConfig; + private final ProfileContainerStoreProvider profileContainerStoreProvider; + private final ProfileDataSource profileDataSource; + + @Inject + MultiInvImporter( + @NotNull WorldGroupManager worldGroupManager, + @NotNull InventoriesConfig inventoriesConfig, + @NotNull ProfileContainerStoreProvider profileContainerStoreProvider, + @NotNull ProfileDataSource profileDataSource) { + super(); + this.worldGroupManager = worldGroupManager; + this.inventoriesConfig = inventoriesConfig; + this.profileContainerStoreProvider = profileContainerStoreProvider; + this.profileDataSource = profileDataSource; + } + + /** + * {@inheritDoc} + */ + @Override + protected void doDataImport() throws DataImportException { + new MultiInvImportHelper( + (MultiInv) importer, + worldGroupManager, + inventoriesConfig, + profileContainerStoreProvider, + profileDataSource + ).importData(); + } + /** + * {@inheritDoc} + */ + @Override + public @NotNull String getPluginName() { + return "MultiInv"; + } + + /** + * {@inheritDoc} + */ + @Override + public @NotNull Class getPluginClass() { + return MultiInv.class; + } +} diff --git a/src/main/java/org/mvplugins/multiverse/inventories/migration/multiinv/package-info.java b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/multiinv/package-info.java similarity index 55% rename from src/main/java/org/mvplugins/multiverse/inventories/migration/multiinv/package-info.java rename to src/main/java/org/mvplugins/multiverse/inventories/dataimport/multiinv/package-info.java index bfbc619f..46044732 100644 --- a/src/main/java/org/mvplugins/multiverse/inventories/migration/multiinv/package-info.java +++ b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/multiinv/package-info.java @@ -1,5 +1,5 @@ /** * This package contains MultiInv classes to handle importing their data. */ -package org.mvplugins.multiverse.inventories.migration.multiinv; +package org.mvplugins.multiverse.inventories.dataimport.multiinv; diff --git a/src/main/java/org/mvplugins/multiverse/inventories/dataimport/package-info.java b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/package-info.java new file mode 100644 index 00000000..ce0d8910 --- /dev/null +++ b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/package-info.java @@ -0,0 +1 @@ +package org.mvplugins.multiverse.inventories.dataimport; \ No newline at end of file diff --git a/src/main/java/org/mvplugins/multiverse/inventories/dataimport/perworldinventory/PerWorldInventoryImporter.java b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/perworldinventory/PerWorldInventoryImporter.java new file mode 100644 index 00000000..b85d1a88 --- /dev/null +++ b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/perworldinventory/PerWorldInventoryImporter.java @@ -0,0 +1,66 @@ +package org.mvplugins.multiverse.inventories.dataimport.perworldinventory; + +import me.ebonjaeger.perworldinventory.PerWorldInventory; +import org.jetbrains.annotations.NotNull; +import org.jvnet.hk2.annotations.Service; +import org.mvplugins.multiverse.core.world.WorldManager; +import org.mvplugins.multiverse.external.jakarta.inject.Inject; +import org.mvplugins.multiverse.inventories.config.InventoriesConfig; +import org.mvplugins.multiverse.inventories.dataimport.AbstractDataImporter; +import org.mvplugins.multiverse.inventories.dataimport.DataImportException; +import org.mvplugins.multiverse.inventories.profile.ProfileDataSource; +import org.mvplugins.multiverse.inventories.profile.group.WorldGroupManager; + +import java.util.Objects; + +@Service +public class PerWorldInventoryImporter extends AbstractDataImporter { + + private final InventoriesConfig inventoriesConfig; + private final WorldManager worldManager; + private final WorldGroupManager worldGroupManager; + private final ProfileDataSource profileDataSource; + + @Inject + PerWorldInventoryImporter( + @NotNull InventoriesConfig inventoriesConfig, + @NotNull WorldManager worldManager, + @NotNull WorldGroupManager worldGroupManager, + @NotNull ProfileDataSource profileDataSource) { + super(); + this.inventoriesConfig = inventoriesConfig; + this.worldManager = worldManager; + this.worldGroupManager = worldGroupManager; + this.profileDataSource = profileDataSource; + } + + /** + * {@inheritDoc} + */ + @Override + protected void doDataImport() throws DataImportException { + new PwiImportHelper( + Objects.requireNonNull(((PerWorldInventory) importer).getApi()), + inventoriesConfig, + worldManager, + worldGroupManager, + profileDataSource + ).importData(); + } + + /** + * {@inheritDoc} + */ + @Override + public @NotNull String getPluginName() { + return "PerWorldInventory"; + } + + /** + * {@inheritDoc} + */ + @Override + public @NotNull Class getPluginClass() { + return PerWorldInventory.class; + } +} diff --git a/src/main/java/org/mvplugins/multiverse/inventories/dataimport/perworldinventory/PwiImportHelper.java b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/perworldinventory/PwiImportHelper.java new file mode 100644 index 00000000..63563ef4 --- /dev/null +++ b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/perworldinventory/PwiImportHelper.java @@ -0,0 +1,349 @@ +package org.mvplugins.multiverse.inventories.dataimport.perworldinventory; + +import com.dumptruckman.bukkit.configuration.util.SerializationHelper; +import com.dumptruckman.minecraft.util.Logging; +import me.ebonjaeger.perworldinventory.Group; +import me.ebonjaeger.perworldinventory.GroupManager; +import me.ebonjaeger.perworldinventory.api.PerWorldInventoryAPI; +import me.ebonjaeger.perworldinventory.configuration.PlayerSettings; +import me.ebonjaeger.perworldinventory.configuration.PluginSettings; +import me.ebonjaeger.perworldinventory.configuration.Settings; +import me.ebonjaeger.perworldinventory.data.FlatFile; +import me.ebonjaeger.perworldinventory.data.ProfileKey; +import me.ebonjaeger.perworldinventory.data.ProfileManager; +import me.ebonjaeger.perworldinventory.libs.json.JSONObject; +import me.ebonjaeger.perworldinventory.libs.json.parser.JSONParser; +import me.ebonjaeger.perworldinventory.serialization.PlayerSerializer; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.OfflinePlayer; +import org.bukkit.potion.PotionEffect; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.mvplugins.multiverse.core.utils.ReflectHelper; +import org.mvplugins.multiverse.core.world.WorldManager; +import org.mvplugins.multiverse.inventories.config.InventoriesConfig; +import org.mvplugins.multiverse.inventories.dataimport.DataImportException; +import org.mvplugins.multiverse.inventories.profile.GlobalProfile; +import org.mvplugins.multiverse.inventories.profile.PlayerProfile; +import org.mvplugins.multiverse.inventories.profile.ProfileDataSource; +import org.mvplugins.multiverse.inventories.profile.ProfileTypes; +import org.mvplugins.multiverse.inventories.profile.container.ContainerType; +import org.mvplugins.multiverse.inventories.profile.group.WorldGroup; +import org.mvplugins.multiverse.inventories.profile.group.WorldGroupManager; +import org.mvplugins.multiverse.inventories.share.Sharables; +import org.mvplugins.multiverse.inventories.util.PlayerStats; + +import java.io.File; +import java.io.FileInputStream; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; + +class PwiImportHelper { + + private final PerWorldInventoryAPI pwiAPI; + private final InventoriesConfig inventoriesConfig; + private final WorldManager worldManager; + private final WorldGroupManager worldGroupManager; + private final ProfileDataSource profileDataSource; + + private Settings pwiSettings; + private GroupManager pwiGroupManager; + private FlatFile pwiFlatFile; + private File dataDirectory; + private Method getFileMethod; + private Method deserializeMethod; + + private List playerList; + + PwiImportHelper( + @NotNull PerWorldInventoryAPI pwiAPI, + @NotNull InventoriesConfig inventoriesConfig, + @NotNull WorldManager worldManager, + @NotNull WorldGroupManager worldGroupManager, + @NotNull ProfileDataSource profileDataSource) { + this.pwiAPI = pwiAPI; + this.inventoriesConfig = inventoriesConfig; + this.worldManager = worldManager; + this.worldGroupManager = worldGroupManager; + this.profileDataSource = profileDataSource; + } + + /** + * The 'Main' method for the import. + */ + void importData() throws DataImportException { + pwiSetUp(); + transferConfigOptions(); + findPlayersWithData(); + // Since there is no such thing as individual world container in PerWorldInventory, + // everything is just groups. No need for world playerData import. + for (Group group : getPWIGroups()) { + createMVGroup(group); + saveMVDataForGroup(group); + } + } + + /** + * Do the necessary reflection to get access to the classes needed for data import. + */ + private void pwiSetUp() { + this.pwiSettings = ReflectHelper.getFieldValue(pwiAPI, "settings", Settings.class); + this.pwiGroupManager = ReflectHelper.getFieldValue(this.pwiAPI, "groupManager", GroupManager.class); + ProfileManager pwiProfileManager = ReflectHelper.getFieldValue(this.pwiAPI, "profileManager", ProfileManager.class); + this.pwiFlatFile = ReflectHelper.getFieldValue(pwiProfileManager, "dataSource", FlatFile.class); + this.getFileMethod = ReflectHelper.getMethod(this.pwiFlatFile, "getFile", ProfileKey.class); + this.dataDirectory = ReflectHelper.getFieldValue(this.pwiFlatFile, "dataDirectory", File.class); + this.deserializeMethod = ReflectHelper.getMethod(SerializationHelper.class, "deserialize", Map.class, boolean.class); + } + + /** + * Set similar/supported config options in MultiverseInventories with the values used in PerWorldInventory. + */ + private void transferConfigOptions() { + inventoriesConfig.setUsingGameModeProfiles(this.pwiSettings.getProperty(PluginSettings.SEPARATE_GM_INVENTORIES)); + inventoriesConfig.setUsingLoggingSaveLoad(this.pwiSettings.getProperty(PluginSettings.LOAD_DATA_ON_JOIN)); + inventoriesConfig.setDefaultingUngroupedWorlds(this.pwiSettings.getProperty(PluginSettings.SHARE_IF_UNCONFIGURED)); + inventoriesConfig.getOptionalShares().setSharing(Sharables.ECONOMY, this.pwiSettings.getProperty(PlayerSettings.USE_ECONOMY)); + inventoriesConfig.save(); + } + + private void findPlayersWithData() throws DataImportException { + if (dataDirectory == null) { + throw new DataImportException("PerWorldInventory data directory not found!"); + } + File[] playerFolders = dataDirectory.listFiles(); + if (playerFolders == null) { + throw new DataImportException("Unable to traverse PerWorldInventory data directory!"); + } + this.playerList = Arrays.stream(playerFolders) + .filter(File::isDirectory) + .map(file -> UUID.fromString(file.getName())) + .map(Bukkit::getOfflinePlayer) + .toList(); + } + + /** + * Gets all PerWorldInventory groups based on all the worlds known by Multiverse. + * + * @return A collection of PerWorldInventory groups. + */ + private Collection getPWIGroups() { + Set groups = new HashSet<>(this.pwiGroupManager.getGroups().values()); + if (!inventoriesConfig.isDefaultingUngroupedWorlds()) { + worldManager.getWorlds().forEach(world -> + groups.add(this.pwiGroupManager.getGroupFromWorld(world.getName()))); + } + return groups; + } + + /** + * Create a MultiverseInventories {@link WorldGroup} based on PerWorldInventory Group. + * + * @param group A PerWorldInventory Group. + */ + private void createMVGroup(Group group) { + Logging.finer("PerWorldInventory Group: %s", group); + WorldGroup worldGroup = worldGroupManager.getGroup(group.getName()); + if (worldGroup == null) { + worldGroup = worldGroupManager.newEmptyGroup(group.getName()); + } + + // In PerWorldInventory, shares can only be toggled to be enabled or disabled globally. + // So setting all shares here then transferring only those enabled later should work enough, + // since you can't actually disable shares in MultiverseInventories. + worldGroup.getShares().addAll(Sharables.allOf()); + worldGroup.addWorlds(group.getWorlds()); + if (group.getRespawnWorld() != null) { + worldGroup.setSpawnWorld(group.getRespawnWorld()); + } + worldGroupManager.updateGroup(worldGroup); + } + + /** + * Transfer all player data from PerWorldInventory to MultiverseInventories for a given group. + * + * @param group A PerWorldInventory Group. + */ + private void saveMVDataForGroup(Group group) throws DataImportException { + for (OfflinePlayer offlinePlayer : this.playerList) { + saveMVDataForPlayer(group, offlinePlayer); + } + } + + private void saveMVDataForPlayer(Group group, OfflinePlayer offlinePlayer) throws DataImportException { + GlobalProfile globalProfile = profileDataSource.getGlobalProfile(offlinePlayer); + globalProfile.setLoadOnLogin(pwiSettings.getProperty(PluginSettings.LOAD_DATA_ON_JOIN)); + profileDataSource.updateGlobalProfile(globalProfile); + for (GameMode gameMode : GameMode.values()) { + me.ebonjaeger.perworldinventory.data.PlayerProfile pwiPlayerData = getPWIPlayerData(offlinePlayer, group, gameMode); + if (pwiPlayerData == null) { + continue; + } + for (var mvProfile : getMVPlayerData(offlinePlayer, group, gameMode)) { + transferToMVPlayerData(mvProfile, pwiPlayerData); + } + } + } + + /** + * Gets MultiverseInventories PlayerProfile based on PerWorldInventory ProfileKey. + * + * @param offlinePlayer OfflinePlayer to get data for. + * @param group Group to get data for. + * @param gameMode GameMode to get data for. + * @return A MultiverseInventories PLayerProfile. + */ + private List getMVPlayerData( + @NotNull OfflinePlayer offlinePlayer, @NotNull Group group, @NotNull GameMode gameMode) { + List profiles = new ArrayList<>(); + profiles.add(profileDataSource.getPlayerData( + ContainerType.GROUP, group.getName(), ProfileTypes.forGameMode(gameMode), offlinePlayer.getUniqueId())); + for (var worldName : group.getWorlds()) { + profiles.add(profileDataSource.getPlayerData( + ContainerType.WORLD, worldName, ProfileTypes.forGameMode(gameMode), offlinePlayer.getUniqueId())); + } + return profiles; + } + + /** + * Gets PerWorldInventory PlayerProfile based on PerWorldInventory ProfileKey. + * + * @param offlinePlayer OfflinePlayer to get data for. + * @param group Group to get data for. + * @param gameMode GameMode to get data for. + * @return A PerWorldInventory PLayerProfile. + */ + private @Nullable me.ebonjaeger.perworldinventory.data.PlayerProfile getPWIPlayerData( + @NotNull OfflinePlayer offlinePlayer, @NotNull Group group, @NotNull GameMode gameMode) throws DataImportException { + ProfileKey pwiKey = new ProfileKey(offlinePlayer.getUniqueId(), group, gameMode); + File pwiPlayerDataFile = getPWIFile(pwiKey); + if (!pwiPlayerDataFile.isFile()) { + Logging.finer("No data for %s.", pwiKey.toString()); + return null; + } + + me.ebonjaeger.perworldinventory.data.PlayerProfile pwiPlayerProfile; + try { + JSONParser parser = new JSONParser(JSONParser.USE_INTEGER_STORAGE); + JSONObject jsonObject = (JSONObject) parser.parse(new FileInputStream(pwiPlayerDataFile)); + if (jsonObject.containsKey("==")) { + pwiPlayerProfile = ReflectHelper.invokeMethod(null, deserializeMethod, jsonObject, true); + } else { + // Use legacy serialization that doesn't use ConfigurationSerializable + pwiPlayerProfile = PlayerSerializer.INSTANCE.deserialize( + jsonObject, + Objects.requireNonNull(offlinePlayer.getName()), + PlayerStats.INVENTORY_SIZE, + PlayerStats.ENDER_CHEST_SIZE); + } + } catch (Exception e) { + Logging.severe("Unable to parse file into profile: " + pwiPlayerDataFile.getAbsolutePath()); + e.printStackTrace(); + return null; + } + if (pwiPlayerProfile == null) { + Logging.warning("Empty serialization for %s.", pwiKey.toString()); + return null; + } + Logging.finer("Got pwiPlayerProfile for %s.", pwiKey.toString()); + return pwiPlayerProfile; + } + + /** + * Gets a PerWorldInventory data file based on it's ProfileKey. + * + * @param pwiKey PerWorldInventory profile key. + * @return A PerWorldInventory data file. + */ + private File getPWIFile(ProfileKey pwiKey) throws DataImportException { + return ReflectHelper.invokeMethod(this.pwiFlatFile, this.getFileMethod, pwiKey); + } + + /** + * Transfers supported player data from PerWorldInventory to MultiverseInventories. + * + * @param mvPlayerProfile MultiverseInventories PlayerProfile to transfer to. + * @param pwiPlayerProfile PerWorldInventory PlayerProfile to transfer from. + */ + private void transferToMVPlayerData( + PlayerProfile mvPlayerProfile, + me.ebonjaeger.perworldinventory.data.PlayerProfile pwiPlayerProfile + ) throws DataImportException { + if (pwiPlayerProfile == null || mvPlayerProfile == null) { + Logging.finer("Null profile(s). No data transferred for %s and %s.", mvPlayerProfile, pwiPlayerProfile); + return; + } + + // Move data from PerWorldInventory profile to MultiverseInventories profile + // Shares that are not available are commented out. + if (pwiSettings.getProperty(PlayerSettings.LOAD_INVENTORY)) { + mvPlayerProfile.set(Sharables.ARMOR, pwiPlayerProfile.getArmor()); + mvPlayerProfile.set(Sharables.INVENTORY, pwiPlayerProfile.getInventory()); + } + if (pwiSettings.getProperty(PlayerSettings.USE_ECONOMY)) { + mvPlayerProfile.set(Sharables.ECONOMY, pwiPlayerProfile.getBalance()); + } + if (pwiSettings.getProperty(PlayerSettings.LOAD_ENDER_CHEST)) { + mvPlayerProfile.set(Sharables.ENDER_CHEST, pwiPlayerProfile.getEnderChest()); + } + if (pwiSettings.getProperty(PlayerSettings.LOAD_EXHAUSTION)) { + mvPlayerProfile.set(Sharables.EXHAUSTION, pwiPlayerProfile.getExhaustion()); + } + if (pwiSettings.getProperty(PlayerSettings.LOAD_EXP)) { + mvPlayerProfile.set(Sharables.EXPERIENCE, pwiPlayerProfile.getExperience()); + } + if (pwiSettings.getProperty(PlayerSettings.LOAD_FALL_DISTANCE)) { + mvPlayerProfile.set(Sharables.FALL_DISTANCE, pwiPlayerProfile.getFallDistance()); + } + if (pwiSettings.getProperty(PlayerSettings.LOAD_FIRE_TICKS)) { + mvPlayerProfile.set(Sharables.FIRE_TICKS, pwiPlayerProfile.getFireTicks()); + } + if (pwiSettings.getProperty(PlayerSettings.LOAD_HUNGER)) { + mvPlayerProfile.set(Sharables.FOOD_LEVEL, pwiPlayerProfile.getFoodLevel()); + } + if (pwiSettings.getProperty(PlayerSettings.LOAD_HUNGER)) { + mvPlayerProfile.set(Sharables.FOOD_LEVEL, pwiPlayerProfile.getFoodLevel()); + } + if (pwiSettings.getProperty(PlayerSettings.LOAD_HEALTH)) { + mvPlayerProfile.set(Sharables.HEALTH, pwiPlayerProfile.getHealth()); + // mvPlayerProfile.set(Sharables, pwiPlayerProfile.getMaxHealth()); + } + if (pwiSettings.getProperty(PlayerSettings.LOAD_LEVEL)) { + mvPlayerProfile.set(Sharables.LEVEL, pwiPlayerProfile.getLevel()); + } + if (pwiSettings.getProperty(PlayerSettings.LOAD_MAX_AIR)) { + mvPlayerProfile.set(Sharables.MAXIMUM_AIR, pwiPlayerProfile.getMaximumAir()); + } + if (pwiSettings.getProperty(PlayerSettings.LOAD_POTION_EFFECTS)) { + mvPlayerProfile.set(Sharables.POTIONS, pwiPlayerProfile.getPotionEffects().toArray(new PotionEffect[0])); + } + if (pwiSettings.getProperty(PlayerSettings.LOAD_REMAINING_AIR)) { + mvPlayerProfile.set(Sharables.REMAINING_AIR, pwiPlayerProfile.getRemainingAir()); + } + if (pwiSettings.getProperty(PlayerSettings.LOAD_SATURATION)) { + mvPlayerProfile.set(Sharables.REMAINING_AIR, pwiPlayerProfile.getRemainingAir()); + } + // if (pwiSettings.getProperty(PlayerSettings.LOAD_DISPLAY_NAME)) { + // mvPlayerProfile.set(Sharables, pwiPlayerProfile.getDisplayName()); + // } + // if (pwiSettings.getProperty(PlayerSettings.LOAD_FLYING)) { + // mvPlayerProfile.set(Sharables, pwiPlayerProfile.getAllowFlight()); + // } + // mvPlayerProfile.set(Sharables.BED_SPAWN, pwiPlayerProfile); + // mvPlayerProfile.set(Sharables.HUNGER, pwiPlayerProfile); + // mvPlayerProfile.set(Sharables.LAST_LOCATION, pwiPlayerProfile); + // mvPlayerProfile.set(Sharables.OFF_HAND, pwiPlayerProfile); + // mvPlayerProfile.set(Sharables.TOTAL_EXPERIENCE, pwiPlayerProfile); + + profileDataSource.updatePlayerData(mvPlayerProfile); + } +} diff --git a/src/main/java/org/mvplugins/multiverse/inventories/dataimport/perworldinventory/package-info.java b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/perworldinventory/package-info.java new file mode 100644 index 00000000..c8e7f714 --- /dev/null +++ b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/perworldinventory/package-info.java @@ -0,0 +1 @@ +package org.mvplugins.multiverse.inventories.dataimport.perworldinventory; \ No newline at end of file diff --git a/src/main/java/org/mvplugins/multiverse/inventories/migration/worldinventories/WorldInventoriesImporter.java b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/worldinventories/WorldInventoriesImportHelper.java similarity index 78% rename from src/main/java/org/mvplugins/multiverse/inventories/migration/worldinventories/WorldInventoriesImporter.java rename to src/main/java/org/mvplugins/multiverse/inventories/dataimport/worldinventories/WorldInventoriesImportHelper.java index a97d9306..1fdc6ae6 100644 --- a/src/main/java/org/mvplugins/multiverse/inventories/migration/worldinventories/WorldInventoriesImporter.java +++ b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/worldinventories/WorldInventoriesImportHelper.java @@ -1,20 +1,6 @@ -package org.mvplugins.multiverse.inventories.migration.worldinventories; +package org.mvplugins.multiverse.inventories.dataimport.worldinventories; import com.dumptruckman.minecraft.util.Logging; -import org.mvplugins.multiverse.inventories.MultiverseInventories; -import org.mvplugins.multiverse.inventories.config.InventoriesConfig; -import org.mvplugins.multiverse.inventories.profile.ProfileDataSource; -import org.mvplugins.multiverse.inventories.profile.container.ContainerType; -import org.mvplugins.multiverse.inventories.profile.container.ProfileContainerStore; -import org.mvplugins.multiverse.inventories.profile.container.ProfileContainerStoreProvider; -import org.mvplugins.multiverse.inventories.profile.group.WorldGroup; -import org.mvplugins.multiverse.inventories.profile.ProfileTypes; -import org.mvplugins.multiverse.inventories.profile.PlayerProfile; -import org.mvplugins.multiverse.inventories.profile.container.ProfileContainer; -import org.mvplugins.multiverse.inventories.profile.group.WorldGroupManager; -import org.mvplugins.multiverse.inventories.share.Sharables; -import org.mvplugins.multiverse.inventories.migration.DataImporter; -import org.mvplugins.multiverse.inventories.migration.MigrationException; import me.drayshak.WorldInventories.Group; import me.drayshak.WorldInventories.WIPlayerInventory; import me.drayshak.WorldInventories.WIPlayerStats; @@ -22,7 +8,18 @@ import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.World; -import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; +import org.mvplugins.multiverse.inventories.config.InventoriesConfig; +import org.mvplugins.multiverse.inventories.dataimport.DataImportException; +import org.mvplugins.multiverse.inventories.profile.PlayerProfile; +import org.mvplugins.multiverse.inventories.profile.ProfileDataSource; +import org.mvplugins.multiverse.inventories.profile.ProfileTypes; +import org.mvplugins.multiverse.inventories.profile.container.ContainerType; +import org.mvplugins.multiverse.inventories.profile.container.ProfileContainer; +import org.mvplugins.multiverse.inventories.profile.container.ProfileContainerStoreProvider; +import org.mvplugins.multiverse.inventories.profile.group.WorldGroup; +import org.mvplugins.multiverse.inventories.profile.group.WorldGroupManager; +import org.mvplugins.multiverse.inventories.share.Sharables; import java.io.File; import java.io.FileInputStream; @@ -32,60 +29,41 @@ import java.util.List; import java.util.Set; -/** - * Handles the importing of data from WorldInventories. - */ -public class WorldInventoriesImporter implements DataImporter { +final class WorldInventoriesImportHelper { - private final WorldInventories wiPlugin; - private final InventoriesConfig config; + @NotNull + private final WorldInventories worldInventories; private final WorldGroupManager worldGroupManager; + private final InventoriesConfig inventoriesConfig; + private final ProfileContainerStoreProvider profileContainerStoreProvider; private final ProfileDataSource profileDataSource; - private final ProfileContainerStore worldProfileContainerStore; - - public WorldInventoriesImporter(MultiverseInventories inventories, WorldInventories wiPlugin) { - this.wiPlugin = wiPlugin; - this.config = inventories.getServiceLocator().getService(InventoriesConfig.class); - this.worldGroupManager = inventories.getServiceLocator().getService(WorldGroupManager.class); - this.profileDataSource = inventories.getServiceLocator().getService(ProfileDataSource.class); - this.worldProfileContainerStore = inventories.getServiceLocator() - .getService(ProfileContainerStoreProvider.class) - .getStore(ContainerType.WORLD); - } - - /** - * @return The WorldInventories plugin hooked to the importer. - */ - public WorldInventories getWIPlugin() { - return this.wiPlugin; - } - /** - * {@inheritDoc} - */ - @Override - public Plugin getPlugin() { - return this.getWIPlugin(); + WorldInventoriesImportHelper( + @NotNull WorldInventories worldInventories, + @NotNull WorldGroupManager worldGroupManager, + @NotNull InventoriesConfig inventoriesConfig, + @NotNull ProfileContainerStoreProvider profileContainerStoreProvider, + @NotNull ProfileDataSource profileDataSource) { + super(); + this.worldInventories = worldInventories; + this.worldGroupManager = worldGroupManager; + this.inventoriesConfig = inventoriesConfig; + this.profileContainerStoreProvider = profileContainerStoreProvider; + this.profileDataSource = profileDataSource; } - /** - * Imports the data from WorldInventories into MultiverseInventories. - * - * @throws MigrationException If there was any MAJOR issues importing the data. - */ - @Override - public void importData() throws MigrationException { + void importData() throws DataImportException { List wiGroups; try { - wiGroups = this.getWIPlugin().getGroups(); + wiGroups = worldInventories.getGroups(); } catch (Exception e) { - throw new MigrationException("Unable to import from this version of WorldInventories!") + throw new DataImportException("Unable to import from this version of WorldInventories!") .setCauseException(e); } catch (Error e) { - throw new MigrationException("Unable to import from this version of WorldInventories!"); + throw new DataImportException("Unable to import from this version of WorldInventories!"); } if (wiGroups == null) { - throw new MigrationException("No data to import from WorldInventories!"); + throw new DataImportException("No data to import from WorldInventories!"); } if (!wiGroups.isEmpty()) { @@ -98,7 +76,7 @@ public void importData() throws MigrationException { this.createGroups(wiGroups); Set noGroupWorlds = this.getWorldsWithoutGroups(); - config.save(); + inventoriesConfig.save(); OfflinePlayer[] offlinePlayers = Bukkit.getServer().getOfflinePlayers(); Logging.info("Processing data for " + offlinePlayers.length + " players. The larger than number, the longer" @@ -121,9 +99,6 @@ public void importData() throws MigrationException { this.transferData(player, null, container); } } - - Logging.info("Import from WorldInventories finished. Disabling WorldInventories."); - Bukkit.getPluginManager().disablePlugin(this.getWIPlugin()); } private void createGroups(List wiGroups) { @@ -160,7 +135,8 @@ private Set getWorldsWithoutGroups() { for (World world : Bukkit.getWorlds()) { if (worldGroupManager.getGroupsForWorld(world.getName()).isEmpty()) { Logging.fine("Added ungrouped world for importing."); - ProfileContainer container = worldProfileContainerStore.getContainer(world.getName()); + ProfileContainer container = profileContainerStoreProvider.getStore(ContainerType.WORLD) + .getContainer(world.getName()); noGroupWorlds.add(container); } } @@ -197,7 +173,7 @@ private File getFile(OfflinePlayer player, Group group, DataType dataType) { } else { path.append(group.getName()); } - path.insert(0, this.getWIPlugin().getDataFolder().getAbsolutePath()); + path.insert(0, worldInventories.getDataFolder().getAbsolutePath()); path.append(File.separator).append(player.getName()).append(dataType.fileExtension); File file = new File(path.toString()); @@ -271,6 +247,7 @@ private WIPlayerStats loadPlayerStats(OfflinePlayer player, Group group) { return playerstats; } + /** * Indicates the type of data we're importing for. */ @@ -285,4 +262,3 @@ private enum DataType { } } } - diff --git a/src/main/java/org/mvplugins/multiverse/inventories/dataimport/worldinventories/WorldInventoriesImporter.java b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/worldinventories/WorldInventoriesImporter.java new file mode 100644 index 00000000..42ce3963 --- /dev/null +++ b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/worldinventories/WorldInventoriesImporter.java @@ -0,0 +1,64 @@ +package org.mvplugins.multiverse.inventories.dataimport.worldinventories; + +import me.drayshak.WorldInventories.WorldInventories; +import org.jetbrains.annotations.NotNull; +import org.jvnet.hk2.annotations.Service; +import org.mvplugins.multiverse.external.jakarta.inject.Inject; +import org.mvplugins.multiverse.inventories.config.InventoriesConfig; +import org.mvplugins.multiverse.inventories.dataimport.AbstractDataImporter; +import org.mvplugins.multiverse.inventories.dataimport.DataImportException; +import org.mvplugins.multiverse.inventories.profile.ProfileDataSource; +import org.mvplugins.multiverse.inventories.profile.container.ProfileContainerStoreProvider; +import org.mvplugins.multiverse.inventories.profile.group.WorldGroupManager; + +@Service +final class WorldInventoriesImporter extends AbstractDataImporter { + + private final WorldGroupManager worldGroupManager; + private final InventoriesConfig inventoriesConfig; + private final ProfileContainerStoreProvider profileContainerStoreProvider; + private final ProfileDataSource profileDataSource; + + @Inject + WorldInventoriesImporter( + @NotNull WorldGroupManager worldGroupManager, + @NotNull InventoriesConfig inventoriesConfig, + @NotNull ProfileContainerStoreProvider profileContainerStoreProvider, + @NotNull ProfileDataSource profileDataSource) { + super(); + this.worldGroupManager = worldGroupManager; + this.inventoriesConfig = inventoriesConfig; + this.profileContainerStoreProvider = profileContainerStoreProvider; + this.profileDataSource = profileDataSource; + } + + /** + * {@inheritDoc} + */ + @Override + protected void doDataImport() throws DataImportException { + new WorldInventoriesImportHelper( + (WorldInventories) importer, + worldGroupManager, + inventoriesConfig, + profileContainerStoreProvider, + profileDataSource + ).importData(); + } + + /** + * {@inheritDoc} + */ + @Override + public @NotNull String getPluginName() { + return "WorldInventories"; + } + + /** + * {@inheritDoc} + */ + @Override + public @NotNull Class getPluginClass() { + return WorldInventories.class; + } +} diff --git a/src/main/java/org/mvplugins/multiverse/inventories/migration/worldinventories/package-info.java b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/worldinventories/package-info.java similarity index 55% rename from src/main/java/org/mvplugins/multiverse/inventories/migration/worldinventories/package-info.java rename to src/main/java/org/mvplugins/multiverse/inventories/dataimport/worldinventories/package-info.java index e7666201..adae4de0 100644 --- a/src/main/java/org/mvplugins/multiverse/inventories/migration/worldinventories/package-info.java +++ b/src/main/java/org/mvplugins/multiverse/inventories/dataimport/worldinventories/package-info.java @@ -1,5 +1,5 @@ /** * This package contains WorldInventories classes to handle importing their data. */ -package org.mvplugins.multiverse.inventories.migration.worldinventories; +package org.mvplugins.multiverse.inventories.dataimport.worldinventories; diff --git a/src/main/java/org/mvplugins/multiverse/inventories/listeners/InventoriesListener.java b/src/main/java/org/mvplugins/multiverse/inventories/listeners/InventoriesListener.java index e571e54d..c55c1af3 100644 --- a/src/main/java/org/mvplugins/multiverse/inventories/listeners/InventoriesListener.java +++ b/src/main/java/org/mvplugins/multiverse/inventories/listeners/InventoriesListener.java @@ -11,7 +11,6 @@ import org.mvplugins.multiverse.inventories.MultiverseInventories; import org.mvplugins.multiverse.inventories.ShareHandlingUpdater; import org.mvplugins.multiverse.inventories.config.InventoriesConfig; -import org.mvplugins.multiverse.inventories.migration.ImportManager; import org.mvplugins.multiverse.inventories.profile.PersistingProfile; import org.mvplugins.multiverse.inventories.profile.ProfileDataSource; import org.mvplugins.multiverse.inventories.profile.container.ContainerType; @@ -68,7 +67,6 @@ public class InventoriesListener implements Listener { private final WorldGroupManager worldGroupManager; private final ProfileDataSource profileDataSource; private final ProfileContainerStoreProvider profileContainerStoreProvider; - private final Provider importManager; private List currentGroups; private Location spawnLoc = null; @@ -79,15 +77,13 @@ public class InventoriesListener implements Listener { @NotNull WorldManager worldManager, @NotNull WorldGroupManager worldGroupManager, @NotNull ProfileDataSource profileDataSource, - @NotNull ProfileContainerStoreProvider profileContainerStoreProvider, - @NotNull Provider importManager) { + @NotNull ProfileContainerStoreProvider profileContainerStoreProvider) { this.inventories = inventories; this.config = config; this.worldManager = worldManager; this.worldGroupManager = worldGroupManager; this.profileDataSource = profileDataSource; this.profileContainerStoreProvider = profileContainerStoreProvider; - this.importManager = importManager; } /** @@ -145,40 +141,6 @@ public void configReload(MVConfigReloadEvent event) { event.addConfig("Multiverse-Inventories - config.yml"); } - /** - * Called when a plugin is enabled. - * - * @param event The plugin enable event. - */ - @EventHandler - public void pluginEnable(PluginEnableEvent event) { - try { - if (event.getPlugin() instanceof MultiInv) { - importManager.get().hookMultiInv((MultiInv) event.getPlugin()); - } else if (event.getPlugin() instanceof WorldInventories) { - importManager.get().hookWorldInventories((WorldInventories) event.getPlugin()); - } - } catch (NoClassDefFoundError ignore) { - } - } - - /** - * Called when a plugin is disabled. - * - * @param event The plugin disable event. - */ - @EventHandler - public void pluginDisable(PluginDisableEvent event) { - try { - if (event.getPlugin() instanceof MultiInv) { - importManager.get().unHookMultiInv(); - } else if (event.getPlugin() instanceof WorldInventories) { - importManager.get().unHookWorldInventories(); - } - } catch (NoClassDefFoundError ignore) { - } - } - @EventHandler(priority = EventPriority.MONITOR) public void playerPreLogin(AsyncPlayerPreLoginEvent event) { if (event.getLoginResult() != Result.ALLOWED) { diff --git a/src/main/java/org/mvplugins/multiverse/inventories/migration/DataImporter.java b/src/main/java/org/mvplugins/multiverse/inventories/migration/DataImporter.java deleted file mode 100644 index 52af376f..00000000 --- a/src/main/java/org/mvplugins/multiverse/inventories/migration/DataImporter.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.mvplugins.multiverse.inventories.migration; - -import org.bukkit.plugin.Plugin; - -/** - * Interface for data migration importers. - */ -public interface DataImporter { - - /** - * Imports the data from another plugin. - * - * @throws MigrationException If there was any MAJOR issue loading the data. - */ - void importData() throws MigrationException; - - /** - * @return The plugin associated with this Importer. - */ - Plugin getPlugin(); -} - diff --git a/src/main/java/org/mvplugins/multiverse/inventories/migration/ImportManager.java b/src/main/java/org/mvplugins/multiverse/inventories/migration/ImportManager.java deleted file mode 100644 index 8b01736b..00000000 --- a/src/main/java/org/mvplugins/multiverse/inventories/migration/ImportManager.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.mvplugins.multiverse.inventories.migration; - -import com.dumptruckman.minecraft.util.Logging; -import org.jvnet.hk2.annotations.Service; -import org.mvplugins.multiverse.external.jakarta.inject.Inject; -import org.mvplugins.multiverse.external.jetbrains.annotations.NotNull; -import org.mvplugins.multiverse.inventories.MultiverseInventories; -import org.mvplugins.multiverse.inventories.migration.multiinv.MultiInvImporter; -import org.mvplugins.multiverse.inventories.migration.worldinventories.WorldInventoriesImporter; -import me.drayshak.WorldInventories.WorldInventories; -import uk.co.tggl.pluckerpluck.multiinv.MultiInv; - -/** - * Manages the import heplers for other similar plugins. - */ -@Service -public class ImportManager { - - private MultiInvImporter multiInvImporter = null; - private WorldInventoriesImporter worldInventoriesImporter = null; - private final MultiverseInventories inventories; - - @Inject - public ImportManager(@NotNull MultiverseInventories inventories) { - this.inventories = inventories; - } - - /** - * Hooks MultiInv for importing it's data. - * - * @param plugin Instance of MultiInv. - */ - public void hookMultiInv(MultiInv plugin) { - this.multiInvImporter = new MultiInvImporter(this.inventories, plugin); - Logging.info("Hooked MultiInv for importing!"); - } - - /** - * Hooks WorldInventories for importing it's data. - * - * @param plugin Instance of WorldInventories. - */ - public void hookWorldInventories(WorldInventories plugin) { - this.worldInventoriesImporter = new WorldInventoriesImporter(this.inventories, plugin); - Logging.info("Hooked WorldInventories for importing!"); - } - - /** - * @return The MultiInv importer class or null if not hooked. - */ - public MultiInvImporter getMultiInvImporter() { - return this.multiInvImporter; - } - - /** - * @return The WorldInventories importer class or null if not hooked. - */ - public WorldInventoriesImporter getWorldInventoriesImporter() { - return this.worldInventoriesImporter; - } - - /** - * Un-hooks MultiInv so we're not able to import from it anymore. - */ - public void unHookMultiInv() { - this.multiInvImporter = null; - } - - /** - * Un-hooks WorldInventories so we're not able to import from it anymore. - */ - public void unHookWorldInventories() { - this.worldInventoriesImporter = null; - } -} - diff --git a/src/main/java/org/mvplugins/multiverse/inventories/migration/MigrationException.java b/src/main/java/org/mvplugins/multiverse/inventories/migration/MigrationException.java deleted file mode 100644 index f7319478..00000000 --- a/src/main/java/org/mvplugins/multiverse/inventories/migration/MigrationException.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.mvplugins.multiverse.inventories.migration; - -/** - * Exception thrown when migration doesn't go well. - */ -public class MigrationException extends Exception { - - private Exception causeException = null; - - public MigrationException(String message) { - super(message); - } - - /** - * Sets what the causing exception was, if any. - * - * @param exception The cause exception. - * @return This exception for easy chainability. - */ - public MigrationException setCauseException(Exception exception) { - this.causeException = exception; - return this; - } - - /** - * @return The causing exception or null if none. - */ - public Exception getCauseException() { - return this.causeException; - } -} - diff --git a/src/main/java/org/mvplugins/multiverse/inventories/migration/package-info.java b/src/main/java/org/mvplugins/multiverse/inventories/migration/package-info.java deleted file mode 100644 index d66b1e65..00000000 --- a/src/main/java/org/mvplugins/multiverse/inventories/migration/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -/** - * This package contains thigns to help with importing player stats/inventory data from - * other similar plugins. - */ -package org.mvplugins.multiverse.inventories.migration; - diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 7dc9b458..368aa413 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -5,4 +5,4 @@ api-version: 1.13 authors: ['dumptruckman', 'benwoo1110'] website: 'https://dev.bukkit.org/projects/multiverse-inventories' depend: ['Multiverse-Core'] -softdepend: [MultiInv, WorldInventories] +softdepend: [MultiInv, WorldInventories, PerWorldInventory] diff --git a/src/test/java/org/mvplugins/multiverse/inventories/InjectionTest.kt b/src/test/java/org/mvplugins/multiverse/inventories/InjectionTest.kt index 1d843d57..6abfcd2f 100644 --- a/src/test/java/org/mvplugins/multiverse/inventories/InjectionTest.kt +++ b/src/test/java/org/mvplugins/multiverse/inventories/InjectionTest.kt @@ -3,6 +3,7 @@ package org.mvplugins.multiverse.inventories import org.junit.jupiter.api.Test import org.mvplugins.multiverse.inventories.commands.InventoriesCommand import org.mvplugins.multiverse.inventories.config.InventoriesConfig +import org.mvplugins.multiverse.inventories.dataimport.DataImportManager import org.mvplugins.multiverse.inventories.listeners.InventoriesListener import org.mvplugins.multiverse.inventories.profile.ProfileDataSource import org.mvplugins.multiverse.inventories.profile.container.ProfileContainerStoreProvider @@ -14,7 +15,7 @@ class InjectionTest : TestWithMockBukkit() { @Test fun `InventoriesCommand are available as a service`() { - assertEquals(5, serviceLocator.getAllActiveServices(InventoriesCommand::class.java).size) + assertEquals(6, serviceLocator.getAllActiveServices(InventoriesCommand::class.java).size) } @Test @@ -41,4 +42,9 @@ class InjectionTest : TestWithMockBukkit() { fun `WorldGroupManager is available as a service`() { assertNotNull(serviceLocator.getActiveService(WorldGroupManager::class.java)) } + + @Test + fun `DataImportManager is available as a service`() { + assertNotNull(serviceLocator.getActiveService(DataImportManager::class.java)) + } } diff --git a/src/test/java/org/mvplugins/multiverse/inventories/TestWithMockBukkit.kt b/src/test/java/org/mvplugins/multiverse/inventories/TestWithMockBukkit.kt index 6a263b31..0a9edad4 100644 --- a/src/test/java/org/mvplugins/multiverse/inventories/TestWithMockBukkit.kt +++ b/src/test/java/org/mvplugins/multiverse/inventories/TestWithMockBukkit.kt @@ -1,6 +1,5 @@ package org.mvplugins.multiverse.inventories -import com.dumptruckman.minecraft.util.Logging import org.bukkit.Location import org.bukkit.configuration.MemorySection import org.bukkit.configuration.file.YamlConfiguration @@ -8,12 +7,17 @@ import org.bukkit.configuration.serialization.ConfigurationSerialization import org.mockbukkit.mockbukkit.MockBukkit import org.mockbukkit.mockbukkit.inventory.ItemStackMock import org.mvplugins.multiverse.core.MultiverseCore +import org.mvplugins.multiverse.core.config.MVCoreConfig import org.mvplugins.multiverse.core.inject.PluginServiceLocator import org.mvplugins.multiverse.inventories.mock.MVServerMock import java.io.File import java.nio.file.Path import kotlin.io.path.absolutePathString -import kotlin.test.* +import kotlin.test.AfterTest +import kotlin.test.BeforeTest +import kotlin.test.assertEquals +import kotlin.test.assertNotNull +import kotlin.test.assertNull /** * Basic abstract test class that sets up MockBukkit and MultiverseCore. @@ -31,8 +35,8 @@ abstract class TestWithMockBukkit { server = MockBukkit.mock(MVServerMock()) multiverseCore = MockBukkit.load(MultiverseCore::class.java) + multiverseCore.serviceLocator.getService(MVCoreConfig::class.java).globalDebug = 3 multiverseInventories = MockBukkit.load(MultiverseInventories::class.java) - Logging.setDebugLevel(3) serviceLocator = multiverseInventories.serviceLocator assertNotNull(server.commandMap) }