mirror of
https://github.com/BentoBoxWorld/Level.git
synced 2025-01-31 12:41:49 +01:00
Added more placeholders. #296
Refactored how the top ten maps are structured. In the future, it may be best to have the key be the island.
This commit is contained in:
parent
9d1a5c7476
commit
117d15f3d0
@ -2,6 +2,7 @@ package world.bentobox.level;
|
|||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
|
import java.util.AbstractMap;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
@ -293,6 +294,40 @@ public class LevelsManager {
|
|||||||
return island == null ? "" : String.valueOf(getLevelsData(island).getPointsToNextLevel());
|
return island == null ? "" : String.valueOf(getLevelsData(island).getPointsToNextLevel());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the weighted top ten for this world. Weighting is based on number of
|
||||||
|
* players per team.
|
||||||
|
*
|
||||||
|
* @param world - world requested
|
||||||
|
* @param size - size of the top ten
|
||||||
|
* @return sorted top ten map. The key is the island unique ID
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public Map<Island, Long> getWeightedTopTen(@NonNull World world, int size) {
|
||||||
|
createAndCleanRankings(world);
|
||||||
|
Map<Island, Long> weightedTopTen = topTenLists.get(world).getTopTen().entrySet().stream()
|
||||||
|
.map(en -> addon.getIslands().getIslandById(en.getKey()).map(island -> {
|
||||||
|
|
||||||
|
long value = (long) (en.getValue() / (double) Math.max(1, island.getMemberSet().size())); // Calculate
|
||||||
|
// weighted
|
||||||
|
// value
|
||||||
|
return new AbstractMap.SimpleEntry<>(island, value);
|
||||||
|
}).orElse(null)) // Handle islands that do not exist according to this ID - old deleted ones
|
||||||
|
.filter(Objects::nonNull) // Filter out null entries
|
||||||
|
.filter(en -> en.getValue() > 0) // Filter out entries with non-positive values
|
||||||
|
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue())) // Sort in descending order of values
|
||||||
|
.limit(size) // Limit to the top 'size' entries
|
||||||
|
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, // In case of key
|
||||||
|
// collision, choose
|
||||||
|
// the first one
|
||||||
|
LinkedHashMap::new // Preserves the order of entries
|
||||||
|
));
|
||||||
|
|
||||||
|
// Return the unmodifiable map
|
||||||
|
return Collections.unmodifiableMap(weightedTopTen);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the top ten for this world. Returns offline players or players with the
|
* Get the top ten for this world. Returns offline players or players with the
|
||||||
* intopten permission.
|
* intopten permission.
|
||||||
|
@ -2,7 +2,6 @@ package world.bentobox.level;
|
|||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -66,19 +65,29 @@ public class PlaceholderManager {
|
|||||||
final int rank = i;
|
final int rank = i;
|
||||||
// Name
|
// Name
|
||||||
bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_top_name_" + i,
|
bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_top_name_" + i,
|
||||||
u -> getRankName(gm.getOverWorld(), rank));
|
u -> getRankName(gm.getOverWorld(), rank, false));
|
||||||
// Island Name
|
// Island Name
|
||||||
bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_top_island_name_" + i,
|
bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_top_island_name_" + i,
|
||||||
u -> getRankIslandName(gm.getOverWorld(), rank));
|
u -> getRankIslandName(gm.getOverWorld(), rank, false));
|
||||||
// Members
|
// Members
|
||||||
bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_top_members_" + i,
|
bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_top_members_" + i,
|
||||||
u -> getRankMembers(gm.getOverWorld(), rank));
|
u -> getRankMembers(gm.getOverWorld(), rank, false));
|
||||||
// Level
|
// Level
|
||||||
bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_top_value_" + i,
|
bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_top_value_" + i,
|
||||||
u -> getRankLevel(gm.getOverWorld(), rank));
|
u -> getRankLevel(gm.getOverWorld(), rank, false));
|
||||||
|
// Weighted Level Name (Level / number of members)
|
||||||
|
bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_top_weighted_name_" + i,
|
||||||
|
u -> getRankName(gm.getOverWorld(), rank, true));
|
||||||
|
// Weighted Island Name
|
||||||
|
bpm.registerPlaceholder(addon,
|
||||||
|
gm.getDescription().getName().toLowerCase() + "_top_weighted_island_name_" + i,
|
||||||
|
u -> getRankIslandName(gm.getOverWorld(), rank, true));
|
||||||
|
// Weighted Members
|
||||||
|
bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_top_weighted_members_" + i,
|
||||||
|
u -> getRankMembers(gm.getOverWorld(), rank, true));
|
||||||
// Weighted Level (Level / number of members)
|
// Weighted Level (Level / number of members)
|
||||||
bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_top_weighted_value_" + i,
|
bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_top_weighted_value_" + i,
|
||||||
u -> getWeightedRankLevel(gm.getOverWorld(), rank));
|
u -> getRankLevel(gm.getOverWorld(), rank, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Personal rank
|
// Personal rank
|
||||||
@ -89,13 +98,18 @@ public class PlaceholderManager {
|
|||||||
/**
|
/**
|
||||||
* Get the name of the owner of the island who holds the rank in this world.
|
* Get the name of the owner of the island who holds the rank in this world.
|
||||||
*
|
*
|
||||||
* @param world world
|
* @param world world
|
||||||
* @param rank rank 1 to 10
|
* @param rank rank 1 to 10
|
||||||
|
* @param weighted if true, then the weighted rank name is returned
|
||||||
* @return rank name
|
* @return rank name
|
||||||
*/
|
*/
|
||||||
String getRankName(World world, int rank) {
|
String getRankName(World world, int rank, boolean weighted) {
|
||||||
// Ensure rank is within bounds
|
// Ensure rank is within bounds
|
||||||
rank = Math.max(1, Math.min(rank, Level.TEN));
|
rank = Math.max(1, Math.min(rank, Level.TEN));
|
||||||
|
if (weighted) {
|
||||||
|
return addon.getManager().getWeightedTopTen(world, Level.TEN).keySet().stream().skip(rank - 1L).limit(1L)
|
||||||
|
.findFirst().map(Island::getOwner).map(addon.getPlayers()::getName).orElse("");
|
||||||
|
}
|
||||||
@Nullable
|
@Nullable
|
||||||
UUID owner = addon.getManager().getTopTen(world, Level.TEN).keySet().stream().skip(rank - 1L).limit(1L)
|
UUID owner = addon.getManager().getTopTen(world, Level.TEN).keySet().stream().skip(rank - 1L).limit(1L)
|
||||||
.findFirst().flatMap(addon.getIslands()::getIslandById).map(Island::getOwner).orElse(null);
|
.findFirst().flatMap(addon.getIslands()::getIslandById).map(Island::getOwner).orElse(null);
|
||||||
@ -106,13 +120,18 @@ public class PlaceholderManager {
|
|||||||
/**
|
/**
|
||||||
* Get the island name for this rank
|
* Get the island name for this rank
|
||||||
*
|
*
|
||||||
* @param world world
|
* @param world world
|
||||||
* @param rank rank 1 to 10
|
* @param rank rank 1 to 10
|
||||||
|
* @param weighted if true, then the weighted rank name is returned
|
||||||
* @return name of island or nothing if there isn't one
|
* @return name of island or nothing if there isn't one
|
||||||
*/
|
*/
|
||||||
String getRankIslandName(World world, int rank) {
|
String getRankIslandName(World world, int rank, boolean weighted) {
|
||||||
// Ensure rank is within bounds
|
// Ensure rank is within bounds
|
||||||
rank = Math.max(1, Math.min(rank, Level.TEN));
|
rank = Math.max(1, Math.min(rank, Level.TEN));
|
||||||
|
if (weighted) {
|
||||||
|
return addon.getManager().getWeightedTopTen(world, Level.TEN).keySet().stream().skip(rank - 1L).limit(1L)
|
||||||
|
.findFirst().map(Island::getName).orElse("");
|
||||||
|
}
|
||||||
return addon.getManager().getTopTen(world, Level.TEN).keySet().stream().skip(rank - 1L).limit(1L).findFirst()
|
return addon.getManager().getTopTen(world, Level.TEN).keySet().stream().skip(rank - 1L).limit(1L).findFirst()
|
||||||
.flatMap(addon.getIslands()::getIslandById).map(Island::getName).orElse("");
|
.flatMap(addon.getIslands()::getIslandById).map(Island::getName).orElse("");
|
||||||
}
|
}
|
||||||
@ -120,13 +139,23 @@ public class PlaceholderManager {
|
|||||||
/**
|
/**
|
||||||
* Gets a comma separated string of island member names
|
* Gets a comma separated string of island member names
|
||||||
*
|
*
|
||||||
* @param world world
|
* @param world world
|
||||||
* @param rank rank to request
|
* @param rank rank to request
|
||||||
|
* @param weighted if true, then the weighted rank name is returned
|
||||||
* @return comma separated string of island member names
|
* @return comma separated string of island member names
|
||||||
*/
|
*/
|
||||||
String getRankMembers(World world, int rank) {
|
String getRankMembers(World world, int rank, boolean weighted) {
|
||||||
// Ensure rank is within bounds
|
// Ensure rank is within bounds
|
||||||
rank = Math.max(1, Math.min(rank, Level.TEN));
|
rank = Math.max(1, Math.min(rank, Level.TEN));
|
||||||
|
if (weighted) {
|
||||||
|
return addon.getManager().getWeightedTopTen(world, Level.TEN).keySet().stream().skip(rank - 1L).limit(1L)
|
||||||
|
.findFirst()
|
||||||
|
.map(is -> is.getMembers().entrySet().stream().filter(e -> e.getValue() >= RanksManager.MEMBER_RANK)
|
||||||
|
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue())).map(Map.Entry::getKey)
|
||||||
|
.map(addon.getPlayers()::getName).collect(Collectors.joining(",")))
|
||||||
|
.orElse("");
|
||||||
|
}
|
||||||
|
|
||||||
Optional<Island> island = addon.getManager().getTopTen(world, Level.TEN).keySet().stream().skip(rank - 1L)
|
Optional<Island> island = addon.getManager().getTopTen(world, Level.TEN).keySet().stream().skip(rank - 1L)
|
||||||
.limit(1L).findFirst().flatMap(addon.getIslands()::getIslandById);
|
.limit(1L).findFirst().flatMap(addon.getIslands()::getIslandById);
|
||||||
|
|
||||||
@ -140,44 +169,20 @@ public class PlaceholderManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the weighted level, which is the level / number of players
|
* Get the level for the rank requested
|
||||||
*
|
*
|
||||||
* @param world world
|
* @param world world
|
||||||
* @param rank level
|
* @param rank rank wanted
|
||||||
* @return weighted level
|
* @param weighted true if weighted (level/number of team members)
|
||||||
|
* @return level for the rank requested
|
||||||
*/
|
*/
|
||||||
String getWeightedRankLevel(World world, int rank) {
|
String getRankLevel(World world, int rank, boolean weighted) {
|
||||||
// Ensure rank is within bounds
|
// Ensure rank is within bounds
|
||||||
rank = Math.max(1, Math.min(rank, Level.TEN));
|
rank = Math.max(1, Math.min(rank, Level.TEN));
|
||||||
|
if (weighted) {
|
||||||
// Retrieve the top ten entries
|
return addon.getManager().formatLevel(addon.getManager().getWeightedTopTen(world, Level.TEN).values()
|
||||||
Map<String, Long> topTen = addon.getManager().getTopTen(world, Level.TEN);
|
.stream().skip(rank - 1L).limit(1L).findFirst().orElse(null));
|
||||||
if (topTen.isEmpty()) {
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the entry corresponding to the rank
|
|
||||||
Entry<String, Long> entry = topTen.entrySet().stream().skip(rank - 1).findFirst().orElse(null);
|
|
||||||
if (entry == null) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate the score
|
|
||||||
Island island = addon.getIslands().getIslandById(entry.getKey()).orElse(null);
|
|
||||||
if (island == null || island.getMemberSet().isEmpty()) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
double score = (double) entry.getValue() / island.getMemberSet().size();
|
|
||||||
|
|
||||||
// Format and return the level
|
|
||||||
return addon.getManager().formatLevel((long) score);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
String getRankLevel(World world, int rank) {
|
|
||||||
// Ensure rank is within bounds
|
|
||||||
rank = Math.max(1, Math.min(rank, Level.TEN));
|
|
||||||
return addon.getManager().formatLevel(addon.getManager().getTopTen(world, Level.TEN).values().stream()
|
return addon.getManager().formatLevel(addon.getManager().getTopTen(world, Level.TEN).values().stream()
|
||||||
.skip(rank - 1L).limit(1L).findFirst().orElse(null));
|
.skip(rank - 1L).limit(1L).findFirst().orElse(null));
|
||||||
}
|
}
|
||||||
|
@ -364,6 +364,19 @@ public class LevelsManagerTest {
|
|||||||
assertEquals(1, lm.getTopTen(world, 1).size());
|
assertEquals(1, lm.getTopTen(world, 1).size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test method for
|
||||||
|
* {@link world.bentobox.level.LevelsManager#getWeightedTopTen(org.bukkit.World, int)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGetWeightedTopTen() {
|
||||||
|
testLoadTopTens();
|
||||||
|
Map<Island, Long> tt = lm.getWeightedTopTen(world, Level.TEN);
|
||||||
|
assertFalse(tt.isEmpty());
|
||||||
|
assertEquals(1, tt.size());
|
||||||
|
assertEquals(1, lm.getTopTen(world, 1).size());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for
|
* Test method for
|
||||||
* {@link world.bentobox.level.LevelsManager#hasTopTenPerm(org.bukkit.World, java.util.UUID)}.
|
* {@link world.bentobox.level.LevelsManager#hasTopTenPerm(org.bukkit.World, java.util.UUID)}.
|
||||||
|
@ -83,7 +83,8 @@ public class PlaceholderManagerTest {
|
|||||||
names.put(UUID.randomUUID(), "vicky");
|
names.put(UUID.randomUUID(), "vicky");
|
||||||
}
|
}
|
||||||
private Map<String, Island> islands = new HashMap<>();
|
private Map<String, Island> islands = new HashMap<>();
|
||||||
private Map<String, Long> map = new HashMap<>();
|
private Map<String, Long> map = new LinkedHashMap<>();
|
||||||
|
private Map<Island, Long> map2 = new LinkedHashMap<>();
|
||||||
private @NonNull IslandLevels data;
|
private @NonNull IslandLevels data;
|
||||||
@Mock
|
@Mock
|
||||||
private PlayersManager pm;
|
private PlayersManager pm;
|
||||||
@ -105,13 +106,14 @@ public class PlaceholderManagerTest {
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
for (Entry<UUID, String> n : names.entrySet()) {
|
for (Entry<UUID, String> n : names.entrySet()) {
|
||||||
UUID uuid = UUID.randomUUID(); // Random island ID
|
UUID uuid = UUID.randomUUID(); // Random island ID
|
||||||
map.put(uuid.toString(), (long)(100 - i++)); // level
|
Long value = (long)(100 - i++);
|
||||||
|
map.put(uuid.toString(), value); // level
|
||||||
Island is = new Island();
|
Island is = new Island();
|
||||||
is.setUniqueId(uuid.toString());
|
is.setUniqueId(uuid.toString());
|
||||||
is.setOwner(n.getKey());
|
is.setOwner(n.getKey());
|
||||||
is.setName(n.getValue() + "'s island");
|
is.setName(n.getValue() + "'s island");
|
||||||
islands.put(uuid.toString(), is);
|
islands.put(uuid.toString(), is);
|
||||||
|
map2.put(is, value);
|
||||||
}
|
}
|
||||||
// Sort
|
// Sort
|
||||||
map = map.entrySet().stream()
|
map = map.entrySet().stream()
|
||||||
@ -145,6 +147,7 @@ public class PlaceholderManagerTest {
|
|||||||
when(lm.getPointsToNextString(any(), any())).thenReturn("1234567");
|
when(lm.getPointsToNextString(any(), any())).thenReturn("1234567");
|
||||||
when(lm.getIslandMaxLevel(any(), any())).thenReturn(987654L);
|
when(lm.getIslandMaxLevel(any(), any())).thenReturn(987654L);
|
||||||
when(lm.getTopTen(world, Level.TEN)).thenReturn(map);
|
when(lm.getTopTen(world, Level.TEN)).thenReturn(map);
|
||||||
|
when(lm.getWeightedTopTen(world, Level.TEN)).thenReturn(map2);
|
||||||
when(lm.formatLevel(any())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(0, Long.class).toString());
|
when(lm.formatLevel(any())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(0, Long.class).toString());
|
||||||
|
|
||||||
data = new IslandLevels("uniqueId");
|
data = new IslandLevels("uniqueId");
|
||||||
@ -206,12 +209,12 @@ public class PlaceholderManagerTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testGetRankName() {
|
public void testGetRankName() {
|
||||||
// Test extremes
|
// Test extremes
|
||||||
assertEquals("tasty", phm.getRankName(world, 0));
|
assertEquals("tasty", phm.getRankName(world, 0, false));
|
||||||
assertEquals("vicky", phm.getRankName(world, 100));
|
assertEquals("vicky", phm.getRankName(world, 100, false));
|
||||||
// Test the ranks
|
// Test the ranks
|
||||||
int rank = 1;
|
int rank = 1;
|
||||||
for (String name : names.values()) {
|
for (String name : names.values()) {
|
||||||
assertEquals(name, phm.getRankName(world, rank++));
|
assertEquals(name, phm.getRankName(world, rank++, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -223,12 +226,12 @@ public class PlaceholderManagerTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testGetRankIslandName() {
|
public void testGetRankIslandName() {
|
||||||
// Test extremes
|
// Test extremes
|
||||||
assertEquals("tasty's island", phm.getRankIslandName(world, 0));
|
assertEquals("tasty's island", phm.getRankIslandName(world, 0, false));
|
||||||
assertEquals("vicky's island", phm.getRankIslandName(world, 100));
|
assertEquals("vicky's island", phm.getRankIslandName(world, 100, false));
|
||||||
// Test the ranks
|
// Test the ranks
|
||||||
int rank = 1;
|
int rank = 1;
|
||||||
for (String name : names.values()) {
|
for (String name : names.values()) {
|
||||||
assertEquals(name + "'s island", phm.getRankIslandName(world, rank++));
|
assertEquals(name + "'s island", phm.getRankIslandName(world, rank++, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -240,11 +243,11 @@ public class PlaceholderManagerTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testGetRankMembers() {
|
public void testGetRankMembers() {
|
||||||
// Test extremes
|
// Test extremes
|
||||||
check(1, phm.getRankMembers(world, 0));
|
check(1, phm.getRankMembers(world, 0, false));
|
||||||
check(2, phm.getRankMembers(world, 100));
|
check(2, phm.getRankMembers(world, 100, false));
|
||||||
// Test the ranks
|
// Test the ranks
|
||||||
for (int rank = 1; rank < 11; rank++) {
|
for (int rank = 1; rank < 11; rank++) {
|
||||||
check(3, phm.getRankMembers(world, rank));
|
check(3, phm.getRankMembers(world, rank, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,11 +264,27 @@ public class PlaceholderManagerTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testGetRankLevel() {
|
public void testGetRankLevel() {
|
||||||
// Test extremes
|
// Test extremes
|
||||||
assertEquals("100", phm.getRankLevel(world, 0));
|
assertEquals("100", phm.getRankLevel(world, 0, false));
|
||||||
assertEquals("91", phm.getRankLevel(world, 100));
|
assertEquals("91", phm.getRankLevel(world, 100, false));
|
||||||
// Test the ranks
|
// Test the ranks
|
||||||
for (int rank = 1; rank < 11; rank++) {
|
for (int rank = 1; rank < 11; rank++) {
|
||||||
assertEquals(String.valueOf(101 - rank), phm.getRankLevel(world, rank));
|
assertEquals(String.valueOf(101 - rank), phm.getRankLevel(world, rank, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test method for
|
||||||
|
* {@link world.bentobox.level.PlaceholderManager#getRankLevel(org.bukkit.World, int)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGetWeightedRankLevel() {
|
||||||
|
// Test extremes
|
||||||
|
assertEquals("100", phm.getRankLevel(world, 0, true));
|
||||||
|
assertEquals("91", phm.getRankLevel(world, 100, true));
|
||||||
|
// Test the ranks
|
||||||
|
for (int rank = 1; rank < 11; rank++) {
|
||||||
|
assertEquals(String.valueOf(101 - rank), phm.getRankLevel(world, rank, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user