Merge branch 'v5' into features/v5/uuid

This commit is contained in:
NotMyFault 2020-05-25 13:13:29 +02:00 committed by GitHub
commit 09327b0128
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 1956 additions and 609 deletions

2
.github/FUNDING.yml vendored
View File

@ -9,4 +9,4 @@ community_bridge: # Replace with a single Community Bridge project-name e.g., cl
liberapay: # Replace with a single Liberapay username liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie 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']

View File

@ -28,6 +28,7 @@ assignees: ''
<!--- Issue /plot debugpaste in game or in your console and copy the supplied URL here --> <!--- Issue /plot debugpaste in game or in your console and copy the supplied URL here -->
<!--- If you cannot perform the above, we require logs/latest.log; settings.yml; worlds.yml and possibly PlotSquared.use_THIS.yml --> <!--- If you cannot perform the above, we require logs/latest.log; settings.yml; worlds.yml and possibly PlotSquared.use_THIS.yml -->
<!--- If you are unwilling to supply the information we need, we reserve the right to not assist you. Redact IP addresses if you need to. --> <!--- If you are unwilling to supply the information we need, we reserve the right to not assist you. Redact IP addresses if you need to. -->
**/plot debugpaste:**
### Server type: ### Server type:
**Select one** **Select one**

View File

