Load chunks before pasting islands. Runs async.

1.15.2 can take a looooong time to load a chunk, sometimes up to 10
seconds.

https://github.com/BentoBoxWorld/BentoBox/issues/1180
This commit is contained in:
tastybento 2020-02-10 20:14:43 -08:00
parent 5e02954a54
commit 9f65537ab8
3 changed files with 21 additions and 11 deletions

View File

@ -41,6 +41,7 @@ import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBlock;
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintCreatureSpawner;
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintEntity;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.managers.BlueprintsManager;
import world.bentobox.bentobox.util.Util;
/**
@ -51,6 +52,8 @@ import world.bentobox.bentobox.util.Util;
public class BlueprintPaster {
enum PasteState {
CHUNK_LOAD,
CHUNK_LOADING,
BLOCKS,
ATTACHMENTS,
ENTITIES,
@ -61,7 +64,7 @@ public class BlueprintPaster {
private static final String MINECRAFT = "minecraft:";
private static final Map<String, String> BLOCK_CONVERSION = ImmutableMap.of("sign", "oak_sign", "wall_sign", "oak_wall_sign");
private BentoBox plugin;
// The minimum block position (x,y,z)
private Location pos1;
@ -150,7 +153,7 @@ public class BlueprintPaster {
Iterator<Entry<Vector, List<BlueprintEntity>>> it3 = entities.entrySet().iterator();
// Initial state & speed
pasteState = PasteState.BLOCKS;
pasteState = PasteState.CHUNK_LOAD;
final int pasteSpeed = plugin.getSettings().getPasteSpeed();
// If this is an island OVERWORLD paste, get the island owner.
@ -161,14 +164,26 @@ public class BlueprintPaster {
owner.ifPresent(user -> {
// Estimated time:
double total = (double) blocks.size() + attached.size() + entities.size();
BigDecimal time = BigDecimal.valueOf(total / (pasteSpeed * 20.0D)).setScale(1, RoundingMode.UP);
BigDecimal time = BigDecimal.valueOf(total / (pasteSpeed * 20.0D) + (BlueprintsManager.chunkLoadTime / 1000)).setScale(1, RoundingMode.UP);
user.sendMessage("commands.island.create.pasting.estimated-time", TextVariables.NUMBER, String.valueOf(time.doubleValue()));
// We're pasting blocks!
user.sendMessage("commands.island.create.pasting.blocks", TextVariables.NUMBER, String.valueOf(blocks.size() + attached.size()));
});
pastingTask = Bukkit.getScheduler().runTaskTimer(plugin, () -> {
long timer = System.currentTimeMillis();
int count = 0;
if (pasteState.equals(PasteState.CHUNK_LOAD)) {
pasteState = PasteState.CHUNK_LOADING;
// Load chunk
Util.getChunkAtAsync(location).thenRun(() -> {
pasteState = PasteState.BLOCKS;
long duration = System.currentTimeMillis() - timer;
if (duration > BlueprintsManager.chunkLoadTime) {
BlueprintsManager.chunkLoadTime = duration;
}
});
}
while (pasteState.equals(PasteState.BLOCKS) && count < pasteSpeed && it.hasNext()) {
pasteBlock(location, it.next());
count++;
@ -221,6 +236,7 @@ public class BlueprintPaster {
World world = location.getWorld();
Location pasteTo = location.clone().add(entry.getKey());
BlueprintBlock bpBlock = entry.getValue();
Block block = pasteTo.getBlock();
// Set the block data - default is AIR
BlockData bd;

View File

@ -60,6 +60,8 @@ public class BlueprintsManager {
public static final @NonNull String FOLDER_NAME = "blueprints";
private static final String FOR = "' for ";
public static long chunkLoadTime = 0;
/**
* Map of blueprint bundles to game mode addon.

View File

@ -187,25 +187,19 @@ public class NewIsland {
throw new IOException("commands.island.create.unable-create-island");
}
}
// Clear any old home locations (they should be clear, but just in case)
plugin.getPlayers().clearHomeLocations(world, user.getUniqueId());
// Set home location
plugin.getPlayers().setHomeLocation(user, new Location(next.getWorld(), next.getX() + 0.5D, next.getY(), next.getZ() + 0.5D), 1);
// Reset deaths
if (plugin.getIWM().isDeathsResetOnNewIsland(world)) {
plugin.getPlayers().setDeaths(world, user.getUniqueId(), 0);
}
// Check if owner has a different range permission than the island size
island.setProtectionRange(user.getPermissionValue(plugin.getIWM().getAddon(island.getWorld())
.map(GameModeAddon::getPermissionPrefix).orElse("") + "island.range", island.getProtectionRange()));
// Save the player so that if the server crashes weird things won't happen
plugin.getPlayers().save(user.getUniqueId());
// Fire event
IslandBaseEvent event = IslandEvent.builder()
.involvedPlayer(user.getUniqueId())
@ -217,7 +211,6 @@ public class NewIsland {
if (event.isCancelled()) {
return;
}
// Get the new BlueprintBundle if it was changed
switch (reason) {
case CREATE:
@ -241,7 +234,6 @@ public class NewIsland {
if (reason.equals(Reason.RESET) || (reason.equals(Reason.CREATE) && plugin.getIWM().isTeleportPlayerToIslandUponIslandCreation(world))) {
user.getPlayer().setVelocity(new Vector(0, 0, 0));
user.getPlayer().setFallDistance(0F);
// Teleport player after this island is built
plugin.getIslands().homeTeleport(world, user.getPlayer(), true);
} else {