Island levels (#178)

* Stores level data on a per island basis

* Migrate after BentoBox worlds have loaded.

* Added new Admin set initial level handicap command

* Bug fixing

* Fix test

* Removed code smell
This commit is contained in:
tastybento 2020-07-26 14:40:17 -07:00 committed by GitHub
parent 507cefd128
commit dab0e84bc0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 383 additions and 98 deletions

View File

@ -65,7 +65,7 @@
<!-- Do not change unless you want different name for local builds. -->
<build.number>-LOCAL</build.number>
<!-- This allows to change between versions. -->
<build.version>2.3.4</build.version>
<build.version>2.4.0</build.version>
</properties>
<!-- Profiles will allow to automatically change build version. -->

View File

@ -22,6 +22,7 @@ import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.level.calculators.Pipeliner;
import world.bentobox.level.commands.AdminLevelCommand;
import world.bentobox.level.commands.AdminLevelStatusCommand;
import world.bentobox.level.commands.AdminSetInitialLevelCommand;
import world.bentobox.level.commands.AdminTopCommand;
import world.bentobox.level.commands.IslandLevelCommand;
import world.bentobox.level.commands.IslandTopCommand;
@ -30,7 +31,6 @@ import world.bentobox.level.config.BlockConfig;
import world.bentobox.level.config.ConfigSettings;
import world.bentobox.level.listeners.IslandActivitiesListeners;
import world.bentobox.level.listeners.JoinLeaveListener;
import world.bentobox.level.objects.LevelsData;
import world.bentobox.level.requests.LevelRequestHandler;
import world.bentobox.level.requests.TopTenRequestHandler;
@ -99,6 +99,9 @@ public class Level extends Addon implements Listener {
@EventHandler
public void onBentoBoxReady(BentoBoxReadyEvent e) {
// Perform upgrade check
manager.migrate();
// Load TopTens
manager.loadTopTens();
/*
* DEBUG code to generate fake islands and then try to level them all.
@ -119,8 +122,8 @@ public class Level extends Addon implements Listener {
getIslands().getIslands().stream().filter(Island::isOwned).forEach(is -> {
this.getManager().calculateLevel(is.getOwner(), is).thenAccept(r ->
log("Result for island calc " + r.getLevel() + " at " + is.getCenter()));
this.getManager().calculateLevel(is.getOwner(), is).thenAccept(r ->
log("Result for island calc " + r.getLevel() + " at " + is.getCenter()));
});
}, 60L);*/
@ -187,6 +190,7 @@ public class Level extends Addon implements Listener {
new AdminLevelCommand(this, adminCommand);
new AdminTopCommand(this, adminCommand);
new AdminLevelStatusCommand(this, adminCommand);
new AdminSetInitialLevelCommand(this, adminCommand);
});
gm.getPlayerCommand().ifPresent(playerCmd -> {
new IslandLevelCommand(this, playerCmd);
@ -319,12 +323,4 @@ public class Level extends Addon implements Listener {
if (island != null) getManager().calculateLevel(playerUUID, island);
}
/**
* Load a player from the cache or database
* @param targetPlayer - UUID of target player
* @return LevelsData object or null if not found
*/
public LevelsData getLevelsData(UUID targetPlayer) {
return getManager().getLevelsData(targetPlayer);
}
}

View File

@ -9,6 +9,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.TreeMap;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
@ -21,6 +22,8 @@ import org.bukkit.World;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import com.google.common.collect.Maps;
import world.bentobox.bentobox.api.events.addon.AddonBaseEvent;
import world.bentobox.bentobox.api.events.addon.AddonEvent;
import world.bentobox.bentobox.api.panels.PanelItem;
@ -33,6 +36,7 @@ import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.level.calculators.Results;
import world.bentobox.level.events.IslandLevelCalculatedEvent;
import world.bentobox.level.events.IslandPreLevelEvent;
import world.bentobox.level.objects.IslandLevels;
import world.bentobox.level.objects.LevelsData;
import world.bentobox.level.objects.TopTenData;
import world.bentobox.level.panels.DetailsGUITab;
@ -55,9 +59,9 @@ public class LevelsManager {
// Database handler for level data
private final Database<LevelsData> handler;
private final Database<IslandLevels> handler;
// A cache of island levels.
private final Map<UUID, LevelsData> levelsCache;
private final Map<String, IslandLevels> levelsCache;
private final Database<TopTenData> topTenHandler;
// Top ten lists
@ -72,7 +76,7 @@ public class LevelsManager {
// Get the BentoBox database
// Set up the database handler to store and retrieve data
// Note that these are saved by the BentoBox database
handler = new Database<>(addon, LevelsData.class);
handler = new Database<>(addon, IslandLevels.class);
// Top Ten handler
topTenHandler = new Database<>(addon, TopTenData.class);
// Initialize the cache
@ -83,6 +87,39 @@ public class LevelsManager {
background = new PanelItemBuilder().icon(Material.BLACK_STAINED_GLASS_PANE).name(" ").build();
}
public void migrate() {
Database<LevelsData> oldDb = new Database<>(addon, LevelsData.class);
oldDb.loadObjects().forEach(ld -> {
try {
UUID owner = UUID.fromString(ld.getUniqueId());
// Step through each world
ld.getLevels().keySet().stream()
// World
.map(Bukkit::getWorld).filter(Objects::nonNull)
// Island
.map(w -> addon.getIslands().getIsland(w, owner)).filter(Objects::nonNull)
.forEach(i -> {
// Make new database entry
World w = i.getWorld();
IslandLevels il = new IslandLevels(i.getUniqueId());
il.setInitialLevel(ld.getInitialLevel(w));
il.setLevel(ld.getLevel(w));
il.setMdCount(ld.getMdCount(w));
il.setPointsToNextLevel(ld.getPointsToNextLevel(w));
il.setUwCount(ld.getUwCount(w));
// Save it
handler.saveObjectAsync(il);
});
// Now delete the old database entry
oldDb.deleteID(ld.getUniqueId());
} catch (Exception e) {
addon.logError("Could not migrate level data database! " + e.getMessage());
e.printStackTrace();
return;
}
});
}
/**
* Add a score to the top players list
* @param world - world
@ -286,9 +323,7 @@ public class LevelsManager {
* @return initial level of island
*/
public long getInitialLevel(Island island) {
@Nullable
LevelsData ld = getLevelsData(island.getOwner());
return ld == null ? 0 : ld.getInitialLevel(island.getWorld());
return getLevelsData(island).getInitialLevel();
}
/**
@ -299,11 +334,9 @@ public class LevelsManager {
*/
public long getIslandLevel(@NonNull World world, @Nullable UUID targetPlayer) {
if (targetPlayer == null) return 0L;
// Get the island owner
UUID owner = addon.getIslands().getOwner(world, targetPlayer);
if (owner == null) return 0L;
LevelsData ld = getLevelsData(owner);
return ld == null ? 0L : ld.getLevel(world);
// Get the island
Island island = addon.getIslands().getIsland(world, targetPlayer);
return island == null ? 0L : getLevelsData(island).getLevel();
}
/**
@ -317,23 +350,30 @@ public class LevelsManager {
}
/**
* Load a level data for the island owner from the cache or database. Only island owners are stored.
* @param islandOwner - UUID of island owner
* @return LevelsData object or null if not found
* Load a level data for the island from the cache or database.
* @param island - UUID of island
* @return IslandLevels object
*/
@Nullable
public LevelsData getLevelsData(@NonNull UUID islandOwner) {
// Get from database if not in cache
if (!levelsCache.containsKey(islandOwner) && handler.objectExists(islandOwner.toString())) {
LevelsData ld = handler.loadObject(islandOwner.toString());
if (ld != null) {
levelsCache.put(islandOwner, ld);
} else {
handler.deleteID(islandOwner.toString());
}
@NonNull
public IslandLevels getLevelsData(@NonNull Island island) {
String id = island.getUniqueId();
if (levelsCache.containsKey(id)) {
return levelsCache.get(id);
}
// Return cached value or null
return levelsCache.get(islandOwner);
// Get from database if not in cache
if (handler.objectExists(id)) {
IslandLevels ld = handler.loadObject(id);
if (ld != null) {
levelsCache.put(id, ld);
} else {
handler.deleteID(id);
levelsCache.put(id, new IslandLevels(id));
}
} else {
levelsCache.put(id, new IslandLevels(id));
}
// Return cached value
return levelsCache.get(id);
}
/**
@ -344,10 +384,8 @@ public class LevelsManager {
*/
public String getPointsToNextString(@NonNull World world, @Nullable UUID targetPlayer) {
if (targetPlayer == null) return "";
UUID owner = addon.getIslands().getOwner(world, targetPlayer);
if (owner == null) return "";
LevelsData ld = getLevelsData(owner);
return ld == null ? "" : String.valueOf(ld.getPointsToNextLevel(world));
Island island = addon.getIslands().getIsland(world, targetPlayer);
return island == null ? "" : String.valueOf(getLevelsData(island).getPointsToNextLevel());
}
/**
@ -394,9 +432,6 @@ public class LevelsManager {
// Update based on user data
// Remove any non island owners
tt.getTopTen().keySet().removeIf(u -> !addon.getIslands().isOwner(world, u));
for (UUID uuid : tt.getTopTen().keySet()) {
tt.getTopTen().compute(uuid, (k,v) -> v = updateLevel(k, world));
}
} else {
addon.logError("TopTen world '" + tt.getUniqueId() + "' is not known on server. You might want to delete this table. Skipping...");
}
@ -409,14 +444,6 @@ public class LevelsManager {
* @param uuid - the player's uuid
*/
public void removeEntry(World world, UUID uuid) {
// Load the user if they haven't yet done anything to put them in the cache
this.getLevelsData(uuid);
// Remove them
if (levelsCache.containsKey(uuid)) {
levelsCache.get(uuid).remove(world);
// Save
handler.saveObjectAsync(levelsCache.get(uuid));
}
if (topTenLists.containsKey(world)) {
topTenLists.get(world).getTopTen().remove(uuid);
topTenHandler.saveObjectAsync(topTenLists.get(world));
@ -441,14 +468,14 @@ public class LevelsManager {
}
/**
* Set an initial island level for player
* @param island - the island to set. Must have a non-null world and owner
* Set an initial island level
* @param island - the island to set. Must have a non-null world
* @param lv - initial island level
*/
public void setInitialIslandLevel(@NonNull Island island, long lv) {
if (island.getOwner() == null || island.getWorld() == null) return;
levelsCache.computeIfAbsent(island.getOwner(), LevelsData::new).setInitialLevel(island.getWorld(), lv);
handler.saveObjectAsync(levelsCache.get(island.getOwner()));
if (island.getWorld() == null) return;
levelsCache.computeIfAbsent(island.getUniqueId(), IslandLevels::new).setInitialLevel(lv);
handler.saveObjectAsync(levelsCache.get(island.getUniqueId()));
}
/**
@ -458,10 +485,18 @@ public class LevelsManager {
* @param lv - level
*/
public void setIslandLevel(@NonNull World world, @NonNull UUID targetPlayer, long lv) {
levelsCache.computeIfAbsent(targetPlayer, LevelsData::new).setLevel(world, lv);
handler.saveObjectAsync(levelsCache.get(targetPlayer));
// Update TopTen
addToTopTen(world, targetPlayer, levelsCache.get(targetPlayer).getLevel(world));
// Get the island
Island island = addon.getIslands().getIsland(world, targetPlayer);
if (island != null) {
String id = island.getUniqueId();
IslandLevels il = levelsCache.computeIfAbsent(id, IslandLevels::new);
// Remove the initial level
il.setLevel(lv - il.getInitialLevel());
handler.saveObjectAsync(levelsCache.get(id));
// Update TopTen
addToTopTen(world, targetPlayer, levelsCache.get(id).getLevel());
}
}
/**
@ -471,26 +506,27 @@ public class LevelsManager {
* @param r - results of the calculation
*/
private void setIslandResults(World world, @NonNull UUID owner, Results r) {
LevelsData ld = levelsCache.computeIfAbsent(owner, LevelsData::new);
ld.setLevel(world, r.getLevel());
ld.setUwCount(world, r.getUwCount());
ld.setMdCount(world, r.getMdCount());
ld.setPointsToNextLevel(world, r.getPointsToNextLevel());
levelsCache.put(owner, ld);
// Get the island
Island island = addon.getIslands().getIsland(world, owner);
if (island == null) return;
IslandLevels ld = levelsCache.computeIfAbsent(island.getUniqueId(), IslandLevels::new);
ld.setLevel(r.getLevel() - ld.getInitialLevel());
ld.setUwCount(Maps.asMap(r.getUwCount().elementSet(), elem -> r.getUwCount().count(elem)));
ld.setMdCount(Maps.asMap(r.getMdCount().elementSet(), elem -> r.getMdCount().count(elem)));
ld.setPointsToNextLevel(r.getPointsToNextLevel());
levelsCache.put(island.getUniqueId(), ld);
handler.saveObjectAsync(ld);
// Update TopTen
addToTopTen(world, owner, ld.getLevel(world));
addToTopTen(world, owner, ld.getLevel());
}
private Long updateLevel(UUID uuid, World world) {
if (handler.objectExists(uuid.toString())) {
@Nullable
LevelsData ld = handler.loadObject(uuid.toString());
if (ld != null) {
return ld.getLevel(world);
}
}
return 0L;
/**
* Removes island from cache when it is deleted
* @param uniqueId - id of island
*/
public void deleteIsland(String uniqueId) {
levelsCache.remove(uniqueId);
handler.deleteID(uniqueId);
}
}

View File

@ -0,0 +1,80 @@
package world.bentobox.level.commands;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import org.eclipse.jdt.annotation.Nullable;
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.util.Util;
import world.bentobox.level.Level;
public class AdminSetInitialLevelCommand extends CompositeCommand {
private @Nullable UUID targetUUID;
private @Nullable Island island;
private Level addon;
public AdminSetInitialLevelCommand(Level addon, CompositeCommand parent) {
super(parent, "sethandicap");
this.addon = addon;
}
@Override
public void setup() {
this.setPermission("admin.level.sethandicap");
this.setOnlyPlayer(false);
this.setParametersHelp("admin.level.sethandicap.parameters");
this.setDescription("admin.level.sethandicap.description");
}
@Override
public Optional<List<String>> tabComplete(User user, String alias, List<String> args) {
String lastArg = !args.isEmpty() ? args.get(args.size()-1) : "";
if (args.isEmpty()) {
// Don't show every player on the server. Require at least the first letter
return Optional.empty();
}
List<String> options = new ArrayList<>(Util.getOnlinePlayerList(user));
return Optional.of(Util.tabLimit(options, lastArg));
}
@Override
public boolean execute(User user, String label, List<String> args) {
String initialLevel = String.valueOf(addon.getManager().getInitialLevel(island));
long lv = Long.parseLong(args.get(1));
addon.getManager().setInitialIslandLevel(island, lv);
user.sendMessage("admin.level.sethandicap.changed", TextVariables.NUMBER, initialLevel, "[new_number]", String.valueOf(lv));
return true;
}
@Override
public boolean canExecute(User user, String label, List<String> args) {
if (args.size() != 2) {
showHelp(this, user);
return false;
}
targetUUID = getAddon().getPlayers().getUUID(args.get(0));
if (targetUUID == null) {
user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0));
return false;
}
// Check value
if (!Util.isInteger(args.get(1), true)) {
user.sendMessage("admin.level.sethandicap.invalid-level");
return false;
}
// Check island
island = getAddon().getIslands().getIsland(getWorld(), targetUUID);
if (island == null) {
user.sendMessage("general.errors.player-has-no-island");
return false;
}
return true;
}
}

View File

@ -38,7 +38,7 @@ public class IslandLevelCommand extends CompositeCommand {
final UUID playerUUID = getPlugin().getPlayers().getUUID(args.get(0));
if (playerUUID == null) {
user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0));
return true;
return false;
}
// Ops, console and admin perms can request and calculate other player levels
if (!user.isPlayer() || user.isOp() || user.hasPermission(this.getPermissionPrefix() + "admin.level")) {

View File

@ -8,6 +8,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import world.bentobox.bentobox.api.events.island.IslandEvent.IslandCreatedEvent;
import world.bentobox.bentobox.api.events.island.IslandEvent.IslandDeleteEvent;
import world.bentobox.bentobox.api.events.island.IslandEvent.IslandPreclearEvent;
import world.bentobox.bentobox.api.events.island.IslandEvent.IslandRegisteredEvent;
import world.bentobox.bentobox.api.events.island.IslandEvent.IslandResettedEvent;
@ -65,6 +66,12 @@ public class IslandActivitiesListeners implements Listener {
remove(world, uuid);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onIslandDeleted(IslandDeleteEvent e) {
// Remove island
addon.getManager().deleteIsland(e.getIsland().getUniqueId());
}
private void remove(World world, UUID uuid) {
if (uuid != null && world != null) {
addon.getManager().removeEntry(world, uuid);
@ -88,14 +95,14 @@ public class IslandActivitiesListeners implements Listener {
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onIsland(IslandUnregisteredEvent e) {
// Remove player from the top ten and level
// Remove player from the top ten
remove(e.getIsland().getWorld(), e.getPlayerUUID());
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onIsland(IslandRegisteredEvent e) {
// Remove player from the top ten and level
// Remove player from the top ten
remove(e.getIsland().getWorld(), e.getPlayerUUID());
}

View File

@ -27,8 +27,6 @@ public class JoinLeaveListener implements Listener {
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onPlayerJoin(PlayerJoinEvent e) {
// Load player into cache
addon.getManager().getLevelsData(e.getPlayer().getUniqueId());
// If level calc on login is enabled, run through all the worlds and calculate the level
if (addon.getSettings().isCalcOnLogin()) {
addon.getPlugin().getAddonsManager().getGameModeAddons().stream()

View File

@ -0,0 +1,154 @@
package world.bentobox.level.objects;
import java.util.EnumMap;
import java.util.Map;
import org.bukkit.Material;
import com.google.gson.annotations.Expose;
import world.bentobox.bentobox.database.objects.DataObject;
import world.bentobox.bentobox.database.objects.Table;
/**
* Stores the levels data of the island.
* A note - if this class is extended to support new exposed fields and legacy data doesn't include those fields
* they will be set to null by GSON. They will not be initialized and if any attempt is made to use them, then
* the JVM will give up WITHOUT AN ERROR!!! That is why there are null checks throughout this class.
*
* @author tastybento
*
*/
@Table(name = "IslandLevels")
public class IslandLevels implements DataObject {
// uniqueId is the island's UUID
@Expose
private String uniqueId = "";
/**
* Island level
*/
@Expose
private long level;
/**
* Initial level
*/
@Expose
private long initialLevel;
/**
* Points to next level
*/
@Expose
private long pointsToNextLevel;
/**
* Underwater count
*/
@Expose
private Map<Material, Integer> uwCount;
/**
* MaterialData count - count of all blocks
*/
@Expose
private Map<Material, Integer> mdCount;
/**
* Constructor for new island
* @param islandUUID - island UUID
*/
public IslandLevels(String islandUUID) {
uniqueId = islandUUID;
uwCount = new EnumMap<>(Material.class);
mdCount = new EnumMap<>(Material.class);
}
/**
* @return the uniqueId
*/
@Override
public String getUniqueId() {
return uniqueId;
}
/**
* @param uniqueId the uniqueId to set
*/
@Override
public void setUniqueId(String uniqueId) {
this.uniqueId = uniqueId;
}
/**
* @return the level
*/
public long getLevel() {
return level;
}
/**
* @param level the level to set
*/
public void setLevel(long level) {
this.level = level;
}
/**
* @return the initialLevel
*/
public long getInitialLevel() {
return initialLevel;
}
/**
* @param initialLevel the initialLevel to set
*/
public void setInitialLevel(long initialLevel) {
this.initialLevel = initialLevel;
}
/**
* @return the pointsToNextLevel
*/
public long getPointsToNextLevel() {
return pointsToNextLevel;
}
/**
* @param pointsToNextLevel the pointsToNextLevel to set
*/
public void setPointsToNextLevel(long pointsToNextLevel) {
this.pointsToNextLevel = pointsToNextLevel;
}
/**
* @return the uwCount
*/
public Map<Material, Integer> getUwCount() {
return uwCount;
}
/**
* @param uwCount the uwCount to set
*/
public void setUwCount(Map<Material, Integer> uwCount) {
this.uwCount = uwCount;
}
/**
* @return the mdCount
*/
public Map<Material, Integer> getMdCount() {
return mdCount;
}
/**
* @param mdCount the mdCount to set
*/
public void setMdCount(Map<Material, Integer> mdCount) {
this.mdCount = mdCount;
}
}

View File

@ -27,7 +27,7 @@ import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.util.Util;
import world.bentobox.level.Level;
import world.bentobox.level.objects.LevelsData;
import world.bentobox.level.objects.IslandLevels;
/**
* @author tastybento
@ -131,20 +131,20 @@ public class DetailsGUITab implements Tab, ClickHandler {
private void generateReport(DetailsType type) {
items = new ArrayList<>();
LevelsData ld = addon.getManager().getLevelsData(island.getOwner());
IslandLevels ld = addon.getManager().getLevelsData(island);
// Get the items from the report
Map<Material, Integer> sumTotal = new EnumMap<>(Material.class);
sumTotal.putAll(ld.getMdCount(world));
sumTotal.putAll(ld.getUwCount(world));
sumTotal.putAll(ld.getMdCount());
sumTotal.putAll(ld.getUwCount());
switch(type) {
case ABOVE_SEA_LEVEL_BLOCKS:
ld.getMdCount(world).forEach(this::createItem);
ld.getMdCount().forEach(this::createItem);
break;
case SPAWNERS:
sumTotal.entrySet().stream().filter(m -> m.getKey().equals(Material.SPAWNER)).forEach(e -> createItem(e.getKey(), e.getValue()));
break;
case UNDERWATER_BLOCKS:
ld.getUwCount(world).forEach(this::createItem);
ld.getUwCount().forEach(this::createItem);
break;
default:
sumTotal.forEach(this::createItem);

View File

@ -7,6 +7,11 @@ admin:
level:
parameters: "<player>"
description: "calculate the island level for player"
sethandicap:
parameters: <player> <handicap>
description: "set the island handicap, usually the level of the starter island"
changed: "&a Initial island handicap changed from [number] to [new_number]."
invalid-level: "&c Invalid handicap. Use an integer."
levelstatus:
description: "show how many islands are in the queue for scanning"
islands-in-queue: "&a Islands in queue: [number]"
@ -18,6 +23,7 @@ admin:
description: "remove player from Top Ten"
parameters: "<player>"
island:
level:
parameters: "[player]"

View File

@ -275,8 +275,8 @@ public class LevelTest {
addon.onEnable();
verify(plugin).logWarning("[Level] Level Addon: No such world in blockconfig.yml : acidisland_world");
verify(plugin).log("[Level] Level hooking into BSkyBlock");
verify(cmd, times(3)).getAddon(); // Three commands
verify(adminCmd, times(3)).getAddon(); // Three commands
verify(cmd, times(3)).getAddon(); // 3 commands
verify(adminCmd, times(4)).getAddon(); // Four commands
// Placeholders
verify(phm).registerPlaceholder(eq(addon), eq("bskyblock_island_level"), any());
verify(phm).registerPlaceholder(eq(addon), eq("bskyblock_visited_island_level"), any());

View File

@ -16,6 +16,7 @@ import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
@ -58,7 +59,7 @@ import world.bentobox.bentobox.managers.PlayersManager;
import world.bentobox.level.calculators.Pipeliner;
import world.bentobox.level.calculators.Results;
import world.bentobox.level.config.ConfigSettings;
import world.bentobox.level.objects.LevelsData;
import world.bentobox.level.objects.IslandLevels;
import world.bentobox.level.objects.TopTenData;
/**
@ -104,7 +105,7 @@ public class LevelsManagerTest {
@Mock
private PluginManager pim;
@Mock
private LevelsData levelsData;
private IslandLevels levelsData;
@Mock
private IslandsManager im;
@ -125,6 +126,7 @@ public class LevelsManagerTest {
/**
* @throws java.lang.Exception
*/
@SuppressWarnings("unchecked")
@Before
public void setUp() throws Exception {
when(addon.getPlugin()).thenReturn(plugin);
@ -154,9 +156,11 @@ public class LevelsManagerTest {
when(island.getMemberSet()).thenReturn(iset);
when(island.getOwner()).thenReturn(uuid);
when(island.getWorld()).thenReturn(world);
when(island.getUniqueId()).thenReturn(UUID.randomUUID().toString());
// Default to uuid's being island owners
when(im.isOwner(eq(world), any())).thenReturn(true);
when(im.getOwner(any(), any(UUID.class))).thenAnswer(in -> in.getArgument(1, UUID.class));
when(im.getIsland(eq(world), eq(uuid))).thenReturn(island);
// Player
when(player.getUniqueId()).thenReturn(uuid);
@ -205,9 +209,10 @@ public class LevelsManagerTest {
// Include a known UUID
ttd.getTopTen().put(uuid, 456789L);
topTen.add(ttd);
when(handler.loadObjects()).thenReturn(topTen);
// Supply no island levels first, then topTen
when(handler.loadObjects()).thenReturn(Collections.emptyList(), topTen);
when(handler.objectExists(anyString())).thenReturn(true);
when(levelsData.getLevel(any())).thenReturn(-5L, -4L, -3L, -2L, -1L, 0L, 1L, 2L, 3L, 4L, 5L, 45678L);
when(levelsData.getLevel()).thenReturn(-5L, -4L, -3L, -2L, -1L, 0L, 1L, 2L, 3L, 4L, 5L, 45678L);
when(levelsData.getUniqueId()).thenReturn(uuid.toString());
when(handler.loadObject(anyString())).thenReturn(levelsData );
@ -220,6 +225,7 @@ public class LevelsManagerTest {
when(iwm.getPermissionPrefix(any())).thenReturn("bskyblock.");
lm = new LevelsManager(addon);
lm.migrate();
}
/**
@ -252,7 +258,7 @@ public class LevelsManagerTest {
lm.calculateLevel(uuid, island);
cf.complete(results);
assertEquals(Long.valueOf(10000), lm.getLevelsData(uuid).getLevel(world));
assertEquals(10000L, lm.getLevelsData(island).getLevel());
//Map<UUID, Long> tt = lm.getTopTen(world, 10);
//assertEquals(1, tt.size());
//assertTrue(tt.get(uuid) == 10000);
@ -280,7 +286,9 @@ public class LevelsManagerTest {
*/
@Test
public void testGetPointsToNextString() {
assertEquals("0", lm.getPointsToNextString(world, UUID.randomUUID()));
// No island player
assertEquals("", lm.getPointsToNextString(world, UUID.randomUUID()));
// Player has island
assertEquals("0", lm.getPointsToNextString(world, uuid));
}
@ -297,7 +305,7 @@ public class LevelsManagerTest {
*/
@Test
public void testGetLevelsData() {
assertEquals(levelsData, lm.getLevelsData(uuid));
assertEquals(levelsData, lm.getLevelsData(island));
}