@ -1,101 +0,0 @@
---
name: Bug/Issue report for PlotSquared
about: Bug / Issue report about this plugin
title: ''
labels: "[?] Testing Required"
assignees: ''
---
<!--- READ THIS BEFORE SUBMITTING AN ISSUE REPORT!!! -->
<!--- ##### DO NOT REMOVE THIS TEMPLATE! YOUR ISSUE *WILL* FIT IN IT! ##### -->
<!--- # NOTICE:
**Feature requests & Suggestions are to be submitted at the [PlotSquared Suggestions tracker](https://github.com/IntellectualSites/PlotSquaredSuggestions)**
**Code contributions are to be done through [PRs](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request), tagging the specific issue ticket(s) if applicable.**
**[DISCORD INVITE LINK](https://discord.gg/KxkjDVg)**
-->
# Bug Report Template:
<!--- Incomplete reports will most likely be marked as invalid, and closed, with few exceptions.-->
## Required Information section:
> ALL FIELDS IN THIS SECTION ARE REQUIRED, and must contain appropriate information
### Server config info (/plot debugpaste / file paste links):
<!--- Issue /plot debugpaste in game or in your console and copy the supplied URL here -->
<!--- If you cannot perform the above, we require logs/latest.log; settings.yml; worlds.yml and possibly PlotSquared.use_THIS.yml -->
<!--- If you are unwilling to supply the information we need, we reserve the right to not assist you. Redact IP addresses if you need to. -->
**/plot debugpaste:**
### Server type:
**Select one**
<!-- Select the type you are reporting the issue for (put an "X" between of brackets): -->
- [] Spigot / Paper *(CraftBukkit should not be used, re-test with Spigot first!)*
- [] Sponge
- [] NukkitX
### PlotSquared version:
<!-- Run /plot plugin in-game or in console & paste the full output here: -->
```
Paste the output here, between the tick marks, replacing this text
```
### Minecraft Version:
**Select one**
<!-- Select the type you are reporting the issue for (put an "X" between of brackets) -->
- [] 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:
<!--- Run /version in-game or in console & paste the full output here: -->
```
Paste the output here, between the tick marks, replacing this text
```
### WorldEdit/FAWE versions:
<!--- Specify which plugin you are using, and add its version. Either use /fawe version or /we version -->
- [] FAWE version:
- [] WorldEdit version:
### Description of the problem:
<!--- Be as specific as possible. Don't lie, redact information, or use false names/situations. -->
<!--- Who, What, When, Where, Why, How, Expected behavior, Resultant behavior, etc -->
### How to replicate:
<!--- If you can reproduce the issue please tell us as detailed as possible step by step how to do that -->
## 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:
<!--- Optional but recommended - issue "/plugins" in-game or in console and copy/paste the list -->
### Relevant console output, log lines, and/or screenshots:
<!--- Please use in-line code insertion
```
like this
```
for short (20 lines or less) text blobs, or a paste service for large blobs -->
### Additional relevant comments/remarks:
<!--- Use this space to give us any additional information which may be relevant to this issue, such as: if you are using a Minecraft hosting provider; unusual installation environment; etc -->
# AFFIRMATION OF COMPLETION:
<!-- Make sure you have completed the following steps (put an "X" between of brackets): -->
- [] 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.

View File

@ -1,5 +1,8 @@
blank_issues_enabled: false blank_issues_enabled: false
contact_links: 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 - name: PlotSquared Suggestions
url: https://github.com/IntellectualSites/PlotSquaredSuggestions url: https://github.com/IntellectualSites/PlotSquaredSuggestions
about: If you want to submit feature or suggestion ideas, do that here about: If you want to submit feature or suggestion ideas, do that here

View File

@ -31,9 +31,9 @@ dependencies {
compile("com.github.MilkBowl:VaultAPI:1.7") { compile("com.github.MilkBowl:VaultAPI:1.7") {
exclude(module: "bukkit") 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.luckperms:api:5.1")
implementation("net.ess3:EssentialsX:2.16.1") implementation("net.ess3:EssentialsX:2.17.2")
implementation("net.alpenblock:BungeePerms:4.0-dev-106") implementation("net.alpenblock:BungeePerms:4.0-dev-106")
compile("se.hyperver.hyperverse:Core:0.6.0-SNAPSHOT"){ transitive = false } compile("se.hyperver.hyperverse:Core:0.6.0-SNAPSHOT"){ transitive = false }
compile 'com.github.pavog:SquirrelID:0.6.1' compile 'com.github.pavog:SquirrelID:0.6.1'
@ -93,6 +93,9 @@ shadowJar {
include(dependency("io.papermc:paperlib:1.0.2")) include(dependency("io.papermc:paperlib:1.0.2"))
include(dependency("net.kyori:text-adapter-bukkit:3.0.3")) include(dependency("net.kyori:text-adapter-bukkit:3.0.3"))
include(dependency("org.bstats:bstats-bukkit:1.7")) 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"))
include(dependency("com.github.pavog:SquirrelID:0.6.1")) include(dependency("com.github.pavog:SquirrelID:0.6.1"))
} }
relocate('net.kyori.text', 'com.plotsquared.formatting.text') relocate('net.kyori.text', 'com.plotsquared.formatting.text')

View File

@ -36,6 +36,9 @@ import org.jetbrains.annotations.Nullable;
import java.io.File; import java.io.File;
import java.io.IOException; 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 * Default Bukkit world manager. It will handle world creation by
@ -76,4 +79,13 @@ public class BukkitWorldManager implements PlatformWorldManager<World> {
return "bukkit"; return "bukkit";
} }
@Override public Collection<String> getWorlds() {
final List<World> worlds = Bukkit.getWorlds();
final List<String> worldNames = new ArrayList<>();
for (final World world : worlds) {
worldNames.add(world.getName());
}
return worldNames;
}
} }

View File

@ -348,7 +348,7 @@ public class BukkitRegionManager extends RegionManager {
CuboidRegion currentPlotClear = RegionUtil CuboidRegion currentPlotClear = RegionUtil
.createRegion(pos1.getX(), pos2.getX(), pos1.getZ(), pos2.getZ()); .createRegion(pos1.getX(), pos2.getX(), pos1.getZ(), pos2.getZ());
map.saveEntitiesOut(chunkObj, currentPlotClear); map.saveEntitiesOut(chunkObj, currentPlotClear);
AugmentedUtils.bypass(ignoreAugment, () -> ChunkManager.manager AugmentedUtils.bypass(ignoreAugment, () -> ChunkManager
.setChunkInPlotArea(null, new RunnableVal<ScopedLocalBlockQueue>() { .setChunkInPlotArea(null, new RunnableVal<ScopedLocalBlockQueue>() {
@Override public void run(ScopedLocalBlockQueue value) { @Override public void run(ScopedLocalBlockQueue value) {
Location min = value.getMin(); Location min = value.getMin();

View File

@ -16,6 +16,7 @@ dependencies {
testAnnotationProcessor("org.projectlombok:lombok:1.18.8") testAnnotationProcessor("org.projectlombok:lombok:1.18.8")
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.3.72") implementation("org.jetbrains.kotlin:kotlin-stdlib:1.3.72")
implementation("org.jetbrains:annotations:19.0.0") implementation("org.jetbrains:annotations:19.0.0")
implementation 'com.github.davidmoten:rtree:0.8.7'
} }
sourceCompatibility = 1.8 sourceCompatibility = 1.8
@ -73,6 +74,7 @@ shadowJar {
include(dependency("net.kyori:text-serializer-gson:3.0.2")) 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-legacy:3.0.2"))
include(dependency("net.kyori:text-serializer-plain: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('net.kyori.text', 'com.plotsquared.formatting.text')
relocate("org.json", "com.plotsquared.json") { relocate("org.json", "com.plotsquared.json") {

View File

@ -92,6 +92,12 @@
<version>1.3.72</version> <version>1.3.72</version>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<dependency>
<groupId>com.github.davidmoten</groupId>
<artifactId>rtree</artifactId>
<version>0.8.7</version>
<scope>runtime</scope>
</dependency>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>

View File

@ -53,6 +53,7 @@ import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.BlockBucket; import com.plotsquared.core.plot.BlockBucket;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.PlotAreaTerrainType;
import com.plotsquared.core.plot.PlotAreaType; import com.plotsquared.core.plot.PlotAreaType;
import com.plotsquared.core.plot.PlotCluster; import com.plotsquared.core.plot.PlotCluster;
import com.plotsquared.core.plot.PlotFilter; import com.plotsquared.core.plot.PlotFilter;
@ -81,6 +82,7 @@ import com.plotsquared.core.util.SetupUtils;
import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.StringMan;
import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.WorldUtil;
import com.plotsquared.core.util.logger.ILogger; 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.task.TaskManager;
import com.plotsquared.core.uuid.UUIDPipeline; import com.plotsquared.core.uuid.UUIDPipeline;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
@ -116,6 +118,7 @@ import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
@ -267,7 +270,8 @@ public class PlotSquared {
// create setup util class // create setup util class
SetupUtils.manager = this.IMP.initSetupUtils(); SetupUtils.manager = this.IMP.initSetupUtils();
// Set block // 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(); GlobalBlockQueue.IMP.runTask();
// Set chunk // Set chunk
ChunkManager.manager = this.IMP.initChunkManager(); ChunkManager.manager = this.IMP.initChunkManager();
@ -620,17 +624,7 @@ public class PlotSquared {
* @return Set of base Plots * @return Set of base Plots
*/ */
public Set<Plot> getBasePlots() { public Set<Plot> getBasePlots() {
int size = getPlotCount(); return PlotQuery.newQuery().whereBasePlot().asSet();
final Set<Plot> result = new HashSet<>(size);
forEachPlotArea(value -> {
for (Plot plot : value.getPlots()) {
if (!plot.isBasePlot()) {
continue;
}
result.add(plot);
}
});
return Collections.unmodifiableSet(result);
} }
public List<Plot> sortPlotsByTemp(Collection<Plot> plots) { public List<Plot> sortPlotsByTemp(Collection<Plot> plots) {
@ -883,27 +877,25 @@ public class PlotSquared {
* *
* @param filters the filter * @param filters the filter
* @return a filtered set of plots * @return a filtered set of plots
* @deprecated Use {@link PlotQuery}
*/ */
public Set<Plot> getPlots(final PlotFilter... filters) { @Deprecated public Set<Plot> getPlots(final PlotFilter... filters) {
final HashSet<Plot> set = new HashSet<>(); final List<PlotArea> areas = new LinkedList<>();
forEachPlotArea(value -> { for (final PlotArea plotArea : this.getPlotAreas()) {
for (PlotFilter filter : filters) { for (final PlotFilter filter : filters) {
if (!filter.allowsArea(value)) { if (filter.allowsArea(plotArea)) {
return; areas.add(plotArea);
} }
} }
loop: }
for (Entry<PlotId, Plot> entry2 : value.getPlotEntries()) { return PlotQuery.newQuery().inAreas(areas).thatPasses(plot -> {
Plot plot = entry2.getValue(); for (final PlotFilter filter : filters) {
for (PlotFilter filter : filters) {
if (!filter.allowsPlot(plot)) { if (!filter.allowsPlot(plot)) {
continue loop; return false;
} }
} }
set.add(plot); return true;
} }).asSet();
});
return set;
} }
/** /**
@ -970,7 +962,7 @@ public class PlotSquared {
* @return Set of plot * @return Set of plot
*/ */
public Set<Plot> getPlots(String world, PlotPlayer player) { public Set<Plot> getPlots(String world, PlotPlayer player) {
return getPlots(world, player.getUUID()); return PlotQuery.newQuery().inWorld(world).ownedBy(player).asSet();
} }
/** /**
@ -981,7 +973,7 @@ public class PlotSquared {
* @return Set of plot * @return Set of plot
*/ */
public Set<Plot> getPlots(PlotArea area, PlotPlayer player) { public Set<Plot> getPlots(PlotArea area, PlotPlayer player) {
return getPlots(area, player.getUUID()); return PlotQuery.newQuery().inArea(area).ownedBy(player).asSet();
} }
/** /**
@ -991,14 +983,8 @@ public class PlotSquared {
* @param uuid the plot owner * @param uuid the plot owner
* @return Set of plot * @return Set of plot
*/ */
public Set<Plot> getPlots(String world, @Nullable UUID uuid) { public Set<Plot> getPlots(String world, UUID uuid) {
if (uuid == null) { return PlotQuery.newQuery().inWorld(world).ownedBy(uuid).asSet();
return Collections.emptySet();
}
final Set<Plot> plots =
getPlots(world).stream().filter(plot -> plot.hasOwner() && plot.isOwnerAbs(uuid))
.collect(Collectors.toSet());
return Collections.unmodifiableSet(plots);
} }
/** /**
@ -1009,13 +995,7 @@ public class PlotSquared {
* @return Set of plots * @return Set of plots
*/ */
public Set<Plot> getPlots(PlotArea area, UUID uuid) { public Set<Plot> getPlots(PlotArea area, UUID uuid) {
final Set<Plot> plots = new HashSet<>(); return PlotQuery.newQuery().inArea(area).ownedBy(uuid).asSet();
for (Plot plot : getPlots(area)) {
if (plot.hasOwner() && plot.isOwnerAbs(uuid)) {
plots.add(plot);
}
}
return Collections.unmodifiableSet(plots);
} }
/** /**
@ -1030,9 +1010,7 @@ public class PlotSquared {
} }
public Collection<Plot> getPlots(String world) { public Collection<Plot> getPlots(String world) {
final Set<Plot> set = new HashSet<>(); return PlotQuery.newQuery().inWorld(world).asCollection();
forEachPlotArea(world, value -> set.addAll(value.getPlots()));
return set;
} }
/** /**
@ -1042,7 +1020,7 @@ public class PlotSquared {
* @return Set of Plot * @return Set of Plot
*/ */
public Set<Plot> getPlots(PlotPlayer player) { public Set<Plot> getPlots(PlotPlayer player) {
return getPlots(player.getUUID()); return PlotQuery.newQuery().ownedBy(player).asSet();
} }
public Collection<Plot> getPlots(PlotArea area) { public Collection<Plot> getPlots(PlotArea area) {
@ -1064,13 +1042,7 @@ public class PlotSquared {
* @return Set of Plot's owned by the player * @return Set of Plot's owned by the player
*/ */
public Set<Plot> getPlots(final UUID uuid) { public Set<Plot> getPlots(final UUID uuid) {
final Set<Plot> plots = new HashSet<>(); return PlotQuery.newQuery().ownedBy(uuid).asSet();
forEachPlot(value -> {
if (value.isOwnerAbs(uuid)) {
plots.add(value);
}
});
return Collections.unmodifiableSet(plots);
} }
public boolean hasPlot(final UUID uuid) { public boolean hasPlot(final UUID uuid) {
@ -1079,13 +1051,7 @@ public class PlotSquared {
} }
public Set<Plot> getBasePlots(final UUID uuid) { public Set<Plot> getBasePlots(final UUID uuid) {
final Set<Plot> plots = new HashSet<>(); return PlotQuery.newQuery().ownedBy(uuid).whereBasePlot().asSet();
forEachBasePlot(value -> {
if (value.isOwner(uuid)) {
plots.add(value);
}
});
return Collections.unmodifiableSet(plots);
} }
/** /**
@ -1095,13 +1061,7 @@ public class PlotSquared {
* @return Set of Plot * @return Set of Plot
*/ */
public Set<Plot> getPlotsAbs(final UUID uuid) { public Set<Plot> getPlotsAbs(final UUID uuid) {
final Set<Plot> plots = new HashSet<>(); return PlotQuery.newQuery().ownedBy(uuid).asSet();
forEachPlot(value -> {
if (value.isOwnerAbs(uuid)) {
plots.add(value);
}
});
return Collections.unmodifiableSet(plots);
} }
/** /**
@ -1996,6 +1956,23 @@ public class PlotSquared {
return Collections.unmodifiableSet(set); 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) { public boolean isAugmented(@NonNull final String world) {
final PlotArea[] areas = plotAreaManager.getPlotAreas(world, null); final PlotArea[] areas = plotAreaManager.getPlotAreas(world, null);
return areas != null && (areas.length > 1 || areas[0].getType() != PlotAreaType.NORMAL); return areas != null && (areas.length > 1 || areas[0].getType() != PlotAreaType.NORMAL);
@ -2085,16 +2062,7 @@ public class PlotSquared {
*/ */
public Set<Plot> getPlotsByAlias(@Nullable final String alias, public Set<Plot> getPlotsByAlias(@Nullable final String alias,
@NonNull final String worldname) { @NonNull final String worldname) {
final Set<Plot> result = new HashSet<>(); return PlotQuery.newQuery().inWorld(worldname).withAlias(alias).asSet();
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);
} }
public Set<PlotArea> getPlotAreas(final String world, final CuboidRegion region) { public Set<PlotArea> getPlotAreas(final String world, final CuboidRegion region) {

View File

@ -33,6 +33,7 @@ import com.plotsquared.core.events.TeleportCause;
import com.plotsquared.core.generator.AugmentedUtils; import com.plotsquared.core.generator.AugmentedUtils;
import com.plotsquared.core.generator.HybridPlotWorld; import com.plotsquared.core.generator.HybridPlotWorld;
import com.plotsquared.core.location.Location; import com.plotsquared.core.location.Location;
import com.plotsquared.core.player.ConsolePlayer;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.PlotAreaTerrainType; import com.plotsquared.core.plot.PlotAreaTerrainType;
@ -45,14 +46,28 @@ import com.plotsquared.core.util.MathMan;
import com.plotsquared.core.util.Permissions; import com.plotsquared.core.util.Permissions;
import com.plotsquared.core.util.RegionManager; import com.plotsquared.core.util.RegionManager;
import com.plotsquared.core.util.RegionUtil; import com.plotsquared.core.util.RegionUtil;
import com.plotsquared.core.util.SchematicHandler;
import com.plotsquared.core.util.SetupUtils; import com.plotsquared.core.util.SetupUtils;
import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.StringMan;
import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.WorldUtil;
import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.RunnableVal;
import com.plotsquared.core.util.task.RunnableVal3; 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.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion; 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.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Objects; import java.util.Objects;
@ -74,6 +89,139 @@ public class Area extends SubCommand {
return false; return false;
} }
switch (args[0].toLowerCase()) { 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;
}
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;
}
final LocalSession localSession = WorldEdit.getInstance().getSessionManager().getIfPresent(player.toActor());
if (localSession == null) {
MainUtil.sendMessage(player, Captions.SINGLE_AREA_MISSING_SELECTION);
return false;
}
Region playerSelectedRegion = null;
try {
playerSelectedRegion = localSession.getSelection(((Player) player.toActor()).getWorld());
} catch (final Exception ignored) {}
if (playerSelectedRegion == null) {
MainUtil.sendMessage(player, Captions.SINGLE_AREA_MISSING_SELECTION);
return false;
}
if (playerSelectedRegion.getWidth() != playerSelectedRegion.getLength()) {
MainUtil.sendMessage(player, Captions.SINGLE_AREA_NOT_SQUARE);
return false;
}
if (PlotSquared.get().getPlotAreaManager().getPlotAreas(
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],
Objects.requireNonNull(PlotSquared.imp()).getDefaultGenerator(), plotId, plotId);
// 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.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 = playerSelectionMin.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());
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);
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);
e.printStackTrace();
return false;
}
// Setup schematic
try {
hybridPlotWorld.setupSchematics();
} catch (final SchematicHandler.UnsupportedFormatException e) {
e.printStackTrace();
}
// 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();
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 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);
MainUtil.sendMessage(player, Captions.SINGLE_AREA_CREATED);
} else {
MainUtil.sendMessage(player,
"An error occurred while creating the world: " + hybridPlotWorld
.getWorldName());
}
};
singleRun.run();
return true;
case "c": case "c":
case "setup": case "setup":
case "create": case "create":

View File

@ -121,7 +121,7 @@ public class DebugPaste extends SubCommand {
b.append("OS Arch: ").append(System.getProperty("os.arch")).append('\n'); 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("# Okay :D Great. You are now ready to create your bug report!");
b.append( 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"); b.append("\n# or via our Discord at https://discord.gg/KxkjDVg");
final IncendoPaster incendoPaster = new IncendoPaster("plotsquared"); final IncendoPaster incendoPaster = new IncendoPaster("plotsquared");

View File

@ -26,14 +26,12 @@
package com.plotsquared.core.command; package com.plotsquared.core.command;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.PlotSquared.SortType;
import com.plotsquared.core.configuration.CaptionUtility; import com.plotsquared.core.configuration.CaptionUtility;
import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.Rating;
import com.plotsquared.core.plot.expiration.ExpireManager; import com.plotsquared.core.plot.expiration.ExpireManager;
import com.plotsquared.core.plot.flag.implementations.DoneFlag; import com.plotsquared.core.plot.flag.implementations.DoneFlag;
import com.plotsquared.core.plot.flag.implementations.PriceFlag; import com.plotsquared.core.plot.flag.implementations.PriceFlag;
@ -44,19 +42,24 @@ import com.plotsquared.core.util.MathMan;
import com.plotsquared.core.util.Permissions; import com.plotsquared.core.util.Permissions;
import com.plotsquared.core.util.StringComparison; import com.plotsquared.core.util.StringComparison;
import com.plotsquared.core.util.StringMan; 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; import com.plotsquared.core.util.task.RunnableVal3;
import com.plotsquared.core.uuid.UUIDMapping; import com.plotsquared.core.uuid.UUIDMapping;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map.Entry;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.stream.Collectors;
@CommandDeclaration(command = "list", @CommandDeclaration(command = "list",
aliases = {"l", "find", "search"}, aliases = {"l", "find", "search"},
@ -140,22 +143,31 @@ public class ListCmd extends SubCommand {
String arg = args[0].toLowerCase(); String arg = args[0].toLowerCase();
final boolean[] sort = new boolean[] {true}; final boolean[] sort = new boolean[] {true};
final Consumer<Collection<Plot>> plotConsumer = plots -> { final Consumer<PlotQuery> plotConsumer = query -> {
if (plots == null) { if (query == null) {
sendMessage(player, Captions.DID_YOU_MEAN, sendMessage(player, Captions.DID_YOU_MEAN,
new StringComparison<>(args[0], new String[] {"mine", "shared", "world", "all"}) new StringComparison<>(args[0], new String[] {"mine", "shared", "world", "all"})
.getBestMatch()); .getBestMatch());
return; return;
} }
if (area != null) {
query.relativeToArea(area);
}
if (sort[0]) {
query.withSortingStrategy(SortingStrategy.SORT_BY_CREATION);
}
final List<Plot> plots = query.asList();
if (plots.isEmpty()) { if (plots.isEmpty()) {
MainUtil.sendMessage(player, Captions.FOUND_NO_PLOTS); MainUtil.sendMessage(player, Captions.FOUND_NO_PLOTS);
return; return;
} }
displayPlots(player, new ArrayList<>(plots), 12, page, area, args, sort[0]); displayPlots(player, plots, 12, page, args);
}; };
final List<Plot> plots = new ArrayList<>();
switch (arg) { switch (arg) {
case "mine": case "mine":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_MINE)) { if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_MINE)) {
@ -164,8 +176,7 @@ public class ListCmd extends SubCommand {
return false; return false;
} }
sort[0] = false; sort[0] = false;
plotConsumer.accept( plotConsumer.accept(PlotQuery.newQuery().ownedBy(player).whereBasePlot().withSortingStrategy(SortingStrategy.SORT_BY_TEMP));
PlotSquared.get().sortPlotsByTemp(PlotSquared.get().getBasePlots(player)));
break; break;
case "shared": case "shared":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_SHARED)) { if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_SHARED)) {
@ -173,13 +184,7 @@ public class ListCmd extends SubCommand {
Captions.PERMISSION_LIST_SHARED); Captions.PERMISSION_LIST_SHARED);
return false; return false;
} }
for (Plot plot : PlotSquared.get().getPlots()) { plotConsumer.accept(PlotQuery.newQuery().withMember(player.getUUID()).thatPasses(plot -> !plot.isOwnerAbs(player.getUUID())));
if (plot.getTrusted().contains(player.getUUID()) || plot.getMembers()
.contains(player.getUUID())) {
plots.add(plot);
}
}
plotConsumer.accept(plots);
break; break;
case "world": case "world":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_WORLD)) { if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_WORLD)) {
@ -194,7 +199,7 @@ public class ListCmd extends SubCommand {
world)); world));
return false; return false;
} }
plotConsumer.accept(PlotSquared.get().getPlots(world)); plotConsumer.accept(PlotQuery.newQuery().inWorld(world));
break; break;
case "expired": case "expired":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_EXPIRED)) { if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_EXPIRED)) {
@ -202,9 +207,11 @@ public class ListCmd extends SubCommand {
Captions.PERMISSION_LIST_EXPIRED); Captions.PERMISSION_LIST_EXPIRED);
return false; return false;
} }
plotConsumer.accept(ExpireManager.IMP == null ? if (ExpireManager.IMP == null) {
new ArrayList<>() : plotConsumer.accept(PlotQuery.newQuery().noPlots());
new ArrayList<>(ExpireManager.IMP.getPendingExpired())); } else {
plotConsumer.accept(PlotQuery.newQuery().expiredPlots());
}
break; break;
case "area": case "area":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_AREA)) { if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_AREA)) {
@ -219,8 +226,11 @@ public class ListCmd extends SubCommand {
world)); world));
return false; return false;
} }
plotConsumer.accept( if (area == null) {
area == null ? new ArrayList<Plot>() : new ArrayList<>(area.getPlots())); plotConsumer.accept(PlotQuery.newQuery().noPlots());
} else {
plotConsumer.accept(PlotQuery.newQuery().inArea(area));
}
break; break;
case "all": case "all":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_ALL)) { if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_ALL)) {
@ -228,7 +238,7 @@ public class ListCmd extends SubCommand {
.sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_LIST_ALL); .sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_LIST_ALL);
return false; return false;
} }
plotConsumer.accept(new ArrayList<>(PlotSquared.get().getPlots())); plotConsumer.accept(PlotQuery.newQuery().allPlots());
break; break;
case "done": case "done":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_DONE)) { if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_DONE)) {
@ -236,24 +246,8 @@ public class ListCmd extends SubCommand {
.sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_LIST_DONE); .sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_LIST_DONE);
return false; return false;
} }
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;
});
sort[0] = false; sort[0] = false;
plotConsumer.accept(plots); plotConsumer.accept(PlotQuery.newQuery().allPlots().thatPasses(DoneFlag::isDone).withSortingStrategy(SortingStrategy.SORT_BY_DONE));
break; break;
case "top": case "top":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_TOP)) { if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_TOP)) {
@ -261,33 +255,8 @@ public class ListCmd extends SubCommand {
.sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_LIST_TOP); .sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_LIST_TOP);
return false; return false;
} }
plots.addAll(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<UUID, Rating> 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);
});
sort[0] = false; sort[0] = false;
plotConsumer.accept(plots); plotConsumer.accept(PlotQuery.newQuery().allPlots().withSortingStrategy(SortingStrategy.SORT_BY_RATING));
break; break;
case "forsale": case "forsale":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_FOR_SALE)) { if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_FOR_SALE)) {
@ -298,12 +267,7 @@ public class ListCmd extends SubCommand {
if (EconHandler.manager == null) { if (EconHandler.manager == null) {
break; break;
} }
for (Plot plot : PlotSquared.get().getPlots()) { plotConsumer.accept(PlotQuery.newQuery().allPlots().thatPasses(plot -> plot.getFlag(PriceFlag.class) > 0));
if (plot.getFlag(PriceFlag.class) > 0) {
plots.add(plot);
}
}
plotConsumer.accept(plots);
break; break;
case "unowned": case "unowned":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_UNOWNED)) { if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_UNOWNED)) {
@ -311,12 +275,7 @@ public class ListCmd extends SubCommand {
Captions.PERMISSION_LIST_UNOWNED); Captions.PERMISSION_LIST_UNOWNED);
return false; return false;
} }
for (Plot plot : PlotSquared.get().getPlots()) { plotConsumer.accept(PlotQuery.newQuery().allPlots().thatPasses(plot -> plot.getOwner() == null));
if (plot.getOwner() == null) {
plots.add(plot);
}
}
plotConsumer.accept(plots);
break; break;
case "fuzzy": case "fuzzy":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_FUZZY)) { if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_FUZZY)) {
@ -335,7 +294,7 @@ public class ListCmd extends SubCommand {
term = StringMan.join(Arrays.copyOfRange(args, 1, args.length), " "); term = StringMan.join(Arrays.copyOfRange(args, 1, args.length), " ");
} }
sort[0] = false; sort[0] = false;
plotConsumer.accept(MainUtil.getPlotsBySearch(term)); plotConsumer.accept(PlotQuery.newQuery().plotsBySearch(term));
break; break;
default: default:
if (PlotSquared.get().hasPlotArea(args[0])) { if (PlotSquared.get().hasPlotArea(args[0])) {
@ -352,7 +311,7 @@ public class ListCmd extends SubCommand {
args[0])); args[0]));
return false; return false;
} }
plotConsumer.accept(new ArrayList<>(PlotSquared.get().getPlots(args[0]))); plotConsumer.accept(PlotQuery.newQuery().inWorld(args[0]));
break; break;
} }
@ -377,24 +336,18 @@ public class ListCmd extends SubCommand {
Captions.PERMISSION_LIST_PLAYER); Captions.PERMISSION_LIST_PLAYER);
} else { } else {
sort[0] = false; sort[0] = false;
plotConsumer.accept(PlotSquared.get() plotConsumer.accept(PlotQuery.newQuery().ownedBy(uuid).withSortingStrategy(SortingStrategy.SORT_BY_TEMP));
.sortPlotsByTemp(PlotSquared.get().getPlots(uuid)));
} }
} }
}); });
break;
} }
return true; return true;
} }
public void displayPlots(final PlotPlayer player, List<Plot> plots, int pageSize, int page, public void displayPlots(final PlotPlayer player, List<Plot> plots, int pageSize, int page, String[] args) {
PlotArea area, String[] args, boolean sort) {
// Header // Header
plots.removeIf(plot -> !plot.isBasePlot()); plots.removeIf(plot -> !plot.isBasePlot());
if (sort) {
plots = PlotSquared.get().sortPlots(plots, SortType.CREATION_DATE, area);
}
this.paginate(player, plots, pageSize, page, this.paginate(player, plots, pageSize, page,
new RunnableVal3<Integer, Plot, PlotMessage>() { new RunnableVal3<Integer, Plot, PlotMessage>() {
@Override public void run(Integer i, Plot plot, PlotMessage message) { @Override public void run(Integer i, Plot plot, PlotMessage message) {
@ -449,4 +402,48 @@ public class ListCmd extends SubCommand {
}, "/plot list " + args[0], Captions.PLOT_LIST_HEADER_PAGED.getTranslated()); }, "/plot list " + args[0], Captions.PLOT_LIST_HEADER_PAGED.getTranslated());
} }
@Override public Collection<Command> tab(PlotPlayer player, String[] args, boolean space) {
final List<String> 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<Command> 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;
}
} }

View File

@ -27,7 +27,6 @@ package com.plotsquared.core.command;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.events.TeleportCause; import com.plotsquared.core.events.TeleportCause;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
@ -36,19 +35,20 @@ import com.plotsquared.core.plot.flag.implementations.UntrustedVisitFlag;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.MathMan; import com.plotsquared.core.util.MathMan;
import com.plotsquared.core.util.Permissions; 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; import com.plotsquared.core.util.task.RunnableVal2;
import com.plotsquared.core.util.task.RunnableVal3; import com.plotsquared.core.util.task.RunnableVal3;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
@CommandDeclaration(command = "visit", @CommandDeclaration(command = "visit",
permission = "plots.visit", permission = "plots.visit",
@ -63,42 +63,43 @@ public class Visit extends Command {
super(MainCommand.getInstance(), true); super(MainCommand.getInstance(), true);
} }
@Override public Collection<Command> tab(PlotPlayer player, String[] args, boolean space) { private void visit(@NotNull final PlotPlayer player, @NotNull final PlotQuery query, final PlotArea sortByArea,
return tabOf(player, args, space, getUsage()); final RunnableVal3<Command, Runnable, Runnable> confirm, final RunnableVal2<Command, CommandResult> whenDone) {
this.visit(player, query, sortByArea, confirm, whenDone, 1);
} }
@Override private void visit(@NotNull final PlotPlayer player, @NotNull final PlotQuery query, final PlotArea sortByArea,
public CompletableFuture<Boolean> execute(final PlotPlayer player, String[] args, final RunnableVal3<Command, Runnable, Runnable> confirm, final RunnableVal2<Command, CommandResult> whenDone, int page) {
RunnableVal3<Command, Runnable, Runnable> confirm, // We get the query once,
final RunnableVal2<Command, CommandResult> whenDone) throws CommandException { // then we get it another time further on
if (args.length == 1 && args[0].contains(":")) { final List<Plot> unsorted = query.asList();
args = args[0].split(":");
if (unsorted.isEmpty()) {
Captions.FOUND_NO_PLOTS.send(player);
return;
} }
final Collection<Plot> unsortedPre = new HashSet<>(); if (unsorted.size() > 1) {
final PlotArea[] sortByArea = new PlotArea[] {player.getApplicablePlotArea()}; query.whereBasePlot();
final AtomicBoolean shouldSortByArea = new AtomicBoolean(Settings.Teleport.PER_WORLD_VISIT); }
final Consumer<Integer> pageConsumer = page -> {
if (page == Integer.MIN_VALUE) { if (page == Integer.MIN_VALUE) {
page = 1; page = 1;
} }
if (unsortedPre.isEmpty()) {
Captions.FOUND_NO_PLOTS.send(player);
} else {
final Collection<Plot> unsorted = new ArrayList<>(unsortedPre);
if (unsorted.size() > 1) {
unsorted.removeIf(plot -> !plot.isBasePlot());
}
if (page < 1 || page > unsorted.size()) { if (page < 1 || page > unsorted.size()) {
Captions.NOT_VALID_NUMBER.send(player, "(1, " + unsorted.size() + ")"); MainUtil.sendMessage(player, String.format("(1, %d)", unsorted.size()));
} else { return;
List<Plot> plots;
if (shouldSortByArea.get()) {
plots = PlotSquared.get().sortPlots(unsorted, PlotSquared.SortType.CREATION_DATE, sortByArea[0]);
} else {
plots = PlotSquared.get().sortPlotsByTemp(unsorted);
} }
if (sortByArea != null) {
query.relativeToArea(sortByArea).withSortingStrategy(SortingStrategy.SORT_BY_CREATION);
} else {
query.withSortingStrategy(SortingStrategy.SORT_BY_TEMP);
}
final List<Plot> plots = query.asList();
final Plot plot = plots.get(page - 1); final Plot plot = plots.get(page - 1);
if (!plot.hasOwner()) { if (!plot.hasOwner()) {
if (!Permissions.hasPermission(player, Captions.PERMISSION_VISIT_UNOWNED)) { if (!Permissions.hasPermission(player, Captions.PERMISSION_VISIT_UNOWNED)) {
@ -106,7 +107,8 @@ public class Visit extends Command {
return; return;
} }
} else if (plot.isOwner(player.getUUID())) { } else if (plot.isOwner(player.getUUID())) {
if (!Permissions.hasPermission(player, Captions.PERMISSION_VISIT_OWNED) && !Permissions.hasPermission(player, Captions.PERMISSION_HOME)) { if (!Permissions.hasPermission(player, Captions.PERMISSION_VISIT_OWNED) && !Permissions
.hasPermission(player, Captions.PERMISSION_HOME)) {
Captions.NO_PERMISSION.send(player, Captions.PERMISSION_VISIT_OWNED); Captions.NO_PERMISSION.send(player, Captions.PERMISSION_VISIT_OWNED);
return; return;
} }
@ -120,13 +122,14 @@ public class Visit extends Command {
Captions.NO_PERMISSION.send(player, Captions.PERMISSION_VISIT_OTHER); Captions.NO_PERMISSION.send(player, Captions.PERMISSION_VISIT_OTHER);
return; return;
} }
if (!plot.getFlag(UntrustedVisitFlag.class) && !Permissions.hasPermission(player, Captions.PERMISSION_ADMIN_VISIT_UNTRUSTED)) { if (!plot.getFlag(UntrustedVisitFlag.class) && !Permissions
.hasPermission(player, Captions.PERMISSION_ADMIN_VISIT_UNTRUSTED)) {
Captions.NO_PERMISSION.send(player, Captions.PERMISSION_ADMIN_VISIT_UNTRUSTED); Captions.NO_PERMISSION.send(player, Captions.PERMISSION_ADMIN_VISIT_UNTRUSTED);
return; return;
} }
} }
confirm.run(this,
() -> plot.teleportPlayer(player, TeleportCause.COMMAND, result -> { confirm.run(this, () -> plot.teleportPlayer(player, TeleportCause.COMMAND, result -> {
if (result) { if (result) {
whenDone.run(Visit.this, CommandResult.SUCCESS); whenDone.run(Visit.this, CommandResult.SUCCESS);
} else { } else {
@ -134,83 +137,172 @@ public class Visit extends Command {
} }
}), () -> whenDone.run(Visit.this, CommandResult.FAILURE)); }), () -> whenDone.run(Visit.this, CommandResult.FAILURE));
} }
}
};
final int[] page = new int[]{Integer.MIN_VALUE}; @Override
public CompletableFuture<Boolean> execute(final PlotPlayer player,
String[] args,
final RunnableVal3<Command, Runnable, Runnable> confirm,
final RunnableVal2<Command, CommandResult> whenDone) throws CommandException {
if (args.length == 1 && args[0].contains(":")) {
args = args[0].split(":");
}
PlotArea sortByArea;
int page = Integer.MIN_VALUE;
switch (args.length) { switch (args.length) {
// /p v [...] [...] <page>
case 3: case 3:
if (!MathMan.isInteger(args[1])) { if (!MathMan.isInteger(args[1])) {
Captions.NOT_VALID_NUMBER.send(player, "(1, ∞)"); Captions.NOT_VALID_NUMBER.send(player, "(1, ∞)");
Captions.COMMAND_SYNTAX.send(player, getUsage()); Captions.COMMAND_SYNTAX.send(player, getUsage());
return CompletableFuture.completedFuture(false); return CompletableFuture.completedFuture(false);
} }
page[0] = Integer.parseInt(args[2]); page = Integer.parseInt(args[2]);
// /p v <name> <area> [page]
// /p v <name> [page]
case 2: case 2:
if (page[0] != Integer.MIN_VALUE || !MathMan.isInteger(args[1])) { if (page != Integer.MIN_VALUE || !MathMan.isInteger(args[1])) {
sortByArea[0] = PlotSquared.get().getPlotAreaByString(args[1]); sortByArea = PlotSquared.get().getPlotAreaByString(args[1]);
if (sortByArea[0] == null) { if (sortByArea == null) {
Captions.NOT_VALID_NUMBER.send(player, "(1, ∞)"); Captions.NOT_VALID_NUMBER.send(player, "(1, ∞)");
Captions.COMMAND_SYNTAX.send(player, getUsage()); Captions.COMMAND_SYNTAX.send(player, getUsage());
return CompletableFuture.completedFuture(false); return CompletableFuture.completedFuture(false);
} }
final PlotArea finalSortByArea = sortByArea;
int finalPage1 = page;
MainUtil.getUUIDsFromString(args[0], (uuids, throwable) -> { MainUtil.getUUIDsFromString(args[0], (uuids, throwable) -> {
if (throwable instanceof TimeoutException) { if (throwable instanceof TimeoutException) {
Captions.FETCHING_PLAYERS_TIMEOUT.send(player); Captions.FETCHING_PLAYERS_TIMEOUT.send(player);
} else if (throwable != null || uuids.size() != 1) { } else if (throwable != null || uuids.size() != 1) {
Captions.COMMAND_SYNTAX.send(player, getUsage()); Captions.COMMAND_SYNTAX.send(player, getUsage());
} else { } else {
unsortedPre.addAll(PlotSquared.get().getBasePlots((UUID) uuids.toArray()[0])); final UUID uuid = uuids.toArray(new UUID[0])[0];
shouldSortByArea.set(true); this.visit(player, PlotQuery.newQuery().ownedBy(uuid).whereBasePlot(), finalSortByArea, confirm, whenDone, finalPage1);
pageConsumer.accept(page[0]);
} }
}); });
break; break;
} }
page[0] = Integer.parseInt(args[1]); page = Integer.parseInt(args[1]);
// /p v <name> [page]
// /p v <page> [page]
// /p v <uuid> [page]
// /p v <plot> [page]
case 1: case 1:
final String[] finalArgs = args; final String[] finalArgs = args;
final Consumer<UUID> uuidConsumer = uuid -> { int finalPage = page;
if (page[0] == Integer.MIN_VALUE && uuid == null && MathMan.isInteger(finalArgs[0])) { if (args[0].length() >= 2 && !args[0].contains(";") && !args[0].contains(",")) {
page[0] = Integer.parseInt(finalArgs[0]);
unsortedPre.addAll(PlotSquared.get().getBasePlots(player));
} else {
if (uuid != null) {
unsortedPre.addAll(PlotSquared.get().getBasePlots(uuid));
} else {
Plot plot = MainUtil.getPlotFromString(player, finalArgs[0], true);
if (plot != null) {
unsortedPre.addAll(Collections.singletonList(plot.getBasePlot(false)));
}
}
}
pageConsumer.accept(page[0]);
};
if (args[0].length() >= 2) {
PlotSquared.get().getImpromptuUUIDPipeline().getSingle(args[0], (uuid, throwable) -> { PlotSquared.get().getImpromptuUUIDPipeline().getSingle(args[0], (uuid, throwable) -> {
if (throwable instanceof TimeoutException) { if (throwable instanceof TimeoutException) {
// The request timed out
MainUtil.sendMessage(player, Captions.FETCHING_PLAYERS_TIMEOUT); MainUtil.sendMessage(player, Captions.FETCHING_PLAYERS_TIMEOUT);
} else if (uuid != null && !PlotSquared.get().hasPlot(uuid)) { } 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 { } else {
uuidConsumer.accept(uuid); // 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 {
this.visit(player, PlotQuery.newQuery().ownedBy(uuid).whereBasePlot(), null, confirm, whenDone, finalPage);
} }
}); });
} else { } 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; break;
case 0: case 0:
unsortedPre.addAll(PlotSquared.get().getPlots(player)); // /p v
pageConsumer.accept(1); this.visit(player, PlotQuery.newQuery().ownedBy(player), null, confirm, whenDone);
break; break;
default: default:
} }
return CompletableFuture.completedFuture(true); return CompletableFuture.completedFuture(true);
} }
public Collection<Command> tab(PlotPlayer player, String[] args, boolean space) {
final List<Command> completions = new LinkedList<>();
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<Command> commands, final String arg, final int start) {
for (int i = 0; i < 100; 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<Command> 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) {});
}
}
} }

