Merge branch 'develop'

This commit is contained in:
tastybento 2020-10-10 20:13:55 -07:00
commit 2d7aa216af
22 changed files with 2642 additions and 281 deletions

View File

@ -5,7 +5,7 @@ addons:
organization: "bentobox-world" organization: "bentobox-world"
jdk: jdk:
- openjdk8 - openjdk11
script: script:
# JaCoCo is used to have code coverage, the agent has to be activated # JaCoCo is used to have code coverage, the agent has to be activated

19
pom.xml
View File

@ -58,14 +58,14 @@
<!-- Non-minecraft related dependencies --> <!-- Non-minecraft related dependencies -->
<powermock.version>2.0.4</powermock.version> <powermock.version>2.0.4</powermock.version>
<!-- More visible way how to change dependency versions --> <!-- More visible way how to change dependency versions -->
<spigot.version>1.16.1-R0.1-SNAPSHOT</spigot.version> <spigot.version>1.16.2-R0.1-SNAPSHOT</spigot.version>
<bentobox.version>1.14.0</bentobox.version> <bentobox.version>1.14.0</bentobox.version>
<!-- Revision variable removes warning about dynamic version --> <!-- Revision variable removes warning about dynamic version -->
<revision>${build.version}-SNAPSHOT</revision> <revision>${build.version}-SNAPSHOT</revision>
<!-- Do not change unless you want different name for local builds. --> <!-- Do not change unless you want different name for local builds. -->
<build.number>-LOCAL</build.number> <build.number>-LOCAL</build.number>
<!-- This allows to change between versions. --> <!-- This allows to change between versions. -->
<build.version>1.14.2</build.version> <build.version>1.14.3</build.version>
</properties> </properties>
<!-- Profiles will allow to automatically change build version. --> <!-- Profiles will allow to automatically change build version. -->
@ -147,6 +147,10 @@
<id>codemc-repo</id> <id>codemc-repo</id>
<url>https://repo.codemc.org/repository/maven-public/</url> <url>https://repo.codemc.org/repository/maven-public/</url>
</repository> </repository>
<repository>
<id>ess-repo</id>
<url>https://ci.ender.zone/plugin/repository/everything/</url>
</repository>
</repositories> </repositories>
@ -192,6 +196,13 @@
<artifactId>org.eclipse.jdt.annotation</artifactId> <artifactId>org.eclipse.jdt.annotation</artifactId>
<version>2.2.200</version> <version>2.2.200</version>
</dependency> </dependency>
<!-- EssentialsX -->
<dependency>
<groupId>net.ess3</groupId>
<artifactId>EssentialsX</artifactId>
<version>2.17.2</version>
<scope>provided</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>
@ -267,11 +278,13 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId> <artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.1</version> <version>3.2.0</version>
<configuration> <configuration>
<source>8</source>
<show>public</show> <show>public</show>
<failOnError>false</failOnError> <failOnError>false</failOnError>
<additionalJOption>-Xdoclint:none</additionalJOption> <additionalJOption>-Xdoclint:none</additionalJOption>
<!-- <javadocExecutable>${java.home}/bin/javadoc</javadocExecutable> -->
</configuration> </configuration>
<executions> <executions>
<execution> <execution>

View File

