Optimize Region List and Region Teleport commands (#1868)

* Optimized command usage for /rg list and /rg teleport:
* added a flag to the teleport command to teleport the actor to the center of the region
* added a flag to the list command to filter the regions for special ids
* added a flag to the list command to get regions intersecting your selection

* Fixed wrong pagination in RegionLister
This commit is contained in:
JOO200 2022-01-23 19:03:40 +01:00 committed by GitHub
parent 4abf971cf6
commit dca0515104
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 79 additions and 12 deletions

View File

@ -31,6 +31,7 @@
import com.sk89q.worldedit.command.util.AsyncCommandBuilder;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.formatting.component.ErrorFormat;
import com.sk89q.worldedit.util.formatting.component.LabelFormat;
@ -42,6 +43,7 @@
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import com.sk89q.worldedit.util.formatting.text.format.TextDecoration;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.gamemode.GameModes;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.commands.task.RegionAdder;
@ -75,6 +77,7 @@
import com.sk89q.worldguard.protection.regions.ProtectedRegion.CircularInheritanceException;
import com.sk89q.worldguard.protection.regions.RegionContainer;
import com.sk89q.worldguard.protection.util.DomainInputResolver.UserLocatorPolicy;
import com.sk89q.worldguard.protection.util.WorldEditRegionConverter;
import com.sk89q.worldguard.session.Session;
import com.sk89q.worldguard.util.Enums;
import com.sk89q.worldguard.util.logging.LoggerToChatHandler;
@ -449,9 +452,9 @@ public void info(CommandContext args, Actor sender) throws CommandException {
* @throws CommandException any error
*/
@Command(aliases = {"list"},
usage = "[page]",
usage = "[-w world] [-p owner [-n]] [-s] [-i filter] [page]",
desc = "Get a list of regions",
flags = "np:w:",
flags = "np:w:i:s",
max = 1)
public void list(CommandContext args, Actor sender) throws CommandException {
warnAboutSaveFailures(sender);
@ -488,6 +491,16 @@ public void list(CommandContext args, Actor sender) throws CommandException {
task.filterOwnedByName(ownedBy, args.hasFlag('n'));
}
if (args.hasFlag('s')) {
ProtectedRegion existing = checkRegionFromSelection(sender, "tmp");
task.filterByIntersecting(existing);
}
// -i string is in region id
if (args.hasFlag('i')) {
task.filterIdByMatch(args.getFlag('i'));
}
AsyncCommandBuilder.wrap(task, sender)
.registerWithSupervisor(WorldGuard.getInstance().getSupervisor(), "Getting region list")
.sendMessageAfterDelay("(Please wait... fetching region list...)")
@ -1146,8 +1159,8 @@ public void migrateHeights(CommandContext args, Actor sender) throws CommandExce
* @throws CommandException any error
*/
@Command(aliases = {"teleport", "tp"},
usage = "<id>",
flags = "sw:",
usage = "[-w world] [-c|s] <id>",
flags = "csw:",
desc = "Teleports you to the location associated with the region.",
min = 1, max = 1)
public void teleport(CommandContext args, Actor sender) throws CommandException {
@ -1172,6 +1185,23 @@ public void teleport(CommandContext args, Actor sender) throws CommandException
throw new CommandException(
"The region has no spawn point associated.");
}
} else if (args.hasFlag('c')) {
// Check permissions
if (!getPermissionModel(player).mayTeleportToCenter(existing)) {
throw new CommandPermissionsException();
}
Region region = WorldEditRegionConverter.convertToRegion(existing);
if (region == null || region.getCenter() == null) {
throw new CommandException("The region has no center point.");
}
if (player.getGameMode() == GameModes.SPECTATOR) {
teleportLocation = new Location(world, region.getCenter(), 0, 0);
} else {
// TODO: Add some method to create a safe teleport location.
// The method AbstractPlayerActor$findFreePoisition(Location loc) is no good way for this.
// It doesn't return the found location and it can't be checked if the location is inside the region.
throw new CommandException("Center teleport is only availible in Spectator gamemode.");
}
} else {
teleportLocation = FlagValueCalculator.getEffectiveFlagOf(existing, Flags.TELE_LOC, player);

View File

@ -327,6 +327,12 @@ public void appendBounds() {
+ teleFlag.getBlockZ()))))
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND,
"/rg tp -w \"" + world + "\" " + region.getId()))));
} else if (perms != null && perms.mayTeleportToCenter(region) && region.isPhysicalArea()) {
builder.append(TextComponent.space().append(TextComponent.of("[Center Teleport]", TextColor.GRAY)
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT,
TextComponent.of("Click to teleport to the center of the region")))
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND,
"/rg tp -c -w \"" + world + "\" " + region.getId()))));
}
newline();

