Skip to content

Commit

Permalink
Improve WorldEdit flagging
Browse files Browse the repository at this point in the history
General cleanup
Fix all selections being treated as rectangular
  • Loading branch information
Jikoo committed Feb 11, 2024
1 parent f41d86b commit 8f44591
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 66 deletions.
110 changes: 45 additions & 65 deletions src/main/java/com/github/jikoo/regionerator/commands/FlagHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,17 @@
import com.github.jikoo.regionerator.Regionerator;
import com.github.jikoo.regionerator.util.yaml.Config;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.regions.Region;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
* Class for handling logic related to flag management commands.
Expand All @@ -39,7 +38,7 @@ public FlagHandler(@NotNull Regionerator plugin) {
}

public void handleFlags(@NotNull CommandSender sender, String @NotNull [] args, boolean flag) {
List<ChunkPosition> chunks = getSelectedArea(sender, args);
Set<ChunkPosition> chunks = getSelectedArea(sender, args);
if (chunks == null) {
// More descriptive errors are handled when selecting chunks
return;
Expand All @@ -50,7 +49,7 @@ public void handleFlags(@NotNull CommandSender sender, String @NotNull [] args,
return;
}

String worldName = chunks.get(0).name();
String worldName = chunks.stream().findFirst().get().name();
boolean invalid = true;
for (String world : plugin.config().enabledWorlds()) {
if (world.equalsIgnoreCase(worldName)) {
Expand All @@ -67,7 +66,7 @@ public void handleFlags(@NotNull CommandSender sender, String @NotNull [] args,

for (ChunkPosition chunk : chunks) {
if (flag) {
plugin.getFlagger().flagChunksInRadius(worldName, chunk.chunkX(), chunk.chunkZ(), 0, Config.FLAG_ETERNAL);
plugin.getFlagger().flagChunk(worldName, chunk.chunkX(), chunk.chunkZ(), Config.FLAG_ETERNAL);
} else {
plugin.getFlagger().unflagChunk(worldName, chunk.chunkX(), chunk.chunkZ());
}
Expand All @@ -76,7 +75,7 @@ public void handleFlags(@NotNull CommandSender sender, String @NotNull [] args,
sender.sendMessage("Edited flags successfully!");
}

private @Nullable List<ChunkPosition> getSelectedArea(CommandSender sender, String @NotNull [] args) {
private @Nullable Set<ChunkPosition> getSelectedArea(CommandSender sender, String @NotNull [] args) {
if (args.length < 3 && !(sender instanceof Player)) {
sender.sendMessage("Console usage: /regionerator (un)flag <world> <chunk X> <chunk Z>");
sender.sendMessage("Chunk coordinates = regular coordinates / 16");
Expand All @@ -85,29 +84,7 @@ public void handleFlags(@NotNull CommandSender sender, String @NotNull [] args,

// Flag chunks by chunk coordinates
if (args.length > 2) {

String worldName;
if (args.length > 3) {
worldName = args[1];
} else if (sender instanceof Player) {
worldName = ((Player) sender).getWorld().getName();
} else {
sender.sendMessage("Unable to parse world.");
sender.sendMessage("/regionerator (un)flag [world] <chunk X> <chunk Z>");
return null;
}

int chunkX;
int chunkZ;
try {
chunkX = Integer.parseInt(args[args.length - 2]);
chunkZ = Integer.parseInt(args[args.length - 1]);
} catch (NumberFormatException e) {
sender.sendMessage("/regionerator (un)flag [world] <chunk X> <chunk Z>");
return null;
}
// This looks silly, but it's necessary to make the compiler happy
return Collections.singletonList(new ChunkPosition(worldName, chunkX, chunkZ));
return getExplicitChunk(sender, args);
}

// Safe cast: prior 2 blocks remove all non-players.
Expand All @@ -116,7 +93,7 @@ public void handleFlags(@NotNull CommandSender sender, String @NotNull [] args,
// Flag current chunk
if (args.length < 2) {
Location location = player.getLocation();
return Collections.singletonList(new ChunkPosition(
return Set.of(new ChunkPosition(
player.getWorld().getName(),
Coords.blockToChunk(location.getBlockX()),
Coords.blockToChunk(location.getBlockZ())));
Expand All @@ -131,61 +108,64 @@ public void handleFlags(@NotNull CommandSender sender, String @NotNull [] args,
return null;
}

try {
Class.forName("com.sk89q.worldedit.bukkit.WorldEditPlugin");
} catch (ClassNotFoundException e) {
sender.sendMessage("WorldEdit must be enabled to (un)flag selection!");
return getWorldEditSelection(player);
}

private @Nullable Set<ChunkPosition> getExplicitChunk(@NotNull CommandSender sender, @NotNull String @NotNull [] args) {
String worldName;
if (args.length > 3) {
worldName = args[1];
} else if (sender instanceof Player player) {
worldName = player.getWorld().getName();
} else {
sender.sendMessage("Unable to parse world.");
sender.sendMessage("/regionerator (un)flag [world] <chunk X> <chunk Z>");
return null;
}

WorldEditPlugin worldedit = getWE();
int chunkX;
int chunkZ;
try {
chunkX = Integer.parseInt(args[args.length - 2]);
chunkZ = Integer.parseInt(args[args.length - 1]);
} catch (NumberFormatException e) {
sender.sendMessage("/regionerator (un)flag [world] <chunk X> <chunk Z>");
return null;
}
return Set.of(new ChunkPosition(worldName, chunkX, chunkZ));
}

if (worldedit == null) {
sender.sendMessage("WorldEdit must be enabled to (un)flag selection!");
private @Nullable Set<ChunkPosition> getWorldEditSelection(@NotNull Player player) {
try {
Class.forName("com.sk89q.worldedit.WorldEdit");
} catch (ClassNotFoundException e) {
player.sendMessage("WorldEdit must be enabled to (un)flag selection!");
return null;
}

LocalSession session = worldedit.getSession(player);
LocalSession session = WorldEdit.getInstance().getSessionManager().getIfPresent(BukkitAdapter.adapt(player));

if (session == null || session.getSelectionWorld() == null) {
sender.sendMessage("You must select an area with WorldEdit to (un)flag!");
player.sendMessage("You must select an area with WorldEdit to (un)flag!");
return null;
}

Region selection = null;
try {
selection = session.getSelection(session.getSelectionWorld());
} catch (Exception ignored) {
// Ignored - we return anyway.
// If there was an exception getting their selection, they probably don't have one.
}

if (selection == null) {
sender.sendMessage("You must select an area with WorldEdit to (un)flag!");
player.sendMessage("You must select an area with WorldEdit to (un)flag!");
return null;
}

ArrayList<ChunkPosition> chunks = new ArrayList<>();
String worldName = session.getSelectionWorld().getName();
int maxChunkX = Coords.blockToChunk(selection.getMaximumPoint().getBlockX());
int maxChunkZ = Coords.blockToChunk(selection.getMaximumPoint().getBlockZ());

for (int minChunkX = Coords.blockToChunk(selection.getMinimumPoint().getBlockX());
minChunkX <= maxChunkX; minChunkX++) {
for (int minChunkZ = Coords.blockToChunk(selection.getMinimumPoint().getBlockZ());
minChunkZ <= maxChunkZ; minChunkZ++) {
chunks.add(new ChunkPosition(worldName, minChunkX, minChunkZ));
}
}

return chunks;
}

private @Nullable WorldEditPlugin getWE() {
if (!Bukkit.getPluginManager().isPluginEnabled("WorldEdit")) {
return null;
}

return WorldEditPlugin.getPlugin(WorldEditPlugin.class);
return selection.getChunks().stream()
.map(vector -> new ChunkPosition(worldName, vector.getX(), vector.getZ()))
.collect(Collectors.toUnmodifiableSet());
}

private record ChunkPosition(String name, int chunkX, int chunkZ) {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ public long getLastVisit() {
* @return the VisitStatus
*/
public @NotNull VisitStatus getVisitStatus() {
return visitStatusSupplier.get();
return visitStatusSupplier.get();
}

/**
Expand Down

0 comments on commit 8f44591

Please sign in to comment.