WorldGuard region support

This commit is contained in:
Esophose 2020-05-13 01:15:48 -06:00
parent 4afc2135b1
commit 179c6b58e1
17 changed files with 172 additions and 27 deletions

View file

@ -10,7 +10,7 @@ sourceCompatibility = 1.8
targetCompatibility = 1.8
compileJava.options.encoding = 'UTF-8'
group = 'dev.esophose'
version = '7.11'
version = '7.12'
java {
withJavadocJar()
@ -31,6 +31,7 @@ dependencies {
compile 'org.slf4j:slf4j-nop:1.7.25'
compile 'com.zaxxer:HikariCP:3.2.0'
compile 'org.bstats:bstats-bukkit-lite:1.7'
compile 'org.codemc.worldguardwrapper:worldguardwrapper:1.1.6-SNAPSHOT'
shadow 'com.googlecode.json-simple:json-simple:1.1.1'
shadow 'org.jetbrains:annotations:16.0.2'
shadow 'me.clip:placeholderapi:2.10.4'
@ -45,6 +46,7 @@ shadowJar {
relocate('org.bstats', 'dev.esophose.playerparticles.libs.bstats')
relocate('org.slf4j', 'dev.esophose.playerparticles.libs.slf4j')
relocate('com.zaxxer.hikari', 'dev.esophose.playerparticles.libs.hikaricp')
relocate('org.codemc.worldguardwrapper', 'dev.esophose.playerparticles.libs.worldguardwrapper')
}
processResources {

View file

@ -1,3 +1,8 @@
=== v7.12 ===
+ Added WorldGuard region support
+ Added permission 'playerparticles.worldguard.bypass'
+ Added placeholder %playerparticles_is_in_allowed_region%
* Fixed empty player list bug with versions older than 1.9
=== v7.11 ===
+ Added support for Spigot 1.8.8 and 1.7.10. I make no guarantees this will work perfectly.
* The plugin will now disable and print an error message on startup if the server is running CraftBukkit

View file

@ -36,6 +36,8 @@ public class ParticlePlaceholderExpansion extends PlaceholderExpansion {
return String.valueOf(pplayer.isMoving());
case "is_in_combat":
return String.valueOf(pplayer.isInCombat());
case "is_in_allowed_region":
return String.valueOf(pplayer.isInAllowedRegion());
case "can_see_particles":
return String.valueOf(pplayer.canSeeParticles());
}

View file

@ -0,0 +1,51 @@
package dev.esophose.playerparticles.hook;
import dev.esophose.playerparticles.manager.ConfigurationManager.Setting;
import java.util.List;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.codemc.worldguardwrapper.WorldGuardWrapper;
import org.codemc.worldguardwrapper.region.IWrappedRegion;
public class WorldGuardHook {
private static Boolean enabled;
private static WorldGuardWrapper worldGuardWrapper;
/**
* @return true if WorldGuard is enabled, otherwise false
*/
public static boolean enabled() {
if (enabled != null)
return enabled;
enabled = Bukkit.getPluginManager().getPlugin("WorldGuard") != null;
worldGuardWrapper = WorldGuardWrapper.getInstance();
return enabled;
}
/**
* Checks if a location is in a region that allows particles to spawn
*
* @param location The location to check
* @return true if the location is in an allowed region, otherwise false
*/
public static boolean isInAllowedRegion(Location location) {
if (!enabled())
return true;
Set<IWrappedRegion> regions = worldGuardWrapper.getRegions(location);
List<String> disallowedRegionIds = Setting.WORLDGUARD_DISALLOWED_REGIONS.getStringList();
if (regions.stream().map(IWrappedRegion::getId).anyMatch(disallowedRegionIds::contains))
return false;
if (Setting.WORLDGUARD_USE_ALLOWED_REGIONS.getBoolean()) {
List<String> allowedRegionIds = Setting.WORLDGUARD_ALLOWED_REGIONS.getStringList();
return regions.stream().map(IWrappedRegion::getId).anyMatch(allowedRegionIds::contains);
}
return true;
}
}

View file

@ -57,6 +57,13 @@ public class ConfigurationManager extends Manager {
DUST_SIZE("dust-size", 1.0, "How large should dust particles appear?", "Note: Can include decimals", "Only works in 1.13+"),
GUI_GROUP_CREATION_MESSAGE_DISPLAY_AREA("gui-group-creation-message-display-area", "ACTION_BAR", "Valid values: ACTION_BAR, TITLE, CHAT", "Where should the GUI group creation countdown message be displayed?", "Note: Server versions less than 1.11.2 will always use CHAT"),
WORLDGUARD_SETTINGS("worldguard-settings", null, "Settings for WorldGuard", "If WorldGuard is not installed, these settings will do nothing"),
WORLDGUARD_USE_ALLOWED_REGIONS("worldguard-settings.use-allowed-regions", false, "If true, particles will be able to spawn unless they are in a disallowed region", "If false, particles will not be able to spawn unless they are in an allowed region"),
WORLDGUARD_ALLOWED_REGIONS("worldguard-settings.allowed-regions", Arrays.asList("example_region_1", "example_region_2"), "Regions that particles will be allowed to spawn in"),
WORLDGUARD_DISALLOWED_REGIONS("worldguard-settings.disallowed-regions", Arrays.asList("example_region_3", "example_region_4"), "Regions that particles will be blocked from spawning in", "This overrides allowed regions if they overlap"),
WORLDGUARD_CHECK_INTERVAL("worldguard-settings.check-interval", 10, "How often to check if a player is in a region that allows spawning particles", "Measured in ticks"),
WORLDGUARD_ENABLE_BYPASS_PERMISSION("worldguard-settings.enable-bypass-permission", false, "If true, the permission playerparticles.worldguard.bypass will allow", "the player to bypass the region requirements"),
MYSQL_SETTINGS("mysql-settings", null, "Settings for if you want to use MySQL for data management"),
MYSQL_ENABLED("mysql-settings.enabled", false, "Enable MySQL", "If false, SQLite will be used instead"),
MYSQL_HOSTNAME("mysql-settings.hostname", "", "MySQL Database Hostname"),

View file

@ -1,6 +1,7 @@
package dev.esophose.playerparticles.manager;
import dev.esophose.playerparticles.PlayerParticles;
import dev.esophose.playerparticles.hook.WorldGuardHook;
import dev.esophose.playerparticles.manager.ConfigurationManager.Setting;
import dev.esophose.playerparticles.particles.ConsolePPlayer;
import dev.esophose.playerparticles.particles.FixedParticleEffect;
@ -43,6 +44,11 @@ public class ParticleManager extends Manager implements Listener, Runnable {
*/
private BukkitTask particleTask;
/**
* The task that checks player worldguard region statuses
*/
private BukkitTask worldGuardTask;
/**
* Rainbow particle effect hue and note color used for rainbow colorable effects
*/
@ -67,10 +73,20 @@ public class ParticleManager extends Manager implements Listener, Runnable {
if (this.particleTask != null)
this.particleTask.cancel();
if (this.worldGuardTask != null) {
this.worldGuardTask.cancel();
this.worldGuardTask = null;
}
Bukkit.getScheduler().runTaskLater(this.playerParticles, () -> {
long ticks = Setting.TICKS_PER_PARTICLE.getLong();
this.particleTask = Bukkit.getScheduler().runTaskTimerAsynchronously(this.playerParticles, this, 5, ticks);
}, 1);
this.particleTask = Bukkit.getScheduler().runTaskTimerAsynchronously(this.playerParticles, this, 0, ticks);
if (WorldGuardHook.enabled()) {
long worldGuardTicks = Setting.WORLDGUARD_CHECK_INTERVAL.getLong();
this.worldGuardTask = Bukkit.getScheduler().runTaskTimer(this.playerParticles, this::updateWorlGuardStatuses, 0, worldGuardTicks);
}
}, 5);
this.particlePlayers.clear();
DataManager dataManager = this.playerParticles.getManager(DataManager.class);
@ -164,6 +180,25 @@ public class ParticleManager extends Manager implements Listener, Runnable {
}
}
/**
* Updates the WorldGuard region statuses for players
*/
private void updateWorlGuardStatuses() {
PermissionManager permissionManager = this.playerParticles.getManager(PermissionManager.class);
for (PPlayer pplayer : this.particlePlayers.values()) {
Player player = pplayer.getPlayer();
if (player == null)
continue;
boolean inAllowedRegion = WorldGuardHook.isInAllowedRegion(player.getLocation());
if (!inAllowedRegion && Setting.WORLDGUARD_ENABLE_BYPASS_PERMISSION.getBoolean())
inAllowedRegion = permissionManager.hasWorldGuardBypass(player);
pplayer.setInAllowedRegion(inAllowedRegion);
}
}
/**
* Displays particles at the given player location with their settings
*
@ -176,6 +211,9 @@ public class ParticleManager extends Manager implements Listener, Runnable {
if (Setting.TOGGLE_ON_COMBAT.getBoolean() && particle.getStyle().canToggleWithCombat() && pplayer.isInCombat())
return;
if (!pplayer.isInAllowedRegion())
return;
if (particle.getStyle().canToggleWithMovement() && pplayer.isMoving()) {
switch (Setting.TOGGLE_ON_MOVE.getString().toUpperCase()) {
case "DISPLAY_FEET":
@ -207,14 +245,22 @@ public class ParticleManager extends Manager implements Listener, Runnable {
/**
* An alternative method used for event styles
*
* @param player The player the particles are spawning from, nullable for special cases
* @param pplayer The PPlayer the particles are spawning from, nullable for special cases
* @param world The world the particles are spawning in
* @param particle The ParticlePair to use for getting particle settings
* @param particles The particles to display
* @param isLongRange If the particle can be viewed from long range
*/
public void displayParticles(Player player, World world, ParticlePair particle, List<PParticle> particles, boolean isLongRange) {
public void displayParticles(PPlayer pplayer, World world, ParticlePair particle, List<PParticle> particles, boolean isLongRange) {
PermissionManager permissionManager = this.playerParticles.getManager(PermissionManager.class);
Player player = null;
if (pplayer != null) {
if (!pplayer.isInAllowedRegion())
return;
player = pplayer.getPlayer();
}
if ((player != null && (NMSUtil.getVersionNumber() < 8 || player.getGameMode() == GameMode.SPECTATOR)) || !permissionManager.isWorldEnabled(world.getName()))
return;

View file

@ -45,7 +45,9 @@ public class PermissionManager extends Manager {
PARTICLES_UNLIMITED("particles.unlimited"),
GROUPS_MAX("groups.max"),
GROUPS_UNLIMITED("groups.unlimited");
GROUPS_UNLIMITED("groups.unlimited"),
WORLDGUARD_BYPASS("worldguard.bypass");
private final String permissionString;
@ -139,6 +141,8 @@ public class PermissionManager extends Manager {
pluginManager.addPermission(new Permission("playerparticles.groups.max"));
pluginManager.addPermission(new Permission("playerparticles.groups.unlimited"));
pluginManager.addPermission(new Permission("playerparticles.worldguard.bypass"));
// Register all non-child permissions
Map<String, Boolean> childPermissions = new HashMap<>();
for (Permission permission : allPermissions) {
@ -426,7 +430,7 @@ public class PermissionManager extends Manager {
* Checks if a player can use /ppo
*
* @param sender The CommandSender to check
* @return If the player can use /ppo
* @return If the sender can use /ppo
*/
public boolean canOverride(CommandSender sender) {
if (this.isConsole(sender))
@ -435,6 +439,16 @@ public class PermissionManager extends Manager {
return PPermission.OVERRIDE.check(sender);
}
/**
* Checks if a player has the WorldGuard bypass permission
*
* @param player The Player to check
* @return If the player has the WorldGuard bypass permission
*/
public boolean hasWorldGuardBypass(Player player) {
return PPermission.WORLDGUARD_BYPASS.check(player);
}
private boolean isConsole(PPlayer pplayer) {
return this.isConsole(pplayer.getUnderlyingExecutor());
}

View file

@ -48,6 +48,11 @@ public class PPlayer {
*/
private boolean inCombat;
/**
* If the player is in an allowed region
*/
private boolean inAllowedRegion;
/**
* Constructs a new PPlayer
*
@ -64,6 +69,7 @@ public class PPlayer {
this.particlesHidden = particlesHidden;
this.isMoving = false;
this.inCombat = false;
this.inAllowedRegion = true;
}
/**
@ -130,16 +136,14 @@ public class PPlayer {
/**
* Sets the player's movement state
*
* @param isMoving True if the player is moving, otherwise false if they are standing still
* @param isMoving true if the player is moving, otherwise false if they are standing still
*/
public void setMoving(boolean isMoving) {
this.isMoving = isMoving;
}
/**
* Gets if a player is moving
*
* @return True if the player is moving
* @return true if the player is moving, otherwise false
*/
public boolean isMoving() {
return this.isMoving;
@ -148,21 +152,35 @@ public class PPlayer {
/**
* Sets the player's combat state
*
* @param inCombat True if the player is in combat, otherwise false
* @param inCombat true if the player is in combat, otherwise false
*/
public void setInCombat(boolean inCombat) {
this.inCombat = inCombat;
}
/**
* Gets if a player is in combat
*
* @return True if the player is in combat
* @return true if the player is in combat, otherwise false
*/
public boolean isInCombat() {
return this.inCombat;
}
/**
* Sets the player's region state
*
* @param inAllowedRegion true if the player is in an allowed region, otherwise false
*/
public void setInAllowedRegion(boolean inAllowedRegion) {
this.inAllowedRegion = inAllowedRegion;
}
/**
* @return true if the player is in an allowed region, otherwise false
*/
public boolean isInAllowedRegion() {
return this.inAllowedRegion;
}
/**
* Gets a ParticleGroup this player has by its name
*

View file

@ -74,7 +74,7 @@ public class ParticleStyleBlockBreak extends DefaultParticleStyle implements Lis
for (ParticlePair particle : pplayer.getActiveParticlesForStyle(DefaultStyles.BLOCKBREAK)) {
Location loc = event.getBlock().getLocation().clone();
particleManager.displayParticles(player, player.getWorld(), particle, DefaultStyles.BLOCKBREAK.getParticles(particle, loc), false);
particleManager.displayParticles(pplayer, player.getWorld(), particle, DefaultStyles.BLOCKBREAK.getParticles(particle, loc), false);
}
}

View file

@ -74,7 +74,7 @@ public class ParticleStyleBlockPlace extends DefaultParticleStyle implements Lis
for (ParticlePair particle : pplayer.getActiveParticlesForStyle(DefaultStyles.BLOCKPLACE)) {
Location loc = event.getBlock().getLocation().clone();
particleManager.displayParticles(player, player.getWorld(), particle, DefaultStyles.BLOCKPLACE.getParticles(particle, loc), false);
particleManager.displayParticles(pplayer, player.getWorld(), particle, DefaultStyles.BLOCKPLACE.getParticles(particle, loc), false);
}
}

View file

@ -129,7 +129,7 @@ public class ParticleStyleCelebration extends DefaultParticleStyle {
trail.setEffect(ParticleStyleCelebration.this.fuseEffect);
trail.setStyle(DefaultStyles.CELEBRATION);
particleManager.displayParticles(player, this.location.getWorld(), trail, Collections.singletonList(new PParticle(this.location)), true);
particleManager.displayParticles(pplayer, this.location.getWorld(), trail, Collections.singletonList(new PParticle(this.location)), true);
this.location.add(0, ParticleStyleCelebration.this.fuseSpacing, 0);
} else {
@ -146,7 +146,7 @@ public class ParticleStyleCelebration extends DefaultParticleStyle {
particles.add(new PParticle(this.location.clone().add(dx, dy, dz)));
}
particleManager.displayParticles(player, this.location.getWorld(), particle, particles, true);
particleManager.displayParticles(pplayer, this.location.getWorld(), particle, particles, true);
this.cancel();
}

View file

@ -56,7 +56,7 @@ public class ParticleStyleHurt extends DefaultParticleStyle implements Listener
if (pplayer != null) {
for (ParticlePair particle : pplayer.getActiveParticlesForStyle(DefaultStyles.HURT)) {
Location loc = player.getLocation().clone().add(0, 1, 0);
particleManager.displayParticles(player, player.getWorld(), particle, DefaultStyles.HURT.getParticles(particle, loc), false);
particleManager.displayParticles(pplayer, player.getWorld(), particle, DefaultStyles.HURT.getParticles(particle, loc), false);
}
}
}

View file

@ -67,7 +67,7 @@ public class ParticleStyleMove extends DefaultParticleStyle implements Listener
for (ParticlePair particle : pplayer.getActiveParticlesForStyle(DefaultStyles.MOVE)) {
Location loc = player.getLocation().clone();
loc.setY(loc.getY() + 0.05);
particleManager.displayParticles(player, player.getWorld(), particle, DefaultStyles.MOVE.getParticles(particle, loc), false);
particleManager.displayParticles(pplayer, player.getWorld(), particle, DefaultStyles.MOVE.getParticles(particle, loc), false);
}
}

View file

@ -90,7 +90,7 @@ public class ParticleStyleSwords extends DefaultParticleStyle implements Listene
for (ParticlePair particle : pplayer.getActiveParticlesForStyle(DefaultStyles.SWORDS)) {
Location loc = entity.getLocation().clone().add(0, 1, 0);
particleManager.displayParticles(player, player.getWorld(), particle, DefaultStyles.SWORDS.getParticles(particle, loc), false);
particleManager.displayParticles(pplayer, player.getWorld(), particle, DefaultStyles.SWORDS.getParticles(particle, loc), false);
}
}
}

View file

@ -87,14 +87,14 @@ public class ParticleStyleTeleport extends DefaultParticleStyle implements Liste
if (this.before) {
Location loc1 = player.getLocation().clone();
loc1.setY(loc1.getY() + 1);
particleManager.displayParticles(player, player.getWorld(), particle, DefaultStyles.TELEPORT.getParticles(particle, loc1), false);
particleManager.displayParticles(pplayer, player.getWorld(), particle, DefaultStyles.TELEPORT.getParticles(particle, loc1), false);
}
if (this.after) {
Bukkit.getScheduler().runTaskLater(PlayerParticles.getInstance(), () -> {
Location loc2 = player.getLocation().clone();
loc2.setY(loc2.getY() + 1);
particleManager.displayParticles(player, player.getWorld(), particle, DefaultStyles.TELEPORT.getParticles(particle, loc2), false);
particleManager.displayParticles(pplayer, player.getWorld(), particle, DefaultStyles.TELEPORT.getParticles(particle, loc2), false);
}, 1);
}
}

View file

@ -67,7 +67,7 @@ public class ParticleStyleTrail extends DefaultParticleStyle implements Listener
for (ParticlePair particle : pplayer.getActiveParticlesForStyle(DefaultStyles.TRAIL)) {
Location loc = player.getLocation().clone();
loc.setY(loc.getY() + 1);
particleManager.displayParticles(player, player.getWorld(), particle, DefaultStyles.TRAIL.getParticles(particle, loc), false);
particleManager.displayParticles(pplayer, player.getWorld(), particle, DefaultStyles.TRAIL.getParticles(particle, loc), false);
}
}

View file

@ -5,7 +5,7 @@ api-version: '1.13'
description: Display particles around your player and blocks using customized styles and data!
author: Esophose
website: https://www.spigotmc.org/resources/playerparticles.40261/
softdepend: [PlaceholderAPI]
softdepend: [PlaceholderAPI, WorldGuard, WorldEdit]
commands:
pp:
description: The main PlayerParticles command. By default, opens the GUI.