From 6796fceee883f2bf5b4e769438a440f9d0267d35 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sat, 19 Mar 2022 16:19:31 +0000 Subject: [PATCH] Clearer paster (#1953) * WIP - make easier to understand. * Small refactor of paster to make it easier to understand * Fix tabs to spaces. Sorry - new editor! * Fix tabs to spaces * Fix tab to spaces --- .../team/IslandTeamInviteAcceptCommand.java | 2 +- .../api/panels/reader/TemplateReader.java | 38 ++--- .../bentobox/blueprints/BlueprintPaster.java | 159 ++++++++++-------- 3 files changed, 105 insertions(+), 94 deletions(-) diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteAcceptCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteAcceptCommand.java index fa2615156..bc5ceb271 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteAcceptCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteAcceptCommand.java @@ -21,7 +21,7 @@ import world.bentobox.bentobox.util.Util; public class IslandTeamInviteAcceptCommand extends ConfirmableCommand { private static final String INVALID_INVITE = "commands.island.team.invite.errors.invalid-invite"; - private final IslandTeamCommand itc; + private final IslandTeamCommand itc; private UUID playerUUID; private UUID prospectiveOwnerUUID; diff --git a/src/main/java/world/bentobox/bentobox/api/panels/reader/TemplateReader.java b/src/main/java/world/bentobox/bentobox/api/panels/reader/TemplateReader.java index 52931219a..4407ae8d2 100644 --- a/src/main/java/world/bentobox/bentobox/api/panels/reader/TemplateReader.java +++ b/src/main/java/world/bentobox/bentobox/api/panels/reader/TemplateReader.java @@ -41,12 +41,12 @@ public class TemplateReader private static final String BORDER = "border"; private static final String FORCE_SHOWN = "force-shown"; private static final String FALLBACK = "fallback"; - private static final String YML = ".yml"; - private static final String ACTIONS = "actions"; - private static final String TOOLTIP = "tooltip"; - private static final String CLICK_TYPE = "click-type"; - private static final String CONTENT = "content"; - private static final String TYPE = "type"; + private static final String YML = ".yml"; + private static final String ACTIONS = "actions"; + private static final String TOOLTIP = "tooltip"; + private static final String CLICK_TYPE = "click-type"; + private static final String CONTENT = "content"; + private static final String TYPE = "type"; /** @@ -88,7 +88,7 @@ public class TemplateReader } final String panelKey = file.getAbsolutePath() + ":" + panelName; - + // Check if panel is already crafted. if (TemplateReader.loadedPanels.containsKey(panelKey)) { @@ -373,14 +373,14 @@ public class TemplateReader if (actionDataSection != null && actionDataSection.contains(CLICK_TYPE)) { clickType = Enums.getIfPresent(ClickType.class, - actionDataSection.getString(CLICK_TYPE, "UNKNOWN").toUpperCase()). - or(ClickType.UNKNOWN); - + actionDataSection.getString(CLICK_TYPE, "UNKNOWN").toUpperCase()). + or(ClickType.UNKNOWN); + ItemTemplateRecord.ActionRecords actionData = - new ItemTemplateRecord.ActionRecords(clickType, - actionKey, - actionDataSection.getString(CONTENT), - actionDataSection.getString(TOOLTIP)); + new ItemTemplateRecord.ActionRecords(clickType, + actionKey, + actionDataSection.getString(CONTENT), + actionDataSection.getString(TOOLTIP)); itemRecord.addAction(actionData); } } @@ -397,15 +397,15 @@ public class TemplateReader { actionList.forEach(valueMap -> { ClickType clickType = Enums.getIfPresent(ClickType.class, - String.valueOf(valueMap.get(CLICK_TYPE)).toUpperCase()).orNull(); + String.valueOf(valueMap.get(CLICK_TYPE)).toUpperCase()).orNull(); if (clickType != null) { ItemTemplateRecord.ActionRecords actionData = - new ItemTemplateRecord.ActionRecords(clickType, - valueMap.containsKey(TYPE) ? String.valueOf(valueMap.get(TYPE)) : null, - valueMap.containsKey(CONTENT) ? String.valueOf(valueMap.get(CONTENT)) : null, - valueMap.containsKey(TOOLTIP) ? String.valueOf(valueMap.get(TOOLTIP)) : null); + new ItemTemplateRecord.ActionRecords(clickType, + valueMap.containsKey(TYPE) ? String.valueOf(valueMap.get(TYPE)) : null, + valueMap.containsKey(CONTENT) ? String.valueOf(valueMap.get(CONTENT)) : null, + valueMap.containsKey(TOOLTIP) ? String.valueOf(valueMap.get(TOOLTIP)) : null); itemRecord.addAction(actionData); } }); diff --git a/src/main/java/world/bentobox/bentobox/blueprints/BlueprintPaster.java b/src/main/java/world/bentobox/bentobox/blueprints/BlueprintPaster.java index 6528f58bd..c91cc14b0 100644 --- a/src/main/java/world/bentobox/bentobox/blueprints/BlueprintPaster.java +++ b/src/main/java/world/bentobox/bentobox/blueprints/BlueprintPaster.java @@ -134,99 +134,110 @@ public class BlueprintPaster { this.location = island.getProtectionCenter().toVector().subtract(off).toLocation(world); } + private record Bits(Map blocks, + Map attached, + Map> entities, + Iterator> it, + Iterator> it2, + Iterator>> it3, + int pasteSpeed) {} /** * The main pasting method */ public CompletableFuture paste() { CompletableFuture result = new CompletableFuture<>(); // Iterators for the various maps to paste - Map blocks = blueprint.getBlocks() == null ? Collections.emptyMap() : blueprint.getBlocks(); - Map attached = blueprint.getAttached() == null ? Collections.emptyMap() : blueprint.getAttached(); - Map> entities = blueprint.getEntities() == null ? Collections.emptyMap() : blueprint.getEntities(); - Iterator> it = blocks.entrySet().iterator(); - Iterator> it2 = attached.entrySet().iterator(); - Iterator>> it3 = entities.entrySet().iterator(); + final Map blocks = blueprint.getBlocks() == null ? Collections.emptyMap() : blueprint.getBlocks(); + final Map attached = blueprint.getAttached() == null ? Collections.emptyMap() : blueprint.getAttached(); + final Map> entities = blueprint.getEntities() == null ? Collections.emptyMap() : blueprint.getEntities(); // Initial state & speed pasteState = PasteState.CHUNK_LOAD; - final int pasteSpeed = plugin.getSettings().getPasteSpeed(); // If this is an island OVERWORLD paste, get the island owner. final Optional owner = Optional.ofNullable(island) .filter(i -> location.getWorld().getEnvironment().equals(World.Environment.NORMAL)) .map(i -> User.getInstance(i.getOwner())); // Tell the owner we're pasting blocks and how much time it might take - owner.ifPresent(user -> { - // Estimated time: - double total = (double) blocks.size() + attached.size() + entities.size(); - BigDecimal time = BigDecimal.valueOf(total / (pasteSpeed * 20.0D) + (chunkLoadTime / 1000.0D)).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 > chunkLoadTime) { - chunkLoadTime = duration; - } - }); - } - while (pasteState.equals(PasteState.BLOCKS) && count < pasteSpeed && it.hasNext()) { - pasteBlock(location, it.next()); - count++; - } - while (pasteState.equals(PasteState.ATTACHMENTS) && count < pasteSpeed && it2.hasNext()) { - pasteBlock(location, it2.next()); - count++; - } - while (pasteState.equals(PasteState.ENTITIES) && count < pasteSpeed && it3.hasNext()) { - pasteEntity(location, it3.next()); - count++; - } - // STATE SHIFT - if (pasteState.equals(PasteState.BLOCKS) && !it.hasNext()) { - // Blocks done - // Next paste attachments - pasteState = PasteState.ATTACHMENTS; - } - else if (pasteState.equals(PasteState.ATTACHMENTS) && !it2.hasNext()) { - // Attachments done. Next paste entities - pasteState = PasteState.ENTITIES; - if (entities.size() != 0) { - owner.ifPresent(user -> user.sendMessage("commands.island.create.pasting.entities", TextVariables.NUMBER, String.valueOf(entities.size()))); - } - } - else if (pasteState.equals(PasteState.ENTITIES) && !it3.hasNext()) { - pasteState = PasteState.DONE; - owner.ifPresent(user -> user.sendMessage("commands.island.create.pasting.done")); - } - else if (pasteState.equals(PasteState.DONE)) { - // All done. Cancel task - // Set pos1 and 2 if this was a clipboard paste - if (island == null && clipboard != null) { - clipboard.setPos1(pos1); - clipboard.setPos2(pos2); - } - result.complete(true); - pasteState = PasteState.CANCEL; - } else if (pasteState.equals(PasteState.CANCEL)) { - // This state makes sure the follow-on task only ever runs once - pastingTask.cancel(); - result.complete(true); - } - }, 0L, 1L); + owner.ifPresent(user -> tellOwner(user, blocks.size(), attached.size(), entities.size(), plugin.getSettings().getPasteSpeed())); + Bits bits = new Bits(blocks, attached, entities, + blocks.entrySet().iterator(), attached.entrySet().iterator(), entities.entrySet().iterator(), + plugin.getSettings().getPasteSpeed()); + pastingTask = Bukkit.getScheduler().runTaskTimer(plugin, () -> pasterTask(result, owner, bits), 0L, 1L); return result; } + private void pasterTask(CompletableFuture result, Optional owner, Bits bits) { + final int pasteSpeed = plugin.getSettings().getPasteSpeed(); + + 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 > chunkLoadTime) { + chunkLoadTime = duration; + } + }); + } + while (pasteState.equals(PasteState.BLOCKS) && count < pasteSpeed && bits.it.hasNext()) { + pasteBlock(location, bits.it.next()); + count++; + } + while (pasteState.equals(PasteState.ATTACHMENTS) && count < pasteSpeed && bits.it2.hasNext()) { + pasteBlock(location, bits.it2.next()); + count++; + } + while (pasteState.equals(PasteState.ENTITIES) && count < pasteSpeed && bits.it3.hasNext()) { + pasteEntity(location, bits.it3.next()); + count++; + } + // STATE SHIFT + if (pasteState.equals(PasteState.BLOCKS) && !bits.it.hasNext()) { + // Blocks done + // Next paste attachments + pasteState = PasteState.ATTACHMENTS; + } + else if (pasteState.equals(PasteState.ATTACHMENTS) && !bits.it2.hasNext()) { + // Attachments done. Next paste entities + pasteState = PasteState.ENTITIES; + if (bits.entities.size() != 0) { + owner.ifPresent(user -> user.sendMessage("commands.island.create.pasting.entities", TextVariables.NUMBER, String.valueOf(bits.entities.size()))); + } + } + else if (pasteState.equals(PasteState.ENTITIES) && !bits.it3.hasNext()) { + pasteState = PasteState.DONE; + owner.ifPresent(user -> user.sendMessage("commands.island.create.pasting.done")); + } + else if (pasteState.equals(PasteState.DONE)) { + // All done. Cancel task + // Set pos1 and 2 if this was a clipboard paste + if (island == null && clipboard != null) { + clipboard.setPos1(pos1); + clipboard.setPos2(pos2); + } + pasteState = PasteState.CANCEL; + result.complete(true); + } else if (pasteState.equals(PasteState.CANCEL)) { + // This state makes sure the follow-on task only ever runs once + pastingTask.cancel(); + result.complete(true); + } + } + + private void tellOwner(User user, int blocksSize, int attachedSize, int entitiesSize, int pasteSpeed) { + // Estimated time: + double total = (double) blocksSize + attachedSize + entitiesSize; + BigDecimal time = BigDecimal.valueOf(total / (pasteSpeed * 20.0D) + (chunkLoadTime / 1000.0D)).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(blocksSize + attachedSize)); + } + private void pasteBlock(Location location, Entry entry) { World world = location.getWorld(); Location pasteTo = location.clone().add(entry.getKey());