View File

@ -445,6 +445,7 @@ public enum Captions implements Caption {
NOT_VALID_WORLD("$2That is not a valid world (case sensitive)", "Errors"), 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"), NOT_VALID_PLOT_WORLD("$2That is not a valid plot area (case sensitive)", "Errors"),
NO_PLOTS("$2You don't have any plots", "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"), 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"), TILE_ENTITY_CAP_REACHED("$2The total number of tile entities in this chunk may not exceed $1%s", "Errors"),
//</editor-fold> //</editor-fold>
@ -785,6 +786,17 @@ public enum Captions implements Caption {
GENERIC_INVALID_CHOICE("invalid choice", "Generic"), GENERIC_INVALID_CHOICE("invalid choice", "Generic"),
//</editor-fold> //</editor-fold>
//<editor-fold des="Single area">
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 <name>", "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"),
SINGLE_AREA_CREATED("$1The area was created successfully!", "Single"),
//</editor-fold>
/** /**
* Legacy Configuration Conversion * Legacy Configuration Conversion
*/ */

View File

@ -506,7 +506,7 @@ public class Settings extends Config {
@Comment("Settings relating to PlotSquared's GlobalBlockQueue") @Comment("Settings relating to PlotSquared's GlobalBlockQueue")
public static final class QUEUE { 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."}) "Waits (chunk task time / target_time) ticks before completely the next task."})
public static int TARGET_TIME = 65; public static int TARGET_TIME = 65;
} }

View File

@ -195,8 +195,16 @@ public class HybridPlotWorld extends ClassicPlotWorld {
public void setupSchematics() throws SchematicHandler.UnsupportedFormatException { public void setupSchematics() throws SchematicHandler.UnsupportedFormatException {
this.G_SCH = new HashMap<>(); this.G_SCH = new HashMap<>();
this.G_SCH_B = new HashMap<>(); this.G_SCH_B = new HashMap<>();
File root = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(),
// 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()); "schematics/GEN_ROAD_SCHEMATIC/" + this.getWorldName());
}
File schematic1File = new File(root, "sideroad.schem"); File schematic1File = new File(root, "sideroad.schem");
if (!schematic1File.exists()) if (!schematic1File.exists())
schematic1File = new File(root, "sideroad.schematic"); schematic1File = new File(root, "sideroad.schematic");
@ -272,37 +280,8 @@ public class HybridPlotWorld extends ClassicPlotWorld {
(short) (z + shift + oddshift + centerShiftZ), biome); (short) (z + shift + oddshift + centerShiftZ), biome);
} }
} }
/* HashMap<BlockLoc, CompoundTag> items = schematic3.getTiles();
if (!items.isEmpty()) {
this.G_SCH_STATE = new HashMap<>();
outer:
for (Map.Entry<BlockLoc, CompoundTag> 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<Integer, CompoundTag> 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(); PlotSquared.debug(Captions.PREFIX + "&3 - plot schematic: &7" + schematic3File.getPath());
Map<String, Tag> 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;
}
}*/
} }
if (schematic1 == null || schematic2 == null || this.ROAD_WIDTH == 0) { if (schematic1 == null || schematic2 == null || this.ROAD_WIDTH == 0) {
PlotSquared.debug(Captions.PREFIX + "&3 - schematic: &7false"); PlotSquared.debug(Captions.PREFIX + "&3 - schematic: &7false");

View File

@ -1023,7 +1023,7 @@ public abstract class PlotArea {
* @return true if plot signs are allow, false otherwise. * @return true if plot signs are allow, false otherwise.
*/ */
public boolean allowSigns() { public boolean allowSigns() {
return allowSigns; return allowSigns && (this.plots.size() > 1) /* Do not generate signs for single plots */;
} }
/** /**

View File

@ -25,7 +25,10 @@
*/ */
package com.plotsquared.core.plot; 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) { public boolean allowsArea(final PlotArea area) {
return true; return true;
} }
@ -33,4 +36,5 @@ public abstract class PlotFilter {
public boolean allowsPlot(final Plot plot) { public boolean allowsPlot(final Plot plot) {
return true; return true;
} }
} }

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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<PlotArea> getAreas();
/**
* Get all plot areas in a specified region
*
* @param region Region
* @return All areas in the region
*/
@NotNull public abstract Collection<PlotArea> 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;
}
}

