mirror of
https://github.com/garbagemule/MobArena.git
synced 2024-11-22 10:36:00 +01:00
Introducing MobArena Labs.
This commit introduces the concept of MobArena Labs as well as the first explicitly experimental feature in the form of custom entity type lists for the cleanup procedure. MobArena Labs is an attempt at a compromise between the otherwise rigid approach to functionality due to maintainability concerns and some of the esoteric feature requests we see on Github. The compromise manifests itself as follows: - All experimental functionality is opt-in and set up primarily in a new file, `labs.yml`, which must be created manually. Nothing is provided for users by default, so the "I know what I'm doing"-attitude required for this functionality to work hopefully helps convey the user-facing downside; that experimental functionality is much more likely to break between releases, and that compatibility issues are ignored. - The other side of the coin is that we can try new things as long as they are _local to MobArena_, i.e. no external dependencies. Some of the esoteric and niche feature requests we see on Github could make it into the plugin as experimental features. If enough servers make use of them and provide feedback, they could end up as regular features with stability and robustness concerns on par with core parts of the plugin. We use bStats to help visualize feature usage (or lack thereof so we can remove unused functionality if it is problematic). The first experimental feature is the ability to customize the list of entity types that MobArena looks for when clearing the arena region of residual entities such as arrows and experience orbs. This is called the Housekeeper, and it has its own section in `labs.yml`. It can be toggled on or off with the `enabled` flag, and the list of entities is specified with the `entities` list. Because the original code was hardcoded in the ArenaImpl class, no effort has been made to make the Housekeeper and its settings per-arena configurable. Closes #667
This commit is contained in:
parent
52226fa1c9
commit
252c2b4c01
@ -6,6 +6,7 @@ import com.garbagemule.MobArena.ScoreboardManager.NullScoreboardManager;
|
||||
import com.garbagemule.MobArena.announce.Announcer;
|
||||
import com.garbagemule.MobArena.announce.MessengerAnnouncer;
|
||||
import com.garbagemule.MobArena.announce.TitleAnnouncer;
|
||||
import com.garbagemule.MobArena.housekeeper.Housekeeper;
|
||||
import com.garbagemule.MobArena.steps.Step;
|
||||
import com.garbagemule.MobArena.steps.StepFactory;
|
||||
import com.garbagemule.MobArena.steps.PlayerJoinArena;
|
||||
@ -35,7 +36,6 @@ import com.garbagemule.MobArena.waves.SheepBouncer;
|
||||
import com.garbagemule.MobArena.waves.WaveManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
@ -148,6 +148,7 @@ public class ArenaImpl implements Arena
|
||||
private StepFactory playerSpecArena;
|
||||
|
||||
private SpawnsPets spawnsPets;
|
||||
private Housekeeper housekeeper;
|
||||
|
||||
/**
|
||||
* Primary constructor. Requires a name and a world.
|
||||
@ -257,6 +258,8 @@ public class ArenaImpl implements Arena
|
||||
this.playerSpecArena = PlayerSpecArena.create(this);
|
||||
|
||||
this.spawnsPets = plugin.getArenaMaster().getSpawnsPets();
|
||||
|
||||
this.housekeeper = plugin.getLabs().housekeeper;
|
||||
}
|
||||
|
||||
|
||||
@ -1355,45 +1358,10 @@ public class ArenaImpl implements Arena
|
||||
}
|
||||
|
||||
private void cleanup() {
|
||||
removeMonsters();
|
||||
removeBlocks();
|
||||
removeEntities();
|
||||
housekeeper.clean(this);
|
||||
clearPlayers();
|
||||
}
|
||||
|
||||
private void removeMonsters() {
|
||||
monsterManager.clear();
|
||||
}
|
||||
|
||||
private void removeBlocks() {
|
||||
for (Block b : blocks) {
|
||||
b.setType(Material.AIR);
|
||||
}
|
||||
blocks.clear();
|
||||
}
|
||||
|
||||
private void removeEntities() {
|
||||
List<Chunk> chunks = region.getChunks();
|
||||
|
||||
for (Chunk c : chunks) {
|
||||
for (Entity e : c.getEntities()) {
|
||||
if (e == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (e.getType()) {
|
||||
case DROPPED_ITEM:
|
||||
case EXPERIENCE_ORB:
|
||||
case ARROW:
|
||||
case MINECART:
|
||||
case BOAT:
|
||||
case SHULKER_BULLET:
|
||||
e.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void clearPlayers() {
|
||||
arenaPlayers.clear();
|
||||
arenaPlayerMap.clear();
|
||||
|
@ -8,6 +8,8 @@ import com.garbagemule.MobArena.formula.FormulaMacros;
|
||||
import com.garbagemule.MobArena.formula.FormulaManager;
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.framework.ArenaMaster;
|
||||
import com.garbagemule.MobArena.labs.Labs;
|
||||
import com.garbagemule.MobArena.labs.LabsChart;
|
||||
import com.garbagemule.MobArena.listeners.MAGlobalListener;
|
||||
import com.garbagemule.MobArena.metrics.ArenaCountChart;
|
||||
import com.garbagemule.MobArena.metrics.ClassChestsChart;
|
||||
@ -69,6 +71,8 @@ public class MobArena extends JavaPlugin
|
||||
|
||||
private SignListeners signListeners;
|
||||
|
||||
private Labs labs;
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
thingman = new ThingManager(this);
|
||||
@ -180,6 +184,8 @@ public class MobArena extends JavaPlugin
|
||||
metrics.addCustomChart(new IsolatedChatChart(this));
|
||||
metrics.addCustomChart(new MonsterInfightChart(this));
|
||||
metrics.addCustomChart(new PvpEnabledChart(this));
|
||||
|
||||
metrics.addCustomChart(new LabsChart(this, "labs_housekeeper_pie", config -> config.housekeeper));
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
@ -188,6 +194,7 @@ public class MobArena extends JavaPlugin
|
||||
|
||||
try {
|
||||
reloadConfig();
|
||||
reloadLabs();
|
||||
reloadGlobalMessenger();
|
||||
reloadFormulaMacros();
|
||||
reloadArenaMaster();
|
||||
@ -210,6 +217,15 @@ public class MobArena extends JavaPlugin
|
||||
config = loadsConfigFile.load();
|
||||
}
|
||||
|
||||
private void reloadLabs() {
|
||||
try {
|
||||
labs = Labs.create(this);
|
||||
} catch (IOException e) {
|
||||
getLogger().log(Level.WARNING, "There was an error loading MobArena Labs!", e);
|
||||
labs = Labs.createDefault();
|
||||
}
|
||||
}
|
||||
|
||||
private void reloadGlobalMessenger() {
|
||||
String prefix = config.getString("global-settings.prefix", "");
|
||||
if (prefix.isEmpty()) {
|
||||
@ -317,4 +333,8 @@ public class MobArena extends JavaPlugin
|
||||
public FormulaMacros getFormulaMacros() {
|
||||
return macros;
|
||||
}
|
||||
|
||||
public Labs getLabs() {
|
||||
return labs;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
package com.garbagemule.MobArena.housekeeper;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import org.bukkit.Material;
|
||||
|
||||
class BlockCleaner implements Housekeeper {
|
||||
|
||||
private static final BlockCleaner DEFAULT = new BlockCleaner();
|
||||
|
||||
private BlockCleaner() {
|
||||
// OK BOSS
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clean(Arena arena) {
|
||||
arena.getBlocks().forEach(block -> block.setType(Material.AIR));
|
||||
arena.getBlocks().clear();
|
||||
}
|
||||
|
||||
static BlockCleaner getDefault() {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.garbagemule.MobArena.housekeeper;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
class CompositeHousekeeper implements Housekeeper {
|
||||
|
||||
private final List<Housekeeper> minions;
|
||||
|
||||
CompositeHousekeeper(Housekeeper... minions) {
|
||||
this.minions = Arrays.asList(minions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clean(Arena arena) {
|
||||
minions.forEach(minion -> minion.clean(arena));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package com.garbagemule.MobArena.housekeeper;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.region.ArenaRegion;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.Objects;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
class EntityCleaner implements Housekeeper {
|
||||
|
||||
private static final EntityCleaner DEFAULT = new EntityCleaner(EnumSet.of(
|
||||
EntityType.ARROW,
|
||||
EntityType.BOAT,
|
||||
EntityType.DROPPED_ITEM,
|
||||
EntityType.EXPERIENCE_ORB,
|
||||
EntityType.MINECART,
|
||||
EntityType.SHULKER_BULLET
|
||||
));
|
||||
|
||||
private final EnumSet<EntityType> entities;
|
||||
|
||||
EntityCleaner(EnumSet<EntityType> entities) {
|
||||
this.entities = entities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clean(Arena arena) {
|
||||
ArenaRegion region = arena.getRegion();
|
||||
|
||||
for (Chunk chunk : region.getChunks()) {
|
||||
for (Entity entity : chunk.getEntities()) {
|
||||
if (entity == null) {
|
||||
continue;
|
||||
}
|
||||
if (entities.contains(entity.getType())) {
|
||||
entity.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static EntityCleaner getDefault() {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
static EntityCleaner create(HousekeeperConfig config, Logger log) {
|
||||
if (config.entities == null || config.entities.isEmpty()) {
|
||||
return EntityCleaner.getDefault();
|
||||
}
|
||||
|
||||
EnumSet<EntityType> entities = config.entities
|
||||
.stream()
|
||||
.map(value -> parse(value, log))
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toCollection(() -> EnumSet.noneOf(EntityType.class)));
|
||||
|
||||
return new EntityCleaner(entities);
|
||||
}
|
||||
|
||||
private static EntityType parse(String value, Logger log) {
|
||||
try {
|
||||
return EntityType.valueOf(value.toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
if (log != null) {
|
||||
log.warning("Unknown housekeeper entity type '" + value + "', skipping...");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.garbagemule.MobArena.housekeeper;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
|
||||
public interface Housekeeper {
|
||||
|
||||
void clean(Arena arena);
|
||||
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
package com.garbagemule.MobArena.housekeeper;
|
||||
|
||||
import com.garbagemule.MobArena.labs.LabsConfigSection;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class HousekeeperConfig extends LabsConfigSection {
|
||||
|
||||
public final Set<String> entities;
|
||||
|
||||
private HousekeeperConfig(boolean enabled, Set<String> entities) {
|
||||
super(enabled);
|
||||
this.entities = Collections.unmodifiableSet(entities);
|
||||
}
|
||||
|
||||
public static HousekeeperConfig parse(Map<String, Object> section) {
|
||||
boolean enabled = parseEnabled(section);
|
||||
Set<String> entities = parseEntities(section);
|
||||
|
||||
return new HousekeeperConfig(enabled, entities);
|
||||
}
|
||||
|
||||
private static boolean parseEnabled(Map<String, Object> section) {
|
||||
if (section == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Object raw = section.get("enabled");
|
||||
if (raw == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (raw instanceof Boolean) {
|
||||
return (Boolean) raw;
|
||||
}
|
||||
if (raw instanceof String) {
|
||||
return Boolean.parseBoolean((String) raw);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unexpected 'enabled' value in housekeeper config");
|
||||
}
|
||||
|
||||
private static Set<String> parseEntities(Map<String, Object> section) {
|
||||
if (section == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
Object raw = section.get("entities");
|
||||
if (raw == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
if (raw instanceof List) {
|
||||
return ((List<?>) raw)
|
||||
.stream()
|
||||
.map(String::valueOf)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
if (raw instanceof String) {
|
||||
String value = (String) raw;
|
||||
String[] parts = value.split(",");
|
||||
return Arrays.stream(parts)
|
||||
.map(String::trim)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unexpected 'entities' value in housekeeper config");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package com.garbagemule.MobArena.housekeeper;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public final class Housekeepers {
|
||||
|
||||
private static final Housekeeper DEFAULT = new CompositeHousekeeper(
|
||||
MonsterCleaner.getDefault(),
|
||||
BlockCleaner.getDefault(),
|
||||
EntityCleaner.getDefault()
|
||||
);
|
||||
|
||||
public static Housekeeper getDefault() {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
public static Housekeeper create(HousekeeperConfig config, Logger log) {
|
||||
MonsterCleaner monsters = MonsterCleaner.getDefault();
|
||||
BlockCleaner blocks = BlockCleaner.getDefault();
|
||||
EntityCleaner entities = EntityCleaner.create(config, log);
|
||||
|
||||
return new CompositeHousekeeper(monsters, blocks, entities);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.garbagemule.MobArena.housekeeper;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
|
||||
class MonsterCleaner implements Housekeeper {
|
||||
|
||||
private static final MonsterCleaner DEFAULT = new MonsterCleaner();
|
||||
|
||||
private MonsterCleaner() {
|
||||
// OK BOSS
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clean(Arena arena) {
|
||||
arena.getMonsterManager().clear();
|
||||
}
|
||||
|
||||
static MonsterCleaner getDefault() {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
}
|
77
src/main/java/com/garbagemule/MobArena/labs/Labs.java
Normal file
77
src/main/java/com/garbagemule/MobArena/labs/Labs.java
Normal file
@ -0,0 +1,77 @@
|
||||
package com.garbagemule.MobArena.labs;
|
||||
|
||||
import com.garbagemule.MobArena.MobArena;
|
||||
import com.garbagemule.MobArena.housekeeper.Housekeeper;
|
||||
import com.garbagemule.MobArena.housekeeper.HousekeeperConfig;
|
||||
import com.garbagemule.MobArena.housekeeper.Housekeepers;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class Labs {
|
||||
|
||||
public final LabsConfig config;
|
||||
public final Housekeeper housekeeper;
|
||||
|
||||
private Labs(
|
||||
LabsConfig config,
|
||||
Housekeeper housekeeper
|
||||
) {
|
||||
this.config = config;
|
||||
this.housekeeper = housekeeper;
|
||||
}
|
||||
|
||||
public static Labs create(MobArena plugin) throws IOException {
|
||||
Path labsFile = plugin.getDataFolder().toPath().resolve("labs.yml");
|
||||
if (!Files.exists(labsFile)) {
|
||||
return createDefault();
|
||||
}
|
||||
|
||||
Logger log = plugin.getLogger();
|
||||
String[] lines = {
|
||||
"---==[ MobArena Labs ]==---",
|
||||
"Labs is a set of experimental opt-in features that are exempt from",
|
||||
"the goals of stability and robustness that are usually imposed on",
|
||||
"functionality in the plugin. This means that breaking changes are",
|
||||
"to be expected. No effort is made to ensure compatibility between",
|
||||
"different iterations of Labs features.",
|
||||
};
|
||||
Arrays.stream(lines).forEach(log::info);
|
||||
|
||||
Yaml yaml = new Yaml();
|
||||
byte[] bytes = Files.readAllBytes(labsFile);
|
||||
Map<String, Object> map = yaml.load(new String(bytes));
|
||||
|
||||
LabsConfig config = LabsConfig.parse(map);
|
||||
Housekeeper housekeeper = createHousekeeper(config, log);
|
||||
|
||||
log.info("---");
|
||||
|
||||
return new Labs(config, housekeeper);
|
||||
}
|
||||
|
||||
private static Housekeeper createHousekeeper(LabsConfig root, Logger log) {
|
||||
HousekeeperConfig config = root.housekeeper;
|
||||
if (config == null || !config.enabled) {
|
||||
return Housekeepers.getDefault();
|
||||
}
|
||||
|
||||
Housekeeper housekeeper = Housekeepers.create(config, log);
|
||||
log.info("Custom housekeeper created.");
|
||||
|
||||
return housekeeper;
|
||||
}
|
||||
|
||||
public static Labs createDefault() {
|
||||
return new Labs(
|
||||
LabsConfig.parse(null),
|
||||
Housekeepers.getDefault()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
35
src/main/java/com/garbagemule/MobArena/labs/LabsChart.java
Normal file
35
src/main/java/com/garbagemule/MobArena/labs/LabsChart.java
Normal file
@ -0,0 +1,35 @@
|
||||
package com.garbagemule.MobArena.labs;
|
||||
|
||||
import com.garbagemule.MobArena.MobArena;
|
||||
import org.bstats.charts.SimplePie;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class LabsChart extends SimplePie {
|
||||
|
||||
public LabsChart(
|
||||
MobArena plugin,
|
||||
String chartId,
|
||||
Function<LabsConfig, LabsConfigSection> getter
|
||||
) {
|
||||
super(chartId, () -> usesFeature(plugin, getter) ? "Yes" : "No");
|
||||
}
|
||||
|
||||
private static boolean usesFeature(
|
||||
MobArena plugin,
|
||||
Function<LabsConfig, LabsConfigSection> getter
|
||||
) {
|
||||
Labs labs = plugin.getLabs();
|
||||
if (labs == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LabsConfigSection section = getter.apply(labs.config);
|
||||
if (section == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return section.enabled;
|
||||
}
|
||||
|
||||
}
|
42
src/main/java/com/garbagemule/MobArena/labs/LabsConfig.java
Normal file
42
src/main/java/com/garbagemule/MobArena/labs/LabsConfig.java
Normal file
@ -0,0 +1,42 @@
|
||||
package com.garbagemule.MobArena.labs;
|
||||
|
||||
import com.garbagemule.MobArena.housekeeper.HousekeeperConfig;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class LabsConfig {
|
||||
|
||||
public final HousekeeperConfig housekeeper;
|
||||
|
||||
LabsConfig(
|
||||
HousekeeperConfig housekeeper
|
||||
) {
|
||||
this.housekeeper = housekeeper;
|
||||
}
|
||||
|
||||
static LabsConfig parse(Map<String, Object> root) {
|
||||
return new LabsConfig(
|
||||
parse(root, "housekeeper", HousekeeperConfig::parse)
|
||||
);
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
private static <C> C parse(
|
||||
Map<String, Object> root,
|
||||
String key,
|
||||
Function<Map<String, Object>, C> parse
|
||||
) {
|
||||
if (root == null) {
|
||||
return parse.apply(null);
|
||||
}
|
||||
|
||||
Object raw = root.get(key);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> section = (Map<String, Object>) raw;
|
||||
|
||||
return parse.apply(section);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.garbagemule.MobArena.labs;
|
||||
|
||||
public abstract class LabsConfigSection {
|
||||
|
||||
public final boolean enabled;
|
||||
|
||||
protected LabsConfigSection(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
}
|
@ -2,6 +2,14 @@ package com.garbagemule.MobArena.util;
|
||||
|
||||
public class Enums
|
||||
{
|
||||
public static <E extends Enum<E>> E valueOf(Class<E> type, String value) {
|
||||
try {
|
||||
return Enum.valueOf(type, value);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the enum value of a string, null if it doesn't exist.
|
||||
*/
|
||||
|
@ -0,0 +1,36 @@
|
||||
package com.garbagemule.MobArena.housekeeper;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
public class BlockCleanerTest {
|
||||
|
||||
@Test
|
||||
public void defaultCleanerSetsArenaBlocksToAir() {
|
||||
Block block1 = mock(Block.class);
|
||||
Block block2 = mock(Block.class);
|
||||
Block block3 = mock(Block.class);
|
||||
Set<Block> blocks = new HashSet<>(Arrays.asList(block1, block2, block3));
|
||||
Arena arena = mock(Arena.class);
|
||||
when(arena.getBlocks()).thenReturn(blocks);
|
||||
BlockCleaner subject = BlockCleaner.getDefault();
|
||||
|
||||
subject.clean(arena);
|
||||
|
||||
verify(block1).setType(Material.AIR);
|
||||
verify(block2).setType(Material.AIR);
|
||||
verify(block3).setType(Material.AIR);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
package com.garbagemule.MobArena.housekeeper;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.region.ArenaRegion;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
public class EntityCleanerTest {
|
||||
|
||||
@Test
|
||||
public void defaultCleanerRemovesDefaultsOnly() {
|
||||
Entity[] defaults = new Entity[] {
|
||||
fake(EntityType.ARROW),
|
||||
fake(EntityType.BOAT),
|
||||
fake(EntityType.DROPPED_ITEM),
|
||||
fake(EntityType.EXPERIENCE_ORB),
|
||||
fake(EntityType.MINECART),
|
||||
fake(EntityType.SHULKER_BULLET),
|
||||
};
|
||||
Entity[] extras = new Entity[] {
|
||||
fake(EntityType.ARMOR_STAND),
|
||||
fake(EntityType.PIG),
|
||||
};
|
||||
Arena arena = mock(Arena.class);
|
||||
ArenaRegion region = mock(ArenaRegion.class);
|
||||
Chunk chunk = mock(Chunk.class);
|
||||
when(arena.getRegion()).thenReturn(region);
|
||||
when(region.getChunks()).thenReturn(Collections.singletonList(chunk));
|
||||
when(chunk.getEntities()).thenReturn(concat(defaults, extras));
|
||||
EntityCleaner subject = EntityCleaner.getDefault();
|
||||
|
||||
subject.clean(arena);
|
||||
|
||||
for (Entity entity : defaults) {
|
||||
verify(entity).remove();
|
||||
}
|
||||
for (Entity entity : extras) {
|
||||
verify(entity, never()).remove();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customCleanerRemovesProvidedTypesOnly() {
|
||||
Entity[] removed = new Entity[] {
|
||||
fake(EntityType.DROPPED_ITEM),
|
||||
fake(EntityType.DROPPED_ITEM),
|
||||
fake(EntityType.ARMOR_STAND),
|
||||
fake(EntityType.DROPPED_ITEM),
|
||||
};
|
||||
Entity[] retained = new Entity[] {
|
||||
fake(EntityType.MINECART),
|
||||
fake(EntityType.EXPERIENCE_ORB),
|
||||
fake(EntityType.EXPERIENCE_ORB),
|
||||
fake(EntityType.EXPERIENCE_ORB),
|
||||
fake(EntityType.ARROW),
|
||||
fake(EntityType.ARROW),
|
||||
};
|
||||
Arena arena = mock(Arena.class);
|
||||
ArenaRegion region = mock(ArenaRegion.class);
|
||||
Chunk chunk = mock(Chunk.class);
|
||||
when(arena.getRegion()).thenReturn(region);
|
||||
when(region.getChunks()).thenReturn(Collections.singletonList(chunk));
|
||||
when(chunk.getEntities()).thenReturn(concat(removed, retained));
|
||||
EntityCleaner subject = new EntityCleaner(EnumSet.of(
|
||||
EntityType.DROPPED_ITEM,
|
||||
EntityType.ARMOR_STAND
|
||||
));
|
||||
|
||||
subject.clean(arena);
|
||||
|
||||
for (Entity entity : removed) {
|
||||
verify(entity).remove();
|
||||
}
|
||||
for (Entity entity : retained) {
|
||||
verify(entity, never()).remove();
|
||||
}
|
||||
}
|
||||
|
||||
private static Entity fake(EntityType type) {
|
||||
Entity entity = mock(Entity.class);
|
||||
when(entity.getType()).thenReturn(type);
|
||||
return entity;
|
||||
}
|
||||
|
||||
private static Entity[] concat(Entity[] a, Entity[] b) {
|
||||
Entity[] result = Arrays.copyOf(a, a.length + b.length);
|
||||
System.arraycopy(b, 0, result, a.length, b.length);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.garbagemule.MobArena.housekeeper;
|
||||
|
||||
import com.garbagemule.MobArena.MonsterManager;
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
public class MonsterCleanerTest {
|
||||
|
||||
@Test
|
||||
public void defaultCleanerClearsMonsterManager() {
|
||||
Arena arena = mock(Arena.class);
|
||||
MonsterManager monsters = mock(MonsterManager.class);
|
||||
when(arena.getMonsterManager()).thenReturn(monsters);
|
||||
MonsterCleaner subject = MonsterCleaner.getDefault();
|
||||
|
||||
subject.clean(arena);
|
||||
|
||||
verify(monsters).clear();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user