diff --git a/pom.xml b/pom.xml
index 8d63e8bb0..6efe8b389 100644
--- a/pom.xml
+++ b/pom.xml
@@ -235,6 +235,12 @@
${spigot.version}
provided
+
+ org.spigotmc.....
+ spigot
+ 1.21-R0.1-SNAPSHOT
+ provided
+
org.spigotmc....
spigot
diff --git a/src/main/java/world/bentobox/bentobox/commands/BentoBoxMigrateCommand.java b/src/main/java/world/bentobox/bentobox/commands/BentoBoxMigrateCommand.java
index b4b763270..0face2d24 100644
--- a/src/main/java/world/bentobox/bentobox/commands/BentoBoxMigrateCommand.java
+++ b/src/main/java/world/bentobox/bentobox/commands/BentoBoxMigrateCommand.java
@@ -1,8 +1,13 @@
package world.bentobox.bentobox.commands;
+import java.util.LinkedList;
import java.util.List;
+import java.util.Queue;
import java.util.Set;
+import org.bukkit.Bukkit;
+import org.bukkit.scheduler.BukkitTask;
+
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.commands.ConfirmableCommand;
@@ -20,6 +25,8 @@ import world.bentobox.bentobox.database.objects.DataObject;
public class BentoBoxMigrateCommand extends ConfirmableCommand {
private static final String MIGRATED = "commands.bentobox.migrate.migrated";
+ private Queue> classQueue;
+ private BukkitTask task;
/**
* Reloads settings, addons and localization command
@@ -41,11 +48,21 @@ public class BentoBoxMigrateCommand extends ConfirmableCommand {
user.sendMessage("commands.bentobox.migrate.addons");
Set> classSet = getPlugin().getAddonsManager().getDataObjects();
classSet.addAll(Database.getDataobjects());
- classSet.forEach(t -> {
- user.sendMessage("commands.bentobox.migrate.class", TextVariables.DESCRIPTION, BentoBox.getInstance().getSettings().getDatabasePrefix() + t.getCanonicalName());
- new Database<>(getPlugin(), t).loadObjects();
- user.sendMessage(MIGRATED);
- });
+ // Put classSet into classQueue
+ classQueue = new LinkedList<>(classSet);
+ // Start a scheduler to step through these in a reasonable time
+ task = Bukkit.getScheduler().runTaskTimer(getPlugin(), () -> {
+ Class extends DataObject> t = classQueue.poll();
+ if (t != null) {
+ user.sendMessage("commands.bentobox.migrate.class", TextVariables.DESCRIPTION,
+ BentoBox.getInstance().getSettings().getDatabasePrefix() + t.getCanonicalName());
+ new Database<>(getPlugin(), t).loadObjects();
+ user.sendMessage(MIGRATED);
+ } else {
+ user.sendMessage("commands.bentobox.migrate.completed");
+ task.cancel();
+ }
+ }, 0, 20L);
});
return true;
}
diff --git a/src/main/java/world/bentobox/bentobox/database/transition/TransitionDatabaseHandler.java b/src/main/java/world/bentobox/bentobox/database/transition/TransitionDatabaseHandler.java
index c1402be8a..966be709c 100644
--- a/src/main/java/world/bentobox/bentobox/database/transition/TransitionDatabaseHandler.java
+++ b/src/main/java/world/bentobox/bentobox/database/transition/TransitionDatabaseHandler.java
@@ -44,8 +44,16 @@ public class TransitionDatabaseHandler extends AbstractDatabaseHandler {
List listTo = toHandler.loadObjects();
// If source database has objects, then delete and save them in the destination database
for (T object : listFrom) {
- toHandler.saveObject(object);
- fromHandler.deleteObject(object);
+ toHandler.saveObject(object).thenAccept(b -> {
+ // Only delete if save was successful
+ if (b) {
+ try {
+ fromHandler.deleteObject(object);
+ } catch (IllegalAccessException | InvocationTargetException | IntrospectionException e) {
+ plugin.logStacktrace(e);
+ }
+ }
+ });
}
// Merge results
listTo.addAll(listFrom);
diff --git a/src/main/java/world/bentobox/bentobox/nms/v1_21_R0_1_SNAPSHOT/PasteHandlerImpl.java b/src/main/java/world/bentobox/bentobox/nms/v1_21_R0_1_SNAPSHOT/PasteHandlerImpl.java
new file mode 100644
index 000000000..ece376eb2
--- /dev/null
+++ b/src/main/java/world/bentobox/bentobox/nms/v1_21_R0_1_SNAPSHOT/PasteHandlerImpl.java
@@ -0,0 +1,52 @@
+package world.bentobox.bentobox.nms.v1_21_R0_1_SNAPSHOT;
+
+import java.util.concurrent.CompletableFuture;
+
+import org.bukkit.Location;
+import org.bukkit.block.Block;
+import org.bukkit.block.data.BlockData;
+import org.bukkit.craftbukkit.v1_21_R1.CraftWorld;
+import org.bukkit.craftbukkit.v1_21_R1.block.data.CraftBlockData;
+
+import net.minecraft.core.BlockPosition;
+import net.minecraft.world.level.block.state.IBlockData;
+import net.minecraft.world.level.chunk.Chunk;
+import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBlock;
+import world.bentobox.bentobox.database.objects.Island;
+import world.bentobox.bentobox.nms.PasteHandler;
+import world.bentobox.bentobox.util.DefaultPasteUtil;
+import world.bentobox.bentobox.util.Util;
+
+public class PasteHandlerImpl implements PasteHandler {
+
+ protected static final IBlockData AIR = ((CraftBlockData) AIR_BLOCKDATA).getState();
+
+ /**
+ * Set the block to the location
+ *
+ * @param island - island
+ * @param location - location
+ * @param bpBlock - blueprint block
+ */
+ @Override
+ public CompletableFuture setBlock(Island island, Location location, BlueprintBlock bpBlock) {
+ return Util.getChunkAtAsync(location).thenRun(() -> {
+ Block block = location.getBlock();
+ // Set the block data - default is AIR
+ BlockData bd = DefaultPasteUtil.createBlockData(bpBlock);
+ CraftBlockData craft = (CraftBlockData) bd;
+ net.minecraft.world.level.World nmsWorld = ((CraftWorld) location.getWorld()).getHandle();
+ Chunk nmsChunk = nmsWorld.d(location.getBlockX() >> 4, location.getBlockZ() >> 4);
+ BlockPosition bp = new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ());
+ // Setting the block to air before setting to another state prevents some console errors
+ nmsChunk.a(bp, AIR, false);
+ nmsChunk.a(bp, craft.getState(), false);
+ block.setBlockData(bd, false);
+ DefaultPasteUtil.setBlockState(island, block, bpBlock);
+ // Set biome
+ if (bpBlock.getBiome() != null) {
+ block.setBiome(bpBlock.getBiome());
+ }
+ });
+ }
+}
diff --git a/src/main/java/world/bentobox/bentobox/nms/v1_21_R0_1_SNAPSHOT/WorldRegeneratorImpl.java b/src/main/java/world/bentobox/bentobox/nms/v1_21_R0_1_SNAPSHOT/WorldRegeneratorImpl.java
new file mode 100644
index 000000000..6e1e3855f
--- /dev/null
+++ b/src/main/java/world/bentobox/bentobox/nms/v1_21_R0_1_SNAPSHOT/WorldRegeneratorImpl.java
@@ -0,0 +1,26 @@
+package world.bentobox.bentobox.nms.v1_21_R0_1_SNAPSHOT;
+
+import org.bukkit.block.data.BlockData;
+import org.bukkit.craftbukkit.v1_21_R1.CraftWorld;
+import org.bukkit.craftbukkit.v1_21_R1.block.data.CraftBlockData;
+
+import net.minecraft.core.BlockPosition;
+import net.minecraft.world.level.World;
+import net.minecraft.world.level.chunk.Chunk;
+import world.bentobox.bentobox.nms.CopyWorldRegenerator;
+
+public class WorldRegeneratorImpl extends CopyWorldRegenerator {
+
+ @Override
+ public void setBlockInNativeChunk(org.bukkit.Chunk chunk, int x, int y, int z, BlockData blockData,
+ boolean applyPhysics) {
+ CraftBlockData craft = (CraftBlockData) blockData;
+ World nmsWorld = ((CraftWorld) chunk.getWorld()).getHandle();
+ Chunk nmsChunk = nmsWorld.d(chunk.getX(), chunk.getZ());
+ BlockPosition bp = new BlockPosition((chunk.getX() << 4) + x, y, (chunk.getZ() << 4) + z);
+ // Setting the block to air before setting to another state prevents some console errors
+ nmsChunk.a(bp, PasteHandlerImpl.AIR, applyPhysics);
+ nmsChunk.a(bp, craft.getState(), applyPhysics);
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/resources/locales/en-US.yml b/src/main/resources/locales/en-US.yml
index 645ab8e53..1eb99735d 100644
--- a/src/main/resources/locales/en-US.yml
+++ b/src/main/resources/locales/en-US.yml
@@ -514,6 +514,7 @@ commands:
addons: '[prefix_bentobox]&6 Migrating addons'
class: '[prefix_bentobox]&6 Migrating [description]'
migrated: '[prefix_bentobox]&a Migrated'
+ completed: '[prefix_bentobox]&a Completed'
rank:
description: 'list, add, or remove ranks'
parameters: '&a [list | add | remove] [rank reference] [rank value]'