View File

@ -25,143 +25,93 @@
*/ */
package com.plotsquared.core.plot.world; package com.plotsquared.core.plot.world;
import com.plotsquared.core.collection.QuadMap;
import com.plotsquared.core.location.Location; import com.plotsquared.core.location.Location;
import com.plotsquared.core.plot.PlotArea; 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.plotsquared.core.util.StringMan;
import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CuboidRegion;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashSet; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
public class DefaultPlotAreaManager implements PlotAreaManager { public class DefaultPlotAreaManager implements PlotAreaManager {
final PlotArea[] noPlotAreas = new PlotArea[0]; final PlotArea[] noPlotAreas = new PlotArea[0];
// All plot areas mapped by world private final Map<String, PlotWorld> plotWorlds = new HashMap<>();
private final HashMap<String, PlotArea[]> plotAreaMap = new HashMap<>();
// All plot areas mapped by position
private final HashMap<String, QuadMap<PlotArea>> plotAreaGrid = new HashMap<>();
private final HashSet<Integer> plotAreaHashCheck = new HashSet<>();
// All plot areas
private PlotArea[] plotAreas = new PlotArea[0];
// Optimization if there are no hash collisions
private boolean plotAreaHasCollision = false;
private String[] worlds = new String[0];
@Override public PlotArea[] getAllPlotAreas() { @Override public PlotArea[] getAllPlotAreas() {
return plotAreas; final Set<PlotArea> area = new HashSet<>();
for (final PlotWorld world : plotWorlds.values()) {
area.addAll(world.getAreas());
}
return area.toArray(new PlotArea[0]);
} }
@Override public PlotArea getApplicablePlotArea(Location location) { @Override @Nullable public PlotArea getApplicablePlotArea(final Location location) {
switch (this.plotAreas.length) { if (location == null) {
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; return null;
} }
int z; final PlotWorld world = this.plotWorlds.get(location.getWorld());
int x; if (world == null) {
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; return null;
default:
QuadMap<PlotArea> search = this.plotAreaGrid.get(location.getWorld());
return search.get(location.getX(), location.getZ());
}
} }
return world.getArea(location);
} }
@Override public void addPlotArea(PlotArea plotArea) { @Override public void addPlotArea(final PlotArea plotArea) {
HashSet<PlotArea> localAreas = PlotWorld world = this.plotWorlds.get(plotArea.getWorldName());
new HashSet<>(Arrays.asList(getPlotAreas(plotArea.getWorldName(), null))); if (world != null) {
HashSet<PlotArea> globalAreas = new HashSet<>(Arrays.asList(plotAreas)); if (world instanceof StandardPlotWorld && world.getAreas().isEmpty()) {
localAreas.add(plotArea); this.plotWorlds.remove(plotArea.getWorldName());
globalAreas.add(plotArea);
this.plotAreas = globalAreas.toArray(new PlotArea[0]);
this.plotAreaMap.put(plotArea.getWorldName(), localAreas.toArray(new PlotArea[0]));
QuadMap<PlotArea> map = this.plotAreaGrid.get(plotArea.getWorldName());
if (map == null) {
map = new QuadMap<PlotArea>(Integer.MAX_VALUE, 0, 0) {
@Override public CuboidRegion getRegion(PlotArea value) {
return value.getRegion();
}
};
this.plotAreaGrid.put(plotArea.getWorldName(), map);
}
map.add(plotArea);
}
@Override public void removePlotArea(PlotArea area) {
ArrayList<PlotArea> 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());
} else { } else {
this.plotAreaMap.put(area.getWorldName(), globalAreas.toArray(new PlotArea[0])); world.addArea(plotArea);
this.plotAreaGrid.get(area.getWorldName()).remove(area); return;
}
}
if (plotArea.getType() != PlotAreaType.PARTIAL) {
world = new StandardPlotWorld(plotArea.getWorldName(), plotArea);
} else {
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) { @Override public PlotArea getPlotArea(final String world, final String id) {
PlotArea[] areas = this.plotAreaMap.get(world); final PlotWorld plotWorld = this.plotWorlds.get(world);
if (areas == null) { if (plotWorld == null) {
return null; return null;
} }
if (areas.length == 1) { final List<PlotArea> areas = new ArrayList<>(plotWorld.getAreas());
return areas[0]; if (areas.size() == 1) {
} else if (id == null) { return areas.get(0);
}
if (id == null) {
return null; return null;
} }
for (PlotArea area : areas) { for (final PlotArea area : areas) {
if (StringMan.isEqual(id, area.getId())) { if (StringMan.isEqual(id, area.getId())) {
return area; return area;
} }
@ -169,103 +119,37 @@ public class DefaultPlotAreaManager implements PlotAreaManager {
return null; return null;
} }
@Override public PlotArea getPlotArea(@NotNull Location location) { @Override public PlotArea getPlotArea(@NotNull final Location location) {
switch (this.plotAreas.length) { return this.getApplicablePlotArea(location);
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<PlotArea> search = this.plotAreaGrid.get(location.getWorld());
return search.get(location.getX(), location.getZ());
}
}
} }
@Override public PlotArea[] getPlotAreas(String world, CuboidRegion region) { @Override public PlotArea[] getPlotAreas(final String world, final CuboidRegion region) {
final PlotWorld plotWorld = this.plotWorlds.get(world);
if (plotWorld == null) {
return noPlotAreas;
}
if (region == null) { if (region == null) {
PlotArea[] areas = this.plotAreaMap.get(world); return plotWorld.getAreas().toArray(new PlotArea[0]);
if (areas == null) {
return noPlotAreas;
}
return areas;
}
QuadMap<PlotArea> areas = this.plotAreaGrid.get(world);
if (areas == null) {
return noPlotAreas;
} else {
Set<PlotArea> found = areas.get(region);
return found.toArray(new PlotArea[0]);
} }
return plotWorld.getAreasInRegion(region).toArray(new PlotArea[0]);
} }
@Override public void addWorld(String worldName) { @Override public void addWorld(final String worldName) {
if (!this.plotAreaHasCollision && !this.plotAreaHashCheck.add(worldName.hashCode())) { PlotWorld world = this.plotWorlds.get(worldName);
this.plotAreaHasCollision = true; if (world != null) {
return;
} }
Set<String> tmp = new LinkedHashSet<>(); // Create a new empty world. When a new area is added
Collections.addAll(tmp, worlds); // the world will be re-recreated with the correct type
tmp.add(worldName); world = new StandardPlotWorld(worldName, null);
worlds = tmp.toArray(new String[0]); this.plotWorlds.put(worldName, world);
} }
@Override public void removeWorld(String worldName) { @Override public void removeWorld(final String worldName) {
Set<String> tmp = new LinkedHashSet<>(); this.plotWorlds.remove(worldName);
Collections.addAll(tmp, worlds);
tmp.remove(worldName);
worlds = tmp.toArray(new String[0]);
} }
@Override public String[] getAllWorlds() { @Override public String[] getAllWorlds() {
return worlds; return this.plotWorlds.keySet().toArray(new String[0]);
} }
} }

View File

@ -29,6 +29,7 @@ import com.plotsquared.core.location.Location;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CuboidRegion;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface PlotAreaManager { public interface PlotAreaManager {
@ -44,7 +45,7 @@ public interface PlotAreaManager {
* @param location The location * @param location The location
* @return An applicable area, or null * @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 * Get the plot area, if there is any, for the given

View File

@ -0,0 +1,116 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* 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 <http://www.gnu.org/licenses/>.
*/
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<PlotArea> areas = new LinkedList<>();
private final Object treeLock = new Object();
private RTree<PlotArea, Geometry> 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) {
if (this.areas.isEmpty()) {
return null;
}
synchronized (this.treeLock) {
final Observable<Entry<PlotArea, Geometry>> 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<PlotArea> 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<PlotArea> getAreasInRegion(@NotNull final CuboidRegion region) {
if (this.areas.isEmpty()) {
return Collections.emptyList();
}
synchronized (this.treeLock) {
final List<PlotArea> 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()));
}
}
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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<PlotArea> getAreas() {
if (this.area == null) {
return Collections.emptyList();
}
return Collections.singletonList(this.area);
}
@Override @NotNull public Collection<PlotArea> getAreasInRegion(@NotNull final CuboidRegion region) {
return this.getAreas();
}
}

View File

@ -52,7 +52,7 @@ public abstract class ChunkManager {
public static void setChunkInPlotArea(RunnableVal<ScopedLocalBlockQueue> force, public static void setChunkInPlotArea(RunnableVal<ScopedLocalBlockQueue> force,
RunnableVal<ScopedLocalBlockQueue> add, String world, BlockVector2 loc) { RunnableVal<ScopedLocalBlockQueue> add, String world, BlockVector2 loc) {
LocalBlockQueue queue = GlobalBlockQueue.IMP.getNewQueue(world, false); 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 blockX = loc.getX() << 4;
int blockZ = loc.getZ() << 4; int blockZ = loc.getZ() << 4;
ScopedLocalBlockQueue scoped = ScopedLocalBlockQueue scoped =

View File

@ -28,6 +28,8 @@ package com.plotsquared.core.util;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.Collection;
/** /**
* This class should be implemented by each platform to allow PlotSquared to interact * This class should be implemented by each platform to allow PlotSquared to interact
* with the world management solution used on the server. * with the world management solution used on the server.
@ -62,4 +64,11 @@ public interface PlatformWorldManager<T> {
*/ */
String getName(); String getName();
/**
* Get the names of all worlds on the server
*
* @return Worlds
*/
Collection<String> getWorlds();
} }

View File

@ -25,9 +25,13 @@
*/ */
package com.plotsquared.core.util; 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.plotsquared.core.plot.Plot;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CuboidRegion;
import org.jetbrains.annotations.NotNull;
public class RegionUtil { public class RegionUtil {
public static CuboidRegion createRegion(int pos1x, int pos2x, int pos1z, int pos2z) { public static CuboidRegion createRegion(int pos1x, int pos2x, int pos1z, int pos2z) {
@ -54,6 +58,12 @@ public class RegionUtil {
.getY() && y <= max.getY(); .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 // Because WE (not fawe) lack this for CuboidRegion
public static boolean intersects(CuboidRegion region, CuboidRegion other) { public static boolean intersects(CuboidRegion region, CuboidRegion other) {
BlockVector3 regionMin = region.getMinimumPoint(); BlockVector3 regionMin = region.getMinimumPoint();

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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());
}
}

View File

@ -0,0 +1,51 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* 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 <http://www.gnu.org/licenses/>.
*/
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.LinkedList;
import java.util.List;
class AreaLimitedPlotProvider implements PlotProvider {
private final Collection<PlotArea> areas;
AreaLimitedPlotProvider(Collection<PlotArea> areas) {
this.areas = areas;
}
@Override public Collection<Plot> getPlots() {
final List<Plot> plots = new LinkedList<>();
for (final PlotArea area : areas) {
plots.addAll(area.getPlots());
}
return plots;
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.util.query;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.expiration.ExpireManager;
import java.util.Collection;
class ExpiredPlotProvider implements PlotProvider {
@Override public Collection<Plot> getPlots() {
return ExpireManager.IMP.getPendingExpired();
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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<Plot> getPlots() {
return Collections.singleton(plot);
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.util.query;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.plot.Plot;
import java.util.Collection;
class GlobalPlotProvider implements PlotProvider {
@Override public Collection<Plot> getPlots() {
return PlotSquared.get().getPlots();
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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<Plot> getPlots() {
return Collections.emptyList();
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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<Plot> plots;
private final int pageSize;
PaginatedPlotResult(@NotNull final List<Plot> 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<Plot> 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);
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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<Plot> {
@Override default boolean test(@NotNull final Plot plot) {
return this.accepts(plot);
}
boolean accepts(@NotNull final Plot plot);
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.util.query;
import com.plotsquared.core.plot.Plot;
import java.util.Collection;
@FunctionalInterface interface PlotProvider {
Collection<Plot> getPlots();
}

View File

@ -0,0 +1,385 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* 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 <http://www.gnu.org/licenses/>.
*/
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 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.Comparator;
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.Stream;
/**
* This represents a plot query, and can be used to
* search for plots matching certain criteria.
* <p>
* The queries can be reused as no results are stored
* in the query itself
*/
public final class PlotQuery {
private final Collection<PlotFilter> filters = new LinkedList<>();
private PlotProvider plotProvider = new GlobalPlotProvider();
private SortingStrategy sortingStrategy = SortingStrategy.NO_SORTING;
private PlotArea priorityArea;
private Comparator<Plot> plotComparator;
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<PlotArea> 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 expired plots
*
* @return The query instance
*/
@NotNull public PlotQuery expiredPlots() {
this.plotProvider = new ExpiredPlotProvider();
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 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
*
* @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<Plot> predicate) {
Preconditions.checkNotNull(predicate, "Predicate may not be null");
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;
}
/**
* Use a custom comparator to sort the results
*
* @param comparator Comparator
* @return The query instance
*/
@NotNull public PlotQuery sorted(@NotNull final Comparator<Plot> 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
*
* @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;
return this;
}
/**
* Get all plots that match the given criteria
*
* @return Matching plots
*/
@NotNull public Stream<Plot> asStream() {
return this.asList().stream();
}
/**
* Get all plots that match the given criteria
*
* @return Matching plots as a mutable
*/
@NotNull public List<Plot> asList() {
final List<Plot> result;
if (this.filters.isEmpty()) {
result = new ArrayList<>(this.plotProvider.getPlots());
} else {
final Collection<Plot> plots = this.plotProvider.getPlots();
result = new ArrayList<>(plots.size());
outer: for (final Plot plot : plots) {
for (final PlotFilter filter : this.filters) {
if (!filter.accepts(plot)) {
continue outer;
}
}
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<UUID, Rating> 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);
} else if (this.sortingStrategy == SortingStrategy.COMPARATOR) {
result.sort(this.plotComparator);
}
return result;
}
/**
* Get all plots that match the given criteria
*
* @return Matching plots as a mutable set
*/
@NotNull public Set<Plot> asSet() {
return new HashSet<>(this.asList());
}
/**
* 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<Plot> asCollection() {
return this.asList();
}
@NotNull private PlotQuery addFilter(@NotNull final PlotFilter filter) {
this.filters.add(filter);
return this;
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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<Plot> predicate;
PredicateFilter(@NotNull final Predicate<Plot> predicate) {
this.predicate = predicate;
}
@Override public boolean accepts(@NotNull final Plot plot) {
return predicate.test(plot);
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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<Plot> getPlots() {
return MainUtil.getPlotsBySearch(this.searchTerm);
}
}

View File

@ -0,0 +1,56 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* 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 <http://www.gnu.org/licenses/>.
*/
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,
/**
* Sort using a comparator
*/
COMPARATOR;
}

View File

@ -28,6 +28,7 @@ is to provide a lag-free and smooth experience.
* [Download](https://www.spigotmc.org/resources/plotsquared-v5.77506/) * [Download](https://www.spigotmc.org/resources/plotsquared-v5.77506/)
* [Discord](https://discord.gg/KxkjDVg) * [Discord](https://discord.gg/KxkjDVg)
* [Wiki](https://wiki.intellectualsites.com/plotsquared/home) * [Wiki](https://wiki.intellectualsites.com/plotsquared/home)
* [Issues](https://issues.intellectualsites.com/projects/ps)
### Developer Resources ### Developer Resources
* [API Documentation](https://wiki.intellectualsites.com/en/plotsquared/developer/development-portal) * [API Documentation](https://wiki.intellectualsites.com/en/plotsquared/developer/development-portal)