View File

@ -42,6 +42,7 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@ -58,6 +59,8 @@ public class RegionLister implements Callable<Integer> {
private final RegionManager manager;
private final String world;
private OwnerMatcher ownerMatcher;
private String idFilter;
private ProtectedRegion filterByIntersecting;
private int page;
private String playerName;
private boolean nameOnly;
@ -80,6 +83,10 @@ public void setPage(int page) {
this.page = page;
}
public void filterByIntersecting(ProtectedRegion region) {
this.filterByIntersecting = region;
}
public void filterOwnedByName(String name, boolean nameOnly) {
this.playerName = name;
this.nameOnly = nameOnly;
@ -144,20 +151,29 @@ public boolean isContainedWithin(DefaultDomain domain) throws CommandException {
};
}
public void filterIdByMatch(String idFilter) {
this.idFilter = idFilter;
}
@Override
public Integer call() throws Exception {
Map<String, ProtectedRegion> regions = manager.getRegions();
Collection<ProtectedRegion> iterableRegions = regions.values();
if (filterByIntersecting != null) {
iterableRegions = filterByIntersecting.getIntersectingRegions(iterableRegions);
}
// Build a list of regions to show
List<RegionListEntry> entries = new ArrayList<>();
for (Map.Entry<String, ProtectedRegion> rg : regions.entrySet()) {
if (rg.getKey().equals("__global__")) {
for (ProtectedRegion rg : iterableRegions) {
if (rg.getId().equals("__global__")) {
continue;
}
final ProtectedRegion region = rg.getValue();
final RegionListEntry entry = new RegionListEntry(region);
if (entry.matches(ownerMatcher)) {
final RegionListEntry entry = new RegionListEntry(rg);
if (entry.matches(idFilter) && entry.matches(ownerMatcher)) {
entries.add(entry);
}
}
@ -168,7 +184,7 @@ public Integer call() throws Exception {
// insert global on top
if (regions.containsKey("__global__")) {
final RegionListEntry entry = new RegionListEntry(regions.get("__global__"));
if (entry.matches(ownerMatcher)) {
if (entry.matches(idFilter) && entry.matches(ownerMatcher)) {
entries.add(0, entry);
}
}
@ -182,6 +198,8 @@ public Integer call() throws Exception {
String cmd = "/rg list -w \"" + world + "\""
+ (playerName != null ? " -p " + playerName : "")
+ (nameOnly ? " -n" : "")
+ (filterByIntersecting != null ? " -s" : "")
+ (idFilter != null ? " -i " + idFilter : "")
+ " %page%";
PaginationBox box = new RegionListBox(title, cmd, perms, entries, world);
sender.print(box.create(page));
@ -210,6 +228,10 @@ public boolean matches(OwnerMatcher matcher) throws CommandException {
|| (isMember = matcher.isContainedWithin(region.getMembers()));
}
public boolean matches(String idMatcher) {
return idMatcher == null || region.getId().contains(idMatcher);
}
public ProtectedRegion getRegion() {
return region;
}
@ -270,6 +292,12 @@ public Component getComponent(int number) {
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to teleport")))
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND,
"/rg tp -w \"" + world + "\" " + entry.region.getId()))));
} else if (perms != null && perms.mayTeleportToCenter(entry.getRegion()) && entry.getRegion().isPhysicalArea()) {
builder.append(TextComponent.space().append(TextComponent.of("[TP-Center]", TextColor.GRAY)
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT,
TextComponent.of("Click to teleport to the center")))
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND,
"/rg tp -c -w \"" + world + "\" " + entry.region.getId()))));
}
return builder.build();
}

View File

@ -110,6 +110,10 @@ public boolean mayTeleportTo(ProtectedRegion region) {
return hasPatternPermission("teleport", region);
}
public boolean mayTeleportToCenter(ProtectedRegion region) {
return hasPatternPermission("teleportcenter", region);
}
public boolean mayOverrideLocationFlagBounds(ProtectedRegion region) {
return hasPatternPermission("locationoverride", region);
}
@ -129,7 +133,7 @@ public boolean mayList(String targetPlayer) {
return mayList();
}
}
public boolean maySetFlag(ProtectedRegion region) {
return hasPatternPermission("flag.regions", region);
}
@ -199,5 +203,4 @@ private boolean hasPatternPermission(String perm, ProtectedRegion region) {
return hasPluginPermission(effectivePerm);
}
}