Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,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.19.3</build.version>
<build.version>2.20.0</build.version>
<sonar.projectKey>BentoBoxWorld_Level</sonar.projectKey>
<sonar.organization>bentobox-world</sonar.organization>
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
Expand Down
80 changes: 47 additions & 33 deletions src/main/java/world/bentobox/level/Level.java
Original file line number Diff line number Diff line change
Expand Up @@ -339,12 +339,13 @@ public long getIslandLevel(World world, @Nullable UUID targetPlayer) {
}

/**
* Sets the player's level to a value
*
* @param world - world
* @param targetPlayer - target player
* @param level - level
*/
* Sets the player's level to a value. This will only last until the player reruns the level command
*
* @param world - world
* @param targetPlayer - target player
* @param level - level
* @deprecated This is a useless method.
*/
public void setIslandLevel(World world, UUID targetPlayer, long level) {
getManager().setIslandLevel(world, targetPlayer, level);
}
Expand All @@ -355,19 +356,31 @@ public void setIslandLevel(World world, UUID targetPlayer, long level) {
* @param island - island
* @param level - initial calculated island level
*/
public void setInitialIslandLevel(@NonNull Island island, long level) {
getManager().setInitialIslandLevel(island, level);
}
/* TODO
public void setInitialIslandLevel(@NonNull Island island, long level) {
getManager().setInitialIslandLevel(island, level);
}

/**
* Get the initial island level
*
* @param island - island
* @return level or 0 by default
*/
/* TODO
public long getInitialIslandLevel(@NonNull Island island) {
return getManager().getInitialLevel(island);
}*/

/**
* Get the initial island level
*
* @param island - island
* @return level or 0 by default
*/
public long getInitialIslandLevel(@NonNull Island island) {
return getManager().getInitialLevel(island);
}
/**
* Get the initial island count
*
* @param island - island
* @return count or 0 by default
*/
public long getInitialIslandCount(@NonNull Island island) {
return getManager().getInitialCount(island);
}

/**
* Calculates a user's island
Expand All @@ -392,21 +405,22 @@ public void calculateIslandLevel(World world, @Nullable User user, @NonNull UUID
* @return LevelsData object or null if not found. Only island levels are set!
* @deprecated Do not use this anymore. Use {@link #getIslandLevel(World, UUID)}
*/
@Deprecated(since = "2.3.0", forRemoval = true)
public LevelsData getLevelsData(UUID targetPlayer) {
LevelsData ld = new LevelsData(targetPlayer);
getPlugin().getAddonsManager().getGameModeAddons().stream()
.filter(gm -> !settings.getGameModes().contains(gm.getDescription().getName())).forEach(gm -> {
if (getSettings().isZeroNewIslandLevels()) {
Island island = getIslands().getIsland(gm.getOverWorld(), targetPlayer);
if (island != null) {
ld.setInitialLevel(gm.getOverWorld(), this.getInitialIslandLevel(island));
}
}
ld.setLevel(gm.getOverWorld(), this.getIslandLevel(gm.getOverWorld(), targetPlayer));
});
return ld;
}
/*
@Deprecated(since = "2.3.0", forRemoval = true)
public LevelsData getLevelsData(UUID targetPlayer) {
LevelsData ld = new LevelsData(targetPlayer);
getPlugin().getAddonsManager().getGameModeAddons().stream()
.filter(gm -> !settings.getGameModes().contains(gm.getDescription().getName())).forEach(gm -> {
if (getSettings().isZeroNewIslandLevels()) {
Island island = getIslands().getIsland(gm.getOverWorld(), targetPlayer);
if (island != null) {
ld.setInitialLevel(gm.getOverWorld(), this.getInitialIslandLevel(island));
}
}
ld.setLevel(gm.getOverWorld(), this.getIslandLevel(gm.getOverWorld(), targetPlayer));
});
return ld;
}*/

/**
* @return the registeredGameModes
Expand Down
84 changes: 66 additions & 18 deletions src/main/java/world/bentobox/level/LevelsManager.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package world.bentobox.level;

import java.io.IOException;
import java.math.BigInteger;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.time.Instant;
import java.util.AbstractMap;
import java.util.Collections;
Expand All @@ -26,6 +28,7 @@

import world.bentobox.bentobox.database.Database;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.level.calculators.EquationEvaluator;
import world.bentobox.level.calculators.Results;
import world.bentobox.level.events.IslandLevelCalculatedEvent;
import world.bentobox.level.events.IslandPreLevelEvent;
Expand Down Expand Up @@ -130,7 +133,7 @@ private boolean fireIslandLevelCalcEvent(UUID targetPlayer, Island island, Resul
return true;
// Set the values if they were altered
results.setLevel((Long) ilce.getKeyValues().getOrDefault("level", results.getLevel()));
results.setInitialLevel((Long) ilce.getKeyValues().getOrDefault("initialLevel", results.getInitialLevel()));
results.setInitialCount((Long) ilce.getKeyValues().getOrDefault("initialCount", results.getInitialCount()));
results.setDeathHandicap((int) ilce.getKeyValues().getOrDefault("deathHandicap", results.getDeathHandicap()));
results.setPointsToNextLevel(
(Long) ilce.getKeyValues().getOrDefault("pointsToNextLevel", results.getPointsToNextLevel()));
Expand Down Expand Up @@ -168,13 +171,65 @@ public String formatLevel(@Nullable Long lvl) {
}

/**
* Get the initial level of the island. Used to zero island levels
* Get the initial count of the island. Used to zero island levels
*
* @param island - island
* @return initial level of island
* @return initial count of island
*/
public long getInitialLevel(Island island) {
return getLevelsData(island).getInitialLevel();
@SuppressWarnings("deprecation")
public long getInitialCount(Island island) {
Long initialLevel = getLevelsData(island).getInitialLevel(); // Backward compatibility check. For all new islands, this should be null.
Long initialCount = getLevelsData(island).getInitialCount();
if (initialLevel != null) {
// Initial level exists so convert it
if (initialCount == null) { // If initialCount is not null, then this is an edge case and initialCount will be used and initialLevel discarded
// Convert from level to count
initialCount = 0L;
try {
initialCount = getNumBlocks(initialLevel);
} catch (Exception e) {
addon.logError("Could not convert legacy initial level to count, so it will be set to 0. Error is: "
+ e.getLocalizedMessage());
initialCount = 0L;
}
}
// Null out the old initial level and save
getLevelsData(island).setInitialLevel(null);
// Save
this.setInitialIslandCount(island, initialCount);
}
// If initialCount doesn't exist, set it to 0L
if (initialCount == null) {
initialCount = 0L;
getLevelsData(island).setInitialCount(0L);
}
return initialCount;
}

/**
* Runs the level calculation using the current formula until the level matches the initial value, or fails.
* @param initialLevel - the old initial level
* @return block count to obtain this level now
* @throws ParseException if the formula for level calc is bugged
* @throws IOException if the number of blocks cannot be found for this level
*/
private long getNumBlocks(final long initialLevel) throws ParseException, IOException {
String calcString = addon.getSettings().getLevelCalc();
int result = -1;
long calculatedLevel = 0;
String withCost = calcString.replace("level_cost", String.valueOf(this.addon.getSettings().getLevelCost()));
long time = System.currentTimeMillis() + 10 * 1000; // 10 seconds
do {
result++;
if (System.currentTimeMillis() > time) {
throw new IOException("Timeout: Blocks cannot be found to create this initial level");
}
// Paste in the values to the formula
String withValues = withCost.replace("blocks", String.valueOf(result));
// Try and evaluate it
calculatedLevel = (long) EquationEvaluator.eval(withValues);
} while (calculatedLevel != initialLevel);
return result;
}

/**
Expand Down Expand Up @@ -422,15 +477,13 @@ public void removeEntry(World world, String uuid) {
}

/**
* Set an initial island level
* Set an initial island count
*
* @param island - the island to set. Must have a non-null world
* @param lv - initial island level
* @param island - the island to set.
* @param lv - initial island count
*/
public void setInitialIslandLevel(@NonNull Island island, long lv) {
if (island.getWorld() == null)
return;
levelsCache.computeIfAbsent(island.getUniqueId(), IslandLevels::new).setInitialLevel(lv);
public void setInitialIslandCount(@NonNull Island island, long lv) {
levelsCache.computeIfAbsent(island.getUniqueId(), IslandLevels::new).setInitialCount(lv);
handler.saveObjectAsync(levelsCache.get(island.getUniqueId()));
}

Expand All @@ -448,12 +501,7 @@ public void setIslandLevel(@NonNull World world, @NonNull UUID targetPlayer, lon
if (island != null) {
String id = island.getUniqueId();
IslandLevels il = levelsCache.computeIfAbsent(id, IslandLevels::new);
// Remove the initial level
if (addon.getSettings().isZeroNewIslandLevels()) {
il.setLevel(lv - il.getInitialLevel());
} else {
il.setLevel(lv);
}
il.setLevel(lv);
handler.saveObjectAsync(levelsCache.get(id));
// Update TopTen
addToTopTen(island, levelsCache.get(id).getLevel());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ public IslandLevelCalculator(Level addon, Island island, CompletableFuture<Resul
chunksToCheck = getChunksToScan(island);
this.limitCount = new HashMap<>();
// Get the initial island level
results.initialLevel.set(addon.getInitialIslandLevel(island));
// TODO: results.initialLevel.set(addon.getInitialIslandLevel(island));
results.setInitialCount(addon.getInitialIslandCount(island));
// Set up the worlds
worlds.put(Environment.NORMAL, Util.getWorld(island.getWorld()));
// Nether
Expand All @@ -117,19 +118,22 @@ public IslandLevelCalculator(Level addon, Island island, CompletableFuture<Resul
/**
* Calculate the level based on the raw points
*
* @param blockAndDeathPoints - raw points counted on island
* @param rawPoints - raw points counted on island
* @return level of island
*/
private long calculateLevel(long blockAndDeathPoints) {
private long calculateLevel(final long rawPoints) {
String calcString = addon.getSettings().getLevelCalc();
String withValues = calcString.replace("blocks", String.valueOf(blockAndDeathPoints)).replace("level_cost",
// Reduce count by initial count, if zeroing is done
long modifiedPoints = rawPoints
- (addon.getSettings().isZeroNewIslandLevels() ? results.initialCount.get() : 0);
// Paste in the values to the formula
String withValues = calcString.replace("blocks", String.valueOf(modifiedPoints)).replace("level_cost",
String.valueOf(this.addon.getSettings().getLevelCost()));
long evalWithValues;
// Try and evaluate it
try {
evalWithValues = (long) EquationEvaluator.eval(withValues);
return evalWithValues - (addon.getSettings().isZeroNewIslandLevels() ? results.initialLevel.get() : 0);

return (long) EquationEvaluator.eval(withValues);
} catch (ParseException e) {
// Hmm, error.
addon.getPlugin().logStacktrace(e);
return 0L;
}
Expand Down Expand Up @@ -240,8 +244,12 @@ private List<String> getReport() {
reportLines.add("Formula to calculate island level: " + addon.getSettings().getLevelCalc());
reportLines.add("Level cost = " + addon.getSettings().getLevelCost());
reportLines.add("Deaths handicap = " + results.deathHandicap.get());
/*
if (addon.getSettings().isZeroNewIslandLevels()) {
reportLines.add("Initial island level = " + (0L - addon.getManager().getInitialLevel(island)));
}*/
if (addon.getSettings().isZeroNewIslandLevels()) {
reportLines.add("Initial island count = " + (0L - addon.getManager().getInitialCount(island)));
}
reportLines.add("Previous level = " + addon.getManager().getIslandLevel(island.getWorld(), island.getOwner()));
reportLines.add("New level = " + results.getLevel());
Expand Down
43 changes: 39 additions & 4 deletions src/main/java/world/bentobox/level/calculators/Results.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
import com.google.common.collect.HashMultiset;
import com.google.common.collect.Multiset;

/**
* Where results are stored
*/
public class Results {
public enum Result {
/**
Expand All @@ -23,17 +26,33 @@ public enum Result {
TIMEOUT
}
List<String> report;
/**
* MaterialData count anything above sea level
*/
final Multiset<Object> mdCount = HashMultiset.create();
/**
* Underwater count
*/
final Multiset<Object> uwCount = HashMultiset.create();
/**
* Not-in-config count - blocks not listed in the scoring config file
*/
final Multiset<Object> ncCount = HashMultiset.create();
/**
* Blocks not counted because they exceeded limits
*/
final Multiset<Object> ofCount = HashMultiset.create();
// AtomicLong and AtomicInteger must be used because they are changed by multiple concurrent threads
AtomicLong rawBlockCount = new AtomicLong(0);
AtomicLong underWaterBlockCount = new AtomicLong(0);
AtomicLong level = new AtomicLong(0);
AtomicInteger deathHandicap = new AtomicInteger(0);
AtomicLong pointsToNextLevel = new AtomicLong(0);
AtomicLong initialLevel = new AtomicLong(0);
//AtomicLong initialLevel = new AtomicLong(0);
AtomicLong initialCount = new AtomicLong(0);
/**
* Total points before any death penalties
*/
AtomicLong totalPoints = new AtomicLong(0);
final Result state;

Expand Down Expand Up @@ -107,24 +126,26 @@ public void setTotalPoints(long points) {
totalPoints.set(points);
}

/*
public long getInitialLevel() {
return initialLevel.get();
}

public void setInitialLevel(long initialLevel) {
this.initialLevel.set(initialLevel);
}

*/
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
/*
@Override
public String toString() {
return "Results [report=" + report + ", mdCount=" + mdCount + ", uwCount=" + uwCount + ", ncCount="
+ ncCount + ", ofCount=" + ofCount + ", rawBlockCount=" + rawBlockCount + ", underWaterBlockCount="
+ underWaterBlockCount + ", level=" + level + ", deathHandicap=" + deathHandicap
+ ", pointsToNextLevel=" + pointsToNextLevel + ", totalPoints=" + totalPoints + ", initialLevel=" + initialLevel + "]";
}
}*/
/**
* @return the mdCount
*/
Expand All @@ -144,4 +165,18 @@ public Result getState() {
return state;
}

/**
* @return the initialCount
*/
public long getInitialCount() {
return initialCount.get();
}

/**
* @param long1 the initialCount to set
*/
public void setInitialCount(Long count) {
this.initialCount.set(count);
}

}
Loading