mirror of
https://github.com/IntellectualSites/PlotSquared.git
synced 2024-11-24 22:26:45 +01:00
feature: add flag for beacon effects of other plots (#3627)
* feature: add flag for beacon effects of other plots Took 7 minutes * fix: don't add the beacon effect flag if the platform is not paper Took 2 minutes * fix: creating consistency in documentation Took 7 minutes * feature: add global paper setting for the beacon-effect * fix: description of the plot flag and rewrite of the listener * fix: renamed flag and added road support * fix: renamed flag and changed flag functionality * fix: added spigot fallback listener and fixed NPE * refactor: Address checkstyle violations * addition: remove beacon effects when player leaves a plot * fix: updated javadoc and fixed usage of the PlotListener#addEffect method * chore: Run license updater Co-authored-by: BuildTools <unconfigured@null.spigotmc.org> Co-authored-by: Alexander Brandes <mc.cache@web.de>
This commit is contained in:
parent
69f5f88183
commit
476f3d328d
@ -41,6 +41,7 @@ import com.plotsquared.bukkit.listener.PlayerEventListener;
|
||||
import com.plotsquared.bukkit.listener.ProjectileEventListener;
|
||||
import com.plotsquared.bukkit.listener.ServerListener;
|
||||
import com.plotsquared.bukkit.listener.SingleWorldListener;
|
||||
import com.plotsquared.bukkit.listener.SpigotListener;
|
||||
import com.plotsquared.bukkit.listener.WorldEvents;
|
||||
import com.plotsquared.bukkit.placeholder.PAPIPlaceholders;
|
||||
import com.plotsquared.bukkit.placeholder.PlaceholderFormatter;
|
||||
@ -360,6 +361,8 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
|
||||
} else {
|
||||
getServer().getPluginManager().registerEvents(injector().getInstance(PaperListener.class), this);
|
||||
}
|
||||
} else {
|
||||
getServer().getPluginManager().registerEvents(injector().getInstance(SpigotListener.class), this);
|
||||
}
|
||||
this.plotListener.startRunnable();
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
*/
|
||||
package com.plotsquared.bukkit.listener;
|
||||
|
||||
import com.destroystokyo.paper.event.block.BeaconEffectEvent;
|
||||
import com.destroystokyo.paper.event.entity.EntityPathfindEvent;
|
||||
import com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent;
|
||||
import com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent;
|
||||
@ -36,8 +37,11 @@ import com.plotsquared.core.permissions.Permission;
|
||||
import com.plotsquared.core.player.PlotPlayer;
|
||||
import com.plotsquared.core.plot.Plot;
|
||||
import com.plotsquared.core.plot.PlotArea;
|
||||
import com.plotsquared.core.plot.flag.FlagContainer;
|
||||
import com.plotsquared.core.plot.flag.implementations.BeaconEffectsFlag;
|
||||
import com.plotsquared.core.plot.flag.implementations.DoneFlag;
|
||||
import com.plotsquared.core.plot.flag.implementations.ProjectilesFlag;
|
||||
import com.plotsquared.core.plot.flag.types.BooleanFlag;
|
||||
import com.plotsquared.core.plot.world.PlotAreaManager;
|
||||
import com.plotsquared.core.util.Permissions;
|
||||
import net.kyori.adventure.text.minimessage.Template;
|
||||
@ -400,4 +404,50 @@ public class PaperListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onBeaconEffect(final BeaconEffectEvent event) {
|
||||
Block block = event.getBlock();
|
||||
Location beaconLocation = BukkitUtil.adapt(block.getLocation());
|
||||
Plot beaconPlot = beaconLocation.getPlot();
|
||||
|
||||
PlotArea area = beaconLocation.getPlotArea();
|
||||
if (area == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
Location playerLocation = BukkitUtil.adapt(player.getLocation());
|
||||
|
||||
PlotPlayer<Player> plotPlayer = BukkitUtil.adapt(player);
|
||||
Plot playerStandingPlot = playerLocation.getPlot();
|
||||
if (playerStandingPlot == null) {
|
||||
FlagContainer container = area.getRoadFlagContainer();
|
||||
if (!getBooleanFlagValue(container, BeaconEffectsFlag.class, true) ||
|
||||
(beaconPlot != null && Settings.Enabled_Components.DISABLE_BEACON_EFFECT_OVERFLOW)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
FlagContainer container = playerStandingPlot.getFlagContainer();
|
||||
boolean plotBeaconEffects = getBooleanFlagValue(container, BeaconEffectsFlag.class, true);
|
||||
if (playerStandingPlot.equals(beaconPlot)) {
|
||||
if (!plotBeaconEffects) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!plotBeaconEffects || Settings.Enabled_Components.DISABLE_BEACON_EFFECT_OVERFLOW) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean getBooleanFlagValue(@NonNull FlagContainer container,
|
||||
@NonNull Class<? extends BooleanFlag<?>> flagClass,
|
||||
boolean defaultValue) {
|
||||
BooleanFlag<?> flag = container.getFlag(flagClass);
|
||||
return flag == null ? defaultValue : flag.getValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -106,6 +106,7 @@ import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.entity.EntityPickupItemEvent;
|
||||
import org.bukkit.event.entity.EntityPlaceEvent;
|
||||
import org.bukkit.event.entity.EntityPotionEffectEvent;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
|
||||
import org.bukkit.event.hanging.HangingPlaceEvent;
|
||||
@ -142,6 +143,7 @@ import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
import org.bukkit.metadata.MetadataValue;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
@ -204,6 +206,29 @@ public class PlayerEventListener implements Listener {
|
||||
this.plotListener = plotListener;
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onEffect(@NonNull EntityPotionEffectEvent event) {
|
||||
if (Settings.Enabled_Components.DISABLE_BEACON_EFFECT_OVERFLOW ||
|
||||
event.getCause() != EntityPotionEffectEvent.Cause.BEACON ||
|
||||
!(event.getEntity() instanceof Player player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
UUID uuid = player.getUniqueId();
|
||||
PotionEffect effect = event.getNewEffect();
|
||||
if (effect == null) {
|
||||
PotionEffect oldEffect = event.getOldEffect();
|
||||
if (oldEffect != null) {
|
||||
String name = oldEffect.getType().getName();
|
||||
plotListener.addEffect(uuid, name, -1);
|
||||
}
|
||||
} else {
|
||||
long expiresAt = System.currentTimeMillis() + effect.getDuration() * 50L; //Convert ticks to milliseconds
|
||||
String name = effect.getType().getName();
|
||||
plotListener.addEffect(uuid, name, expiresAt);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onVehicleEntityCollision(VehicleEntityCollisionEvent e) {
|
||||
if (e.getVehicle().getType() == EntityType.BOAT) {
|
||||
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* PlotSquared, a land and world management plugin for Minecraft.
|
||||
* Copyright (C) IntellectualSites <https://intellectualsites.com>
|
||||
* Copyright (C) IntellectualSites team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.plotsquared.bukkit.listener;
|
||||
|
||||
import com.plotsquared.bukkit.util.BukkitUtil;
|
||||
import com.plotsquared.core.location.Location;
|
||||
import com.plotsquared.core.plot.Plot;
|
||||
import com.plotsquared.core.plot.flag.FlagContainer;
|
||||
import com.plotsquared.core.plot.flag.implementations.BeaconEffectsFlag;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityPotionEffectEvent;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
/**
|
||||
* Fallback listener for paper events on spigot
|
||||
*/
|
||||
public class SpigotListener implements Listener {
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onEffect(@NonNull EntityPotionEffectEvent event) {
|
||||
if (event.getCause() != EntityPotionEffectEvent.Cause.BEACON) {
|
||||
return;
|
||||
}
|
||||
|
||||
Entity entity = event.getEntity();
|
||||
Location location = BukkitUtil.adapt(entity.getLocation());
|
||||
Plot plot = location.getPlot();
|
||||
if (plot == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
FlagContainer container = plot.getFlagContainer();
|
||||
BeaconEffectsFlag effectsEnabled = container.getFlag(BeaconEffectsFlag.class);
|
||||
if (effectsEnabled != null && !effectsEnabled.getValue()) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -47,13 +47,13 @@ import org.bukkit.event.EventException;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
import org.bukkit.plugin.RegisteredListener;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.checkerframework.checker.index.qual.NonNegative;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.sk89q.worldedit.world.gamemode.GameModes.ADVENTURE;
|
||||
import static com.sk89q.worldedit.world.gamemode.GameModes.CREATIVE;
|
||||
@ -348,6 +348,14 @@ public class BukkitPlayer extends PlotPlayer<Player> {
|
||||
return BukkitUtil.BUKKIT_AUDIENCES.player(this.player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeEffect(@NonNull String name) {
|
||||
PotionEffectType type = PotionEffectType.getByName(name);
|
||||
if (type != null) {
|
||||
player.removePotionEffect(type);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canSee(final PlotPlayer<?> other) {
|
||||
if (other instanceof ConsolePlayer) {
|
||||
|
@ -808,6 +808,8 @@ public class Settings extends Config {
|
||||
);
|
||||
@Comment("Whether PlotSquared should hook into MvDWPlaceholderAPI or not")
|
||||
public static boolean USE_MVDWAPI = true;
|
||||
@Comment("Prevent cross plot beacon effects")
|
||||
public static boolean DISABLE_BEACON_EFFECT_OVERFLOW = true;
|
||||
|
||||
}
|
||||
|
||||
|
@ -67,10 +67,13 @@ import com.sk89q.worldedit.world.item.ItemType;
|
||||
import com.sk89q.worldedit.world.item.ItemTypes;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.minimessage.Template;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
@ -82,6 +85,7 @@ public class PlotListener {
|
||||
|
||||
private final HashMap<UUID, Interval> feedRunnable = new HashMap<>();
|
||||
private final HashMap<UUID, Interval> healRunnable = new HashMap<>();
|
||||
private final Map<UUID, List<StatusEffect>> playerEffects = new HashMap<>();
|
||||
|
||||
private final EventDispatcher eventDispatcher;
|
||||
|
||||
@ -131,6 +135,17 @@ public class PlotListener {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!playerEffects.isEmpty()) {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
for (Iterator<Map.Entry<UUID, List<StatusEffect>>> iterator =
|
||||
playerEffects.entrySet().iterator(); iterator.hasNext(); ) {
|
||||
Map.Entry<UUID, List<StatusEffect>> entry = iterator.next();
|
||||
List<StatusEffect> effects = entry.getValue();
|
||||
effects.removeIf(effect -> currentTime > effect.expiresAt);
|
||||
if (effects.isEmpty()) iterator.remove();
|
||||
}
|
||||
}
|
||||
}, TaskTime.seconds(1L));
|
||||
}
|
||||
|
||||
@ -360,6 +375,17 @@ public class PlotListener {
|
||||
try (final MetaDataAccess<Plot> lastPlot = player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
|
||||
final Plot previous = lastPlot.remove();
|
||||
this.eventDispatcher.callLeave(player, plot);
|
||||
|
||||
List<StatusEffect> effects = playerEffects.remove(player.getUUID());
|
||||
if (effects != null) {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
effects.forEach(effect -> {
|
||||
if (currentTime <= effect.expiresAt) {
|
||||
player.removeEffect(effect.name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (plot.hasOwner()) {
|
||||
PlotArea pw = plot.getArea();
|
||||
if (pw == null) {
|
||||
@ -468,6 +494,23 @@ public class PlotListener {
|
||||
public void logout(UUID uuid) {
|
||||
feedRunnable.remove(uuid);
|
||||
healRunnable.remove(uuid);
|
||||
playerEffects.remove(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks an effect as a status effect that will be removed on leaving a plot
|
||||
* @param uuid The uuid of the player the effect belongs to
|
||||
* @param name The name of the status effect
|
||||
* @param expiresAt The time when the effect expires
|
||||
* @since TODO
|
||||
*/
|
||||
public void addEffect(@NonNull UUID uuid, @NonNull String name, long expiresAt) {
|
||||
List<StatusEffect> effects = playerEffects.getOrDefault(uuid, new ArrayList<>());
|
||||
effects.removeIf(effect -> effect.name.equals(name));
|
||||
if (expiresAt != -1) {
|
||||
effects.add(new StatusEffect(name, expiresAt));
|
||||
}
|
||||
playerEffects.put(uuid, effects);
|
||||
}
|
||||
|
||||
private static class Interval {
|
||||
@ -485,4 +528,13 @@ public class PlotListener {
|
||||
|
||||
}
|
||||
|
||||
private record StatusEffect(@NonNull String name, long expiresAt) {
|
||||
|
||||
private StatusEffect(@NonNull String name, long expiresAt) {
|
||||
this.name = name;
|
||||
this.expiresAt = expiresAt;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -246,6 +246,10 @@ public class ConsolePlayer extends PlotPlayer<Actor> {
|
||||
return PlotSquared.platform().consoleAudience();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeEffect(@NonNull String name) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canSee(final PlotPlayer<?> other) {
|
||||
return true;
|
||||
|
@ -1016,6 +1016,14 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer,
|
||||
return this.lockRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes any effects present of the given type.
|
||||
*
|
||||
* @param name the name of the type to remove
|
||||
* @since TODO
|
||||
*/
|
||||
public abstract void removeEffect(@NonNull String name);
|
||||
|
||||
@FunctionalInterface
|
||||
public interface PlotPlayerConverter<BaseObject> {
|
||||
|
||||
|
@ -23,6 +23,7 @@ import com.plotsquared.core.plot.flag.implementations.AnalysisFlag;
|
||||
import com.plotsquared.core.plot.flag.implementations.AnimalAttackFlag;
|
||||
import com.plotsquared.core.plot.flag.implementations.AnimalCapFlag;
|
||||
import com.plotsquared.core.plot.flag.implementations.AnimalInteractFlag;
|
||||
import com.plotsquared.core.plot.flag.implementations.BeaconEffectsFlag;
|
||||
import com.plotsquared.core.plot.flag.implementations.BlockBurnFlag;
|
||||
import com.plotsquared.core.plot.flag.implementations.BlockIgnitionFlag;
|
||||
import com.plotsquared.core.plot.flag.implementations.BlockedCmdsFlag;
|
||||
@ -137,6 +138,7 @@ public final class GlobalFlagContainer extends FlagContainer {
|
||||
this.addFlag(AnimalAttackFlag.ANIMAL_ATTACK_FALSE);
|
||||
this.addFlag(AnimalInteractFlag.ANIMAL_INTERACT_FALSE);
|
||||
this.addFlag(BlockBurnFlag.BLOCK_BURN_FALSE);
|
||||
this.addFlag(BeaconEffectsFlag.BEACON_EFFECT_TRUE);
|
||||
this.addFlag(BlockIgnitionFlag.BLOCK_IGNITION_TRUE);
|
||||
this.addFlag(ChatFlag.CHAT_FLAG_TRUE);
|
||||
this.addFlag(CopperOxideFlag.COPPER_OXIDE_FALSE);
|
||||
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* PlotSquared, a land and world management plugin for Minecraft.
|
||||
* Copyright (C) IntellectualSites <https://intellectualsites.com>
|
||||
* Copyright (C) IntellectualSites team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.plotsquared.core.plot.flag.implementations;
|
||||
|
||||
import com.plotsquared.core.configuration.caption.TranslatableCaption;
|
||||
import com.plotsquared.core.plot.flag.types.BooleanFlag;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
public class BeaconEffectsFlag extends BooleanFlag<BeaconEffectsFlag> {
|
||||
|
||||
public static final BeaconEffectsFlag BEACON_EFFECT_TRUE = new BeaconEffectsFlag(true);
|
||||
public static final BeaconEffectsFlag BEACON_EFFECT_FALSE = new BeaconEffectsFlag(false);
|
||||
|
||||
private BeaconEffectsFlag(boolean value){
|
||||
super(value, TranslatableCaption.of("flags.flag_description_beacon_effect"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BeaconEffectsFlag flagOf(@NonNull final Boolean value) {
|
||||
return value ? BEACON_EFFECT_TRUE : BEACON_EFFECT_FALSE;
|
||||
}
|
||||
|
||||
}
|
@ -618,6 +618,7 @@
|
||||
"flags.flag_description_prevent_creative_copy": "<gray>Prevents people from copying item NBT data in the plot unless they're added as members.</gray>",
|
||||
"flags.flag_description_leaf_decay": "<gray>Set to `false` to prevent leaves from decaying.",
|
||||
"flags.flag_description_projectiles": "<gray>Prevents guests from shooting projectiles on the plot when set to false.</gray>",
|
||||
"flags.flag_description_beacon_effect": "<gray>Enables beacon effects on the plot.</gray>",
|
||||
"flags.flag_error_boolean": "Flag value must be a boolean (true | false).",
|
||||
"flags.flag_error_enum": "Must be one of: <list>",
|
||||
"flags.flag_error_integer": "Flag value must be a whole positive number.",
|
||||
|
Loading…
Reference in New Issue
Block a user