@ -153,7 +153,7 @@ public class AISettings implements WorldSettings {
@ConfigComment("World difficulty setting - PEACEFUL, EASY, NORMAL, HARD") @ConfigComment("World difficulty setting - PEACEFUL, EASY, NORMAL, HARD")
@ConfigComment("Other plugins may override this setting") @ConfigComment("Other plugins may override this setting")
@ConfigEntry(path = "world.difficulty") @ConfigEntry(path = "world.difficulty")
private Difficulty difficulty; private Difficulty difficulty = Difficulty.NORMAL;
@ConfigComment("Spawn limits. These override the limits set in bukkit.yml") @ConfigComment("Spawn limits. These override the limits set in bukkit.yml")
@ConfigComment("If set to a negative number, the server defaults will be used") @ConfigComment("If set to a negative number, the server defaults will be used")
@ -175,7 +175,6 @@ public class AISettings implements WorldSettings {
private int ticksPerMonsterSpawns = -1; private int ticksPerMonsterSpawns = -1;
@ConfigComment("Radius of island in blocks. (So distance between islands is twice this)") @ConfigComment("Radius of island in blocks. (So distance between islands is twice this)")
@ConfigComment("Will be rounded up to the nearest 16 blocks.")
@ConfigComment("It is the same for every dimension : Overworld, Nether and End.") @ConfigComment("It is the same for every dimension : Overworld, Nether and End.")
@ConfigComment("This value cannot be changed mid-game and the plugin will not start if it is different.") @ConfigComment("This value cannot be changed mid-game and the plugin will not start if it is different.")
@ConfigEntry(path = "world.distance-between-islands", needsReset = true) @ConfigEntry(path = "world.distance-between-islands", needsReset = true)
@ -1082,7 +1081,9 @@ public class AISettings implements WorldSettings {
/** /**
* @param adminCommand what you want your admin command to be * @param adminCommand what you want your admin command to be
*/ */
public void setAdminCommand(String adminCommand) { this.adminCommandAliases = adminCommand; } public void setAdminCommand(String adminCommand) {
this.adminCommandAliases = adminCommand;
}
/** /**
* @param allowSetHomeInNether the allowSetHomeInNether to set * @param allowSetHomeInNether the allowSetHomeInNether to set
*/ */
@ -1196,7 +1197,9 @@ public class AISettings implements WorldSettings {
/** /**
* @param islandCommand what you want your island command to be * @param islandCommand what you want your island command to be
*/ */
public void setIslandCommand(String islandCommand) { this.playerCommandAliases = islandCommand; } public void setIslandCommand(String islandCommand) {
this.playerCommandAliases = islandCommand;
}
/** /**
* @param islandDistance the islandDistance to set * @param islandDistance the islandDistance to set

View File

@ -1,5 +1,6 @@
package world.bentobox.acidisland; package world.bentobox.acidisland;
import org.bukkit.Bukkit;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.World.Environment; import org.bukkit.World.Environment;
import org.bukkit.WorldCreator; import org.bukkit.WorldCreator;
@ -30,7 +31,7 @@ public class AcidIsland extends GameModeAddon {
private @Nullable AISettings settings; private @Nullable AISettings settings;
private @Nullable AcidTask acidTask; private @Nullable AcidTask acidTask;
private @Nullable ChunkGenerator chunkGenerator; private @Nullable ChunkGenerator chunkGenerator;
private Config<AISettings> config = new Config<>(this, AISettings.class); private final Config<AISettings> config = new Config<>(this, AISettings.class);
private static final String NETHER = "_nether"; private static final String NETHER = "_nether";
private static final String THE_END = "_the_end"; private static final String THE_END = "_the_end";
@ -100,33 +101,28 @@ public class AcidIsland extends GameModeAddon {
return settings; return settings;
} }
@Override
public void log(String string) {
getPlugin().log(string);
}
/* (non-Javadoc) /* (non-Javadoc)
* @see world.bentobox.bentobox.api.addons.GameModeAddon#createWorlds() * @see world.bentobox.bentobox.api.addons.GameModeAddon#createWorlds()
*/ */
@Override @Override
public void createWorlds() { public void createWorlds() {
String worldName = settings.getWorldName().toLowerCase(); String worldName = settings.getWorldName().toLowerCase();
if (getServer().getWorld(worldName) == null) { if (Bukkit.getWorld(worldName) == null) {
getLogger().info("Creating AcidIsland..."); log("Creating AcidIsland...");
} }
// Create the world if it does not exist // Create the world if it does not exist
chunkGenerator = new ChunkGeneratorWorld(this); chunkGenerator = new ChunkGeneratorWorld(this);
islandWorld = getWorld(worldName, World.Environment.NORMAL, chunkGenerator); islandWorld = getWorld(worldName, World.Environment.NORMAL, chunkGenerator);
// Make the nether if it does not exist // Make the nether if it does not exist
if (settings.isNetherGenerate()) { if (settings.isNetherGenerate()) {
if (getServer().getWorld(worldName + NETHER) == null) { if (Bukkit.getWorld(worldName + NETHER) == null) {
log("Creating AcidIsland's Nether..."); log("Creating AcidIsland's Nether...");
} }
netherWorld = settings.isNetherIslands() ? getWorld(worldName, World.Environment.NETHER, chunkGenerator) : getWorld(worldName, World.Environment.NETHER, null); netherWorld = settings.isNetherIslands() ? getWorld(worldName, World.Environment.NETHER, chunkGenerator) : getWorld(worldName, World.Environment.NETHER, null);
} }
// Make the end if it does not exist // Make the end if it does not exist
if (settings.isEndGenerate()) { if (settings.isEndGenerate()) {
if (getServer().getWorld(worldName + THE_END) == null) { if (Bukkit.getWorld(worldName + THE_END) == null) {
log("Creating AcidIsland's End World..."); log("Creating AcidIsland's End World...");
} }
endWorld = settings.isEndIslands() ? getWorld(worldName, World.Environment.THE_END, chunkGenerator) : getWorld(worldName, World.Environment.THE_END, null); endWorld = settings.isEndIslands() ? getWorld(worldName, World.Environment.THE_END, chunkGenerator) : getWorld(worldName, World.Environment.THE_END, null);
@ -161,7 +157,7 @@ public class AcidIsland extends GameModeAddon {
@Override @Override
public WorldSettings getWorldSettings() { public WorldSettings getWorldSettings() {
return settings; return getSettings();
} }
@Override @Override

View File

@ -0,0 +1,99 @@
package world.bentobox.acidisland.events;
import java.util.List;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.potion.PotionEffectType;
/**
* This event is fired when a player is going to be burned by acid or acid rain
*
* @author tastybento
*
*/
public abstract class AbstractAcidEvent extends Event implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private Player player;
private final double protection;
/**
* @since 1.9.1
*/
private List<PotionEffectType> potionEffects;
private boolean cancelled;
/**
* @param player
* @param rainDamage
* @param protection
*/
protected AbstractAcidEvent(Player player, double protection, List<PotionEffectType> potionEffects) {
this.player = player;
this.protection = protection;
this.potionEffects = potionEffects;
}
/**
* @return the player being damaged by acid rain
*/
public Player getPlayer() {
return player;
}
/**
* @param player the player to set
*/
public void setPlayer(Player player) {
this.player = player;
}
/**
* Get the amount the damage was reduced for this player due to armor, etc.
* @return the protection
*/
public double getProtection() {
return protection;
}
/**
* Returns the potion effects that will be applied to the player.
* @return list of potion effect types
* @since 1.9.1
*/
public List<PotionEffectType> getPotionEffects() {
return potionEffects;
}
/**
*
* @param potionEffects the potionEffects to set
* @since 1.9.1
*/
public void setPotionEffects(List<PotionEffectType> potionEffects) {
this.potionEffects = potionEffects;
}
@Override
public HandlerList getHandlers() {
return getHandlerList();
}
public static HandlerList getHandlerList() {
return handlers;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
}

View File

@ -3,9 +3,6 @@ package world.bentobox.acidisland.events;
import java.util.List; import java.util.List;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
/** /**
@ -14,13 +11,9 @@ import org.bukkit.potion.PotionEffectType;
* @author tastybento * @author tastybento
* *
*/ */
public class AcidEvent extends Event implements Cancellable { public class AcidEvent extends AbstractAcidEvent {
private static final HandlerList handlers = new HandlerList();
private Player player;
private double totalDamage; private double totalDamage;
private final double protection;
private List<PotionEffectType> potionEffects;
/** /**
* @param player - player * @param player - player
@ -29,26 +22,8 @@ public class AcidEvent extends Event implements Cancellable {
* @param potionEffects - potion effects given to the player * @param potionEffects - potion effects given to the player
*/ */
public AcidEvent(Player player, double totalDamage, double protection, List<PotionEffectType> potionEffects) { public AcidEvent(Player player, double totalDamage, double protection, List<PotionEffectType> potionEffects) {
this.player = player; super(player, protection, potionEffects);
this.totalDamage = totalDamage; this.totalDamage = totalDamage;
this.protection = protection;
this.potionEffects = potionEffects;
}
private boolean cancelled;
/**
* @return the player being damaged by acid rain
*/
public Player getPlayer() {
return player;
}
/**
* @param player the player to set
*/
public void setPlayer(Player player) {
this.player = player;
} }
/** /**
@ -59,14 +34,6 @@ public class AcidEvent extends Event implements Cancellable {
return totalDamage; return totalDamage;
} }
/**
* Get the amount the damage was reduced for this player due to armor, etc.
* @return the protection
*/
public double getProtection() {
return protection;
}
/** /**
* @param totalDamage to set * @param totalDamage to set
*/ */
@ -74,36 +41,4 @@ public class AcidEvent extends Event implements Cancellable {
this.totalDamage = totalDamage; this.totalDamage = totalDamage;
} }
/**
* @return the potionEffects
*/
public List<PotionEffectType> getPotionEffects() {
return potionEffects;
}
/**
* @param potionEffects the potionEffects to set
*/
public void setPotionEffects(List<PotionEffectType> potionEffects) {
this.potionEffects = potionEffects;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
} }

View File

@ -3,9 +3,6 @@ package world.bentobox.acidisland.events;
import java.util.List; import java.util.List;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
/** /**
@ -14,44 +11,18 @@ import org.bukkit.potion.PotionEffectType;
* @author tastybento * @author tastybento
* *
*/ */
public class AcidRainEvent extends Event implements Cancellable { public class AcidRainEvent extends AbstractAcidEvent {
private static final HandlerList handlers = new HandlerList();
private Player player;
private double rainDamage; private double rainDamage;
private final double protection;
/**
* @since 1.9.1
*/
private List<PotionEffectType> potionEffects;
private boolean cancelled;
/** /**
* @param player * @param player - player
* @param rainDamage * @param rainDamage - rain damage caused
* @param protection * @param protection - protection reducer to damage
* @param potionEffects - potion effects to apply if acid rain affects player
*/ */
public AcidRainEvent(Player player, double rainDamage, double protection, List<PotionEffectType> potionEffects) { public AcidRainEvent(Player player, double rainDamage, double protection, List<PotionEffectType> potionEffects) {
this.player = player; super(player, protection, potionEffects);
this.rainDamage = rainDamage; this.rainDamage = rainDamage;
this.protection = protection;
this.potionEffects = potionEffects;
}
/**
* @return the player being damaged by acid rain
*/
public Player getPlayer() {
return player;
}
/**
* @param player the player to set
*/
public void setPlayer(Player player) {
this.player = player;
} }
/** /**
@ -62,14 +33,6 @@ public class AcidRainEvent extends Event implements Cancellable {
return rainDamage; return rainDamage;
} }
/**
* Get the amount the damage was reduced for this player due to armor, etc.
* @return the protection
*/
public double getProtection() {
return protection;
}
/** /**
* @param rainDamage the rainDamage to set * @param rainDamage the rainDamage to set
*/ */
@ -77,40 +40,4 @@ public class AcidRainEvent extends Event implements Cancellable {
this.rainDamage = rainDamage; this.rainDamage = rainDamage;
} }
/**
* Returns the potion effects that will be applied to the player.
* @return list of potion effect types
* @since 1.9.1
*/
public List<PotionEffectType> getPotionEffects() {
return potionEffects;
}
/**
*
* @param potionEffects the potionEffects to set
* @since 1.9.1
*/
public void setPotionEffects(List<PotionEffectType> potionEffects) {
this.potionEffects = potionEffects;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
} }

View File

@ -15,7 +15,6 @@ public class ItemFillWithAcidEvent extends IslandBaseEvent {
private final Player player; private final Player player;
private final ItemStack item; private final ItemStack item;
// TODO: dispenser?
public ItemFillWithAcidEvent(Island island, Player player, ItemStack item) { public ItemFillWithAcidEvent(Island island, Player player, ItemStack item) {
super(island); super(island);
this.player = player; this.player = player;

View File

@ -1,12 +1,13 @@
package world.bentobox.acidisland.listeners; package world.bentobox.acidisland.listeners;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.World.Environment; import org.bukkit.World.Environment;
@ -18,6 +19,7 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.inventory.EntityEquipment; import org.bukkit.inventory.EntityEquipment;
@ -29,10 +31,13 @@ import org.bukkit.potion.PotionEffectType;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import com.earth2me.essentials.Essentials;
import world.bentobox.acidisland.AcidIsland; import world.bentobox.acidisland.AcidIsland;
import world.bentobox.acidisland.events.AcidEvent; import world.bentobox.acidisland.events.AcidEvent;
import world.bentobox.acidisland.events.AcidRainEvent; import world.bentobox.acidisland.events.AcidRainEvent;
import world.bentobox.acidisland.world.AcidTask; import world.bentobox.acidisland.world.AcidTask;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.util.Util; import world.bentobox.bentobox.util.Util;
/** /**
@ -43,9 +48,13 @@ import world.bentobox.bentobox.util.Util;
public class AcidEffect implements Listener { public class AcidEffect implements Listener {
private final AcidIsland addon; private final AcidIsland addon;
private final Map<Player, Long> burningPlayers = new HashMap<>(); private final Map<Player, Long> burningPlayers;
private final Map<Player, Long> wetPlayers = new HashMap<>(); private final Map<Player, Long> wetPlayers;
private static final List<PotionEffectType> EFFECTS = Arrays.asList( private Essentials essentials;
private boolean essentialsCheck;
private static final List<PotionEffectType> EFFECTS;
static {
List<PotionEffectType> pe = Arrays.asList(
PotionEffectType.BLINDNESS, PotionEffectType.BLINDNESS,
PotionEffectType.CONFUSION, PotionEffectType.CONFUSION,
PotionEffectType.HUNGER, PotionEffectType.HUNGER,
@ -53,12 +62,21 @@ public class AcidEffect implements Listener {
PotionEffectType.SLOW_DIGGING, PotionEffectType.SLOW_DIGGING,
PotionEffectType.WEAKNESS, PotionEffectType.WEAKNESS,
PotionEffectType.POISON); PotionEffectType.POISON);
private static final List<PotionEffectType> IMMUNE_EFFECTS = Arrays.asList( EFFECTS = Collections.unmodifiableList(pe);
}
private static final List<PotionEffectType> IMMUNE_EFFECTS;
static {
List<PotionEffectType> im = Arrays.asList(
PotionEffectType.WATER_BREATHING, PotionEffectType.WATER_BREATHING,
PotionEffectType.CONDUIT_POWER); PotionEffectType.CONDUIT_POWER);
IMMUNE_EFFECTS = Collections.unmodifiableList(im);
}
public AcidEffect(AcidIsland addon) { public AcidEffect(AcidIsland addon) {
this.addon = addon; this.addon = addon;
burningPlayers = new HashMap<>();
wetPlayers = new HashMap<>();
// Burn monsters or animals that fall into the acid // Burn monsters or animals that fall into the acid
new AcidTask(addon); new AcidTask(addon);
} }
@ -93,7 +111,6 @@ public class AcidEffect implements Listener {
return; return;
} }
// Slow checks // Slow checks
Location playerLoc = player.getLocation();
// Check for acid rain // Check for acid rain
if (addon.getSettings().getAcidRainDamage() > 0D && addon.getOverWorld().hasStorm()) { if (addon.getSettings().getAcidRainDamage() > 0D && addon.getOverWorld().hasStorm()) {
if (isSafeFromRain(player)) { if (isSafeFromRain(player)) {
@ -110,9 +127,40 @@ public class AcidEffect implements Listener {
@Override @Override
public void run() { public void run() {
// Check if it is still raining or player is safe or dead or there is no damage // Check if it is still raining or player is safe or dead or there is no damage
if (checkForRain(player)) {
this.cancel();
}
}
}.runTaskTimer(addon.getPlugin(), 0L, 20L);
}
}
// If they are already burning in acid then return
if (burningPlayers.containsKey(player) || isSafeFromAcid(player)) {
return;
}
// ACID!
// Put the player into the acid list
burningPlayers.put(player, System.currentTimeMillis() + addon.getSettings().getAcidDamageDelay() * 1000);
// This runnable continuously hurts the player even if they are not
// moving but are in acid.
new BukkitRunnable() {
@Override
public void run() {
if (continuouslyHurtPlayer(player)) {
this.cancel();
}
}
}.runTaskTimer(addon.getPlugin(), 0L, 20L);
}
protected boolean checkForRain(Player player) {
if (!addon.getOverWorld().hasStorm() || player.isDead() || isSafeFromRain(player) || addon.getSettings().getAcidRainDamage() <= 0D) { if (!addon.getOverWorld().hasStorm() || player.isDead() || isSafeFromRain(player) || addon.getSettings().getAcidRainDamage() <= 0D) {
wetPlayers.remove(player); wetPlayers.remove(player);
this.cancel(); return true;
// Check they are still in this world // Check they are still in this world
} else if (wetPlayers.containsKey(player) && wetPlayers.get(player) < System.currentTimeMillis()) { } else if (wetPlayers.containsKey(player) && wetPlayers.get(player) < System.currentTimeMillis()) {
double protection = addon.getSettings().getAcidRainDamage() * getDamageReduced(player); double protection = addon.getSettings().getAcidRainDamage() * getDamageReduced(player);
@ -124,50 +172,32 @@ public class AcidEffect implements Listener {
// Apply damage if there is any // Apply damage if there is any
if (event.getRainDamage() > 0D) { if (event.getRainDamage() > 0D) {
player.damage(event.getRainDamage()); player.damage(event.getRainDamage());
player.getWorld().playSound(playerLoc, Sound.ENTITY_CREEPER_PRIMED, 3F, 3F); player.getWorld().playSound(player.getLocation(), Sound.ENTITY_CREEPER_PRIMED, 3F, 3F);
} }
} }
} }
} return false;
}.runTaskTimer(addon.getPlugin(), 0L, 20L);
} }
protected boolean continuouslyHurtPlayer(Player player) {
}
// If they are already burning in acid then return
if (burningPlayers.containsKey(player)) {
return;
}
if (isSafeFromAcid(player)) {
return;
}
// ACID!
// Put the player into the acid list
burningPlayers.put(player, System.currentTimeMillis() + addon.getSettings().getAcidDamageDelay() * 1000);
// This runnable continuously hurts the player even if they are not
// moving but are in acid.
new BukkitRunnable() {
@Override
public void run() {
if (player.isDead() || isSafeFromAcid(player)) { if (player.isDead() || isSafeFromAcid(player)) {
burningPlayers.remove(player); burningPlayers.remove(player);
this.cancel(); return true;
} else if (burningPlayers.containsKey(player) && burningPlayers.get(player) < System.currentTimeMillis()) { } else if (burningPlayers.containsKey(player) && burningPlayers.get(player) < System.currentTimeMillis()) {
double protection = addon.getSettings().getAcidDamage() * getDamageReduced(player); double protection = addon.getSettings().getAcidDamage() * getDamageReduced(player);
double totalDamage = Math.max(0, addon.getSettings().getAcidDamage() - protection); double totalDamage = Math.max(0, addon.getSettings().getAcidDamage() - protection);
AcidEvent acidEvent = new AcidEvent(player, totalDamage, protection, addon.getSettings().getAcidEffects()); AcidEvent event = new AcidEvent(player, totalDamage, protection, addon.getSettings().getAcidEffects());
addon.getServer().getPluginManager().callEvent(acidEvent); addon.getServer().getPluginManager().callEvent(event);
if (!acidEvent.isCancelled()) { if (!event.isCancelled()) {
acidEvent.getPotionEffects().stream().filter(EFFECTS::contains).forEach(t -> player.addPotionEffect(new PotionEffect(t, addon.getSettings().getAcidEffectDuation() * 20, 1))); event.getPotionEffects().stream().filter(EFFECTS::contains).forEach(t -> player.addPotionEffect(new PotionEffect(t, addon.getSettings().getAcidEffectDuation() * 20, 1)));
// Apply damage if there is any // Apply damage if there is any
if (acidEvent.getTotalDamage() > 0D) { if (event.getTotalDamage() > 0D) {
player.damage(acidEvent.getTotalDamage()); player.damage(event.getTotalDamage());
player.getWorld().playSound(playerLoc, Sound.ENTITY_CREEPER_PRIMED, 3F, 3F); player.getWorld().playSound(player.getLocation(), Sound.ENTITY_CREEPER_PRIMED, 3F, 3F);
} }
} }
} }
} return false;
}.runTaskTimer(addon.getPlugin(), 0L, 20L);
} }
/** /**
@ -176,12 +206,16 @@ public class AcidEffect implements Listener {
* @return true if they are safe * @return true if they are safe
*/ */
private boolean isSafeFromRain(Player player) { private boolean isSafeFromRain(Player player) {
if (player.getWorld().getEnvironment().equals(Environment.NETHER) if (isEssentialsGodMode(player)
|| player.getWorld().getEnvironment().equals(Environment.NETHER)
|| player.getWorld().getEnvironment().equals(Environment.THE_END) || player.getWorld().getEnvironment().equals(Environment.THE_END)
|| (addon.getSettings().isHelmetProtection() && (player.getInventory().getHelmet() != null && player.getInventory().getHelmet().getType().name().contains("HELMET"))) || (addon.getSettings().isHelmetProtection() && (player.getInventory().getHelmet() != null && player.getInventory().getHelmet().getType().name().contains("HELMET")))
|| (!addon.getSettings().isAcidDamageSnow() && player.getLocation().getBlock().getTemperature() < 0.1) // snow falls || (!addon.getSettings().isAcidDamageSnow() && player.getLocation().getBlock().getTemperature() < 0.1) // snow falls
|| player.getLocation().getBlock().getHumidity() == 0 // dry || player.getLocation().getBlock().getHumidity() == 0 // dry
|| (player.getActivePotionEffects().stream().map(PotionEffect::getType).anyMatch(IMMUNE_EFFECTS::contains)) || (player.getActivePotionEffects().stream().map(PotionEffect::getType).anyMatch(IMMUNE_EFFECTS::contains))
// Protect visitors
|| (addon.getPlugin().getIWM().getIvSettings(player.getWorld()).contains(DamageCause.CUSTOM.name())
&& !addon.getIslands().userIsOnIsland(player.getWorld(), User.getInstance(player)))
) { ) {
return true; return true;
} }
@ -200,6 +234,14 @@ public class AcidEffect implements Listener {
* @return true if player is safe * @return true if player is safe
*/ */
private boolean isSafeFromAcid(Player player) { private boolean isSafeFromAcid(Player player) {
// Check for GodMode
if (isEssentialsGodMode(player)
// Protect visitors
|| (addon.getPlugin().getIWM().getIvSettings(player.getWorld()).contains(DamageCause.CUSTOM.name())
&& !addon.getIslands().userIsOnIsland(player.getWorld(), User.getInstance(player)))
) {
return true;
}
// Not in liquid or on snow // Not in liquid or on snow
if (!player.getLocation().getBlock().getType().equals(Material.WATER) if (!player.getLocation().getBlock().getType().equals(Material.WATER)
&& !player.getLocation().getBlock().getType().equals(Material.BUBBLE_COLUMN) && !player.getLocation().getBlock().getType().equals(Material.BUBBLE_COLUMN)
@ -221,6 +263,19 @@ public class AcidEffect implements Listener {
return player.getActivePotionEffects().stream().map(PotionEffect::getType).anyMatch(IMMUNE_EFFECTS::contains); return player.getActivePotionEffects().stream().map(PotionEffect::getType).anyMatch(IMMUNE_EFFECTS::contains);
} }
/**
* Checks if player has Essentials God Mode enabled.
* @param player - player
* @return true if God Mode enabled, false if not or if Essentials plug does not exist
*/
private boolean isEssentialsGodMode(Player player) {
if (!essentialsCheck && essentials == null) {
essentials = (Essentials)Bukkit.getPluginManager().getPlugin("Essentials");
essentialsCheck = true;
}
return essentials != null && essentials.getUser(player).isGodModeEnabled();
}
/** /**
* Checks what protection armor provides and slightly damages it as a result of the acid * Checks what protection armor provides and slightly damages it as a result of the acid
* @param le - player * @param le - player
@ -236,36 +291,25 @@ public class AcidEffect implements Listener {
ItemStack helmet = inv.getHelmet(); ItemStack helmet = inv.getHelmet();
ItemStack chest = inv.getChestplate(); ItemStack chest = inv.getChestplate();
ItemStack pants = inv.getLeggings(); ItemStack pants = inv.getLeggings();
if (helmet != null) {
// Damage if helmet // Damage if helmet
if (helmet.getType().name().contains("HELMET") && damage(helmet)) { if (helmet != null&& helmet.getType().name().contains("HELMET") && damage(helmet)) {
le.getWorld().playSound(le.getLocation(), Sound.ENTITY_ITEM_BREAK, 1F, 1F); le.getWorld().playSound(le.getLocation(), Sound.ENTITY_ITEM_BREAK, 1F, 1F);
inv.setHelmet(null); inv.setHelmet(null);
} }
} if (boots != null && damage(boots)) {
if (boots != null) {
// Damage
if (damage(boots)) {
le.getWorld().playSound(le.getLocation(), Sound.ENTITY_ITEM_BREAK, 1F, 1F); le.getWorld().playSound(le.getLocation(), Sound.ENTITY_ITEM_BREAK, 1F, 1F);
inv.setBoots(null); inv.setBoots(null);
} }
}
// Pants // Pants
if (pants != null) { if (pants != null && damage(pants)) {
// Damage
if (damage(pants)) {
le.getWorld().playSound(le.getLocation(), Sound.ENTITY_ITEM_BREAK, 1F, 1F); le.getWorld().playSound(le.getLocation(), Sound.ENTITY_ITEM_BREAK, 1F, 1F);
inv.setLeggings(null); inv.setLeggings(null);
} }
}
// Chest plate // Chest plate
if (chest != null) { if (chest != null && damage(chest)) {
// Damage
if (damage(chest)) {
le.getWorld().playSound(le.getLocation(), Sound.ENTITY_ITEM_BREAK, 1F, 1F); le.getWorld().playSound(le.getLocation(), Sound.ENTITY_ITEM_BREAK, 1F, 1F);
inv.setChestplate(null); inv.setChestplate(null);
} }
}
return red; return red;
} }

View File

@ -1,5 +1,6 @@
package world.bentobox.acidisland.listeners; package world.bentobox.acidisland.listeners;
import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
@ -8,6 +9,7 @@ import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockFromToEvent; import org.bukkit.event.block.BlockFromToEvent;
import world.bentobox.acidisland.AcidIsland; import world.bentobox.acidisland.AcidIsland;
import world.bentobox.bentobox.util.Util;
public class LavaCheck implements Listener { public class LavaCheck implements Listener {
@ -26,14 +28,13 @@ public class LavaCheck implements Listener {
*/ */
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onCleanstoneGen(BlockFromToEvent e) { public void onCleanstoneGen(BlockFromToEvent e) {
// Only do this in AcidIsland over world if (!(e.getToBlock().getType().equals(Material.WATER)
if (!e.getBlock().getWorld().equals(addon.getOverWorld()) || addon.getSettings().getAcidDamage() <= 0 || !addon.getOverWorld().equals(Util.getWorld(e.getBlock().getWorld()))
// TODO: backward compatibility hack || addon.getSettings().getAcidDamage() <= 0)) {
|| !(e.getToBlock().getType().name().equals("WATER"))) {
return; return;
} }
Material prev = e.getToBlock().getType(); Material prev = e.getToBlock().getType();
addon.getServer().getScheduler().runTask(addon.getPlugin(), () -> { Bukkit.getScheduler().runTask(addon.getPlugin(), () -> {
if (e.getToBlock().getType().equals(Material.STONE)) { if (e.getToBlock().getType().equals(Material.STONE)) {
e.getToBlock().setType(prev); e.getToBlock().setType(prev);
e.getToBlock().getWorld().playSound(e.getToBlock().getLocation(), Sound.ENTITY_CREEPER_PRIMED, 1F, 2F); e.getToBlock().getWorld().playSound(e.getToBlock().getLocation(), Sound.ENTITY_CREEPER_PRIMED, 1F, 2F);

View File

@ -27,7 +27,7 @@ public class AcidTask {
private final AcidIsland addon; private final AcidIsland addon;
private static final List<EntityType> IMMUNE = Arrays.asList(EntityType.TURTLE, EntityType.POLAR_BEAR, EntityType.DROWNED); private static final List<EntityType> IMMUNE = Arrays.asList(EntityType.TURTLE, EntityType.POLAR_BEAR, EntityType.DROWNED);
private Map<Entity, Long> itemsInWater = new ConcurrentHashMap<>(); private Map<Entity, Long> itemsInWater = new ConcurrentHashMap<>();
private BukkitTask findMobsTask; private final BukkitTask findMobsTask;
/** /**
* Runs repeating tasks to deliver acid damage to mobs, etc. * Runs repeating tasks to deliver acid damage to mobs, etc.
@ -35,7 +35,7 @@ public class AcidTask {
*/ */
public AcidTask(AcidIsland addon) { public AcidTask(AcidIsland addon) {
this.addon = addon; this.addon = addon;
findMobsTask = Bukkit.getScheduler().runTaskTimerAsynchronously(addon.getPlugin(), () -> findEntities(), 0L, 20L); findMobsTask = Bukkit.getScheduler().runTaskTimerAsynchronously(addon.getPlugin(), this::findEntities, 0L, 20L);
} }
void findEntities() { void findEntities() {
@ -60,7 +60,7 @@ public class AcidTask {
} }
} }
// Remove any entities not on the burn list // Remove any entities not on the burn list
itemsInWater.keySet().removeIf(i -> !burnList.keySet().contains(i)); itemsInWater.keySet().removeIf(i -> !burnList.containsKey(i));
if (!burnList.isEmpty()) { if (!burnList.isEmpty()) {
Bukkit.getScheduler().runTask(addon.getPlugin(), () -> Bukkit.getScheduler().runTask(addon.getPlugin(), () ->

View File

@ -27,8 +27,8 @@ public class ChunkGeneratorWorld extends ChunkGenerator {
private final AcidIsland addon; private final AcidIsland addon;
private final Random rand = new Random(); private final Random rand = new Random();
private Map<Environment, Integer> seaHeight = new EnumMap<>(Environment.class); private final Map<Environment, Integer> seaHeight = new EnumMap<>(Environment.class);
private Map<Vector, Material> roofChunk = new HashMap<>(); private final Map<Vector, Material> roofChunk = new HashMap<>();
/** /**
* @param addon - addon * @param addon - addon

View File

@ -445,7 +445,6 @@ protection:
invincible-visitors: invincible-visitors:
- BLOCK_EXPLOSION - BLOCK_EXPLOSION
- CONTACT - CONTACT
- CUSTOM
- DROWNING - DROWNING
- ENTITY_ATTACK - ENTITY_ATTACK
- ENTITY_EXPLOSION - ENTITY_EXPLOSION

View File

@ -0,0 +1,7 @@
---
acidisland:
sign:
line0: "&1Đảo Axit"
line1: "[tên]"
line2: Nước là axit!
line3: Hãy cẩn thận! &c<3

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,269 @@
/**
*
*/
package world.bentobox.acidisland;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.logging.Logger;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.entity.Player;
import org.bukkit.plugin.PluginManager;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.stubbing.Answer;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;
import world.bentobox.acidisland.world.ChunkGeneratorWorld;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.Settings;
import world.bentobox.bentobox.api.addons.AddonDescription;
import world.bentobox.bentobox.api.configuration.Config;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.managers.AddonsManager;
import world.bentobox.bentobox.managers.CommandsManager;
import world.bentobox.bentobox.managers.FlagsManager;
import world.bentobox.bentobox.managers.IslandWorldManager;
import world.bentobox.bentobox.managers.IslandsManager;
/**
* @author tastybento
*
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest({Bukkit.class, BentoBox.class, User.class, Config.class })
public class AcidIslandTest {
/**
* Class under test
*/
private AcidIsland addon;
@Mock
private User user;
@Mock
private IslandsManager im;
@Mock
private Island island;
@Mock
private BentoBox plugin;
@Mock
private FlagsManager fm;
@Mock
private Settings settings;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
// Set up plugin
Whitebox.setInternalState(BentoBox.class, "instance", plugin);
when(plugin.getLogger()).thenReturn(Logger.getAnonymousLogger());
// Command manager
CommandsManager cm = mock(CommandsManager.class);
when(plugin.getCommandsManager()).thenReturn(cm);
// Player
Player p = mock(Player.class);
// Sometimes use Mockito.withSettings().verboseLogging()
when(user.isOp()).thenReturn(false);
UUID uuid = UUID.randomUUID();
when(user.getUniqueId()).thenReturn(uuid);
when(user.getPlayer()).thenReturn(p);
when(user.getName()).thenReturn("tastybento");
User.setPlugin(plugin);
// Island World Manager
IslandWorldManager iwm = mock(IslandWorldManager.class);
when(plugin.getIWM()).thenReturn(iwm);
// Player has island to begin with
island = mock(Island.class);
when(im.getIsland(Mockito.any(), Mockito.any(UUID.class))).thenReturn(island);
when(plugin.getIslands()).thenReturn(im);
// Locales
// Return the reference (USE THIS IN THE FUTURE)
when(user.getTranslation(Mockito.anyString())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(0, String.class));
// Server
PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS);
Server server = mock(Server.class);
when(Bukkit.getServer()).thenReturn(server);
when(Bukkit.getLogger()).thenReturn(Logger.getAnonymousLogger());
when(Bukkit.getPluginManager()).thenReturn(mock(PluginManager.class));
when(Bukkit.getWorld(anyString())).thenReturn(null);
// Addon
addon = new AcidIsland();
File jFile = new File("addon.jar");
List<String> lines = Arrays.asList("# AcidIsland Configuration", "uniqueId: config");
Path path = Paths.get("config.yml");
Files.write(path, lines, Charset.forName("UTF-8"));
try (JarOutputStream tempJarOutputStream = new JarOutputStream(new FileOutputStream(jFile))) {
//Added the new files to the jar.
try (FileInputStream fis = new FileInputStream(path.toFile())) {
byte[] buffer = new byte[1024];
int bytesRead = 0;
JarEntry entry = new JarEntry(path.toString());
tempJarOutputStream.putNextEntry(entry);
while((bytesRead = fis.read(buffer)) != -1) {
tempJarOutputStream.write(buffer, 0, bytesRead);
}
}
}
File dataFolder = new File("addons/AcidIsland");
addon.setDataFolder(dataFolder);
addon.setFile(jFile);
AddonDescription desc = new AddonDescription.Builder("bentobox", "AcidIsland", "1.3").description("test").authors("tasty").build();
addon.setDescription(desc);
// Addons manager
AddonsManager am = mock(AddonsManager.class);
when(plugin.getAddonsManager()).thenReturn(am);
// Flags manager
when(plugin.getFlagsManager()).thenReturn(fm);
when(fm.getFlags()).thenReturn(Collections.emptyList());
// Settings
when(plugin.getSettings()).thenReturn(settings);
}
/**
* @throws java.lang.Exception
*/
@After
public void tearDown() throws Exception {
new File("addon.jar").delete();
new File("config.yml").delete();
new File("addons/acidisland","config.yml").delete();
new File("addons/acidisland").delete();
new File("addons").delete();
}
/**
* Test method for {@link world.bentobox.acidisland.AcidIsland#onLoad()}.
*/
@Test
public void testOnLoad() {
addon.onLoad();
// Check that config.yml file has been saved
File check = new File("addons/AcidIsland","config.yml");
assertTrue(check.exists());
}
/**
* Test method for {@link world.bentobox.acidisland.AcidIsland#onEnable()}.
*/
@Test
public void testOnEnable() {
testOnLoad();
addon.onEnable();
assertTrue(addon.getPlayerCommand().isPresent());
assertTrue(addon.getAdminCommand().isPresent());
}
/**
* Test method for {@link world.bentobox.acidisland.AcidIsland#onReload()}.
*/
@Test
public void testOnReload() {
addon.onReload();
// Check that config.yml file has been saved
File check = new File("addons/AcidIsland","config.yml");
assertTrue(check.exists());
}
/**
* Test method for {@link world.bentobox.acidisland.AcidIsland#createWorlds()}.
*/
@Test
public void testCreateWorlds() {
addon.onLoad();
addon.createWorlds();
Mockito.verify(plugin).log("[AcidIsland] Creating AcidIsland...");
Mockito.verify(plugin).log("[AcidIsland] Creating AcidIsland's Nether...");
Mockito.verify(plugin).log("[AcidIsland] Creating AcidIsland's End World...");
}
/**
* Test method for {@link world.bentobox.acidisland.AcidIsland#getSettings()}.
*/
@Test
public void testGetSettings() {
addon.onLoad();
assertNotNull(addon.getSettings());
}
/**
* Test method for {@link world.bentobox.acidisland.AcidIsland#getWorldSettings()}.
*/
@Test
public void testGetWorldSettings() {
addon.onLoad();
assertEquals(addon.getSettings(), addon.getWorldSettings());
}
/**
* Test method for {@link world.bentobox.acidisland.AcidIsland#getDefaultWorldGenerator(java.lang.String, java.lang.String)}.
*/
@Test
public void testGetDefaultWorldGeneratorStringString() {
assertNull(addon.getDefaultWorldGenerator("", ""));
addon.onLoad();
addon.createWorlds();
assertNotNull(addon.getDefaultWorldGenerator("", ""));
assertTrue(addon.getDefaultWorldGenerator("", "") instanceof ChunkGeneratorWorld);
}
/**
* Test method for {@link world.bentobox.acidisland.AcidIsland#allLoaded()}.
*/
@Test
public void testAllLoaded() {
addon.allLoaded();
}
/**
* Test method for {@link world.bentobox.acidisland.AcidIsland#saveWorldSettings()}.
*/
@Test
public void testSaveWorldSettings() {
addon.saveWorldSettings();
}
}

View File

@ -21,12 +21,11 @@ public class AcidEventTest {
@Mock @Mock
private Player player; private Player player;
private List<PotionEffectType> effects;
private AcidEvent e; private AcidEvent e;
@Before @Before
public void setUp() throws Exception { public void setUp() {
effects = Arrays.asList(PotionEffectType.values()); List<PotionEffectType> effects = Arrays.asList(PotionEffectType.values());
e = new AcidEvent(player, 10, 5, effects); e = new AcidEvent(player, 10, 5, effects);
} }
@ -49,18 +48,18 @@ public class AcidEventTest {
@Test @Test
public void testGetTotalDamage() { public void testGetTotalDamage() {
assertTrue(e.getTotalDamage() == 10D); assertEquals(10D, e.getTotalDamage(), 0D);
} }
@Test @Test
public void testGetProtection() { public void testGetProtection() {
assertTrue(e.getProtection() == 5D); assertEquals(5D, e.getProtection(), 0D);
} }
@Test @Test
public void testSetTotalDamage() { public void testSetTotalDamage() {
e.setTotalDamage(50); e.setTotalDamage(50);
assertTrue(e.getTotalDamage() == 50D); assertEquals(50D, e.getTotalDamage(), 0D);
} }
@Test @Test

View File

@ -21,12 +21,11 @@ public class AcidRainEventTest {
@Mock @Mock
private Player player; private Player player;
private List<PotionEffectType> effects;
private AcidRainEvent e; private AcidRainEvent e;
@Before @Before
public void setUp() throws Exception { public void setUp() {
effects = Arrays.asList(PotionEffectType.values()); List<PotionEffectType> effects = Arrays.asList(PotionEffectType.values());
e = new AcidRainEvent(player, 10, 5, effects); e = new AcidRainEvent(player, 10, 5, effects);
} }

View File

@ -12,6 +12,7 @@ import static org.mockito.Mockito.when;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.GameMode; import org.bukkit.GameMode;
@ -34,6 +35,7 @@ import org.bukkit.inventory.ItemFactory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory; import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.PluginManager;
import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
import org.bukkit.scheduler.BukkitScheduler; import org.bukkit.scheduler.BukkitScheduler;
@ -44,12 +46,19 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito; import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner; import org.powermock.modules.junit4.PowerMockRunner;
import com.earth2me.essentials.Essentials;
import com.earth2me.essentials.User;
import world.bentobox.acidisland.AISettings; import world.bentobox.acidisland.AISettings;
import world.bentobox.acidisland.AcidIsland; import world.bentobox.acidisland.AcidIsland;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.managers.IslandWorldManager;
import world.bentobox.bentobox.managers.IslandsManager;
import world.bentobox.bentobox.managers.PlayersManager; import world.bentobox.bentobox.managers.PlayersManager;
import world.bentobox.bentobox.util.Util; import world.bentobox.bentobox.util.Util;
@ -91,18 +100,34 @@ public class AcidEffectTest {
private PlayerInventory inv; private PlayerInventory inv;
@Mock @Mock
private ItemMeta itemMeta; private ItemMeta itemMeta;
@Mock
private PluginManager pim;
@Mock
private Essentials essentials;
@Mock
private User essentialsUser;
@Mock
private BentoBox plugin;
@Mock
private IslandWorldManager iwm;
@Mock
private IslandsManager im;
/** /**
* @throws java.lang.Exception
*/ */
@Before @Before
public void setUp() throws Exception { public void setUp() {
PowerMockito.mockStatic(Bukkit.class); PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS);
when(Bukkit.getScheduler()).thenReturn(scheduler); when(Bukkit.getScheduler()).thenReturn(scheduler);
when(addon.getSettings()).thenReturn(settings); when(addon.getSettings()).thenReturn(settings);
when(addon.getOverWorld()).thenReturn(world); when(addon.getOverWorld()).thenReturn(world);
// Essentials
when(Bukkit.getPluginManager()).thenReturn(pim);
when(pim.getPlugin(eq("Essentials"))).thenReturn(essentials);
when(essentials.getUser(any(Player.class))).thenReturn(essentialsUser);
// Player // Player
when(player.getGameMode()).thenReturn(GameMode.SURVIVAL); when(player.getGameMode()).thenReturn(GameMode.SURVIVAL);
when(player.getWorld()).thenReturn(world); when(player.getWorld()).thenReturn(world);
@ -149,14 +174,23 @@ public class AcidEffectTest {
when(world.getMaxHeight()).thenReturn(5); when(world.getMaxHeight()).thenReturn(5);
when(world.getEnvironment()).thenReturn(Environment.NORMAL); when(world.getEnvironment()).thenReturn(Environment.NORMAL);
// Plugin
when(addon.getPlugin()).thenReturn(plugin);
when(plugin.getIWM()).thenReturn(iwm);
// CUSTOM damage protection
when(iwm.getIvSettings(any())).thenReturn(Collections.singletonList("CUSTOM"));
// Island manager
when(addon.getIslands()).thenReturn(im);
when(im.userIsOnIsland(any(), any())).thenReturn(true);
ae = new AcidEffect(addon); ae = new AcidEffect(addon);
} }
/** /**
* @throws java.lang.Exception
*/ */
@After @After
public void tearDown() throws Exception { public void tearDown() {
} }
/** /**
@ -235,6 +269,40 @@ public class AcidEffectTest {
verify(settings, times(2)).getAcidDamageDelay(); verify(settings, times(2)).getAcidDamageDelay();
} }
/**
* Test method for {@link world.bentobox.acidisland.listeners.AcidEffect#onPlayerMove(org.bukkit.event.player.PlayerMoveEvent)}.
*/
@Test
public void testOnPlayerMoveVisitorNoAcidAndRainDamage() {
when(im.userIsOnIsland(any(), any())).thenReturn(false);
PlayerMoveEvent e = new PlayerMoveEvent(player, from, to);
ae.onPlayerMove(e);
verify(settings, never()).getAcidDamageDelay();
}
/**
* Test method for {@link world.bentobox.acidisland.listeners.AcidEffect#onPlayerMove(org.bukkit.event.player.PlayerMoveEvent)}.
*/
@Test
public void testOnPlayerMoveVisitorAcidAndRainDamage() {
// No protection against CUSTOM damage
when(iwm.getIvSettings(any())).thenReturn(Collections.emptyList());
PlayerMoveEvent e = new PlayerMoveEvent(player, from, to);
ae.onPlayerMove(e);
verify(settings, times(2)).getAcidDamageDelay();
}
/**
* Test method for {@link world.bentobox.acidisland.listeners.AcidEffect#onPlayerMove(org.bukkit.event.player.PlayerMoveEvent)}.
*/
@Test
public void testOnPlayerMoveGodModeNoAcidAndRainDamage() {
when(essentialsUser.isGodModeEnabled()).thenReturn(true);
PlayerMoveEvent e = new PlayerMoveEvent(player, from, to);
ae.onPlayerMove(e);
verify(settings, never()).getAcidDamageDelay();
}
/** /**
* Test method for {@link world.bentobox.acidisland.listeners.AcidEffect#onPlayerMove(org.bukkit.event.player.PlayerMoveEvent)}. * Test method for {@link world.bentobox.acidisland.listeners.AcidEffect#onPlayerMove(org.bukkit.event.player.PlayerMoveEvent)}.
*/ */
@ -319,8 +387,8 @@ public class AcidEffectTest {
PlayerMoveEvent e = new PlayerMoveEvent(player, from, to); PlayerMoveEvent e = new PlayerMoveEvent(player, from, to);
ae.onPlayerMove(e); ae.onPlayerMove(e);
// 2 times only // 3 times only
verify(addon, times(2)).getPlugin(); verify(addon, times(3)).getPlugin();
} }
/** /**
@ -335,8 +403,8 @@ public class AcidEffectTest {
PlayerMoveEvent e = new PlayerMoveEvent(player, from, to); PlayerMoveEvent e = new PlayerMoveEvent(player, from, to);
ae.onPlayerMove(e); ae.onPlayerMove(e);
// 2 times only // 3 times only
verify(addon, times(2)).getPlugin(); verify(addon, times(3)).getPlugin();
} }
/** /**

View File

@ -0,0 +1,194 @@
package world.bentobox.acidisland.listeners;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.event.block.BlockFromToEvent;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.PluginManager;
import org.bukkit.scheduler.BukkitScheduler;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.earth2me.essentials.Essentials;
import com.earth2me.essentials.User;
import world.bentobox.acidisland.AISettings;
import world.bentobox.acidisland.AcidIsland;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.managers.IslandWorldManager;
import world.bentobox.bentobox.managers.IslandsManager;
import world.bentobox.bentobox.managers.PlayersManager;
import world.bentobox.bentobox.util.Util;
/**
* @author tastybento
*
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest({Bukkit.class, Util.class})
public class LavaCheckTest {
@Mock
private AcidIsland addon;
@Mock
private BukkitScheduler scheduler;
private AISettings settings;
@Mock
private Location from;
@Mock
private Location to;
@Mock
private World world;
@Mock
private Location location;
@Mock
private PlayersManager pm;
@Mock
private Block block;
@Mock
private Block airBlock;
@Mock
private Block solidBlock;
@Mock
private PlayerInventory inv;
@Mock
private ItemMeta itemMeta;
@Mock
private PluginManager pim;
@Mock
private Essentials essentials;
@Mock
private User essentialsUser;
@Mock
private BentoBox plugin;
@Mock
private IslandWorldManager iwm;
@Mock
private IslandsManager im;
private LavaCheck lc;
/**
*/
@Before
public void setUp() {
PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS);
when(Bukkit.getScheduler()).thenReturn(scheduler);
settings = new AISettings();
when(addon.getSettings()).thenReturn(settings);
when(addon.getOverWorld()).thenReturn(world);
// Blocks
when(block.getType()).thenReturn(Material.WATER);
when(block.getWorld()).thenReturn(world);
when(block.getLocation()).thenReturn(location);
// CUT
lc = new LavaCheck(addon);
}
/**
*/
@After
public void tearDown() {
}
/**
* Test method for {@link world.bentobox.acidisland.listeners.LavaCheck#onCleanstoneGen(org.bukkit.event.block.BlockFromToEvent)}.
*/
@Test
public void testOnCleanstoneGen() {
ArgumentCaptor<Runnable> argument = ArgumentCaptor.forClass(Runnable.class);
BlockFromToEvent e = new BlockFromToEvent(airBlock, block);
lc.onCleanstoneGen(e);
verify(scheduler).runTask(any(), argument.capture());
// make block now be stone
when(block.getType()).thenReturn(Material.STONE);
// Run runnable
argument.getValue().run();
verify(block).setType(eq(Material.WATER));
verify(world).playSound(eq(location), eq(Sound.ENTITY_CREEPER_PRIMED), eq(1F), eq(2F));
}
/**
* Test method for {@link world.bentobox.acidisland.listeners.LavaCheck#onCleanstoneGen(org.bukkit.event.block.BlockFromToEvent)}.
*/
@Test
public void testOnCleanstoneGenNoStone() {
ArgumentCaptor<Runnable> argument = ArgumentCaptor.forClass(Runnable.class);
BlockFromToEvent e = new BlockFromToEvent(airBlock, block);
lc.onCleanstoneGen(e);
verify(scheduler).runTask(any(), argument.capture());
// make block now be obsidian
when(block.getType()).thenReturn(Material.OBSIDIAN);
// Run runnable
argument.getValue().run();
verify(block, never()).setType(any());
verify(world, never()).playSound(any(Location.class), any(Sound.class), anyFloat(),anyFloat());
}
/**
* Test method for {@link world.bentobox.acidisland.listeners.LavaCheck#onCleanstoneGen(org.bukkit.event.block.BlockFromToEvent)}.
*/
@Test
public void testOnCleanstoneGenWrongWorld() {
when(block.getWorld()).thenReturn(Mockito.mock(World.class));
BlockFromToEvent e = new BlockFromToEvent(airBlock, block);
lc.onCleanstoneGen(e);
verify(block, never()).setType(any());
verify(world, never()).playSound(any(Location.class), any(Sound.class), anyFloat(),anyFloat());
}
/**
* Test method for {@link world.bentobox.acidisland.listeners.LavaCheck#onCleanstoneGen(org.bukkit.event.block.BlockFromToEvent)}.
*/
@Test
public void testOnCleanstoneGenNotWater() {
when(block.getType()).thenReturn(Material.LAVA);
BlockFromToEvent e = new BlockFromToEvent(airBlock, block);
lc.onCleanstoneGen(e);
verify(block, never()).setType(any());
verify(world, never()).playSound(any(Location.class), any(Sound.class), anyFloat(),anyFloat());
}
/**
* Test method for {@link world.bentobox.acidisland.listeners.LavaCheck#onCleanstoneGen(org.bukkit.event.block.BlockFromToEvent)}.
*/
@Test
public void testOnCleanstoneGenNoAcid() {
// No acid damage
settings.setAcidDamage(0);
BlockFromToEvent e = new BlockFromToEvent(airBlock, block);
lc.onCleanstoneGen(e);
verify(block, never()).setType(any());
verify(world, never()).playSound(any(Location.class), any(Sound.class), anyFloat(),anyFloat());
}
}

View File

@ -64,8 +64,6 @@ public class AcidTaskTest {
@Mock @Mock
private World world; private World world;
private List<Entity> mob;
@Mock @Mock
private @Nullable World nether; private @Nullable World nether;
@Mock @Mock
@ -81,10 +79,9 @@ public class AcidTaskTest {
/** /**
* @throws java.lang.Exception
*/ */
@Before @Before
public void setUp() throws Exception { public void setUp() {
PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS); PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS);
when(Bukkit.getScheduler()).thenReturn(scheduler); when(Bukkit.getScheduler()).thenReturn(scheduler);
when(scheduler.runTaskTimerAsynchronously(any(), any(Runnable.class), anyLong(), anyLong())).thenReturn(task); when(scheduler.runTaskTimerAsynchronously(any(), any(Runnable.class), anyLong(), anyLong())).thenReturn(task);
@ -101,7 +98,7 @@ public class AcidTaskTest {
// Default squid // Default squid
mob = new ArrayList<>(); List<Entity> mob = new ArrayList<>();
Squid squid = mock(Squid.class); Squid squid = mock(Squid.class);
when(squid.getType()).thenReturn(EntityType.SQUID); when(squid.getType()).thenReturn(EntityType.SQUID);
when(squid.getLocation()).thenReturn(l); when(squid.getLocation()).thenReturn(l);
@ -141,10 +138,9 @@ public class AcidTaskTest {
} }
/** /**
* @throws java.lang.Exception
*/ */
@After @After
public void tearDown() throws Exception { public void tearDown() {
} }
/** /**

View File

@ -54,10 +54,9 @@ public class ChunkGeneratorWorldTest {
private ChunkData data; private ChunkData data;
/** /**
* @throws java.lang.Exception
*/ */
@Before @Before
public void setUp() throws Exception { public void setUp() {
// Bukkit // Bukkit
PowerMockito.mockStatic(Bukkit.class); PowerMockito.mockStatic(Bukkit.class);
Server server = mock(Server.class); Server server = mock(Server.class);
@ -76,10 +75,9 @@ public class ChunkGeneratorWorldTest {
} }
/** /**
* @throws java.lang.Exception
*/ */
@After @After
public void tearDown() throws Exception { public void tearDown() {
} }
/** /**