mirror of
https://github.com/Samsuik/Sakura.git
synced 2025-12-19 14:59:30 +00:00
add regions to debug command and fix large overlapping regions
This commit is contained in:
@@ -0,0 +1,88 @@
|
|||||||
|
package me.samsuik.sakura.command;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@NullMarked
|
||||||
|
public abstract class BaseMenuCommand extends BaseSubCommand {
|
||||||
|
private static final String HEADER_MESSAGE = "<dark_purple>| <white><message>";
|
||||||
|
private static final String COMMAND_MSG = "<dark_purple>| <dark_gray>*</dark_gray> /<light_purple><command>";
|
||||||
|
|
||||||
|
public BaseMenuCommand(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract String header();
|
||||||
|
|
||||||
|
public Iterable<Command> helpCommands() {
|
||||||
|
return this.subCommands();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract Iterable<Command> subCommands();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void execute(CommandSender sender, String[] args) {
|
||||||
|
if (args.length > 0) {
|
||||||
|
for (final Command base : this.subCommands()) {
|
||||||
|
if (base.getName().equalsIgnoreCase(args[0])) {
|
||||||
|
base.execute(sender, "", Arrays.copyOfRange(args, 1, args.length));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sendHelpMessage(sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendHelpMessage(CommandSender sender) {
|
||||||
|
sender.sendMessage(Component.text(".", NamedTextColor.DARK_PURPLE));
|
||||||
|
for (final String header : this.header().split("\n")) {
|
||||||
|
if (!header.isEmpty()) {
|
||||||
|
sender.sendRichMessage(HEADER_MESSAGE, Placeholder.unparsed("message", header));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final Command command : this.helpCommands()) {
|
||||||
|
if (command != this) {
|
||||||
|
sender.sendRichMessage(COMMAND_MSG, Placeholder.unparsed("command", command.getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sender.sendMessage(Component.text("'", NamedTextColor.DARK_PURPLE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
|
||||||
|
if (!this.testPermissionSilent(sender) || args.length == 0) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
final Command command = SakuraCommands.getCommand(args[0]);
|
||||||
|
final List<String> completions = new ArrayList<>();
|
||||||
|
if (command != null && args.length > 1) {
|
||||||
|
final String[] newArgs = Arrays.copyOfRange(args, 1, args.length);
|
||||||
|
completions.addAll(command.tabComplete(sender, alias, newArgs));
|
||||||
|
} else {
|
||||||
|
for (final Command subCommand : SakuraCommands.SUB_COMMANDS) {
|
||||||
|
final String commandName = subCommand.getName();
|
||||||
|
if (commandName.startsWith(args[0])) {
|
||||||
|
completions.add(commandName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final String lastArg = args[args.length - 1];
|
||||||
|
return completions.stream()
|
||||||
|
.filter(result -> result.startsWith(lastArg))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -42,6 +42,10 @@ public abstract class BaseSubCommand extends Command {
|
|||||||
return completions;
|
return completions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void sendPlayerOnlyMessage(CommandSender sender) {
|
||||||
|
sender.sendRichMessage("<red>This command can only be ran by players");
|
||||||
|
}
|
||||||
|
|
||||||
protected final Optional<Integer> parseInt(String[] args, int index) {
|
protected final Optional<Integer> parseInt(String[] args, int index) {
|
||||||
return this.parse(args, index, Integer::parseInt);
|
return this.parse(args, index, Integer::parseInt);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,84 +1,33 @@
|
|||||||
package me.samsuik.sakura.command;
|
package me.samsuik.sakura.command;
|
||||||
|
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.jspecify.annotations.NullMarked;
|
import org.jspecify.annotations.NullMarked;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@NullMarked
|
@NullMarked
|
||||||
public final class SakuraCommand extends Command {
|
public final class SakuraCommand extends BaseMenuCommand {
|
||||||
private static final Component HEADER_MESSAGE = MiniMessage.miniMessage().deserialize("""
|
|
||||||
<dark_purple>.</dark_purple>
|
|
||||||
<dark_purple>| <white>This is the main command for <gradient:red:light_purple:0.5>Sakura</gradient>.
|
|
||||||
<dark_purple>| <white>All exclusive commands are listed below."""
|
|
||||||
);
|
|
||||||
|
|
||||||
private static final String COMMAND_MSG = "<dark_purple>| <dark_gray>*</dark_gray> /<light_purple><command>";
|
|
||||||
|
|
||||||
public SakuraCommand(String name) {
|
public SakuraCommand(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
this.description = "";
|
this.description = "";
|
||||||
this.usageMessage = "/sakura";
|
|
||||||
this.setPermission("bukkit.command.sakura");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(CommandSender sender, String commandLabel, String[] args) {
|
public String header() {
|
||||||
if (args.length > 0) {
|
return "This is the main command for <gradient:red:light_purple:0.5>Sakura</gradient>.\n" +
|
||||||
final Command versionCommand = MinecraftServer.getServer().server.getCommandMap().getCommand("version");
|
"All exclusive commands are listed below.";
|
||||||
for (final Command base : Iterables.concat(SakuraCommands.SUB_COMMANDS, List.of(versionCommand))) {
|
|
||||||
if (base.getName().equalsIgnoreCase(args[0])) {
|
|
||||||
return base.execute(sender, commandLabel, Arrays.copyOfRange(args, 1, args.length));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.sendHelpMessage(sender);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendHelpMessage(CommandSender sender) {
|
|
||||||
sender.sendMessage(HEADER_MESSAGE);
|
|
||||||
|
|
||||||
for (final Command command : SakuraCommands.COMMANDS.values()) {
|
|
||||||
if (command != this) {
|
|
||||||
sender.sendRichMessage(COMMAND_MSG, Placeholder.unparsed("command", command.getName()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sender.sendMessage(Component.text("'", NamedTextColor.DARK_PURPLE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
|
public Iterable<Command> helpCommands() {
|
||||||
if (!this.testPermissionSilent(sender) || args.length == 0) {
|
return SakuraCommands.COMMANDS.values();
|
||||||
return Collections.emptyList();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
final Command command = SakuraCommands.getCommand(args[0]);
|
@Override
|
||||||
final List<String> completions = new ArrayList<>();
|
public Iterable<Command> subCommands() {
|
||||||
if (command != null && args.length > 1) {
|
final Command versionCommand = MinecraftServer.getServer().server.getCommandMap().getCommand("version");
|
||||||
final String[] newArgs = Arrays.copyOfRange(args, 1, args.length);
|
return Iterables.concat(SakuraCommands.SUB_COMMANDS, List.of(versionCommand));
|
||||||
completions.addAll(command.tabComplete(sender, alias, newArgs));
|
|
||||||
} else {
|
|
||||||
for (final Command subCommand : SakuraCommands.SUB_COMMANDS) {
|
|
||||||
final String commandName = subCommand.getName();
|
|
||||||
if (commandName.startsWith(args[0])) {
|
|
||||||
completions.add(commandName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final String lastArg = args[args.length - 1];
|
|
||||||
return completions.stream()
|
|
||||||
.filter(result -> result.startsWith(lastArg))
|
|
||||||
.toList();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package me.samsuik.sakura.command;
|
package me.samsuik.sakura.command;
|
||||||
|
|
||||||
import me.samsuik.sakura.command.subcommands.*;
|
import me.samsuik.sakura.command.subcommands.*;
|
||||||
|
import me.samsuik.sakura.command.subcommands.debug.DebugLocalRegions;
|
||||||
|
import me.samsuik.sakura.command.subcommands.debug.DebugRedstoneCache;
|
||||||
import me.samsuik.sakura.player.visibility.VisibilityTypes;
|
import me.samsuik.sakura.player.visibility.VisibilityTypes;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
@@ -14,8 +16,9 @@ import java.util.Set;
|
|||||||
|
|
||||||
@NullMarked
|
@NullMarked
|
||||||
public final class SakuraCommands {
|
public final class SakuraCommands {
|
||||||
static final Map<String, Command> COMMANDS = new HashMap<>();
|
public static final Map<String, Command> COMMANDS = new HashMap<>();
|
||||||
static final Set<Command> SUB_COMMANDS = new HashSet<>();
|
public static final Set<Command> SUB_COMMANDS = new HashSet<>();
|
||||||
|
public static final Set<Command> DEBUG_COMMANDS = new HashSet<>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
COMMANDS.put("config", new ConfigCommand("config"));
|
COMMANDS.put("config", new ConfigCommand("config"));
|
||||||
@@ -27,6 +30,8 @@ public final class SakuraCommands {
|
|||||||
SUB_COMMANDS.add(new DebugCommand("debug"));
|
SUB_COMMANDS.add(new DebugCommand("debug"));
|
||||||
// "sakura" isn't a subcommand
|
// "sakura" isn't a subcommand
|
||||||
COMMANDS.put("sakura", new SakuraCommand("sakura"));
|
COMMANDS.put("sakura", new SakuraCommand("sakura"));
|
||||||
|
DEBUG_COMMANDS.add(new DebugRedstoneCache("redstone-cache"));
|
||||||
|
DEBUG_COMMANDS.add(new DebugLocalRegions("local-regions"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void registerCommands(MinecraftServer server) {
|
public static void registerCommands(MinecraftServer server) {
|
||||||
|
|||||||
@@ -1,74 +1,23 @@
|
|||||||
package me.samsuik.sakura.command.subcommands;
|
package me.samsuik.sakura.command.subcommands;
|
||||||
|
|
||||||
import me.samsuik.sakura.command.BaseSubCommand;
|
import me.samsuik.sakura.command.BaseMenuCommand;
|
||||||
import me.samsuik.sakura.redstone.RedstoneNetwork;
|
import me.samsuik.sakura.command.SakuraCommands;
|
||||||
import net.minecraft.core.BlockPos;
|
import org.bukkit.command.Command;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import org.bukkit.DyeColor;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
|
||||||
import org.bukkit.craftbukkit.util.CraftLocation;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.jspecify.annotations.NullMarked;
|
import org.jspecify.annotations.NullMarked;
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
|
||||||
|
|
||||||
@NullMarked
|
@NullMarked
|
||||||
public final class DebugCommand extends BaseSubCommand {
|
public final class DebugCommand extends BaseMenuCommand {
|
||||||
public DebugCommand(String name) {
|
public DebugCommand(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, String[] args) {
|
public String header() {
|
||||||
if (!(sender instanceof Player player) || args.length == 0) {
|
return "Debug command for testing Sakura features and api";
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerPlayer nmsPlayer = ((CraftPlayer) player).getHandle();
|
|
||||||
if (args[0].equalsIgnoreCase("redstone-cache")) {
|
|
||||||
this.showCachedWires(player, nmsPlayer.level());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tabComplete(List<String> list, String[] args) throws IllegalArgumentException {
|
public Iterable<Command> subCommands() {
|
||||||
list.add("redstone-cache");
|
return SakuraCommands.DEBUG_COMMANDS;
|
||||||
}
|
|
||||||
|
|
||||||
private void showCachedWires(Player player, Level level) {
|
|
||||||
Set<Location> locations = new HashSet<>();
|
|
||||||
for (RedstoneNetwork network : level.redstoneWireCache.getNetworkCache().values()) {
|
|
||||||
byte randomColour = (byte) ThreadLocalRandom.current().nextInt(16);
|
|
||||||
DyeColor dyeColour = DyeColor.getByWoolData(randomColour);
|
|
||||||
Material material = Material.matchMaterial(dyeColour.name() + "_WOOL");
|
|
||||||
|
|
||||||
if (!network.isRegistered()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (BlockPos pos : network.getWirePositions()) {
|
|
||||||
Location location = CraftLocation.toBukkit(pos, level);
|
|
||||||
if (player.getLocation().distance(location) >= 64.0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
player.sendBlockChange(location, material.createBlockData());
|
|
||||||
locations.add(location);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
player.sendRichMessage("<red>Displaying %dx cached redstone wires".formatted(locations.size()));
|
|
||||||
|
|
||||||
level.levelTickScheduler.delayedTask(() -> {
|
|
||||||
for (Location loc : locations) {
|
|
||||||
player.sendBlockChange(loc, loc.getBlock().getBlockData());
|
|
||||||
}
|
|
||||||
}, 1200);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package me.samsuik.sakura.command.subcommands.debug;
|
||||||
|
|
||||||
|
import me.samsuik.sakura.command.BaseSubCommand;
|
||||||
|
import me.samsuik.sakura.local.LocalRegion;
|
||||||
|
import me.samsuik.sakura.local.storage.LocalStorageHandler;
|
||||||
|
import me.samsuik.sakura.local.storage.LocalValueStorage;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@NullMarked
|
||||||
|
public final class DebugLocalRegions extends BaseSubCommand {
|
||||||
|
private static final int DEFAULT_REGION_SIZE = 16;
|
||||||
|
|
||||||
|
public DebugLocalRegions(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender sender, String[] args) {
|
||||||
|
if (!(sender instanceof Player player)) {
|
||||||
|
this.sendPlayerOnlyMessage(sender);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Location location = player.getLocation();
|
||||||
|
final World world = location.getWorld();
|
||||||
|
final LocalStorageHandler storageHandler = world.getStorageHandler();
|
||||||
|
final int blockX = location.getBlockX();
|
||||||
|
final int blockZ = location.getBlockZ();
|
||||||
|
final Optional<LocalRegion> currentRegion = storageHandler.locate(blockX, blockZ);
|
||||||
|
|
||||||
|
if ("create".equalsIgnoreCase(args[0])) {
|
||||||
|
final int size = parseInt(args, 1).orElse(DEFAULT_REGION_SIZE);
|
||||||
|
final LocalRegion region = LocalRegion.at(blockX, blockZ, size);
|
||||||
|
storageHandler.put(region, new LocalValueStorage());
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("get".equalsIgnoreCase(args[0])) {
|
||||||
|
sender.sendRichMessage("<red>" + (currentRegion.isPresent() ? currentRegion.get() : "not inside of a region"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentRegion.isPresent()) {
|
||||||
|
final LocalRegion region = currentRegion.get();
|
||||||
|
if ("delete".equalsIgnoreCase(args[0])) {
|
||||||
|
storageHandler.remove(region);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package me.samsuik.sakura.command.subcommands.debug;
|
||||||
|
|
||||||
|
import me.samsuik.sakura.command.BaseSubCommand;
|
||||||
|
import me.samsuik.sakura.redstone.RedstoneNetwork;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import org.bukkit.DyeColor;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||||
|
import org.bukkit.craftbukkit.util.CraftLocation;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
|
@NullMarked
|
||||||
|
public final class DebugRedstoneCache extends BaseSubCommand {
|
||||||
|
public DebugRedstoneCache(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender sender, String[] args) {
|
||||||
|
if (!(sender instanceof Player player)) {
|
||||||
|
this.sendPlayerOnlyMessage(sender);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerPlayer nmsPlayer = ((CraftPlayer) player).getHandle();
|
||||||
|
Level level = nmsPlayer.level();
|
||||||
|
Set<Location> locations = new HashSet<>();
|
||||||
|
for (RedstoneNetwork network : level.redstoneWireCache.getNetworkCache().values()) {
|
||||||
|
byte randomColour = (byte) ThreadLocalRandom.current().nextInt(16);
|
||||||
|
DyeColor dyeColour = DyeColor.getByWoolData(randomColour);
|
||||||
|
Material material = Material.matchMaterial(dyeColour.name() + "_WOOL");
|
||||||
|
|
||||||
|
if (!network.isRegistered()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (BlockPos pos : network.getWirePositions()) {
|
||||||
|
Location location = CraftLocation.toBukkit(pos, level);
|
||||||
|
if (player.getLocation().distance(location) >= 64.0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
player.sendBlockChange(location, material.createBlockData());
|
||||||
|
locations.add(location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
player.sendRichMessage("<red>Displaying %dx cached redstone wires".formatted(locations.size()));
|
||||||
|
|
||||||
|
level.levelTickScheduler.delayedTask(() -> {
|
||||||
|
for (Location loc : locations) {
|
||||||
|
player.sendBlockChange(loc, loc.getBlock().getBlockData());
|
||||||
|
}
|
||||||
|
}, 1200);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -62,10 +62,12 @@ public final class LocalConfigManager implements LocalStorageHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void put(@NonNull LocalRegion region, @NonNull LocalValueStorage storage) {
|
public synchronized void put(@NonNull LocalRegion region, @NonNull LocalValueStorage storage) {
|
||||||
this.ensureNotOverlapping(region);
|
|
||||||
int shift = this.regionExponent;
|
int shift = this.regionExponent;
|
||||||
int regionChunks = regionChunks(region, shift);
|
int regionChunks = regionChunks(region, shift);
|
||||||
|
|
||||||
|
// make sure there's no overlapping regions
|
||||||
|
this.ensureRegionIsNotOverlapping(region, regionChunks);
|
||||||
|
|
||||||
if (regionChunks <= SMALL_REGION_SIZE) {
|
if (regionChunks <= SMALL_REGION_SIZE) {
|
||||||
this.forEachRegionChunks(region, pos -> {
|
this.forEachRegionChunks(region, pos -> {
|
||||||
this.smallRegions.computeIfAbsent(pos, k -> new ArrayList<>())
|
this.smallRegions.computeIfAbsent(pos, k -> new ArrayList<>())
|
||||||
@@ -73,8 +75,9 @@ public final class LocalConfigManager implements LocalStorageHandler {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.largeRegions.add(region);
|
this.largeRegions.add(region);
|
||||||
// The region exponent might be too small
|
|
||||||
if (this.largeRegions.size() % 24 == 0) {
|
// The region exponent may be too small
|
||||||
|
if ((this.largeRegions.size() & 15) == 0) {
|
||||||
this.resizeRegions();
|
this.resizeRegions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -189,14 +192,18 @@ public final class LocalConfigManager implements LocalStorageHandler {
|
|||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ensureNotOverlapping(LocalRegion region) {
|
private void ensureRegionIsNotOverlapping(LocalRegion region, int regionChunks) {
|
||||||
Set<LocalRegion> nearbyRegions = new ReferenceOpenHashSet<>();
|
Set<LocalRegion> nearbyRegions = new ReferenceOpenHashSet<>();
|
||||||
this.forEachRegionChunks(region, pos -> {
|
if (regionChunks > SMALL_REGION_SIZE) {
|
||||||
nearbyRegions.addAll(this.smallRegions.getOrDefault(pos, List.of()));
|
nearbyRegions.addAll(this.storageMap.keySet());
|
||||||
});
|
} else {
|
||||||
|
this.forEachRegionChunks(region, pos -> {
|
||||||
|
nearbyRegions.addAll(this.smallRegions.getOrDefault(pos, List.of()));
|
||||||
|
});
|
||||||
|
}
|
||||||
for (LocalRegion present : Iterables.concat(nearbyRegions, this.largeRegions)) {
|
for (LocalRegion present : Iterables.concat(nearbyRegions, this.largeRegions)) {
|
||||||
if (present != region && present.intersects(region)) {
|
if (present != region && present.intersects(region)) {
|
||||||
throw new UnsupportedOperationException("overlapping region (%s, %s)".formatted(present, region));
|
throw new OverlappingRegionException(present, region);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package me.samsuik.sakura.configuration.local;
|
||||||
|
|
||||||
|
import me.samsuik.sakura.local.LocalRegion;
|
||||||
|
|
||||||
|
public final class OverlappingRegionException extends RuntimeException {
|
||||||
|
public OverlappingRegionException(LocalRegion presentRegion, LocalRegion region) {
|
||||||
|
super("overlapping region (%s, %s)".formatted(presentRegion, region));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user