Add missing methods to PlotQuery and use PlotQuery in ListCmd

This commit is contained in:
Alexander Söderberg 2020-05-23 23:58:24 +02:00 committed by Alexander Söderberg
parent e912909aad
commit 508fdce704
9 changed files with 364 additions and 107 deletions

View File

@ -26,13 +26,11 @@
package com.plotsquared.core.command;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.PlotSquared.SortType;
import com.plotsquared.core.configuration.CaptionUtility;
import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.Rating;
import com.plotsquared.core.plot.expiration.ExpireManager;
import com.plotsquared.core.plot.flag.implementations.DoneFlag;
import com.plotsquared.core.plot.flag.implementations.PriceFlag;
@ -43,13 +41,14 @@ import com.plotsquared.core.util.MathMan;
import com.plotsquared.core.util.Permissions;
import com.plotsquared.core.util.StringComparison;
import com.plotsquared.core.util.StringMan;
import com.plotsquared.core.util.query.PlotQuery;
import com.plotsquared.core.util.query.SortingStrategy;
import com.plotsquared.core.util.task.RunnableVal3;
import com.plotsquared.core.util.uuid.UUIDHandler;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map.Entry;
import java.util.UUID;
@CommandDeclaration(command = "list",
@ -128,12 +127,13 @@ public class ListCmd extends SubCommand {
}
}
List<Plot> plots = null;
String world = player.getLocation().getWorld();
PlotArea area = player.getApplicablePlotArea();
String arg = args[0].toLowerCase();
boolean sort = true;
PlotQuery query = null;
switch (arg) {
case "mine":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_MINE)) {
@ -141,8 +141,8 @@ public class ListCmd extends SubCommand {
.sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_LIST_MINE);
return false;
}
query = PlotQuery.newQuery().ownedBy(player).whereBasePlot().withSortingStrategy(SortingStrategy.SORT_BY_TEMP);
sort = false;
plots = PlotSquared.get().sortPlotsByTemp(PlotSquared.get().getBasePlots(player));
break;
case "shared":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_SHARED)) {
@ -150,13 +150,8 @@ public class ListCmd extends SubCommand {
Captions.PERMISSION_LIST_SHARED);
return false;
}
plots = new ArrayList<>();
for (Plot plot : PlotSquared.get().getPlots()) {
if (plot.getTrusted().contains(player.getUUID()) || plot.getMembers()
.contains(player.getUUID())) {
plots.add(plot);
}
}
// withMember checks for trusted + members + owner, we don't want the owner part
query = PlotQuery.newQuery().withMember(player.getUUID()).thatPasses(plot -> !plot.isOwnerAbs(player.getUUID()));
break;
case "world":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_WORLD)) {
@ -171,7 +166,7 @@ public class ListCmd extends SubCommand {
world));
return false;
}
plots = new ArrayList<>(PlotSquared.get().getPlots(world));
query = PlotQuery.newQuery().inWorld(world);
break;
case "expired":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_EXPIRED)) {
@ -179,9 +174,11 @@ public class ListCmd extends SubCommand {
Captions.PERMISSION_LIST_EXPIRED);
return false;
}
plots = ExpireManager.IMP == null ?
new ArrayList<Plot>() :
new ArrayList<>(ExpireManager.IMP.getPendingExpired());
if (ExpireManager.IMP == null) {
query = PlotQuery.newQuery().noPlots();
} else {
query = PlotQuery.newQuery().expiredPlots();
}
break;
case "area":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_AREA)) {
@ -196,7 +193,11 @@ public class ListCmd extends SubCommand {
world));
return false;
}
plots = area == null ? new ArrayList<Plot>() : new ArrayList<>(area.getPlots());
if (area == null) {
query = PlotQuery.newQuery().noPlots();
} else {
query = PlotQuery.newQuery().inArea(area);
}
break;
case "all":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_ALL)) {
@ -204,7 +205,7 @@ public class ListCmd extends SubCommand {
.sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_LIST_ALL);
return false;
}
plots = new ArrayList<>(PlotSquared.get().getPlots());
query = PlotQuery.newQuery().allPlots();
break;
case "done":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_DONE)) {
@ -212,23 +213,7 @@ public class ListCmd extends SubCommand {
.sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_LIST_DONE);
return false;
}
plots = new ArrayList<>();
for (Plot plot : PlotSquared.get().getPlots()) {
if (DoneFlag.isDone(plot)) {
plots.add(plot);
}
}
plots.sort((a, b) -> {
String va = a.getFlag(DoneFlag.class);
String vb = b.getFlag(DoneFlag.class);
if (MathMan.isInteger(va)) {
if (MathMan.isInteger(vb)) {
return Integer.parseInt(vb) - Integer.parseInt(va);
}
return -1;
}
return 1;
});
query = PlotQuery.newQuery().allPlots().thatPasses(DoneFlag::isDone).withSortingStrategy(SortingStrategy.SORT_BY_DONE);
sort = false;
break;
case "top":
@ -237,31 +222,7 @@ public class ListCmd extends SubCommand {
.sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_LIST_TOP);
return false;
}
plots = new ArrayList<>(PlotSquared.get().getPlots());
plots.sort((p1, p2) -> {
double v1 = 0;
int p1s = p1.getSettings().getRatings().size();
int p2s = p2.getRatings().size();
if (!p1.getSettings().getRatings().isEmpty()) {
v1 = p1.getRatings().values().stream().mapToDouble(Rating::getAverageRating)
.map(av -> av * av).sum();
v1 /= p1s;
v1 += p1s;
}
double v2 = 0;
if (!p2.getSettings().getRatings().isEmpty()) {
for (Entry<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);
});
query = PlotQuery.newQuery().allPlots().withSortingStrategy(SortingStrategy.SORT_BY_RATING);
sort = false;
break;
case "forsale":
@ -273,12 +234,7 @@ public class ListCmd extends SubCommand {
if (EconHandler.manager == null) {
break;
}
plots = new ArrayList<>();
for (Plot plot : PlotSquared.get().getPlots()) {
if (plot.getFlag(PriceFlag.class) > 0) {
plots.add(plot);
}
}
query = PlotQuery.newQuery().allPlots().thatPasses(plot -> plot.getFlag(PriceFlag.class) > 0);
break;
case "unowned":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_UNOWNED)) {
@ -286,12 +242,7 @@ public class ListCmd extends SubCommand {
Captions.PERMISSION_LIST_UNOWNED);
return false;
}
plots = new ArrayList<>();
for (Plot plot : PlotSquared.get().getPlots()) {
if (plot.getOwner() == null) {
plots.add(plot);
}
}
query = PlotQuery.newQuery().allPlots().thatPasses(plot -> plot.getOwner() == null);
break;
case "unknown":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_UNKNOWN)) {
@ -299,15 +250,12 @@ public class ListCmd extends SubCommand {
Captions.PERMISSION_LIST_UNKNOWN);
return false;
}
plots = new ArrayList<>();
for (Plot plot : PlotSquared.get().getPlots()) {
query = PlotQuery.newQuery().allPlots().thatPasses(plot -> {
if (plot.getOwner() == null) {
continue;
return false;
}
if (UUIDHandler.getName(plot.getOwner()) == null) {
plots.add(plot);
}
}
return UUIDHandler.getName(plot.getOwner()) == null;
});
break;
case "fuzzy":
if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_FUZZY)) {
@ -325,7 +273,7 @@ public class ListCmd extends SubCommand {
} else {
term = StringMan.join(Arrays.copyOfRange(args, 1, args.length), " ");
}
plots = MainUtil.getPlotsBySearch(term);
query = PlotQuery.newQuery().plotsBySearch(term);
sort = false;
break;
default:
@ -343,7 +291,7 @@ public class ListCmd extends SubCommand {
args[0]));
return false;
}
plots = new ArrayList<>(PlotSquared.get().getPlots(args[0]));
query = PlotQuery.newQuery().inWorld(args[0]);
break;
}
UUID uuid = UUIDHandler.getUUID(args[0], null);
@ -360,33 +308,40 @@ public class ListCmd extends SubCommand {
return false;
}
sort = false;
plots = PlotSquared.get().sortPlotsByTemp(PlotSquared.get().getPlots(uuid));
query = PlotQuery.newQuery().ownedBy(uuid).withSortingStrategy(SortingStrategy.SORT_BY_TEMP);
break;
}
}
if (plots == null) {
if (query == null) {
sendMessage(player, Captions.DID_YOU_MEAN,
new StringComparison<>(args[0], new String[] {"mine", "shared", "world", "all"})
.getBestMatch());
return false;
}
if (area != null) {
query.relativeToArea(area);
}
if (sort) {
query.withSortingStrategy(SortingStrategy.SORT_BY_CREATION);
}
final List<Plot> plots = query.asList();
if (plots.isEmpty()) {
MainUtil.sendMessage(player, Captions.FOUND_NO_PLOTS);
return false;
}
displayPlots(player, plots, 12, page, area, args, sort);
displayPlots(player, plots, 12, page, args);
return true;
}
public void displayPlots(final PlotPlayer player, List<Plot> plots, int pageSize, int page,
PlotArea area, String[] args, boolean sort) {
public void displayPlots(final PlotPlayer player, List<Plot> plots, int pageSize, int page, String[] args) {
// Header
plots.removeIf(plot -> !plot.isBasePlot());
if (sort) {
plots = PlotSquared.get().sortPlots(plots, SortType.CREATION_DATE, area);
}
this.paginate(player, plots, pageSize, page,
new RunnableVal3<Integer, Plot, PlotMessage>() {
@Override public void run(Integer i, Plot plot, PlotMessage message) {

View File

@ -29,7 +29,8 @@ import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea;
import java.util.Collection;
import java.util.stream.Stream;
import java.util.LinkedList;
import java.util.List;
class AreaLimitedPlotProvider implements PlotProvider {
@ -39,8 +40,12 @@ class AreaLimitedPlotProvider implements PlotProvider {
this.areas = areas;
}
@Override public Stream<Plot> getPlots() {
return areas.stream().flatMap(area -> area.getPlots().stream());
@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 ExploredPlotProvider implements PlotProvider {
@Override public Collection<Plot> getPlots() {
return ExpireManager.IMP.getPendingExpired();
}
}

View File

@ -28,12 +28,12 @@ package com.plotsquared.core.util.query;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.plot.Plot;
import java.util.stream.Stream;
import java.util.Collection;
class GlobalPlotProvider implements PlotProvider {
@Override public Stream<Plot> getPlots() {
return PlotSquared.get().getPlots().stream();
@Override public Collection<Plot> getPlots() {
return PlotSquared.get().getPlots();
}
}

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

@ -27,10 +27,10 @@ package com.plotsquared.core.util.query;
import com.plotsquared.core.plot.Plot;
import java.util.stream.Stream;
import java.util.Collection;
@FunctionalInterface interface PlotProvider {
Stream<Plot> getPlots();
Collection<Plot> getPlots();
}

View File

@ -30,16 +30,21 @@ import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.Rating;
import com.plotsquared.core.plot.flag.implementations.DoneFlag;
import com.plotsquared.core.util.MathMan;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
@ -51,8 +56,10 @@ import java.util.stream.Stream;
*/
public final class PlotQuery {
private PlotProvider plotProvider = new GlobalPlotProvider();
private final Collection<PlotFilter> filters = new LinkedList<>();
private PlotProvider plotProvider = new GlobalPlotProvider();
private SortingStrategy sortingStrategy = SortingStrategy.NO_SORTING;
private PlotArea priorityArea;
private PlotQuery() {
}
@ -103,6 +110,47 @@ public final class PlotQuery {
return this;
}
/**
* Query for expired plots
*
* @return The query instance
*/
@NotNull public PlotQuery expiredPlots() {
this.plotProvider = new ExploredPlotProvider();
return this;
}
/**
* Query for all plots
*
* @return The query instance
*/
@NotNull public PlotQuery allPlots() {
this.plotProvider = new GlobalPlotProvider();
return this;
}
/**
* Don't query at all
*
* @return The query instance
*/
@NotNull public PlotQuery noPlots() {
this.plotProvider = new NullProvider();
return this;
}
/**
* Query for plots based on a search term
*
* @return The query instance
*/
@NotNull public PlotQuery plotsBySearch(@NotNull final String searchTerm) {
Preconditions.checkNotNull(searchTerm, "Search term may not be null");
this.plotProvider = new SearchPlotProvider(searchTerm);
return this;
}
/**
* Query for base plots only
*
@ -167,17 +215,32 @@ public final class PlotQuery {
return this.addFilter(new PredicateFilter(predicate));
}
/**
* Specify the sorting strategy that will decide how to
* sort the results. This only matters if you use {@link #asList()}
*
* @param strategy Strategy
* @return The query instance
*/
@NotNull public PlotQuery withSortingStrategy(@NotNull final SortingStrategy strategy) {
Preconditions.checkNotNull(strategy, "Strategy may not be null");
this.sortingStrategy = strategy;
return this;
}
@NotNull public PlotQuery relativeToArea(@NotNull final PlotArea plotArea) {
Preconditions.checkNotNull(plotArea, "Area may not be null");
this.priorityArea = plotArea;
return this;
}
/**
* Get all plots that match the given criteria
*
* @return Matching plots
*/
@NotNull public Stream<Plot> asStream() {
Stream<Plot> plots = this.plotProvider.getPlots();
for (final PlotFilter filter : this.filters) {
plots = plots.filter(filter);
}
return plots;
return this.asList().stream();
}
/**
@ -186,7 +249,65 @@ public final class PlotQuery {
* @return Matching plots as an immutable list
*/
@NotNull public List<Plot> asList() {
return Collections.unmodifiableList(this.asStream().collect(Collectors.toList()));
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());
for (final Plot plot : plots) {
for (final PlotFilter filter : this.filters) {
if (filter.accepts(plot)) {
result.add(plot);
}
}
}
}
if (this.sortingStrategy == SortingStrategy.NO_SORTING) {
return result;
} else if (this.sortingStrategy == SortingStrategy.SORT_BY_TEMP) {
return PlotSquared.get().sortPlotsByTemp(result);
} else if (this.sortingStrategy == SortingStrategy.SORT_BY_DONE) {
result.sort((a, b) -> {
String va = a.getFlag(DoneFlag.class);
String vb = b.getFlag(DoneFlag.class);
if (MathMan.isInteger(va)) {
if (MathMan.isInteger(vb)) {
return Integer.parseInt(vb) - Integer.parseInt(va);
}
return -1;
}
return 1;
});
} else if (this.sortingStrategy == SortingStrategy.SORT_BY_RATING) {
result.sort((p1, p2) -> {
double v1 = 0;
int p1s = p1.getSettings().getRatings().size();
int p2s = p2.getRatings().size();
if (!p1.getSettings().getRatings().isEmpty()) {
v1 = p1.getRatings().values().stream().mapToDouble(Rating::getAverageRating)
.map(av -> av * av).sum();
v1 /= p1s;
v1 += p1s;
}
double v2 = 0;
if (!p2.getSettings().getRatings().isEmpty()) {
for (Map.Entry<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);
}
return result;
}
/**
@ -195,7 +316,7 @@ public final class PlotQuery {
* @return Matching plots as an immutable set
*/
@NotNull public Set<Plot> asSet() {
return Collections.unmodifiableSet(this.asStream().collect(Collectors.toSet()));
return new HashSet<>(this.asList());
}
/**

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,52 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* PlotSquared plot management system for Minecraft
* Copyright (C) 2020 IntellectualSites
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <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
}