Added timings, fixed bugs.

This commit is contained in:
tastybento 2020-07-04 18:13:02 -07:00
parent 7f75caab36
commit 85cd89bdf7
9 changed files with 132 additions and 43 deletions

View File

@ -21,8 +21,7 @@ import org.bukkit.World;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import com.google.common.collect.Multiset;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.events.addon.AddonBaseEvent;
import world.bentobox.bentobox.api.events.addon.AddonEvent;
import world.bentobox.bentobox.api.panels.PanelItem;
@ -128,7 +127,7 @@ public class LevelsManager {
}
// Save result
addon.logWarning("Saving results");
setIslandResults(island.getWorld(), island.getOwner(), r.getLevel(), r.getUwCount(), r.getMdCount());
setIslandResults(island.getWorld(), island.getOwner(), r);
// Save top ten
addon.logWarning("Saving top ten");
addon.getManager().saveTopTen(island.getWorld());
@ -307,7 +306,7 @@ public class LevelsManager {
}
/**
* Load a level data for the island owner from the cache or database. Only island onwers are stored.
* 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
*/
@ -399,6 +398,9 @@ 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
@ -433,7 +435,9 @@ public class LevelsManager {
* @param lv - initial island level
*/
public void setInitialIslandLevel(@NonNull Island island, long lv) {
BentoBox.getInstance().logDebug("Setting initial island level " + island +" " + lv);
if (island.getOwner() == null || island.getWorld() == null) return;
BentoBox.getInstance().logDebug("saving");
levelsCache.computeIfAbsent(island.getOwner(), LevelsData::new).setInitialLevel(island.getWorld(), lv);
handler.saveObjectAsync(levelsCache.get(island.getOwner()));
}
@ -454,17 +458,15 @@ public class LevelsManager {
/**
* Set the island level for the owner of the island that targetPlayer is a member
* @param world - world
* @param owner
* @param level
* @param uwCount
* @param mdCount
* @param owner - owner of the island
* @param r - results of the calculation
*/
private void setIslandResults(World world, @Nullable UUID owner, long level, Multiset<Material> uwCount,
Multiset<Material> mdCount) {
private void setIslandResults(World world, @Nullable UUID owner, Results r) {
LevelsData ld = levelsCache.computeIfAbsent(owner, LevelsData::new);
ld.setLevel(world, level);
ld.setUwCount(world, uwCount);
ld.setMdCount(world, mdCount);
ld.setLevel(world, r.getLevel());
ld.setUwCount(world, r.getUwCount());
ld.setMdCount(world, r.getMdCount());
ld.setPointsToNextLevel(world, r.getPointsToNextLevel());
levelsCache.put(owner, ld);
handler.saveObjectAsync(ld);
// Update TopTen

View File

@ -146,18 +146,20 @@ public class IslandLevelCalculator {
private final Results results;
private long duration;
/**
* Constructor to get the level for an island
* @param addon - Level addon
* @param island - the island to scan
* @param r - completeable result that will be completed when the calculation is complete
* @param r - completable result that will be completed when the calculation is complete
*/
public IslandLevelCalculator(Level addon, Island island, CompletableFuture<Results> r) {
this.addon = addon;
this.island = island;
this.r = r;
results = new Results();
duration = System.currentTimeMillis();
chunksToCheck = getChunksToScan(island);
this.limitCount = new HashMap<>(addon.getBlockConfig().getBlockLimits());
}
@ -310,7 +312,7 @@ public class IslandLevelCalculator {
if (addon.getSettings().isNether()) {
World nether = addon.getPlugin().getIWM().getNetherWorld(island.getWorld());
if (nether != null) {
return Util.getChunkAtAsync(nether, x, z, false);
return Util.getChunkAtAsync(nether, x, z, true);
}
}
// There is no chunk to scan, so return a null chunk
@ -319,13 +321,13 @@ public class IslandLevelCalculator {
if (addon.getSettings().isEnd()) {
World end = addon.getPlugin().getIWM().getEndWorld(island.getWorld());
if (end != null) {
return Util.getChunkAtAsync(end, x, z, false);
return Util.getChunkAtAsync(end, x, z, true);
}
}
// There is no chunk to scan, so return a null chunk
return CompletableFuture.completedFuture(null);
default:
return Util.getChunkAtAsync(world, x, z, false);
return Util.getChunkAtAsync(world, x, z, true);
}
}
@ -530,6 +532,8 @@ public class IslandLevelCalculator {
// Report
results.report = getReport();
// Set the duration
addon.getPipeliner().setTime(System.currentTimeMillis() - duration);
// All done.
}
}

View File

@ -18,10 +18,13 @@ import world.bentobox.level.Level;
*/
public class Pipeliner {
private static final int START_DURATION = 10; // 10 seconds
private final Queue<IslandLevelCalculator> processQueue;
private final BukkitTask task;
private boolean inProcess;
private final Level addon;
private long time;
private long count;
/**
* Construct the pipeliner
@ -53,8 +56,11 @@ public class Pipeliner {
task.cancel();
}
/**
* @return number of islands currently in the queue or in process
*/
public int getIslandsInQueue() {
return processQueue.size();
return inProcess ? processQueue.size() + 1 : processQueue.size();
}
/**
@ -95,8 +101,26 @@ public class Pipeliner {
public CompletableFuture<Results> addIsland(Island island) {
CompletableFuture<Results> r = new CompletableFuture<>();
processQueue.add(new IslandLevelCalculator(addon, island, r));
count++;
return r;
}
/**
* Get the average time it takes to run a level check
* @return the average time in seconds
*/
public int getTime() {
return time == 0 || count == 0 ? START_DURATION : (int)((double)time/count/1000);
}
/**
* Submit how long a level check took
* @param time the time to set
*/
public void setTime(long time) {
// Running average
this.time += time;
}
}

View File

@ -78,8 +78,9 @@ public class IslandLevelCommand extends CompositeCommand {
return false;
}
user.sendMessage("island.level.calculating");
int inQueue = addon.getPipeliner().getIslandsInQueue();
user.sendMessage("island.level.calculating");
user.sendMessage("island.level.estimated-wait", TextVariables.NUMBER, String.valueOf(addon.getPipeliner().getTime() * (inQueue + 1)));
if (inQueue > 1) {
user.sendMessage("island.level.in-queue", TextVariables.NUMBER, String.valueOf(inQueue + 1));
}

View File

@ -7,6 +7,7 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.events.island.IslandEvent.IslandCreatedEvent;
import world.bentobox.bentobox.api.events.island.IslandEvent.IslandPreclearEvent;
import world.bentobox.bentobox.api.events.island.IslandEvent.IslandRegisteredEvent;
@ -38,17 +39,20 @@ public class IslandActivitiesListeners implements Listener {
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onNewIsland(IslandCreatedEvent e) {
BentoBox.getInstance().logDebug(e.getEventName());
zeroIsland(e.getIsland());
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onNewIsland(IslandResettedEvent e) {
BentoBox.getInstance().logDebug(e.getEventName());
zeroIsland(e.getIsland());
}
private void zeroIsland(final Island island) {
// Clear the island setting
if (island.getOwner() != null && island.getWorld() != null) {
BentoBox.getInstance().logDebug("Zeroing island");
addon.getPipeliner().addIsland(island).thenAccept(results ->
addon.getManager().setInitialIslandLevel(island, results.getLevel()));
}
@ -56,9 +60,11 @@ public class IslandActivitiesListeners implements Listener {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onIslandDelete(IslandPreclearEvent e) {
BentoBox.getInstance().logDebug(e.getEventName());
// Remove player from the top ten and level
UUID uuid = e.getIsland().getOwner();
World world = e.getIsland().getWorld();
BentoBox.getInstance().logDebug(uuid + " " + world);
remove(world, uuid);
}
@ -70,36 +76,42 @@ public class IslandActivitiesListeners implements Listener {
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onNewIslandOwner(TeamSetownerEvent e) {
BentoBox.getInstance().logDebug(e.getEventName());
// Remove player from the top ten and level
remove(e.getIsland().getWorld(), e.getIsland().getOwner());
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onIsland(TeamJoinedEvent e) {
BentoBox.getInstance().logDebug(e.getEventName());
// Remove player from the top ten and level
remove(e.getIsland().getWorld(), e.getPlayerUUID());
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onIsland(IslandUnregisteredEvent e) {
BentoBox.getInstance().logDebug(e.getEventName());
// Remove player from the top ten and level
remove(e.getIsland().getWorld(), e.getPlayerUUID());
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onIsland(IslandRegisteredEvent e) {
BentoBox.getInstance().logDebug(e.getEventName());
// Remove player from the top ten and level
remove(e.getIsland().getWorld(), e.getPlayerUUID());
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onIsland(TeamLeaveEvent e) {
BentoBox.getInstance().logDebug(e.getEventName());
// Remove player from the top ten and level
remove(e.getIsland().getWorld(), e.getPlayerUUID());
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onIsland(TeamKickEvent e) {
BentoBox.getInstance().logDebug(e.getEventName());
// Remove player from the top ten and level
remove(e.getIsland().getWorld(), e.getPlayerUUID());
}

View File

@ -13,6 +13,7 @@ import org.bukkit.World;
import com.google.common.collect.Multiset;
import com.google.gson.annotations.Expose;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.database.objects.DataObject;
import world.bentobox.bentobox.database.objects.Table;
@ -141,8 +142,12 @@ public class LevelsData implements DataObject {
* @param world - world to remove
*/
public void remove(World world) {
levels.remove(world.getName().toLowerCase(Locale.ENGLISH));
initialLevel.remove(world.getName().toLowerCase(Locale.ENGLISH));
BentoBox.getInstance().logDebug("Removing world");
this.levels.remove(world.getName().toLowerCase(Locale.ENGLISH));
this.initialLevel.remove(world.getName().toLowerCase(Locale.ENGLISH));
this.pointsToNextLevel.remove(world.getName().toLowerCase(Locale.ENGLISH));
this.mdCount.remove(world.getName().toLowerCase(Locale.ENGLISH));
this.uwCount.remove(world.getName().toLowerCase(Locale.ENGLISH));
}
/**
@ -211,6 +216,9 @@ public class LevelsData implements DataObject {
* @return the uwCount
*/
public Map<Material, Integer> getUwCount(World world) {
if (this.uwCount == null) {
this.uwCount = new HashMap<>();
}
return uwCount.getOrDefault(world.getName(), Collections.emptyMap());
}
@ -219,6 +227,9 @@ public class LevelsData implements DataObject {
* @return the mdCount
*/
public Map<Material, Integer> getMdCount(World world) {
if (this.mdCount == null) {
this.mdCount = new HashMap<>();
}
return mdCount.getOrDefault(world.getName(), Collections.emptyMap());
}

View File

@ -17,6 +17,7 @@ import org.eclipse.jdt.annotation.Nullable;
import com.google.common.base.Enums;
import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.panels.Panel;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.PanelItem.ClickHandler;
@ -41,6 +42,9 @@ public class DetailsGUITab implements Tab, ClickHandler {
UNDERWATER_BLOCKS
}
/**
* Converts block materials to item materials
*/
private static final Map<Material, Material> M2I;
static {
Map<Material, Material> m2i = new HashMap<>();
@ -72,6 +76,7 @@ public class DetailsGUITab implements Tab, ClickHandler {
m2i.put(Material.BUBBLE_COLUMN, Material.WATER_BUCKET);
m2i.put(Material.SWEET_BERRY_BUSH, Material.SWEET_BERRIES);
m2i.put(Material.BAMBOO_SAPLING, Material.BAMBOO);
m2i.put(Material.FIRE, Material.FLINT_AND_STEEL);
// 1.16.1
if (Enums.getIfPresent(Material.class, "WEEPING_VINES_PLANT").isPresent()) {
m2i.put(Material.WEEPING_VINES_PLANT, Material.WEEPING_VINES);
@ -104,19 +109,22 @@ public class DetailsGUITab implements Tab, ClickHandler {
// Convert walls
m = Enums.getIfPresent(Material.class, m.name().replace("WALL_", "")).or(m);
// Tags
if (Tag.FIRE.isTagged(m)) {
items.add(new PanelItemBuilder()
.icon(Material.CAMPFIRE)
.name(Util.prettifyText(m.name()) + " x " + count)
.build());
return;
if (Enums.getIfPresent(Material.class, "SOUL_CAMPFIRE").isPresent()) {
if (Tag.FIRE.isTagged(m)) {
items.add(new PanelItemBuilder()
.icon(Material.CAMPFIRE)
.name(Util.prettifyText(m.name()) + " x " + count)
.build());
return;
}
}
if (Tag.FLOWER_POTS.isTagged(m)) {
m = Enums.getIfPresent(Material.class, m.name().replace("POTTED_", "")).or(m);
}
items.add(new PanelItemBuilder()
.icon(M2I.getOrDefault(m, m))
.name(Util.prettifyText(m.name()) + " x " + count)
.name(user.getTranslation("island.level-details.syntax", TextVariables.NAME,
Util.prettifyText(m.name()), TextVariables.NUMBER, String.valueOf(count)))
.build());
}
@ -141,30 +149,35 @@ public class DetailsGUITab implements Tab, ClickHandler {
default:
sumTotal.forEach(this::createItem);
break;
}
if (type.equals(DetailsType.ALL_BLOCKS) && items.isEmpty()) {
// Nothing here - looks like they need to run level
items.add(new PanelItemBuilder()
.name(user.getTranslation("island.level-details.hint")).icon(Material.WRITTEN_BOOK)
.build());
}
}
@Override
public PanelItem getIcon() {
switch(type) {
case ABOVE_SEA_LEVEL_BLOCKS:
return new PanelItemBuilder().icon(Material.GRASS_BLOCK).name("Above Sea Level Blocks").build();
return new PanelItemBuilder().icon(Material.GRASS_BLOCK).name(user.getTranslation("island.level-details.above-sea-level-blocks")).build();
case SPAWNERS:
return new PanelItemBuilder().icon(Material.SPAWNER).name("Spawners").build();
return new PanelItemBuilder().icon(Material.SPAWNER).name(user.getTranslation("island.level-details.spawners")).build();
case UNDERWATER_BLOCKS:
return new PanelItemBuilder().icon(Material.WATER_BUCKET).name("Underwater Blocks").build();
return new PanelItemBuilder().icon(Material.WATER_BUCKET).name(user.getTranslation("island.level-details.underwater-blocks")).build();
default:
return new PanelItemBuilder().icon(Material.GRASS_BLOCK).name("All Blocks").build();
return new PanelItemBuilder().icon(Material.GRASS_BLOCK).name(user.getTranslation("island.level-details.all-blocks")).build();
}
}
@Override
public String getName() {
String name = "&c No island!";
String name = user.getTranslation("island.level-details.no-island");
if (island.getOwner() != null) {
name = island.getName() != null ? island.getName() : addon.getPlayers().getName(island.getOwner()) + "'s island";
name = island.getName() != null ? island.getName() :
user.getTranslation("island.level-details.names-island", TextVariables.NAME, addon.getPlayers().getName(island.getOwner()));
}
return name;
}
@ -176,17 +189,16 @@ public class DetailsGUITab implements Tab, ClickHandler {
@Override
public String getPermission() {
String permPrefix = addon.getPlugin().getIWM().getPermissionPrefix(world);
switch(type) {
case ABOVE_SEA_LEVEL_BLOCKS:
return "";
case ALL_BLOCKS:
return "";
return permPrefix + "island.level.details.above-sea-level";
case SPAWNERS:
return "";
return permPrefix + "island.level.details.spawners";
case UNDERWATER_BLOCKS:
return "";
return permPrefix + "island.level.details.underwater";
default:
return "";
return permPrefix + "island.level.details.blocks";
}
}

View File

@ -19,6 +19,18 @@ permissions:
'[gamemode].island.value':
description: Player can use value command
default: true
'[gamemode].island.level.details.blocks':
description: Player see the level details
default: true
'[gamemode].island.level.details.spawners':
description: Player can see the spawners tab in the level details
default: false
'[gamemode].island.level.details.underwater':
description: Player can see the underwater tab in the level details
default: false
'[gamemode].island.level.details.above-sea-level':
description: Player can see the above sea level tab in the level details
default: false
'[gamemode].admin.level':
description: Player can use admin level command
default: op

View File

@ -22,7 +22,8 @@ island:
level:
parameters: "[player]"
description: "calculate your island level or show the level of [player]"
calculating: "&a Calculating level..."
calculating: "&a Calculating level..."
estimated-wait: "&a Estimated wait: [number] seconds"
in-queue: "&a You are number [number] in the queue"
island-level-is: "&a Island level is &b[level]"
required-points-to-next-level: "&a [points] points required until the next level"
@ -35,6 +36,16 @@ island:
gui-heading: "&6[name]: &B[rank]"
island-level: "&b Level [level]"
warp-to: "&A Warping to [name]'s island"
level-details:
above-sea-level-blocks: "Above Sea Level Blocks"
spawners: "Spawners"
underwater-blocks: "Underwater Blocks"
all-blocks: "All Blocks"
no-island: "&c No island!"
names-island: "[name]'s island"
syntax: "[name] x [number]"
hint: "&c Run level to see the block report"
value:
description: "shows the value of any block"