From a6a0b5eb6609b376cbcafa4bf86117dff60e7d41 Mon Sep 17 00:00:00 2001 From: Hannes Greule Date: Sat, 27 Aug 2022 16:48:54 +0200 Subject: [PATCH 01/16] fix: avoid recursive LegacyMapper initialization (#1922) --- .../factory/parser/DefaultBlockParser.java | 2 +- .../sk89q/worldedit/world/block/BlockTypes.java | 17 +++++++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java index e37e5b0fa..4d8523f84 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java @@ -455,7 +455,7 @@ public class DefaultBlockParser extends InputParser { state = item.getType().getBlockType().getDefaultState(); nbt = item.getNbtData(); } else { - BlockType type = BlockTypes.parse(typeString.toLowerCase(Locale.ROOT)); + BlockType type = BlockTypes.parse(typeString.toLowerCase(Locale.ROOT), context); if (type != null) { state = type.getDefaultState(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java index 152c4df9b..47e083809 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java @@ -23,6 +23,7 @@ import com.fastasyncworldedit.core.command.SuggestInputParseException; import com.fastasyncworldedit.core.util.JoinedCharSequence; import com.fastasyncworldedit.core.util.StringMan; import com.sk89q.worldedit.extension.input.InputParseException; +import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.world.registry.LegacyMapper; import javax.annotation.Nullable; @@ -1948,6 +1949,9 @@ public final class BlockTypes { */ public static BlockType parse(final String type) throws InputParseException { + return parse(type, new ParserContext()); + } + public static BlockType parse(final String type, final ParserContext context) throws InputParseException { final String inputLower = type.toLowerCase(Locale.ROOT); String input = inputLower; @@ -1958,13 +1962,14 @@ public final class BlockTypes { if (result != null) { return result; } - - try { - BlockStateHolder block = LegacyMapper.getInstance().getBlockFromLegacy(input); - if (block != null) { - return block.getBlockType(); + if (context.isTryingLegacy()) { + try { + BlockStateHolder block = LegacyMapper.getInstance().getBlockFromLegacy(input); + if (block != null) { + return block.getBlockType(); + } + } catch (NumberFormatException | IndexOutOfBoundsException ignored) { } - } catch (NumberFormatException | IndexOutOfBoundsException ignored) { } throw new SuggestInputParseException("Does not match a valid block type: " + inputLower, inputLower, () -> Stream.of( -- 2.39.2 From a51863c6f006f2a3587e4dd16bf565ed1d229fd3 Mon Sep 17 00:00:00 2001 From: Hannes Greule Date: Sat, 27 Aug 2022 16:49:01 +0200 Subject: [PATCH 02/16] fix: use proper level data for regen (#1921) --- .../impl/fawe/v1_17_R1_2/regen/PaperweightRegen.java | 9 +++++---- .../impl/fawe/v1_18_R2/regen/PaperweightRegen.java | 5 ++--- .../impl/fawe/v1_19_R1/regen/PaperweightRegen.java | 5 ++--- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/regen/PaperweightRegen.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/regen/PaperweightRegen.java index 6ea695d8c..3d9694af9 100644 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/regen/PaperweightRegen.java +++ b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/regen/PaperweightRegen.java @@ -79,6 +79,7 @@ import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.OptionalLong; import java.util.Random; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; @@ -217,10 +218,10 @@ public class PaperweightRegen extends Regenerator Date: Mon, 29 Aug 2022 17:21:21 +0200 Subject: [PATCH 03/16] Update upstream 7e61ff1 Work around invalid legacy values in schematics (2171) --- .../extent/clipboard/io/MCEditSchematicReader.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/MCEditSchematicReader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/MCEditSchematicReader.java index 760598ad5..aebef3e9a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/MCEditSchematicReader.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/MCEditSchematicReader.java @@ -484,7 +484,12 @@ public class MCEditSchematicReader extends NBTSchematicReader { } private BlockState getBlockState(int id, int data) { - return LegacyMapper.getInstance().getBlockFromLegacy(id, data); + BlockState foundBlock = LegacyMapper.getInstance().getBlockFromLegacy(id, data); + if (foundBlock == null && data != 0) { + // Some schematics contain invalid data values, so try without the data value + return LegacyMapper.getInstance().getBlockFromLegacy(id, 0); + } + return foundBlock; } @Override -- 2.39.2 From 8233f132d4ac56129b74e6ccc527abbd3b2aeec2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Aug 2022 21:31:06 +0200 Subject: [PATCH 04/16] Update dependency com.github.TownyAdvanced:Towny to v0.98.3.6 (#1926) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 689fb110a..a992f52bc 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ griefprevention = "16.18" griefdefender = "2.1.0-SNAPSHOT" mcore = "7.0.1" residence = "4.5._13.1" -towny = "0.98.3.5" +towny = "0.98.3.6" redprotect = "1.9.6" # Third party -- 2.39.2 From 3b109ba3ffd73deafcfa03e592068b5c8b666ac9 Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Sun, 4 Sep 2022 23:30:02 +0200 Subject: [PATCH 05/16] Upload files to curseforge on release (#1929) * chore: Upload files to curseforge on release * chore: Use direct artifact path --- .github/workflows/upload-release-assets.yml | 23 +++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/.github/workflows/upload-release-assets.yml b/.github/workflows/upload-release-assets.yml index 93587ed76..423c49802 100644 --- a/.github/workflows/upload-release-assets.yml +++ b/.github/workflows/upload-release-assets.yml @@ -26,3 +26,26 @@ jobs: files: 'worldedit-bukkit/build/libs/FastAsyncWorldEdit-Bukkit-*.jar' repo-token: ${{ secrets.GITHUB_TOKEN }} release-tag: ${{ github.event.release.tag_name }} + + upload-to-curseforge: + runs-on: ubuntu-latest + steps: + - uses: Kir-Antipov/mc-publish@v3.2 + with: + curseforge-id: 103525 + curseforge-token: ${{ secrets.CURSEFORGE_TOKEN }} + + files-primary: worldedit-bukkit/build/libs/FastAsyncWorldEdit-Bukkit-*.jar + + name: FastAsyncWorldEdit ${{ github.event.release.tag_name }} + version: ${{ github.event.release.tag_name }} + version-type: release + + game-versions: | + 1.19.1 + 1.19 + 1.18.2 + 1.18.1 + 1.18 + 1.17 + 1.16 -- 2.39.2 From 5da558e24c9e13b91327063c07a687d140dfdd46 Mon Sep 17 00:00:00 2001 From: Hannes Greule Date: Sun, 4 Sep 2022 23:30:32 +0200 Subject: [PATCH 06/16] feature: support paper chunk system (#1884) * avoid usage of ticking chunk future on paper * fix entity handling * fix entity handling but on spigot * seems like no one uses spigot Co-authored-by: Alexander Brandes --- .../PaperweightPlatformAdapter.java | 2 +- .../v1_18_R2/PaperweightPlatformAdapter.java | 2 +- .../fawe/v1_19_R1/PaperweightFaweAdapter.java | 17 -------------- .../fawe/v1_19_R1/PaperweightGetBlocks.java | 2 +- .../v1_19_R1/PaperweightPlatformAdapter.java | 22 +++++++++++-------- .../sk89q/worldedit/bukkit/BukkitWorld.java | 9 +++----- 6 files changed, 19 insertions(+), 35 deletions(-) diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightPlatformAdapter.java index 4b446d620..3ea9df730 100644 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightPlatformAdapter.java @@ -473,7 +473,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { } static List getEntities(LevelChunk chunk) { - return chunk.level.entityManager.getEntities(new ChunkPos(chunk.locX, chunk.locZ)); + return chunk.level.entityManager.getEntities(chunk.getPos()); } } diff --git a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightPlatformAdapter.java index 8546de630..9de310b96 100644 --- a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightPlatformAdapter.java @@ -588,7 +588,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { } static List getEntities(LevelChunk chunk) { - return chunk.level.entityManager.getEntities(new ChunkPos(chunk.locX, chunk.locZ)); + return chunk.level.entityManager.getEntities(chunk.getPos()); } record FakeIdMapBlock(int size) implements IdMap { diff --git a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightFaweAdapter.java index 997e11e21..f05648b0d 100644 --- a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightFaweAdapter.java @@ -585,23 +585,6 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements return true; } - @Override - public List getEntities(org.bukkit.World world) { - // Quickly add each entity to a list copy. - List mcEntities = new ArrayList<>(); - ((CraftWorld) world).getHandle().entityManager.getEntityGetter().getAll().forEach(mcEntities::add); - - List list = new ArrayList<>(); - mcEntities.forEach((mcEnt) -> { - org.bukkit.entity.Entity bukkitEntity = mcEnt.getBukkitEntity(); - if (bukkitEntity.isValid()) { - list.add(bukkitEntity); - } - - }); - return list; - } - @Override public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) { final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); diff --git a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightGetBlocks.java index 3c543d2c7..9ee467201 100644 --- a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightGetBlocks.java @@ -676,7 +676,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } if (Settings.settings().EXPERIMENTAL.REMOVE_ENTITY_FROM_WORLD_ON_CHUNK_FAIL) { for (UUID uuid : entityRemoves) { - Entity entity = nmsWorld.entityManager.getEntityGetter().get(uuid); + Entity entity = nmsWorld.getEntities().get(uuid); if (entity != null) { removeEntity(entity); } diff --git a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightPlatformAdapter.java index aa87aceea..307a52d77 100644 --- a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightPlatformAdapter.java @@ -278,20 +278,21 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { return; } ChunkPos coordIntPair = new ChunkPos(chunkX, chunkZ); - // UNLOADED_CHUNK - Optional optional = ((Either) chunkHolder - .getTickingChunkFuture() - .getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).left(); + LevelChunk levelChunk; if (PaperLib.isPaper()) { // getChunkAtIfLoadedImmediately is paper only - optional = optional.or(() -> Optional.ofNullable(nmsWorld + levelChunk = nmsWorld .getChunkSource() - .getChunkAtIfLoadedImmediately(chunkX, chunkZ))); + .getChunkAtIfLoadedImmediately(chunkX, chunkZ); + } else { + levelChunk = ((Optional) ((Either) chunkHolder + .getTickingChunkFuture() // method is not present with new paper chunk system + .getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).left()) + .orElse(null); } - if (optional.isEmpty()) { + if (levelChunk == null) { return; } - LevelChunk levelChunk = optional.get(); TaskManager.taskManager().task(() -> { ClientboundLevelChunkWithLightPacket packet; if (PaperLib.isPaper()) { @@ -589,7 +590,10 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { } static List getEntities(LevelChunk chunk) { - return chunk.level.entityManager.getEntities(new ChunkPos(chunk.locX, chunk.locZ)); + if (PaperLib.isPaper()) { + return Arrays.asList(chunk.entities.getRawData()); + } + return chunk.level.entityManager.getEntities(chunk.getPos()); } record FakeIdMapBlock(int size) implements IdMap { diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java index 7530c41ed..66bf6648f 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java @@ -141,10 +141,9 @@ public class BukkitWorld extends AbstractWorld { @Override public List getEntities(Region region) { - //FAWE start - allow async entity retrieval - List ents = WorldEditPlugin.getInstance().getBukkitImplAdapter().getEntities(getWorld()); - //FAWE end + World world = getWorld(); + List ents = world.getEntities(); List entities = new ArrayList<>(); for (Entity ent : ents) { if (region.contains(BukkitAdapter.asBlockVector(ent.getLocation()))) { @@ -157,9 +156,7 @@ public class BukkitWorld extends AbstractWorld { @Override public List getEntities() { List list = new ArrayList<>(); - //FAWE start - allow async entity retrieval - for (Entity entity : WorldEditPlugin.getInstance().getBukkitImplAdapter().getEntities(getWorld())) { - //FAWE end + for (Entity entity : getWorld().getEntities()) { list.add(BukkitAdapter.adapt(entity)); } return list; -- 2.39.2 From 122b32b9f04e1e4b314cc041d90af4d6cc4e56af Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Mon, 5 Sep 2022 11:26:31 +0200 Subject: [PATCH 07/16] Release 2.4.5 --- .github/workflows/upload-release-assets.yml | 9 +++------ build.gradle.kts | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/.github/workflows/upload-release-assets.yml b/.github/workflows/upload-release-assets.yml index 423c49802..cbfa9eafa 100644 --- a/.github/workflows/upload-release-assets.yml +++ b/.github/workflows/upload-release-assets.yml @@ -26,16 +26,13 @@ jobs: files: 'worldedit-bukkit/build/libs/FastAsyncWorldEdit-Bukkit-*.jar' repo-token: ${{ secrets.GITHUB_TOKEN }} release-tag: ${{ github.event.release.tag_name }} - - upload-to-curseforge: - runs-on: ubuntu-latest - steps: - - uses: Kir-Antipov/mc-publish@v3.2 + - name: Upload release to CurseForge + uses: Kir-Antipov/mc-publish@v3.2 with: curseforge-id: 103525 curseforge-token: ${{ secrets.CURSEFORGE_TOKEN }} - files-primary: worldedit-bukkit/build/libs/FastAsyncWorldEdit-Bukkit-*.jar + files-primary: 'worldedit-bukkit/build/libs/FastAsyncWorldEdit-Bukkit-*.jar' name: FastAsyncWorldEdit ${{ github.event.release.tag_name }} version: ${{ github.event.release.tag_name }} diff --git a/build.gradle.kts b/build.gradle.kts index 7ea9ffb46..af6b84df8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -41,7 +41,7 @@ ext { } } -version = String.format("%s-%s", rootVersion, buildNumber) +version = String.format("%s", rootVersion) if (!project.hasProperty("gitCommitHash")) { apply(plugin = "org.ajoberstar.grgit") -- 2.39.2 From 673b467ad9e8b6e5e35a9f50e87864c205b4ac3e Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Mon, 5 Sep 2022 11:29:51 +0200 Subject: [PATCH 08/16] Back to snapshot for development --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index af6b84df8..7ea9ffb46 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -41,7 +41,7 @@ ext { } } -version = String.format("%s", rootVersion) +version = String.format("%s-%s", rootVersion, buildNumber) if (!project.hasProperty("gitCommitHash")) { apply(plugin = "org.ajoberstar.grgit") -- 2.39.2 From dd8ed8d5c68f0dcf5c8e0063821dc5190240ffa3 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Tue, 6 Sep 2022 21:34:07 +0200 Subject: [PATCH 09/16] Move clipboards to temp --- .../sk89q/worldedit/bukkit/BukkitPlayer.java | 2 +- .../clipboard/DiskOptimizedClipboard.java | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java index acfd5cacd..f5ae8fbc2 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java @@ -110,7 +110,7 @@ public class BukkitPlayer extends AbstractPlayerActor { if (player != null && Settings.settings().CLIPBOARD.USE_DISK) { BukkitPlayer cached = WorldEditPlugin.getInstance().getCachedPlayer(player); if (cached == null) { - loadClipboardFromDisk(); + //loadClipboardFromDisk(); } } //FAWE end diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/DiskOptimizedClipboard.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/DiskOptimizedClipboard.java index acdf9fad7..f87fd5afa 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/DiskOptimizedClipboard.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/DiskOptimizedClipboard.java @@ -71,16 +71,25 @@ public class DiskOptimizedClipboard extends LinearClipboard { private boolean canHaveBiomes = true; private int nbtBytesRemaining; + private static File createTmpFile() { + File temp; + try { + temp = File.createTempFile("fawe", ".bd"); + } catch (IOException e) { + throw new RuntimeException(e); + } + temp.deleteOnExit(); + + return temp; + } + /** * Creates a new DiskOptimizedClipboard for the given region. Creates or overwrites a file using the given UUID as a name. */ public DiskOptimizedClipboard(Region region, UUID uuid) { this( region.getDimensions(), - MainUtil.getFile( - Fawe.instance() != null ? Fawe.platform().getDirectory() : new File("."), - Settings.settings().PATHS.CLIPBOARD + File.separator + uuid + ".bd" - ) + createTmpFile() ); setOffset(region.getMinimumPoint()); setOrigin(region.getMinimumPoint()); -- 2.39.2 From 2547fd590d138ac8841e1b4d139449a8aba7817b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 12 Sep 2022 11:16:14 +0200 Subject: [PATCH 10/16] Update dependency org.mockito:mockito-core to v4.8.0 (#1940) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- worldedit-sponge/build.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a992f52bc..2a9522e71 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -38,7 +38,7 @@ text = "3.0.4" piston = "0.5.7" # Tests -mockito = "4.7.0" +mockito = "4.8.0" # Gradle plugins pluginyml = "0.5.2" diff --git a/worldedit-sponge/build.gradle.kts b/worldedit-sponge/build.gradle.kts index 20b9d7b68..befd85873 100644 --- a/worldedit-sponge/build.gradle.kts +++ b/worldedit-sponge/build.gradle.kts @@ -28,7 +28,7 @@ dependencies { }) api("org.apache.logging.log4j:log4j-api") api("org.bstats:bstats-sponge:1.7") - testImplementation("org.mockito:mockito-core:4.7.0") + testImplementation("org.mockito:mockito-core:4.8.0") } <<<<<<< HEAD -- 2.39.2 From c819031d1fac76b404720d9fb62952e877e24a83 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 12 Sep 2022 11:18:46 +0200 Subject: [PATCH 11/16] [ci skip] Update dependency com.github.TownyAdvanced:Towny to v0.98.3.8 (#1936) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2a9522e71..b6a7f4236 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ griefprevention = "16.18" griefdefender = "2.1.0-SNAPSHOT" mcore = "7.0.1" residence = "4.5._13.1" -towny = "0.98.3.6" +towny = "0.98.3.8" redprotect = "1.9.6" # Third party -- 2.39.2 From 1706d64ddf943aa827332aa0b02337cb9fe5888b Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Thu, 15 Sep 2022 21:19:31 +0200 Subject: [PATCH 12/16] Retrieve the latest asset release version automatically (#1947) * feat: retrieve the latest release version automatically (cherry picked from commit a8885a349a567849f6db29565cc65b14e3dab155) * feat/fix: validate hash of downloaded asset file * chore: address review comments Usage of nio Path instead of direct File access Usage of HexFormat instead of custom implementation No need for usage of channels * chore: simplified sha-1 calculation logic Co-authored-by: Pierre Maurice Schwang --- .../core/util/TextureUtil.java | 127 ++++++++++++++++-- 1 file changed, 117 insertions(+), 10 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java index 21771867a..6261249fc 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java @@ -5,6 +5,9 @@ import com.fastasyncworldedit.core.configuration.Settings; import com.fastasyncworldedit.core.extent.filter.block.SingleFilterBlock; import com.fastasyncworldedit.core.util.image.ImageUtil; import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import com.google.gson.reflect.TypeToken; import com.google.gson.stream.JsonReader; import com.sk89q.worldedit.extent.clipboard.Clipboard; @@ -24,19 +27,27 @@ import org.apache.logging.log4j.Logger; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.BufferedInputStream; +import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.OutputStream; import java.lang.reflect.Type; import java.net.URL; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.DigestOutputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; +import java.util.HexFormat; import java.util.List; import java.util.Locale; import java.util.Map; @@ -321,6 +332,8 @@ public class TextureUtil implements TextureHolder { new BiomeColor(253, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F), new BiomeColor(254, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F), new BiomeColor(255, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F)}; + + private static final String VERSION_MANIFEST = "https://piston-meta.mojang.com/mc/game/version_manifest.json"; private final BlockType[] layerBuffer = new BlockType[2]; protected int[] blockColors = new int[BlockTypes.size()]; protected long[] blockDistance = new long[BlockTypes.size()]; @@ -352,17 +365,43 @@ public class TextureUtil implements TextureHolder { try { LOGGER.info("Downloading asset jar from Mojang, please wait..."); new File(Fawe.platform().getDirectory() + "/" + Settings.settings().PATHS.TEXTURES + "/").mkdirs(); - try (BufferedInputStream in = new BufferedInputStream( - new URL("https://piston-data.mojang.com/v1/objects/c0898ec7c6a5a2eaa317770203a1554260699994/client.jar") - .openStream()); - FileOutputStream fileOutputStream = new FileOutputStream( - Fawe.platform().getDirectory() + "/" + Settings.settings().PATHS.TEXTURES + "/1.19.2.jar")) { - byte[] dataBuffer = new byte[1024]; - int bytesRead; - while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) { - fileOutputStream.write(dataBuffer, 0, bytesRead); + + try { + VersionMetadata metadata = getLatestVersion(); + LOGGER.info("Latest release version is {}", metadata.version()); + HashedResource resource = getLatestClientJarUrl(metadata); + + Path out = Path.of( + Fawe.platform().getDirectory().getPath(), + Settings.settings().PATHS.TEXTURES, + metadata.version() + ".jar" + ); + // Copy resource to local fs + try (final InputStream stream = new URL(resource.resource()).openStream(); + final OutputStream writer = Files.newOutputStream(out)) { + stream.transferTo(writer); } - LOGGER.info("Asset jar down has been downloaded successfully."); + // Validate sha-1 hash + try { + final String sha1 = calculateSha1(out); + if (!sha1.equals(resource.hash())) { + Files.deleteIfExists(out); + LOGGER.error( + "Hash comparison of final file failed (Expected: '{}', Calculated: '{}')", + resource.hash(), sha1 + ); + LOGGER.error("To prevent possibly malicious intentions, the downloaded file has been removed"); + return; + } + } catch (NoSuchAlgorithmException e) { + LOGGER.warn("Couldn't verify integrity of downloaded client file"); + LOGGER.warn( + "Please verify that the downloaded files '{}' hash is equal to '{}'", + out, resource.hash() + ); + return; + } + LOGGER.info("Asset jar has been downloaded and validated successfully."); } catch (IOException e) { LOGGER.error( "Could not download version jar. Please do so manually by creating a `FastAsyncWorldEdit/textures` " + @@ -555,6 +594,66 @@ public class TextureUtil implements TextureHolder { return totalDistSqr / area; } + /** + * Retrieves the minecraft versions manifest (containing all released versions) and returns the first {@code release} + * version (latest) + * + * @return {@link VersionMetadata} containing the id (= version) and url to the client manifest itself + * @throws IOException If any http / i/o operation fails. + * @since TODO + */ + private static VersionMetadata getLatestVersion() throws IOException { + try (BufferedInputStream in = new BufferedInputStream(new URL(VERSION_MANIFEST).openStream()); + BufferedReader reader = new BufferedReader(new InputStreamReader(in))) { + final JsonElement element = JsonParser.parseReader(reader); + for (final JsonElement versions : element.getAsJsonObject().getAsJsonArray("versions")) { + JsonObject version = versions.getAsJsonObject(); + if (!version.get("type").getAsString().equals("release")) { + continue; + } + final String clientJsonUrl = version.get("url").getAsString(); + final String id = version.get("id").getAsString(); + return new VersionMetadata(id, clientJsonUrl); + } + } + throw new IOException("Failed to get latest version metadata"); + } + + /** + * Retrieves the url to the client.jar based on the previously retrieved {@link VersionMetadata} + * + * @param metadata The version metadata containing the url to the client.jar + * @return The full url to the client.jar including the expected file hash for validation purposes + * @throws IOException If any http / i/o operation fails. + * @since TODO + */ + private static HashedResource getLatestClientJarUrl(VersionMetadata metadata) throws IOException { + try (BufferedInputStream in = new BufferedInputStream(new URL(metadata.url()).openStream()); + BufferedReader reader = new BufferedReader(new InputStreamReader(in))) { + final JsonObject object = JsonParser.parseReader(reader).getAsJsonObject(); + final JsonObject client = object.getAsJsonObject("downloads").getAsJsonObject("client"); + return new HashedResource(client.get("url").getAsString(), client.get("sha1").getAsString()); + } + } + + /** + * Calculates the sha-1 hash based on the content of the provided file. + * + * @param path The path of the resource to generate the sha-1 hash for + * @return The hash of the file contents + * @throws NoSuchAlgorithmException If the SHA-1 algorithm could not be resolved + * @throws IOException If any I/O operation failed + * @since TODO + */ + private static String calculateSha1(Path path) throws NoSuchAlgorithmException, IOException { + MessageDigest digest = MessageDigest.getInstance("SHA-1"); + try (final BufferedInputStream stream = new BufferedInputStream(Files.newInputStream(path)); + final DigestOutputStream digestOutputStream = new DigestOutputStream(OutputStream.nullOutputStream(), digest)) { + stream.transferTo(digestOutputStream); + return HexFormat.of().formatHex(digest.digest()); + } + } + @Override public TextureUtil getTextureUtil() { return this; @@ -1130,4 +1229,12 @@ public class TextureUtil implements TextureHolder { } + private record VersionMetadata(String version, String url) { + + } + + private record HashedResource(String resource, String hash) { + + } + } -- 2.39.2 From ab55d07ffddbae559544f6e6cfb77069cd8ebf50 Mon Sep 17 00:00:00 2001 From: Pierre Maurice Schwang Date: Wed, 21 Sep 2022 16:17:41 +0200 Subject: [PATCH 13/16] Fix #saturate-Pattern (#1944) * fix: block type access + resources in #saturate pattern * chore: no need to download jar file in loadModTextures --- .../function/pattern/SaturatePattern.java | 2 +- .../core/util/TextureUtil.java | 62 +++++++++---------- 2 files changed, 29 insertions(+), 35 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SaturatePattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SaturatePattern.java index 48c411750..0c42c814a 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SaturatePattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SaturatePattern.java @@ -66,7 +66,7 @@ public class SaturatePattern extends AbstractPattern { } int newColor = TextureUtil.multiplyColor(currentColor, color); BlockType newBlock = util.getNearestBlock(newColor); - if (newBlock.equals(type)) { + if (newBlock == null || newBlock.equals(type)) { return false; } return set.setBlock(extent, newBlock.getDefaultState()); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java index 6261249fc..078b0dc38 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java @@ -30,7 +30,6 @@ import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -427,7 +426,7 @@ public class TextureUtil implements TextureHolder { HashSet blocks = new HashSet<>(); for (int typeId = 0; typeId < ids.length; typeId++) { if (ids[typeId]) { - blocks.add(BlockTypes.get(typeId)); + blocks.add(BlockTypesCache.values[typeId]); } } return fromBlocks(blocks); @@ -445,7 +444,7 @@ public class TextureUtil implements TextureHolder { TextureUtil tu = Fawe.instance().getTextureUtil(); for (int typeId : tu.getValidBlockIds()) { - BlockType block = BlockTypes.get(typeId); + BlockType block = BlockTypesCache.values[typeId]; extent.init(0, 0, 0, block.getDefaultState().toBaseBlock()); if (mask.test(extent)) { blocks.add(block); @@ -685,7 +684,7 @@ public class TextureUtil implements TextureHolder { if (min == Long.MAX_VALUE) { return null; } - return BlockTypes.get(closest); + return BlockTypesCache.values[closest]; } /** @@ -714,7 +713,7 @@ public class TextureUtil implements TextureHolder { if (min == Long.MAX_VALUE) { return null; } - return BlockTypes.get(closest); + return BlockTypesCache.values[closest]; } /** @@ -737,8 +736,8 @@ public class TextureUtil implements TextureHolder { } } } - layerBuffer[0] = BlockTypes.get(closest[0]); - layerBuffer[1] = BlockTypes.get(closest[1]); + layerBuffer[0] = BlockTypesCache.values[closest[0]]; + layerBuffer[1] = BlockTypesCache.values[closest[1]]; return layerBuffer; } @@ -905,36 +904,25 @@ public class TextureUtil implements TextureHolder { if (folder.exists()) { // Get all the jar files File[] files = folder.listFiles((dir, name) -> name.endsWith(".jar")); - if (files.length == 0) { - new File(Fawe.platform().getDirectory() + "/" + Settings.settings().PATHS.TEXTURES + "/") - .mkdirs(); - try (BufferedInputStream in = new BufferedInputStream( - new URL("https://piston-data.mojang.com/v1/objects/c0898ec7c6a5a2eaa317770203a1554260699994/client.jar") - .openStream()); - FileOutputStream fileOutputStream = new FileOutputStream( - Fawe.platform().getDirectory() + "/" + Settings.settings().PATHS.TEXTURES + "/1.19.2.jar")) { - byte[] dataBuffer = new byte[1024]; - int bytesRead; - while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) { - fileOutputStream.write(dataBuffer, 0, bytesRead); - } - fileOutputStream.close(); - files = folder.listFiles((dir, name) -> name.endsWith(".jar")); - } catch (IOException e) { - LOGGER.error( - "Could not download version jar. Please do so manually by creating a `FastAsyncWorldEdit/textures` " + - "folder with a `.minecraft/versions` jar or mods in it."); - LOGGER.error("If the file exists, please make sure the server has read access to the directory."); - } + // We expect the latest version to be already there, due to the download in TextureUtil# + if (files == null || files.length == 0) { + LOGGER.error("No version jar found in {}. Delete the named folder and restart your server to download the " + + "missing assets.", folder.getPath()); + LOGGER.error( + "If no asset jar is created, please do so manually by creating a `FastAsyncWorldEdit/textures` " + + "folder with a `.minecraft/versions` jar or mods in it."); } - if ((files.length > 0)) { + if (files != null && (files.length > 0)) { for (File file : files) { ZipFile zipFile = new ZipFile(file); // Get all the groups in the current jar // The vanilla textures are in `assets/minecraft` // A jar may contain textures for multiple mods - String modelsDir = "assets/%1$s/models/block/%2$s.json"; + String[] modelsDir = { + "assets/%1$s/models/block/%2$s.json", + "assets/%1$s/models/item/%2$s.json" + }; String texturesDir = "assets/%1$s/textures/%2$s.png"; Type typeToken = new TypeToken>() { @@ -958,10 +946,15 @@ public class TextureUtil implements TextureHolder { String nameSpace = split.length == 1 ? "" : split[0]; // Read models - String modelFileName = String.format(modelsDir, nameSpace, name); - ZipEntry entry = getEntry(zipFile, modelFileName); + ZipEntry entry = null; + for (final String dir : modelsDir) { + String modelFileName = String.format(dir, nameSpace, name); + if ((entry = getEntry(zipFile, modelFileName)) != null) { + break; + } + } if (entry == null) { - LOGGER.error("Cannot find {} in {}", modelFileName, file); + LOGGER.error("Cannot find {} in {}", modelsDir, file); continue; } @@ -1179,7 +1172,8 @@ public class TextureUtil implements TextureHolder { if (min == Long.MAX_VALUE) { return null; } - return BlockTypes.get(closest); + + return BlockTypesCache.values[closest]; } private String getFileName(String path) { -- 2.39.2 From 4f26561cc178ef100980c63387608b9357a1c772 Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Wed, 21 Sep 2022 16:41:07 +0200 Subject: [PATCH 14/16] Release 2.4.6 --- build.gradle.kts | 4 ++-- .../java/com/fastasyncworldedit/core/util/TextureUtil.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 7ea9ffb46..e261a0e58 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -23,7 +23,7 @@ logger.lifecycle(""" ******************************************* """) -var rootVersion by extra("2.4.5") +var rootVersion by extra("2.4.6") var snapshot by extra("SNAPSHOT") var revision: String by extra("") var buildNumber by extra("") @@ -41,7 +41,7 @@ ext { } } -version = String.format("%s-%s", rootVersion, buildNumber) +version = String.format("%s", rootVersion) if (!project.hasProperty("gitCommitHash")) { apply(plugin = "org.ajoberstar.grgit") diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java index 078b0dc38..f6f896f56 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java @@ -599,7 +599,7 @@ public class TextureUtil implements TextureHolder { * * @return {@link VersionMetadata} containing the id (= version) and url to the client manifest itself * @throws IOException If any http / i/o operation fails. - * @since TODO + * @since 2.4.6 */ private static VersionMetadata getLatestVersion() throws IOException { try (BufferedInputStream in = new BufferedInputStream(new URL(VERSION_MANIFEST).openStream()); @@ -624,7 +624,7 @@ public class TextureUtil implements TextureHolder { * @param metadata The version metadata containing the url to the client.jar * @return The full url to the client.jar including the expected file hash for validation purposes * @throws IOException If any http / i/o operation fails. - * @since TODO + * @since 2.4.6 */ private static HashedResource getLatestClientJarUrl(VersionMetadata metadata) throws IOException { try (BufferedInputStream in = new BufferedInputStream(new URL(metadata.url()).openStream()); @@ -642,7 +642,7 @@ public class TextureUtil implements TextureHolder { * @return The hash of the file contents * @throws NoSuchAlgorithmException If the SHA-1 algorithm could not be resolved * @throws IOException If any I/O operation failed - * @since TODO + * @since 2.4.6 */ private static String calculateSha1(Path path) throws NoSuchAlgorithmException, IOException { MessageDigest digest = MessageDigest.getInstance("SHA-1"); -- 2.39.2 From 10b852d416ff8fcafb95de3e540b35c01bfd1719 Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Wed, 21 Sep 2022 16:45:40 +0200 Subject: [PATCH 15/16] Back to snapshot for development --- build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index e261a0e58..069db1c3e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -23,7 +23,7 @@ logger.lifecycle(""" ******************************************* """) -var rootVersion by extra("2.4.6") +var rootVersion by extra("2.4.7") var snapshot by extra("SNAPSHOT") var revision: String by extra("") var buildNumber by extra("") @@ -41,7 +41,7 @@ ext { } } -version = String.format("%s", rootVersion) +version = String.format("%s-%s", rootVersion, buildNumber) if (!project.hasProperty("gitCommitHash")) { apply(plugin = "org.ajoberstar.grgit") -- 2.39.2 From ae66ccfa8f706c8a204680d7a9e93c0f8c4c4bc0 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Sat, 24 Sep 2022 19:32:14 +0200 Subject: [PATCH 16/16] Fix ci --- steamwarci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/steamwarci.yml b/steamwarci.yml index b851e38b3..06489e900 100644 --- a/steamwarci.yml +++ b/steamwarci.yml @@ -3,4 +3,4 @@ build: - "./gradlew --stop" artifacts: - "/binarys/FastAsyncWorldEdit-1.18.jar": "worldedit-bukkit/build/libs/FastAsyncWorldEdit-Bukkit-2.4.5-SNAPSHOT.jar" + "/binarys/FastAsyncWorldEdit-1.18.jar": "worldedit-bukkit/build/libs/FastAsyncWorldEdit-Bukkit-2.4.7-SNAPSHOT.jar" -- 2.39.2