mirror of
https://github.com/BentoBoxWorld/Level.git
synced 2024-12-26 11:08:15 +01:00
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:
parent
507cefd128
commit
dab0e84bc0
2
pom.xml
2
pom.xml
@ -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. -->
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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")) {
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
|
154
src/main/java/world/bentobox/level/objects/IslandLevels.java
Normal file
154
src/main/java/world/bentobox/level/objects/IslandLevels.java
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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);
|
||||
|
@ -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]"
|
||||
|
@ -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());
|
||||
|
@ -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));
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user