Add region whitelist flag
This commit is contained in:
1 parent
c422e555c7
commit
63acbc99d5
10 files changed
+356
-1
No files matched your search
@@ -10,6 +10,7 @@ import org.battleplugins.arena.spleef.action.GiveShovelAction;
|
||||
import org.battleplugins.arena.spleef.action.PasteLayersAction;
|
||||
import org.battleplugins.arena.spleef.api.SpleefApiListener;
|
||||
import org.battleplugins.arena.spleef.arena.SpleefArena;
|
||||
import org.battleplugins.arena.spleef.hook.GameModeInventoriesListener;
|
||||
import org.battleplugins.arena.spleef.hook.PlayerBountiesListener;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.NamespacedKey;
|
||||
@@ -34,9 +35,26 @@ public class ArenaSpleef extends JavaPlugin {
|
||||
private static ArenaSpleef instance;
|
||||
|
||||
private SpleefConfig config;
|
||||
private GameModeInventoriesListener gameModeInventoriesListener;
|
||||
|
||||
private final NamespacedKey spleefItemKey = new NamespacedKey(this, "spleef_item");
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
|
||||
if (Bukkit.getPluginManager().getPlugin("WorldGuard") != null) {
|
||||
|
||||
SpleefFlags.register(this);
|
||||
|
||||
} else {
|
||||
|
||||
this.getSLF4JLogger().warn(
|
||||
"WorldGuard not present at load time; the 'allow-spleef' region flag will not be registered.");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
|
||||
@@ -72,6 +90,14 @@ public class ArenaSpleef extends JavaPlugin {
|
||||
|
||||
this.getServer().getPluginManager().registerEvents(new SpleefApiListener(), this);
|
||||
|
||||
this.gameModeInventoriesListener = GameModeInventoriesListener.register(this);
|
||||
if (this.gameModeInventoriesListener != null) {
|
||||
|
||||
this.getSLF4JLogger()
|
||||
.info("Hooked into GameModeInventories-OG; Spleef will preserve gamemode-specific inventories.");
|
||||
|
||||
}
|
||||
|
||||
if (PlayerBountiesListener.register(this)) {
|
||||
|
||||
this.getSLF4JLogger().info(
|
||||
@@ -84,6 +110,12 @@ public class ArenaSpleef extends JavaPlugin {
|
||||
@Override
|
||||
public void onDisable() {
|
||||
|
||||
if (this.gameModeInventoriesListener != null) {
|
||||
|
||||
this.gameModeInventoriesListener.releaseAll();
|
||||
|
||||
}
|
||||
|
||||
Bukkit.getScheduler().cancelTasks(this);
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import org.battleplugins.arena.config.ArenaOption;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
public class SpleefConfig {
|
||||
@@ -14,6 +16,9 @@ public class SpleefConfig {
|
||||
@ArenaOption(name = "shovels", description = "The shovels for this spleef game.", required = true)
|
||||
private Map<String, ItemStack> shovels;
|
||||
|
||||
@ArenaOption(name = "world-whitelist", description = "Worlds where Spleef arenas may be created and run. Empty list = all worlds allowed.")
|
||||
private List<String> worldWhitelist;
|
||||
|
||||
public boolean shouldProjectilesBreakBlocks() {
|
||||
|
||||
return this.projectilesBreakBlocks;
|
||||
@@ -34,4 +39,39 @@ public class SpleefConfig {
|
||||
|
||||
}
|
||||
|
||||
public boolean isWorldAllowed(String worldName) {
|
||||
|
||||
if (this.worldWhitelist == null || this.worldWhitelist.isEmpty()) {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
if (worldName == null) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
String target = worldName.toLowerCase(Locale.ROOT);
|
||||
for (String allowed : this.worldWhitelist) {
|
||||
|
||||
if (allowed != null && allowed.toLowerCase(Locale.ROOT).equals(target)) {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public List<String> getWorldWhitelist() {
|
||||
|
||||
return this.worldWhitelist == null ? List.of() : List.copyOf(this.worldWhitelist);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,6 +18,36 @@ public class SpleefExecutor extends ArenaCommandExecutor {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create(Player player) {
|
||||
|
||||
SpleefConfig config = ArenaSpleef.getInstance().getMainConfig();
|
||||
String worldName = player.getWorld().getName();
|
||||
if (config != null && !config.isWorldAllowed(worldName)) {
|
||||
|
||||
SpleefMessages.CREATE_WORLD_NOT_WHITELISTED.send(player, worldName);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (!WorldGuardSupport.isEnabled()) {
|
||||
|
||||
SpleefMessages.CREATE_WG_MISSING.send(player);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (!WorldGuardSupport.isSpleefAllowedAt(player)) {
|
||||
|
||||
SpleefMessages.CREATE_WG_FLAG_REQUIRED.send(player);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
super.create(player);
|
||||
|
||||
}
|
||||
|
||||
@ArenaCommand(commands = "layer", subCommands = "add", description = "Adds a layer to a spleef arena.", permissionNode = "layer.add")
|
||||
public void layer(Player player, CompetitionMap map) {
|
||||
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package org.battleplugins.arena.spleef;
|
||||
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagConflictException;
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public final class SpleefFlags {
|
||||
|
||||
public static final String ALLOW_SPLEEF_FLAG_NAME = "allow-spleef";
|
||||
|
||||
private static StateFlag allowSpleefFlag;
|
||||
|
||||
private SpleefFlags() {
|
||||
|
||||
}
|
||||
|
||||
public static void register(Plugin plugin) {
|
||||
|
||||
FlagRegistry registry = WorldGuard.getInstance().getFlagRegistry();
|
||||
try {
|
||||
|
||||
StateFlag flag = new StateFlag(ALLOW_SPLEEF_FLAG_NAME, false);
|
||||
registry.register(flag);
|
||||
allowSpleefFlag = flag;
|
||||
|
||||
} catch (FlagConflictException conflict) {
|
||||
|
||||
Flag<?> existing = registry.get(ALLOW_SPLEEF_FLAG_NAME);
|
||||
if (existing instanceof StateFlag stateFlag) {
|
||||
|
||||
allowSpleefFlag = stateFlag;
|
||||
plugin.getSLF4JLogger().info("Reusing existing WorldGuard flag '{}'.", ALLOW_SPLEEF_FLAG_NAME);
|
||||
|
||||
} else {
|
||||
|
||||
plugin.getSLF4JLogger().error(
|
||||
"WorldGuard flag '{}' is already registered with an incompatible type; spleef will not enforce it.",
|
||||
ALLOW_SPLEEF_FLAG_NAME);
|
||||
|
||||
}
|
||||
|
||||
} catch (IllegalStateException late) {
|
||||
|
||||
plugin.getSLF4JLogger().error(
|
||||
"Failed to register WorldGuard flag '{}' — registry already locked. Ensure Spleef-OG loads before WorldGuard enables.",
|
||||
ALLOW_SPLEEF_FLAG_NAME, late);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static StateFlag getAllowSpleefFlag() {
|
||||
|
||||
return allowSpleefFlag;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -34,4 +34,13 @@ public final class SpleefMessages {
|
||||
public static final Message DEATH_REGION_SET = Messages.success("spleef-death-region-set",
|
||||
"Death region set successfully!");
|
||||
|
||||
public static final Message CREATE_WORLD_NOT_WHITELISTED = Messages.error("spleef-create-world-not-whitelisted",
|
||||
"Spleef arenas cannot be created in this world. World <secondary>{}</secondary> is not in the Spleef world whitelist.");
|
||||
public static final Message CREATE_WG_FLAG_REQUIRED = Messages.error("spleef-create-wg-flag-required",
|
||||
"You must stand inside a WorldGuard region that has the <secondary>allow-spleef</secondary> flag set to <secondary>allow</secondary> to create a Spleef arena here.");
|
||||
public static final Message CREATE_WG_MISSING = Messages.error("spleef-create-wg-missing",
|
||||
"WorldGuard is not loaded; Spleef arena creation is disabled.");
|
||||
public static final Message WORLD_BLOCKED_AT_RUNTIME = Messages.error("spleef-world-blocked",
|
||||
"Spleef matches are not permitted in world <secondary>{}</secondary>.");
|
||||
|
||||
}
|
||||
@@ -2,11 +2,15 @@ package org.battleplugins.arena.spleef;
|
||||
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public final class WorldGuardSupport {
|
||||
|
||||
@@ -36,4 +40,29 @@ public final class WorldGuardSupport {
|
||||
|
||||
}
|
||||
|
||||
public static boolean isSpleefAllowedAt(Player player) {
|
||||
|
||||
StateFlag flag = SpleefFlags.getAllowSpleefFlag();
|
||||
if (flag == null) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
|
||||
Location location = player.getLocation();
|
||||
RegionManager regionManager = WorldGuard.getInstance().getPlatform().getRegionContainer()
|
||||
.get(BukkitAdapter.adapt(location.getWorld()));
|
||||
if (regionManager == null) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
BlockVector3 position = BlockVector3.at(location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
||||
ApplicableRegionSet regions = regionManager.getApplicableRegions(position);
|
||||
return regions.testState(localPlayer, flag);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -84,6 +84,17 @@ public class SpleefArena extends Arena {
|
||||
|
||||
if (event.getCompetition() instanceof SpleefCompetition spleefCompetition) {
|
||||
|
||||
org.bukkit.World mapWorld = spleefCompetition.getMap().getWorld();
|
||||
String worldName = mapWorld == null ? null : mapWorld.getName();
|
||||
if (!ArenaSpleef.getInstance().getMainConfig().isWorldAllowed(worldName)) {
|
||||
|
||||
ArenaSpleef.getInstance().getSLF4JLogger().warn(
|
||||
"Refusing to start Spleef competition '{}' — world '{}' is not in the Spleef world whitelist.",
|
||||
spleefCompetition.getMap().getName(), worldName);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
spleefCompetition.beginLayerDecay();
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
package org.battleplugins.arena.spleef.hook;
|
||||
|
||||
import org.battleplugins.arena.event.player.ArenaJoinEvent;
|
||||
import org.battleplugins.arena.event.player.ArenaLeaveEvent;
|
||||
import org.battleplugins.arena.event.player.ArenaSpectateEvent;
|
||||
import org.battleplugins.arena.spleef.api.SpleefAPI;
|
||||
import org.battleplugins.arena.spleef.arena.SpleefCompetition;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.permissions.PermissionAttachment;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public final class GameModeInventoriesListener implements Listener {
|
||||
|
||||
public static final String PLUGIN_NAME = "GameModeInventories-OG";
|
||||
|
||||
private static final String USE_PERMISSION = "gamemodeinventories.use";
|
||||
|
||||
private final Plugin owner;
|
||||
private final Map<UUID, PermissionAttachment> attachments = new HashMap<>();
|
||||
|
||||
private GameModeInventoriesListener(Plugin owner) {
|
||||
|
||||
this.owner = owner;
|
||||
|
||||
}
|
||||
|
||||
public static GameModeInventoriesListener register(Plugin owner) {
|
||||
|
||||
final Plugin gameModeInventories = Bukkit.getPluginManager().getPlugin(PLUGIN_NAME);
|
||||
if (gameModeInventories == null || !gameModeInventories.isEnabled()) {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
final GameModeInventoriesListener listener = new GameModeInventoriesListener(owner);
|
||||
Bukkit.getPluginManager().registerEvents(listener, owner);
|
||||
return listener;
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||
public void onArenaJoin(ArenaJoinEvent event) {
|
||||
|
||||
if (event.getArenaPlayer().getCompetition() instanceof SpleefCompetition) {
|
||||
|
||||
this.suspend(event.getPlayer());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||
public void onArenaSpectate(ArenaSpectateEvent event) {
|
||||
|
||||
if (event.getArenaPlayer().getCompetition() instanceof SpleefCompetition) {
|
||||
|
||||
this.suspend(event.getPlayer());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onArenaLeave(ArenaLeaveEvent event) {
|
||||
|
||||
if (!(event.getArenaPlayer().getCompetition() instanceof SpleefCompetition)) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
final Player player = event.getPlayer();
|
||||
Bukkit.getScheduler().runTask(this.owner, () -> {
|
||||
|
||||
if (!SpleefAPI.isInSpleef(player)) {
|
||||
|
||||
this.release(player);
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void releaseAll() {
|
||||
|
||||
for (PermissionAttachment attachment : this.attachments.values()) {
|
||||
|
||||
try {
|
||||
|
||||
attachment.remove();
|
||||
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.attachments.clear();
|
||||
|
||||
}
|
||||
|
||||
private void suspend(Player player) {
|
||||
|
||||
// Keep GMI from saving arena-cleared contents over real inventories.
|
||||
this.attachments.computeIfAbsent(player.getUniqueId(),
|
||||
key -> player.addAttachment(this.owner, USE_PERMISSION, false));
|
||||
|
||||
}
|
||||
|
||||
private void release(Player player) {
|
||||
|
||||
final PermissionAttachment attachment = this.attachments.remove(player.getUniqueId());
|
||||
if (attachment == null) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
attachment.remove();
|
||||
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,6 +10,10 @@ config-version: 2.0 # The config version, do not change!
|
||||
# Whether projectiles (i.e. snowballs) should break blocks or not.
|
||||
projectiles-break-blocks: false
|
||||
|
||||
# Worlds where Spleef arenas may be created and where matches may run.
|
||||
# Leave empty to allow every world. Names are matched case-insensitively.
|
||||
world-whitelist: []
|
||||
|
||||
# The shovels to use for Spleef.
|
||||
shovels:
|
||||
classic: diamond_shovel{display-name=<yellow>Spleef Shovel}
|
||||
|
||||
@@ -6,4 +6,4 @@ author: BattlePlugins
|
||||
website: https://battleplugins.org
|
||||
api-version: ${apiVersion}
|
||||
depend: [BattleArena, WorldGuard]
|
||||
softdepend: [HorseTp-OG, PetTeleport-OG, PlayerBounties-OG, WorldEdit]
|
||||
softdepend: [GameModeInventories-OG, HorseTp-OG, PetTeleport-OG, PlayerBounties-OG, WorldEdit]
|
||||
Reference in new issue
Block a user