From 4969dac39c759de43cceb05c72a261d9decabc7d Mon Sep 17 00:00:00 2001 From: Matthew Miller Date: Thu, 20 Sep 2018 16:56:46 +1000 Subject: [PATCH 1/5] Potential minor performance improvements when checking fuzzy equality. --- .../worldedit/world/block/BaseBlock.java | 5 ++++- .../worldedit/world/block/BlockState.java | 4 ++++ .../worldedit/world/block/BlockType.java | 15 +++++++++++++-- .../worldedit/world/chunk/AnvilChunk.java | 19 +++++++++++++------ .../worldedit/world/chunk/AnvilChunk13.java | 10 +++++++--- .../sk89q/worldedit/world/chunk/Chunk.java | 4 ++-- .../sk89q/worldedit/world/chunk/OldChunk.java | 16 +++++++++++++--- .../world/snapshot/SnapshotRestore.java | 3 +-- .../sponge/SpongePermissionsProvider.java | 4 +--- 9 files changed, 58 insertions(+), 22 deletions(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BaseBlock.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BaseBlock.java index aa3100326..e3dd5d7d3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BaseBlock.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BaseBlock.java @@ -134,12 +134,15 @@ public class BaseBlock implements BlockStateHolder, TileEntityBlock { @Override public boolean equals(Object o) { if (!(o instanceof BaseBlock)) { + if (!hasNbtData() && o instanceof BlockStateHolder) { + return Objects.equals(toImmutableState(), ((BlockStateHolder) o).toImmutableState()); + } return false; } final BaseBlock otherBlock = (BaseBlock) o; - return this.toImmutableState().equals(otherBlock.toImmutableState()) && Objects.equals(getNbtData(), otherBlock.getNbtData()); + return Objects.equals(this.toImmutableState(), otherBlock.toImmutableState()) && Objects.equals(getNbtData(), otherBlock.getNbtData()); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java index 2b89d9195..de527baf4 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java @@ -168,6 +168,10 @@ public class BlockState implements BlockStateHolder { @Override public boolean equalsFuzzy(BlockStateHolder o) { + if (this == o) { + // Added a reference equality check for + return true; + } if (!getBlockType().equals(o.getBlockType())) { return false; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java index 05cd6543b..2b9db5ea6 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java @@ -22,12 +22,12 @@ package com.sk89q.worldedit.world.block; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.sk89q.worldedit.WorldEdit; -import com.sk89q.worldedit.world.registry.BlockMaterial; import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.registry.NamespacedRegistry; import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.item.ItemTypes; +import com.sk89q.worldedit.world.registry.BlockMaterial; import com.sk89q.worldedit.world.registry.BundledBlockData; import com.sk89q.worldedit.world.registry.LegacyMapper; @@ -46,6 +46,7 @@ public class BlockType { private BlockState defaultState; private Map properties; private BlockMaterial blockMaterial; + private Map, Object>, BlockState> blockStatesMap; public BlockType(String id) { this(id, null); @@ -57,7 +58,8 @@ public class BlockType { id = "minecraft:" + id; } this.id = id; - this.defaultState = new ArrayList<>(BlockState.generateStateMap(this).values()).get(0); + this.blockStatesMap = BlockState.generateStateMap(this); + this.defaultState = new ArrayList<>(this.blockStatesMap.values()).get(0); if (values != null) { this.defaultState = values.apply(this.defaultState); } @@ -127,6 +129,15 @@ public class BlockType { return this.defaultState; } + /** + * Gets a list of all possible states for this BlockType. + * + * @return All possible states + */ + public List getAllStates() { + return ImmutableList.copyOf(this.blockStatesMap.values()); + } + /** * Gets whether this block type has an item representation. * diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk.java index 0f0d70d05..6b1265854 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk.java @@ -28,10 +28,12 @@ import com.sk89q.jnbt.NBTUtils; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.BlockVector; import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.world.block.BaseBlock; +import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.world.DataException; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockStateHolder; +import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.registry.LegacyMapper; import com.sk89q.worldedit.world.storage.InvalidFormatException; @@ -51,8 +53,6 @@ public class AnvilChunk implements Chunk { private int rootZ; private Map> tileEntities; - @SuppressWarnings("unused") - private World world; // TODO: remove if stays unused. /** * Construct the chunk with a compound tag. @@ -63,7 +63,6 @@ public class AnvilChunk implements Chunk { */ public AnvilChunk(World world, CompoundTag tag) throws DataException { rootTag = tag; - this.world = world; rootX = NBTUtils.getChildTag(rootTag.getValue(), "xPos", IntTag.class).getValue(); rootZ = NBTUtils.getChildTag(rootTag.getValue(), "zPos", IntTag.class).getValue(); @@ -255,14 +254,22 @@ public class AnvilChunk implements Chunk { } @Override - public BaseBlock getBlock(Vector position) throws DataException { + public BlockStateHolder getBlock(Vector position) throws DataException { int id = getBlockID(position); int data = getBlockData(position); BlockState state = LegacyMapper.getInstance().getBlockFromLegacy(id, data); + if (state == null) { + WorldEdit.logger.warning("Unknown legacy block " + id + ":" + data + " found when loading legacy anvil chunk."); + return BlockTypes.AIR.getDefaultState(); + } CompoundTag tileEntity = getBlockTileEntity(position); - return state.toBaseBlock(tileEntity); + if (tileEntity != null) { + return state.toBaseBlock(tileEntity); + } + + return state; } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java index 1f673ab6b..025390c66 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java @@ -29,9 +29,9 @@ import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.BlockVector; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.registry.state.Property; -import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.DataException; import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.storage.InvalidFormatException; @@ -230,7 +230,7 @@ public class AnvilChunk13 implements Chunk { } @Override - public BaseBlock getBlock(Vector position) throws DataException { + public BlockStateHolder getBlock(Vector position) throws DataException { int x = position.getBlockX() - rootX * 16; int y = position.getBlockY(); int z = position.getBlockZ() - rootZ * 16; @@ -247,7 +247,11 @@ public class AnvilChunk13 implements Chunk { CompoundTag tileEntity = getBlockTileEntity(position); - return state.toBaseBlock(tileEntity); + if (tileEntity != null) { + return state.toBaseBlock(tileEntity); + } + + return state; } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/Chunk.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/Chunk.java index 6ba2e8a54..2f261570e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/Chunk.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/Chunk.java @@ -20,8 +20,8 @@ package com.sk89q.worldedit.world.chunk; import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.DataException; +import com.sk89q.worldedit.world.block.BlockStateHolder; /** * A 16 by 16 block chunk. @@ -35,6 +35,6 @@ public interface Chunk { * @return block the block * @throws DataException thrown on data error */ - BaseBlock getBlock(Vector position) throws DataException; + BlockStateHolder getBlock(Vector position) throws DataException; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/OldChunk.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/OldChunk.java index 631470ac2..c6f983ced 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/OldChunk.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/OldChunk.java @@ -27,10 +27,11 @@ import com.sk89q.jnbt.NBTUtils; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.BlockVector; import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.world.block.BaseBlock; +import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.world.DataException; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.registry.LegacyMapper; import com.sk89q.worldedit.world.storage.InvalidFormatException; @@ -153,7 +154,7 @@ public class OldChunk implements Chunk { } @Override - public BaseBlock getBlock(Vector position) throws DataException { + public BlockStateHolder getBlock(Vector position) throws DataException { if(position.getBlockY() >= 128) BlockTypes.VOID_AIR.getDefaultState().toBaseBlock(); int id, dataVal; @@ -181,9 +182,18 @@ public class OldChunk implements Chunk { } BlockState state = LegacyMapper.getInstance().getBlockFromLegacy(id, dataVal); + if (state == null) { + WorldEdit.logger.warning("Unknown legacy block " + id + ":" + dataVal + " found when loading legacy anvil chunk."); + return BlockTypes.AIR.getDefaultState(); + } + CompoundTag tileEntity = getBlockTileEntity(position); - return state.toBaseBlock(tileEntity); + if (tileEntity != null) { + return state.toBaseBlock(tileEntity); + } + + return state; } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/snapshot/SnapshotRestore.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/snapshot/SnapshotRestore.java index 814818a5c..a7ef7ca9d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/snapshot/SnapshotRestore.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/snapshot/SnapshotRestore.java @@ -147,8 +147,7 @@ public class SnapshotRestore { // Now just copy blocks! for (Vector pos : entry.getValue()) { try { - BaseBlock block = chunk.getBlock(pos); - editSession.setBlock(pos, block); + editSession.setBlock(pos, chunk.getBlock(pos)); } catch (DataException e) { // this is a workaround: just ignore for now } diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePermissionsProvider.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePermissionsProvider.java index d9970ecb1..986dd2555 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePermissionsProvider.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePermissionsProvider.java @@ -26,8 +26,6 @@ import org.spongepowered.api.service.permission.PermissionDescription; import org.spongepowered.api.service.permission.PermissionService; import org.spongepowered.api.service.permission.SubjectReference; -import java.util.stream.Collectors; - public class SpongePermissionsProvider { public boolean hasPermission(Player player, String permission) { @@ -44,6 +42,6 @@ public class SpongePermissionsProvider { public String[] getGroups(Player player) { return player.getParents().stream() .map(SubjectReference::getSubjectIdentifier) - .collect(Collectors.toList()).toArray(new String[0]); + .toArray(String[]::new); } } From 1a2cd3a948416a78a2b7321ce00e8f9cceae9129 Mon Sep 17 00:00:00 2001 From: Matthew Miller Date: Thu, 20 Sep 2018 17:09:50 +1000 Subject: [PATCH 2/5] Fixes WORLDEDIT-3609, Message should say cut when //cut is used. --- .../java/com/sk89q/worldedit/command/ClipboardCommands.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java index c3c7b827f..181f648d7 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java @@ -127,7 +127,7 @@ public class ClipboardCommands { Operations.completeLegacy(copy); session.setClipboard(new ClipboardHolder(clipboard)); - player.print(region.getArea() + " block(s) were copied."); + player.print(region.getArea() + " block(s) were cut."); } @Command( From 8975469efbc636d3200bf392cbc464132c66df7f Mon Sep 17 00:00:00 2001 From: Matthew Miller Date: Thu, 20 Sep 2018 17:18:11 +1000 Subject: [PATCH 3/5] Bump to beta 01 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 9d91915c1..c0b845136 100644 --- a/build.gradle +++ b/build.gradle @@ -35,7 +35,7 @@ buildscript { allprojects { group = 'com.sk89q.worldedit' - version = '7.0.0-SNAPSHOT' + version = '7.0.0-beta-01' } if (!project.hasProperty("artifactory_contextUrl")) ext.artifactory_contextUrl = "http://localhost" From 568643d08a5f4c835de29df6fa4799c371b0dfa5 Mon Sep 17 00:00:00 2001 From: Matthew Miller Date: Thu, 20 Sep 2018 17:31:14 +1000 Subject: [PATCH 4/5] Back to snapshot for continued development --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index c0b845136..9d91915c1 100644 --- a/build.gradle +++ b/build.gradle @@ -35,7 +35,7 @@ buildscript { allprojects { group = 'com.sk89q.worldedit' - version = '7.0.0-beta-01' + version = '7.0.0-SNAPSHOT' } if (!project.hasProperty("artifactory_contextUrl")) ext.artifactory_contextUrl = "http://localhost" From 02c6f11bb9125116d0ff6defdc889af1f23414b8 Mon Sep 17 00:00:00 2001 From: Matthew Miller Date: Thu, 20 Sep 2018 22:59:42 +1000 Subject: [PATCH 5/5] Added bStats --- config/checkstyle/import-control.xml | 2 + worldedit-bukkit/build.gradle | 85 ++++++++++--------- .../worldedit/bukkit/WorldEditPlugin.java | 4 + worldedit-sponge/build.gradle | 8 ++ .../worldedit/sponge/SpongeWorldEdit.java | 4 + 5 files changed, 63 insertions(+), 40 deletions(-) diff --git a/config/checkstyle/import-control.xml b/config/checkstyle/import-control.xml index d620978fd..2fe94d97d 100644 --- a/config/checkstyle/import-control.xml +++ b/config/checkstyle/import-control.xml @@ -38,6 +38,7 @@ + @@ -58,6 +59,7 @@ + diff --git a/worldedit-bukkit/build.gradle b/worldedit-bukkit/build.gradle index 5c1a39cd9..8d9ca0eea 100644 --- a/worldedit-bukkit/build.gradle +++ b/worldedit-bukkit/build.gradle @@ -1,40 +1,45 @@ -apply plugin: 'eclipse' -apply plugin: 'idea' -apply plugin: 'maven' - -repositories { - maven { url "https://hub.spigotmc.org/nexus/content/groups/public" } -} - -dependencies { - compile project(':worldedit-core') - compile 'com.sk89q:dummypermscompat:1.8' - compile 'org.bukkit:bukkit:1.13-R0.1-SNAPSHOT' // zzz - testCompile 'org.mockito:mockito-core:1.9.0-rc1' -} - -processResources { - from (sourceSets.main.resources.srcDirs) { - expand 'internalVersion': project.internalVersion - include 'plugin.yml' - } - - from (sourceSets.main.resources.srcDirs) { - exclude 'plugin.yml' - } -} - -jar { - manifest { - attributes("Class-Path": "truezip.jar WorldEdit/truezip.jar js.jar WorldEdit/js.jar", - "WorldEdit-Version": version) - } -} - -shadowJar { - dependencies { - include(dependency(':worldedit-core')) - } -} - -build.dependsOn(shadowJar) +apply plugin: 'eclipse' +apply plugin: 'idea' +apply plugin: 'maven' + +repositories { + maven { url "https://hub.spigotmc.org/nexus/content/groups/public" } + maven { url "http://repo.bstats.org/content/repositories/releases/" } +} + +dependencies { + compile project(':worldedit-core') + compile 'com.sk89q:dummypermscompat:1.8' + compile 'org.bukkit:bukkit:1.13-R0.1-SNAPSHOT' // zzz + compile 'org.bstats:bstats-bukkit:1.2' + testCompile 'org.mockito:mockito-core:1.9.0-rc1' +} + +processResources { + from (sourceSets.main.resources.srcDirs) { + expand 'internalVersion': project.internalVersion + include 'plugin.yml' + } + + from (sourceSets.main.resources.srcDirs) { + exclude 'plugin.yml' + } +} + +jar { + manifest { + attributes("Class-Path": "truezip.jar WorldEdit/truezip.jar js.jar WorldEdit/js.jar", + "WorldEdit-Version": version) + } +} + +shadowJar { + dependencies { + include(dependency(':worldedit-core')) + relocate ("org.bstats", "com.sk89q.worldedit.bukkit.bstats") { + include(dependency("org.bstats:bstats-bukkit:1.2")) + } + } +} + +build.dependsOn(shadowJar) diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java index 324babd4f..c4b017e83 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java @@ -37,6 +37,7 @@ import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.extension.platform.Platform; import com.sk89q.worldedit.extent.inventory.BlockBag; +import org.bstats.bukkit.Metrics; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabCompleter; @@ -102,6 +103,9 @@ public class WorldEditPlugin extends JavaPlugin implements TabCompleter { // Forge WorldEdit and there's (probably) not going to be any other // platforms to be worried about... at the current time of writing WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent()); + + // Enable metrics + new Metrics(this); } private void loadConfig() { diff --git a/worldedit-sponge/build.gradle b/worldedit-sponge/build.gradle index d068d4804..ec3da06c1 100644 --- a/worldedit-sponge/build.gradle +++ b/worldedit-sponge/build.gradle @@ -12,9 +12,14 @@ plugins { id 'org.spongepowered.plugin' version '0.8.1' } +repositories { + maven { url "http://repo.bstats.org/content/repositories/releases/" } +} + dependencies { compile project(':worldedit-core') compile 'org.spongepowered:spongeapi:7.0.0-SNAPSHOT' + compile 'org.bstats:bstats-sponge:1.2' testCompile group: 'org.mockito', name: 'mockito-core', version:'1.9.0-rc1' } @@ -37,6 +42,9 @@ jar { shadowJar { dependencies { include(dependency(':worldedit-core')) + relocate ("org.bstats", "com.sk89q.worldedit.sponge.bstats") { + include(dependency("org.bstats:bstats-sponge:1.2")) + } } } diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java index d86e77c7c..ea0d2a36e 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java @@ -34,6 +34,7 @@ import com.sk89q.worldedit.sponge.adapter.SpongeImplAdapter; import com.sk89q.worldedit.sponge.adapter.SpongeImplLoader; import com.sk89q.worldedit.sponge.config.SpongeConfiguration; import com.sk89q.worldedit.world.item.ItemTypes; +import org.bstats.sponge.Metrics; import org.slf4j.Logger; import org.spongepowered.api.Sponge; import org.spongepowered.api.block.BlockSnapshot; @@ -75,6 +76,9 @@ public class SpongeWorldEdit { @Inject private Logger logger; + @Inject + private Metrics metrics; + public static final String MOD_ID = "worldedit"; private SpongePermissionsProvider provider;