From dab37e6af488791c8c9a5936e15db2528ec3254b Mon Sep 17 00:00:00 2001 From: tastybento Date: Sat, 30 Nov 2019 18:29:22 -0800 Subject: [PATCH 01/18] Version 1.9.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 036adc1..f8d0db7 100644 --- a/pom.xml +++ b/pom.xml @@ -65,7 +65,7 @@ -LOCAL - 1.9.0 + 1.9.1 From 002da7594fad1dc88553591c38ff48d02d9972c1 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sat, 30 Nov 2019 18:30:08 -0800 Subject: [PATCH 02/18] Addresses issue with null targets and visited island placeholder https://github.com/BentoBoxWorld/Level/issues/106 Added Level test class. --- src/main/java/world/bentobox/level/Level.java | 30 +- .../java/world/bentobox/level/LevelTest.java | 371 ++++++++++++++++++ 2 files changed, 389 insertions(+), 12 deletions(-) create mode 100644 src/test/java/world/bentobox/level/LevelTest.java diff --git a/src/main/java/world/bentobox/level/Level.java b/src/main/java/world/bentobox/level/Level.java index 4710e11..a744427 100644 --- a/src/main/java/world/bentobox/level/Level.java +++ b/src/main/java/world/bentobox/level/Level.java @@ -6,6 +6,7 @@ import java.util.Map; import java.util.UUID; import org.bukkit.World; +import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import world.bentobox.bentobox.api.addons.Addon; @@ -55,16 +56,17 @@ public class Level extends Addon { * @param user - the user who is asking, or null if none * @param playerUUID - the target island member's UUID */ - public void calculateIslandLevel(World world, @Nullable User user, UUID playerUUID) { + public void calculateIslandLevel(World world, @Nullable User user, @NonNull UUID playerUUID) { levelPresenter.calculateIslandLevel(world, user, playerUUID); } /** - * Get level from cache for a player - * @param targetPlayer - target player - * @return Level of player + * Get level from cache for a player. + * @param targetPlayer - target player UUID + * @return Level of player or zero if player is unknown or UUID is null */ - public long getIslandLevel(World world, UUID targetPlayer) { + public long getIslandLevel(World world, @Nullable UUID targetPlayer) { + if (targetPlayer == null) return 0L; LevelsData ld = getLevelsData(targetPlayer); return ld == null ? 0L : ld.getLevel(world); } @@ -74,7 +76,7 @@ public class Level extends Addon { * @param targetPlayer - UUID of target player * @return LevelsData object or null if not found */ - public LevelsData getLevelsData(UUID targetPlayer) { + public LevelsData getLevelsData(@NonNull UUID targetPlayer) { // Get from database if not in cache if (!levelsCache.containsKey(targetPlayer) && handler.objectExists(targetPlayer.toString())) { levelsCache.put(targetPlayer, handler.loadObject(targetPlayer.toString())); @@ -163,9 +165,9 @@ public class Level extends Addon { getPlugin().getPlaceholdersManager().registerPlaceholder(this, gm.getDescription().getName().toLowerCase() + "_visited_island_level", user -> getPlugin().getIslands().getIslandAt(user.getLocation()) - .map(island -> getIslandLevel(gm.getOverWorld(), island.getOwner())) - .map(level -> getLevelPresenter().getLevelString(level)) - .orElse("0")); + .map(island -> getIslandLevel(gm.getOverWorld(), island.getOwner())) + .map(level -> getLevelPresenter().getLevelString(level)) + .orElse("0")); // Top Ten for (int i = 1; i <= 10; i++) { @@ -236,7 +238,7 @@ public class Level extends Addon { * @param island - island * @param level - initial calculated island level */ - public void setInitialIslandLevel(Island island, long level) { + public void setInitialIslandLevel(@NonNull Island island, long level) { if (island.getWorld() == null || island.getOwner() == null) { this.logError("Level: request to store a null (initial) " + island.getWorld() + " " + island.getOwner()); return; @@ -250,15 +252,19 @@ public class Level extends Addon { * @param island - island * @return level or 0 by default */ - public long getInitialIslandLevel(Island island) { + public long getInitialIslandLevel(@NonNull Island island) { return levelsCache.containsKey(island.getOwner()) ? levelsCache.get(island.getOwner()).getInitialLevel(island.getWorld()) : 0L; } + /** + * @return database handler + */ + @Nullable public Database getHandler() { return handler; } - public void uncachePlayer(UUID uniqueId) { + public void uncachePlayer(@Nullable UUID uniqueId) { if (levelsCache.containsKey(uniqueId) && levelsCache.get(uniqueId) != null) { handler.saveObject(levelsCache.get(uniqueId)); } diff --git a/src/test/java/world/bentobox/level/LevelTest.java b/src/test/java/world/bentobox/level/LevelTest.java new file mode 100644 index 0000000..d2d9353 --- /dev/null +++ b/src/test/java/world/bentobox/level/LevelTest.java @@ -0,0 +1,371 @@ +package world.bentobox.level; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.Comparator; +import java.util.Optional; +import java.util.UUID; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; +import java.util.logging.Logger; + +import org.bukkit.Bukkit; +import org.bukkit.Server; +import org.bukkit.UnsafeValues; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFactory; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.plugin.PluginManager; +import org.bukkit.scheduler.BukkitScheduler; +import org.eclipse.jdt.annotation.NonNull; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.stubbing.Answer; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.reflect.Whitebox; + +import world.bentobox.bentobox.BentoBox; +import world.bentobox.bentobox.Settings; +import world.bentobox.bentobox.api.addons.AddonDescription; +import world.bentobox.bentobox.api.addons.GameModeAddon; +import world.bentobox.bentobox.api.commands.CompositeCommand; +import world.bentobox.bentobox.api.user.User; +import world.bentobox.bentobox.database.DatabaseSetup.DatabaseType; +import world.bentobox.bentobox.database.objects.Island; +import world.bentobox.bentobox.managers.AddonsManager; +import world.bentobox.bentobox.managers.CommandsManager; +import world.bentobox.bentobox.managers.FlagsManager; +import world.bentobox.bentobox.managers.IslandWorldManager; +import world.bentobox.bentobox.managers.IslandsManager; +import world.bentobox.bentobox.managers.PlaceholdersManager; +import world.bentobox.level.listeners.IslandTeamListeners; +import world.bentobox.level.listeners.JoinLeaveListener; + +/** + * @author tastybento + * + */ +@SuppressWarnings("deprecation") +@RunWith(PowerMockRunner.class) +@PrepareForTest({Bukkit.class, BentoBox.class, User.class}) +public class LevelTest { + + private static File jFile; + @Mock + private User user; + @Mock + private IslandsManager im; + @Mock + private Island island; + @Mock + private BentoBox plugin; + @Mock + private FlagsManager fm; + @Mock + private GameModeAddon gameMode; + @Mock + private AddonsManager am; + @Mock + private BukkitScheduler scheduler; + @Mock + private Settings settings; + + private Level addon; + + @Mock + private Logger logger; + @Mock + private PlaceholdersManager phm; + @Mock + private CompositeCommand cmd; + @Mock + private CompositeCommand adminCmd; + @Mock + private World world; + private UUID uuid; + + @BeforeClass + public static void beforeClass() throws IOException { + jFile = new File("addon.jar"); + // Copy over config file from src folder + Path fromPath = Paths.get("src/main/resources/config.yml"); + Path path = Paths.get("config.yml"); + Files.copy(fromPath, path); + try (JarOutputStream tempJarOutputStream = new JarOutputStream(new FileOutputStream(jFile))) { + //Added the new files to the jar. + try (FileInputStream fis = new FileInputStream(path.toFile())) { + byte[] buffer = new byte[1024]; + int bytesRead = 0; + JarEntry entry = new JarEntry(path.toString()); + tempJarOutputStream.putNextEntry(entry); + while((bytesRead = fis.read(buffer)) != -1) { + tempJarOutputStream.write(buffer, 0, bytesRead); + } + } + } + } + + /** + * @throws java.lang.Exception + */ + @SuppressWarnings("deprecation") + @Before + public void setUp() throws Exception { + // Set up plugin + Whitebox.setInternalState(BentoBox.class, "instance", plugin); + when(plugin.getLogger()).thenReturn(Logger.getAnonymousLogger()); + //when(plugin.isEnabled()).thenReturn(true); + // Command manager + CommandsManager cm = mock(CommandsManager.class); + when(plugin.getCommandsManager()).thenReturn(cm); + + // Player + Player p = mock(Player.class); + // Sometimes use Mockito.withSettings().verboseLogging() + when(user.isOp()).thenReturn(false); + uuid = UUID.randomUUID(); + when(user.getUniqueId()).thenReturn(uuid); + when(user.getPlayer()).thenReturn(p); + when(user.getName()).thenReturn("tastybento"); + User.setPlugin(plugin); + + // Island World Manager + IslandWorldManager iwm = mock(IslandWorldManager.class); + when(plugin.getIWM()).thenReturn(iwm); + + + // Player has island to begin with + when(im.getIsland(Mockito.any(), Mockito.any(UUID.class))).thenReturn(island); + when(plugin.getIslands()).thenReturn(im); + + // Locales + // Return the reference (USE THIS IN THE FUTURE) + when(user.getTranslation(Mockito.anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); + + // Server + PowerMockito.mockStatic(Bukkit.class); + Server server = mock(Server.class); + when(Bukkit.getServer()).thenReturn(server); + when(Bukkit.getLogger()).thenReturn(Logger.getAnonymousLogger()); + when(Bukkit.getPluginManager()).thenReturn(mock(PluginManager.class)); + + // Addon + addon = new Level(); + File dataFolder = new File("addons/Level"); + addon.setDataFolder(dataFolder); + addon.setFile(jFile); + AddonDescription desc = new AddonDescription.Builder("bentobox", "Level", "1.3").description("test").authors("tastybento").build(); + addon.setDescription(desc); + // Addons manager + when(plugin.getAddonsManager()).thenReturn(am); + // One game mode + when(am.getGameModeAddons()).thenReturn(Collections.singletonList(gameMode)); + AddonDescription desc2 = new AddonDescription.Builder("bentobox", "BSkyBlock", "1.3").description("test").authors("tasty").build(); + when(gameMode.getDescription()).thenReturn(desc2); + + // Player command + @NonNull + Optional opCmd = Optional.of(cmd); + when(gameMode.getPlayerCommand()).thenReturn(opCmd); + // Admin command + Optional opAdminCmd = Optional.of(adminCmd); + when(gameMode.getAdminCommand()).thenReturn(opAdminCmd); + + // Flags manager + when(plugin.getFlagsManager()).thenReturn(fm); + when(fm.getFlags()).thenReturn(Collections.emptyList()); + + // The database type has to be created one line before the thenReturn() to work! + when(plugin.getSettings()).thenReturn(settings); + DatabaseType value = DatabaseType.JSON; + when(settings.getDatabaseType()).thenReturn(value); + + // Bukkit + PowerMockito.mockStatic(Bukkit.class); + when(Bukkit.getScheduler()).thenReturn(scheduler); + ItemMeta meta = mock(ItemMeta.class); + ItemFactory itemFactory = mock(ItemFactory.class); + when(itemFactory.getItemMeta(any())).thenReturn(meta); + when(Bukkit.getItemFactory()).thenReturn(itemFactory); + UnsafeValues unsafe = mock(UnsafeValues.class); + when(unsafe.getDataVersion()).thenReturn(777); + when(Bukkit.getUnsafe()).thenReturn(unsafe); + + // placeholders + when(plugin.getPlaceholdersManager()).thenReturn(phm); + + // World + when(world.getName()).thenReturn("bskyblock-world"); + // Island + when(island.getWorld()).thenReturn(world); + when(island.getOwner()).thenReturn(uuid); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception { + deleteAll(new File("database")); + } + + @AfterClass + public static void cleanUp() throws Exception { + new File("addon.jar").delete(); + new File("config.yml").delete(); + deleteAll(new File("addons")); + } + + private static void deleteAll(File file) throws IOException { + if (file.exists()) { + Files.walk(file.toPath()) + .sorted(Comparator.reverseOrder()) + .map(Path::toFile) + .forEach(File::delete); + } + } + + /** + * Test method for {@link world.bentobox.level.Level#onEnable()}. + */ + @Test + public void testOnEnable() { + addon.onEnable(); + verify(plugin).logWarning("[Level] Level Addon: No such world in config.yml : acidisland_world"); + verify(plugin).log("[Level] Level hooking into BSkyBlock"); + verify(cmd, times(3)).getAddon(); // Three commands + verify(adminCmd, times(2)).getAddon(); // Two commands + // Placeholders + verify(phm).registerPlaceholder(eq(addon), eq("bskyblock-island-level"), any()); + for (int i = 1; i < 11; i++) { + verify(phm).registerPlaceholder(eq(addon), eq("bskyblock-island-level-top-name-" + i), any()); + verify(phm).registerPlaceholder(eq(addon), eq("bskyblock-island-level-top-value-" + i), any()); + } + verify(phm).registerPlaceholder(eq(addon), eq("bskyblock_island_level"), any()); + verify(phm).registerPlaceholder(eq(addon), eq("bskyblock_visited_island_level"), any()); + for (int i = 1; i < 11; i++) { + verify(phm).registerPlaceholder(eq(addon), eq("bskyblock_top_name_" + i), any()); + verify(phm).registerPlaceholder(eq(addon), eq("bskyblock_top_value_" + i), any()); + } + // Commands + verify(am).registerListener(eq(addon), any(IslandTeamListeners.class)); + verify(am).registerListener(eq(addon), any(JoinLeaveListener.class)); + } + + /** + * Test method for {@link world.bentobox.level.Level#getIslandLevel(org.bukkit.World, java.util.UUID)}. + */ + @Test + public void testGetIslandLevelUnknown() { + addon.onEnable(); + assertEquals(0L, addon.getIslandLevel(world, UUID.randomUUID())); + } + + /** + * Test method for {@link world.bentobox.level.Level#getIslandLevel(org.bukkit.World, java.util.UUID)}. + */ + @Test + public void testGetIslandLevelNullTarget() { + addon.onEnable(); + assertEquals(0L, addon.getIslandLevel(world, UUID.randomUUID())); + + } + + /** + * Test method for {@link world.bentobox.level.Level#getLevelsData(java.util.UUID)}. + */ + @Test + public void testGetLevelsDataUnknown() { + addon.onEnable(); + assertNull(addon.getLevelsData(UUID.randomUUID())); + } + + /** + * Test method for {@link world.bentobox.level.Level#getSettings()}. + */ + @Test + public void testGetSettings() { + addon.onEnable(); + world.bentobox.level.config.Settings s = addon.getSettings(); + assertEquals(100, s.getDeathPenalty()); + } + + /** + * Test method for {@link world.bentobox.level.Level#getTopTen()}. + */ + @Test + public void testGetTopTen() { + addon.onEnable(); + assertNotNull(addon.getTopTen()); + } + + /** + * Test method for {@link world.bentobox.level.Level#getLevelPresenter()}. + */ + @Test + public void testGetLevelPresenter() { + addon.onEnable(); + assertNotNull(addon.getLevelPresenter()); + } + + /** + * Test method for {@link world.bentobox.level.Level#setIslandLevel(org.bukkit.World, java.util.UUID, long)}. + */ + @Test + public void testSetIslandLevel() { + addon.onEnable(); + addon.setIslandLevel(world, uuid, 345L); + assertEquals(345L, addon.getIslandLevel(world, uuid)); + verify(plugin, never()).logError(anyString()); + } + + /** + * Test method for {@link world.bentobox.level.Level#getInitialIslandLevel(world.bentobox.bentobox.database.objects.Island)}. + */ + @Test + public void testGetInitialIslandLevel() { + addon.onEnable(); + addon.setInitialIslandLevel(island, 40); + verify(plugin, never()).logError(anyString()); + assertEquals(40, addon.getInitialIslandLevel(island)); + + } + + /** + * Test method for {@link world.bentobox.level.Level#getHandler()}. + */ + @Test + public void testGetHandler() { + addon.onEnable(); + assertNotNull(addon.getHandler()); + } + + +} From 5c9c84c98a811c6044dcd5c1536d87813face69e Mon Sep 17 00:00:00 2001 From: tastybento Date: Wed, 18 Dec 2019 13:27:59 -0800 Subject: [PATCH 03/18] Removed condition that always waa true. --- .../world/bentobox/level/requests/TopTenRequestHandler.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/world/bentobox/level/requests/TopTenRequestHandler.java b/src/main/java/world/bentobox/level/requests/TopTenRequestHandler.java index 6c92f4c..ea2f524 100644 --- a/src/main/java/world/bentobox/level/requests/TopTenRequestHandler.java +++ b/src/main/java/world/bentobox/level/requests/TopTenRequestHandler.java @@ -7,7 +7,6 @@ import org.bukkit.Bukkit; import world.bentobox.bentobox.api.addons.request.AddonRequestHandler; import world.bentobox.level.Level; -import world.bentobox.level.objects.TopTenData; /** @@ -54,8 +53,7 @@ public class TopTenRequestHandler extends AddonRequestHandler { return Collections.emptyMap(); } - // Null-point check. - TopTenData data = addon.getTopTen().getTopTenList(Bukkit.getWorld((String) map.get(WORLD_NAME))); - return data != null ? data.getTopTen() : Collections.emptyMap(); + // No null check required + return addon.getTopTen().getTopTenList(Bukkit.getWorld((String) map.get(WORLD_NAME))).getTopTen(); } } From 09583aa3a719ad87a4e2a8930a035d2d36e41408 Mon Sep 17 00:00:00 2001 From: tastybento Date: Wed, 18 Dec 2019 14:45:15 -0800 Subject: [PATCH 04/18] Use enum map --- .../level/calculators/CalcIslandLevel.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/main/java/world/bentobox/level/calculators/CalcIslandLevel.java b/src/main/java/world/bentobox/level/calculators/CalcIslandLevel.java index e64b31d..7bd747d 100644 --- a/src/main/java/world/bentobox/level/calculators/CalcIslandLevel.java +++ b/src/main/java/world/bentobox/level/calculators/CalcIslandLevel.java @@ -1,6 +1,16 @@ package world.bentobox.level.calculators; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.EnumMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.Set; +import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; @@ -38,7 +48,7 @@ public class CalcIslandLevel { private final Runnable onExit; // Copy the limits hash map - private final HashMap limitCount; + private final Map limitCount; private final List worlds; private final World world; @@ -59,7 +69,7 @@ public class CalcIslandLevel { this.addon = addon; this.island = island; this.world = island.getWorld(); - this.limitCount = new HashMap<>(addon.getSettings().getBlockLimits()); + this.limitCount = new EnumMap<>(addon.getSettings().getBlockLimits()); this.onExit = onExit; this.worlds = new ArrayList<>(); this.worlds.add(world); @@ -93,6 +103,7 @@ public class CalcIslandLevel { } } queueid = Bukkit.getScheduler().scheduleSyncRepeatingTask(addon.getPlugin(), new Runnable() { + @Override public void run() { for (int i = 0; i < 10; i++) { if (q.size() == 0) { From eba6e11ec99be6cb14c0d1133db14342a4a85b8c Mon Sep 17 00:00:00 2001 From: tastybento Date: Thu, 19 Dec 2019 11:40:33 -0800 Subject: [PATCH 05/18] Revert "Use enum map" This reverts commit 09583aa3a719ad87a4e2a8930a035d2d36e41408. --- .../level/calculators/CalcIslandLevel.java | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/src/main/java/world/bentobox/level/calculators/CalcIslandLevel.java b/src/main/java/world/bentobox/level/calculators/CalcIslandLevel.java index 7bd747d..e64b31d 100644 --- a/src/main/java/world/bentobox/level/calculators/CalcIslandLevel.java +++ b/src/main/java/world/bentobox/level/calculators/CalcIslandLevel.java @@ -1,16 +1,6 @@ package world.bentobox.level.calculators; -import java.util.ArrayList; -import java.util.Collection; -import java.util.EnumMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Queue; -import java.util.Set; -import java.util.UUID; +import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; @@ -48,7 +38,7 @@ public class CalcIslandLevel { private final Runnable onExit; // Copy the limits hash map - private final Map limitCount; + private final HashMap limitCount; private final List worlds; private final World world; @@ -69,7 +59,7 @@ public class CalcIslandLevel { this.addon = addon; this.island = island; this.world = island.getWorld(); - this.limitCount = new EnumMap<>(addon.getSettings().getBlockLimits()); + this.limitCount = new HashMap<>(addon.getSettings().getBlockLimits()); this.onExit = onExit; this.worlds = new ArrayList<>(); this.worlds.add(world); @@ -103,7 +93,6 @@ public class CalcIslandLevel { } } queueid = Bukkit.getScheduler().scheduleSyncRepeatingTask(addon.getPlugin(), new Runnable() { - @Override public void run() { for (int i = 0; i < 10; i++) { if (q.size() == 0) { From 3edb12581d70ba4356e7ef34f2f4781c362a7c6a Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Tue, 24 Dec 2019 15:45:28 +0100 Subject: [PATCH 06/18] Fix top10 placeholders (#110) --- src/main/java/world/bentobox/level/Level.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/world/bentobox/level/Level.java b/src/main/java/world/bentobox/level/Level.java index a744427..876a58d 100644 --- a/src/main/java/world/bentobox/level/Level.java +++ b/src/main/java/world/bentobox/level/Level.java @@ -177,7 +177,7 @@ public class Level extends Addon { gm.getDescription().getName().toLowerCase() + "_top_value_" + rank, user -> { Collection values = getTopTen().getTopTenList(gm.getOverWorld()).getTopTen().values(); - return values.size() < rank ? "" : values.stream().skip(rank).findFirst().map(String::valueOf).orElse(""); + return values.size() < rank ? "" : values.stream().skip(rank - 1).findFirst().map(String::valueOf).orElse(""); }); // Name @@ -185,7 +185,7 @@ public class Level extends Addon { gm.getDescription().getName().toLowerCase() + "_top_name_" + rank, user -> { Collection values = getTopTen().getTopTenList(gm.getOverWorld()).getTopTen().keySet(); - return values.size() < rank ? "" : getPlayers().getName(values.stream().skip(rank).findFirst().orElse(null)); + return values.size() < rank ? "" : getPlayers().getName(values.stream().skip(rank - 1).findFirst().orElse(null)); }); } } From 816a077dddf4c5cf18a30fa80bcf8cf2a9f4cb7f Mon Sep 17 00:00:00 2001 From: Florian CUNY Date: Tue, 31 Dec 2019 11:07:44 +0100 Subject: [PATCH 07/18] Removed the warnings for deprecated placeholders --- .../world/bentobox/level/placeholders/LevelPlaceholder.java | 3 --- .../bentobox/level/placeholders/TopTenNamePlaceholder.java | 3 --- .../world/bentobox/level/placeholders/TopTenPlaceholder.java | 3 --- 3 files changed, 9 deletions(-) diff --git a/src/main/java/world/bentobox/level/placeholders/LevelPlaceholder.java b/src/main/java/world/bentobox/level/placeholders/LevelPlaceholder.java index 928e20a..964a4c6 100644 --- a/src/main/java/world/bentobox/level/placeholders/LevelPlaceholder.java +++ b/src/main/java/world/bentobox/level/placeholders/LevelPlaceholder.java @@ -31,9 +31,6 @@ public class LevelPlaceholder implements PlaceholderReplacer { */ @Override public String onReplace(User user) { - addon.logWarning("You are using a deprecated placeholder."); - addon.log("Please replace any occurrence of 'Level_" + gm.getDescription().getName().toLowerCase() + "-island-level'"); - addon.log("by 'Level_" + gm.getDescription().getName().toLowerCase() + "_island_level'"); return addon.getLevelPresenter().getLevelString(addon.getIslandLevel(gm.getOverWorld(), user.getUniqueId())); } diff --git a/src/main/java/world/bentobox/level/placeholders/TopTenNamePlaceholder.java b/src/main/java/world/bentobox/level/placeholders/TopTenNamePlaceholder.java index 3e43d47..fe52a5e 100644 --- a/src/main/java/world/bentobox/level/placeholders/TopTenNamePlaceholder.java +++ b/src/main/java/world/bentobox/level/placeholders/TopTenNamePlaceholder.java @@ -30,9 +30,6 @@ public class TopTenNamePlaceholder implements PlaceholderReplacer { */ @Override public String onReplace(User user) { - level.logWarning("You are using a deprecated placeholder."); - level.log("Please replace any occurrence of 'Level_" + gm.getDescription().getName().toLowerCase() + "-island-level-top-name-#'"); - level.log("by 'Level_" + gm.getDescription().getName().toLowerCase() + "_top_name_#'"); Collection values = level.getTopTen().getTopTenList(gm.getOverWorld()).getTopTen().keySet(); return values.size() < i ? "" : level.getPlayers().getName(values.stream().skip(i).findFirst().orElse(null)); } diff --git a/src/main/java/world/bentobox/level/placeholders/TopTenPlaceholder.java b/src/main/java/world/bentobox/level/placeholders/TopTenPlaceholder.java index 7fbd9b6..f96c9be 100644 --- a/src/main/java/world/bentobox/level/placeholders/TopTenPlaceholder.java +++ b/src/main/java/world/bentobox/level/placeholders/TopTenPlaceholder.java @@ -30,9 +30,6 @@ public class TopTenPlaceholder implements PlaceholderReplacer { */ @Override public String onReplace(User user) { - level.logWarning("You are using a deprecated placeholder."); - level.log("Please replace any occurrence of 'Level_" + gm.getDescription().getName().toLowerCase() + "-island-level-top-value-#'"); - level.log("by 'Level_" + gm.getDescription().getName().toLowerCase() + "_top_value_#'"); Collection values = level.getTopTen().getTopTenList(gm.getOverWorld()).getTopTen().values(); return values.size() < i ? "" : values.stream().skip(i).findFirst().map(String::valueOf).orElse(""); } From 1791108ef650b05e0d04bf5c02615b9246e3f915 Mon Sep 17 00:00:00 2001 From: tastybento Date: Fri, 10 Jan 2020 14:01:56 -0800 Subject: [PATCH 08/18] Removed invalid javadoc character --- src/main/java/world/bentobox/level/LevelPresenter.java | 2 +- src/main/java/world/bentobox/level/config/Settings.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/world/bentobox/level/LevelPresenter.java b/src/main/java/world/bentobox/level/LevelPresenter.java index c4a5bd3..4c3c304 100644 --- a/src/main/java/world/bentobox/level/LevelPresenter.java +++ b/src/main/java/world/bentobox/level/LevelPresenter.java @@ -82,7 +82,7 @@ public class LevelPresenter { } /** - * Get the string representation of the level. May be converted to shorthand notation, e.g., 104556 -> 10.5k + * Get the string representation of the level. May be converted to shorthand notation, e.g., 104556 = 10.5k * @param lvl - long value to represent * @return string of the level. */ diff --git a/src/main/java/world/bentobox/level/config/Settings.java b/src/main/java/world/bentobox/level/config/Settings.java index 4bd5a4c..979bd8e 100644 --- a/src/main/java/world/bentobox/level/config/Settings.java +++ b/src/main/java/world/bentobox/level/config/Settings.java @@ -215,7 +215,7 @@ public class Settings { } /** - * @return true if levels should be shown in shorthand notation, e.g., 10,234 -> 10k + * @return true if levels should be shown in shorthand notation, e.g., 10,234 = 10k */ public boolean isShortHand() { return level.getConfig().getBoolean("shorthand"); From 187e491bea6dd8498c1f91df7827223859c95565 Mon Sep 17 00:00:00 2001 From: tastybento Date: Fri, 10 Jan 2020 14:05:00 -0800 Subject: [PATCH 09/18] Updated to BentoBox 1.11.0 API Fixes https://github.com/BentoBoxWorld/Level/issues/117 --- pom.xml | 8 +++++--- .../world/bentobox/level/calculators/PlayerLevel.java | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index f8d0db7..59cbd94 100644 --- a/pom.xml +++ b/pom.xml @@ -59,13 +59,13 @@ 2.0.2 1.14.4-R0.1-SNAPSHOT - 1.9.0-SNAPSHOT + 1.11.0-SNAPSHOT ${build.version}-SNAPSHOT -LOCAL - 1.9.1 + 1.9.2 @@ -242,9 +242,11 @@ maven-javadoc-plugin 3.0.1 - public + private false -Xdoclint:none + ${java.home}/bin/javadoc + 8 diff --git a/src/main/java/world/bentobox/level/calculators/PlayerLevel.java b/src/main/java/world/bentobox/level/calculators/PlayerLevel.java index 90e3f3f..00d3e60 100644 --- a/src/main/java/world/bentobox/level/calculators/PlayerLevel.java +++ b/src/main/java/world/bentobox/level/calculators/PlayerLevel.java @@ -66,7 +66,7 @@ public class PlayerLevel { keyValues.put("pointsToNextLevel", calc.getResult().getPointsToNextLevel()); keyValues.put("deathHandicap", calc.getResult().getDeathHandicap()); keyValues.put("initialLevel", calc.getResult().getInitialLevel()); - addon.getServer().getPluginManager().callEvent(new AddonEvent().builder().addon(addon).keyValues(keyValues).build()); + AddonEvent.builder().addon(addon).keyValues(keyValues).build(); Results results = ilce.getResults(); // Save the results island.getMemberSet().forEach(m -> addon.setIslandLevel(world, m, results.getLevel())); From d8b838cc36ba9398d8ec173fd11aea69dea11b6a Mon Sep 17 00:00:00 2001 From: tastybento Date: Fri, 10 Jan 2020 16:22:44 -0800 Subject: [PATCH 10/18] Makes result of the IslandLevelCalculatedEvent easier for plugins to get https://github.com/BentoBoxWorld/Level/issues/118 --- pom.xml | 2 +- .../event/IslandLevelCalculatedEvent.java | 40 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 59cbd94..89e9be4 100644 --- a/pom.xml +++ b/pom.xml @@ -65,7 +65,7 @@ -LOCAL - 1.9.2 + 1.9.3 diff --git a/src/main/java/world/bentobox/level/event/IslandLevelCalculatedEvent.java b/src/main/java/world/bentobox/level/event/IslandLevelCalculatedEvent.java index 73a9ed8..391c6bf 100644 --- a/src/main/java/world/bentobox/level/event/IslandLevelCalculatedEvent.java +++ b/src/main/java/world/bentobox/level/event/IslandLevelCalculatedEvent.java @@ -1,5 +1,6 @@ package world.bentobox.level.event; +import java.util.List; import java.util.UUID; import world.bentobox.bentobox.api.events.IslandBaseEvent; @@ -29,11 +30,49 @@ public class IslandLevelCalculatedEvent extends IslandBaseEvent { } /** + * Do NOT get this result if you are not a BentoBox addon! * @return the results */ public Results getResults() { return results; } + + /** + * @return death handicap value + */ + public int getDeathHandicap() { + return results.getDeathHandicap(); + } + + /** + * Get the island's initial level. It may be zero if it was never calculated + * or if a player was registered to the island after it was made. + * @return initial level of island as calculated when the island was created. + */ + public long getInitialLevel() { + return results.getInitialLevel(); + } + + /** + * @return the level calculated + */ + public long getLevel() { + return results.getLevel(); + } + + /** + * @return number of points required to next level + */ + public long getPointsToNextLevel() { + return results.getPointsToNextLevel(); + } + + /** + * @return a human readable report explaining how the calculation was made + */ + public List getReport() { + return results.getReport(); + } /** * @return the targetPlayer @@ -42,6 +81,7 @@ public class IslandLevelCalculatedEvent extends IslandBaseEvent { return targetPlayer; } /** + * Do not use this if you are not a BentoBox addon * @param results the results to set */ public void setResults(Results results) { From c06e69e1b5446c40d184a229e2f106ed9046c6b6 Mon Sep 17 00:00:00 2001 From: "gitlocalize-app[bot]" <55277160+gitlocalize-app[bot]@users.noreply.github.com> Date: Fri, 10 Jan 2020 16:27:57 -0800 Subject: [PATCH 11/18] Translate lv.yml via GitLocalize (#116) Co-authored-by: BONNe --- src/main/resources/locales/lv.yml | 44 +++++++++++++++---------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/src/main/resources/locales/lv.yml b/src/main/resources/locales/lv.yml index 08b3621..9e0863d 100644 --- a/src/main/resources/locales/lv.yml +++ b/src/main/resources/locales/lv.yml @@ -1,37 +1,35 @@ -########################################################################################### -# This is a YML file. Be careful when editing. Check your edits in a YAML checker like # -# the one at http://yaml-online-parser.appspot.com # -########################################################################################### - +--- admin: level: + description: aprēķina spēlētāja salas līmeni parameters: "" - description: "aprēķina spēlētāja salas līmeni" top: - description: "rādīt labākās 10 salas" - unknown-world: "&cNezināma pasaule!" + description: rādīt labākās 10 salas display: "&f[rank]. &a[name] &7- &b[level]" - + unknown-world: "&cNezināma pasaule!" + remove: + description: noņemt spēlētāju no labāko desmit saraksta + parameters: "" island: - level: - parameters: "[player]" - description: "aprēķina tavas salas līmeni, vai parāda spēlētāja [player] līmeni" - calculating: "&aAprēķina līmeni..." - island-level-is: "&aSalas līmenis ir &b[level]" - required-points-to-next-level: "&aNepieciešami [points] punkti, lai sasniegtu nākošo līmeni" + level: + calculating: "&aAprēķina līmeni..." + cooldown: "&cTev ir jāuzgaida &b[time]&c sekundes, lai vēlreiz aprēķinātu salas + līmeni!" deaths: "&c([number] nāves)" - cooldown: "&cTev ir jāuzgaida &b[time]&c sekundes, lai vēlreiz aprēķinātu salas līmeni!" - + description: aprēķina tavas salas līmeni, vai parāda spēlētāja [player] līmeni + island-level-is: "&aSalas līmenis ir &b[level]" + parameters: "[player]" + required-points-to-next-level: "&aNepieciešami [points] punkti, lai sasniegtu + nākošo līmeni" top: - description: "rādīt labākos 10" - gui-title: "&aLabākie 10" + description: rādīt labākos 10 gui-heading: "&6[name]: &B[rank]" + gui-title: "&aLabākie 10" island-level: "&BLīmenis [level]" warp-to: "&APārvietoties uz [name] salu." - value: - description: "rādīt vērtību jebkuram blokam" - success: "&7Vērtība šim blokam ir: &e[value]" - success-underwater: "&7Vērtība šim blokam zem jūras līmeņa: &e[value]" + description: rādīt vērtību jebkuram blokam empty-hand: "&cTev nav bloks rokās." no-value: "&cŠim blokam/priekšmetam nav vērtības." + success: "&7Vērtība šim blokam ir: &e[value]" + success-underwater: "&7Vērtība šim blokam zem jūras līmeņa: &e[value]" From 4bf86bb07fa6dc376e3527d4c260c1ea5d121871 Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Sat, 11 Jan 2020 08:28:23 +0800 Subject: [PATCH 12/18] Updating zh-CN Localization (#114) * Sync zh-CN.yml with en-US.yml this translation file is too old. let's start over! * Translating zh-CN.yml --- src/main/resources/locales/zh-CN.yml | 38 ++++++++++++++++++---------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/src/main/resources/locales/zh-CN.yml b/src/main/resources/locales/zh-CN.yml index 47001af..00f291d 100755 --- a/src/main/resources/locales/zh-CN.yml +++ b/src/main/resources/locales/zh-CN.yml @@ -6,25 +6,35 @@ admin: level: parameters: "" - description: "计算玩家的岛屿等级" + description: "计算某玩家的岛屿等级" top: - description: "显示排名前十榜单" - unknown-world: "&c未知世界!" - + description: "显示前十名" + unknown-world: "&c未知世界!" + display: "&f[rank]. &a[name] &7- &b[level]" + remove: + description: "将玩家移出前十" + parameters: "" + island: level: parameters: "[player]" - description: "计算您的岛屿等级或显示 [player] 的岛屿等级" - calculating: "&a正在计算等级……" - island-level-is: "&a岛屿等级是 &b[level]" - required-points-to-next-level: "&a距离下一级还需要 [points] 点" - deaths: "&c([number] 次死亡)" - cooldown: "&c在您可以再次做这件事之前必须等待 &b[time] &c秒" + description: "计算你或玩家 [player] 的岛屿等级" + calculating: "&a计算等级中..." + island-level-is: "&a岛屿等级为 &b[level]" + required-points-to-next-level: "&a还需 [points] 才能升到下一级" + deaths: "&c([number] 次死亡)" + cooldown: "&c再等 &b[time] &c秒才能再次使用" top: - description: "显示排名前十榜单" - gui-title: "&a前十榜" + description: "显示前十名" + gui-title: "&a前十" gui-heading: "&6[name]: &B[rank]" island-level: "&B等级 [level]" - warp-to: "&A正在传送到 [name] 的岛屿" - \ No newline at end of file + warp-to: "&A正传送到 [name] 的岛屿" + + value: + description: "查看某方块的价值" + success: "&7本方块的价值: &e[value]" + success-underwater: "&7本方块的水下价值: &e[value]" + empty-hand: "&c你手里没有方块" + no-value: "&c这个东西一文不值." From ccc3ef65beb3c065e0715d416cd9ba5dba410552 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sat, 11 Jan 2020 09:12:59 -0800 Subject: [PATCH 13/18] Backwards compatibility restored. Fixes https://github.com/BentoBoxWorld/Level/issues/119 --- pom.xml | 2 +- src/main/java/world/bentobox/level/calculators/PlayerLevel.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 89e9be4..8915588 100644 --- a/pom.xml +++ b/pom.xml @@ -59,7 +59,7 @@ 2.0.2 1.14.4-R0.1-SNAPSHOT - 1.11.0-SNAPSHOT + 1.9.0 ${build.version}-SNAPSHOT diff --git a/src/main/java/world/bentobox/level/calculators/PlayerLevel.java b/src/main/java/world/bentobox/level/calculators/PlayerLevel.java index 00d3e60..87820f8 100644 --- a/src/main/java/world/bentobox/level/calculators/PlayerLevel.java +++ b/src/main/java/world/bentobox/level/calculators/PlayerLevel.java @@ -66,7 +66,7 @@ public class PlayerLevel { keyValues.put("pointsToNextLevel", calc.getResult().getPointsToNextLevel()); keyValues.put("deathHandicap", calc.getResult().getDeathHandicap()); keyValues.put("initialLevel", calc.getResult().getInitialLevel()); - AddonEvent.builder().addon(addon).keyValues(keyValues).build(); + new AddonEvent().builder().addon(addon).keyValues(keyValues).build(); Results results = ilce.getResults(); // Save the results island.getMemberSet().forEach(m -> addon.setIslandLevel(world, m, results.getLevel())); From fe0f084781cc5531ce7688c12219407551268976 Mon Sep 17 00:00:00 2001 From: tastybento Date: Thu, 16 Jan 2020 13:44:23 -0800 Subject: [PATCH 14/18] Adds performance tweaking settings to config.yml https://github.com/BentoBoxWorld/Level/issues/122 --- .../level/calculators/CalcIslandLevel.java | 27 +++++++----- .../world/bentobox/level/config/Settings.java | 43 +++++++++++++++++++ src/main/resources/config.yml | 9 ++++ 3 files changed, 69 insertions(+), 10 deletions(-) diff --git a/src/main/java/world/bentobox/level/calculators/CalcIslandLevel.java b/src/main/java/world/bentobox/level/calculators/CalcIslandLevel.java index e64b31d..b927e00 100644 --- a/src/main/java/world/bentobox/level/calculators/CalcIslandLevel.java +++ b/src/main/java/world/bentobox/level/calculators/CalcIslandLevel.java @@ -1,6 +1,15 @@ package world.bentobox.level.calculators; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import java.util.Set; +import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; @@ -92,17 +101,15 @@ public class CalcIslandLevel { total += chunksToScan.size(); } } - queueid = Bukkit.getScheduler().scheduleSyncRepeatingTask(addon.getPlugin(), new Runnable() { - public void run() { - for (int i = 0; i < 10; i++) { - if (q.size() == 0) { - return; - } - Chunk c = q.remove(); - getChunk(c); + queueid = Bukkit.getScheduler().scheduleSyncRepeatingTask(addon.getPlugin(), () -> { + for (int i = 0; i < addon.getSettings().getChunks(); i++) { + if (q.size() == 0) { + return; } + Chunk c = q.remove(); + getChunk(c); } - }, 1L, 1L); + }, addon.getSettings().getTickDelay(), addon.getSettings().getTickDelay()); chunksToScan.forEach(c -> worlds.forEach(w -> Util.getChunkAtAsync(w, c.x, c.z).thenAccept(this::addChunkQueue))); } diff --git a/src/main/java/world/bentobox/level/config/Settings.java b/src/main/java/world/bentobox/level/config/Settings.java index 979bd8e..9beeef9 100644 --- a/src/main/java/world/bentobox/level/config/Settings.java +++ b/src/main/java/world/bentobox/level/config/Settings.java @@ -23,6 +23,8 @@ public class Settings { private int deathpenalty; private long levelCost; private int levelWait; + private int chunks; + private long taskDelay; private List gameModes; @@ -33,9 +35,22 @@ public class Settings { // GameModes gameModes = level.getConfig().getStringList("game-modes"); + + // Performance + setTickDelay(level.getConfig().getLong("task-delay",1)); + if (taskDelay < 1L) { + level.logError("task-delay must be at least 1"); + setTickDelay(1L); + } + setChunks(level.getConfig().getInt("chunks", 10)); + if (chunks < 1) { + level.logError("chunks must be at least 1"); + setChunks(1); + } setLevelWait(level.getConfig().getInt("levelwait", 60)); if (getLevelWait() < 0) { + level.logError("levelwait must be at least 0"); setLevelWait(0); } setDeathpenalty(level.getConfig().getInt("deathpenalty", 0)); @@ -228,4 +243,32 @@ public class Settings { return level.getConfig().getString("level-calc", "blocks / level_cost"); } + /** + * @return the chunks + */ + public int getChunks() { + return chunks; + } + + /** + * @param chunks the chunks to set + */ + public void setChunks(int chunks) { + this.chunks = chunks; + } + + /** + * @return the tickDelay + */ + public long getTickDelay() { + return taskDelay; + } + + /** + * @param tickDelay the tickDelay to set + */ + public void setTickDelay(long tickDelay) { + this.taskDelay = tickDelay; + } + } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index ae1f500..ea1d5cb 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -9,6 +9,15 @@ game-modes: - CaveBlock #- SkyGrid +# Performance settings +# Level is very processor intensive, so these settings may need to be tweaked to optimize for your server +# Delay between each task that loads chunks for calulcating levels +# Increasing this will slow down level calculations but reduce average load +task-delay: 1 + +# Number of chunks that will be processed per task +chunks: 10 + # This file lists the values for various blocks that are used to calculate the # island level. Level = total of all blocks in island boundary / 100. # Players with the permission askyblock.island.multiplier.# will have their blocks From b6f4c15469244f5301627d91a14e7fe186ebe0c2 Mon Sep 17 00:00:00 2001 From: tastybento Date: Thu, 16 Jan 2020 13:45:32 -0800 Subject: [PATCH 15/18] Fixed typos --- src/main/resources/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index ea1d5cb..38764e6 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -10,8 +10,8 @@ game-modes: #- SkyGrid # Performance settings -# Level is very processor intensive, so these settings may need to be tweaked to optimize for your server -# Delay between each task that loads chunks for calulcating levels +# Level is very processor-intensive, so these settings may need to be tweaked to optimize for your server +# Delay between each task that loads chunks for calculating levels # Increasing this will slow down level calculations but reduce average load task-delay: 1 From 1de94afe7e35d4baab04c85249e80644624f82ef Mon Sep 17 00:00:00 2001 From: tastybento Date: Fri, 24 Jan 2020 17:06:30 -0800 Subject: [PATCH 16/18] Adds the ability to override the level in the IslandLevelCalculatedEvent https://github.com/BentoBoxWorld/Level/issues/125 --- .../bentobox/level/calculators/CalcIslandLevel.java | 2 +- .../level/event/IslandLevelCalculatedEvent.java | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/java/world/bentobox/level/calculators/CalcIslandLevel.java b/src/main/java/world/bentobox/level/calculators/CalcIslandLevel.java index b927e00..b3c396d 100644 --- a/src/main/java/world/bentobox/level/calculators/CalcIslandLevel.java +++ b/src/main/java/world/bentobox/level/calculators/CalcIslandLevel.java @@ -390,7 +390,7 @@ public class CalcIslandLevel { * Set level * @param level - level */ - public void setLevel(int level) { + public void setLevel(long level) { this.level.set(level); } /** diff --git a/src/main/java/world/bentobox/level/event/IslandLevelCalculatedEvent.java b/src/main/java/world/bentobox/level/event/IslandLevelCalculatedEvent.java index 391c6bf..8ae9e9e 100644 --- a/src/main/java/world/bentobox/level/event/IslandLevelCalculatedEvent.java +++ b/src/main/java/world/bentobox/level/event/IslandLevelCalculatedEvent.java @@ -60,13 +60,22 @@ public class IslandLevelCalculatedEvent extends IslandBaseEvent { return results.getLevel(); } + + /** + * Overwrite the level. This level will be used instead of the calculated level. + * @param level - the level to set + */ + public void setLevel(long level) { + results.setLevel(level); + } + /** * @return number of points required to next level */ public long getPointsToNextLevel() { return results.getPointsToNextLevel(); } - + /** * @return a human readable report explaining how the calculation was made */ @@ -95,5 +104,4 @@ public class IslandLevelCalculatedEvent extends IslandBaseEvent { this.targetPlayer = targetPlayer; } - } From f779f0ca958b08deb2f00915b710f348963c0cc3 Mon Sep 17 00:00:00 2001 From: Dalton Burchard <48583030+Burchard36@users.noreply.github.com> Date: Tue, 28 Jan 2020 08:32:52 -0800 Subject: [PATCH 17/18] Add support for Wild Stacker (#124) * Add support for Wild Stackers (Blocks Only) * Shorten my recent commit, modified checkBlock method slightly to not pass full BlockData; rather just the Material that is used in the method --- pom.xml | 11 ++++++ src/main/java/world/bentobox/level/Level.java | 8 +++++ .../level/calculators/CalcIslandLevel.java | 36 ++++++++++++++----- 3 files changed, 46 insertions(+), 9 deletions(-) diff --git a/pom.xml b/pom.xml index 8915588..9530fa4 100644 --- a/pom.xml +++ b/pom.xml @@ -147,6 +147,11 @@ codemc-public https://repo.codemc.org/repository/maven-public/ + + + jitpack.io + https://jitpack.io + @@ -182,6 +187,12 @@ ${bentobox.version} provided + + + com.github.OmerBenGera + WildStackerAPI + b17 + diff --git a/src/main/java/world/bentobox/level/Level.java b/src/main/java/world/bentobox/level/Level.java index 876a58d..c2ef35e 100644 --- a/src/main/java/world/bentobox/level/Level.java +++ b/src/main/java/world/bentobox/level/Level.java @@ -13,6 +13,7 @@ import world.bentobox.bentobox.api.addons.Addon; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.Database; import world.bentobox.bentobox.database.objects.Island; +import world.bentobox.level.calculators.CalcIslandLevel; import world.bentobox.level.commands.admin.AdminLevelCommand; import world.bentobox.level.commands.admin.AdminTopCommand; import world.bentobox.level.commands.island.IslandLevelCommand; @@ -199,6 +200,13 @@ public class Level extends Addon { registerRequestHandler(new LevelRequestHandler(this)); registerRequestHandler(new TopTenRequestHandler(this)); + // Check if WildStackers is enabled on the server + if (getPlugin().getServer().getPluginManager().getPlugin("WildStacker") != null) { + // I only added support for counting blocks into the island level + // Someone else can PR if they want spawners added to the Leveling system :) + CalcIslandLevel.stackersEnabled = true; + } else CalcIslandLevel.stackersEnabled = false; + // Done } diff --git a/src/main/java/world/bentobox/level/calculators/CalcIslandLevel.java b/src/main/java/world/bentobox/level/calculators/CalcIslandLevel.java index b3c396d..f21e1b6 100644 --- a/src/main/java/world/bentobox/level/calculators/CalcIslandLevel.java +++ b/src/main/java/world/bentobox/level/calculators/CalcIslandLevel.java @@ -13,12 +13,15 @@ import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; +import com.bgsoftware.wildstacker.api.WildStackerAPI; +import com.bgsoftware.wildstacker.api.objects.StackedBarrel; import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.ChunkSnapshot; import org.bukkit.Material; import org.bukkit.Tag; import org.bukkit.World; +import org.bukkit.block.Block; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.type.Slab; @@ -37,7 +40,8 @@ public class CalcIslandLevel { private static final String LINE_BREAK = "=================================="; - public static final long MAX_AMOUNT = 10000; + public static final long MAX_AMOUNT = 10000; + public static Boolean stackersEnabled; private final Level addon; @@ -122,7 +126,7 @@ public class CalcIslandLevel { ChunkSnapshot snapShot = ch.getChunkSnapshot(); Bukkit.getScheduler().runTaskAsynchronously(addon.getPlugin(), () -> { - this.scanChunk(snapShot); + this.scanChunk(snapShot, ch); count.getAndIncrement(); if (count.get() == total) { Bukkit.getScheduler().cancelTask(queueid); @@ -131,7 +135,7 @@ public class CalcIslandLevel { }); } - private void scanChunk(ChunkSnapshot chunk) { + private void scanChunk(ChunkSnapshot chunk, Chunk physicalChunk) { World chunkWorld = Bukkit.getWorld(chunk.getWorldName()); if (chunkWorld == null) return; int maxHeight = chunkWorld.getMaxHeight(); @@ -155,23 +159,37 @@ public class CalcIslandLevel { if (Tag.SLABS.isTagged(blockData.getMaterial())) { Slab slab = (Slab)blockData; if (slab.getType().equals(Slab.Type.DOUBLE)) { - checkBlock(blockData, belowSeaLevel); + checkBlock(blockData.getMaterial(), belowSeaLevel); } } - checkBlock(blockData, belowSeaLevel); + + // Hook for Wild Stackers (Blocks Only) + if (stackersEnabled && blockData.getMaterial() == Material.CAULDRON) { + Block cauldronBlock = physicalChunk.getBlock(x, y, z); + if (WildStackerAPI.getWildStacker().getSystemManager().isStackedBarrel(cauldronBlock)) { + StackedBarrel barrel = WildStackerAPI.getStackedBarrel(cauldronBlock); + int barrelAmt = WildStackerAPI.getBarrelAmount(cauldronBlock); + for (int _x = 0; _x < barrelAmt; _x++) { + checkBlock(barrel.getType(), belowSeaLevel); + } + } + } + + checkBlock(blockData.getMaterial(), belowSeaLevel); } } } } - private void checkBlock(BlockData bd, boolean belowSeaLevel) { - int count = limitCount(bd.getMaterial()); + // Didnt see a reason to pass BlockData when all that's used was the material + private void checkBlock(Material mat, boolean belowSeaLevel) { + int count = limitCount(mat); if (belowSeaLevel) { result.underWaterBlockCount.addAndGet(count); - result.uwCount.add(bd.getMaterial()); + result.uwCount.add(mat); } else { result.rawBlockCount.addAndGet(count); - result.mdCount.add(bd.getMaterial()); + result.mdCount.add(mat); } } From 21c47374463b03fe182184679bd0ea20cba289e4 Mon Sep 17 00:00:00 2001 From: tastybento Date: Thu, 30 Jan 2020 10:26:47 -0800 Subject: [PATCH 18/18] Czech translation. Credit @Polda18 --- src/main/resources/locales/cs.yml | 42 +++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/main/resources/locales/cs.yml diff --git a/src/main/resources/locales/cs.yml b/src/main/resources/locales/cs.yml new file mode 100644 index 0000000..ea66a57 --- /dev/null +++ b/src/main/resources/locales/cs.yml @@ -0,0 +1,42 @@ +########################################################################################### +# This is a YML file. Be careful when editing. Check your edits in a YAML checker like # +# the one at http://yaml-online-parser.appspot.com # +# # +# Translation by: CZghost # +########################################################################################### + +admin: + level: + parameters: "" + description: "vypočítat úroveň ostrova hráče" + top: + description: "ukázat seznam TOP 10" + unknown-world: "&cNeznámý svět!" + display: "&f[rank]. &a[name] &7- &b[level]" + remove: + description: "odstranit hráče z TOP 10" + parameters: "" + +island: + level: + parameters: "[player]" + description: "spočítat úroveň tvého ostrova nebo ostrova hráče [player]" + calculating: "&aPočítám úroveň..." + island-level-is: "&aÚroveň ostrova je &b[level]" + required-points-to-next-level: "&a[points] vyžadováno do další úrovně" + deaths: "&c([number] smrtí)" + cooldown: "&cMusíš čekat &b[time] &csekund, než můžeš příkaz znovu použít" + + top: + description: "ukázat TOP 10" + gui-title: "&aTOP 10" + gui-heading: "&6[name]: &B[rank]" + island-level: "&BÚroveň [level]" + warp-to: "&AWarp na ostrov [name]" + + value: + description: "ukáže hodnotu jakéhokoliv bloku" + success: "&7Hodnota tohoto bloku je: &e[value]" + success-underwater: "&7Hodnota tohoto bloku pod úrovní moře: &e[value]" + empty-hand: "&cNemáš v ruce žádný blok" + no-value: "&cTento předmět nemá žádnou hodnotu." \ No newline at end of file