From 3ede0447b024b34f62150091707d6a5627d0768f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Thu, 21 May 2020 20:06:04 +0200 Subject: [PATCH 01/39] Fix up the plot area nightmare --- Core/build.gradle | 2 + .../com/plotsquared/core/plot/PlotWorld.java | 105 +++++++ .../plot/world/DefaultPlotAreaManager.java | 269 +++++------------- .../core/plot/world/PlotAreaManager.java | 3 +- .../core/plot/world/ScatteredPlotWorld.java | 110 +++++++ .../core/plot/world/StandardPlotWorld.java | 65 +++++ .../com/plotsquared/core/util/RegionUtil.java | 10 + 7 files changed, 372 insertions(+), 192 deletions(-) create mode 100644 Core/src/main/java/com/plotsquared/core/plot/PlotWorld.java create mode 100644 Core/src/main/java/com/plotsquared/core/plot/world/ScatteredPlotWorld.java create mode 100644 Core/src/main/java/com/plotsquared/core/plot/world/StandardPlotWorld.java diff --git a/Core/build.gradle b/Core/build.gradle index ee6edfda2..8581a39a4 100644 --- a/Core/build.gradle +++ b/Core/build.gradle @@ -16,6 +16,7 @@ dependencies { testAnnotationProcessor("org.projectlombok:lombok:1.18.8") implementation("org.jetbrains.kotlin:kotlin-stdlib:1.3.72") implementation("org.jetbrains:annotations:19.0.0") + implementation 'com.github.davidmoten:rtree:0.8.7' } sourceCompatibility = 1.8 @@ -73,6 +74,7 @@ shadowJar { include(dependency("net.kyori:text-serializer-gson:3.0.2")) include(dependency("net.kyori:text-serializer-legacy:3.0.2")) include(dependency("net.kyori:text-serializer-plain:3.0.2")) + include(dependency("com.github.davidmoten:rtree:0.8.7")) } relocate('net.kyori.text', 'com.plotsquared.formatting.text') relocate("org.json", "com.plotsquared.json") { diff --git a/Core/src/main/java/com/plotsquared/core/plot/PlotWorld.java b/Core/src/main/java/com/plotsquared/core/plot/PlotWorld.java new file mode 100644 index 000000000..ed7b854c2 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/plot/PlotWorld.java @@ -0,0 +1,105 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.core.plot; + +import com.plotsquared.core.location.Location; +import com.sk89q.worldedit.regions.CuboidRegion; +import lombok.EqualsAndHashCode; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +/** + * A world that contains plots + */ +@EqualsAndHashCode +public abstract class PlotWorld { + + private final String world; + + /** + * Create a new plot world with a given world name + * + * @param world World name + */ + protected PlotWorld(@NotNull final String world) { + this.world = world; + } + + /** + * Get the plot area that contains the given location, or null + * if the location is not a part of a plot area. + * + * @param location Location + * @return Containing plot area, or null + */ + @Nullable public abstract PlotArea getArea(@NotNull final Location location); + + /** + * Get all plot areas in the world + * + * @return All plot areas in the world + */ + @NotNull public abstract Collection getAreas(); + + /** + * Get all plot areas in a specified region + * + * @param region Region + * @return All areas in the region + */ + @NotNull public abstract Collection getAreasInRegion( + @NotNull final CuboidRegion region); + + /** + * Register a new area in the world + * + * @param area Plot area + */ + public void addArea(@NotNull final PlotArea area) { + throw new UnsupportedOperationException("This world type does not allow adding new areas"); + } + + /** + * Remove an area from the world + * + * @param area Plot area + */ + public void removeArea(@NotNull final PlotArea area) { + throw new UnsupportedOperationException("This world type does not allow removing areas"); + } + + /** + * Get the world name + * + * @return World name + */ + public String getWorld() { + return this.world; + } + +} diff --git a/Core/src/main/java/com/plotsquared/core/plot/world/DefaultPlotAreaManager.java b/Core/src/main/java/com/plotsquared/core/plot/world/DefaultPlotAreaManager.java index 833bf3d4f..f86b5b8b6 100644 --- a/Core/src/main/java/com/plotsquared/core/plot/world/DefaultPlotAreaManager.java +++ b/Core/src/main/java/com/plotsquared/core/plot/world/DefaultPlotAreaManager.java @@ -25,143 +25,96 @@ */ package com.plotsquared.core.plot.world; -import com.plotsquared.core.collection.QuadMap; import com.plotsquared.core.location.Location; import com.plotsquared.core.plot.PlotArea; +import com.plotsquared.core.plot.PlotAreaType; +import com.plotsquared.core.plot.PlotWorld; import com.plotsquared.core.util.StringMan; import com.sk89q.worldedit.regions.CuboidRegion; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; import java.util.Set; public class DefaultPlotAreaManager implements PlotAreaManager { final PlotArea[] noPlotAreas = new PlotArea[0]; - // All plot areas mapped by world - private final HashMap plotAreaMap = new HashMap<>(); - // All plot areas mapped by position - private final HashMap> plotAreaGrid = new HashMap<>(); - private final HashSet plotAreaHashCheck = new HashSet<>(); - // All plot areas - private PlotArea[] plotAreas = new PlotArea[0]; + + private final Map plotWorlds = new HashMap<>(); // Optimization if there are no hash collisions private boolean plotAreaHasCollision = false; - private String[] worlds = new String[0]; @Override public PlotArea[] getAllPlotAreas() { - return plotAreas; - } - - @Override public PlotArea getApplicablePlotArea(Location location) { - switch (this.plotAreas.length) { - case 0: - return null; - case 1: - return this.plotAreas[0].getWorldHash() == location.getWorld().hashCode() - && this.plotAreas[0].contains(location) && (!this.plotAreaHasCollision - || location.getWorld().equals(this.plotAreas[0].getWorldName())) ? - this.plotAreas[0] : - null; - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - String world = location.getWorld(); - int hash = world.hashCode(); - for (PlotArea area : this.plotAreas) { - if (hash == area.getWorldHash()) { - if (area.contains(location.getX(), location.getZ()) && ( - !this.plotAreaHasCollision || world.equals(area.getWorldName()))) { - return area; - } - } - } - return null; - default: - PlotArea[] areas = this.plotAreaMap.get(location.getWorld()); - if (areas == null) { - return null; - } - int z; - int x; - switch (areas.length) { - case 1: - return areas[0]; - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - x = location.getX(); - z = location.getZ(); - for (PlotArea area : areas) { - if (area.contains(x, z)) { - return area; - } - } - return null; - default: - QuadMap search = this.plotAreaGrid.get(location.getWorld()); - return search.get(location.getX(), location.getZ()); - } + final Set area = new HashSet<>(); + for (final PlotWorld world : plotWorlds.values()) { + area.addAll(world.getAreas()); } + return area.toArray(new PlotArea[0]); } - @Override public void addPlotArea(PlotArea plotArea) { - HashSet localAreas = - new HashSet<>(Arrays.asList(getPlotAreas(plotArea.getWorldName(), null))); - HashSet globalAreas = new HashSet<>(Arrays.asList(plotAreas)); - localAreas.add(plotArea); - globalAreas.add(plotArea); - this.plotAreas = globalAreas.toArray(new PlotArea[0]); - this.plotAreaMap.put(plotArea.getWorldName(), localAreas.toArray(new PlotArea[0])); - QuadMap map = this.plotAreaGrid.get(plotArea.getWorldName()); - if (map == null) { - map = new QuadMap(Integer.MAX_VALUE, 0, 0) { - @Override public CuboidRegion getRegion(PlotArea value) { - return value.getRegion(); - } - }; - this.plotAreaGrid.put(plotArea.getWorldName(), map); + @Override @Nullable public PlotArea getApplicablePlotArea(final Location location) { + if (location == null) { + return null; } - map.add(plotArea); + final PlotWorld world = this.plotWorlds.get(location.getWorld()); + if (world == null) { + return null; + } + return world.getArea(location); } - @Override public void removePlotArea(PlotArea area) { - ArrayList globalAreas = new ArrayList<>(Arrays.asList(plotAreas)); - globalAreas.remove(area); - this.plotAreas = globalAreas.toArray(new PlotArea[0]); - if (globalAreas.isEmpty()) { - this.plotAreaMap.remove(area.getWorldName()); - this.plotAreaGrid.remove(area.getWorldName()); + @Override public void addPlotArea(final PlotArea plotArea) { + PlotWorld world = this.plotWorlds.get(plotArea.getWorldName()); + if (world != null) { + if (world instanceof StandardPlotWorld && world.getAreas().isEmpty()) { + this.plotWorlds.remove(plotArea.getWorldName()); + } else { + world.addArea(plotArea); + return; + } + } + if (plotArea.getType() != PlotAreaType.PARTIAL) { + world = new StandardPlotWorld(plotArea.getWorldName(), plotArea); } else { - this.plotAreaMap.put(area.getWorldName(), globalAreas.toArray(new PlotArea[0])); - this.plotAreaGrid.get(area.getWorldName()).remove(area); + world = new ScatteredPlotWorld(plotArea.getWorldName()); + world.addArea(plotArea); + } + this.plotWorlds.put(plotArea.getWorldName(), world); + } + + @Override public void removePlotArea(final PlotArea area) { + final PlotWorld world = this.plotWorlds.get(area.getWorldName()); + if (world == null) { + return; + } + if (world instanceof StandardPlotWorld) { + this.plotWorlds.remove(world.getWorld()); + } else { + world.removeArea(area); + if (world.getAreas().isEmpty()) { + this.plotWorlds.remove(world.getWorld()); + } } } - @Override public PlotArea getPlotArea(String world, String id) { - PlotArea[] areas = this.plotAreaMap.get(world); - if (areas == null) { + @Override public PlotArea getPlotArea(final String world, final String id) { + final PlotWorld plotWorld = this.plotWorlds.get(world); + if (plotWorld == null) { return null; } - if (areas.length == 1) { - return areas[0]; - } else if (id == null) { + final List areas = new ArrayList<>(plotWorld.getAreas()); + if (areas.size() == 1) { + return areas.get(0); + } + if (id == null) { return null; } - for (PlotArea area : areas) { + for (final PlotArea area : areas) { if (StringMan.isEqual(id, area.getId())) { return area; } @@ -169,103 +122,37 @@ public class DefaultPlotAreaManager implements PlotAreaManager { return null; } - @Override public PlotArea getPlotArea(@NotNull Location location) { - switch (this.plotAreas.length) { - case 0: - return null; - case 1: - PlotArea pa = this.plotAreas[0]; - if (pa.contains(location)) { - return pa; - } else { - return null; - } - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - String world = location.getWorld(); - int hash = world.hashCode(); - for (PlotArea area : this.plotAreas) { - if (hash == area.getWorldHash()) { - if (area.contains(location.getX(), location.getZ()) && ( - !this.plotAreaHasCollision || world.equals(area.getWorldName()))) { - return area; - } - } - } - return null; - default: - PlotArea[] areas = this.plotAreaMap.get(location.getWorld()); - if (areas == null) { - return null; - } - int x; - int z; - switch (areas.length) { - case 0: - PlotArea a = areas[0]; - return a.contains(location.getX(), location.getZ()) ? a : null; - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - x = location.getX(); - z = location.getZ(); - for (PlotArea area : areas) { - if (area.contains(x, z)) { - return area; - } - } - return null; - default: - QuadMap search = this.plotAreaGrid.get(location.getWorld()); - return search.get(location.getX(), location.getZ()); - } - } + @Override public PlotArea getPlotArea(@NotNull final Location location) { + return this.getApplicablePlotArea(location); } - @Override public PlotArea[] getPlotAreas(String world, CuboidRegion region) { - if (region == null) { - PlotArea[] areas = this.plotAreaMap.get(world); - if (areas == null) { - return noPlotAreas; - } - return areas; - } - QuadMap areas = this.plotAreaGrid.get(world); - if (areas == null) { + @Override public PlotArea[] getPlotAreas(final String world, final CuboidRegion region) { + final PlotWorld plotWorld = this.plotWorlds.get(world); + if (plotWorld == null) { return noPlotAreas; - } else { - Set found = areas.get(region); - return found.toArray(new PlotArea[0]); } + if (region == null) { + return plotWorld.getAreas().toArray(new PlotArea[0]); + } + return plotWorld.getAreasInRegion(region).toArray(new PlotArea[0]); } - @Override public void addWorld(String worldName) { - if (!this.plotAreaHasCollision && !this.plotAreaHashCheck.add(worldName.hashCode())) { - this.plotAreaHasCollision = true; + @Override public void addWorld(final String worldName) { + PlotWorld world = this.plotWorlds.get(worldName); + if (world != null) { + return; } - Set tmp = new LinkedHashSet<>(); - Collections.addAll(tmp, worlds); - tmp.add(worldName); - worlds = tmp.toArray(new String[0]); + // Create a new empty world. When a new area is added + // the world will be re-recreated with the correct type + world = new StandardPlotWorld(worldName, null); + this.plotWorlds.put(worldName, world); } - @Override public void removeWorld(String worldName) { - Set tmp = new LinkedHashSet<>(); - Collections.addAll(tmp, worlds); - tmp.remove(worldName); - worlds = tmp.toArray(new String[0]); + @Override public void removeWorld(final String worldName) { + this.plotWorlds.remove(worldName); } @Override public String[] getAllWorlds() { - return worlds; + return this.plotWorlds.keySet().toArray(new String[0]); } } diff --git a/Core/src/main/java/com/plotsquared/core/plot/world/PlotAreaManager.java b/Core/src/main/java/com/plotsquared/core/plot/world/PlotAreaManager.java index b6d23b3d4..34033cb2b 100644 --- a/Core/src/main/java/com/plotsquared/core/plot/world/PlotAreaManager.java +++ b/Core/src/main/java/com/plotsquared/core/plot/world/PlotAreaManager.java @@ -29,6 +29,7 @@ import com.plotsquared.core.location.Location; import com.plotsquared.core.plot.PlotArea; import com.sk89q.worldedit.regions.CuboidRegion; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public interface PlotAreaManager { @@ -44,7 +45,7 @@ public interface PlotAreaManager { * @param location The location * @return An applicable area, or null */ - PlotArea getApplicablePlotArea(Location location); + @Nullable PlotArea getApplicablePlotArea(Location location); /** * Get the plot area, if there is any, for the given diff --git a/Core/src/main/java/com/plotsquared/core/plot/world/ScatteredPlotWorld.java b/Core/src/main/java/com/plotsquared/core/plot/world/ScatteredPlotWorld.java new file mode 100644 index 000000000..78cb0b7b2 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/plot/world/ScatteredPlotWorld.java @@ -0,0 +1,110 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.core.plot.world; + +import com.github.davidmoten.rtree.Entry; +import com.github.davidmoten.rtree.RTree; +import com.github.davidmoten.rtree.geometry.Geometries; +import com.github.davidmoten.rtree.geometry.Geometry; +import com.plotsquared.core.location.Location; +import com.plotsquared.core.plot.PlotArea; +import com.plotsquared.core.plot.PlotWorld; +import com.plotsquared.core.util.RegionUtil; +import com.sk89q.worldedit.regions.CuboidRegion; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import rx.Observable; + +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +/** + * Plot world that contains several plot areas (clusters) + */ +public class ScatteredPlotWorld extends PlotWorld { + + private final List areas = new LinkedList<>(); + private final Object treeLock = new Object(); + private RTree areaTree; + + /** + * Create a new plot world with a given world name + * + * @param world World name + */ + public ScatteredPlotWorld(@NotNull final String world) { + super(world); + } + + @Override @Nullable public PlotArea getArea(@NotNull final Location location) { + synchronized (this.treeLock) { + final Observable> area = + areaTree.search(Geometries.point(location.getX(), location.getZ())); + if (area.isEmpty().toBlocking().first()) { + return null; + } + return area.toBlocking().first().value(); + } + } + + @Override @NotNull public Collection getAreas() { + return Collections.unmodifiableCollection(this.areas); + } + + @Override public void addArea(@NotNull final PlotArea area) { + this.areas.add(area); + this.buildTree(); + } + + @Override public void removeArea(@NotNull final PlotArea area) { + this.areas.remove(area); + this.buildTree(); + } + + @Override @NotNull public Collection getAreasInRegion(@NotNull final CuboidRegion region) { + synchronized (this.treeLock) { + final List areas = new LinkedList<>(); + this.areaTree.search(RegionUtil.toRectangle(region)).toBlocking().forEach(entry -> areas.add(entry.value())); + return areas; + } + } + + /** + * Rebuild the area tree + */ + private void buildTree() { + synchronized (this.treeLock) { + this.areaTree = RTree.create(); + for (final PlotArea area : areas) { + this.areaTree = this.areaTree.add(area, + RegionUtil.toRectangle(area.getRegion())); + } + } + } + +} diff --git a/Core/src/main/java/com/plotsquared/core/plot/world/StandardPlotWorld.java b/Core/src/main/java/com/plotsquared/core/plot/world/StandardPlotWorld.java new file mode 100644 index 000000000..162cf0e9f --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/plot/world/StandardPlotWorld.java @@ -0,0 +1,65 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.core.plot.world; + +import com.plotsquared.core.location.Location; +import com.plotsquared.core.plot.PlotArea; +import com.plotsquared.core.plot.PlotWorld; +import com.sk89q.worldedit.regions.CuboidRegion; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; +import java.util.Collections; + +/** + * Ordinary plot world with a single plot area + */ +public class StandardPlotWorld extends PlotWorld { + + private final PlotArea area; + + public StandardPlotWorld(@NotNull final String world, @Nullable final PlotArea area) { + super(world); + this.area = area; + } + + @Override @Nullable public PlotArea getArea(@NotNull final Location location) { + return this.area; + } + + @Override @NotNull public Collection getAreas() { + if (this.area == null) { + return Collections.emptyList(); + } + return Collections.singletonList(this.area); + } + + @Override @NotNull public Collection getAreasInRegion(@NotNull final CuboidRegion region) { + return this.getAreas(); + } + +} diff --git a/Core/src/main/java/com/plotsquared/core/util/RegionUtil.java b/Core/src/main/java/com/plotsquared/core/util/RegionUtil.java index fe4d83a96..59b14651a 100644 --- a/Core/src/main/java/com/plotsquared/core/util/RegionUtil.java +++ b/Core/src/main/java/com/plotsquared/core/util/RegionUtil.java @@ -25,9 +25,13 @@ */ package com.plotsquared.core.util; +import com.github.davidmoten.rtree.geometry.Geometries; +import com.github.davidmoten.rtree.geometry.Rectangle; import com.plotsquared.core.plot.Plot; +import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; +import org.jetbrains.annotations.NotNull; public class RegionUtil { public static CuboidRegion createRegion(int pos1x, int pos2x, int pos1z, int pos2z) { @@ -54,6 +58,12 @@ public class RegionUtil { .getY() && y <= max.getY(); } + @NotNull public static Rectangle toRectangle(@NotNull final CuboidRegion region) { + final BlockVector2 min = region.getMinimumPoint().toBlockVector2(); + final BlockVector2 max = region.getMaximumPoint().toBlockVector2(); + return Geometries.rectangle(min.getX(), min.getZ(), max.getX(), max.getZ()); + } + // Because WE (not fawe) lack this for CuboidRegion public static boolean intersects(CuboidRegion region, CuboidRegion other) { BlockVector3 regionMin = region.getMinimumPoint(); From 1c6075df2bed1308e1c2a01fa720c1f7be02a992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Thu, 21 May 2020 20:06:37 +0200 Subject: [PATCH 02/39] Get rid of unused field --- .../plotsquared/core/plot/world/DefaultPlotAreaManager.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/Core/src/main/java/com/plotsquared/core/plot/world/DefaultPlotAreaManager.java b/Core/src/main/java/com/plotsquared/core/plot/world/DefaultPlotAreaManager.java index f86b5b8b6..9ce0b1623 100644 --- a/Core/src/main/java/com/plotsquared/core/plot/world/DefaultPlotAreaManager.java +++ b/Core/src/main/java/com/plotsquared/core/plot/world/DefaultPlotAreaManager.java @@ -44,10 +44,7 @@ import java.util.Set; public class DefaultPlotAreaManager implements PlotAreaManager { final PlotArea[] noPlotAreas = new PlotArea[0]; - private final Map plotWorlds = new HashMap<>(); - // Optimization if there are no hash collisions - private boolean plotAreaHasCollision = false; @Override public PlotArea[] getAllPlotAreas() { final Set area = new HashSet<>(); From 38a7c771bee6d2aef959e80535c9c67e7272a45d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Thu, 21 May 2020 20:23:36 +0200 Subject: [PATCH 03/39] Don't access tree until it has been created --- .../com/plotsquared/core/plot/world/ScatteredPlotWorld.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Core/src/main/java/com/plotsquared/core/plot/world/ScatteredPlotWorld.java b/Core/src/main/java/com/plotsquared/core/plot/world/ScatteredPlotWorld.java index 78cb0b7b2..9f245a5ba 100644 --- a/Core/src/main/java/com/plotsquared/core/plot/world/ScatteredPlotWorld.java +++ b/Core/src/main/java/com/plotsquared/core/plot/world/ScatteredPlotWorld.java @@ -62,6 +62,9 @@ public class ScatteredPlotWorld extends PlotWorld { } @Override @Nullable public PlotArea getArea(@NotNull final Location location) { + if (this.areas.isEmpty()) { + return null; + } synchronized (this.treeLock) { final Observable> area = areaTree.search(Geometries.point(location.getX(), location.getZ())); @@ -87,6 +90,9 @@ public class ScatteredPlotWorld extends PlotWorld { } @Override @NotNull public Collection getAreasInRegion(@NotNull final CuboidRegion region) { + if (this.areas.isEmpty()) { + return Collections.emptyList(); + } synchronized (this.treeLock) { final List areas = new LinkedList<>(); this.areaTree.search(RegionUtil.toRectangle(region)).toBlocking().forEach(entry -> areas.add(entry.value())); From 9752e5f62b41942cced1158901044a49e2bb831b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Fri, 22 May 2020 02:48:32 +0200 Subject: [PATCH 04/39] Start working on single plot areas --- Core/pom.xml | 6 + .../com/plotsquared/core/command/Area.java | 106 ++++++++++++++++++ .../core/configuration/Captions.java | 10 ++ .../core/generator/HybridPlotWorld.java | 12 +- 4 files changed, 132 insertions(+), 2 deletions(-) diff --git a/Core/pom.xml b/Core/pom.xml index 280cd8b1a..4e53e831a 100644 --- a/Core/pom.xml +++ b/Core/pom.xml @@ -92,6 +92,12 @@ 1.3.72 runtime + + com.github.davidmoten + rtree + 0.8.7 + runtime + junit junit diff --git a/Core/src/main/java/com/plotsquared/core/command/Area.java b/Core/src/main/java/com/plotsquared/core/command/Area.java index f5d494868..fcb4993c7 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Area.java +++ b/Core/src/main/java/com/plotsquared/core/command/Area.java @@ -33,6 +33,7 @@ import com.plotsquared.core.events.TeleportCause; import com.plotsquared.core.generator.AugmentedUtils; import com.plotsquared.core.generator.HybridPlotWorld; import com.plotsquared.core.location.Location; +import com.plotsquared.core.player.ConsolePlayer; import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotAreaTerrainType; @@ -50,9 +51,18 @@ import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.RunnableVal3; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.entity.Player; +import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; +import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat; +import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter; import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.regions.Region; +import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Objects; @@ -74,6 +84,102 @@ public class Area extends SubCommand { return false; } switch (args[0].toLowerCase()) { + case "single": + if (player instanceof ConsolePlayer) { + MainUtil.sendMessage(player, Captions.IS_CONSOLE); + return false; + } + if (!Permissions.hasPermission(player, Captions.PERMISSION_AREA_CREATE)) { + MainUtil.sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_AREA_CREATE); + return false; + } + if (args.length < 2) { + MainUtil.sendMessage(player, Captions.SINGLE_AREA_NEEDS_NAME); + return false; + } + if (PlotSquared.get().getPlotArea(player.getLocation().getWorld(), args[1]) != null) { + MainUtil.sendMessage(player, Captions.SINGLE_AREA_NAME_TAKEN); + return false; + } + final LocalSession localSession = WorldEdit.getInstance().getSessionManager().getIfPresent(player.toActor()); + if (localSession == null) { + MainUtil.sendMessage(player, Captions.SINGLE_AREA_MISSING_SELECTION); + return false; + } + Region selectedRegion = null; + try { + selectedRegion = localSession.getSelection(((Player) player.toActor()).getWorld()); + } catch (final Exception ignored) {} + if (selectedRegion == null) { + MainUtil.sendMessage(player, Captions.SINGLE_AREA_MISSING_SELECTION); + return false; + } + if (selectedRegion.getWidth() != selectedRegion.getLength()) { + MainUtil.sendMessage(player, Captions.SINGLE_AREA_NOT_SQUARE); + return false; + } + if (PlotSquared.get().getPlotAreaManager().getPlotAreas( + Objects.requireNonNull(selectedRegion.getWorld()).getName(), CuboidRegion.makeCuboid(selectedRegion)).length != 0) { + MainUtil.sendMessage(player, Captions.SINGLE_AREA_OVERLAPPING); + } + // There's only one plot in the area... + final PlotId plotId = new PlotId(1, 1); + final HybridPlotWorld hybridPlotWorld = new HybridPlotWorld(player.getLocation().getWorld(), args[1], + Objects.requireNonNull(PlotSquared.imp()).getDefaultGenerator(), plotId, plotId); + // Plot size is the same as the region width + hybridPlotWorld.SIZE = (short) selectedRegion.getWidth(); + // We use a schematic generator + hybridPlotWorld.setTerrain(PlotAreaTerrainType.ALL); + // It is always a partial plot world + hybridPlotWorld.setType(PlotAreaType.PARTIAL); + // We save the schematic :D + final File parentFile = MainUtil.getFile(PlotSquared.imp().getDirectory(), "schematics" + File.separator + + "GEN_ROAD_SCHEMATIC" + File.separator + hybridPlotWorld.getWorldName() + File.separator + + hybridPlotWorld.getId()); + if (!parentFile.exists() && !parentFile.mkdirs()) { + MainUtil.sendMessage(player, Captions.SINGLE_AREA_COULD_NOT_MAKE_DIRECTORIES); + return false; + } + final File file = new File(parentFile, "plot.schem"); + try (final ClipboardWriter clipboardWriter = BuiltInClipboardFormat.SPONGE_SCHEMATIC.getWriter(new FileOutputStream(file))) { + final BlockArrayClipboard clipboard = new BlockArrayClipboard(selectedRegion); + clipboardWriter.write(clipboard); + } catch (final Exception e) { + MainUtil.sendMessage(player, Captions.SINGLE_AREA_FAILED_TO_SAVE); + e.printStackTrace(); + return false; + } + // Now the schematic is saved, which is wonderful! + final SetupObject singleSetup = new SetupObject(); + singleSetup.world = hybridPlotWorld.getWorldName(); + singleSetup.id = hybridPlotWorld.getId(); + singleSetup.terrain = hybridPlotWorld.getTerrain(); + singleSetup.type = hybridPlotWorld.getType(); + singleSetup.plotManager = PlotSquared.imp().getPluginName(); + singleSetup.setupGenerator = PlotSquared.imp().getPluginName(); + singleSetup.step = hybridPlotWorld.getSettingNodes(); + singleSetup.max = plotId; + singleSetup.min = plotId; + Runnable singleRun = () -> { + final String world = SetupUtils.manager.setupWorld(singleSetup); + if (WorldUtil.IMP.isWorld(world)) { + PlotSquared.get().loadWorld(world, null); + Captions.SETUP_FINISHED.send(player); + player.teleport(WorldUtil.IMP.getSpawn(world), + TeleportCause.COMMAND); + } else { + MainUtil.sendMessage(player, + "An error occurred while creating the world: " + hybridPlotWorld + .getWorldName()); + } + }; + if (hasConfirmation(player)) { + CmdConfirm.addPending(player, + getCommandString() + " create pos2 (Creates world)", singleRun); + } else { + singleRun.run(); + } + return true; case "c": case "setup": case "create": diff --git a/Core/src/main/java/com/plotsquared/core/configuration/Captions.java b/Core/src/main/java/com/plotsquared/core/configuration/Captions.java index 6238ec066..4e1fc9482 100644 --- a/Core/src/main/java/com/plotsquared/core/configuration/Captions.java +++ b/Core/src/main/java/com/plotsquared/core/configuration/Captions.java @@ -783,6 +783,16 @@ public enum Captions implements Caption { GENERIC_INVALID_CHOICE("invalid choice", "Generic"), // + // + SINGLE_AREA_MISSING_SELECTION("$2Error! You need to select a square region", "Single"), + SINGLE_AREA_NOT_SQUARE("$2Error! Your selection needs to be a square", "Single"), + SINGLE_AREA_OVERLAPPING("$2Error! Your selection overlaps with an existing plot area", "Single"), + SINGLE_AREA_NEEDS_NAME("$2Error! Please specify a plot name: /plot area single ", "Single"), + SINGLE_AREA_NAME_TAKEN("$2Error! The plot name is already taken", "Single"), + SINGLE_AREA_FAILED_TO_SAVE("$2Error! Failed to save the area schematic", "Single"), + SINGLE_AREA_COULD_NOT_MAKE_DIRECTORIES("$2Error! Failed to create the schematic directory", "Single"), + // + /** * Legacy Configuration Conversion */ diff --git a/Core/src/main/java/com/plotsquared/core/generator/HybridPlotWorld.java b/Core/src/main/java/com/plotsquared/core/generator/HybridPlotWorld.java index da7f46a47..e8bb47f66 100644 --- a/Core/src/main/java/com/plotsquared/core/generator/HybridPlotWorld.java +++ b/Core/src/main/java/com/plotsquared/core/generator/HybridPlotWorld.java @@ -195,8 +195,16 @@ public class HybridPlotWorld extends ClassicPlotWorld { public void setupSchematics() throws SchematicHandler.UnsupportedFormatException { this.G_SCH = new HashMap<>(); this.G_SCH_B = new HashMap<>(); - File root = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), - "schematics/GEN_ROAD_SCHEMATIC/" + this.getWorldName()); + + // Try to determine root. This means that plot areas can have separate schematic + // directories + File root; + if (!(root = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), "schematics/GEN_ROAD_SCHEMATIC/" + + this.getWorldName() + "/" + this.getId())).exists()) { + root = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), + "schematics/GEN_ROAD_SCHEMATIC/" + this.getWorldName()); + } + File schematic1File = new File(root, "sideroad.schem"); if (!schematic1File.exists()) schematic1File = new File(root, "sideroad.schematic"); From 7c080770f03e84438613719abe65d255b80cd184 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Fri, 22 May 2020 02:51:40 +0200 Subject: [PATCH 05/39] Shade r-tree into the bukkit module --- Bukkit/build.gradle | 1 + Core/pom.xml | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/Bukkit/build.gradle b/Bukkit/build.gradle index 9fa1f8cf1..4e69d6a41 100644 --- a/Bukkit/build.gradle +++ b/Bukkit/build.gradle @@ -87,6 +87,7 @@ shadowJar { include(dependency("io.papermc:paperlib:1.0.2")) include(dependency("net.kyori:text-adapter-bukkit:3.0.3")) include(dependency("org.bstats:bstats-bukkit:1.7")) + include(dependency("com.github.davidmoten:rtree:0.8.7")) } relocate('net.kyori.text', 'com.plotsquared.formatting.text') relocate("io.papermc.lib", "com.plotsquared.bukkit.paperlib") diff --git a/Core/pom.xml b/Core/pom.xml index 280cd8b1a..4e53e831a 100644 --- a/Core/pom.xml +++ b/Core/pom.xml @@ -92,6 +92,12 @@ 1.3.72 runtime + + com.github.davidmoten + rtree + 0.8.7 + runtime + junit junit From a3179bf11478fb483a8ff5c6e62da6f3c1f590a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Fri, 22 May 2020 02:54:10 +0200 Subject: [PATCH 06/39] Shade rx into the bukkot module --- Bukkit/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/Bukkit/build.gradle b/Bukkit/build.gradle index 4e69d6a41..1e1f8bb02 100644 --- a/Bukkit/build.gradle +++ b/Bukkit/build.gradle @@ -88,6 +88,7 @@ shadowJar { include(dependency("net.kyori:text-adapter-bukkit:3.0.3")) include(dependency("org.bstats:bstats-bukkit:1.7")) include(dependency("com.github.davidmoten:rtree:0.8.7")) + include(dependency("io.reactivex:rxjava:1.3.8")) } relocate('net.kyori.text', 'com.plotsquared.formatting.text') relocate("io.papermc.lib", "com.plotsquared.bukkit.paperlib") From d4bd08415a4c0c4f0ffaa5d3b243bc460e89c7a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Fri, 22 May 2020 02:56:23 +0200 Subject: [PATCH 07/39] Shade guava-mini into the bukkot module --- Bukkit/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/Bukkit/build.gradle b/Bukkit/build.gradle index 1e1f8bb02..5a1c91e20 100644 --- a/Bukkit/build.gradle +++ b/Bukkit/build.gradle @@ -89,6 +89,7 @@ shadowJar { include(dependency("org.bstats:bstats-bukkit:1.7")) include(dependency("com.github.davidmoten:rtree:0.8.7")) include(dependency("io.reactivex:rxjava:1.3.8")) + include(dependency("com.github.davidmoten:guava-mini:0.1.1")) } relocate('net.kyori.text', 'com.plotsquared.formatting.text') relocate("io.papermc.lib", "com.plotsquared.bukkit.paperlib") From b61dfd6f973b49e9f639c2938e90e39ade80d65b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Fri, 22 May 2020 03:20:11 +0200 Subject: [PATCH 08/39] Single plot area progress --- .../com/plotsquared/core/command/Area.java | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/Core/src/main/java/com/plotsquared/core/command/Area.java b/Core/src/main/java/com/plotsquared/core/command/Area.java index fcb4993c7..e2c1e828e 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Area.java +++ b/Core/src/main/java/com/plotsquared/core/command/Area.java @@ -58,6 +58,7 @@ import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat; import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter; import com.sk89q.worldedit.math.BlockVector2; +import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.Region; @@ -97,7 +98,8 @@ public class Area extends SubCommand { MainUtil.sendMessage(player, Captions.SINGLE_AREA_NEEDS_NAME); return false; } - if (PlotSquared.get().getPlotArea(player.getLocation().getWorld(), args[1]) != null) { + final PlotArea existingArea = PlotSquared.get().getPlotArea(player.getLocation().getWorld(), args[1]); + if (existingArea != null && existingArea.getId().equalsIgnoreCase(args[1])) { MainUtil.sendMessage(player, Captions.SINGLE_AREA_NAME_TAKEN); return false; } @@ -127,12 +129,15 @@ public class Area extends SubCommand { final HybridPlotWorld hybridPlotWorld = new HybridPlotWorld(player.getLocation().getWorld(), args[1], Objects.requireNonNull(PlotSquared.imp()).getDefaultGenerator(), plotId, plotId); // Plot size is the same as the region width - hybridPlotWorld.SIZE = (short) selectedRegion.getWidth(); + hybridPlotWorld.PLOT_WIDTH = hybridPlotWorld.SIZE = (short) selectedRegion.getWidth(); // We use a schematic generator hybridPlotWorld.setTerrain(PlotAreaTerrainType.ALL); // It is always a partial plot world hybridPlotWorld.setType(PlotAreaType.PARTIAL); // We save the schematic :D + hybridPlotWorld.PLOT_SCHEMATIC = true; + // Set the road width to 0 + hybridPlotWorld.ROAD_WIDTH = hybridPlotWorld.ROAD_OFFSET_X = hybridPlotWorld.ROAD_OFFSET_Z = 0; final File parentFile = MainUtil.getFile(PlotSquared.imp().getDirectory(), "schematics" + File.separator + "GEN_ROAD_SCHEMATIC" + File.separator + hybridPlotWorld.getWorldName() + File.separator + hybridPlotWorld.getId()); @@ -149,6 +154,9 @@ public class Area extends SubCommand { e.printStackTrace(); return false; } + // Calculate the offset + final BlockVector3 singlePos1 = selectedRegion.getMinimumPoint(); + // Now the schematic is saved, which is wonderful! final SetupObject singleSetup = new SetupObject(); singleSetup.world = hybridPlotWorld.getWorldName(); @@ -161,6 +169,19 @@ public class Area extends SubCommand { singleSetup.max = plotId; singleSetup.min = plotId; Runnable singleRun = () -> { + final String path = + "worlds." + hybridPlotWorld.getWorldName() + ".areas." + hybridPlotWorld.getId() + '-' + + singleSetup.min + '-' + singleSetup.max; + final int offsetX = singlePos1.getX(); + final int offsetZ = singlePos1.getZ(); + if (offsetX != 0) { + PlotSquared.get().worlds + .set(path + ".road.offset.x", offsetX); + } + if (offsetZ != 0) { + PlotSquared.get().worlds + .set(path + ".road.offset.z", offsetZ); + } final String world = SetupUtils.manager.setupWorld(singleSetup); if (WorldUtil.IMP.isWorld(world)) { PlotSquared.get().loadWorld(world, null); From bbde2f5e069379a6bb09cca70747dcc7d3c88c4f Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Fri, 22 May 2020 10:44:51 +0100 Subject: [PATCH 09/39] Slow down queue a bit because 1.13+ performance is bad --- .../com/plotsquared/core/configuration/Settings.java | 4 ++-- .../com/plotsquared/core/queue/GlobalBlockQueue.java | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Core/src/main/java/com/plotsquared/core/configuration/Settings.java b/Core/src/main/java/com/plotsquared/core/configuration/Settings.java index 3fbd71394..2be87ada3 100644 --- a/Core/src/main/java/com/plotsquared/core/configuration/Settings.java +++ b/Core/src/main/java/com/plotsquared/core/configuration/Settings.java @@ -491,9 +491,9 @@ public class Settings extends Config { @Comment("Settings relating to PlotSquared's GlobalBlockQueue") public static final class QUEUE { - @Comment({"Average time per tick spent completing chunk tasks in ms. Target average TPS = 20 * 50 / TARGET_TIME.", + @Comment({"Average time per tick spent completing chunk tasks in ms.", "Waits (chunk task time / target_time) ticks before completely the next task."}) - public static int TARGET_TIME = 65; + public static int TARGET_TIME = 40; } diff --git a/Core/src/main/java/com/plotsquared/core/queue/GlobalBlockQueue.java b/Core/src/main/java/com/plotsquared/core/queue/GlobalBlockQueue.java index 3b63a94c0..6abfea8f8 100644 --- a/Core/src/main/java/com/plotsquared/core/queue/GlobalBlockQueue.java +++ b/Core/src/main/java/com/plotsquared/core/queue/GlobalBlockQueue.java @@ -57,6 +57,7 @@ public class GlobalBlockQueue { private final RunnableVal2 SET_TASK = new RunnableVal2() { @Override public void run(Long free, LocalBlockQueue queue) { + long t1 = System.currentTimeMillis(); do { boolean more = queue.next(); if (!more) { @@ -66,9 +67,9 @@ public class GlobalBlockQueue { } return; } - } while ((lastPeriod = - ((GlobalBlockQueue.this.secondLast = System.currentTimeMillis()) - - GlobalBlockQueue.this.last)) < free); + } while (((GlobalBlockQueue.this.secondLast = System.currentTimeMillis()) + - GlobalBlockQueue.this.last) < free); + lastPeriod = System.currentTimeMillis() - t1; } }; @@ -124,8 +125,8 @@ public class GlobalBlockQueue { lastPeriod -= targetTime; return; } - SET_TASK.value1 = 50 + Math.min( - (50 + GlobalBlockQueue.this.last) - (GlobalBlockQueue.this.last = + SET_TASK.value1 = 30 + Math.min( + (30 + GlobalBlockQueue.this.last) - (GlobalBlockQueue.this.last = System.currentTimeMillis()), GlobalBlockQueue.this.secondLast - System.currentTimeMillis()); SET_TASK.value2 = GlobalBlockQueue.this.getNextQueue(); From 1e3379b00a553987026831f6177ff8242e40d0d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Thu, 21 May 2020 20:06:04 +0200 Subject: [PATCH 10/39] Fix up the plot area nightmare --- Core/build.gradle | 2 + .../com/plotsquared/core/plot/PlotWorld.java | 105 +++++++ .../plot/world/DefaultPlotAreaManager.java | 269 +++++------------- .../core/plot/world/PlotAreaManager.java | 3 +- .../core/plot/world/ScatteredPlotWorld.java | 110 +++++++ .../core/plot/world/StandardPlotWorld.java | 65 +++++ .../com/plotsquared/core/util/RegionUtil.java | 10 + 7 files changed, 372 insertions(+), 192 deletions(-) create mode 100644 Core/src/main/java/com/plotsquared/core/plot/PlotWorld.java create mode 100644 Core/src/main/java/com/plotsquared/core/plot/world/ScatteredPlotWorld.java create mode 100644 Core/src/main/java/com/plotsquared/core/plot/world/StandardPlotWorld.java diff --git a/Core/build.gradle b/Core/build.gradle index ee6edfda2..8581a39a4 100644 --- a/Core/build.gradle +++ b/Core/build.gradle @@ -16,6 +16,7 @@ dependencies { testAnnotationProcessor("org.projectlombok:lombok:1.18.8") implementation("org.jetbrains.kotlin:kotlin-stdlib:1.3.72") implementation("org.jetbrains:annotations:19.0.0") + implementation 'com.github.davidmoten:rtree:0.8.7' } sourceCompatibility = 1.8 @@ -73,6 +74,7 @@ shadowJar { include(dependency("net.kyori:text-serializer-gson:3.0.2")) include(dependency("net.kyori:text-serializer-legacy:3.0.2")) include(dependency("net.kyori:text-serializer-plain:3.0.2")) + include(dependency("com.github.davidmoten:rtree:0.8.7")) } relocate('net.kyori.text', 'com.plotsquared.formatting.text') relocate("org.json", "com.plotsquared.json") { diff --git a/Core/src/main/java/com/plotsquared/core/plot/PlotWorld.java b/Core/src/main/java/com/plotsquared/core/plot/PlotWorld.java new file mode 100644 index 000000000..ed7b854c2 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/plot/PlotWorld.java @@ -0,0 +1,105 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.core.plot; + +import com.plotsquared.core.location.Location; +import com.sk89q.worldedit.regions.CuboidRegion; +import lombok.EqualsAndHashCode; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +/** + * A world that contains plots + */ +@EqualsAndHashCode +public abstract class PlotWorld { + + private final String world; + + /** + * Create a new plot world with a given world name + * + * @param world World name + */ + protected PlotWorld(@NotNull final String world) { + this.world = world; + } + + /** + * Get the plot area that contains the given location, or null + * if the location is not a part of a plot area. + * + * @param location Location + * @return Containing plot area, or null + */ + @Nullable public abstract PlotArea getArea(@NotNull final Location location); + + /** + * Get all plot areas in the world + * + * @return All plot areas in the world + */ + @NotNull public abstract Collection getAreas(); + + /** + * Get all plot areas in a specified region + * + * @param region Region + * @return All areas in the region + */ + @NotNull public abstract Collection getAreasInRegion( + @NotNull final CuboidRegion region); + + /** + * Register a new area in the world + * + * @param area Plot area + */ + public void addArea(@NotNull final PlotArea area) { + throw new UnsupportedOperationException("This world type does not allow adding new areas"); + } + + /** + * Remove an area from the world + * + * @param area Plot area + */ + public void removeArea(@NotNull final PlotArea area) { + throw new UnsupportedOperationException("This world type does not allow removing areas"); + } + + /** + * Get the world name + * + * @return World name + */ + public String getWorld() { + return this.world; + } + +} diff --git a/Core/src/main/java/com/plotsquared/core/plot/world/DefaultPlotAreaManager.java b/Core/src/main/java/com/plotsquared/core/plot/world/DefaultPlotAreaManager.java index 833bf3d4f..f86b5b8b6 100644 --- a/Core/src/main/java/com/plotsquared/core/plot/world/DefaultPlotAreaManager.java +++ b/Core/src/main/java/com/plotsquared/core/plot/world/DefaultPlotAreaManager.java @@ -25,143 +25,96 @@ */ package com.plotsquared.core.plot.world; -import com.plotsquared.core.collection.QuadMap; import com.plotsquared.core.location.Location; import com.plotsquared.core.plot.PlotArea; +import com.plotsquared.core.plot.PlotAreaType; +import com.plotsquared.core.plot.PlotWorld; import com.plotsquared.core.util.StringMan; import com.sk89q.worldedit.regions.CuboidRegion; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; import java.util.Set; public class DefaultPlotAreaManager implements PlotAreaManager { final PlotArea[] noPlotAreas = new PlotArea[0]; - // All plot areas mapped by world - private final HashMap plotAreaMap = new HashMap<>(); - // All plot areas mapped by position - private final HashMap> plotAreaGrid = new HashMap<>(); - private final HashSet plotAreaHashCheck = new HashSet<>(); - // All plot areas - private PlotArea[] plotAreas = new PlotArea[0]; + + private final Map plotWorlds = new HashMap<>(); // Optimization if there are no hash collisions private boolean plotAreaHasCollision = false; - private String[] worlds = new String[0]; @Override public PlotArea[] getAllPlotAreas() { - return plotAreas; - } - - @Override public PlotArea getApplicablePlotArea(Location location) { - switch (this.plotAreas.length) { - case 0: - return null; - case 1: - return this.plotAreas[0].getWorldHash() == location.getWorld().hashCode() - && this.plotAreas[0].contains(location) && (!this.plotAreaHasCollision - || location.getWorld().equals(this.plotAreas[0].getWorldName())) ? - this.plotAreas[0] : - null; - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - String world = location.getWorld(); - int hash = world.hashCode(); - for (PlotArea area : this.plotAreas) { - if (hash == area.getWorldHash()) { - if (area.contains(location.getX(), location.getZ()) && ( - !this.plotAreaHasCollision || world.equals(area.getWorldName()))) { - return area; - } - } - } - return null; - default: - PlotArea[] areas = this.plotAreaMap.get(location.getWorld()); - if (areas == null) { - return null; - } - int z; - int x; - switch (areas.length) { - case 1: - return areas[0]; - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - x = location.getX(); - z = location.getZ(); - for (PlotArea area : areas) { - if (area.contains(x, z)) { - return area; - } - } - return null; - default: - QuadMap search = this.plotAreaGrid.get(location.getWorld()); - return search.get(location.getX(), location.getZ()); - } + final Set area = new HashSet<>(); + for (final PlotWorld world : plotWorlds.values()) { + area.addAll(world.getAreas()); } + return area.toArray(new PlotArea[0]); } - @Override public void addPlotArea(PlotArea plotArea) { - HashSet localAreas = - new HashSet<>(Arrays.asList(getPlotAreas(plotArea.getWorldName(), null))); - HashSet globalAreas = new HashSet<>(Arrays.asList(plotAreas)); - localAreas.add(plotArea); - globalAreas.add(plotArea); - this.plotAreas = globalAreas.toArray(new PlotArea[0]); - this.plotAreaMap.put(plotArea.getWorldName(), localAreas.toArray(new PlotArea[0])); - QuadMap map = this.plotAreaGrid.get(plotArea.getWorldName()); - if (map == null) { - map = new QuadMap(Integer.MAX_VALUE, 0, 0) { - @Override public CuboidRegion getRegion(PlotArea value) { - return value.getRegion(); - } - }; - this.plotAreaGrid.put(plotArea.getWorldName(), map); + @Override @Nullable public PlotArea getApplicablePlotArea(final Location location) { + if (location == null) { + return null; } - map.add(plotArea); + final PlotWorld world = this.plotWorlds.get(location.getWorld()); + if (world == null) { + return null; + } + return world.getArea(location); } - @Override public void removePlotArea(PlotArea area) { - ArrayList globalAreas = new ArrayList<>(Arrays.asList(plotAreas)); - globalAreas.remove(area); - this.plotAreas = globalAreas.toArray(new PlotArea[0]); - if (globalAreas.isEmpty()) { - this.plotAreaMap.remove(area.getWorldName()); - this.plotAreaGrid.remove(area.getWorldName()); + @Override public void addPlotArea(final PlotArea plotArea) { + PlotWorld world = this.plotWorlds.get(plotArea.getWorldName()); + if (world != null) { + if (world instanceof StandardPlotWorld && world.getAreas().isEmpty()) { + this.plotWorlds.remove(plotArea.getWorldName()); + } else { + world.addArea(plotArea); + return; + } + } + if (plotArea.getType() != PlotAreaType.PARTIAL) { + world = new StandardPlotWorld(plotArea.getWorldName(), plotArea); } else { - this.plotAreaMap.put(area.getWorldName(), globalAreas.toArray(new PlotArea[0])); - this.plotAreaGrid.get(area.getWorldName()).remove(area); + world = new ScatteredPlotWorld(plotArea.getWorldName()); + world.addArea(plotArea); + } + this.plotWorlds.put(plotArea.getWorldName(), world); + } + + @Override public void removePlotArea(final PlotArea area) { + final PlotWorld world = this.plotWorlds.get(area.getWorldName()); + if (world == null) { + return; + } + if (world instanceof StandardPlotWorld) { + this.plotWorlds.remove(world.getWorld()); + } else { + world.removeArea(area); + if (world.getAreas().isEmpty()) { + this.plotWorlds.remove(world.getWorld()); + } } } - @Override public PlotArea getPlotArea(String world, String id) { - PlotArea[] areas = this.plotAreaMap.get(world); - if (areas == null) { + @Override public PlotArea getPlotArea(final String world, final String id) { + final PlotWorld plotWorld = this.plotWorlds.get(world); + if (plotWorld == null) { return null; } - if (areas.length == 1) { - return areas[0]; - } else if (id == null) { + final List areas = new ArrayList<>(plotWorld.getAreas()); + if (areas.size() == 1) { + return areas.get(0); + } + if (id == null) { return null; } - for (PlotArea area : areas) { + for (final PlotArea area : areas) { if (StringMan.isEqual(id, area.getId())) { return area; } @@ -169,103 +122,37 @@ public class DefaultPlotAreaManager implements PlotAreaManager { return null; } - @Override public PlotArea getPlotArea(@NotNull Location location) { - switch (this.plotAreas.length) { - case 0: - return null; - case 1: - PlotArea pa = this.plotAreas[0]; - if (pa.contains(location)) { - return pa; - } else { - return null; - } - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - String world = location.getWorld(); - int hash = world.hashCode(); - for (PlotArea area : this.plotAreas) { - if (hash == area.getWorldHash()) { - if (area.contains(location.getX(), location.getZ()) && ( - !this.plotAreaHasCollision || world.equals(area.getWorldName()))) { - return area; - } - } - } - return null; - default: - PlotArea[] areas = this.plotAreaMap.get(location.getWorld()); - if (areas == null) { - return null; - } - int x; - int z; - switch (areas.length) { - case 0: - PlotArea a = areas[0]; - return a.contains(location.getX(), location.getZ()) ? a : null; - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - x = location.getX(); - z = location.getZ(); - for (PlotArea area : areas) { - if (area.contains(x, z)) { - return area; - } - } - return null; - default: - QuadMap search = this.plotAreaGrid.get(location.getWorld()); - return search.get(location.getX(), location.getZ()); - } - } + @Override public PlotArea getPlotArea(@NotNull final Location location) { + return this.getApplicablePlotArea(location); } - @Override public PlotArea[] getPlotAreas(String world, CuboidRegion region) { - if (region == null) { - PlotArea[] areas = this.plotAreaMap.get(world); - if (areas == null) { - return noPlotAreas; - } - return areas; - } - QuadMap areas = this.plotAreaGrid.get(world); - if (areas == null) { + @Override public PlotArea[] getPlotAreas(final String world, final CuboidRegion region) { + final PlotWorld plotWorld = this.plotWorlds.get(world); + if (plotWorld == null) { return noPlotAreas; - } else { - Set found = areas.get(region); - return found.toArray(new PlotArea[0]); } + if (region == null) { + return plotWorld.getAreas().toArray(new PlotArea[0]); + } + return plotWorld.getAreasInRegion(region).toArray(new PlotArea[0]); } - @Override public void addWorld(String worldName) { - if (!this.plotAreaHasCollision && !this.plotAreaHashCheck.add(worldName.hashCode())) { - this.plotAreaHasCollision = true; + @Override public void addWorld(final String worldName) { + PlotWorld world = this.plotWorlds.get(worldName); + if (world != null) { + return; } - Set tmp = new LinkedHashSet<>(); - Collections.addAll(tmp, worlds); - tmp.add(worldName); - worlds = tmp.toArray(new String[0]); + // Create a new empty world. When a new area is added + // the world will be re-recreated with the correct type + world = new StandardPlotWorld(worldName, null); + this.plotWorlds.put(worldName, world); } - @Override public void removeWorld(String worldName) { - Set tmp = new LinkedHashSet<>(); - Collections.addAll(tmp, worlds); - tmp.remove(worldName); - worlds = tmp.toArray(new String[0]); + @Override public void removeWorld(final String worldName) { + this.plotWorlds.remove(worldName); } @Override public String[] getAllWorlds() { - return worlds; + return this.plotWorlds.keySet().toArray(new String[0]); } } diff --git a/Core/src/main/java/com/plotsquared/core/plot/world/PlotAreaManager.java b/Core/src/main/java/com/plotsquared/core/plot/world/PlotAreaManager.java index b6d23b3d4..34033cb2b 100644 --- a/Core/src/main/java/com/plotsquared/core/plot/world/PlotAreaManager.java +++ b/Core/src/main/java/com/plotsquared/core/plot/world/PlotAreaManager.java @@ -29,6 +29,7 @@ import com.plotsquared.core.location.Location; import com.plotsquared.core.plot.PlotArea; import com.sk89q.worldedit.regions.CuboidRegion; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public interface PlotAreaManager { @@ -44,7 +45,7 @@ public interface PlotAreaManager { * @param location The location * @return An applicable area, or null */ - PlotArea getApplicablePlotArea(Location location); + @Nullable PlotArea getApplicablePlotArea(Location location); /** * Get the plot area, if there is any, for the given diff --git a/Core/src/main/java/com/plotsquared/core/plot/world/ScatteredPlotWorld.java b/Core/src/main/java/com/plotsquared/core/plot/world/ScatteredPlotWorld.java new file mode 100644 index 000000000..78cb0b7b2 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/plot/world/ScatteredPlotWorld.java @@ -0,0 +1,110 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.core.plot.world; + +import com.github.davidmoten.rtree.Entry; +import com.github.davidmoten.rtree.RTree; +import com.github.davidmoten.rtree.geometry.Geometries; +import com.github.davidmoten.rtree.geometry.Geometry; +import com.plotsquared.core.location.Location; +import com.plotsquared.core.plot.PlotArea; +import com.plotsquared.core.plot.PlotWorld; +import com.plotsquared.core.util.RegionUtil; +import com.sk89q.worldedit.regions.CuboidRegion; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import rx.Observable; + +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +/** + * Plot world that contains several plot areas (clusters) + */ +public class ScatteredPlotWorld extends PlotWorld { + + private final List areas = new LinkedList<>(); + private final Object treeLock = new Object(); + private RTree areaTree; + + /** + * Create a new plot world with a given world name + * + * @param world World name + */ + public ScatteredPlotWorld(@NotNull final String world) { + super(world); + } + + @Override @Nullable public PlotArea getArea(@NotNull final Location location) { + synchronized (this.treeLock) { + final Observable> area = + areaTree.search(Geometries.point(location.getX(), location.getZ())); + if (area.isEmpty().toBlocking().first()) { + return null; + } + return area.toBlocking().first().value(); + } + } + + @Override @NotNull public Collection getAreas() { + return Collections.unmodifiableCollection(this.areas); + } + + @Override public void addArea(@NotNull final PlotArea area) { + this.areas.add(area); + this.buildTree(); + } + + @Override public void removeArea(@NotNull final PlotArea area) { + this.areas.remove(area); + this.buildTree(); + } + + @Override @NotNull public Collection getAreasInRegion(@NotNull final CuboidRegion region) { + synchronized (this.treeLock) { + final List areas = new LinkedList<>(); + this.areaTree.search(RegionUtil.toRectangle(region)).toBlocking().forEach(entry -> areas.add(entry.value())); + return areas; + } + } + + /** + * Rebuild the area tree + */ + private void buildTree() { + synchronized (this.treeLock) { + this.areaTree = RTree.create(); + for (final PlotArea area : areas) { + this.areaTree = this.areaTree.add(area, + RegionUtil.toRectangle(area.getRegion())); + } + } + } + +} diff --git a/Core/src/main/java/com/plotsquared/core/plot/world/StandardPlotWorld.java b/Core/src/main/java/com/plotsquared/core/plot/world/StandardPlotWorld.java new file mode 100644 index 000000000..162cf0e9f --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/plot/world/StandardPlotWorld.java @@ -0,0 +1,65 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.core.plot.world; + +import com.plotsquared.core.location.Location; +import com.plotsquared.core.plot.PlotArea; +import com.plotsquared.core.plot.PlotWorld; +import com.sk89q.worldedit.regions.CuboidRegion; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; +import java.util.Collections; + +/** + * Ordinary plot world with a single plot area + */ +public class StandardPlotWorld extends PlotWorld { + + private final PlotArea area; + + public StandardPlotWorld(@NotNull final String world, @Nullable final PlotArea area) { + super(world); + this.area = area; + } + + @Override @Nullable public PlotArea getArea(@NotNull final Location location) { + return this.area; + } + + @Override @NotNull public Collection getAreas() { + if (this.area == null) { + return Collections.emptyList(); + } + return Collections.singletonList(this.area); + } + + @Override @NotNull public Collection getAreasInRegion(@NotNull final CuboidRegion region) { + return this.getAreas(); + } + +} diff --git a/Core/src/main/java/com/plotsquared/core/util/RegionUtil.java b/Core/src/main/java/com/plotsquared/core/util/RegionUtil.java index fe4d83a96..59b14651a 100644 --- a/Core/src/main/java/com/plotsquared/core/util/RegionUtil.java +++ b/Core/src/main/java/com/plotsquared/core/util/RegionUtil.java @@ -25,9 +25,13 @@ */ package com.plotsquared.core.util; +import com.github.davidmoten.rtree.geometry.Geometries; +import com.github.davidmoten.rtree.geometry.Rectangle; import com.plotsquared.core.plot.Plot; +import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; +import org.jetbrains.annotations.NotNull; public class RegionUtil { public static CuboidRegion createRegion(int pos1x, int pos2x, int pos1z, int pos2z) { @@ -54,6 +58,12 @@ public class RegionUtil { .getY() && y <= max.getY(); } + @NotNull public static Rectangle toRectangle(@NotNull final CuboidRegion region) { + final BlockVector2 min = region.getMinimumPoint().toBlockVector2(); + final BlockVector2 max = region.getMaximumPoint().toBlockVector2(); + return Geometries.rectangle(min.getX(), min.getZ(), max.getX(), max.getZ()); + } + // Because WE (not fawe) lack this for CuboidRegion public static boolean intersects(CuboidRegion region, CuboidRegion other) { BlockVector3 regionMin = region.getMinimumPoint(); From dd4c5014fc2eb65540a93f2e89b98ec5eb4f39d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Thu, 21 May 2020 20:06:37 +0200 Subject: [PATCH 11/39] Get rid of unused field --- .../plotsquared/core/plot/world/DefaultPlotAreaManager.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/Core/src/main/java/com/plotsquared/core/plot/world/DefaultPlotAreaManager.java b/Core/src/main/java/com/plotsquared/core/plot/world/DefaultPlotAreaManager.java index f86b5b8b6..9ce0b1623 100644 --- a/Core/src/main/java/com/plotsquared/core/plot/world/DefaultPlotAreaManager.java +++ b/Core/src/main/java/com/plotsquared/core/plot/world/DefaultPlotAreaManager.java @@ -44,10 +44,7 @@ import java.util.Set; public class DefaultPlotAreaManager implements PlotAreaManager { final PlotArea[] noPlotAreas = new PlotArea[0]; - private final Map plotWorlds = new HashMap<>(); - // Optimization if there are no hash collisions - private boolean plotAreaHasCollision = false; @Override public PlotArea[] getAllPlotAreas() { final Set area = new HashSet<>(); From 93619b39888791e9dd37c1d918b16dad60e442d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Thu, 21 May 2020 20:23:36 +0200 Subject: [PATCH 12/39] Don't access tree until it has been created --- .../com/plotsquared/core/plot/world/ScatteredPlotWorld.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Core/src/main/java/com/plotsquared/core/plot/world/ScatteredPlotWorld.java b/Core/src/main/java/com/plotsquared/core/plot/world/ScatteredPlotWorld.java index 78cb0b7b2..9f245a5ba 100644 --- a/Core/src/main/java/com/plotsquared/core/plot/world/ScatteredPlotWorld.java +++ b/Core/src/main/java/com/plotsquared/core/plot/world/ScatteredPlotWorld.java @@ -62,6 +62,9 @@ public class ScatteredPlotWorld extends PlotWorld { } @Override @Nullable public PlotArea getArea(@NotNull final Location location) { + if (this.areas.isEmpty()) { + return null; + } synchronized (this.treeLock) { final Observable> area = areaTree.search(Geometries.point(location.getX(), location.getZ())); @@ -87,6 +90,9 @@ public class ScatteredPlotWorld extends PlotWorld { } @Override @NotNull public Collection getAreasInRegion(@NotNull final CuboidRegion region) { + if (this.areas.isEmpty()) { + return Collections.emptyList(); + } synchronized (this.treeLock) { final List areas = new LinkedList<>(); this.areaTree.search(RegionUtil.toRectangle(region)).toBlocking().forEach(entry -> areas.add(entry.value())); From d2af342a5d15b43d6b3f19d29796257f93f33b9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Fri, 22 May 2020 02:51:40 +0200 Subject: [PATCH 13/39] Shade r-tree into the bukkit module --- Bukkit/build.gradle | 1 + Core/pom.xml | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/Bukkit/build.gradle b/Bukkit/build.gradle index 9fa1f8cf1..4e69d6a41 100644 --- a/Bukkit/build.gradle +++ b/Bukkit/build.gradle @@ -87,6 +87,7 @@ shadowJar { include(dependency("io.papermc:paperlib:1.0.2")) include(dependency("net.kyori:text-adapter-bukkit:3.0.3")) include(dependency("org.bstats:bstats-bukkit:1.7")) + include(dependency("com.github.davidmoten:rtree:0.8.7")) } relocate('net.kyori.text', 'com.plotsquared.formatting.text') relocate("io.papermc.lib", "com.plotsquared.bukkit.paperlib") diff --git a/Core/pom.xml b/Core/pom.xml index 280cd8b1a..4e53e831a 100644 --- a/Core/pom.xml +++ b/Core/pom.xml @@ -92,6 +92,12 @@ 1.3.72 runtime + + com.github.davidmoten + rtree + 0.8.7 + runtime + junit junit From a833803bdf223793573162448b50688f55bf3ffd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Fri, 22 May 2020 02:54:10 +0200 Subject: [PATCH 14/39] Shade rx into the bukkot module --- Bukkit/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/Bukkit/build.gradle b/Bukkit/build.gradle index 4e69d6a41..1e1f8bb02 100644 --- a/Bukkit/build.gradle +++ b/Bukkit/build.gradle @@ -88,6 +88,7 @@ shadowJar { include(dependency("net.kyori:text-adapter-bukkit:3.0.3")) include(dependency("org.bstats:bstats-bukkit:1.7")) include(dependency("com.github.davidmoten:rtree:0.8.7")) + include(dependency("io.reactivex:rxjava:1.3.8")) } relocate('net.kyori.text', 'com.plotsquared.formatting.text') relocate("io.papermc.lib", "com.plotsquared.bukkit.paperlib") From eee04ab87d272e494b8dd6931ace9f68b6d1ea5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Fri, 22 May 2020 02:56:23 +0200 Subject: [PATCH 15/39] Shade guava-mini into the bukkot module --- Bukkit/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/Bukkit/build.gradle b/Bukkit/build.gradle index 1e1f8bb02..5a1c91e20 100644 --- a/Bukkit/build.gradle +++ b/Bukkit/build.gradle @@ -89,6 +89,7 @@ shadowJar { include(dependency("org.bstats:bstats-bukkit:1.7")) include(dependency("com.github.davidmoten:rtree:0.8.7")) include(dependency("io.reactivex:rxjava:1.3.8")) + include(dependency("com.github.davidmoten:guava-mini:0.1.1")) } relocate('net.kyori.text', 'com.plotsquared.formatting.text') relocate("io.papermc.lib", "com.plotsquared.bukkit.paperlib") From 5e6b27e21f4f6af015917d8b2217dfd005ef4532 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sat, 23 May 2020 00:33:30 +0200 Subject: [PATCH 16/39] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 17dc0331c..f001d121e 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ is to provide a lag-free and smooth experience. * [Download](https://www.spigotmc.org/resources/plotsquared-v5.77506/) * [Discord](https://discord.gg/KxkjDVg) * [Wiki](https://wiki.intellectualsites.com/plotsquared/home) +* [Issues](https://issues.intellectualsites.com/projects/6572cc05-7756-4c9e-92de-bd28b9aabc3f) ### Developer Resources * [API Documentation](https://wiki.intellectualsites.com/en/plotsquared/developer/development-portal) From 6090c7ccacc764b5a056a35fe3e9a8fca2e3cf90 Mon Sep 17 00:00:00 2001 From: N0tMyFaultOG Date: Sat, 23 May 2020 01:25:18 +0200 Subject: [PATCH 17/39] Link issues to new issue tracker for legacy reasons --- .github/FUNDING.yml | 2 +- .github/ISSUE_TEMPLATE.md | 3 +- .../bug-issue-report-for-plotsquared.md | 101 ------------------ .github/ISSUE_TEMPLATE/config.yml | 3 + README.md | 2 +- 5 files changed, 7 insertions(+), 104 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug-issue-report-for-plotsquared.md diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 717a9cdfc..9b0dbc13e 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -9,4 +9,4 @@ community_bridge: # Replace with a single Community Bridge project-name e.g., cl liberapay: # Replace with a single Liberapay username issuehunt: # Replace with a single IssueHunt username otechie: # Replace with a single Otechie username -custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] +custom: https://www.paypal.me/AlexanderBrandes # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index a70ab837c..f1ee68845 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -28,6 +28,7 @@ assignees: '' +**/plot debugpaste:** ### Server type: **Select one** @@ -97,4 +98,4 @@ for short (20 lines or less) text blobs, or a paste service for large blobs --> - [] I made sure there are no duplicates of this report [(Use Search)](https://github.com/IntellectualSites/PlotSquared/issues?utf8=%E2%9C%93&q=is%3Aissue) - [] I made sure I am using an up-to-date version of PlotSquared - [] I made sure the bug/error is not caused by any other plugin -- [x] I didn't read but checked everything above. +- [x] I didn't read but checked everything above. \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug-issue-report-for-plotsquared.md b/.github/ISSUE_TEMPLATE/bug-issue-report-for-plotsquared.md deleted file mode 100644 index c619a6d14..000000000 --- a/.github/ISSUE_TEMPLATE/bug-issue-report-for-plotsquared.md +++ /dev/null @@ -1,101 +0,0 @@ ---- -name: Bug/Issue report for PlotSquared -about: Bug / Issue report about this plugin -title: '' -labels: "[?] Testing Required" -assignees: '' - ---- - - - - - - - -# Bug Report Template: - -## Required Information section: -> ALL FIELDS IN THIS SECTION ARE REQUIRED, and must contain appropriate information -### Server config info (/plot debugpaste / file paste links): - - - -**/plot debugpaste:** - -### Server type: -**Select one** - -- [] Spigot / Paper *(CraftBukkit should not be used, re-test with Spigot first!)* -- [] Sponge -- [] NukkitX - -### PlotSquared version: - -``` -Paste the output here, between the tick marks, replacing this text -``` - -### Minecraft Version: -**Select one** - -- [] Minecraft 1.15.2 -- [] Minecraft 1.14.4 -- [] Minecraft 1.13.2 -- [] Minecraft 1.12.2 -- [] Minecraft 1.11.2 -- [] Minecraft 1.10.2 -- [] Minecraft 1.9.4 -- [] Minecraft 1.8.8 -- [] Minecraft Java Edition *other versions, please specify*: -- [] Minecraft Bedrock Edition *specify version*: -- [] Minecraft Sponge *specify version*: - -### Server build info: - -``` -Paste the output here, between the tick marks, replacing this text -``` - -### WorldEdit/FAWE versions: - -- [] FAWE version: -- [] WorldEdit version: - -### Description of the problem: - - - -### How to replicate: - - -## Additional Information: -> The information here is optional for you to provide, however it may help us to more readily diagnose any compatibility and bug issues. - -### Other plugins being used on the server: - - -### Relevant console output, log lines, and/or screenshots: - - -### Additional relevant comments/remarks: - - -# AFFIRMATION OF COMPLETION: - -- [] I included all information required in the sections above -- [] I made sure there are no duplicates of this report [(Use Search)](https://github.com/IntellectualSites/PlotSquared/issues?utf8=%E2%9C%93&q=is%3Aissue) -- [] I made sure I am using an up-to-date version of PlotSquared -- [] I made sure the bug/error is not caused by any other plugin -- [x] I didn't read but checked everything above. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 83661f8c6..fd39e3738 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,5 +1,8 @@ blank_issues_enabled: false contact_links: + - name: PlotSquared Issue Tracker + url: https://issues.intellectualsites.com/projects/ps + about: Click here to move to our new issue tracker - name: PlotSquared Suggestions url: https://github.com/IntellectualSites/PlotSquaredSuggestions about: If you want to submit feature or suggestion ideas, do that here \ No newline at end of file diff --git a/README.md b/README.md index f001d121e..64a012710 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ is to provide a lag-free and smooth experience. * [Download](https://www.spigotmc.org/resources/plotsquared-v5.77506/) * [Discord](https://discord.gg/KxkjDVg) * [Wiki](https://wiki.intellectualsites.com/plotsquared/home) -* [Issues](https://issues.intellectualsites.com/projects/6572cc05-7756-4c9e-92de-bd28b9aabc3f) +* [Issues](https://issues.intellectualsites.com/projects/ps) ### Developer Resources * [API Documentation](https://wiki.intellectualsites.com/en/plotsquared/developer/development-portal) From 32a55127f1029c2da0aed0e68a7701d8e9d861e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sat, 23 May 2020 14:32:02 +0200 Subject: [PATCH 18/39] Fix partial area regeneration when using PlotSquared generation. Also fix issues with region height and road width. --- .../bukkit/util/BukkitRegionManager.java | 2 +- .../com/plotsquared/core/PlotSquared.java | 22 ++++++++++++++++++- .../com/plotsquared/core/command/Area.java | 4 +++- .../plotsquared/core/util/ChunkManager.java | 2 +- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitRegionManager.java b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitRegionManager.java index 16c63d093..158f90928 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitRegionManager.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitRegionManager.java @@ -348,7 +348,7 @@ public class BukkitRegionManager extends RegionManager { CuboidRegion currentPlotClear = RegionUtil .createRegion(pos1.getX(), pos2.getX(), pos1.getZ(), pos2.getZ()); map.saveEntitiesOut(chunkObj, currentPlotClear); - AugmentedUtils.bypass(ignoreAugment, () -> ChunkManager.manager + AugmentedUtils.bypass(ignoreAugment, () -> ChunkManager .setChunkInPlotArea(null, new RunnableVal() { @Override public void run(ScopedLocalBlockQueue value) { Location min = value.getMin(); diff --git a/Core/src/main/java/com/plotsquared/core/PlotSquared.java b/Core/src/main/java/com/plotsquared/core/PlotSquared.java index 4cb0731d5..535406a96 100644 --- a/Core/src/main/java/com/plotsquared/core/PlotSquared.java +++ b/Core/src/main/java/com/plotsquared/core/PlotSquared.java @@ -53,6 +53,7 @@ import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.plot.BlockBucket; import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.PlotArea; +import com.plotsquared.core.plot.PlotAreaTerrainType; import com.plotsquared.core.plot.PlotAreaType; import com.plotsquared.core.plot.PlotCluster; import com.plotsquared.core.plot.PlotFilter; @@ -90,6 +91,7 @@ import com.sk89q.worldedit.regions.CuboidRegion; import lombok.Getter; import lombok.NonNull; import lombok.Setter; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.BufferedReader; @@ -270,7 +272,8 @@ public class PlotSquared { // create setup util class SetupUtils.manager = this.IMP.initSetupUtils(); // Set block - GlobalBlockQueue.IMP = new GlobalBlockQueue(IMP.initBlockQueue(), 1, Settings.QUEUE.TARGET_TIME); + GlobalBlockQueue.IMP = + new GlobalBlockQueue(IMP.initBlockQueue(), 1, Settings.QUEUE.TARGET_TIME); GlobalBlockQueue.IMP.runTask(); // Set chunk ChunkManager.manager = this.IMP.initChunkManager(); @@ -2014,6 +2017,23 @@ public class PlotSquared { return Collections.unmodifiableSet(set); } + /** + * Check if the chunk uses vanilla/non-PlotSquared generation + * + * @param world World name + * @param chunkCoordinates Chunk coordinates + * @return True if the chunk uses non-standard generation, false if not + */ + public boolean isNonStandardGeneration(@NotNull final String world, + @NotNull final BlockVector2 chunkCoordinates) { + final Location location = new Location(world, chunkCoordinates.getBlockX() << 4, 64, chunkCoordinates.getBlockZ() << 4); + final PlotArea area = plotAreaManager.getApplicablePlotArea(location); + if (area == null) { + return true; + } + return area.getTerrain() != PlotAreaTerrainType.NONE; + } + public boolean isAugmented(@NonNull final String world) { final PlotArea[] areas = plotAreaManager.getPlotAreas(world, null); return areas != null && (areas.length > 1 || areas[0].getType() != PlotAreaType.NORMAL); diff --git a/Core/src/main/java/com/plotsquared/core/command/Area.java b/Core/src/main/java/com/plotsquared/core/command/Area.java index e2c1e828e..05d97faca 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Area.java +++ b/Core/src/main/java/com/plotsquared/core/command/Area.java @@ -131,13 +131,15 @@ public class Area extends SubCommand { // Plot size is the same as the region width hybridPlotWorld.PLOT_WIDTH = hybridPlotWorld.SIZE = (short) selectedRegion.getWidth(); // We use a schematic generator - hybridPlotWorld.setTerrain(PlotAreaTerrainType.ALL); + hybridPlotWorld.setTerrain(PlotAreaTerrainType.NONE); // It is always a partial plot world hybridPlotWorld.setType(PlotAreaType.PARTIAL); // We save the schematic :D hybridPlotWorld.PLOT_SCHEMATIC = true; // Set the road width to 0 hybridPlotWorld.ROAD_WIDTH = hybridPlotWorld.ROAD_OFFSET_X = hybridPlotWorld.ROAD_OFFSET_Z = 0; + // Set the plot height to the selection height + hybridPlotWorld.PLOT_HEIGHT = hybridPlotWorld.ROAD_HEIGHT = hybridPlotWorld.WALL_HEIGHT = selectedRegion.getHeight(); final File parentFile = MainUtil.getFile(PlotSquared.imp().getDirectory(), "schematics" + File.separator + "GEN_ROAD_SCHEMATIC" + File.separator + hybridPlotWorld.getWorldName() + File.separator + hybridPlotWorld.getId()); diff --git a/Core/src/main/java/com/plotsquared/core/util/ChunkManager.java b/Core/src/main/java/com/plotsquared/core/util/ChunkManager.java index 7bbea34d1..3e052737a 100644 --- a/Core/src/main/java/com/plotsquared/core/util/ChunkManager.java +++ b/Core/src/main/java/com/plotsquared/core/util/ChunkManager.java @@ -52,7 +52,7 @@ public abstract class ChunkManager { public static void setChunkInPlotArea(RunnableVal force, RunnableVal add, String world, BlockVector2 loc) { LocalBlockQueue queue = GlobalBlockQueue.IMP.getNewQueue(world, false); - if (PlotSquared.get().isAugmented(world)) { + if (PlotSquared.get().isAugmented(world) && PlotSquared.get().isNonStandardGeneration(world, loc)) { int blockX = loc.getX() << 4; int blockZ = loc.getZ() << 4; ScopedLocalBlockQueue scoped = From 47c74cfa6d7650675f631e5882313909b4e2709e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sat, 23 May 2020 14:39:28 +0200 Subject: [PATCH 19/39] Set correct region height --- Core/src/main/java/com/plotsquared/core/command/Area.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/main/java/com/plotsquared/core/command/Area.java b/Core/src/main/java/com/plotsquared/core/command/Area.java index 05d97faca..f8846fbf7 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Area.java +++ b/Core/src/main/java/com/plotsquared/core/command/Area.java @@ -139,7 +139,7 @@ public class Area extends SubCommand { // Set the road width to 0 hybridPlotWorld.ROAD_WIDTH = hybridPlotWorld.ROAD_OFFSET_X = hybridPlotWorld.ROAD_OFFSET_Z = 0; // Set the plot height to the selection height - hybridPlotWorld.PLOT_HEIGHT = hybridPlotWorld.ROAD_HEIGHT = hybridPlotWorld.WALL_HEIGHT = selectedRegion.getHeight(); + hybridPlotWorld.PLOT_HEIGHT = hybridPlotWorld.ROAD_HEIGHT = hybridPlotWorld.WALL_HEIGHT = selectedRegion.getMaximumPoint().getBlockY(); final File parentFile = MainUtil.getFile(PlotSquared.imp().getDirectory(), "schematics" + File.separator + "GEN_ROAD_SCHEMATIC" + File.separator + hybridPlotWorld.getWorldName() + File.separator + hybridPlotWorld.getId()); From 8c37cc53407f8526f4a7c9793a9321f4a8e5c8b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sat, 23 May 2020 15:02:31 +0200 Subject: [PATCH 20/39] Fix minor issues --- .../com/plotsquared/core/command/Area.java | 22 +++++++------ .../core/generator/HybridPlotWorld.java | 31 +------------------ .../com/plotsquared/core/plot/PlotArea.java | 2 +- 3 files changed, 15 insertions(+), 40 deletions(-) diff --git a/Core/src/main/java/com/plotsquared/core/command/Area.java b/Core/src/main/java/com/plotsquared/core/command/Area.java index f8846fbf7..15705da27 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Area.java +++ b/Core/src/main/java/com/plotsquared/core/command/Area.java @@ -46,6 +46,7 @@ import com.plotsquared.core.util.MathMan; import com.plotsquared.core.util.Permissions; import com.plotsquared.core.util.RegionManager; import com.plotsquared.core.util.RegionUtil; +import com.plotsquared.core.util.SchematicHandler; import com.plotsquared.core.util.SetupUtils; import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.WorldUtil; @@ -140,6 +141,8 @@ public class Area extends SubCommand { hybridPlotWorld.ROAD_WIDTH = hybridPlotWorld.ROAD_OFFSET_X = hybridPlotWorld.ROAD_OFFSET_Z = 0; // Set the plot height to the selection height hybridPlotWorld.PLOT_HEIGHT = hybridPlotWorld.ROAD_HEIGHT = hybridPlotWorld.WALL_HEIGHT = selectedRegion.getMaximumPoint().getBlockY(); + // No sign plz + hybridPlotWorld.setAllowSigns(false); final File parentFile = MainUtil.getFile(PlotSquared.imp().getDirectory(), "schematics" + File.separator + "GEN_ROAD_SCHEMATIC" + File.separator + hybridPlotWorld.getWorldName() + File.separator + hybridPlotWorld.getId()); @@ -156,6 +159,14 @@ public class Area extends SubCommand { e.printStackTrace(); return false; } + + // Setup schematic + try { + hybridPlotWorld.setupSchematics(); + } catch (final SchematicHandler.UnsupportedFormatException e) { + e.printStackTrace(); + } + // Calculate the offset final BlockVector3 singlePos1 = selectedRegion.getMinimumPoint(); @@ -187,21 +198,14 @@ public class Area extends SubCommand { final String world = SetupUtils.manager.setupWorld(singleSetup); if (WorldUtil.IMP.isWorld(world)) { PlotSquared.get().loadWorld(world, null); - Captions.SETUP_FINISHED.send(player); - player.teleport(WorldUtil.IMP.getSpawn(world), - TeleportCause.COMMAND); + MainUtil.sendMessage(player, Captions.SINGLE_AREA_CREATED); } else { MainUtil.sendMessage(player, "An error occurred while creating the world: " + hybridPlotWorld .getWorldName()); } }; - if (hasConfirmation(player)) { - CmdConfirm.addPending(player, - getCommandString() + " create pos2 (Creates world)", singleRun); - } else { - singleRun.run(); - } + singleRun.run(); return true; case "c": case "setup": diff --git a/Core/src/main/java/com/plotsquared/core/generator/HybridPlotWorld.java b/Core/src/main/java/com/plotsquared/core/generator/HybridPlotWorld.java index e8bb47f66..c2c1323c5 100644 --- a/Core/src/main/java/com/plotsquared/core/generator/HybridPlotWorld.java +++ b/Core/src/main/java/com/plotsquared/core/generator/HybridPlotWorld.java @@ -280,37 +280,8 @@ public class HybridPlotWorld extends ClassicPlotWorld { (short) (z + shift + oddshift + centerShiftZ), biome); } } -/* HashMap items = schematic3.getTiles(); - if (!items.isEmpty()) { - this.G_SCH_STATE = new HashMap<>(); - outer: - for (Map.Entry entry : items.entrySet()) { - BlockLoc loc = entry.getKey(); - short x = (short) (loc.x + shift + oddshift + centerShiftX); - short z = (short) (loc.z + shift + oddshift + centerShiftZ); - short y = (short) (loc.y + this.PLOT_HEIGHT); - int pair = MathMan.pair(x, z); - HashMap existing = this.G_SCH_STATE.get(pair); - if (existing == null) { - existing = new HashMap<>(); - this.G_SCH_STATE.put(pair, existing); - } - existing.put((int) y, entry.getValue()); - CompoundTag tag = entry.getValue(); - Map map = ReflectionUtils.getMap(tag.getValue()); - for (int i = 1; i <= 4; i++) { - String ln = tag.getString("Line" + i); - if (ln == null || ln.length() > 11) - continue outer; - } - SIGN_LOCATION = - new Location(worldname, loc.x + centerShiftX, this.PLOT_HEIGHT + loc.y, - loc.z + centerShiftZ); - ALLOW_SIGNS = true; - continue outer; - } - }*/ + PlotSquared.debug(Captions.PREFIX + "&3 - plot schematic: &7true"); } if (schematic1 == null || schematic2 == null || this.ROAD_WIDTH == 0) { PlotSquared.debug(Captions.PREFIX + "&3 - schematic: &7false"); diff --git a/Core/src/main/java/com/plotsquared/core/plot/PlotArea.java b/Core/src/main/java/com/plotsquared/core/plot/PlotArea.java index 45749d9e1..fc2c12453 100644 --- a/Core/src/main/java/com/plotsquared/core/plot/PlotArea.java +++ b/Core/src/main/java/com/plotsquared/core/plot/PlotArea.java @@ -1023,7 +1023,7 @@ public abstract class PlotArea { * @return true if plot signs are allow, false otherwise. */ public boolean allowSigns() { - return allowSigns; + return allowSigns && (this.plots.size() > 1) /* Do not generate signs for single plots */; } /** From 4dd2613f2f6d88947044a71b471ec30282adbbdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sat, 23 May 2020 15:02:53 +0200 Subject: [PATCH 21/39] Add missing caption --- .../main/java/com/plotsquared/core/configuration/Captions.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/src/main/java/com/plotsquared/core/configuration/Captions.java b/Core/src/main/java/com/plotsquared/core/configuration/Captions.java index 4e1fc9482..1e411d38c 100644 --- a/Core/src/main/java/com/plotsquared/core/configuration/Captions.java +++ b/Core/src/main/java/com/plotsquared/core/configuration/Captions.java @@ -791,6 +791,7 @@ public enum Captions implements Caption { SINGLE_AREA_NAME_TAKEN("$2Error! The plot name is already taken", "Single"), SINGLE_AREA_FAILED_TO_SAVE("$2Error! Failed to save the area schematic", "Single"), SINGLE_AREA_COULD_NOT_MAKE_DIRECTORIES("$2Error! Failed to create the schematic directory", "Single"), + SINGLE_AREA_CREATED("$1The area was created successfully!", "Single"), // /** From 113da81f29f1397d970f6eb2f2ce22d935375fb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sat, 23 May 2020 16:15:48 +0200 Subject: [PATCH 22/39] Actually save the schematic --- .../com/plotsquared/core/command/Area.java | 27 ++++++++++++++----- .../core/generator/HybridPlotWorld.java | 2 +- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/Core/src/main/java/com/plotsquared/core/command/Area.java b/Core/src/main/java/com/plotsquared/core/command/Area.java index 15705da27..932bbf0ab 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Area.java +++ b/Core/src/main/java/com/plotsquared/core/command/Area.java @@ -52,12 +52,15 @@ import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.RunnableVal3; +import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat; import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter; +import com.sk89q.worldedit.function.operation.ForwardExtentCopy; +import com.sk89q.worldedit.function.operation.Operations; import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; @@ -109,22 +112,29 @@ public class Area extends SubCommand { MainUtil.sendMessage(player, Captions.SINGLE_AREA_MISSING_SELECTION); return false; } - Region selectedRegion = null; + Region playerSelectedRegion = null; try { - selectedRegion = localSession.getSelection(((Player) player.toActor()).getWorld()); + playerSelectedRegion = localSession.getSelection(((Player) player.toActor()).getWorld()); } catch (final Exception ignored) {} - if (selectedRegion == null) { + if (playerSelectedRegion == null) { MainUtil.sendMessage(player, Captions.SINGLE_AREA_MISSING_SELECTION); return false; } - if (selectedRegion.getWidth() != selectedRegion.getLength()) { + if (playerSelectedRegion.getWidth() != playerSelectedRegion.getLength()) { MainUtil.sendMessage(player, Captions.SINGLE_AREA_NOT_SQUARE); return false; } if (PlotSquared.get().getPlotAreaManager().getPlotAreas( - Objects.requireNonNull(selectedRegion.getWorld()).getName(), CuboidRegion.makeCuboid(selectedRegion)).length != 0) { + Objects.requireNonNull(playerSelectedRegion.getWorld()).getName(), CuboidRegion.makeCuboid(playerSelectedRegion)).length != 0) { MainUtil.sendMessage(player, Captions.SINGLE_AREA_OVERLAPPING); } + // Alter the region + final BlockVector3 playerSelectionMin = playerSelectedRegion.getMinimumPoint(); + final BlockVector3 playerSelectionMax = playerSelectedRegion.getMaximumPoint(); + // Create a new selection that spans the entire vertical range of the world + final CuboidRegion selectedRegion = new CuboidRegion(playerSelectedRegion.getWorld(), + BlockVector3.at(playerSelectionMin.getX(), 0, playerSelectionMin.getZ()), + BlockVector3.at(playerSelectionMax.getX(), 255, playerSelectionMax.getZ())); // There's only one plot in the area... final PlotId plotId = new PlotId(1, 1); final HybridPlotWorld hybridPlotWorld = new HybridPlotWorld(player.getLocation().getWorld(), args[1], @@ -140,7 +150,7 @@ public class Area extends SubCommand { // Set the road width to 0 hybridPlotWorld.ROAD_WIDTH = hybridPlotWorld.ROAD_OFFSET_X = hybridPlotWorld.ROAD_OFFSET_Z = 0; // Set the plot height to the selection height - hybridPlotWorld.PLOT_HEIGHT = hybridPlotWorld.ROAD_HEIGHT = hybridPlotWorld.WALL_HEIGHT = selectedRegion.getMaximumPoint().getBlockY(); + hybridPlotWorld.PLOT_HEIGHT = hybridPlotWorld.ROAD_HEIGHT = hybridPlotWorld.WALL_HEIGHT = playerSelectionMin.getBlockY(); // No sign plz hybridPlotWorld.setAllowSigns(false); final File parentFile = MainUtil.getFile(PlotSquared.imp().getDirectory(), "schematics" + File.separator + @@ -153,6 +163,11 @@ public class Area extends SubCommand { final File file = new File(parentFile, "plot.schem"); try (final ClipboardWriter clipboardWriter = BuiltInClipboardFormat.SPONGE_SCHEMATIC.getWriter(new FileOutputStream(file))) { final BlockArrayClipboard clipboard = new BlockArrayClipboard(selectedRegion); + final EditSession editSession = WorldEdit.getInstance().getEditSessionFactory().getEditSession(selectedRegion.getWorld(), -1); + final ForwardExtentCopy forwardExtentCopy = new ForwardExtentCopy(editSession, selectedRegion, clipboard, selectedRegion.getMinimumPoint()); + forwardExtentCopy.setCopyingBiomes(true); + forwardExtentCopy.setCopyingEntities(true); + Operations.complete(forwardExtentCopy); clipboardWriter.write(clipboard); } catch (final Exception e) { MainUtil.sendMessage(player, Captions.SINGLE_AREA_FAILED_TO_SAVE); diff --git a/Core/src/main/java/com/plotsquared/core/generator/HybridPlotWorld.java b/Core/src/main/java/com/plotsquared/core/generator/HybridPlotWorld.java index c2c1323c5..49a5c0da4 100644 --- a/Core/src/main/java/com/plotsquared/core/generator/HybridPlotWorld.java +++ b/Core/src/main/java/com/plotsquared/core/generator/HybridPlotWorld.java @@ -281,7 +281,7 @@ public class HybridPlotWorld extends ClassicPlotWorld { } } - PlotSquared.debug(Captions.PREFIX + "&3 - plot schematic: &7true"); + PlotSquared.debug(Captions.PREFIX + "&3 - plot schematic: &7" + schematic3File.getPath()); } if (schematic1 == null || schematic2 == null || this.ROAD_WIDTH == 0) { PlotSquared.debug(Captions.PREFIX + "&3 - schematic: &7false"); From e912909aade0eff98e66c093d4b64346d36b44b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sat, 23 May 2020 22:20:57 +0200 Subject: [PATCH 23/39] Add plot query system --- .../com/plotsquared/core/PlotSquared.java | 99 ++------ .../core/util/query/AliasFilter.java | 43 ++++ .../util/query/AreaLimitedPlotProvider.java | 46 ++++ .../core/util/query/GlobalPlotProvider.java | 39 +++ .../core/util/query/MemberFilter.java | 45 ++++ .../core/util/query/OwnerFilter.java | 46 ++++ .../core/util/query/PaginatedPlotResult.java | 73 ++++++ .../core/util/query/PlotFilter.java | 41 ++++ .../core/util/query/PlotProvider.java | 36 +++ .../core/util/query/PlotQuery.java | 228 ++++++++++++++++++ .../core/util/query/PredicateFilter.java | 45 ++++ 11 files changed, 667 insertions(+), 74 deletions(-) create mode 100644 Core/src/main/java/com/plotsquared/core/util/query/AliasFilter.java create mode 100644 Core/src/main/java/com/plotsquared/core/util/query/AreaLimitedPlotProvider.java create mode 100644 Core/src/main/java/com/plotsquared/core/util/query/GlobalPlotProvider.java create mode 100644 Core/src/main/java/com/plotsquared/core/util/query/MemberFilter.java create mode 100644 Core/src/main/java/com/plotsquared/core/util/query/OwnerFilter.java create mode 100644 Core/src/main/java/com/plotsquared/core/util/query/PaginatedPlotResult.java create mode 100644 Core/src/main/java/com/plotsquared/core/util/query/PlotFilter.java create mode 100644 Core/src/main/java/com/plotsquared/core/util/query/PlotProvider.java create mode 100644 Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java create mode 100644 Core/src/main/java/com/plotsquared/core/util/query/PredicateFilter.java diff --git a/Core/src/main/java/com/plotsquared/core/PlotSquared.java b/Core/src/main/java/com/plotsquared/core/PlotSquared.java index 4cb0731d5..e83cc56ba 100644 --- a/Core/src/main/java/com/plotsquared/core/PlotSquared.java +++ b/Core/src/main/java/com/plotsquared/core/PlotSquared.java @@ -82,6 +82,7 @@ import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.StringWrapper; import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.logger.ILogger; +import com.plotsquared.core.util.query.PlotQuery; import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.uuid.UUIDHandler; import com.sk89q.worldedit.WorldEdit; @@ -116,6 +117,7 @@ import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; @@ -640,17 +642,7 @@ public class PlotSquared { * @return Set of base Plots */ public Set getBasePlots() { - int size = getPlotCount(); - final Set result = new HashSet<>(size); - forEachPlotArea(value -> { - for (Plot plot : value.getPlots()) { - if (!plot.isBasePlot()) { - continue; - } - result.add(plot); - } - }); - return Collections.unmodifiableSet(result); + return PlotQuery.newQuery().whereBasePlot().asSet(); } public List sortPlotsByTemp(Collection plots) { @@ -905,25 +897,22 @@ public class PlotSquared { * @return a filtered set of plots */ public Set getPlots(final PlotFilter... filters) { - final HashSet set = new HashSet<>(); - forEachPlotArea(value -> { - for (PlotFilter filter : filters) { - if (!filter.allowsArea(value)) { - return; + final List areas = new LinkedList<>(); + for (final PlotArea plotArea : this.getPlotAreas()) { + for (final PlotFilter filter : filters) { + if (filter.allowsArea(plotArea)) { + areas.add(plotArea); } } - loop: - for (Entry entry2 : value.getPlotEntries()) { - Plot plot = entry2.getValue(); - for (PlotFilter filter : filters) { - if (!filter.allowsPlot(plot)) { - continue loop; - } + } + return PlotQuery.newQuery().inAreas(areas).thatPasses(plot -> { + for (final PlotFilter filter : filters) { + if (!filter.allowsPlot(plot)) { + return false; } - set.add(plot); } - }); - return set; + return true; + }).asSet(); } /** @@ -990,7 +979,7 @@ public class PlotSquared { * @return Set of plot */ public Set getPlots(String world, PlotPlayer player) { - return getPlots(world, player.getUUID()); + return PlotQuery.newQuery().inWorld(world).ownedBy(player).asSet(); } /** @@ -1001,7 +990,7 @@ public class PlotSquared { * @return Set of plot */ public Set getPlots(PlotArea area, PlotPlayer player) { - return getPlots(area, player.getUUID()); + return PlotQuery.newQuery().inArea(area).ownedBy(player).asSet(); } /** @@ -1012,10 +1001,7 @@ public class PlotSquared { * @return Set of plot */ public Set getPlots(String world, UUID uuid) { - final Set plots = - getPlots(world).stream().filter(plot -> plot.hasOwner() && plot.isOwnerAbs(uuid)) - .collect(Collectors.toSet()); - return Collections.unmodifiableSet(plots); + return PlotQuery.newQuery().inWorld(world).ownedBy(uuid).asSet(); } /** @@ -1026,13 +1012,7 @@ public class PlotSquared { * @return Set of plots */ public Set getPlots(PlotArea area, UUID uuid) { - final Set plots = new HashSet<>(); - for (Plot plot : getPlots(area)) { - if (plot.hasOwner() && plot.isOwnerAbs(uuid)) { - plots.add(plot); - } - } - return Collections.unmodifiableSet(plots); + return PlotQuery.newQuery().inArea(area).ownedBy(uuid).asSet(); } /** @@ -1047,9 +1027,7 @@ public class PlotSquared { } public Collection getPlots(String world) { - final Set set = new HashSet<>(); - forEachPlotArea(world, value -> set.addAll(value.getPlots())); - return set; + return PlotQuery.newQuery().inWorld(world).asCollection(); } /** @@ -1059,7 +1037,7 @@ public class PlotSquared { * @return Set of Plot */ public Set getPlots(PlotPlayer player) { - return getPlots(player.getUUID()); + return PlotQuery.newQuery().ownedBy(player).asSet(); } public Collection getPlots(PlotArea area) { @@ -1081,13 +1059,7 @@ public class PlotSquared { * @return Set of Plot's owned by the player */ public Set getPlots(final UUID uuid) { - final Set plots = new HashSet<>(); - forEachPlot(value -> { - if (value.isOwnerAbs(uuid)) { - plots.add(value); - } - }); - return Collections.unmodifiableSet(plots); + return PlotQuery.newQuery().ownedBy(uuid).asSet(); } public boolean hasPlot(final UUID uuid) { @@ -1096,13 +1068,7 @@ public class PlotSquared { } public Set getBasePlots(final UUID uuid) { - final Set plots = new HashSet<>(); - forEachBasePlot(value -> { - if (value.isOwner(uuid)) { - plots.add(value); - } - }); - return Collections.unmodifiableSet(plots); + return PlotQuery.newQuery().ownedBy(uuid).whereBasePlot().asSet(); } /** @@ -1112,13 +1078,7 @@ public class PlotSquared { * @return Set of Plot */ public Set getPlotsAbs(final UUID uuid) { - final Set plots = new HashSet<>(); - forEachPlot(value -> { - if (value.isOwnerAbs(uuid)) { - plots.add(value); - } - }); - return Collections.unmodifiableSet(plots); + return PlotQuery.newQuery().ownedBy(uuid).asSet(); } /** @@ -2103,16 +2063,7 @@ public class PlotSquared { */ public Set getPlotsByAlias(@Nullable final String alias, @NonNull final String worldname) { - final Set result = new HashSet<>(); - if (alias != null) { - for (final Plot plot : getPlots()) { - if (alias.equals(plot.getAlias()) && (worldname == null || worldname - .equals(plot.getWorldName()))) { - result.add(plot); - } - } - } - return Collections.unmodifiableSet(result); + return PlotQuery.newQuery().inWorld(worldname).withAlias(alias).asSet(); } public Set getPlotAreas(final String world, final CuboidRegion region) { diff --git a/Core/src/main/java/com/plotsquared/core/util/query/AliasFilter.java b/Core/src/main/java/com/plotsquared/core/util/query/AliasFilter.java new file mode 100644 index 000000000..808f34797 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/util/query/AliasFilter.java @@ -0,0 +1,43 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.core.util.query; + +import com.plotsquared.core.plot.Plot; +import org.jetbrains.annotations.NotNull; + +class AliasFilter implements PlotFilter { + + private final String alias; + + AliasFilter(@NotNull final String alias) { + this.alias = alias; + } + + @Override public boolean accepts(@NotNull final Plot plot) { + return this.alias.equalsIgnoreCase(plot.getAlias()); + } + +} diff --git a/Core/src/main/java/com/plotsquared/core/util/query/AreaLimitedPlotProvider.java b/Core/src/main/java/com/plotsquared/core/util/query/AreaLimitedPlotProvider.java new file mode 100644 index 000000000..21a149176 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/util/query/AreaLimitedPlotProvider.java @@ -0,0 +1,46 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.core.util.query; + +import com.plotsquared.core.plot.Plot; +import com.plotsquared.core.plot.PlotArea; + +import java.util.Collection; +import java.util.stream.Stream; + +class AreaLimitedPlotProvider implements PlotProvider { + + private final Collection areas; + + AreaLimitedPlotProvider(Collection areas) { + this.areas = areas; + } + + @Override public Stream getPlots() { + return areas.stream().flatMap(area -> area.getPlots().stream()); + } + +} diff --git a/Core/src/main/java/com/plotsquared/core/util/query/GlobalPlotProvider.java b/Core/src/main/java/com/plotsquared/core/util/query/GlobalPlotProvider.java new file mode 100644 index 000000000..82965aec3 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/util/query/GlobalPlotProvider.java @@ -0,0 +1,39 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.core.util.query; + +import com.plotsquared.core.PlotSquared; +import com.plotsquared.core.plot.Plot; + +import java.util.stream.Stream; + +class GlobalPlotProvider implements PlotProvider { + + @Override public Stream getPlots() { + return PlotSquared.get().getPlots().stream(); + } + +} diff --git a/Core/src/main/java/com/plotsquared/core/util/query/MemberFilter.java b/Core/src/main/java/com/plotsquared/core/util/query/MemberFilter.java new file mode 100644 index 000000000..3f9670d08 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/util/query/MemberFilter.java @@ -0,0 +1,45 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.core.util.query; + +import com.plotsquared.core.plot.Plot; +import org.jetbrains.annotations.NotNull; + +import java.util.UUID; + +class MemberFilter implements PlotFilter { + + @NotNull private final UUID uuid; + + MemberFilter(@NotNull final UUID uuid) { + this.uuid = uuid; + } + + @Override public boolean accepts(@NotNull final Plot plot) { + return plot.isAdded(uuid); + } + +} diff --git a/Core/src/main/java/com/plotsquared/core/util/query/OwnerFilter.java b/Core/src/main/java/com/plotsquared/core/util/query/OwnerFilter.java new file mode 100644 index 000000000..cae258722 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/util/query/OwnerFilter.java @@ -0,0 +1,46 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.core.util.query; + +import com.plotsquared.core.plot.Plot; +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; +import java.util.UUID; + +class OwnerFilter implements PlotFilter { + + private final UUID owner; + + OwnerFilter(@NotNull final UUID owner) { + this.owner = owner; + } + + @Override public boolean accepts(@NotNull final Plot plot) { + return plot.hasOwner() && Objects.equals(plot.getOwnerAbs(), this.owner); + } + +} diff --git a/Core/src/main/java/com/plotsquared/core/util/query/PaginatedPlotResult.java b/Core/src/main/java/com/plotsquared/core/util/query/PaginatedPlotResult.java new file mode 100644 index 000000000..2c0ed9152 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/util/query/PaginatedPlotResult.java @@ -0,0 +1,73 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.core.util.query; + +import com.google.common.base.Preconditions; +import com.plotsquared.core.plot.Plot; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.List; + +/** + * Paginated collection of plots as a result of a {@link PlotQuery query} + */ +public final class PaginatedPlotResult { + + private final List plots; + private final int pageSize; + + PaginatedPlotResult(@NotNull final List plots, final int pageSize) { + this.plots = plots; + this.pageSize = pageSize; + } + + /** + * Get the plots belonging to a certain page. + * + * @param page Positive page number. Indexed from 1 + * @return Plots that belong to the specified page + */ + public List getPage(final int page) { + Preconditions.checkState(page >= 0, "Page must be positive"); + final int from = (page - 1) * this.pageSize; + if (this.plots.size() < from) { + return Collections.emptyList(); + } + final int to = Math.max(from + pageSize, this.plots.size()); + return this.plots.subList(from, to); + } + + /** + * Get the number of available pages + * + * @return Available pages + */ + public int getPages() { + return (int) Math.ceil((double) plots.size() / (double) pageSize); + } + +} diff --git a/Core/src/main/java/com/plotsquared/core/util/query/PlotFilter.java b/Core/src/main/java/com/plotsquared/core/util/query/PlotFilter.java new file mode 100644 index 000000000..c017b21b0 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/util/query/PlotFilter.java @@ -0,0 +1,41 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.core.util.query; + +import com.plotsquared.core.plot.Plot; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Predicate; + +@FunctionalInterface interface PlotFilter extends Predicate { + + @Override default boolean test(@NotNull final Plot plot) { + return this.accepts(plot); + } + + boolean accepts(@NotNull final Plot plot); + +} diff --git a/Core/src/main/java/com/plotsquared/core/util/query/PlotProvider.java b/Core/src/main/java/com/plotsquared/core/util/query/PlotProvider.java new file mode 100644 index 000000000..783288850 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/util/query/PlotProvider.java @@ -0,0 +1,36 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.core.util.query; + +import com.plotsquared.core.plot.Plot; + +import java.util.stream.Stream; + +@FunctionalInterface interface PlotProvider { + + Stream getPlots(); + +} diff --git a/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java b/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java new file mode 100644 index 000000000..0c6132fd9 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java @@ -0,0 +1,228 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.core.util.query; + +import com.google.common.base.Preconditions; +import com.plotsquared.core.PlotSquared; +import com.plotsquared.core.player.PlotPlayer; +import com.plotsquared.core.plot.Plot; +import com.plotsquared.core.plot.PlotArea; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * This represents a plot query, and can be used to + * search for plots matching certain criteria. + *

+ * The queries can be reused as no results are stored + * in the query itself + */ +public final class PlotQuery { + + private PlotProvider plotProvider = new GlobalPlotProvider(); + private final Collection filters = new LinkedList<>(); + + private PlotQuery() { + } + + /** + * Create a new plot query instance + * + * @return New query + */ + public static PlotQuery newQuery() { + return new PlotQuery(); + } + + /** + * Query for plots in a single area + * + * @param area Area + * @return The query instance + */ + @NotNull public PlotQuery inArea(@NotNull final PlotArea area) { + Preconditions.checkNotNull(area, "Area may not be null"); + this.plotProvider = new AreaLimitedPlotProvider(Collections.singletonList(area)); + return this; + } + + /** + * Query for plots in all areas in a world + * + * @param world World name + * @return The query instance + */ + @NotNull public PlotQuery inWorld(@NotNull final String world) { + Preconditions.checkNotNull(world, "World may not be null"); + this.plotProvider = new AreaLimitedPlotProvider(PlotSquared.get().getPlotAreas(world)); + return this; + } + + /** + * Query for plots in specific areas + * + * @param areas Plot areas + * @return The query instance + */ + @NotNull public PlotQuery inAreas(@NotNull final Collection areas) { + Preconditions.checkNotNull(areas, "Areas may not be null"); + Preconditions.checkState(!areas.isEmpty(), "At least one area must be provided"); + this.plotProvider = new AreaLimitedPlotProvider(Collections.unmodifiableCollection(areas)); + return this; + } + + /** + * Query for base plots only + * + * @return The query instance + */ + @NotNull public PlotQuery whereBasePlot() { + return this.addFilter(new PredicateFilter(Plot::isBasePlot)); + } + + /** + * Query for plots owned by a specific player + * + * @param owner Owner UUID + * @return The query instance + */ + @NotNull public PlotQuery ownedBy(@NotNull final UUID owner) { + Preconditions.checkNotNull(owner, "Owner may not be null"); + return this.addFilter(new OwnerFilter(owner)); + } + + /** + * Query for plots owned by a specific player + * + * @param owner Owner + * @return The query instance + */ + @NotNull public PlotQuery ownedBy(@NotNull final PlotPlayer owner) { + Preconditions.checkNotNull(owner, "Owner may not be null"); + return this.addFilter(new OwnerFilter(owner.getUUID())); + } + + /** + * Query for plots with a specific alias + * + * @param alias Plot alias + * @return The query instance + */ + @NotNull public PlotQuery withAlias(@NotNull final String alias) { + Preconditions.checkNotNull(alias, "Alias may not be null"); + return this.addFilter(new AliasFilter(alias)); + } + + /** + * Query for plots with a specific member (added/trusted/owner) + * + * @param member Member UUID + * @return The query instance + */ + @NotNull public PlotQuery withMember(@NotNull final UUID member) { + Preconditions.checkNotNull(member, "Member may not be null"); + return this.addFilter(new MemberFilter(member)); + } + + /** + * Query for plots that passes a given predicate + * + * @param predicate Predicate + * @return The query instance + */ + @NotNull public PlotQuery thatPasses(@NotNull final Predicate predicate) { + Preconditions.checkNotNull(predicate, "Predicate may not be null"); + return this.addFilter(new PredicateFilter(predicate)); + } + + /** + * Get all plots that match the given criteria + * + * @return Matching plots + */ + @NotNull public Stream asStream() { + Stream plots = this.plotProvider.getPlots(); + for (final PlotFilter filter : this.filters) { + plots = plots.filter(filter); + } + return plots; + } + + /** + * Get all plots that match the given criteria + * + * @return Matching plots as an immutable list + */ + @NotNull public List asList() { + return Collections.unmodifiableList(this.asStream().collect(Collectors.toList())); + } + + /** + * Get all plots that match the given criteria + * + * @return Matching plots as an immutable set + */ + @NotNull public Set asSet() { + return Collections.unmodifiableSet(this.asStream().collect(Collectors.toSet())); + } + + /** + * Get all plots that match the given criteria + * in the form of a {@link PaginatedPlotResult} + * + * @param pageSize The size of the pages. Must be positive. + * @return Paginated plot result + */ + @NotNull public PaginatedPlotResult getPaginated(final int pageSize) { + Preconditions.checkState(pageSize > 0, "Page size must be greater than 0"); + return new PaginatedPlotResult(this.asList(), pageSize); + } + + /** + * Get all plots that match the given criteria + * + * @return Matching plots as an immutable collection + */ + @NotNull public Collection asCollection() { + return this.asList(); + } + + @NotNull private PlotQuery addFilter(@NotNull final PlotFilter filter) { + this.filters.add(filter); + return this; + } + + +} diff --git a/Core/src/main/java/com/plotsquared/core/util/query/PredicateFilter.java b/Core/src/main/java/com/plotsquared/core/util/query/PredicateFilter.java new file mode 100644 index 000000000..dd68f081d --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/util/query/PredicateFilter.java @@ -0,0 +1,45 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.core.util.query; + +import com.plotsquared.core.plot.Plot; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Predicate; + +class PredicateFilter implements PlotFilter { + + private final Predicate predicate; + + PredicateFilter(@NotNull final Predicate predicate) { + this.predicate = predicate; + } + + @Override public boolean accepts(@NotNull final Plot plot) { + return predicate.test(plot); + } + +} From 508fdce70485a111bbe75e79988b323aef28311f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sat, 23 May 2020 23:58:24 +0200 Subject: [PATCH 24/39] Add missing methods to PlotQuery and use PlotQuery in ListCmd --- .../com/plotsquared/core/command/ListCmd.java | 135 ++++++----------- .../util/query/AreaLimitedPlotProvider.java | 11 +- .../core/util/query/ExploredPlotProvider.java | 39 +++++ .../core/util/query/GlobalPlotProvider.java | 6 +- .../core/util/query/NullProvider.java | 39 +++++ .../core/util/query/PlotProvider.java | 4 +- .../core/util/query/PlotQuery.java | 139 ++++++++++++++++-- .../core/util/query/SearchPlotProvider.java | 46 ++++++ .../core/util/query/SortingStrategy.java | 52 +++++++ 9 files changed, 364 insertions(+), 107 deletions(-) create mode 100644 Core/src/main/java/com/plotsquared/core/util/query/ExploredPlotProvider.java create mode 100644 Core/src/main/java/com/plotsquared/core/util/query/NullProvider.java create mode 100644 Core/src/main/java/com/plotsquared/core/util/query/SearchPlotProvider.java create mode 100644 Core/src/main/java/com/plotsquared/core/util/query/SortingStrategy.java diff --git a/Core/src/main/java/com/plotsquared/core/command/ListCmd.java b/Core/src/main/java/com/plotsquared/core/command/ListCmd.java index 8d151fb10..c83ee5c4a 100644 --- a/Core/src/main/java/com/plotsquared/core/command/ListCmd.java +++ b/Core/src/main/java/com/plotsquared/core/command/ListCmd.java @@ -26,13 +26,11 @@ package com.plotsquared.core.command; import com.plotsquared.core.PlotSquared; -import com.plotsquared.core.PlotSquared.SortType; import com.plotsquared.core.configuration.CaptionUtility; import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.PlotArea; -import com.plotsquared.core.plot.Rating; import com.plotsquared.core.plot.expiration.ExpireManager; import com.plotsquared.core.plot.flag.implementations.DoneFlag; import com.plotsquared.core.plot.flag.implementations.PriceFlag; @@ -43,13 +41,14 @@ import com.plotsquared.core.util.MathMan; import com.plotsquared.core.util.Permissions; import com.plotsquared.core.util.StringComparison; import com.plotsquared.core.util.StringMan; +import com.plotsquared.core.util.query.PlotQuery; +import com.plotsquared.core.util.query.SortingStrategy; import com.plotsquared.core.util.task.RunnableVal3; import com.plotsquared.core.util.uuid.UUIDHandler; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.Map.Entry; import java.util.UUID; @CommandDeclaration(command = "list", @@ -128,12 +127,13 @@ public class ListCmd extends SubCommand { } } - List plots = null; - String world = player.getLocation().getWorld(); PlotArea area = player.getApplicablePlotArea(); String arg = args[0].toLowerCase(); boolean sort = true; + + PlotQuery query = null; + switch (arg) { case "mine": if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_MINE)) { @@ -141,8 +141,8 @@ public class ListCmd extends SubCommand { .sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_LIST_MINE); return false; } + query = PlotQuery.newQuery().ownedBy(player).whereBasePlot().withSortingStrategy(SortingStrategy.SORT_BY_TEMP); sort = false; - plots = PlotSquared.get().sortPlotsByTemp(PlotSquared.get().getBasePlots(player)); break; case "shared": if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_SHARED)) { @@ -150,13 +150,8 @@ public class ListCmd extends SubCommand { Captions.PERMISSION_LIST_SHARED); return false; } - plots = new ArrayList<>(); - for (Plot plot : PlotSquared.get().getPlots()) { - if (plot.getTrusted().contains(player.getUUID()) || plot.getMembers() - .contains(player.getUUID())) { - plots.add(plot); - } - } + // withMember checks for trusted + members + owner, we don't want the owner part + query = PlotQuery.newQuery().withMember(player.getUUID()).thatPasses(plot -> !plot.isOwnerAbs(player.getUUID())); break; case "world": if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_WORLD)) { @@ -171,7 +166,7 @@ public class ListCmd extends SubCommand { world)); return false; } - plots = new ArrayList<>(PlotSquared.get().getPlots(world)); + query = PlotQuery.newQuery().inWorld(world); break; case "expired": if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_EXPIRED)) { @@ -179,9 +174,11 @@ public class ListCmd extends SubCommand { Captions.PERMISSION_LIST_EXPIRED); return false; } - plots = ExpireManager.IMP == null ? - new ArrayList() : - new ArrayList<>(ExpireManager.IMP.getPendingExpired()); + if (ExpireManager.IMP == null) { + query = PlotQuery.newQuery().noPlots(); + } else { + query = PlotQuery.newQuery().expiredPlots(); + } break; case "area": if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_AREA)) { @@ -196,7 +193,11 @@ public class ListCmd extends SubCommand { world)); return false; } - plots = area == null ? new ArrayList() : new ArrayList<>(area.getPlots()); + if (area == null) { + query = PlotQuery.newQuery().noPlots(); + } else { + query = PlotQuery.newQuery().inArea(area); + } break; case "all": if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_ALL)) { @@ -204,7 +205,7 @@ public class ListCmd extends SubCommand { .sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_LIST_ALL); return false; } - plots = new ArrayList<>(PlotSquared.get().getPlots()); + query = PlotQuery.newQuery().allPlots(); break; case "done": if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_DONE)) { @@ -212,23 +213,7 @@ public class ListCmd extends SubCommand { .sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_LIST_DONE); return false; } - plots = new ArrayList<>(); - for (Plot plot : PlotSquared.get().getPlots()) { - if (DoneFlag.isDone(plot)) { - plots.add(plot); - } - } - plots.sort((a, b) -> { - String va = a.getFlag(DoneFlag.class); - String vb = b.getFlag(DoneFlag.class); - if (MathMan.isInteger(va)) { - if (MathMan.isInteger(vb)) { - return Integer.parseInt(vb) - Integer.parseInt(va); - } - return -1; - } - return 1; - }); + query = PlotQuery.newQuery().allPlots().thatPasses(DoneFlag::isDone).withSortingStrategy(SortingStrategy.SORT_BY_DONE); sort = false; break; case "top": @@ -237,31 +222,7 @@ public class ListCmd extends SubCommand { .sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_LIST_TOP); return false; } - plots = new ArrayList<>(PlotSquared.get().getPlots()); - plots.sort((p1, p2) -> { - double v1 = 0; - int p1s = p1.getSettings().getRatings().size(); - int p2s = p2.getRatings().size(); - if (!p1.getSettings().getRatings().isEmpty()) { - v1 = p1.getRatings().values().stream().mapToDouble(Rating::getAverageRating) - .map(av -> av * av).sum(); - v1 /= p1s; - v1 += p1s; - } - double v2 = 0; - if (!p2.getSettings().getRatings().isEmpty()) { - for (Entry entry : p2.getRatings().entrySet()) { - double av = entry.getValue().getAverageRating(); - v2 += av * av; - } - v2 /= p2s; - v2 += p2s; - } - if (v2 == v1 && v2 != 0) { - return p2s - p1s; - } - return (int) Math.signum(v2 - v1); - }); + query = PlotQuery.newQuery().allPlots().withSortingStrategy(SortingStrategy.SORT_BY_RATING); sort = false; break; case "forsale": @@ -273,12 +234,7 @@ public class ListCmd extends SubCommand { if (EconHandler.manager == null) { break; } - plots = new ArrayList<>(); - for (Plot plot : PlotSquared.get().getPlots()) { - if (plot.getFlag(PriceFlag.class) > 0) { - plots.add(plot); - } - } + query = PlotQuery.newQuery().allPlots().thatPasses(plot -> plot.getFlag(PriceFlag.class) > 0); break; case "unowned": if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_UNOWNED)) { @@ -286,12 +242,7 @@ public class ListCmd extends SubCommand { Captions.PERMISSION_LIST_UNOWNED); return false; } - plots = new ArrayList<>(); - for (Plot plot : PlotSquared.get().getPlots()) { - if (plot.getOwner() == null) { - plots.add(plot); - } - } + query = PlotQuery.newQuery().allPlots().thatPasses(plot -> plot.getOwner() == null); break; case "unknown": if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_UNKNOWN)) { @@ -299,15 +250,12 @@ public class ListCmd extends SubCommand { Captions.PERMISSION_LIST_UNKNOWN); return false; } - plots = new ArrayList<>(); - for (Plot plot : PlotSquared.get().getPlots()) { + query = PlotQuery.newQuery().allPlots().thatPasses(plot -> { if (plot.getOwner() == null) { - continue; + return false; } - if (UUIDHandler.getName(plot.getOwner()) == null) { - plots.add(plot); - } - } + return UUIDHandler.getName(plot.getOwner()) == null; + }); break; case "fuzzy": if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_FUZZY)) { @@ -325,7 +273,7 @@ public class ListCmd extends SubCommand { } else { term = StringMan.join(Arrays.copyOfRange(args, 1, args.length), " "); } - plots = MainUtil.getPlotsBySearch(term); + query = PlotQuery.newQuery().plotsBySearch(term); sort = false; break; default: @@ -343,7 +291,7 @@ public class ListCmd extends SubCommand { args[0])); return false; } - plots = new ArrayList<>(PlotSquared.get().getPlots(args[0])); + query = PlotQuery.newQuery().inWorld(args[0]); break; } UUID uuid = UUIDHandler.getUUID(args[0], null); @@ -360,33 +308,40 @@ public class ListCmd extends SubCommand { return false; } sort = false; - plots = PlotSquared.get().sortPlotsByTemp(PlotSquared.get().getPlots(uuid)); + query = PlotQuery.newQuery().ownedBy(uuid).withSortingStrategy(SortingStrategy.SORT_BY_TEMP); break; } } - if (plots == null) { + if (query == null) { sendMessage(player, Captions.DID_YOU_MEAN, new StringComparison<>(args[0], new String[] {"mine", "shared", "world", "all"}) .getBestMatch()); return false; } + + if (area != null) { + query.relativeToArea(area); + } + + if (sort) { + query.withSortingStrategy(SortingStrategy.SORT_BY_CREATION); + } + + final List plots = query.asList(); + if (plots.isEmpty()) { MainUtil.sendMessage(player, Captions.FOUND_NO_PLOTS); return false; } - displayPlots(player, plots, 12, page, area, args, sort); + displayPlots(player, plots, 12, page, args); return true; } - public void displayPlots(final PlotPlayer player, List plots, int pageSize, int page, - PlotArea area, String[] args, boolean sort) { + public void displayPlots(final PlotPlayer player, List plots, int pageSize, int page, String[] args) { // Header plots.removeIf(plot -> !plot.isBasePlot()); - if (sort) { - plots = PlotSquared.get().sortPlots(plots, SortType.CREATION_DATE, area); - } this.paginate(player, plots, pageSize, page, new RunnableVal3() { @Override public void run(Integer i, Plot plot, PlotMessage message) { diff --git a/Core/src/main/java/com/plotsquared/core/util/query/AreaLimitedPlotProvider.java b/Core/src/main/java/com/plotsquared/core/util/query/AreaLimitedPlotProvider.java index 21a149176..2a6e88171 100644 --- a/Core/src/main/java/com/plotsquared/core/util/query/AreaLimitedPlotProvider.java +++ b/Core/src/main/java/com/plotsquared/core/util/query/AreaLimitedPlotProvider.java @@ -29,7 +29,8 @@ import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.PlotArea; import java.util.Collection; -import java.util.stream.Stream; +import java.util.LinkedList; +import java.util.List; class AreaLimitedPlotProvider implements PlotProvider { @@ -39,8 +40,12 @@ class AreaLimitedPlotProvider implements PlotProvider { this.areas = areas; } - @Override public Stream getPlots() { - return areas.stream().flatMap(area -> area.getPlots().stream()); + @Override public Collection getPlots() { + final List plots = new LinkedList<>(); + for (final PlotArea area : areas) { + plots.addAll(area.getPlots()); + } + return plots; } } diff --git a/Core/src/main/java/com/plotsquared/core/util/query/ExploredPlotProvider.java b/Core/src/main/java/com/plotsquared/core/util/query/ExploredPlotProvider.java new file mode 100644 index 000000000..94bf9b92e --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/util/query/ExploredPlotProvider.java @@ -0,0 +1,39 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.core.util.query; + +import com.plotsquared.core.plot.Plot; +import com.plotsquared.core.plot.expiration.ExpireManager; + +import java.util.Collection; + +class ExploredPlotProvider implements PlotProvider { + + @Override public Collection getPlots() { + return ExpireManager.IMP.getPendingExpired(); + } + +} diff --git a/Core/src/main/java/com/plotsquared/core/util/query/GlobalPlotProvider.java b/Core/src/main/java/com/plotsquared/core/util/query/GlobalPlotProvider.java index 82965aec3..3fb2420c5 100644 --- a/Core/src/main/java/com/plotsquared/core/util/query/GlobalPlotProvider.java +++ b/Core/src/main/java/com/plotsquared/core/util/query/GlobalPlotProvider.java @@ -28,12 +28,12 @@ package com.plotsquared.core.util.query; import com.plotsquared.core.PlotSquared; import com.plotsquared.core.plot.Plot; -import java.util.stream.Stream; +import java.util.Collection; class GlobalPlotProvider implements PlotProvider { - @Override public Stream getPlots() { - return PlotSquared.get().getPlots().stream(); + @Override public Collection getPlots() { + return PlotSquared.get().getPlots(); } } diff --git a/Core/src/main/java/com/plotsquared/core/util/query/NullProvider.java b/Core/src/main/java/com/plotsquared/core/util/query/NullProvider.java new file mode 100644 index 000000000..6cf3a70d4 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/util/query/NullProvider.java @@ -0,0 +1,39 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.core.util.query; + +import com.plotsquared.core.plot.Plot; + +import java.util.Collection; +import java.util.Collections; + +class NullProvider implements PlotProvider { + + @Override public Collection getPlots() { + return Collections.emptyList(); + } + +} diff --git a/Core/src/main/java/com/plotsquared/core/util/query/PlotProvider.java b/Core/src/main/java/com/plotsquared/core/util/query/PlotProvider.java index 783288850..c8048da1a 100644 --- a/Core/src/main/java/com/plotsquared/core/util/query/PlotProvider.java +++ b/Core/src/main/java/com/plotsquared/core/util/query/PlotProvider.java @@ -27,10 +27,10 @@ package com.plotsquared.core.util.query; import com.plotsquared.core.plot.Plot; -import java.util.stream.Stream; +import java.util.Collection; @FunctionalInterface interface PlotProvider { - Stream getPlots(); + Collection getPlots(); } diff --git a/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java b/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java index 0c6132fd9..612c4c21c 100644 --- a/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java +++ b/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java @@ -30,16 +30,21 @@ import com.plotsquared.core.PlotSquared; import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.PlotArea; +import com.plotsquared.core.plot.Rating; +import com.plotsquared.core.plot.flag.implementations.DoneFlag; +import com.plotsquared.core.util.MathMan; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.function.Predicate; -import java.util.stream.Collectors; import java.util.stream.Stream; /** @@ -51,8 +56,10 @@ import java.util.stream.Stream; */ public final class PlotQuery { - private PlotProvider plotProvider = new GlobalPlotProvider(); private final Collection filters = new LinkedList<>(); + private PlotProvider plotProvider = new GlobalPlotProvider(); + private SortingStrategy sortingStrategy = SortingStrategy.NO_SORTING; + private PlotArea priorityArea; private PlotQuery() { } @@ -103,6 +110,47 @@ public final class PlotQuery { return this; } + /** + * Query for expired plots + * + * @return The query instance + */ + @NotNull public PlotQuery expiredPlots() { + this.plotProvider = new ExploredPlotProvider(); + return this; + } + + /** + * Query for all plots + * + * @return The query instance + */ + @NotNull public PlotQuery allPlots() { + this.plotProvider = new GlobalPlotProvider(); + return this; + } + + /** + * Don't query at all + * + * @return The query instance + */ + @NotNull public PlotQuery noPlots() { + this.plotProvider = new NullProvider(); + return this; + } + + /** + * Query for plots based on a search term + * + * @return The query instance + */ + @NotNull public PlotQuery plotsBySearch(@NotNull final String searchTerm) { + Preconditions.checkNotNull(searchTerm, "Search term may not be null"); + this.plotProvider = new SearchPlotProvider(searchTerm); + return this; + } + /** * Query for base plots only * @@ -167,17 +215,32 @@ public final class PlotQuery { return this.addFilter(new PredicateFilter(predicate)); } + /** + * Specify the sorting strategy that will decide how to + * sort the results. This only matters if you use {@link #asList()} + * + * @param strategy Strategy + * @return The query instance + */ + @NotNull public PlotQuery withSortingStrategy(@NotNull final SortingStrategy strategy) { + Preconditions.checkNotNull(strategy, "Strategy may not be null"); + this.sortingStrategy = strategy; + return this; + } + + @NotNull public PlotQuery relativeToArea(@NotNull final PlotArea plotArea) { + Preconditions.checkNotNull(plotArea, "Area may not be null"); + this.priorityArea = plotArea; + return this; + } + /** * Get all plots that match the given criteria * * @return Matching plots */ @NotNull public Stream asStream() { - Stream plots = this.plotProvider.getPlots(); - for (final PlotFilter filter : this.filters) { - plots = plots.filter(filter); - } - return plots; + return this.asList().stream(); } /** @@ -186,7 +249,65 @@ public final class PlotQuery { * @return Matching plots as an immutable list */ @NotNull public List asList() { - return Collections.unmodifiableList(this.asStream().collect(Collectors.toList())); + final List result; + if (this.filters.isEmpty()) { + result = new ArrayList<>(this.plotProvider.getPlots()); + } else { + final Collection plots = this.plotProvider.getPlots(); + result = new ArrayList<>(plots.size()); + for (final Plot plot : plots) { + for (final PlotFilter filter : this.filters) { + if (filter.accepts(plot)) { + result.add(plot); + } + } + } + } + if (this.sortingStrategy == SortingStrategy.NO_SORTING) { + return result; + } else if (this.sortingStrategy == SortingStrategy.SORT_BY_TEMP) { + return PlotSquared.get().sortPlotsByTemp(result); + } else if (this.sortingStrategy == SortingStrategy.SORT_BY_DONE) { + result.sort((a, b) -> { + String va = a.getFlag(DoneFlag.class); + String vb = b.getFlag(DoneFlag.class); + if (MathMan.isInteger(va)) { + if (MathMan.isInteger(vb)) { + return Integer.parseInt(vb) - Integer.parseInt(va); + } + return -1; + } + return 1; + }); + } else if (this.sortingStrategy == SortingStrategy.SORT_BY_RATING) { + result.sort((p1, p2) -> { + double v1 = 0; + int p1s = p1.getSettings().getRatings().size(); + int p2s = p2.getRatings().size(); + if (!p1.getSettings().getRatings().isEmpty()) { + v1 = p1.getRatings().values().stream().mapToDouble(Rating::getAverageRating) + .map(av -> av * av).sum(); + v1 /= p1s; + v1 += p1s; + } + double v2 = 0; + if (!p2.getSettings().getRatings().isEmpty()) { + for (Map.Entry entry : p2.getRatings().entrySet()) { + double av = entry.getValue().getAverageRating(); + v2 += av * av; + } + v2 /= p2s; + v2 += p2s; + } + if (v2 == v1 && v2 != 0) { + return p2s - p1s; + } + return (int) Math.signum(v2 - v1); + }); + } else if (this.sortingStrategy == SortingStrategy.SORT_BY_CREATION) { + return PlotSquared.get().sortPlots(result, PlotSquared.SortType.CREATION_DATE, this.priorityArea); + } + return result; } /** @@ -195,7 +316,7 @@ public final class PlotQuery { * @return Matching plots as an immutable set */ @NotNull public Set asSet() { - return Collections.unmodifiableSet(this.asStream().collect(Collectors.toSet())); + return new HashSet<>(this.asList()); } /** diff --git a/Core/src/main/java/com/plotsquared/core/util/query/SearchPlotProvider.java b/Core/src/main/java/com/plotsquared/core/util/query/SearchPlotProvider.java new file mode 100644 index 000000000..91193a79e --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/util/query/SearchPlotProvider.java @@ -0,0 +1,46 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.core.util.query; + +import com.plotsquared.core.plot.Plot; +import com.plotsquared.core.util.MainUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +class SearchPlotProvider implements PlotProvider { + + private final String searchTerm; + + SearchPlotProvider(@NotNull final String searchTerm) { + this.searchTerm = searchTerm; + } + + @Override public Collection getPlots() { + return MainUtil.getPlotsBySearch(this.searchTerm); + } + +} diff --git a/Core/src/main/java/com/plotsquared/core/util/query/SortingStrategy.java b/Core/src/main/java/com/plotsquared/core/util/query/SortingStrategy.java new file mode 100644 index 000000000..2e6351dcc --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/util/query/SortingStrategy.java @@ -0,0 +1,52 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.core.util.query; + +/** + * Strategy used when sorting plot results + */ +public enum SortingStrategy { + /** + * Plots won't be sorted at all + */ + NO_SORTING, + /** + * Sort by the temporary (magic) plot ID + */ + SORT_BY_TEMP, + /** + * Sort by the value in the plot's {@link com.plotsquared.core.plot.flag.implementations.DoneFlag} + */ + SORT_BY_DONE, + /** + * Sort by the plot rating + */ + SORT_BY_RATING, + /** + * Sort by creation date + */ + SORT_BY_CREATION +} From 6b31743fb30462fa7ffc8cd2f1209d01fc05e7b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sun, 24 May 2020 00:02:08 +0200 Subject: [PATCH 25/39] add missing javadoc --- .../java/com/plotsquared/core/util/query/PlotQuery.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java b/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java index 612c4c21c..379702e12 100644 --- a/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java +++ b/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java @@ -228,6 +228,13 @@ public final class PlotQuery { return this; } + /** + * Defines the area around which plots may be sorted, depending on the + * sorting strategy + * + * @param plotArea Plot area + * @return The query instance + */ @NotNull public PlotQuery relativeToArea(@NotNull final PlotArea plotArea) { Preconditions.checkNotNull(plotArea, "Area may not be null"); this.priorityArea = plotArea; From 1aa144e47deb7fab83ce63f0c0fc61077e0a5898 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sun, 24 May 2020 00:05:55 +0200 Subject: [PATCH 26/39] Deprecate old PlotFilter class --- Core/src/main/java/com/plotsquared/core/PlotSquared.java | 3 ++- .../src/main/java/com/plotsquared/core/plot/PlotFilter.java | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Core/src/main/java/com/plotsquared/core/PlotSquared.java b/Core/src/main/java/com/plotsquared/core/PlotSquared.java index e83cc56ba..bf0ef762b 100644 --- a/Core/src/main/java/com/plotsquared/core/PlotSquared.java +++ b/Core/src/main/java/com/plotsquared/core/PlotSquared.java @@ -895,8 +895,9 @@ public class PlotSquared { * * @param filters the filter * @return a filtered set of plots + * @deprecated Use {@link PlotQuery} */ - public Set getPlots(final PlotFilter... filters) { + @Deprecated public Set getPlots(final PlotFilter... filters) { final List areas = new LinkedList<>(); for (final PlotArea plotArea : this.getPlotAreas()) { for (final PlotFilter filter : filters) { diff --git a/Core/src/main/java/com/plotsquared/core/plot/PlotFilter.java b/Core/src/main/java/com/plotsquared/core/plot/PlotFilter.java index f7433a2ae..9319c048e 100644 --- a/Core/src/main/java/com/plotsquared/core/plot/PlotFilter.java +++ b/Core/src/main/java/com/plotsquared/core/plot/PlotFilter.java @@ -25,7 +25,10 @@ */ package com.plotsquared.core.plot; -public abstract class PlotFilter { +/** + * Use {@link com.plotsquared.core.util.query.PlotQuery} instead + */ +@Deprecated public abstract class PlotFilter { public boolean allowsArea(final PlotArea area) { return true; } @@ -33,4 +36,5 @@ public abstract class PlotFilter { public boolean allowsPlot(final Plot plot) { return true; } + } From a0d1da32742ddb73b7889abe487931e487fba9af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sun, 24 May 2020 00:08:52 +0200 Subject: [PATCH 27/39] fix dum typo --- .../{ExploredPlotProvider.java => ExpiredPlotProvider.java} | 2 +- .../main/java/com/plotsquared/core/util/query/PlotQuery.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename Core/src/main/java/com/plotsquared/core/util/query/{ExploredPlotProvider.java => ExpiredPlotProvider.java} (96%) diff --git a/Core/src/main/java/com/plotsquared/core/util/query/ExploredPlotProvider.java b/Core/src/main/java/com/plotsquared/core/util/query/ExpiredPlotProvider.java similarity index 96% rename from Core/src/main/java/com/plotsquared/core/util/query/ExploredPlotProvider.java rename to Core/src/main/java/com/plotsquared/core/util/query/ExpiredPlotProvider.java index 94bf9b92e..9b369dc4e 100644 --- a/Core/src/main/java/com/plotsquared/core/util/query/ExploredPlotProvider.java +++ b/Core/src/main/java/com/plotsquared/core/util/query/ExpiredPlotProvider.java @@ -30,7 +30,7 @@ import com.plotsquared.core.plot.expiration.ExpireManager; import java.util.Collection; -class ExploredPlotProvider implements PlotProvider { +class ExpiredPlotProvider implements PlotProvider { @Override public Collection getPlots() { return ExpireManager.IMP.getPendingExpired(); diff --git a/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java b/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java index 379702e12..208fac5d7 100644 --- a/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java +++ b/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java @@ -116,7 +116,7 @@ public final class PlotQuery { * @return The query instance */ @NotNull public PlotQuery expiredPlots() { - this.plotProvider = new ExploredPlotProvider(); + this.plotProvider = new ExpiredPlotProvider(); return this; } From 76913d4a78d581067ec2db93d5b27c1484f6bc68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sun, 24 May 2020 00:14:33 +0200 Subject: [PATCH 28/39] immutable -> mutable --- .../main/java/com/plotsquared/core/util/query/PlotQuery.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java b/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java index 208fac5d7..67abfd1fa 100644 --- a/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java +++ b/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java @@ -253,7 +253,7 @@ public final class PlotQuery { /** * Get all plots that match the given criteria * - * @return Matching plots as an immutable list + * @return Matching plots as a mutable */ @NotNull public List asList() { final List result; @@ -320,7 +320,7 @@ public final class PlotQuery { /** * Get all plots that match the given criteria * - * @return Matching plots as an immutable set + * @return Matching plots as a mutable set */ @NotNull public Set asSet() { return new HashSet<>(this.asList()); From 0ac6383c2cf3bc6fe687f70a35876e209db0608d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sun, 24 May 2020 00:27:38 +0200 Subject: [PATCH 29/39] Use PlotQuery in Visit --- .../com/plotsquared/core/command/Visit.java | 41 +++++++++++------ .../core/util/query/FixedPlotProvider.java | 46 +++++++++++++++++++ .../core/util/query/PlotQuery.java | 28 +++++++++++ .../core/util/query/SortingStrategy.java | 6 ++- 4 files changed, 105 insertions(+), 16 deletions(-) create mode 100644 Core/src/main/java/com/plotsquared/core/util/query/FixedPlotProvider.java diff --git a/Core/src/main/java/com/plotsquared/core/command/Visit.java b/Core/src/main/java/com/plotsquared/core/command/Visit.java index 372130a2d..442c40aeb 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Visit.java +++ b/Core/src/main/java/com/plotsquared/core/command/Visit.java @@ -36,13 +36,13 @@ import com.plotsquared.core.plot.flag.implementations.UntrustedVisitFlag; import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MathMan; import com.plotsquared.core.util.Permissions; +import com.plotsquared.core.util.query.PlotQuery; +import com.plotsquared.core.util.query.SortingStrategy; import com.plotsquared.core.util.task.RunnableVal2; import com.plotsquared.core.util.task.RunnableVal3; import com.plotsquared.core.util.uuid.UUIDHandler; -import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -72,9 +72,11 @@ public class Visit extends Command { args = args[0].split(":"); } int page = Integer.MIN_VALUE; - Collection unsorted = null; PlotArea sortByArea = player.getApplicablePlotArea(); boolean shouldSortByArea = Settings.Teleport.PER_WORLD_VISIT; + + final PlotQuery query = PlotQuery.newQuery(); + switch (args.length) { case 3: if (!MathMan.isInteger(args[1])) { @@ -96,7 +98,7 @@ public class Visit extends Command { Captions.COMMAND_SYNTAX.send(player, getUsage()); return CompletableFuture.completedFuture(false); } - unsorted = PlotSquared.get().getBasePlots(user); + query.ownedBy(user).whereBasePlot(); shouldSortByArea = true; break; } @@ -108,21 +110,21 @@ public class Visit extends Command { } if (page == Integer.MIN_VALUE && user == null && MathMan.isInteger(args[0])) { page = Integer.parseInt(args[0]); - unsorted = PlotSquared.get().getBasePlots(player); + query.ownedBy(player).whereBasePlot(); break; } if (user != null) { - unsorted = PlotSquared.get().getBasePlots(user); + query.ownedBy(player).whereBasePlot(); } else { Plot plot = MainUtil.getPlotFromString(player, args[0], true); if (plot != null) { - unsorted = Collections.singletonList(plot.getBasePlot(false)); + query.withPlot(plot); } } break; case 0: page = 1; - unsorted = PlotSquared.get().getPlots(player); + query.ownedBy(player); break; default: @@ -130,25 +132,33 @@ public class Visit extends Command { if (page == Integer.MIN_VALUE) { page = 1; } - if (unsorted == null || unsorted.isEmpty()) { + + // We get the query once, + // then we get it another time further on + final List unsorted = query.asList(); + + if (unsorted.isEmpty()) { Captions.FOUND_NO_PLOTS.send(player); return CompletableFuture.completedFuture(false); } - unsorted = new ArrayList<>(unsorted); + if (unsorted.size() > 1) { - unsorted.removeIf(plot -> !plot.isBasePlot()); + query.whereBasePlot(); } + if (page < 1 || page > unsorted.size()) { Captions.NOT_VALID_NUMBER.send(player, "(1, " + unsorted.size() + ")"); return CompletableFuture.completedFuture(false); } - List plots; + if (shouldSortByArea) { - plots = PlotSquared.get() - .sortPlots(unsorted, PlotSquared.SortType.CREATION_DATE, sortByArea); + query.relativeToArea(sortByArea).withSortingStrategy(SortingStrategy.SORT_BY_CREATION); } else { - plots = PlotSquared.get().sortPlotsByTemp(unsorted); + query.withSortingStrategy(SortingStrategy.SORT_BY_TEMP); } + + final List plots = query.asList(); + final Plot plot = plots.get(page - 1); if (!plot.hasOwner()) { if (!Permissions.hasPermission(player, Captions.PERMISSION_VISIT_UNOWNED)) { @@ -177,6 +187,7 @@ public class Visit extends Command { return CompletableFuture.completedFuture(false); } } + confirm.run(this, () -> plot.teleportPlayer(player, TeleportCause.COMMAND, result -> { if (result) { whenDone.run(Visit.this, CommandResult.SUCCESS); diff --git a/Core/src/main/java/com/plotsquared/core/util/query/FixedPlotProvider.java b/Core/src/main/java/com/plotsquared/core/util/query/FixedPlotProvider.java new file mode 100644 index 000000000..3bf79c783 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/util/query/FixedPlotProvider.java @@ -0,0 +1,46 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.core.util.query; + +import com.plotsquared.core.plot.Plot; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.Collections; + +class FixedPlotProvider implements PlotProvider { + + private final Plot plot; + + FixedPlotProvider(@NotNull final Plot plot) { + this.plot = plot; + } + + @Override public Collection getPlots() { + return Collections.singleton(plot); + } + +} diff --git a/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java b/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java index 67abfd1fa..6c90e969f 100644 --- a/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java +++ b/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java @@ -38,6 +38,7 @@ import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.HashSet; import java.util.LinkedList; import java.util.List; @@ -60,6 +61,7 @@ public final class PlotQuery { private PlotProvider plotProvider = new GlobalPlotProvider(); private SortingStrategy sortingStrategy = SortingStrategy.NO_SORTING; private PlotArea priorityArea; + private Comparator plotComparator; private PlotQuery() { } @@ -151,6 +153,17 @@ public final class PlotQuery { return this; } + /** + * Query with a pre-defined result + * + * @return The query instance + */ + @NotNull public PlotQuery withPlot(@NotNull final Plot plot) { + Preconditions.checkNotNull(plot, "Plot may not be null"); + this.plotProvider = new FixedPlotProvider(plot); + return this; + } + /** * Query for base plots only * @@ -228,6 +241,19 @@ public final class PlotQuery { return this; } + /** + * Use a custom comparator to sort the results + * + * @param comparator Comparator + * @return The query instance + */ + @NotNull public PlotQuery sorted(@NotNull final Comparator comparator) { + Preconditions.checkNotNull(comparator, "Comparator may not be null"); + this.sortingStrategy = SortingStrategy.COMPARATOR; + this.plotComparator = comparator; + return this; + } + /** * Defines the area around which plots may be sorted, depending on the * sorting strategy @@ -313,6 +339,8 @@ public final class PlotQuery { }); } else if (this.sortingStrategy == SortingStrategy.SORT_BY_CREATION) { return PlotSquared.get().sortPlots(result, PlotSquared.SortType.CREATION_DATE, this.priorityArea); + } else if (this.sortingStrategy == SortingStrategy.COMPARATOR) { + result.sort(this.plotComparator); } return result; } diff --git a/Core/src/main/java/com/plotsquared/core/util/query/SortingStrategy.java b/Core/src/main/java/com/plotsquared/core/util/query/SortingStrategy.java index 2e6351dcc..7a70b46fd 100644 --- a/Core/src/main/java/com/plotsquared/core/util/query/SortingStrategy.java +++ b/Core/src/main/java/com/plotsquared/core/util/query/SortingStrategy.java @@ -48,5 +48,9 @@ public enum SortingStrategy { /** * Sort by creation date */ - SORT_BY_CREATION + SORT_BY_CREATION, + /** + * Sort using a comparator + */ + COMPARATOR; } From 0b12c4e5b25e42d2e65bd332ab051e53905fb291 Mon Sep 17 00:00:00 2001 From: NotMyFault Date: Sun, 24 May 2020 18:48:15 +0200 Subject: [PATCH 30/39] Update issue link --- Core/src/main/java/com/plotsquared/core/command/DebugPaste.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/main/java/com/plotsquared/core/command/DebugPaste.java b/Core/src/main/java/com/plotsquared/core/command/DebugPaste.java index c5c42a4c2..ea223c60a 100644 --- a/Core/src/main/java/com/plotsquared/core/command/DebugPaste.java +++ b/Core/src/main/java/com/plotsquared/core/command/DebugPaste.java @@ -122,7 +122,7 @@ public class DebugPaste extends SubCommand { b.append("OS Arch: ").append(System.getProperty("os.arch")).append('\n'); b.append("# Okay :D Great. You are now ready to create your bug report!"); b.append( - "\n# You can do so at https://github.com/IntellectualSites/PlotSquared/issues"); + "\n# You can do so at https://issues.intellectualsites.com/projects/ps"); b.append("\n# or via our Discord at https://discord.gg/KxkjDVg"); final IncendoPaster incendoPaster = new IncendoPaster("plotsquared"); From 172bd6f0f2be60c9abb4a5e3e69aa9fc41a3381a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sun, 24 May 2020 19:05:09 +0200 Subject: [PATCH 31/39] This should hopefully fix that broken merge. Maybe. Possibly. Idk. --- .../com/plotsquared/core/command/ListCmd.java | 44 ++++--------------- .../com/plotsquared/core/command/Visit.java | 13 +++--- 2 files changed, 14 insertions(+), 43 deletions(-) diff --git a/Core/src/main/java/com/plotsquared/core/command/ListCmd.java b/Core/src/main/java/com/plotsquared/core/command/ListCmd.java index dfd582f0f..489208adf 100644 --- a/Core/src/main/java/com/plotsquared/core/command/ListCmd.java +++ b/Core/src/main/java/com/plotsquared/core/command/ListCmd.java @@ -49,7 +49,6 @@ import com.plotsquared.core.uuid.UUIDMapping; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.List; import java.util.UUID; import java.util.concurrent.ExecutionException; @@ -139,20 +138,19 @@ public class ListCmd extends SubCommand { String arg = args[0].toLowerCase(); final boolean[] sort = new boolean[] {true}; - final Consumer plotConsumer = plots -> { + final Consumer plotConsumer = query -> { if (query == null) { sendMessage(player, Captions.DID_YOU_MEAN, new StringComparison<>(args[0], new String[] {"mine", "shared", "world", "all"}) .getBestMatch()); - return false; + return; } - if (area != null) { query.relativeToArea(area); } - if (sort) { + if (sort[0]) { query.withSortingStrategy(SortingStrategy.SORT_BY_CREATION); } @@ -160,7 +158,7 @@ public class ListCmd extends SubCommand { if (plots.isEmpty()) { MainUtil.sendMessage(player, Captions.FOUND_NO_PLOTS); - return false; + return; } displayPlots(player, plots, 12, page, args); }; @@ -198,7 +196,6 @@ public class ListCmd extends SubCommand { } plotConsumer.accept(PlotQuery.newQuery().inWorld(world)); break; - plotConsumer.accept(PlotSquared.get().getPlots(world)); case "expired": if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_EXPIRED)) { MainUtil.sendMessage(player, Captions.NO_PERMISSION, @@ -211,9 +208,6 @@ public class ListCmd extends SubCommand { plotConsumer.accept(PlotQuery.newQuery().expiredPlots()); } break; - plotConsumer.accept(ExpireManager.IMP == null ? - new ArrayList<>() : - new ArrayList<>(ExpireManager.IMP.getPendingExpired())); case "area": if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_AREA)) { MainUtil @@ -239,7 +233,7 @@ public class ListCmd extends SubCommand { .sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_LIST_ALL); return false; } - plotConsumer.accept(PlotQuery().newQuery().allPlots()); + plotConsumer.accept(PlotQuery.newQuery().allPlots()); break; case "done": if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_DONE)) { @@ -248,7 +242,7 @@ public class ListCmd extends SubCommand { return false; } sort[0] = false; - plotConsumer.accept(PlotQuery.newQuery().allPlots().thatPasses(DoneFlag::isDone).withSortingStrategy(SortingStrategy.SORT_BY_DONE)) + plotConsumer.accept(PlotQuery.newQuery().allPlots().thatPasses(DoneFlag::isDone).withSortingStrategy(SortingStrategy.SORT_BY_DONE)); break; case "top": if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_TOP)) { @@ -257,7 +251,7 @@ public class ListCmd extends SubCommand { return false; } sort[0] = false; - plotConsumer.accept(PlotQuery.newQuery().allPlots().withSortingStrategy(SortingStrategy.SORT_BY_RATING)) + plotConsumer.accept(PlotQuery.newQuery().allPlots().withSortingStrategy(SortingStrategy.SORT_BY_RATING)); break; case "forsale": if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_FOR_SALE)) { @@ -337,36 +331,16 @@ public class ListCmd extends SubCommand { Captions.PERMISSION_LIST_PLAYER); } else { sort[0] = false; - plotConsumer.accept(PlotSquared.get() - .sortPlotsByTemp(PlotSquared.get().getPlots(uuid))); + plotConsumer.accept(PlotQuery.newQuery().ownedBy(uuid).withSortingStrategy(SortingStrategy.SORT_BY_TEMP)); } } }); - - - UUID uuid = UUIDHandler.getUUID(args[0], null); - if (uuid == null) { - try { - uuid = UUID.fromString(args[0]); - } catch (Exception ignored) { - } - } - if (uuid != null) { - if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_PLAYER)) { - MainUtil.sendMessage(player, Captions.NO_PERMISSION, - Captions.PERMISSION_LIST_PLAYER); - return false; - } - sort[0] = false; - plotConsumer.accept(PlotQuery.newQuery().ownedBy(uuid).withSortingStrategy(SortingStrategy.SORT_BY_TEMP)); - break; - } } return true; } - public void displayPlots(final PlotPlayer player, List plots, int pageSize, int page, String[] args { + public void displayPlots(final PlotPlayer player, List plots, int pageSize, int page, String[] args) { // Header plots.removeIf(plot -> !plot.isBasePlot()); this.paginate(player, plots, pageSize, page, diff --git a/Core/src/main/java/com/plotsquared/core/command/Visit.java b/Core/src/main/java/com/plotsquared/core/command/Visit.java index cd541c33e..3a18fc7d9 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Visit.java +++ b/Core/src/main/java/com/plotsquared/core/command/Visit.java @@ -41,10 +41,7 @@ import com.plotsquared.core.util.query.SortingStrategy; import com.plotsquared.core.util.task.RunnableVal2; import com.plotsquared.core.util.task.RunnableVal3; -import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -79,7 +76,7 @@ public class Visit extends Command { final PlotQuery query = PlotQuery.newQuery(); final PlotArea[] sortByArea = new PlotArea[] {player.getApplicablePlotArea()}; - final Atomicboolean shouldSortByArea = new AtomicBoolean(Settings.Teleport.PER_WORLD_VISIT); + final AtomicBoolean shouldSortByArea = new AtomicBoolean(Settings.Teleport.PER_WORLD_VISIT); final Consumer pageConsumer = page -> { // We get the query once, @@ -88,7 +85,7 @@ public class Visit extends Command { if (unsorted.isEmpty()) { Captions.FOUND_NO_PLOTS.send(player); - return CompletableFuture.completedFuture(false); + return; } if (unsorted.size() > 1) { @@ -97,11 +94,11 @@ public class Visit extends Command { if (page < 1 || page > unsorted.size()) { Captions.NOT_VALID_NUMBER.send(player, "(1, " + unsorted.size() + ")"); - return CompletableFuture.completedFuture(false); + return; } if (shouldSortByArea.get()) { - query.relativeToArea(sortByArea).withSortingStrategy(SortingStrategy.SORT_BY_CREATION); + query.relativeToArea(sortByArea[0]).withSortingStrategy(SortingStrategy.SORT_BY_CREATION); } else { query.withSortingStrategy(SortingStrategy.SORT_BY_TEMP); } @@ -171,7 +168,7 @@ public class Visit extends Command { } else if (throwable != null || uuids.size() != 1) { Captions.COMMAND_SYNTAX.send(player, getUsage()); } else { - query.ownedBy(user).whereBasePlot(); + query.ownedBy(uuids.toArray(new UUID[0])[0]).whereBasePlot(); shouldSortByArea.set(true); pageConsumer.accept(page[0]); } From 69cfb431b145a26ba2aea50cbf87a0d966e4d6e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sun, 24 May 2020 20:18:02 +0200 Subject: [PATCH 32/39] Unstupidify Visit --- .../com/plotsquared/core/command/Visit.java | 248 ++++++++++-------- .../core/configuration/Captions.java | 1 + .../core/util/query/PlotQuery.java | 7 +- 3 files changed, 149 insertions(+), 107 deletions(-) diff --git a/Core/src/main/java/com/plotsquared/core/command/Visit.java b/Core/src/main/java/com/plotsquared/core/command/Visit.java index 3a18fc7d9..3c1ed70c3 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Visit.java +++ b/Core/src/main/java/com/plotsquared/core/command/Visit.java @@ -27,7 +27,6 @@ package com.plotsquared.core.command; import com.plotsquared.core.PlotSquared; import com.plotsquared.core.configuration.Captions; -import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.events.TeleportCause; import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.plot.Plot; @@ -40,14 +39,13 @@ import com.plotsquared.core.util.query.PlotQuery; import com.plotsquared.core.util.query.SortingStrategy; import com.plotsquared.core.util.task.RunnableVal2; import com.plotsquared.core.util.task.RunnableVal3; +import org.jetbrains.annotations.NotNull; import java.util.Collection; import java.util.List; import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Consumer; @CommandDeclaration(command = "visit", permission = "plots.visit", @@ -66,152 +64,194 @@ public class Visit extends Command { return tabOf(player, args, space, getUsage()); } + private void visit(@NotNull final PlotPlayer player, @NotNull final PlotQuery query, final PlotArea sortByArea, + final RunnableVal3 confirm, final RunnableVal2 whenDone) { + this.visit(player, query, sortByArea, confirm, whenDone, 1); + } + + private void visit(@NotNull final PlotPlayer player, @NotNull final PlotQuery query, final PlotArea sortByArea, + final RunnableVal3 confirm, final RunnableVal2 whenDone, int page) { + // We get the query once, + // then we get it another time further on + final List unsorted = query.asList(); + + if (unsorted.isEmpty()) { + Captions.FOUND_NO_PLOTS.send(player); + return; + } + + if (unsorted.size() > 1) { + query.whereBasePlot(); + } + + if (page == Integer.MIN_VALUE) { + page = 1; + } + + if (page < 1 || page > unsorted.size()) { + MainUtil.sendMessage(player, String.format("(1, %d)", unsorted.size())); + return; + } + + if (sortByArea != null) { + query.relativeToArea(sortByArea).withSortingStrategy(SortingStrategy.SORT_BY_CREATION); + } else { + query.withSortingStrategy(SortingStrategy.SORT_BY_TEMP); + } + + final List plots = query.asList(); + + final Plot plot = plots.get(page - 1); + if (!plot.hasOwner()) { + if (!Permissions.hasPermission(player, Captions.PERMISSION_VISIT_UNOWNED)) { + Captions.NO_PERMISSION.send(player, Captions.PERMISSION_VISIT_UNOWNED); + return; + } + } else if (plot.isOwner(player.getUUID())) { + if (!Permissions.hasPermission(player, Captions.PERMISSION_VISIT_OWNED) && !Permissions + .hasPermission(player, Captions.PERMISSION_HOME)) { + Captions.NO_PERMISSION.send(player, Captions.PERMISSION_VISIT_OWNED); + return; + } + } else if (plot.isAdded(player.getUUID())) { + if (!Permissions.hasPermission(player, Captions.PERMISSION_SHARED)) { + Captions.NO_PERMISSION.send(player, Captions.PERMISSION_SHARED); + return; + } + } else { + if (!Permissions.hasPermission(player, Captions.PERMISSION_VISIT_OTHER)) { + Captions.NO_PERMISSION.send(player, Captions.PERMISSION_VISIT_OTHER); + return; + } + if (!plot.getFlag(UntrustedVisitFlag.class) && !Permissions + .hasPermission(player, Captions.PERMISSION_ADMIN_VISIT_UNTRUSTED)) { + Captions.NO_PERMISSION.send(player, Captions.PERMISSION_ADMIN_VISIT_UNTRUSTED); + return; + } + } + + confirm.run(this, () -> plot.teleportPlayer(player, TeleportCause.COMMAND, result -> { + if (result) { + whenDone.run(Visit.this, CommandResult.SUCCESS); + } else { + whenDone.run(Visit.this, CommandResult.FAILURE); + } + }), () -> whenDone.run(Visit.this, CommandResult.FAILURE)); + } + @Override - public CompletableFuture execute(final PlotPlayer player, String[] args, - RunnableVal3 confirm, + public CompletableFuture execute(final PlotPlayer player, + String[] args, + final RunnableVal3 confirm, final RunnableVal2 whenDone) throws CommandException { if (args.length == 1 && args[0].contains(":")) { args = args[0].split(":"); } - final PlotQuery query = PlotQuery.newQuery(); - final PlotArea[] sortByArea = new PlotArea[] {player.getApplicablePlotArea()}; - final AtomicBoolean shouldSortByArea = new AtomicBoolean(Settings.Teleport.PER_WORLD_VISIT); + PlotArea sortByArea; - final Consumer pageConsumer = page -> { - // We get the query once, - // then we get it another time further on - final List unsorted = query.asList(); - - if (unsorted.isEmpty()) { - Captions.FOUND_NO_PLOTS.send(player); - return; - } - - if (unsorted.size() > 1) { - query.whereBasePlot(); - } - - if (page < 1 || page > unsorted.size()) { - Captions.NOT_VALID_NUMBER.send(player, "(1, " + unsorted.size() + ")"); - return; - } - - if (shouldSortByArea.get()) { - query.relativeToArea(sortByArea[0]).withSortingStrategy(SortingStrategy.SORT_BY_CREATION); - } else { - query.withSortingStrategy(SortingStrategy.SORT_BY_TEMP); - } - - final List plots = query.asList(); - - final Plot plot = plots.get(page - 1); - if (!plot.hasOwner()) { - if (!Permissions.hasPermission(player, Captions.PERMISSION_VISIT_UNOWNED)) { - Captions.NO_PERMISSION.send(player, Captions.PERMISSION_VISIT_UNOWNED); - return; - } - } else if (plot.isOwner(player.getUUID())) { - if (!Permissions.hasPermission(player, Captions.PERMISSION_VISIT_OWNED) && !Permissions - .hasPermission(player, Captions.PERMISSION_HOME)) { - Captions.NO_PERMISSION.send(player, Captions.PERMISSION_VISIT_OWNED); - return; - } - } else if (plot.isAdded(player.getUUID())) { - if (!Permissions.hasPermission(player, Captions.PERMISSION_SHARED)) { - Captions.NO_PERMISSION.send(player, Captions.PERMISSION_SHARED); - return; - } - } else { - if (!Permissions.hasPermission(player, Captions.PERMISSION_VISIT_OTHER)) { - Captions.NO_PERMISSION.send(player, Captions.PERMISSION_VISIT_OTHER); - return; - } - if (!plot.getFlag(UntrustedVisitFlag.class) && !Permissions - .hasPermission(player, Captions.PERMISSION_ADMIN_VISIT_UNTRUSTED)) { - Captions.NO_PERMISSION.send(player, Captions.PERMISSION_ADMIN_VISIT_UNTRUSTED); - return; - } - } - - confirm.run(this, () -> plot.teleportPlayer(player, TeleportCause.COMMAND, result -> { - if (result) { - whenDone.run(Visit.this, CommandResult.SUCCESS); - } else { - whenDone.run(Visit.this, CommandResult.FAILURE); - } - }), () -> whenDone.run(Visit.this, CommandResult.FAILURE)); - }; - - final int[] page = new int[]{Integer.MIN_VALUE}; + int page = Integer.MIN_VALUE; switch (args.length) { + // /p v [...] [...] case 3: if (!MathMan.isInteger(args[1])) { Captions.NOT_VALID_NUMBER.send(player, "(1, ∞)"); Captions.COMMAND_SYNTAX.send(player, getUsage()); return CompletableFuture.completedFuture(false); } - page[0] = Integer.parseInt(args[2]); + page = Integer.parseInt(args[2]); + // /p v [page] + // /p v [page] case 2: - if (page[0] != Integer.MIN_VALUE || !MathMan.isInteger(args[1])) { - sortByArea[0] = PlotSquared.get().getPlotAreaByString(args[1]); - if (sortByArea[0] == null) { + if (page != Integer.MIN_VALUE || !MathMan.isInteger(args[1])) { + sortByArea = PlotSquared.get().getPlotAreaByString(args[1]); + if (sortByArea == null) { Captions.NOT_VALID_NUMBER.send(player, "(1, ∞)"); Captions.COMMAND_SYNTAX.send(player, getUsage()); return CompletableFuture.completedFuture(false); } + final PlotArea finalSortByArea = sortByArea; + int finalPage1 = page; MainUtil.getUUIDsFromString(args[0], (uuids, throwable) -> { if (throwable instanceof TimeoutException) { Captions.FETCHING_PLAYERS_TIMEOUT.send(player); } else if (throwable != null || uuids.size() != 1) { Captions.COMMAND_SYNTAX.send(player, getUsage()); } else { - query.ownedBy(uuids.toArray(new UUID[0])[0]).whereBasePlot(); - shouldSortByArea.set(true); - pageConsumer.accept(page[0]); + final UUID uuid = uuids.toArray(new UUID[0])[0]; + this.visit(player, PlotQuery.newQuery().ownedBy(uuid).whereBasePlot(), finalSortByArea, confirm, whenDone, finalPage1); } }); break; } - page[0] = Integer.parseInt(args[1]); + page = Integer.parseInt(args[1]); + // /p v [page] + // /p v [page] + // /p v [page] + // /p v [page] case 1: final String[] finalArgs = args; - final Consumer uuidConsumer = uuid -> { - if (page[0] == Integer.MIN_VALUE && uuid == null && MathMan.isInteger(finalArgs[0])) { - page[0] = Integer.parseInt(finalArgs[0]); - query.ownedBy(player).whereBasePlot(); - } else { - if (uuid != null) { - query.ownedBy(player).whereBasePlot(); - } else { - Plot plot = MainUtil.getPlotFromString(player, finalArgs[0], true); - if (plot != null) { - query.withPlot(plot); - } - } - } - pageConsumer.accept(page[0]); - }; - + int finalPage = page; if (args[0].length() >= 2) { PlotSquared.get().getImpromptuUUIDPipeline().getSingle(args[0], (uuid, throwable) -> { if (throwable instanceof TimeoutException) { + // The request timed out MainUtil.sendMessage(player, Captions.FETCHING_PLAYERS_TIMEOUT); } else if (uuid != null && !PlotSquared.get().hasPlot(uuid)) { - uuidConsumer.accept(null); + // It was a valid UUID but the player has no plots + MainUtil.sendMessage(player, Captions.PLAYER_NO_PLOTS); + } else if (uuid == null) { + if (finalPage == Integer.MIN_VALUE && MathMan.isInteger(finalArgs[0])) { + // The argument was a number, so we assume it's the page number + int parsedPage; + try { + parsedPage = Integer.parseInt(finalArgs[0]); + } catch (final Throwable t) { + MainUtil.sendMessage(player, Captions.NOT_A_NUMBER, finalArgs[0]); + return; + } + this.visit(player, PlotQuery.newQuery().ownedBy(player).whereBasePlot(), null, + confirm, whenDone, parsedPage); + } else { + // Try to parse a plot + final Plot plot = MainUtil.getPlotFromString(player, finalArgs[0], true); + if (plot == null) { + MainUtil.sendMessage(player, Captions.NOT_VALID_PLOT_ID); + return; + } + this.visit(player, PlotQuery.newQuery().withPlot(plot), null, confirm, whenDone, 1); + } } else { - uuidConsumer.accept(uuid); + this.visit(player, PlotQuery.newQuery().ownedBy(uuid).whereBasePlot(), null, confirm, whenDone, finalPage); } }); } else { - uuidConsumer.accept(null); + if (finalPage == Integer.MIN_VALUE && MathMan.isInteger(finalArgs[0])) { + // The argument was a number, so we assume it's the page number + int parsedPage; + try { + parsedPage = Integer.parseInt(finalArgs[0]); + this.visit(player, PlotQuery.newQuery().ownedBy(player).whereBasePlot(), null, confirm, + whenDone, parsedPage); + } catch (final Throwable throwable) { + MainUtil.sendMessage(player, Captions.NOT_A_NUMBER, finalArgs[0]); + } + } else { + // Try to parse a plot + final Plot plot = MainUtil.getPlotFromString(player, finalArgs[0], true); + if (plot == null) { + MainUtil.sendMessage(player, Captions.NOT_VALID_PLOT_ID); + } else { + this.visit(player, PlotQuery.newQuery().withPlot(plot), null, confirm, whenDone, 1); + } + } } break; case 0: - query.ownedBy(player); - pageConsumer.accept(1); + // /p v + this.visit(player, PlotQuery.newQuery().ownedBy(player), null, confirm, whenDone); break; default: } diff --git a/Core/src/main/java/com/plotsquared/core/configuration/Captions.java b/Core/src/main/java/com/plotsquared/core/configuration/Captions.java index 98cb8b9ce..eb5f6f444 100644 --- a/Core/src/main/java/com/plotsquared/core/configuration/Captions.java +++ b/Core/src/main/java/com/plotsquared/core/configuration/Captions.java @@ -445,6 +445,7 @@ public enum Captions implements Caption { NOT_VALID_WORLD("$2That is not a valid world (case sensitive)", "Errors"), NOT_VALID_PLOT_WORLD("$2That is not a valid plot area (case sensitive)", "Errors"), NO_PLOTS("$2You don't have any plots", "Errors"), + PLAYER_NO_PLOTS("$2That player does not own any plots", "Errors"), WAIT_FOR_TIMER("$2A set block timer is bound to either the current plot or you. Please wait for it to finish", "Errors"), TILE_ENTITY_CAP_REACHED("$2The total number of tile entities in this chunk may not exceed $1%s", "Errors"), // diff --git a/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java b/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java index 6c90e969f..40d883062 100644 --- a/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java +++ b/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java @@ -288,12 +288,13 @@ public final class PlotQuery { } else { final Collection plots = this.plotProvider.getPlots(); result = new ArrayList<>(plots.size()); - for (final Plot plot : plots) { + outer: for (final Plot plot : plots) { for (final PlotFilter filter : this.filters) { - if (filter.accepts(plot)) { - result.add(plot); + if (!filter.accepts(plot)) { + continue outer; } } + result.add(plot); } } if (this.sortingStrategy == SortingStrategy.NO_SORTING) { From 862467c0fa3eeab412ffa6220eade3c52c1973ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sun, 24 May 2020 20:53:16 +0200 Subject: [PATCH 33/39] Tab complete `/plot visit` --- .../com/plotsquared/core/command/Visit.java | 61 +++++++++++++++++-- 1 file changed, 56 insertions(+), 5 deletions(-) diff --git a/Core/src/main/java/com/plotsquared/core/command/Visit.java b/Core/src/main/java/com/plotsquared/core/command/Visit.java index 3c1ed70c3..2b64746c2 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Visit.java +++ b/Core/src/main/java/com/plotsquared/core/command/Visit.java @@ -35,6 +35,7 @@ import com.plotsquared.core.plot.flag.implementations.UntrustedVisitFlag; import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MathMan; import com.plotsquared.core.util.Permissions; +import com.plotsquared.core.util.TabCompletions; import com.plotsquared.core.util.query.PlotQuery; import com.plotsquared.core.util.query.SortingStrategy; import com.plotsquared.core.util.task.RunnableVal2; @@ -42,6 +43,8 @@ import com.plotsquared.core.util.task.RunnableVal3; import org.jetbrains.annotations.NotNull; import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; import java.util.List; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -60,10 +63,6 @@ public class Visit extends Command { super(MainCommand.getInstance(), true); } - @Override public Collection tab(PlotPlayer player, String[] args, boolean space) { - return tabOf(player, args, space, getUsage()); - } - private void visit(@NotNull final PlotPlayer player, @NotNull final PlotQuery query, final PlotArea sortByArea, final RunnableVal3 confirm, final RunnableVal2 whenDone) { this.visit(player, query, sortByArea, confirm, whenDone, 1); @@ -194,7 +193,7 @@ public class Visit extends Command { case 1: final String[] finalArgs = args; int finalPage = page; - if (args[0].length() >= 2) { + if (args[0].length() >= 2 && !args[0].contains(";") && !args[0].contains(",")) { PlotSquared.get().getImpromptuUUIDPipeline().getSingle(args[0], (uuid, throwable) -> { if (throwable instanceof TimeoutException) { // The request timed out @@ -259,4 +258,56 @@ public class Visit extends Command { return CompletableFuture.completedFuture(true); } + public Collection tab(PlotPlayer player, String[] args, boolean space) { + final List completions = new LinkedList<>(); + player.sendMessage("u haef " + args.length + " args and they r "); + for (int i = 0; i < args.length; i++) { + player.sendMessage(i + ": " + args[i]); + } + + switch (args.length - 1) { + case 0: + this.completeNumbers(completions, args[0], 0); + completions.addAll(TabCompletions.completePlayers(args[0], Collections.emptyList())); + break; + case 1: + if (MathMan.isInteger(args[0])) { + break; + } + this.completeNumbers(completions, args[1], 0); + this.completeAreas(completions, args[1]); + break; + case 2: + if (MathMan.isInteger(args[1])) { + break; + } + this.completeNumbers(completions, args[2], 0); + break; + } + + return completions; + } + + private void completeNumbers(final List commands, final String arg, final int start) { + for (int i = 0; i < 10; i++) { + final String command = Integer.toString(start + 1); + if (!command.toLowerCase().startsWith(arg.toLowerCase())) { + continue; + } + commands.add(new Command(this, false, command, "", + RequiredType.NONE, CommandCategory.TELEPORT) {}); + } + } + + private void completeAreas(final List commands, final String arg) { + for (final PlotArea area : PlotSquared.get().getPlotAreas()) { + final String areaName = area.getWorldName() + ";" + area.getId(); + if (!areaName.toLowerCase().startsWith(arg.toLowerCase())) { + continue; + } + commands.add(new Command(this, false, area.getWorldName() + ";" + area.getId(), "", + RequiredType.NONE, CommandCategory.TELEPORT) {}); + } + } + } From 2436a6a402423581e268457b359f6c06bf7c52f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sun, 24 May 2020 20:54:10 +0200 Subject: [PATCH 34/39] remove debug, whoops --- Core/src/main/java/com/plotsquared/core/command/Visit.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Core/src/main/java/com/plotsquared/core/command/Visit.java b/Core/src/main/java/com/plotsquared/core/command/Visit.java index 2b64746c2..651a1c0b0 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Visit.java +++ b/Core/src/main/java/com/plotsquared/core/command/Visit.java @@ -260,11 +260,6 @@ public class Visit extends Command { public Collection tab(PlotPlayer player, String[] args, boolean space) { final List completions = new LinkedList<>(); - player.sendMessage("u haef " + args.length + " args and they r "); - for (int i = 0; i < args.length; i++) { - player.sendMessage(i + ": " + args[i]); - } - switch (args.length - 1) { case 0: this.completeNumbers(completions, args[0], 0); @@ -289,7 +284,7 @@ public class Visit extends Command { } private void completeNumbers(final List commands, final String arg, final int start) { - for (int i = 0; i < 10; i++) { + for (int i = 0; i < 100; i++) { final String command = Integer.toString(start + 1); if (!command.toLowerCase().startsWith(arg.toLowerCase())) { continue; From 46b68e489d9c90565c0caa877d14f748f3008a0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sun, 24 May 2020 21:08:11 +0200 Subject: [PATCH 35/39] Tab complete `/p list` --- .../bukkit/managers/BukkitWorldManager.java | 12 +++++ .../com/plotsquared/core/command/ListCmd.java | 49 +++++++++++++++++++ .../core/util/PlatformWorldManager.java | 9 ++++ 3 files changed, 70 insertions(+) diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/managers/BukkitWorldManager.java b/Bukkit/src/main/java/com/plotsquared/bukkit/managers/BukkitWorldManager.java index 482d02896..4646868a1 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/managers/BukkitWorldManager.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/managers/BukkitWorldManager.java @@ -36,6 +36,9 @@ import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; /** * Default Bukkit world manager. It will handle world creation by @@ -76,4 +79,13 @@ public class BukkitWorldManager implements PlatformWorldManager { return "bukkit"; } + @Override public Collection getWorlds() { + final List worlds = Bukkit.getWorlds(); + final List worldNames = new ArrayList<>(); + for (final World world : worlds) { + worldNames.add(world.getName()); + } + return worldNames; + } + } diff --git a/Core/src/main/java/com/plotsquared/core/command/ListCmd.java b/Core/src/main/java/com/plotsquared/core/command/ListCmd.java index 489208adf..0054df62e 100644 --- a/Core/src/main/java/com/plotsquared/core/command/ListCmd.java +++ b/Core/src/main/java/com/plotsquared/core/command/ListCmd.java @@ -42,6 +42,7 @@ import com.plotsquared.core.util.MathMan; import com.plotsquared.core.util.Permissions; import com.plotsquared.core.util.StringComparison; import com.plotsquared.core.util.StringMan; +import com.plotsquared.core.util.TabCompletions; import com.plotsquared.core.util.query.PlotQuery; import com.plotsquared.core.util.query.SortingStrategy; import com.plotsquared.core.util.task.RunnableVal3; @@ -49,12 +50,16 @@ import com.plotsquared.core.uuid.UUIDMapping; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; import java.util.List; import java.util.UUID; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.function.Consumer; +import java.util.stream.Collectors; @CommandDeclaration(command = "list", aliases = {"l", "find", "search"}, @@ -397,4 +402,48 @@ public class ListCmd extends SubCommand { }, "/plot list " + args[0], Captions.PLOT_LIST_HEADER_PAGED.getTranslated()); } + @Override public Collection tab(PlotPlayer player, String[] args, boolean space) { + final List completions = new LinkedList<>(); + if (EconHandler.manager != null && Permissions + .hasPermission(player, Captions.PERMISSION_LIST_FOR_SALE)) { + completions.add("forsale"); + } + if (Permissions.hasPermission(player, Captions.PERMISSION_LIST_MINE)) { + completions.add("mine"); + } + if (Permissions.hasPermission(player, Captions.PERMISSION_LIST_SHARED)) { + completions.add("shared"); + } + if (Permissions.hasPermission(player, Captions.PERMISSION_LIST_WORLD)) { + completions.addAll(PlotSquared.imp().getWorldManager().getWorlds()); + } + if (Permissions.hasPermission(player, Captions.PERMISSION_LIST_TOP)) { + completions.add("top"); + } + if (Permissions.hasPermission(player, Captions.PERMISSION_LIST_ALL)) { + completions.add("all"); + } + if (Permissions.hasPermission(player, Captions.PERMISSION_LIST_UNOWNED)) { + completions.add("unowned"); + } + if (Permissions.hasPermission(player, Captions.PERMISSION_LIST_DONE)) { + completions.add("done"); + } + if (Permissions.hasPermission(player, Captions.PERMISSION_LIST_EXPIRED)) { + completions.add("expired"); + } + + final List commands = new LinkedList<>(); + commands.addAll(completions.stream() + .filter(completion -> completion.toLowerCase().startsWith(args[0].toLowerCase())) + .map(completion -> new Command(null, true, completion, "", RequiredType.NONE, CommandCategory.TELEPORT) {}) + .collect(Collectors.toList())); + + if (Permissions.hasPermission(player, Captions.PERMISSION_LIST_PLAYER) && args[0].length() > 0) { + commands.addAll(TabCompletions.completePlayers(args[0], Collections.emptyList())); + } + + return commands; + } + } diff --git a/Core/src/main/java/com/plotsquared/core/util/PlatformWorldManager.java b/Core/src/main/java/com/plotsquared/core/util/PlatformWorldManager.java index f57e42a21..c304ff04c 100644 --- a/Core/src/main/java/com/plotsquared/core/util/PlatformWorldManager.java +++ b/Core/src/main/java/com/plotsquared/core/util/PlatformWorldManager.java @@ -28,6 +28,8 @@ package com.plotsquared.core.util; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collection; + /** * This class should be implemented by each platform to allow PlotSquared to interact * with the world management solution used on the server. @@ -62,4 +64,11 @@ public interface PlatformWorldManager { */ String getName(); + /** + * Get the names of all worlds on the server + * + * @return Worlds + */ + Collection getWorlds(); + } From 0021b114def5d6fe380df3fa32780efdaa634fe1 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Sun, 24 May 2020 23:24:27 +0100 Subject: [PATCH 36/39] Revert "Slow down queue a bit because 1.13+ performance is bad" This reverts commit bbde2f5e069379a6bb09cca70747dcc7d3c88c4f. --- .../com/plotsquared/core/configuration/Settings.java | 4 ++-- .../com/plotsquared/core/queue/GlobalBlockQueue.java | 11 +++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Core/src/main/java/com/plotsquared/core/configuration/Settings.java b/Core/src/main/java/com/plotsquared/core/configuration/Settings.java index 2be87ada3..3fbd71394 100644 --- a/Core/src/main/java/com/plotsquared/core/configuration/Settings.java +++ b/Core/src/main/java/com/plotsquared/core/configuration/Settings.java @@ -491,9 +491,9 @@ public class Settings extends Config { @Comment("Settings relating to PlotSquared's GlobalBlockQueue") public static final class QUEUE { - @Comment({"Average time per tick spent completing chunk tasks in ms.", + @Comment({"Average time per tick spent completing chunk tasks in ms. Target average TPS = 20 * 50 / TARGET_TIME.", "Waits (chunk task time / target_time) ticks before completely the next task."}) - public static int TARGET_TIME = 40; + public static int TARGET_TIME = 65; } diff --git a/Core/src/main/java/com/plotsquared/core/queue/GlobalBlockQueue.java b/Core/src/main/java/com/plotsquared/core/queue/GlobalBlockQueue.java index 6abfea8f8..3b63a94c0 100644 --- a/Core/src/main/java/com/plotsquared/core/queue/GlobalBlockQueue.java +++ b/Core/src/main/java/com/plotsquared/core/queue/GlobalBlockQueue.java @@ -57,7 +57,6 @@ public class GlobalBlockQueue { private final RunnableVal2 SET_TASK = new RunnableVal2() { @Override public void run(Long free, LocalBlockQueue queue) { - long t1 = System.currentTimeMillis(); do { boolean more = queue.next(); if (!more) { @@ -67,9 +66,9 @@ public class GlobalBlockQueue { } return; } - } while (((GlobalBlockQueue.this.secondLast = System.currentTimeMillis()) - - GlobalBlockQueue.this.last) < free); - lastPeriod = System.currentTimeMillis() - t1; + } while ((lastPeriod = + ((GlobalBlockQueue.this.secondLast = System.currentTimeMillis()) + - GlobalBlockQueue.this.last)) < free); } }; @@ -125,8 +124,8 @@ public class GlobalBlockQueue { lastPeriod -= targetTime; return; } - SET_TASK.value1 = 30 + Math.min( - (30 + GlobalBlockQueue.this.last) - (GlobalBlockQueue.this.last = + SET_TASK.value1 = 50 + Math.min( + (50 + GlobalBlockQueue.this.last) - (GlobalBlockQueue.this.last = System.currentTimeMillis()), GlobalBlockQueue.this.secondLast - System.currentTimeMillis()); SET_TASK.value2 = GlobalBlockQueue.this.getNextQueue(); From 31b71ade695016a58fe2b4c29ed9f377c4927e47 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Sun, 24 May 2020 23:43:15 +0100 Subject: [PATCH 37/39] * :D --- .../main/java/com/plotsquared/core/configuration/Settings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/main/java/com/plotsquared/core/configuration/Settings.java b/Core/src/main/java/com/plotsquared/core/configuration/Settings.java index 3fbd71394..76d384fff 100644 --- a/Core/src/main/java/com/plotsquared/core/configuration/Settings.java +++ b/Core/src/main/java/com/plotsquared/core/configuration/Settings.java @@ -491,7 +491,7 @@ public class Settings extends Config { @Comment("Settings relating to PlotSquared's GlobalBlockQueue") public static final class QUEUE { - @Comment({"Average time per tick spent completing chunk tasks in ms. Target average TPS = 20 * 50 / TARGET_TIME.", + @Comment({"Average time per tick spent completing chunk tasks in ms.", "Waits (chunk task time / target_time) ticks before completely the next task."}) public static int TARGET_TIME = 65; } From 4b0df8087844d0d6e91f84fe6c013cb949bc2a86 Mon Sep 17 00:00:00 2001 From: darbyjack Date: Mon, 25 May 2020 00:09:28 -0500 Subject: [PATCH 38/39] Updated PAPI & EssX dependency to ensure compatibility --- Bukkit/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Bukkit/build.gradle b/Bukkit/build.gradle index caafd3ef0..119516422 100644 --- a/Bukkit/build.gradle +++ b/Bukkit/build.gradle @@ -30,9 +30,9 @@ dependencies { compile("com.github.MilkBowl:VaultAPI:1.7") { exclude(module: "bukkit") } - implementation("me.clip:placeholderapi:2.10.4") + implementation("me.clip:placeholderapi:2.10.6") implementation("net.luckperms:api:5.0") - implementation("net.ess3:EssentialsX:2.16.1") + implementation("net.ess3:EssentialsX:2.17.2") compile("se.hyperver.hyperverse:Core:0.6.0-SNAPSHOT"){ transitive = false } compile 'com.github.pavog:SquirrelID:0.6.1' } From 67fbfb0f2d41b00b96aa11fa6d119868115a8c4a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 25 May 2020 09:13:10 +0000 Subject: [PATCH 39/39] Bump api from 5.0 to 5.1 Bumps [api](https://github.com/lucko/LuckPerms) from 5.0 to 5.1. - [Release notes](https://github.com/lucko/LuckPerms/releases) - [Commits](https://github.com/lucko/LuckPerms/compare/v5.0...v5.1) Signed-off-by: dependabot-preview[bot] --- Bukkit/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Bukkit/build.gradle b/Bukkit/build.gradle index caafd3ef0..391a755dc 100644 --- a/Bukkit/build.gradle +++ b/Bukkit/build.gradle @@ -31,7 +31,7 @@ dependencies { exclude(module: "bukkit") } implementation("me.clip:placeholderapi:2.10.4") - implementation("net.luckperms:api:5.0") + implementation("net.luckperms:api:5.1") implementation("net.ess3:EssentialsX:2.16.1") compile("se.hyperver.hyperverse:Core:0.6.0-SNAPSHOT"){ transitive = false } compile 'com.github.pavog:SquirrelID:0.6.1'