Add IslandTop command with refresh cooldown (#1)
* Add IslandTop command with refresh cooldown The "IslandTop" command has been added. This provides a sorted list of top-performing islands. A configuration for refresh cooldown was also added. The sorted island list is updated once the specified minutes in the configuration have passed to improve performance. The ranking display for the player's island is highlighted in green text. * Update IslandTop command On plugin startup the IslandData is now loaded in. IslandData was moved to its own file and gets updated when a new island is created or when one levels up. The IslandData gets deleted when the owner leaves the island, destroying it.
This commit is contained in:
parent
d09e8567ac
commit
d1c8d29cde
|
|
@ -4,6 +4,7 @@ import com.alttd.cometskyblock.commands.challenges.ChallengeCommand;
|
|||
import com.alttd.cometskyblock.commands.island.IslandCommand;
|
||||
import com.alttd.cometskyblock.configuration.*;
|
||||
import com.alttd.cometskyblock.gui.GUIListener;
|
||||
import com.alttd.cometskyblock.island.IslandData;
|
||||
import com.alttd.cometskyblock.listeners.BedListener;
|
||||
import com.alttd.cometskyblock.listeners.CobbestoneGeneratorListener;
|
||||
import com.alttd.cometskyblock.listeners.PlayerJoinListener;
|
||||
|
|
@ -48,6 +49,9 @@ public class CometSkyBlockPlugin extends JavaPlugin implements CometSkyBlockAPI
|
|||
// Load event listeners
|
||||
loadEventListeners();
|
||||
|
||||
// Reload island data for top list
|
||||
IslandData.reloadAllIslandData();
|
||||
|
||||
// load data from storage
|
||||
|
||||
// run cleanup tasks
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ public class IslandCommand extends PlayerSubCommand {
|
|||
this.plugin = plugin;
|
||||
|
||||
registerSubCommand(new IslandGo(plugin)); // TODO -- Add some more output
|
||||
registerSubCommand(new IslandTop(plugin));
|
||||
registerSubCommand(new IslandRestart(plugin)); // TODO -- Add IslandRestartCommand
|
||||
registerSubCommand(new IslandAccept(plugin));
|
||||
registerSubCommand(new IslandDeny(plugin));
|
||||
|
|
|
|||
|
|
@ -2,19 +2,58 @@ package com.alttd.cometskyblock.commands.island;
|
|||
|
||||
import com.alttd.cometskyblock.CometSkyBlockPlugin;
|
||||
import com.alttd.cometskyblock.commands.PlayerSubCommand;
|
||||
import com.alttd.cometskyblock.configuration.PluginConfiguration;
|
||||
import com.alttd.cometskyblock.island.IslandData;
|
||||
import com.alttd.cometskyblock.island.IslandPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class IslandTop extends PlayerSubCommand {
|
||||
|
||||
private final PluginConfiguration pluginConfiguration;
|
||||
|
||||
public IslandTop(CometSkyBlockPlugin plugin) {
|
||||
super(plugin, "top");
|
||||
pluginConfiguration = plugin.pluginConfiguration().get();
|
||||
}
|
||||
// TODO - Finish TOP command
|
||||
|
||||
@Override
|
||||
public boolean execute(Player player, IslandPlayer islandPlayer, String[] args) {
|
||||
// TODO -- Implement
|
||||
player.sendRichMessage("<red>Not implemented yet, please wait for a future update.");
|
||||
int playerIslandId = islandPlayer.islandId();
|
||||
|
||||
//TODO allow players to iterate through the list
|
||||
List<IslandData> islandData = IslandData.getIslandData(pluginConfiguration.topRefreshMinutesCoolDown());
|
||||
String islandRankings = IntStream.range(0, 10)
|
||||
.mapToObj(i -> (i + 1) + ". " + islandData.get(i).format(playerIslandId))
|
||||
.collect(Collectors.joining("\n"));
|
||||
|
||||
islandRankings += getFormattedPlayerIslandRanking(islandData, playerIslandId, 0, 10);
|
||||
|
||||
player.sendRichMessage("<gold>Island Top:\n" + islandRankings);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the formatted ranking of a player's island based on their island ID.
|
||||
*
|
||||
* @param playerIslandId The ID of the player's island.
|
||||
* @return The formatted ranking of the player's island. Returns an empty string if the player's island is not ranked in the top 10.
|
||||
*/
|
||||
private String getFormattedPlayerIslandRanking(List<IslandData> islandDataList, int playerIslandId, int minPos, int maxPos) {
|
||||
OptionalInt position = IntStream.range(0, islandDataList.size())
|
||||
.filter(i -> playerIslandId == islandDataList.get(i).islandId())
|
||||
.findFirst();
|
||||
if (position.isPresent()) {
|
||||
int playerIslandPosition = position.getAsInt();
|
||||
if (playerIslandId < minPos || playerIslandPosition > maxPos) {
|
||||
IslandData islandData = islandDataList.get(playerIslandPosition);
|
||||
return "\n<green>" + playerIslandPosition + ". " + islandData.format() + "</green>";
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,5 +29,6 @@ public class PluginConfiguration implements Configuration {
|
|||
}
|
||||
|
||||
private int requestTimeOut = 30;
|
||||
private int topRefreshMinutesCoolDown = 10;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,10 @@ public class Island extends YamlConfiguration {
|
|||
}
|
||||
}
|
||||
|
||||
public static Island loadIslandFromFile(File file) {
|
||||
return new Island(file);
|
||||
}
|
||||
|
||||
public static void remove(UUID uuid) {
|
||||
synchronized (configs) {
|
||||
configs.remove(uuid);
|
||||
|
|
@ -54,6 +58,16 @@ public class Island extends YamlConfiguration {
|
|||
reload();
|
||||
}
|
||||
|
||||
private Island(File file) {
|
||||
this.islandUUID = Island.NILL_UUID;
|
||||
this.file = file;
|
||||
reload();
|
||||
}
|
||||
|
||||
public static Collection<Island> getIslands() {
|
||||
return configs.values();
|
||||
}
|
||||
|
||||
private void reload() {
|
||||
synchronized (saveLock) {
|
||||
try {
|
||||
|
|
@ -103,8 +117,9 @@ public class Island extends YamlConfiguration {
|
|||
return getInt("island.level", 0);
|
||||
}
|
||||
|
||||
public void level(int id) {
|
||||
set("island.level", id);
|
||||
public void level(int level) {
|
||||
IslandData.updateIsland(new IslandData(islandId(), islandName(), level));
|
||||
set("island.level", level);
|
||||
save();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
package com.alttd.cometskyblock.island;
|
||||
|
||||
import com.alttd.cometskyblock.CometSkyBlockPlugin;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public record IslandData(int islandId, String name, int level) {
|
||||
|
||||
private static final Int2ObjectOpenHashMap<IslandData> islandDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static List<IslandData> sortedIslandData = new ArrayList<>();
|
||||
private static Instant lastUpdated = Instant.MIN;
|
||||
|
||||
public synchronized static void updateIsland(IslandData islandData) {
|
||||
IslandData.islandDataMap.put(islandData.islandId, islandData);
|
||||
}
|
||||
|
||||
public synchronized static void removeIsland(int islandId) {
|
||||
IslandData.islandDataMap.remove(islandId);
|
||||
}
|
||||
|
||||
public static List<IslandData> getIslandData(int maxAgeMinutes) {
|
||||
updateIslandData(maxAgeMinutes);
|
||||
return IslandData.sortedIslandData;
|
||||
}
|
||||
|
||||
private static synchronized void updateIslandData(int maxAgeMinutes) {
|
||||
if (Duration.between(lastUpdated, Instant.now()).toMinutes() <= maxAgeMinutes)
|
||||
return;
|
||||
lastUpdated = Instant.now();
|
||||
sortedIslandData = islandDataMap.values().stream()
|
||||
.sorted(Comparator.comparingInt(IslandData::level).reversed())
|
||||
.toList();
|
||||
lastUpdated = Instant.now();
|
||||
}
|
||||
|
||||
public static synchronized void reloadAllIslandData() {
|
||||
Logger logger = CometSkyBlockPlugin.instance().getLogger();
|
||||
File islandDataDir = new File(CometSkyBlockPlugin.instance().getDataFolder(), "IslandData");
|
||||
if (!islandDataDir.isDirectory()) {
|
||||
logger.warning("No data folder found for IslandData, unable to load files");
|
||||
return;
|
||||
}
|
||||
islandDataMap.clear();
|
||||
try (Stream<Path> paths = Files.walk(islandDataDir.toPath(), 1)) {
|
||||
paths.filter(Files::isRegularFile)
|
||||
.filter(path -> path.toString().endsWith(".yml"))
|
||||
.map(Path::toFile)
|
||||
.map(Island::loadIslandFromFile)
|
||||
.map(island -> new IslandData(island.islandId(), island.islandName(), island.level()))
|
||||
.forEach(island -> islandDataMap.put(island.islandId, island));
|
||||
} catch (IOException e) {
|
||||
logger.severe("Encountered exception while reloading IslandData");
|
||||
logger.throwing(IslandData.class.getName(), "reloadAllIslandData", e);
|
||||
}
|
||||
}
|
||||
|
||||
public String format(int playerIslandId) {
|
||||
if (playerIslandId == islandId) {
|
||||
return "<green>" + format() + "</green>";
|
||||
} else {
|
||||
return format();
|
||||
}
|
||||
}
|
||||
|
||||
public String format() {
|
||||
return name + " - " + level;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package com.alttd.cometskyblock.request;
|
|||
|
||||
import com.alttd.cometskyblock.CometSkyBlockPlugin;
|
||||
import com.alttd.cometskyblock.island.Island;
|
||||
import com.alttd.cometskyblock.island.IslandData;
|
||||
import com.alttd.cometskyblock.island.IslandPlayer;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
|
|
@ -25,8 +26,10 @@ public class LeaveRequest extends Request {
|
|||
requester().sendRichMessage(requests().leave().accept(), placeholders());
|
||||
IslandPlayer islandPlayer = IslandPlayer.getIslandPlayer(requester().getUniqueId());
|
||||
Island island = Island.getIsland(islandPlayer.islandUUID());
|
||||
if (islandPlayer.islandOwner())
|
||||
if (islandPlayer.islandOwner()) {
|
||||
IslandData.removeIsland(island.islandId());
|
||||
island.owner(Island.NILL_UUID);
|
||||
}
|
||||
islandPlayer.islandId(0);
|
||||
islandPlayer.islandUUID(null);
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user