Merge pull request #4 from true-og/agent/restrict-creative-to-worldguard-regions
Restrict creative mode to configured WorldGuard regions
This commit was merged in pull request #4.
This commit is contained in:
5 files changed
+161
-12
No files matched your search
@@ -39,12 +39,14 @@ repositories {
|
||||
maven { url = uri("https://repo.purpurmc.org/snapshots") } // Import the PurpurMC Maven Repository.
|
||||
maven("https://hub.spigotmc.org/nexus/content/groups/public/")
|
||||
maven { url = uri("https://maven.playpro.com/") }
|
||||
maven { url = uri("https://maven.enginehub.org/repo/") }
|
||||
}
|
||||
|
||||
/* ---------------------- Java project deps ---------------------------- */
|
||||
dependencies {
|
||||
compileOnly("org.purpurmc.purpur:purpur-api:1.19.4-R0.1-SNAPSHOT") // Declare Purpur API version to be packaged.
|
||||
compileOnly("net.coreprotect:coreprotect:22.4") // Import the CoreProtect API.
|
||||
compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.0.9") // Import the WorldGuard API.
|
||||
implementation("com.zaxxer:HikariCP:5.0.1")
|
||||
implementation("org.slf4j:slf4j-api:2.0.17") // Bundle a relocated SLF4J API for shaded dependencies.
|
||||
implementation("org.slf4j:slf4j-nop:2.0.17") // Provide a relocated no-op SLF4J backend to avoid provider warnings.
|
||||
|
||||
+145
-9
@@ -1,11 +1,19 @@
|
||||
package me.eccentric_nz.gamemodeinventories;
|
||||
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.regions.RegionContainer;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
@@ -18,6 +26,7 @@ import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.EntityPickupItemEvent;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.event.inventory.InventoryOpenEvent;
|
||||
@@ -29,11 +38,23 @@ import org.bukkit.inventory.ItemStack;
|
||||
public class GameModeInventoriesListener implements Listener {
|
||||
|
||||
private final GameModeInventories plugin;
|
||||
List<Material> containers = new ArrayList<>();
|
||||
private final List<Material> containers = new ArrayList<>();
|
||||
private final Set<String> creativeRegions = new HashSet<>();
|
||||
private final Set<UUID> protectedFromForcedFall = new HashSet<>();
|
||||
private final RegionContainer regionContainer;
|
||||
|
||||
public GameModeInventoriesListener(GameModeInventories plugin) {
|
||||
|
||||
this.plugin = plugin;
|
||||
regionContainer = WorldGuard.getInstance().getPlatform().getRegionContainer();
|
||||
List<String> configuredRegions = this.plugin.getConfig().getStringList("creative_regions");
|
||||
if (configuredRegions.isEmpty()) {
|
||||
|
||||
configuredRegions = List.of("spawn");
|
||||
|
||||
}
|
||||
|
||||
configuredRegions.stream().map(region -> region.toLowerCase(Locale.ROOT)).forEach(creativeRegions::add);
|
||||
for (String m : this.plugin.getConfig().getStringList("containers")) {
|
||||
|
||||
try {
|
||||
@@ -51,11 +72,19 @@ public class GameModeInventoriesListener implements Listener {
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||
public void onGameModeChange(PlayerGameModeChangeEvent event) {
|
||||
|
||||
Player p = event.getPlayer();
|
||||
GameMode newGM = event.getNewGameMode();
|
||||
if (newGM.equals(GameMode.CREATIVE) && !canUseCreativeAt(p, p.getLocation())) {
|
||||
|
||||
event.setCancelled(true);
|
||||
forceSurvival(p);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (newGM.equals(GameMode.SPECTATOR) && plugin.getConfig().getBoolean("restrict_spectator")
|
||||
&& !p.hasPermission("gamemodeinventories.spectator") && !p.hasPermission("noclip.use"))
|
||||
{
|
||||
@@ -73,15 +102,11 @@ public class GameModeInventoriesListener implements Listener {
|
||||
plugin.getInventoryHandler().switchInventories(p, newGM);
|
||||
if (newGM.equals(GameMode.CREATIVE) && plugin.getConfig().getBoolean("creative_world.switch_to")) {
|
||||
|
||||
// get spawn location
|
||||
Location loc = plugin.getServer().getWorld(plugin.getConfig().getString("creative_world.world"))
|
||||
.getSpawnLocation();
|
||||
if (plugin.getConfig().getString("creative_world.location").equals("last_known")) {
|
||||
|
||||
// get last known position in world
|
||||
String uuid = p.getUniqueId().toString();
|
||||
// player changed worlds, record last location
|
||||
// check if the player has a record for this world
|
||||
try (Connection connection = plugin.getDatabaseConnection();
|
||||
PreparedStatement statement = connection.prepareStatement(
|
||||
"SELECT * FROM " + plugin.getPrefix() + "worlds WHERE uuid = ? AND world = ?");)
|
||||
@@ -101,7 +126,6 @@ public class GameModeInventoriesListener implements Listener {
|
||||
double z = rs.getDouble("z");
|
||||
float yaw = rs.getFloat("yaw");
|
||||
float pitch = rs.getFloat("pitch");
|
||||
// send to last location
|
||||
loc = new Location(w, x, y, z, yaw, pitch);
|
||||
|
||||
}
|
||||
@@ -132,6 +156,82 @@ public class GameModeInventoriesListener implements Listener {
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onMove(PlayerMoveEvent event) {
|
||||
|
||||
Location to = event.getTo();
|
||||
if (to == null) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
if (protectedFromForcedFall.contains(player.getUniqueId()) && player.isOnGround()) {
|
||||
|
||||
protectedFromForcedFall.remove(player.getUniqueId());
|
||||
|
||||
}
|
||||
|
||||
Location from = event.getFrom();
|
||||
if (player.getGameMode().equals(GameMode.CREATIVE)
|
||||
&& (from.getBlockX() != to.getBlockX() || from.getBlockY() != to.getBlockY()
|
||||
|| from.getBlockZ() != to.getBlockZ())
|
||||
&& !canUseCreativeAt(player, to))
|
||||
{
|
||||
|
||||
forceSurvival(player);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onTeleportCreativeRestriction(PlayerTeleportEvent event) {
|
||||
|
||||
Player player = event.getPlayer();
|
||||
Location to = event.getTo();
|
||||
if (to != null && player.getGameMode().equals(GameMode.CREATIVE) && !canUseCreativeAt(player, to)) {
|
||||
|
||||
plugin.getServer().getScheduler().runTask(plugin, () -> forceSurvival(player));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(PlayerJoinEvent event) {
|
||||
|
||||
Player player = event.getPlayer();
|
||||
if (player.getGameMode().equals(GameMode.CREATIVE) && !canUseCreativeAt(player, player.getLocation())) {
|
||||
|
||||
plugin.getServer().getScheduler().runTask(plugin, () -> forceSurvival(player));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onFallDamage(EntityDamageEvent event) {
|
||||
|
||||
if (event.getCause().equals(EntityDamageEvent.DamageCause.FALL) && event.getEntity() instanceof Player player
|
||||
&& protectedFromForcedFall.remove(player.getUniqueId()))
|
||||
{
|
||||
|
||||
event.setCancelled(true);
|
||||
player.setFallDistance(0.0F);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onQuit(PlayerQuitEvent event) {
|
||||
|
||||
protectedFromForcedFall.remove(event.getPlayer().getUniqueId());
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onInteract(PlayerInteractEvent event) {
|
||||
|
||||
@@ -240,8 +340,7 @@ public class GameModeInventoriesListener implements Listener {
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPlayerInteractAtEntity(PlayerInteractAtEntityEvent event) {
|
||||
|
||||
// treat it the same as interacting with an entity in general
|
||||
onEntityClick((PlayerInteractEntityEvent) event);
|
||||
onEntityClick(event);
|
||||
|
||||
}
|
||||
|
||||
@@ -312,6 +411,43 @@ public class GameModeInventoriesListener implements Listener {
|
||||
|
||||
}
|
||||
|
||||
private boolean canUseCreativeAt(Player player, Location location) {
|
||||
|
||||
if (player.hasPermission("gamemodeinventories.anywhere")) {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
ApplicableRegionSet regions = regionContainer.createQuery().getApplicableRegions(BukkitAdapter.adapt(location));
|
||||
return regions.getRegions().stream()
|
||||
.anyMatch(region -> creativeRegions.contains(region.getId().toLowerCase(Locale.ROOT)));
|
||||
|
||||
}
|
||||
|
||||
private void forceSurvival(Player player) {
|
||||
|
||||
if (!player.isOnline() || player.getGameMode().equals(GameMode.SURVIVAL)) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
protectedFromForcedFall.add(player.getUniqueId());
|
||||
player.setFallDistance(0.0F);
|
||||
player.setGameMode(GameMode.SURVIVAL);
|
||||
plugin.getServer().getScheduler().runTask(plugin, () -> {
|
||||
|
||||
if (player.isOnline() && player.isOnGround()) {
|
||||
|
||||
protectedFromForcedFall.remove(player.getUniqueId());
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private boolean isBlock(Material m) {
|
||||
|
||||
return !m.isAir() && m.isBlock();
|
||||
|
||||
@@ -7,6 +7,7 @@ import java.io.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
@@ -50,7 +51,12 @@ public class GameModeInventoriesMessage {
|
||||
|
||||
messagesConfig.getKeys(false).forEach((m) -> {
|
||||
|
||||
message.put(m, messagesConfig.getString(m));
|
||||
String configuredMessage = messagesConfig.getString(m);
|
||||
if (configuredMessage != null) {
|
||||
|
||||
message.put(m, ChatColor.translateAlternateColorCodes('&', configuredMessage));
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@@ -94,7 +100,6 @@ public class GameModeInventoriesMessage {
|
||||
out.close();
|
||||
|
||||
} catch (IOException e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -112,7 +117,6 @@ public class GameModeInventoriesMessage {
|
||||
in.close();
|
||||
|
||||
} catch (IOException e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -134,6 +138,7 @@ public class GameModeInventoriesMessage {
|
||||
if (!messagesConfig.contains(entry.getKey())) {
|
||||
|
||||
messagesConfig.set(entry.getKey(), entry.getValue());
|
||||
message.put(entry.getKey(), ChatColor.translateAlternateColorCodes('&', entry.getValue()));
|
||||
m++;
|
||||
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ no_wither_spawn: true
|
||||
no_golem_spawn: true
|
||||
remove_potions: false
|
||||
restrict_creative: true
|
||||
creative_regions:
|
||||
- spawn
|
||||
containers:
|
||||
- ANVIL
|
||||
- BARREL
|
||||
|
||||
@@ -3,6 +3,7 @@ description: Allow players to have separate inventories for each game mode (Crea
|
||||
main: me.eccentric_nz.gamemodeinventories.GameModeInventories
|
||||
name: GameModeInventories-OG
|
||||
load: POSTWORLD
|
||||
depend: [ WorldGuard ]
|
||||
softdepend: [ Multiverse-Core,MultiWorld,CoreProtect ]
|
||||
version: 3.5.0
|
||||
api-version: 1.19
|
||||
@@ -27,6 +28,9 @@ permissions:
|
||||
gamemodeinventories.toggle:
|
||||
default: op
|
||||
description: Allow players to toggle between CREATIVE and SURVIVAL with /gmic.
|
||||
gamemodeinventories.anywhere:
|
||||
default: op
|
||||
description: Allow players to use CREATIVE mode outside configured WorldGuard regions.
|
||||
commands:
|
||||
gmi:
|
||||
aliases: [ gmic ]
|
||||
|
||||
Reference in new issue
Block a user