result = this.getNames(Collections.singletonList(uuid));
+ if (result.isEmpty()) {
+ continue;
+ }
+ results.add(result.get(0));
+ }
+ } else if (uuids.size() == 1) {
+ PlotSquared.debug(Captions.PREFIX + "(UUID) Found invalid UUID: " + uuids.get(0));
+ }
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
diff --git a/Core/src/main/java/com/plotsquared/core/IPlotMain.java b/Core/src/main/java/com/plotsquared/core/IPlotMain.java
index eb70402f6..a38045acb 100644
--- a/Core/src/main/java/com/plotsquared/core/IPlotMain.java
+++ b/Core/src/main/java/com/plotsquared/core/IPlotMain.java
@@ -35,6 +35,7 @@ import com.plotsquared.core.util.ChatManager;
import com.plotsquared.core.util.ChunkManager;
import com.plotsquared.core.util.EconHandler;
import com.plotsquared.core.util.InventoryUtil;
+import com.plotsquared.core.util.PermHandler;
import com.plotsquared.core.util.PlatformWorldManager;
import com.plotsquared.core.util.PlayerManager;
import com.plotsquared.core.util.RegionManager;
@@ -174,11 +175,18 @@ public interface IPlotMain extends ILogger {
boolean initWorldEdit();
/**
- * Gets the economy provider.
+ * Gets the economy provider, if there is one
*
* @return the PlotSquared economy manager
*/
- EconHandler getEconomyHandler();
+ @Nullable EconHandler getEconomyHandler();
+
+ /**
+ * Gets the permission provider, if there is one
+ *
+ * @return the PlotSquared permission manager
+ */
+ @Nullable PermHandler getPermissionHandler();
/**
* Gets the {@link QueueProvider} class.
diff --git a/Core/src/main/java/com/plotsquared/core/PlotSquared.java b/Core/src/main/java/com/plotsquared/core/PlotSquared.java
index b213460be..25e62db2a 100644
--- a/Core/src/main/java/com/plotsquared/core/PlotSquared.java
+++ b/Core/src/main/java/com/plotsquared/core/PlotSquared.java
@@ -154,12 +154,10 @@ public class PlotSquared {
public File styleFile;
public File configFile;
public File worldsFile;
- public File commandsFile;
public File translationFile;
public YamlConfiguration style;
public YamlConfiguration worlds;
public YamlConfiguration storage;
- public YamlConfiguration commands;
// Temporary hold the plots/clusters before the worlds load
public HashMap> clusters_tmp;
public HashMap> plots_tmp;
@@ -258,6 +256,7 @@ public class PlotSquared {
if (Settings.Enabled_Components.CHUNK_PROCESSOR) {
this.IMP.registerChunkProcessor();
}
+ startExpiryTasks();
// Create Event utility class
eventDispatcher = new EventDispatcher();
// create Hybrid utility class
@@ -300,8 +299,7 @@ public class PlotSquared {
}
// Economy
if (Settings.Enabled_Components.ECONOMY) {
- TaskManager
- .runTask(() -> EconHandler.manager = PlotSquared.this.IMP.getEconomyHandler());
+ TaskManager.runTask(() -> EconHandler.initializeEconHandler());
}
if (Settings.Enabled_Components.COMPONENT_PRESETS) {
diff --git a/Core/src/main/java/com/plotsquared/core/command/Alias.java b/Core/src/main/java/com/plotsquared/core/command/Alias.java
index a10bf8a6e..59c0da49c 100644
--- a/Core/src/main/java/com/plotsquared/core/command/Alias.java
+++ b/Core/src/main/java/com/plotsquared/core/command/Alias.java
@@ -33,17 +33,24 @@ import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.MathMan;
import com.plotsquared.core.util.Permissions;
+import com.plotsquared.core.util.query.PlotQuery;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
import java.util.concurrent.TimeoutException;
-@CommandDeclaration(command = "setalias",
+@CommandDeclaration(command = "alias",
permission = "plots.alias",
description = "Set the plot name",
usage = "/plot alias ",
- aliases = {"alias", "sa", "name", "rename", "setname", "seta", "nameplot"},
+ aliases = {"setalias", "sa", "name", "rename", "setname", "seta", "nameplot"},
category = CommandCategory.SETTINGS,
requiredType = RequiredType.PLAYER)
public class Alias extends SubCommand {
+ private static final Command SET_COMMAND = new Command(null, false, "set", null, RequiredType.NONE, null) {};
+ private static final Command REMOVE_COMMAND = new Command(null, false, "remove", null, RequiredType.NONE, null) {};
@Override public boolean onCommand(PlotPlayer> player, String[] args) {
@@ -63,13 +70,11 @@ public class Alias extends SubCommand {
return false;
}
- if (!plot.isOwner(player.getUUID())) {
- MainUtil.sendMessage(player, Captions.NO_PLOT_PERMS);
- return false;
- }
-
boolean result = false;
+ boolean owner = plot.isOwner(player.getUUID());
+ boolean permission;
+ boolean admin;
switch (args[0].toLowerCase()) {
case "set":
if (args.length != 2) {
@@ -77,18 +82,34 @@ public class Alias extends SubCommand {
return false;
}
- if (canExecuteCommand(player, Captions.PERMISSION_ALIAS_SET, false)
- || canExecuteCommand(player, Captions.PERMISSION_ALIAS_SET_OBSOLETE, false)) {
+ permission = isPermitted(player, Captions.PERMISSION_ALIAS_SET)
+ || isPermitted(player, Captions.PERMISSION_ALIAS_SET_OBSOLETE);
+ admin = isPermitted(player, Captions.PERMISSION_ADMIN_ALIAS_SET);
+ if (!admin && !owner) {
+ MainUtil.sendMessage(player, Captions.NO_PLOT_PERMS);
+ return false;
+ }
+ if (permission) { // is either admin or owner
setAlias(player, plot, args[1]);
return true;
} else {
- MainUtil.sendMessage(player, Captions.NO_PERMISSION);
+ MainUtil.sendMessage(player, Captions.NO_PERMISSION,
+ Captions.PERMISSION_ALIAS_SET.getTranslated());
}
break;
case "remove":
- if (canExecuteCommand(player, Captions.PERMISSION_ALIAS_REMOVE, true)) {
+ permission = isPermitted(player, Captions.PERMISSION_ALIAS_REMOVE);
+ admin = isPermitted(player, Captions.PERMISSION_ADMIN_ALIAS_REMOVE);
+ if (!admin && !owner) {
+ MainUtil.sendMessage(player, Captions.NO_PLOT_PERMS);
+ return false;
+ }
+ if (permission) {
result = removeAlias(player, plot);
+ } else {
+ MainUtil.sendMessage(player, Captions.NO_PERMISSION,
+ Captions.PERMISSION_ALIAS_REMOVE.getTranslated());
}
break;
default:
@@ -99,6 +120,20 @@ public class Alias extends SubCommand {
return result;
}
+ @Override
+ public Collection tab(PlotPlayer player, String[] args, boolean space) {
+ final List commands = new ArrayList<>(2);
+ if (args.length == 1) {
+ if ("set".startsWith(args[0])) {
+ commands.add(SET_COMMAND);
+ }
+ if ("remove".startsWith(args[0])) {
+ commands.add(REMOVE_COMMAND);
+ }
+ return commands;
+ }
+ return Collections.emptySet();
+ }
private void setAlias(PlotPlayer player, Plot plot, String alias) {
if (alias.isEmpty()) {
@@ -110,11 +145,11 @@ public class Alias extends SubCommand {
} else if (MathMan.isInteger(alias)) {
Captions.NOT_VALID_VALUE.send(player);
} else {
- for (Plot p : PlotSquared.get().getPlots(plot.getArea())) {
- if (p.getAlias().equalsIgnoreCase(alias)) {
- MainUtil.sendMessage(player, Captions.ALIAS_IS_TAKEN);
- return;
- }
+ if (PlotQuery.newQuery().inArea(plot.getArea())
+ .withAlias(alias)
+ .anyMatch()) {
+ MainUtil.sendMessage(player, Captions.ALIAS_IS_TAKEN);
+ return;
}
PlotSquared.get().getImpromptuUUIDPipeline().getSingle(alias, ((uuid, throwable) -> {
if (throwable instanceof TimeoutException) {
@@ -130,19 +165,13 @@ public class Alias extends SubCommand {
}
}
- private boolean removeAlias(PlotPlayer player, Plot plot) {
+ private boolean removeAlias(PlotPlayer> player, Plot plot) {
plot.setAlias(null);
MainUtil.sendMessage(player, Captions.ALIAS_REMOVED.getTranslated());
return true;
}
- private boolean canExecuteCommand(PlotPlayer player, Captions caption, boolean sendMessage) {
- if (!Permissions.hasPermission(player, caption)) {
- if (sendMessage) {
- MainUtil.sendMessage(player, Captions.NO_PERMISSION);
- }
- return false;
- }
- return true;
+ private boolean isPermitted(PlotPlayer> player, Captions caption) {
+ return Permissions.hasPermission(player, caption);
}
}
diff --git a/Core/src/main/java/com/plotsquared/core/command/Auto.java b/Core/src/main/java/com/plotsquared/core/command/Auto.java
index 9658556d9..4c75de3f8 100644
--- a/Core/src/main/java/com/plotsquared/core/command/Auto.java
+++ b/Core/src/main/java/com/plotsquared/core/command/Auto.java
@@ -157,9 +157,9 @@ public class Auto extends SubCommand {
@Override public boolean onCommand(final PlotPlayer> player, String[] args) {
PlotArea plotarea = player.getApplicablePlotArea();
if (plotarea == null) {
- if (EconHandler.manager != null) {
+ if (EconHandler.getEconHandler() != null) {
for (PlotArea area : PlotSquared.get().getPlotAreaManager().getAllPlotAreas()) {
- if (EconHandler.manager
+ if (EconHandler.getEconHandler()
.hasPermission(area.getWorldName(), player.getName(), "plots.auto")) {
if (plotarea != null) {
plotarea = null;
@@ -253,18 +253,18 @@ public class Auto extends SubCommand {
return true;
}
}
- if (EconHandler.manager != null && plotarea.useEconomy()) {
+ if (EconHandler.getEconHandler() != null && plotarea.useEconomy()) {
Expression costExp = plotarea.getPrices().get("claim");
double cost = costExp.evaluate((double) (Settings.Limit.GLOBAL ?
player.getPlotCount() :
player.getPlotCount(plotarea.getWorldName())));
cost = (size_x * size_z) * cost;
if (cost > 0d) {
- if (!force && EconHandler.manager.getMoney(player) < cost) {
+ if (!force && EconHandler.getEconHandler().getMoney(player) < cost) {
sendMessage(player, Captions.CANNOT_AFFORD_PLOT, "" + cost);
return true;
}
- EconHandler.manager.withdrawMoney(player, cost);
+ EconHandler.getEconHandler().withdrawMoney(player, cost);
sendMessage(player, Captions.REMOVED_BALANCE, cost + "");
}
}
diff --git a/Core/src/main/java/com/plotsquared/core/command/Buy.java b/Core/src/main/java/com/plotsquared/core/command/Buy.java
index 036e2412f..337801385 100644
--- a/Core/src/main/java/com/plotsquared/core/command/Buy.java
+++ b/Core/src/main/java/com/plotsquared/core/command/Buy.java
@@ -58,7 +58,7 @@ public class Buy extends Command {
RunnableVal3 confirm,
final RunnableVal2 whenDone) {
- check(EconHandler.manager, Captions.ECON_DISABLED);
+ check(EconHandler.getEconHandler(), Captions.ECON_DISABLED);
final Plot plot;
if (args.length != 0) {
checkTrue(args.length == 1, Captions.COMMAND_SYNTAX, getUsage());
@@ -82,7 +82,7 @@ public class Buy extends Command {
confirm.run(this, () -> {
Captions.REMOVED_BALANCE.send(player, price);
- EconHandler.manager.depositMoney(PlotSquared.imp().getPlayerManager().getOfflinePlayer(plot.getOwnerAbs()), price);
+ EconHandler.getEconHandler().depositMoney(PlotSquared.imp().getPlayerManager().getOfflinePlayer(plot.getOwnerAbs()), price);
PlotPlayer owner = PlotSquared.imp().getPlayerManager().getPlayerIfExists(plot.getOwnerAbs());
if (owner != null) {
diff --git a/Core/src/main/java/com/plotsquared/core/command/Claim.java b/Core/src/main/java/com/plotsquared/core/command/Claim.java
index 6dcda8c43..2271eaa67 100644
--- a/Core/src/main/java/com/plotsquared/core/command/Claim.java
+++ b/Core/src/main/java/com/plotsquared/core/command/Claim.java
@@ -109,14 +109,14 @@ public class Claim extends SubCommand {
}
}
}
- if ((EconHandler.manager != null) && area.useEconomy() && !force) {
+ if ((EconHandler.getEconHandler() != null) && area.useEconomy() && !force) {
Expression costExr = area.getPrices().get("claim");
double cost = costExr.evaluate((double) currentPlots);
if (cost > 0d) {
- if (EconHandler.manager.getMoney(player) < cost) {
+ if (EconHandler.getEconHandler().getMoney(player) < cost) {
return sendMessage(player, Captions.CANNOT_AFFORD_PLOT, "" + cost);
}
- EconHandler.manager.withdrawMoney(player, cost);
+ EconHandler.getEconHandler().withdrawMoney(player, cost);
sendMessage(player, Captions.REMOVED_BALANCE, cost + "");
}
}
diff --git a/Core/src/main/java/com/plotsquared/core/command/Command.java b/Core/src/main/java/com/plotsquared/core/command/Command.java
index 7238d4566..194fc48a4 100644
--- a/Core/src/main/java/com/plotsquared/core/command/Command.java
+++ b/Core/src/main/java/com/plotsquared/core/command/Command.java
@@ -25,9 +25,7 @@
*/
package com.plotsquared.core.command;
-import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Captions;
-import com.plotsquared.core.configuration.file.YamlConfiguration;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.message.PlotMessage;
import com.plotsquared.core.util.MainUtil;
@@ -40,7 +38,6 @@ import com.plotsquared.core.util.task.RunnableVal3;
import lombok.SneakyThrows;
import org.jetbrains.annotations.NotNull;
-import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
@@ -190,36 +187,16 @@ public abstract class Command {
this.permission = declaration.permission();
this.required = declaration.requiredType();
this.category = declaration.category();
+
List aliasOptions = new ArrayList<>();
aliasOptions.add(this.id);
aliasOptions.addAll(Arrays.asList(declaration.aliases()));
- HashMap options = new HashMap<>();
- options.put("aliases", aliasOptions);
- options.put("description", declaration.description());
- options.put("usage", declaration.usage());
- options.put("confirmation", declaration.confirmation());
- boolean set = false;
- YamlConfiguration commands =
- PlotSquared.get() == null ? new YamlConfiguration() : PlotSquared.get().commands;
- for (Map.Entry entry : options.entrySet()) {
- String key = this.getFullId() + "." + entry.getKey();
- if (!commands.contains(key)) {
- commands.set(key, entry.getValue());
- set = true;
- }
- }
- if (set && PlotSquared.get() != null) {
- try {
- commands.save(PlotSquared.get().commandsFile);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- this.aliases = commands.getStringList(this.getFullId() + ".aliases");
- this.description = commands.getString(this.getFullId() + ".description");
- this.usage = commands.getString(this.getFullId() + ".usage");
- this.confirmation = commands.getBoolean(this.getFullId() + ".confirmation");
+ this.aliases = aliasOptions;
+ this.description = declaration.description();
+ this.usage = declaration.usage();
+ this.confirmation = declaration.confirmation();
+
if (this.parent != null) {
this.parent.register(this);
}
diff --git a/Core/src/main/java/com/plotsquared/core/command/DebugExec.java b/Core/src/main/java/com/plotsquared/core/command/DebugExec.java
index 52bb92069..7447b625a 100644
--- a/Core/src/main/java/com/plotsquared/core/command/DebugExec.java
+++ b/Core/src/main/java/com/plotsquared/core/command/DebugExec.java
@@ -171,7 +171,7 @@ public class DebugExec extends SubCommand {
this.scope.put("BlockManager", WorldUtil.IMP);
this.scope.put("SetupUtils", SetupUtils.manager);
this.scope.put("EventUtil", PlotSquared.get().getEventDispatcher());
- this.scope.put("EconHandler", EconHandler.manager);
+ this.scope.put("EconHandler", EconHandler.getEconHandler());
this.scope.put("DBFunc", DBFunc.dbManager);
this.scope.put("HybridUtils", HybridUtils.manager);
this.scope.put("IMP", PlotSquared.get().IMP);
diff --git a/Core/src/main/java/com/plotsquared/core/command/Delete.java b/Core/src/main/java/com/plotsquared/core/command/Delete.java
index 6d8ea243e..5f8178e06 100644
--- a/Core/src/main/java/com/plotsquared/core/command/Delete.java
+++ b/Core/src/main/java/com/plotsquared/core/command/Delete.java
@@ -86,11 +86,11 @@ public class Delete extends SubCommand {
final long start = System.currentTimeMillis();
boolean result = plot.deletePlot(() -> {
plot.removeRunning();
- if ((EconHandler.manager != null) && plotArea.useEconomy()) {
+ if ((EconHandler.getEconHandler() != null) && plotArea.useEconomy()) {
Expression valueExr = plotArea.getPrices().get("sell");
double value = plots.size() * valueExr.evaluate((double) currentPlots);
if (value > 0d) {
- EconHandler.manager.depositMoney(player, value);
+ EconHandler.getEconHandler().depositMoney(player, value);
sendMessage(player, Captions.ADDED_BALANCE, String.valueOf(value));
}
}
diff --git a/Core/src/main/java/com/plotsquared/core/command/HomeCommand.java b/Core/src/main/java/com/plotsquared/core/command/HomeCommand.java
new file mode 100644
index 000000000..38942ad11
--- /dev/null
+++ b/Core/src/main/java/com/plotsquared/core/command/HomeCommand.java
@@ -0,0 +1,208 @@
+/*
+ * _____ _ _ _____ _
+ * | __ \| | | | / ____| | |
+ * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
+ * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
+ * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
+ * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
+ * | |
+ * |_|
+ * PlotSquared plot management system for Minecraft
+ * Copyright (C) 2020 IntellectualSites
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package com.plotsquared.core.command;
+
+import com.plotsquared.core.PlotSquared;
+import com.plotsquared.core.configuration.Captions;
+import com.plotsquared.core.events.TeleportCause;
+import com.plotsquared.core.player.PlotPlayer;
+import com.plotsquared.core.plot.Plot;
+import com.plotsquared.core.plot.PlotArea;
+import com.plotsquared.core.plot.PlotId;
+import com.plotsquared.core.util.MainUtil;
+import com.plotsquared.core.util.MathMan;
+import com.plotsquared.core.util.Permissions;
+import com.plotsquared.core.util.TabCompletions;
+import com.plotsquared.core.util.query.PlotQuery;
+import com.plotsquared.core.util.query.SortingStrategy;
+import com.plotsquared.core.util.task.RunnableVal2;
+import com.plotsquared.core.util.task.RunnableVal3;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+@CommandDeclaration(command = "home",
+ description = "Teleport to your plot(s)",
+ permission = "plots.home",
+ usage = "/plot home [||| | ]",
+ aliases = {"h"},
+ requiredType = RequiredType.PLAYER,
+ category = CommandCategory.TELEPORT)
+public class HomeCommand extends Command {
+ public HomeCommand() {
+ super(MainCommand.getInstance(), true);
+ }
+
+ private void home(@NotNull final PlotPlayer> player,
+ @NotNull final PlotQuery query, final int page,
+ final RunnableVal3 confirm,
+ final RunnableVal2 whenDone) {
+ List plots = query.asList();
+ if (plots.isEmpty()) {
+ Captions.FOUND_NO_PLOTS.send(player);
+ return;
+ } else if (plots.size() < page) {
+ MainUtil.sendMessage(player,
+ String.format(Captions.NUMBER_NOT_IN_RANGE.getTranslated(), "1", plots.size()));
+ return;
+ }
+ Plot plot = plots.get(page - 1);
+ confirm.run(this, () -> plot.teleportPlayer(player, TeleportCause.COMMAND, result -> {
+ if (result) {
+ whenDone.run(this, CommandResult.SUCCESS);
+ } else {
+ whenDone.run(HomeCommand.this, CommandResult.FAILURE);
+ }
+ }), () -> whenDone.run(HomeCommand.this, CommandResult.FAILURE));
+ }
+
+ @NotNull private PlotQuery query(@NotNull final PlotPlayer> player) {
+ // everything plots need to have in common here
+ return PlotQuery.newQuery().ownedBy(player);
+ }
+
+ @Override public CompletableFuture execute(PlotPlayer> player, String[] args,
+ RunnableVal3 confirm,
+ RunnableVal2 whenDone) throws CommandException {
+ // /plot home (or page, whatever it's called)
+ // /plot home
+ // /plot home <[area;]x;y>
+ // /plot home
+ // /plot home
+ if (!Permissions.hasPermission(player, Captions.PERMISSION_VISIT_OWNED) && !Permissions
+ .hasPermission(player, Captions.PERMISSION_HOME)) {
+ Captions.NO_PERMISSION.send(player, Captions.PERMISSION_VISIT_OWNED);
+ return CompletableFuture.completedFuture(false);
+ }
+ if (args.length > 2) {
+ Captions.COMMAND_SYNTAX.send(player, getUsage());
+ return CompletableFuture.completedFuture(false);
+ }
+ PlotQuery query = query(player);
+ int page = 1; // page = index + 1
+ String identifier;
+ boolean basePlotOnly = true;
+ switch (args.length) {
+ case 1:
+ identifier = args[0];
+ if (MathMan.isInteger(identifier)) {
+ try {
+ page = Integer.parseInt(identifier);
+ } catch (NumberFormatException ignored) {
+ Captions.NOT_A_NUMBER.send(player, identifier);
+ return CompletableFuture.completedFuture(false);
+ }
+ query.withSortingStrategy(SortingStrategy.SORT_BY_CREATION);
+ break;
+ }
+ // either plot id or alias
+ Plot fromId = MainUtil.getPlotFromString(player, identifier, false);
+ if (fromId != null && fromId.isOwner(player.getUUID())) {
+ // it was a valid plot id
+ basePlotOnly = false;
+ query.withPlot(fromId);
+ break;
+ }
+ // it wasn't a valid plot id, trying to find plot by alias
+ query.withAlias(identifier);
+ break;
+ case 2:
+ // we assume args[0] is a plot area and args[1] an identifier
+ PlotArea plotArea = PlotSquared.get().getPlotAreaByString(args[0]);
+ identifier = args[1];
+ if (plotArea == null) {
+ // invalid command, therefore no plots
+ query.noPlots();
+ break;
+ }
+ query.inArea(plotArea);
+ if (MathMan.isInteger(identifier)) {
+ // identifier is a page number
+ try {
+ page = Integer.parseInt(identifier);
+ } catch (NumberFormatException ignored) {
+ Captions.NOT_A_NUMBER.send(player, identifier);
+ return CompletableFuture.completedFuture(false);
+ }
+ query.withSortingStrategy(SortingStrategy.SORT_BY_CREATION);
+ break;
+ }
+ // identifier needs to be a plot id then
+ PlotId id = PlotId.fromStringOrNull(identifier);
+ if (id == null) {
+ // invalid command, therefore no plots
+ query.noPlots();
+ break;
+ }
+ // we can try to get this plot
+ Plot plot = plotArea.getPlot(id);
+ if (plot == null) {
+ query.noPlots();
+ break;
+ }
+ // as the query already filters by owner, this is fine
+ basePlotOnly = false;
+ query.withPlot(plot);
+ break;
+ case 0:
+ query.withSortingStrategy(SortingStrategy.SORT_BY_CREATION);
+ break;
+ }
+ if (basePlotOnly) {
+ query.whereBasePlot();
+ }
+ home(player, query, page, confirm, whenDone);
+ return CompletableFuture.completedFuture(true);
+ }
+
+ @Override
+ public Collection tab(PlotPlayer player, String[] args, boolean space) {
+ final List completions = new ArrayList<>();
+ switch (args.length - 1) {
+ case 0:
+ completions.addAll(
+ TabCompletions.completeAreas(args[0]));
+ if (args[0].isEmpty()) {
+ // if no input is given, only suggest 1 - 3
+ completions.addAll(
+ TabCompletions.asCompletions("1", "2", "3"));
+ break;
+ }
+ // complete more numbers from the already given input
+ completions.addAll(
+ TabCompletions.completeNumbers(args[0], 10, 999));
+ break;
+ case 1:
+ completions.addAll(
+ TabCompletions.completeNumbers(args[1], 10, 999));
+ break;
+ }
+ return completions;
+ }
+}
diff --git a/Core/src/main/java/com/plotsquared/core/command/ListCmd.java b/Core/src/main/java/com/plotsquared/core/command/ListCmd.java
index 811eb88a7..a08de0cd0 100644
--- a/Core/src/main/java/com/plotsquared/core/command/ListCmd.java
+++ b/Core/src/main/java/com/plotsquared/core/command/ListCmd.java
@@ -71,7 +71,7 @@ public class ListCmd extends SubCommand {
private String[] getArgumentList(PlotPlayer player) {
List args = new ArrayList<>();
- if (EconHandler.manager != null && Permissions
+ if (EconHandler.getEconHandler() != null && Permissions
.hasPermission(player, Captions.PERMISSION_LIST_FOR_SALE)) {
args.add("forsale");
}
@@ -264,7 +264,7 @@ public class ListCmd extends SubCommand {
Captions.PERMISSION_LIST_FOR_SALE);
return false;
}
- if (EconHandler.manager == null) {
+ if (EconHandler.getEconHandler() == null) {
break;
}
plotConsumer.accept(PlotQuery.newQuery().allPlots().thatPasses(plot -> plot.getFlag(PriceFlag.class) > 0));
@@ -404,7 +404,7 @@ public class ListCmd extends SubCommand {
@Override public Collection tab(PlotPlayer player, String[] args, boolean space) {
final List completions = new LinkedList<>();
- if (EconHandler.manager != null && Permissions
+ if (EconHandler.getEconHandler() != null && Permissions
.hasPermission(player, Captions.PERMISSION_LIST_FOR_SALE)) {
completions.add("forsale");
}
diff --git a/Core/src/main/java/com/plotsquared/core/command/MainCommand.java b/Core/src/main/java/com/plotsquared/core/command/MainCommand.java
index 6e1151c4c..0df008815 100644
--- a/Core/src/main/java/com/plotsquared/core/command/MainCommand.java
+++ b/Core/src/main/java/com/plotsquared/core/command/MainCommand.java
@@ -77,6 +77,7 @@ public class MainCommand extends Command {
new RegenAllRoads();
new Claim();
new Auto();
+ new HomeCommand();
new Visit();
new Set();
new Clear();
@@ -164,14 +165,14 @@ public class MainCommand extends Command {
public void run(final Command cmd, final Runnable success, final Runnable failure) {
if (cmd.hasConfirmation(player)) {
CmdConfirm.addPending(player, cmd.getUsage(), () -> {
- if (EconHandler.manager != null) {
+ if (EconHandler.getEconHandler() != null) {
PlotArea area = player.getApplicablePlotArea();
if (area != null) {
Expression priceEval =
area.getPrices().get(cmd.getFullId());
Double price = priceEval != null ? priceEval.evaluate(0d) : 0d;
if (price != null
- && EconHandler.manager.getMoney(player) < price) {
+ && EconHandler.getEconHandler().getMoney(player) < price) {
if (failure != null) {
failure.run();
}
@@ -185,12 +186,12 @@ public class MainCommand extends Command {
});
return;
}
- if (EconHandler.manager != null) {
+ if (EconHandler.getEconHandler() != null) {
PlotArea area = player.getApplicablePlotArea();
if (area != null) {
Expression priceEval = area.getPrices().get(cmd.getFullId());
Double price = priceEval != null ? priceEval.evaluate(0d) : 0d;
- if (price != 0d && EconHandler.manager.getMoney(player) < price) {
+ if (price != 0d && EconHandler.getEconHandler().getMoney(player) < price) {
if (failure != null) {
failure.run();
}
@@ -252,14 +253,14 @@ public class MainCommand extends Command {
if ("f".equals(args[0].substring(1))) {
confirm = new RunnableVal3() {
@Override public void run(Command cmd, Runnable success, Runnable failure) {
- if (EconHandler.manager != null) {
+ if (EconHandler.getEconHandler() != null) {
PlotArea area = player.getApplicablePlotArea();
if (area != null) {
Expression priceEval =
area.getPrices().get(cmd.getFullId());
Double price = priceEval != null ? priceEval.evaluate(0d) : 0d;
if (price != 0d
- && EconHandler.manager.getMoney(player) < price) {
+ && EconHandler.getEconHandler().getMoney(player) < price) {
if (failure != null) {
failure.run();
}
diff --git a/Core/src/main/java/com/plotsquared/core/command/Merge.java b/Core/src/main/java/com/plotsquared/core/command/Merge.java
index 962b48163..33754c4b8 100644
--- a/Core/src/main/java/com/plotsquared/core/command/Merge.java
+++ b/Core/src/main/java/com/plotsquared/core/command/Merge.java
@@ -156,8 +156,8 @@ public class Merge extends SubCommand {
return true;
}
if (plot.autoMerge(Direction.ALL, maxSize, uuid, terrain)) {
- if (EconHandler.manager != null && plotArea.useEconomy() && price > 0d) {
- EconHandler.manager.withdrawMoney(player, price);
+ if (EconHandler.getEconHandler() != null && plotArea.useEconomy() && price > 0d) {
+ EconHandler.getEconHandler().withdrawMoney(player, price);
sendMessage(player, Captions.REMOVED_BALANCE, String.valueOf(price));
}
MainUtil.sendMessage(player, Captions.SUCCESS_MERGE);
@@ -174,8 +174,8 @@ public class Merge extends SubCommand {
uuid = plot.getOwnerAbs();
}
}
- if (!force && EconHandler.manager != null && plotArea.useEconomy() && price > 0d
- && EconHandler.manager.getMoney(player) < price) {
+ if (!force && EconHandler.getEconHandler() != null && plotArea.useEconomy() && price > 0d
+ && EconHandler.getEconHandler().getMoney(player) < price) {
sendMessage(player, Captions.CANNOT_AFFORD_MERGE, String.valueOf(price));
return false;
}
@@ -192,8 +192,8 @@ public class Merge extends SubCommand {
return true;
}
if (plot.autoMerge(direction, maxSize - size, uuid, terrain)) {
- if (EconHandler.manager != null && plotArea.useEconomy() && price > 0d) {
- EconHandler.manager.withdrawMoney(player, price);
+ if (EconHandler.getEconHandler() != null && plotArea.useEconomy() && price > 0d) {
+ EconHandler.getEconHandler().withdrawMoney(player, price);
sendMessage(player, Captions.REMOVED_BALANCE, String.valueOf(price));
}
MainUtil.sendMessage(player, Captions.SUCCESS_MERGE);
@@ -226,12 +226,12 @@ public class Merge extends SubCommand {
sendMessage(accepter, Captions.MERGE_NOT_VALID);
return;
}
- if (EconHandler.manager != null && plotArea.useEconomy() && price > 0d) {
- if (!force && EconHandler.manager.getMoney(player) < price) {
+ if (EconHandler.getEconHandler() != null && plotArea.useEconomy() && price > 0d) {
+ if (!force && EconHandler.getEconHandler().getMoney(player) < price) {
sendMessage(player, Captions.CANNOT_AFFORD_MERGE, String.valueOf(price));
return;
}
- EconHandler.manager.withdrawMoney(player, price);
+ EconHandler.getEconHandler().withdrawMoney(player, price);
sendMessage(player, Captions.REMOVED_BALANCE, String.valueOf(price));
}
MainUtil.sendMessage(player, Captions.SUCCESS_MERGE);
diff --git a/Core/src/main/java/com/plotsquared/core/command/Visit.java b/Core/src/main/java/com/plotsquared/core/command/Visit.java
index f5243b4ba..9d803f6e3 100644
--- a/Core/src/main/java/com/plotsquared/core/command/Visit.java
+++ b/Core/src/main/java/com/plotsquared/core/command/Visit.java
@@ -40,12 +40,11 @@ import com.plotsquared.core.util.query.PlotQuery;
import com.plotsquared.core.util.query.SortingStrategy;
import com.plotsquared.core.util.task.RunnableVal2;
import com.plotsquared.core.util.task.RunnableVal3;
-import com.plotsquared.core.uuid.UUIDMapping;
import org.jetbrains.annotations.NotNull;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
@@ -54,8 +53,8 @@ import java.util.concurrent.TimeoutException;
@CommandDeclaration(command = "visit",
permission = "plots.visit",
description = "Visit someones plot",
- usage = "/plot visit [|||] [#]",
- aliases = {"v", "tp", "teleport", "goto", "home", "h", "warp"},
+ usage = "/plot visit || [area]|[#] [#]",
+ aliases = {"v", "tp", "teleport", "goto", "warp"},
requiredType = RequiredType.PLAYER,
category = CommandCategory.TELEPORT)
public class Visit extends Command {
@@ -153,9 +152,9 @@ public class Visit extends Command {
int page = Integer.MIN_VALUE;
switch (args.length) {
- // /p v [...] [...]
+ // /p v
case 3:
- if (!MathMan.isInteger(args[1])) {
+ if (!MathMan.isInteger(args[2])) {
Captions.NOT_VALID_NUMBER.send(player, "(1, ∞)");
Captions.COMMAND_SYNTAX.send(player, getUsage());
return CompletableFuture.completedFuture(false);
@@ -188,24 +187,13 @@ public class Visit extends Command {
}
page = Integer.parseInt(args[1]);
// /p v [page]
- // /p v [page]
// /p v [page]
// /p v [page]
+ // /p v
case 1:
final String[] finalArgs = args;
int finalPage = page;
- // Try to determine whether the given argument is a username
- // or an ordinal
- boolean isNumber = false;
- if (args[0].length() < 2) {
- isNumber = true;
- } else if (args[0].length() <= 4 && MathMan.isInteger(args[0])) {
- // Check if it's an all-digit username that is stored in cache
- final UUIDMapping mapping = PlotSquared.get().getImpromptuUUIDPipeline().getImmediately(args[0]);
- // If no UUID could be found, then we assume it's a number and not a username
- isNumber = mapping == null;
- }
- if (!isNumber && args[0].length() >= 2 && !args[0].contains(";") && !args[0].contains(",")) {
+ if (args[0].length() >= 2 && !args[0].contains(";") && !args[0].contains(",")) {
PlotSquared.get().getImpromptuUUIDPipeline().getSingle(args[0], (uuid, throwable) -> {
if (throwable instanceof TimeoutException) {
// The request timed out
@@ -214,79 +202,61 @@ public class Visit extends Command {
// 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);
+ // player not found, so we assume it's an alias if no page was provided
+ if (finalPage == Integer.MIN_VALUE) {
+ this.visit(player, PlotQuery.newQuery().withAlias(finalArgs[0]), player.getApplicablePlotArea(), confirm, whenDone, 1);
} else {
- // Try to parse a plot
- final Plot plot = MainUtil.getPlotFromString(player, finalArgs[0], true);
- if (plot == null) {
- MainUtil.sendMessage(player, Captions.NOT_VALID_PLOT_ID);
- return;
- }
- this.visit(player, PlotQuery.newQuery().withPlot(plot), null, confirm, whenDone, 1);
+ MainUtil.sendMessage(player, Captions.INVALID_PLAYER, finalArgs[0]);
}
} else {
this.visit(player, PlotQuery.newQuery().ownedBy(uuid).whereBasePlot(), null, confirm, whenDone, finalPage);
}
});
} else {
- 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) {
- this.visit(player, PlotQuery.newQuery().withPlot(plot), null, confirm, whenDone, 1);
- }
+ // Try to parse a plot
+ final Plot plot = MainUtil.getPlotFromString(player, finalArgs[0], true);
+ if (plot != null) {
+ this.visit(player, PlotQuery.newQuery().withPlot(plot), null, confirm, whenDone, 1);
}
}
break;
case 0:
- // /p v
- this.visit(player, PlotQuery.newQuery().ownedBy(player), null, confirm, whenDone);
- break;
+ // /p v is invalid
+ Captions.COMMAND_SYNTAX.send(player, getUsage());
+ return CompletableFuture.completedFuture(false);
default:
}
return CompletableFuture.completedFuture(true);
}
- public Collection tab(PlotPlayer player, String[] args, boolean space) {
- final List completions = new LinkedList<>();
+ @Override public Collection tab(PlotPlayer player, String[] args, boolean space) {
+ final List completions = new ArrayList<>();
switch (args.length - 1) {
case 0:
- this.completeNumbers(completions, args[0], 0);
completions.addAll(TabCompletions.completePlayers(args[0], Collections.emptyList()));
- break;
+ break;
case 1:
- if (MathMan.isInteger(args[0])) {
+ completions.addAll(
+ TabCompletions.completeAreas(args[1]));
+ if (args[1].isEmpty()) {
+ // if no input is given, only suggest 1 - 3
+ completions.addAll(
+ TabCompletions.asCompletions("1", "2", "3"));
break;
}
- this.completeNumbers(completions, args[1], 0);
- this.completeAreas(completions, args[1]);
+ completions.addAll(
+ TabCompletions.completeNumbers(args[1], 10, 999));
break;
case 2:
- if (MathMan.isInteger(args[1])) {
+ if (args[2].isEmpty()) {
+ // if no input is given, only suggest 1 - 3
+ completions.addAll(
+ TabCompletions.asCompletions("1", "2", "3"));
break;
}
- this.completeNumbers(completions, args[2], 0);
+ completions.addAll(
+ TabCompletions.completeNumbers(args[2], 10, 999));
break;
}
diff --git a/Core/src/main/java/com/plotsquared/core/components/ComponentPresetManager.java b/Core/src/main/java/com/plotsquared/core/components/ComponentPresetManager.java
index a3b2f76e4..d31c49c07 100644
--- a/Core/src/main/java/com/plotsquared/core/components/ComponentPresetManager.java
+++ b/Core/src/main/java/com/plotsquared/core/components/ComponentPresetManager.java
@@ -172,12 +172,12 @@ public class ComponentPresetManager {
return false;
}
- if (componentPreset.getCost() > 0.0D && EconHandler.manager != null && plot.getArea().useEconomy()) {
- if (EconHandler.manager.getMoney(player) < componentPreset.getCost()) {
+ if (componentPreset.getCost() > 0.0D && EconHandler.getEconHandler() != null && plot.getArea().useEconomy()) {
+ if (EconHandler.getEconHandler().getMoney(player) < componentPreset.getCost()) {
Captions.PRESET_CANNOT_AFFORD.send(player);
return false;
} else {
- EconHandler.manager.withdrawMoney(player, componentPreset.getCost());
+ EconHandler.getEconHandler().withdrawMoney(player, componentPreset.getCost());
Captions.REMOVED_BALANCE.send(player, componentPreset.getCost() + "");
}
}
@@ -198,7 +198,7 @@ public class ComponentPresetManager {
for (int i = 0; i < allowedPresets.size(); i++) {
final ComponentPreset preset = allowedPresets.get(i);
final List lore = new ArrayList<>();
- if (preset.getCost() > 0 && EconHandler.manager != null && plot.getArea().useEconomy()){
+ if (preset.getCost() > 0 && EconHandler.getEconHandler() != null && plot.getArea().useEconomy()){
lore.add(Captions.PRESET_LORE_COST.getTranslated().replace("%cost%",
String.format("%.2f", preset.getCost())));
}
diff --git a/Core/src/main/java/com/plotsquared/core/configuration/Captions.java b/Core/src/main/java/com/plotsquared/core/configuration/Captions.java
index 03874da48..dbcf463ac 100644
--- a/Core/src/main/java/com/plotsquared/core/configuration/Captions.java
+++ b/Core/src/main/java/com/plotsquared/core/configuration/Captions.java
@@ -182,7 +182,9 @@ public enum Captions implements Caption {
PERMISSION_HOME("plots.home", "static.permissions"),
PERMISSION_ALIAS_SET_OBSOLETE("plots.set.alias", "static.permissions"), // Note this is for backwards compatibility
PERMISSION_ALIAS_SET("plots.alias.set", "static.permissions"),
+ PERMISSION_ADMIN_ALIAS_SET("plots.admin.alias.set", "static.permissions"),
PERMISSION_ALIAS_REMOVE("plots.alias.remove", "static.permissions"),
+ PERMISSION_ADMIN_ALIAS_REMOVE("plots.admin.alias.remove", "static.permissions"),
PERMISSION_ADMIN_CHAT_BYPASS("plots.admin.chat.bypass", "static.permissions"),
PERMISSION_BACKUP("plots.backup", "static.permissions"),
PERMISSION_BACKUP_SAVE("plots.backup.save", "static.permissions"),
diff --git a/Core/src/main/java/com/plotsquared/core/configuration/Settings.java b/Core/src/main/java/com/plotsquared/core/configuration/Settings.java
index 7b0196412..f575fba43 100644
--- a/Core/src/main/java/com/plotsquared/core/configuration/Settings.java
+++ b/Core/src/main/java/com/plotsquared/core/configuration/Settings.java
@@ -257,6 +257,9 @@ public class Settings extends Config {
public static boolean LEGACY_DATABASE_SUPPORT = true;
@Comment("Whether or not PlotSquared should return Unknown if it fails to fulfill a request")
public static boolean UNKNOWN_AS_DEFAULT = true;
+ @Comment("Whether or not automatic background caching should be enabled. It is HIGHLY recommended to keep this turned on."
+ + " This should only be disabled if the server has a very large number of plots (>100k)")
+ public static boolean BACKGROUND_CACHING_ENABLED = true;
}
@@ -385,6 +388,9 @@ public class Settings extends Config {
@Comment(
"Whether schematic based generation should paste schematic on top of plots, or from Y=1")
public static boolean PASTE_ON_TOP = true;
+ @Comment(
+ "Whether schematic based road generation should paste schematic on top of roads, or from Y=1")
+ public static boolean PASTE_ROAD_ON_TOP = true;
}
@@ -527,6 +533,13 @@ public class Settings extends Config {
public static int TARGET_TIME = 65;
}
+ @Comment("Settings related to tab completion")
+ public static final class Tab_Completions {
+ @Comment({"The time in seconds how long tab completions should remain in cache.",
+ "0 will disable caching. Lower values may be less performant."})
+ public static int CACHE_EXPIRATION = 15;
+ }
+
@Comment({"Enable or disable parts of the plugin",
"Note: A cache will use some memory if enabled"})
diff --git a/Core/src/main/java/com/plotsquared/core/generator/HybridGen.java b/Core/src/main/java/com/plotsquared/core/generator/HybridGen.java
index e661e4c5f..a4f955682 100644
--- a/Core/src/main/java/com/plotsquared/core/generator/HybridGen.java
+++ b/Core/src/main/java/com/plotsquared/core/generator/HybridGen.java
@@ -47,7 +47,8 @@ public class HybridGen extends IndependentPlotGenerator {
private void placeSchem(HybridPlotWorld world, ScopedLocalBlockQueue result, short relativeX,
short relativeZ, int x, int z, boolean isRoad) {
int minY; // Math.min(world.PLOT_HEIGHT, world.ROAD_HEIGHT);
- if (isRoad || Settings.Schematics.PASTE_ON_TOP) {
+ if ((isRoad && Settings.Schematics.PASTE_ROAD_ON_TOP) || (!isRoad
+ && Settings.Schematics.PASTE_ON_TOP)) {
minY = world.SCHEM_Y;
} else {
minY = 1;
diff --git a/Core/src/main/java/com/plotsquared/core/generator/HybridPlotManager.java b/Core/src/main/java/com/plotsquared/core/generator/HybridPlotManager.java
index 3fd91eb3c..da4fa74b9 100644
--- a/Core/src/main/java/com/plotsquared/core/generator/HybridPlotManager.java
+++ b/Core/src/main/java/com/plotsquared/core/generator/HybridPlotManager.java
@@ -40,12 +40,14 @@ import com.plotsquared.core.util.ChunkManager;
import com.plotsquared.core.util.FileBytes;
import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.MathMan;
+import com.plotsquared.core.util.RegionManager;
import com.plotsquared.core.util.task.RunnableVal;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypes;
+import lombok.Getter;
import java.io.File;
import java.io.IOException;
@@ -56,7 +58,7 @@ public class HybridPlotManager extends ClassicPlotManager {
public static boolean REGENERATIVE_CLEAR = true;
- private final HybridPlotWorld hybridPlotWorld;
+ @Getter private final HybridPlotWorld hybridPlotWorld;
public HybridPlotManager(HybridPlotWorld hybridPlotWorld) {
super(hybridPlotWorld);
@@ -110,15 +112,17 @@ public class HybridPlotManager extends ClassicPlotManager {
return true;
}
LocalBlockQueue queue = hybridPlotWorld.getQueue(false);
- createSchemAbs(queue, pos1, pos2);
+ createSchemAbs(queue, pos1, pos2, true);
queue.enqueue();
return true;
}
- private void createSchemAbs(LocalBlockQueue queue, Location pos1, Location pos2) {
+ private void createSchemAbs(LocalBlockQueue queue, Location pos1, Location pos2,
+ boolean isRoad) {
int size = hybridPlotWorld.SIZE;
int minY;
- if (Settings.Schematics.PASTE_ON_TOP) {
+ if ((isRoad && Settings.Schematics.PASTE_ROAD_ON_TOP) || (!isRoad
+ && Settings.Schematics.PASTE_ON_TOP)) {
minY = hybridPlotWorld.SCHEM_Y;
} else {
minY = 1;
@@ -170,7 +174,7 @@ public class HybridPlotManager extends ClassicPlotManager {
return true;
}
LocalBlockQueue queue = hybridPlotWorld.getQueue(false);
- createSchemAbs(queue, pos1, pos2);
+ createSchemAbs(queue, pos1, pos2, true);
queue.enqueue();
return true;
}
@@ -184,9 +188,9 @@ public class HybridPlotManager extends ClassicPlotManager {
pos1.setY(0);
pos2.setY(Math.min(getWorldHeight(), 255));
LocalBlockQueue queue = hybridPlotWorld.getQueue(false);
- createSchemAbs(queue, pos1, pos2);
+ createSchemAbs(queue, pos1, pos2, true);
if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) {
- createSchemAbs(queue, pos1, pos2);
+ createSchemAbs(queue, pos1, pos2, true);
}
return queue.enqueue();
}
@@ -199,6 +203,12 @@ public class HybridPlotManager extends ClassicPlotManager {
*
*/
@Override public boolean clearPlot(Plot plot, final Runnable whenDone) {
+ if (RegionManager.manager.notifyClear(this)) {
+ //If this returns false, the clear didn't work
+ if (RegionManager.manager.handleClear(plot, whenDone, this)) {
+ return true;
+ }
+ }
final String world = hybridPlotWorld.getWorldName();
Location pos1 = plot.getBottomAbs();
Location pos2 = plot.getExtendedTopAbs();
@@ -259,7 +269,7 @@ public class HybridPlotManager extends ClassicPlotManager {
if (!hybridPlotWorld.PLOT_SCHEMATIC) {
return;
}
- createSchemAbs(queue, bottom, top);
+ createSchemAbs(queue, bottom, top, false);
}
/**
diff --git a/Core/src/main/java/com/plotsquared/core/generator/HybridPlotWorld.java b/Core/src/main/java/com/plotsquared/core/generator/HybridPlotWorld.java
index 82f87eb90..af6c56768 100644
--- a/Core/src/main/java/com/plotsquared/core/generator/HybridPlotWorld.java
+++ b/Core/src/main/java/com/plotsquared/core/generator/HybridPlotWorld.java
@@ -49,6 +49,7 @@ import com.sk89q.worldedit.math.transform.AffineTransform;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
+import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -71,6 +72,7 @@ public class HybridPlotWorld extends ClassicPlotWorld {
public HashMap G_SCH_B;
public int SCHEM_Y;
private Location SIGN_LOCATION;
+ @Getter private File root = null;
public HybridPlotWorld(String worldName, String id, @NotNull IndependentPlotGenerator generator,
PlotId min, PlotId max) {
@@ -198,7 +200,6 @@ public class HybridPlotWorld extends ClassicPlotWorld {
// 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(),
@@ -339,7 +340,7 @@ public class HybridPlotWorld extends ClassicPlotWorld {
(short) (z - shift), id, false, h2);
}
}
- BiomeType biome = blockArrayClipboard1
+ BiomeType biome = blockArrayClipboard2
.getBiome(BlockVector2.at(x + min.getBlockX(), z + min.getBlockZ()));
addOverlayBiome((short) (x - shift), (short) (z - shift), biome);
}
diff --git a/Core/src/main/java/com/plotsquared/core/generator/HybridUtils.java b/Core/src/main/java/com/plotsquared/core/generator/HybridUtils.java
index 7d21d9579..ed2a23016 100644
--- a/Core/src/main/java/com/plotsquared/core/generator/HybridUtils.java
+++ b/Core/src/main/java/com/plotsquared/core/generator/HybridUtils.java
@@ -87,6 +87,11 @@ public abstract class HybridUtils {
public static PlotArea area;
public static boolean UPDATE = false;
+ public static boolean regeneratePlotWalls(final PlotArea area) {
+ PlotManager plotManager = area.getPlotManager();
+ return plotManager.regenerateAllPlotWalls();
+ }
+
public void analyzeRegion(final String world, final CuboidRegion region,
final RunnableVal whenDone) {
// int diff, int variety, int vertices, int rotation, int height_sd
@@ -503,7 +508,7 @@ public abstract class HybridUtils {
PlotManager plotManager = plotworld.getPlotManager();
int sx = bot.getX() - plotworld.ROAD_WIDTH + 1;
int sz = bot.getZ() + 1;
- int sy = plotworld.ROAD_HEIGHT;
+ int sy = Settings.Schematics.PASTE_ROAD_ON_TOP ? plotworld.ROAD_HEIGHT : 1;
int ex = bot.getX();
int ez = top.getZ();
int ey = get_ey(plotManager, queue, sx, ex, sz, ez, sy);
@@ -623,10 +628,7 @@ public abstract class HybridUtils {
}
if (condition) {
BaseBlock[] blocks = plotWorld.G_SCH.get(MathMan.pair(absX, absZ));
- int minY = plotWorld.SCHEM_Y;
- if (!Settings.Schematics.PASTE_ON_TOP) {
- minY = 1;
- }
+ int minY = Settings.Schematics.PASTE_ROAD_ON_TOP ? plotWorld.SCHEM_Y : 1;
int maxY = Math.max(extend, blocks.length);
for (int y = 0; y < maxY; y++) {
if (y > blocks.length - 1) {
@@ -661,9 +663,4 @@ public abstract class HybridUtils {
}
return false;
}
-
- public static boolean regeneratePlotWalls(final PlotArea area) {
- PlotManager plotManager = area.getPlotManager();
- return plotManager.regenerateAllPlotWalls();
- }
}
diff --git a/Core/src/main/java/com/plotsquared/core/location/Location.java b/Core/src/main/java/com/plotsquared/core/location/Location.java
index 0505137b1..08db98a19 100644
--- a/Core/src/main/java/com/plotsquared/core/location/Location.java
+++ b/Core/src/main/java/com/plotsquared/core/location/Location.java
@@ -34,6 +34,7 @@ import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import lombok.Getter;
import lombok.Setter;
+import org.jetbrains.annotations.NotNull;
import org.khelekore.prtree.MBR;
import org.khelekore.prtree.SimpleMBR;
@@ -103,6 +104,16 @@ public class Location implements Cloneable, Comparable {
}
}
+ /**
+ * Return a copy of the location. This will pass {@link #equals(Object)}
+ * but will have a different identity.
+ *
+ * @return Copy of the location
+ */
+ @NotNull public Location copy() {
+ return new Location(this.world, this.x, this.y, this.z, this.yaw, this.pitch);
+ }
+
public PlotArea getPlotArea() {
return PlotSquared.get().getPlotAreaAbs(this);
}
@@ -179,6 +190,7 @@ public class Location implements Cloneable, Comparable {
this.x += x;
this.y += y;
this.z += z;
+ this.blockVector3 = BlockVector3.at(this.x, this.y, this.z);
return this;
}
@@ -220,6 +232,7 @@ public class Location implements Cloneable, Comparable {
this.x -= x;
this.y -= y;
this.z -= z;
+ this.blockVector3 = BlockVector3.at(this.x, this.y, this.z);
return this;
}
diff --git a/Core/src/main/java/com/plotsquared/core/player/PlotPlayer.java b/Core/src/main/java/com/plotsquared/core/player/PlotPlayer.java
index 07307f37a..a1d178469 100644
--- a/Core/src/main/java/com/plotsquared/core/player/PlotPlayer.java
+++ b/Core/src/main/java/com/plotsquared/core/player/PlotPlayer.java
@@ -371,7 +371,7 @@ public abstract class PlotPlayer implements CommandCaller, OfflinePlotPlayer
@NotNull public Location getLocation() {
Location location = getMeta("location");
if (location != null) {
- return location;
+ return location.copy(); // Always return a copy of the location
}
return getLocationFull();
}
@@ -760,18 +760,18 @@ public abstract class PlotPlayer
implements CommandCaller, OfflinePlotPlayer
* The amount of money this Player has.
*/
public double getMoney() {
- return EconHandler.manager == null ? 0 : EconHandler.manager.getMoney(this);
+ return EconHandler.getEconHandler() == null ? 0 : EconHandler.getEconHandler().getMoney(this);
}
public void withdraw(double amount) {
- if (EconHandler.manager != null) {
- EconHandler.manager.withdrawMoney(this, amount);
+ if (EconHandler.getEconHandler() != null) {
+ EconHandler.getEconHandler().withdrawMoney(this, amount);
}
}
public void deposit(double amount) {
- if (EconHandler.manager != null) {
- EconHandler.manager.depositMoney(this, amount);
+ if (EconHandler.getEconHandler() != null) {
+ EconHandler.getEconHandler().depositMoney(this, amount);
}
}
diff --git a/Core/src/main/java/com/plotsquared/core/plot/Plot.java b/Core/src/main/java/com/plotsquared/core/plot/Plot.java
index a746dd272..f0bd35552 100644
--- a/Core/src/main/java/com/plotsquared/core/plot/Plot.java
+++ b/Core/src/main/java/com/plotsquared/core/plot/Plot.java
@@ -1751,6 +1751,7 @@ public class Plot {
}
} else {
area.addPlot(this);
+ updateWorldBorder();
}
setSign(player.getName());
MainUtil.sendMessage(player, Captions.CLAIMED);
@@ -2998,11 +2999,9 @@ public class Plot {
final String name = player.getName();
TaskManager.TELEPORT_QUEUE.add(name);
TaskManager.runTaskLater(() -> {
- if (!TaskManager.TELEPORT_QUEUE.contains(name)) {
- MainUtil.sendMessage(player, Captions.TELEPORT_FAILED);
+ if (!TaskManager.TELEPORT_QUEUE.remove(name)) {
return;
}
- TaskManager.TELEPORT_QUEUE.remove(name);
if (player.isOnline()) {
MainUtil.sendMessage(player, Captions.TELEPORTED_TO_PLOT);
player.teleport(location, cause);
diff --git a/Core/src/main/java/com/plotsquared/core/plot/PlotArea.java b/Core/src/main/java/com/plotsquared/core/plot/PlotArea.java
index 9501768ed..d2e0d3fda 100644
--- a/Core/src/main/java/com/plotsquared/core/plot/PlotArea.java
+++ b/Core/src/main/java/com/plotsquared/core/plot/PlotArea.java
@@ -122,6 +122,7 @@ public abstract class PlotArea {
@Getter private GameMode gameMode = GameModes.CREATIVE;
@Getter private Map> prices = new HashMap<>();
@Getter(AccessLevel.PROTECTED) private List schematics = new ArrayList<>();
+ @Getter private boolean roadFlags = false;
private boolean worldBorder = false;
private boolean useEconomy = false;
private int hash;
@@ -131,7 +132,9 @@ public abstract class PlotArea {
/**
* Area flag container
*/
- @Getter private FlagContainer flagContainer =
+ @Getter private final FlagContainer flagContainer =
+ new FlagContainer(GlobalFlagContainer.getInstance());
+ @Getter private final FlagContainer roadFlagContainer =
new FlagContainer(GlobalFlagContainer.getInstance());
public PlotArea(@NotNull final String worldName, @Nullable final String id,
@@ -373,6 +376,40 @@ public abstract class PlotArea {
this.spawnEggs = config.getBoolean("event.spawn.egg");
this.spawnCustom = config.getBoolean("event.spawn.custom");
this.spawnBreeding = config.getBoolean("event.spawn.breeding");
+
+ List roadflags = config.getStringList("flags.default");
+ if (roadflags.isEmpty()) {
+ roadflags = config.getStringList("road.flags");
+ if (roadflags.isEmpty()) {
+ roadflags = new ArrayList<>();
+ ConfigurationSection section = config.getConfigurationSection("road.flags");
+ Set keys = section.getKeys(false);
+ for (String key : keys) {
+ if (!"default".equals(key)) {
+ roadflags.add(key + ';' + section.get(key));
+ }
+ }
+ }
+ }
+ this.getRoadFlagContainer().addAll(parseFlags(roadflags));
+
+ StringBuilder roadFlagBuilder = new StringBuilder();
+ Collection> roadFlagCollection = this.getFlagContainer().getFlagMap().values();
+ if (roadFlagCollection.isEmpty()) {
+ roadFlagBuilder.append(Captions.NONE.getTranslated());
+ } else {
+ roadFlags = true;
+ String prefix = " ";
+ for (final PlotFlag, ?> flag : roadFlagCollection) {
+ Object value = flag.toString();
+ roadFlagBuilder.append(prefix).append(CaptionUtility
+ .format(null, Captions.PLOT_FLAG_LIST.getTranslated(), flag.getName(),
+ CaptionUtility.formatRaw(null, value.toString(), "")));
+ prefix = ", ";
+ }
+ }
+ PlotSquared.log(Captions.PREFIX + "&3 - road flags: &7" + roadFlagBuilder.toString());
+
loadConfiguration(config);
}
@@ -416,6 +453,7 @@ public abstract class PlotArea {
options.put("world.max_height", this.getMaxBuildHeight());
options.put("world.min_height", this.getMinBuildHeight());
options.put("world.gamemode", this.getGameMode().getName().toLowerCase());
+ options.put("road.flags.default", null);
if (this.getType() != PlotAreaType.NORMAL) {
options.put("generator.terrain", this.getTerrain());
@@ -437,6 +475,9 @@ public abstract class PlotArea {
config.set("flags.use",
"63,64,68,69,71,77,96,143,167,193,194,195,196,197,77,143,69,70,72,147,148,107,183,184,185,186,187,132");
}
+ if (!config.contains("road.flags")) {
+ config.set("road.flags.liquid-flow", false);
+ }
}
@NotNull @Override public String toString() {
@@ -1074,4 +1115,52 @@ public abstract class PlotArea {
}
return flags;
}
+
+ /**
+ * Get the value associated with the specified flag. This will look at
+ * the default values stored in {@link GlobalFlagContainer}.
+ *
+ * @param flagClass The flag type (Class)
+ * @return The flag value
+ */
+ public T getFlag(final Class extends PlotFlag> flagClass) {
+ return this.flagContainer.getFlag(flagClass).getValue();
+ }
+
+ /**
+ * Get the value associated with the specified flag. This will look at
+ * the default values stored in {@link GlobalFlagContainer}.
+ *
+ * @param flag The flag type (Any instance of the flag)
+ * @return The flag value
+ */
+ public > T getFlag(final V flag) {
+ final Class> flagClass = flag.getClass();
+ final PlotFlag, ?> flagInstance = this.flagContainer.getFlagErased(flagClass);
+ return FlagContainer.castUnsafe(flagInstance).getValue();
+ }
+
+ /**
+ * Get the value associated with the specified road flag. This will look at
+ * the default values stored in {@link GlobalFlagContainer}.
+ *
+ * @param flagClass The flag type (Class)
+ * @return The flag value
+ */
+ public T getRoadFlag(final Class extends PlotFlag> flagClass) {
+ return this.roadFlagContainer.getFlag(flagClass).getValue();
+ }
+
+ /**
+ * Get the value associated with the specified road flag. This will look at
+ * the default values stored in {@link GlobalFlagContainer}.
+ *
+ * @param flag The flag type (Any instance of the flag)
+ * @return The flag value
+ */
+ public > T getRoadFlag(final V flag) {
+ final Class> flagClass = flag.getClass();
+ final PlotFlag, ?> flagInstance = this.roadFlagContainer.getFlagErased(flagClass);
+ return FlagContainer.castUnsafe(flagInstance).getValue();
+ }
}
diff --git a/Core/src/main/java/com/plotsquared/core/util/EconHandler.java b/Core/src/main/java/com/plotsquared/core/util/EconHandler.java
index 15180e68e..a593e0cb0 100644
--- a/Core/src/main/java/com/plotsquared/core/util/EconHandler.java
+++ b/Core/src/main/java/com/plotsquared/core/util/EconHandler.java
@@ -25,42 +25,67 @@
*/
package com.plotsquared.core.util;
+import com.plotsquared.core.IPlotMain;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.player.ConsolePlayer;
import com.plotsquared.core.player.OfflinePlotPlayer;
import com.plotsquared.core.player.PlotPlayer;
+import org.jetbrains.annotations.Nullable;
public abstract class EconHandler {
- public static EconHandler manager;
- private static boolean initialized;
+ /**
+ * @deprecated This will be removed in the future,
+ * call {@link IPlotMain#getEconomyHandler()} instead.
+ */
+ @Deprecated @Nullable public static EconHandler manager;
- public static EconHandler getEconHandler() {
- if (initialized) {
- return manager;
- }
- initialized = true;
- return manager = PlotSquared.get().IMP.getEconomyHandler();
+ /**
+ * Initialize the economy handler using {@link IPlotMain#getEconomyHandler()}
+ * @deprecated Call {@link #init} instead or use {@link IPlotMain#getEconomyHandler()}
+ * which does this already.
+ */
+ @Deprecated public static void initializeEconHandler() {
+ manager = PlotSquared.get().IMP.getEconomyHandler();
}
- public double getMoney(PlotPlayer player) {
+ /**
+ * Return the econ handler instance, if one exists
+ *
+ * @return Economy handler instance
+ * @deprecated Call {@link IPlotMain#getEconomyHandler()} instead
+ */
+ @Deprecated @Nullable public static EconHandler getEconHandler() {
+ manager = PlotSquared.get().IMP.getEconomyHandler();
+ return manager;
+ }
+
+ public abstract boolean init();
+
+ public double getMoney(PlotPlayer> player) {
if (player instanceof ConsolePlayer) {
return Double.MAX_VALUE;
}
return getBalance(player);
}
- public abstract double getBalance(PlotPlayer player);
+ public abstract double getBalance(PlotPlayer> player);
- public abstract void withdrawMoney(PlotPlayer player, double amount);
+ public abstract void withdrawMoney(PlotPlayer> player, double amount);
- public abstract void depositMoney(PlotPlayer player, double amount);
+ public abstract void depositMoney(PlotPlayer> player, double amount);
public abstract void depositMoney(OfflinePlotPlayer player, double amount);
- public abstract boolean hasPermission(String world, String player, String perm);
+ /**
+ * @deprecated Use {@link PermHandler#hasPermission(String, String, String)} instead
+ */
+ @Deprecated public abstract boolean hasPermission(String world, String player, String perm);
- public boolean hasPermission(String player, String perm) {
+ /**
+ * @deprecated Use {@link PermHandler#hasPermission(String, String)} instead
+ */
+ @Deprecated public boolean hasPermission(String player, String perm) {
return hasPermission(null, player, perm);
}
}
diff --git a/Core/src/main/java/com/plotsquared/core/util/MainUtil.java b/Core/src/main/java/com/plotsquared/core/util/MainUtil.java
index df0e253d6..2c9c2a60b 100644
--- a/Core/src/main/java/com/plotsquared/core/util/MainUtil.java
+++ b/Core/src/main/java/com/plotsquared/core/util/MainUtil.java
@@ -373,10 +373,21 @@ public class MainUtil {
/**
* Get the name from a UUID.
*
- * @param owner
+ * @param owner Owner UUID
* @return The player's name, None, Everyone or Unknown
*/
- @NotNull public static String getName(UUID owner) {
+ @NotNull public static String getName(@Nullable UUID owner) {
+ return getName(owner, true);
+ }
+
+ /**
+ * Get the name from a UUID.
+ *
+ * @param owner Owner UUID
+ * @param blocking Whether or not the operation can be blocking
+ * @return The player's name, None, Everyone or Unknown
+ */
+ @NotNull public static String getName(@Nullable final UUID owner, final boolean blocking) {
if (owner == null) {
return Captions.NONE.getTranslated();
}
@@ -386,7 +397,17 @@ public class MainUtil {
if (owner.equals(DBFunc.SERVER)) {
return Captions.SERVER.getTranslated();
}
- String name = PlotSquared.get().getImpromptuUUIDPipeline().getSingle(owner, Settings.UUID.BLOCKING_TIMEOUT);
+ final String name;
+ if (blocking) {
+ name = PlotSquared.get().getImpromptuUUIDPipeline().getSingle(owner, Settings.UUID.BLOCKING_TIMEOUT);
+ } else {
+ final UUIDMapping uuidMapping = PlotSquared.get().getImpromptuUUIDPipeline().getImmediately(owner);
+ if (uuidMapping != null) {
+ name = uuidMapping.getUsername();
+ } else {
+ name = null;
+ }
+ }
if (name == null) {
return Captions.UNKNOWN.getTranslated();
}
diff --git a/Core/src/main/java/com/plotsquared/core/util/PermHandler.java b/Core/src/main/java/com/plotsquared/core/util/PermHandler.java
new file mode 100644
index 000000000..1dec45fd4
--- /dev/null
+++ b/Core/src/main/java/com/plotsquared/core/util/PermHandler.java
@@ -0,0 +1,37 @@
+/*
+ * _____ _ _ _____ _
+ * | __ \| | | | / ____| | |
+ * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
+ * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
+ * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
+ * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
+ * | |
+ * |_|
+ * PlotSquared plot management system for Minecraft
+ * Copyright (C) 2020 IntellectualSites
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package com.plotsquared.core.util;
+
+public abstract class PermHandler {
+
+ public abstract boolean init();
+
+ public abstract boolean hasPermission(String world, String player, String perm);
+
+ public boolean hasPermission(String player, String perm) {
+ return hasPermission(null, player, perm);
+ }
+}
diff --git a/Core/src/main/java/com/plotsquared/core/util/RegionManager.java b/Core/src/main/java/com/plotsquared/core/util/RegionManager.java
index c0162b0d5..c31c1dc03 100644
--- a/Core/src/main/java/com/plotsquared/core/util/RegionManager.java
+++ b/Core/src/main/java/com/plotsquared/core/util/RegionManager.java
@@ -29,6 +29,7 @@ import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea;
+import com.plotsquared.core.plot.PlotManager;
import com.plotsquared.core.queue.LocalBlockQueue;
import com.plotsquared.core.util.task.RunnableVal;
import com.plotsquared.core.util.task.TaskManager;
@@ -167,6 +168,22 @@ public abstract class RegionManager {
return queue.enqueue();
}
+ /**
+ * Notify any plugins that may want to modify clear behaviour that a clear is occuring
+ *
+ * @return true if the notified will accept the clear task
+ */
+ public boolean notifyClear(PlotManager manager) {
+ return false;
+ }
+
+ /**
+ * Only called when {@link RegionManager#notifyClear(PlotManager)} returns true in specific PlotManagers
+ *
+ * @return true if the clear worked. False if someone went wrong so P2 can then handle the clear
+ */
+ public abstract boolean handleClear(Plot plot, final Runnable whenDone, PlotManager manager);
+
/**
* Copy a region to a new location (in the same world)
*/
diff --git a/Core/src/main/java/com/plotsquared/core/util/SchematicHandler.java b/Core/src/main/java/com/plotsquared/core/util/SchematicHandler.java
index 0784ca825..6b8265639 100644
--- a/Core/src/main/java/com/plotsquared/core/util/SchematicHandler.java
+++ b/Core/src/main/java/com/plotsquared/core/util/SchematicHandler.java
@@ -134,8 +134,7 @@ public abstract class SchematicHandler {
name =
plot.getId().x + ";" + plot.getId().y + ',' + plot.getArea() + ',' + owner;
} else {
- name = namingScheme
- .replaceAll("%id%", plot.getId().toString())
+ name = namingScheme.replaceAll("%id%", plot.getId().toString())
.replaceAll("%idx%", plot.getId().x + "")
.replaceAll("%idy%", plot.getId().y + "")
.replaceAll("%world%", plot.getArea().toString());
@@ -552,100 +551,114 @@ public abstract class SchematicHandler {
final int p2z = pos2.getZ();
final int ey = pos2.getY();
Iterator yiter = IntStream.range(sy, ey + 1).iterator();
- final Runnable yTask = () -> {
- long ystart = System.currentTimeMillis();
- while (yiter.hasNext() && System.currentTimeMillis() - ystart < 20) {
- final int y = yiter.next();
- Iterator ziter = IntStream.range(p1z, p2z + 1).iterator();
- final Runnable zTask = () -> {
- long zstart = System.currentTimeMillis();
- while (ziter.hasNext()
- && System.currentTimeMillis() - zstart < 20) {
- final int z = ziter.next();
- Iterator xiter =
- IntStream.range(p1x, p2x + 1).iterator();
- final Runnable xTask = () -> {
- long xstart = System.currentTimeMillis();
- final int ry = y - sy;
- final int rz = z - p1z;
- while (xiter.hasNext()
- && System.currentTimeMillis() - xstart < 20) {
- final int x = xiter.next();
- final int rx = x - p1x;
- BlockVector3 point = BlockVector3.at(x, y, z);
- BaseBlock block =
- cuboidRegion.getWorld().getFullBlock(point);
- if (block.getNbtData() != null) {
- Map values = new HashMap<>();
- for (Map.Entry entry : block
- .getNbtData().getValue().entrySet()) {
- values.put(entry.getKey(), entry.getValue());
+ final Runnable yTask = new Runnable() {
+ @Override public void run() {
+ long ystart = System.currentTimeMillis();
+ while (yiter.hasNext() && System.currentTimeMillis() - ystart < 20) {
+ final int y = yiter.next();
+ Iterator ziter = IntStream.range(p1z, p2z + 1).iterator();
+ final Runnable zTask = new Runnable() {
+ @Override public void run() {
+ long zstart = System.currentTimeMillis();
+ while (ziter.hasNext()
+ && System.currentTimeMillis() - zstart < 20) {
+ final int z = ziter.next();
+ Iterator xiter =
+ IntStream.range(p1x, p2x + 1).iterator();
+ final Runnable xTask = new Runnable() {
+ @Override public void run() {
+ long xstart = System.currentTimeMillis();
+ final int ry = y - sy;
+ final int rz = z - p1z;
+ while (xiter.hasNext()
+ && System.currentTimeMillis() - xstart
+ < 20) {
+ final int x = xiter.next();
+ final int rx = x - p1x;
+ BlockVector3 point =
+ BlockVector3.at(x, y, z);
+ BaseBlock block = cuboidRegion.getWorld()
+ .getFullBlock(point);
+ if (block.getNbtData() != null) {
+ Map values =
+ new HashMap<>();
+ for (Map.Entry entry : block
+ .getNbtData().getValue()
+ .entrySet()) {
+ values.put(entry.getKey(),
+ entry.getValue());
+ }
+ // Remove 'id' if it exists. We want 'Id'
+ values.remove("id");
+
+ // Positions are kept in NBT, we don't want that.
+ values.remove("x");
+ values.remove("y");
+ values.remove("z");
+
+ values.put("Id",
+ new StringTag(block.getNbtId()));
+ values.put("Pos", new IntArrayTag(
+ new int[] {rx, ry, rz}));
+
+ tileEntities
+ .add(new CompoundTag(values));
+ }
+ String blockKey =
+ block.toImmutableState().getAsString();
+ int blockId;
+ if (palette.containsKey(blockKey)) {
+ blockId = palette.get(blockKey);
+ } else {
+ blockId = palette.size();
+ palette.put(blockKey, palette.size());
+ }
+
+ while ((blockId & -128) != 0) {
+ buffer.write(blockId & 127 | 128);
+ blockId >>>= 7;
+ }
+ buffer.write(blockId);
+
+ if (ry > 0) {
+ continue;
+ }
+ BlockVector2 pt = BlockVector2.at(x, z);
+ BiomeType biome =
+ cuboidRegion.getWorld().getBiome(pt);
+ String biomeStr = biome.getId();
+ int biomeId;
+ if (biomePalette.containsKey(biomeStr)) {
+ biomeId = biomePalette.get(biomeStr);
+ } else {
+ biomeId = biomePalette.size();
+ biomePalette.put(biomeStr, biomeId);
+ }
+ while ((biomeId & -128) != 0) {
+ biomeBuffer.write(biomeId & 127 | 128);
+ biomeId >>>= 7;
+ }
+ biomeBuffer.write(biomeId);
+ }
+ if (xiter.hasNext()) {
+ this.run();
+ }
}
- // Remove 'id' if it exists. We want 'Id'
- values.remove("id");
-
- // Positions are kept in NBT, we don't want that.
- values.remove("x");
- values.remove("y");
- values.remove("z");
-
- values.put("Id", new StringTag(block.getNbtId()));
- values.put("Pos",
- new IntArrayTag(new int[] {rx, ry, rz}));
-
- tileEntities.add(new CompoundTag(values));
- }
- String blockKey =
- block.toImmutableState().getAsString();
- int blockId;
- if (palette.containsKey(blockKey)) {
- blockId = palette.get(blockKey);
- } else {
- blockId = palette.size();
- palette.put(blockKey, palette.size());
- }
-
- while ((blockId & -128) != 0) {
- buffer.write(blockId & 127 | 128);
- blockId >>>= 7;
- }
- buffer.write(blockId);
-
- if (ry > 0) {
- continue;
- }
- BlockVector2 pt = BlockVector2.at(x, z);
- BiomeType biome = cuboidRegion.getWorld().getBiome(pt);
- String biomeStr = biome.getId();
- int biomeId;
- if (biomePalette.containsKey(biomeStr)) {
- biomeId = biomePalette.get(biomeStr);
- } else {
- biomeId = biomePalette.size();
- biomePalette.put(biomeStr, biomeId);
- }
- while ((biomeId & -128) != 0) {
- biomeBuffer.write(biomeId & 127 | 128);
- biomeId >>>= 7;
- }
- biomeBuffer.write(biomeId);
+ };
+ xTask.run();
}
- if (xiter.hasNext()) {
+ if (ziter.hasNext()) {
this.run();
}
- };
- xTask.run();
- }
- if (ziter.hasNext()) {
- this.run();
- }
- };
- zTask.run();
- }
- if (yiter.hasNext()) {
- TaskManager.runTaskLater(this, 1);
- } else {
- regionTask.run();
+ }
+ };
+ zTask.run();
+ }
+ if (yiter.hasNext()) {
+ TaskManager.runTaskLater(this, 1);
+ } else {
+ regionTask.run();
+ }
}
};
yTask.run();
diff --git a/Core/src/main/java/com/plotsquared/core/util/TabCompletions.java b/Core/src/main/java/com/plotsquared/core/util/TabCompletions.java
index dbf053c52..077ac4563 100644
--- a/Core/src/main/java/com/plotsquared/core/util/TabCompletions.java
+++ b/Core/src/main/java/com/plotsquared/core/util/TabCompletions.java
@@ -34,6 +34,7 @@ import com.plotsquared.core.command.RequiredType;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
+import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.uuid.UUIDMapping;
import lombok.experimental.UtilityClass;
import org.jetbrains.annotations.NotNull;
@@ -56,7 +57,9 @@ import java.util.stream.Collectors;
public class TabCompletions {
private final Cache> cachedCompletionValues =
- CacheBuilder.newBuilder().expireAfterWrite(15, TimeUnit.SECONDS).build();
+ CacheBuilder.newBuilder()
+ .expireAfterWrite(Settings.Tab_Completions.CACHE_EXPIRATION, TimeUnit.SECONDS)
+ .build();
private final Command booleanTrueCompletion = new Command(null, false, "true", "",
RequiredType.NONE, null) {};
@@ -134,6 +137,65 @@ public class TabCompletions {
return Collections.emptyList();
}
+ /**
+ * Get a list of integer numbers matching the given input. If the input string
+ * is empty, nothing will be returned. The list is unmodifiable.
+ *
+ * @param input Input to filter with
+ * @param amountLimit Maximum amount of suggestions
+ * @param highestLimit Highest number to include
+ * @return Unmodifiable list of number completions
+ */
+ @NotNull public List completeNumbers(@NotNull final String input,
+ final int amountLimit, final int highestLimit) {
+ if (input.isEmpty() || input.length() > highestLimit || !MathMan.isInteger(input)) {
+ return Collections.emptyList();
+ }
+ int offset;
+ try {
+ offset = Integer.parseInt(input) * 10;
+ } catch (NumberFormatException ignored) {
+ return Collections.emptyList();
+ }
+ final List commands = new ArrayList<>();
+ for (int i = offset; i < highestLimit && (offset - i + amountLimit) > 0; i++) {
+ commands.add(String.valueOf(i));
+ }
+ return asCompletions(commands.toArray(new String[0]));
+ }
+
+ /**
+ * Get a list of plot areas matching the given input.
+ * The list is unmodifiable.
+ *
+ * @param input Input to filter with
+ * @return Unmodifiable list of area completions
+ */
+ @NotNull public List completeAreas(@NotNull final String input) {
+ final List completions = new ArrayList<>();
+ for (final PlotArea area : PlotSquared.get().getPlotAreas()) {
+ String areaName = area.getWorldName();
+ if (area.getId() != null) {
+ areaName += ";" + area.getId();
+ }
+ if (!areaName.toLowerCase().startsWith(input.toLowerCase())) {
+ continue;
+ }
+ completions.add(new Command(null, false, areaName, "",
+ RequiredType.NONE, null) {});
+ }
+ return Collections.unmodifiableList(completions);
+ }
+
+ @NotNull public List asCompletions(String... toFilter) {
+ final List completions = new ArrayList<>();
+ for (String completion : toFilter) {
+ completions.add(new Command(null, false, completion, "",
+ RequiredType.NONE, null) {});
+ }
+ return Collections.unmodifiableList(completions);
+ }
+
/**
* @param cacheIdentifier Cache key
* @param input Command input
diff --git a/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java b/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java
index 40d883062..27b4352eb 100644
--- a/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java
+++ b/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java
@@ -376,6 +376,30 @@ public final class PlotQuery {
return this.asList();
}
+ /**
+ * Get whether any provided plot matches the given filters.
+ * If no plot was provided, false will be returned.
+ *
+ * @return true if any provided plot matches the filters.
+ */
+ public boolean anyMatch() {
+ if (this.filters.isEmpty()) {
+ return !this.plotProvider.getPlots().isEmpty();
+ } else {
+ final Collection plots = this.plotProvider.getPlots();
+ outer: for (final Plot plot : plots) {
+ // a plot must pass all filters to match the criteria
+ for (final PlotFilter filter : this.filters) {
+ if (!filter.accepts(plot)) {
+ continue outer;
+ }
+ }
+ return true; // a plot passed all filters, so we have a match
+ }
+ return false;
+ }
+ }
+
@NotNull private PlotQuery addFilter(@NotNull final PlotFilter filter) {
this.filters.add(filter);
return this;
diff --git a/build.gradle b/build.gradle
index 635cd7ea4..a0bae9c0c 100644
--- a/build.gradle
+++ b/build.gradle
@@ -30,7 +30,7 @@ ext {
git = Grgit.open(dir: new File(rootDir.toString() + "/.git"))
}
-def ver = "5.12.2"
+def ver = "5.12.5"
def versuffix = ""
ext {
if (project.hasProperty("versionsuffix")) {
@@ -76,6 +76,8 @@ subprojects {
delete("../target")
}
+ javadoc.options.encoding = 'UTF-8'
+
dependencies {
compile group: 'org.json', name: 'json', version: '20200518'
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 4c5803d13..bb8b2fc26 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.4-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists