Raid abuse fix (#1991)

* Implements new VISITOR_TRIGGER_RAID flag.

This world settings flag allows toggling if visitors can or cannot start a raid on an island they are visiting.

Relates to #1976

* Fixes abuse of Raid Mechanism and Mob Natural Spawn Rules.

Fixes to #1976

* Simplify raid abuse detection.
This commit is contained in:
BONNe 2022-06-14 02:42:48 +03:00 committed by GitHub
parent e41f5ac24f
commit c54358441d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 136 additions and 27 deletions

View File

@ -3,11 +3,13 @@ package world.bentobox.bentobox.listeners.flags.settings;
import java.util.Optional;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.PufferFish;
import org.bukkit.entity.*;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.raid.RaidFinishEvent;
import org.bukkit.event.raid.RaidTriggerEvent;
import org.bukkit.potion.PotionEffectType;
import world.bentobox.bentobox.api.flags.Flag;
import world.bentobox.bentobox.api.flags.FlagListener;
@ -33,6 +35,60 @@ public class MobSpawnListener extends FlagListener
}
/**
* This prevents to start a raid if mob spawning rules prevents it.
* @param event RaidTriggerEvent
*/
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onRaidStartEvent(RaidTriggerEvent event)
{
// If not in the right world exit immediately.
if (!this.getIWM().inWorld(event.getWorld()))
{
return;
}
Optional<Island> island = getIslands().getIslandAt(event.getPlayer().getLocation());
if (island.map(i -> !i.isAllowed(Flags.MONSTER_NATURAL_SPAWN)).orElseGet(
() -> !Flags.MONSTER_NATURAL_SPAWN.isSetForWorld(event.getWorld())))
{
// Monster spawning is disabled on island or world. Cancel the raid.
event.setCancelled(true);
}
}
/**
* This removes HERO_OF_THE_VILLAGE from players that cheated victory.
* @param event RaidFinishEvent
*/
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onRaidFinishEvent(RaidFinishEvent event)
{
// If not in the right world exit immediately.
if (!this.getIWM().inWorld(event.getWorld()))
{
return;
}
Optional<Island> island = getIslands().getIslandAt(event.getRaid().getLocation());
if (island.map(i -> !i.isAllowed(Flags.MONSTER_NATURAL_SPAWN)).orElseGet(
() -> !Flags.MONSTER_NATURAL_SPAWN.isSetForWorld(event.getWorld())))
{
// CHEATERS. PUNISH THEM.
event.getWinners().forEach(player ->
{
if (player.isOnline())
{
player.removePotionEffect(PotionEffectType.HERO_OF_THE_VILLAGE);
}
});
}
}
/**
* Prevents mobs spawning naturally
* @param e - event

View File

@ -0,0 +1,61 @@
//
// Created by BONNe
// Copyright - 2022
//
package world.bentobox.bentobox.listeners.flags.worldsettings;
import org.bukkit.World;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.raid.RaidTriggerEvent;
import java.util.Optional;
import world.bentobox.bentobox.api.flags.FlagListener;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.lists.Flags;
import world.bentobox.bentobox.util.Util;
/**
* This listener checks for island visitors that want to start a new raid.
*/
public class VisitorsStartingRaidListener extends FlagListener
{
/**
* This method process raid allowance from visitors.
* @param event RaidTriggerEvent
*/
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onRaidTrigger(RaidTriggerEvent event)
{
World world = Util.getWorld(event.getWorld());
if (!this.getIWM().inWorld(world) || Flags.VISITOR_TRIGGER_RAID.isSetForWorld(world))
{
// If the player triggers raid non-protected world or VISITOR_TRIGGER_RAID is disabled then do nothing.
this.report(User.getInstance(event.getPlayer()),
event,
event.getPlayer().getLocation(),
Flags.VISITOR_TRIGGER_RAID,
Why.SETTING_ALLOWED_IN_WORLD);
return;
}
Optional<Island> island = this.getIslands().getProtectedIslandAt(event.getPlayer().getLocation());
if (island.isPresent() && !island.get().getMemberSet().contains(event.getPlayer().getUniqueId()))
{
event.setCancelled(true);
this.report(User.getInstance(event.getPlayer()),
event,
event.getPlayer().getLocation(),
Flags.VISITOR_TRIGGER_RAID,
Why.SETTING_NOT_ALLOWED_IN_WORLD);
}
}
}

View File

@ -18,30 +18,7 @@ import world.bentobox.bentobox.listeners.flags.protection.*;
import world.bentobox.bentobox.listeners.flags.settings.DecayListener;
import world.bentobox.bentobox.listeners.flags.settings.MobSpawnListener;
import world.bentobox.bentobox.listeners.flags.settings.PVPListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.ChestDamageListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.CleanSuperFlatListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.CoarseDirtTillingListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.CreeperListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.EnderChestListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.EndermanListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.EnterExitListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.GeoLimitMobsListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.InvincibleVisitorsListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.IslandRespawnListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.ItemFrameListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.LimitMobsListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.LiquidsFlowingOutListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.NaturalSpawningOutsideRangeListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.ObsidianScoopingListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.OfflineGrowthListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.OfflineRedstoneListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.PetTeleportListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.PistonPushListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.RemoveMobsListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.SpawnerSpawnEggsListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.TreesGrowingOutsideRangeListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.VisitorKeepInventoryListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.WitherListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.*;
import world.bentobox.bentobox.managers.RanksManager;
import world.bentobox.bentobox.util.Util;
@ -585,7 +562,14 @@ public final class Flags {
* @see VisitorKeepInventoryListener
*/
public static final Flag VISITOR_KEEP_INVENTORY = new Flag.Builder("VISITOR_KEEP_INVENTORY", Material.TOTEM_OF_UNDYING).listener(new VisitorKeepInventoryListener()).type(Type.WORLD_SETTING).defaultSetting(false).build();
/**
* Toggles whether island visitors can trigger to start a raid on another player's island.
* @since 1.21.0
* @see VisitorsStartingRaidListener
*/
public static final Flag VISITOR_TRIGGER_RAID = new Flag.Builder("VISITOR_TRIGGER_RAID", Material.RAVAGER_SPAWN_EGG).listener(new VisitorsStartingRaidListener()).type(Type.WORLD_SETTING).defaultSetting(true).build();
/**
* Provides a list of all the Flag instances contained in this class using reflection.
* Deprecated Flags are ignored.

View File

@ -1356,6 +1356,14 @@ protection:
&a
&a Island members still lose their items
&a if they die on their own island!
VISITOR_TRIGGER_RAID:
name: "Visitors triggers raids"
description: |-
&a Toggles if visitors can start
&a a raid on an island which they are
&a visiting.
&a
&a Bad Omen effect will be removed!
WITHER_DAMAGE:
name: "Toggle wither damage"
description: |-