diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index d46f4e32e..2a86260b7 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -9,6 +9,7 @@ name: Java CI with Maven on: + workflow_dispatch: {} push: branches: [ "master" ] pull_request: diff --git a/API/src/main/java/dev/lrxh/api/NeptuneAPI.java b/API/src/main/java/dev/lrxh/api/NeptuneAPI.java index 321563d77..c85d5d8e5 100644 --- a/API/src/main/java/dev/lrxh/api/NeptuneAPI.java +++ b/API/src/main/java/dev/lrxh/api/NeptuneAPI.java @@ -5,6 +5,7 @@ import dev.lrxh.api.features.IDivisionService; import dev.lrxh.api.features.IItemBrowserService; import dev.lrxh.api.kit.IKitService; +import dev.lrxh.api.leaderboard.ILeaderboardService; import dev.lrxh.api.match.IMatchService; import dev.lrxh.api.profile.IProfileService; import dev.lrxh.api.scoreboard.IScoreboardService; @@ -25,4 +26,6 @@ public interface NeptuneAPI { ICosmeticService getCosmeticService(); IItemBrowserService getItemBrowserService(); -} \ No newline at end of file + + ILeaderboardService getLeaderboardService(); +} diff --git a/API/src/main/java/dev/lrxh/api/NeptuneAPIImpl.java b/API/src/main/java/dev/lrxh/api/NeptuneAPIImpl.java index 789e8af7c..3c0b217cf 100644 --- a/API/src/main/java/dev/lrxh/api/NeptuneAPIImpl.java +++ b/API/src/main/java/dev/lrxh/api/NeptuneAPIImpl.java @@ -5,6 +5,7 @@ import dev.lrxh.api.features.IDivisionService; import dev.lrxh.api.features.IItemBrowserService; import dev.lrxh.api.kit.IKitService; +import dev.lrxh.api.leaderboard.ILeaderboardService; import dev.lrxh.api.match.IMatchService; import dev.lrxh.api.profile.IProfileService; import dev.lrxh.api.scoreboard.IScoreboardService; @@ -22,4 +23,5 @@ public class NeptuneAPIImpl implements NeptuneAPI { private final IDivisionService divisionService; private final ICosmeticService cosmeticService; private final IItemBrowserService itemBrowserService; + private final ILeaderboardService leaderboardService; } diff --git a/API/src/main/java/dev/lrxh/api/arena/IArenaService.java b/API/src/main/java/dev/lrxh/api/arena/IArenaService.java index 36e09a051..07fc5e356 100644 --- a/API/src/main/java/dev/lrxh/api/arena/IArenaService.java +++ b/API/src/main/java/dev/lrxh/api/arena/IArenaService.java @@ -1,9 +1,14 @@ package dev.lrxh.api.arena; import java.util.LinkedHashSet; +import java.util.List; public interface IArenaService { LinkedHashSet getAllArenas(); IArena getArenaByName(String name); + + List getDuplicatesApi(IArena owner); + + IArena getFreeDuplicateApi(IArena owner); } diff --git a/API/src/main/java/dev/lrxh/api/kit/IKitService.java b/API/src/main/java/dev/lrxh/api/kit/IKitService.java index b6377d742..ae453ca9a 100644 --- a/API/src/main/java/dev/lrxh/api/kit/IKitService.java +++ b/API/src/main/java/dev/lrxh/api/kit/IKitService.java @@ -14,4 +14,6 @@ public interface IKitService { void removeArena(IArena arena); boolean addKit(IKit kit); + + void save(); } diff --git a/API/src/main/java/dev/lrxh/api/leaderboard/ILeaderboardEntry.java b/API/src/main/java/dev/lrxh/api/leaderboard/ILeaderboardEntry.java new file mode 100644 index 000000000..a52c64922 --- /dev/null +++ b/API/src/main/java/dev/lrxh/api/leaderboard/ILeaderboardEntry.java @@ -0,0 +1,11 @@ +package dev.lrxh.api.leaderboard; + +import java.util.UUID; + +public interface ILeaderboardEntry { + String getUsername(); + + UUID getUuid(); + + int getValue(); +} diff --git a/API/src/main/java/dev/lrxh/api/leaderboard/ILeaderboardService.java b/API/src/main/java/dev/lrxh/api/leaderboard/ILeaderboardService.java new file mode 100644 index 000000000..029c1f126 --- /dev/null +++ b/API/src/main/java/dev/lrxh/api/leaderboard/ILeaderboardService.java @@ -0,0 +1,17 @@ +package dev.lrxh.api.leaderboard; + +import dev.lrxh.api.kit.IKit; + +import java.util.List; +import java.util.UUID; + +public interface ILeaderboardService { + List getTopPlayers(IKit kit, ILeaderboardType type, int limit); + + int getPlayerRank(UUID playerUUID, IKit kit, ILeaderboardType type); + + /** + * The loading is asynchronous. + */ + void reload(); +} diff --git a/API/src/main/java/dev/lrxh/api/leaderboard/ILeaderboardType.java b/API/src/main/java/dev/lrxh/api/leaderboard/ILeaderboardType.java new file mode 100644 index 000000000..9578b63b7 --- /dev/null +++ b/API/src/main/java/dev/lrxh/api/leaderboard/ILeaderboardType.java @@ -0,0 +1,10 @@ +package dev.lrxh.api.leaderboard; + +public enum ILeaderboardType { + KILLS, + DEATHS, + WINS, + LOSSES, + BEST_WIN_STREAK, + ELO +} diff --git a/API/src/main/java/dev/lrxh/api/match/IMatch.java b/API/src/main/java/dev/lrxh/api/match/IMatch.java index 5aaeaf9c9..c35bd82e0 100644 --- a/API/src/main/java/dev/lrxh/api/match/IMatch.java +++ b/API/src/main/java/dev/lrxh/api/match/IMatch.java @@ -24,15 +24,21 @@ public interface IMatch { int getRounds(); + int getCurrentRound(); + boolean isDuel(); boolean isEnded(); IParticipant getParticipant(Player player); + IParticipant getParticipant(UUID playerUUID); + + boolean isSpectator(UUID playerUUID); + void broadcast(String message); String getWinnerName(); - + String getLoserName(); } diff --git a/API/src/main/java/dev/lrxh/api/match/IMatchService.java b/API/src/main/java/dev/lrxh/api/match/IMatchService.java index 5c7f33c99..850511d93 100644 --- a/API/src/main/java/dev/lrxh/api/match/IMatchService.java +++ b/API/src/main/java/dev/lrxh/api/match/IMatchService.java @@ -1,7 +1,25 @@ package dev.lrxh.api.match; +import dev.lrxh.api.kit.IKit; import org.bukkit.entity.Player; +import java.util.List; +import java.util.UUID; + public interface IMatchService { void startMatch(IMatch match, Player redPlayer, Player bluePlayer); + + void startFfaMatch(List players, IKit kit); + + void startTeamMatch(List redTeam, List blueTeam, IKit kit); + + void startDuelMatch(Player redPlayer, Player bluePlayer, IKit kit, boolean duel, int rounds); + + IMatch getMatchApi(Player player); + + IMatch getMatchApi(UUID playerUUID); + + List getActiveMatches(); + + void stopMatch(IMatch match); } diff --git a/API/src/main/java/dev/lrxh/api/profile/IProfile.java b/API/src/main/java/dev/lrxh/api/profile/IProfile.java index aef9d0230..63a36ba89 100644 --- a/API/src/main/java/dev/lrxh/api/profile/IProfile.java +++ b/API/src/main/java/dev/lrxh/api/profile/IProfile.java @@ -1,6 +1,7 @@ package dev.lrxh.api.profile; import dev.lrxh.api.data.IGameData; +import dev.lrxh.api.match.IMatch; import org.bukkit.entity.Player; import java.util.UUID; @@ -12,6 +13,8 @@ public interface IProfile { IGameData getGameData(); + IMatch getIMatch(); + void setState(String customState); String getProfileState(); @@ -23,4 +26,6 @@ public interface IProfile { void addCooldown(String name, int millis); boolean hasCooldownEnded(String name); + + void forfeit(); } diff --git a/API/src/main/java/dev/lrxh/api/profile/IProfileService.java b/API/src/main/java/dev/lrxh/api/profile/IProfileService.java index 5504985d1..bfab9e738 100644 --- a/API/src/main/java/dev/lrxh/api/profile/IProfileService.java +++ b/API/src/main/java/dev/lrxh/api/profile/IProfileService.java @@ -6,4 +6,8 @@ public interface IProfileService { CompletableFuture getProfile(UUID uuid); + + IProfile getCachedProfile(UUID uuid); + + boolean isLoaded(UUID uuid); } diff --git a/API/src/main/java/dev/lrxh/api/queue/IQueueService.java b/API/src/main/java/dev/lrxh/api/queue/IQueueService.java index fea457b39..ce328a583 100644 --- a/API/src/main/java/dev/lrxh/api/queue/IQueueService.java +++ b/API/src/main/java/dev/lrxh/api/queue/IQueueService.java @@ -1,6 +1,7 @@ package dev.lrxh.api.queue; import dev.lrxh.api.kit.IKit; +import org.bukkit.entity.Player; import java.util.Map; import java.util.Queue; @@ -14,4 +15,10 @@ public interface IQueueService { IQueueEntry remove(UUID playerUUID); IQueueEntry get(UUID playerUUID); + IQueueEntry get(UUID playerUUID, IKit kit); + + void addPlayerToQueue(Player player, IKit kit); + + boolean isInQueue(UUID playerUUID); + boolean isInQueue(UUID playerUUID, IKit kit); } diff --git a/Plugin/src/main/java/dev/lrxh/neptune/Neptune.java b/Plugin/src/main/java/dev/lrxh/neptune/Neptune.java index 179783f0f..17b294409 100644 --- a/Plugin/src/main/java/dev/lrxh/neptune/Neptune.java +++ b/Plugin/src/main/java/dev/lrxh/neptune/Neptune.java @@ -40,7 +40,6 @@ import dev.lrxh.neptune.feature.settings.command.SettingProvider; import dev.lrxh.neptune.feature.settings.command.SettingsCommand; import dev.lrxh.neptune.game.arena.Arena; -import dev.lrxh.neptune.game.arena.ArenaDuplicator; import dev.lrxh.neptune.game.arena.ArenaService; import com.fastasyncworldedit.core.configuration.Settings; import dev.lrxh.neptune.game.arena.command.ArenaProvider; @@ -120,7 +119,8 @@ private void initAPI() { getServer().getServicesManager().register( NeptuneAPI.class, new NeptuneAPIImpl(ProfileService.get(), MatchService.get(), KitService.get(), ScoreboardService.get(), - ArenaService.get(), DivisionService.get(), CosmeticService.get(), ItemBrowserService.get()), + ArenaService.get(), DivisionService.get(), CosmeticService.get(), ItemBrowserService.get(), + LeaderboardService.get()), this, ServicePriority.Normal); ServerUtils.info("Neptune API Initialized"); diff --git a/Plugin/src/main/java/dev/lrxh/neptune/commands/LeaveCommand.java b/Plugin/src/main/java/dev/lrxh/neptune/commands/LeaveCommand.java index d94f54a5f..0ae3e99cc 100644 --- a/Plugin/src/main/java/dev/lrxh/neptune/commands/LeaveCommand.java +++ b/Plugin/src/main/java/dev/lrxh/neptune/commands/LeaveCommand.java @@ -2,40 +2,15 @@ import com.jonahseguin.drink.annotation.Command; import com.jonahseguin.drink.annotation.Sender; -import dev.lrxh.api.events.PlayerLeaveEvent; import dev.lrxh.neptune.API; -import dev.lrxh.neptune.configs.impl.MessagesLocale; -import dev.lrxh.neptune.profile.data.ProfileState; import dev.lrxh.neptune.profile.impl.Profile; -import dev.lrxh.neptune.utils.PlayerUtil; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; public class LeaveCommand { @Command(name = "", desc = "") public void leave(@Sender Player player) { - Profile profile = API.getProfile(player.getUniqueId()); - ProfileState state = profile.getState(); - String previousStatus = profile.getProfileState(); - switch (state) { - case IN_SPECTATOR: - profile.getMatch().removeSpectator(player.getUniqueId(), true); - return; - case IN_GAME: - profile.getMatch().onLeave(profile.getMatch().getParticipant(player.getUniqueId()), false); - MessagesLocale.MATCH_FORFEIT.send(player); - return; - case IN_CUSTOM: - PlayerUtil.reset(player); - profile.setState(ProfileState.IN_LOBBY); - PlayerUtil.teleportToSpawn(player.getUniqueId()); - return; - default: - break; - } - PlayerLeaveEvent event = new PlayerLeaveEvent(profile, previousStatus); - Bukkit.getPluginManager().callEvent(event); - PlayerUtil.teleportToSpawn(player.getUniqueId()); + Profile profile = API.getProfile(player); + profile.forfeit(); } } diff --git a/Plugin/src/main/java/dev/lrxh/neptune/feature/hotbar/impl/ItemAction.java b/Plugin/src/main/java/dev/lrxh/neptune/feature/hotbar/impl/ItemAction.java index 31c0602fb..9d8a9f137 100644 --- a/Plugin/src/main/java/dev/lrxh/neptune/feature/hotbar/impl/ItemAction.java +++ b/Plugin/src/main/java/dev/lrxh/neptune/feature/hotbar/impl/ItemAction.java @@ -196,11 +196,15 @@ public void execute(Player player) { DuelRequest duelRequest = new DuelRequest(profile.getPlayerUUID(), match.getKit(), arena, false, match.getRounds()); Player opponent = match.getParticipant(player).getOpponent().getPlayer(); - if (opponent == null) + if (opponent == null) { + arena.remove(); return; + } Profile opponentProfile = API.getProfile(opponent); - if (opponentProfile == null) + if (opponentProfile == null) { + arena.remove(); return; + } opponentProfile.sendRequest(duelRequest, true); }); } diff --git a/Plugin/src/main/java/dev/lrxh/neptune/feature/leaderboard/LeaderboardService.java b/Plugin/src/main/java/dev/lrxh/neptune/feature/leaderboard/LeaderboardService.java index d40babdfb..887744fbd 100644 --- a/Plugin/src/main/java/dev/lrxh/neptune/feature/leaderboard/LeaderboardService.java +++ b/Plugin/src/main/java/dev/lrxh/neptune/feature/leaderboard/LeaderboardService.java @@ -1,5 +1,9 @@ package dev.lrxh.neptune.feature.leaderboard; +import dev.lrxh.api.kit.IKit; +import dev.lrxh.api.leaderboard.ILeaderboardEntry; +import dev.lrxh.api.leaderboard.ILeaderboardService; +import dev.lrxh.api.leaderboard.ILeaderboardType; import dev.lrxh.neptune.API; import dev.lrxh.neptune.configs.impl.SettingsLocale; import dev.lrxh.neptune.feature.divisions.DivisionService; @@ -12,23 +16,25 @@ import dev.lrxh.neptune.providers.database.DatabaseService; import dev.lrxh.neptune.providers.database.impl.DataDocument; import dev.lrxh.neptune.utils.ServerUtils; -import lombok.Getter; import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; -@Getter -public class LeaderboardService { +public class LeaderboardService implements ILeaderboardService { private static LeaderboardService instance; public final Pattern PATTERN = Pattern.compile("(KILLS|BEST_WIN_STREAK|DEATHS|ELO)_(.*)_(\\d+)_(name|value)"); private final int MAX_ENTRIES = SettingsLocale.LEADERBOARD_MAX_POSITIONS.getInt(); - private final Comparator BY_VALUE_DESC = - Comparator.comparingInt(PlayerEntry::value).reversed(); + private final Comparator BY_VALUE_DESC = Comparator.comparingInt(PlayerEntry::value).reversed(); private final List changes; private final Map>> leaderboards; @@ -38,8 +44,7 @@ public LeaderboardService() { } public static LeaderboardService get() { - if (instance == null) - instance = new LeaderboardService(); + if (instance == null) instance = new LeaderboardService(); return instance; } @@ -49,19 +54,16 @@ public String getPlaceholder(String placeholder) { String type = matcher.group(1); String kitName = matcher.group(2); int entry = Integer.parseInt(matcher.group(3)); - if (entry < 1 || entry > MAX_ENTRIES) - return placeholder; + if (entry < 1 || entry > MAX_ENTRIES) return placeholder; boolean name = matcher.group(4).equals("name"); Kit kit = KitService.get().getKitByName(kitName); - if (kit == null) - return placeholder; + if (kit == null) return placeholder; LeaderboardType leaderboardType = LeaderboardType.value(type); PlayerEntry playerEntry = getLeaderboardSlot(kit, leaderboardType, entry); - if (playerEntry == null) - return "???"; + if (playerEntry == null) return "???"; return name ? playerEntry.username() : String.valueOf(playerEntry.value()); } return placeholder; @@ -81,19 +83,16 @@ private void checkIfMissing() { public PlayerEntry getLeaderboardSlot(Kit kit, LeaderboardType leaderboardType, int i) { List playerEntries = getPlayerEntries(kit, leaderboardType); - if (i <= 0 || i > playerEntries.size()) - return null; + if (i <= 0 || i > playerEntries.size()) return null; return playerEntries.get(i - 1); } public List getPlayerEntries(Kit kit, LeaderboardType leaderboardType) { Map> kitLeaderboards = leaderboards.get(kit); - if (kitLeaderboards == null) - return Collections.emptyList(); + if (kitLeaderboards == null) return Collections.emptyList(); List entries = kitLeaderboards.get(leaderboardType); - if (entries == null) - return Collections.emptyList(); + if (entries == null) return Collections.emptyList(); List sortedEntries = new ArrayList<>(entries); sortedEntries.sort(BY_VALUE_DESC); @@ -104,40 +103,29 @@ public CompletableFuture load() { checkIfMissing(); for (Map> kitMap : leaderboards.values()) { - for (List entries : kitMap.values()) { - entries.clear(); - } + for (List entries : kitMap.values()) entries.clear(); } List> futures = new ArrayList<>(); - for (LeaderboardType type : LeaderboardType.values()) { - futures.add(loadType(type)); - } + for (LeaderboardType type : LeaderboardType.values()) futures.add(loadType(type)); return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); } private CompletableFuture loadType(LeaderboardType leaderboardType) { return CompletableFuture.runAsync(() -> { for (Kit kit : KitService.get().getKits()) { - DatabaseService.get().getDatabase().getAllByKitType(kit.getName(), leaderboardType.getDatabaseName()) + DatabaseService.get().getDatabase() + .getAllByKitType(kit.getName(), leaderboardType.getDatabaseName()) .thenAccept(documents -> { List tempEntries = new ArrayList<>(); - for (DataDocument document : documents) { String username = document.getString("username"); UUID uuid = UUID.fromString(document.getString("uuid")); - KitData kitData = parseKitData(document, kit); - - if (kitData == null) - continue; - - PlayerEntry playerEntry = new PlayerEntry(username, uuid, leaderboardType.get(kitData)); - tempEntries.add(playerEntry); + if (kitData == null) continue; + tempEntries.add(new PlayerEntry(username, uuid, leaderboardType.get(kitData))); } - tempEntries.sort(BY_VALUE_DESC); - Map> kitLeaderboards = leaderboards.get(kit); if (kitLeaderboards != null) { List currentEntries = kitLeaderboards.get(leaderboardType); @@ -154,18 +142,15 @@ private CompletableFuture loadType(LeaderboardType leaderboardType) { } public CompletableFuture update() { - if (changes.isEmpty()) - return CompletableFuture.completedFuture(null); + if (changes.isEmpty()) return CompletableFuture.completedFuture(null); checkIfMissing(); List copy = new ArrayList<>(changes); changes.clear(); List> futures = new ArrayList<>(); - for (LeaderboardPlayerEntry leaderboardPlayerEntry : copy) { - for (LeaderboardType type : LeaderboardType.values()) { - futures.add(loadLB(type, leaderboardPlayerEntry)); - } + for (LeaderboardPlayerEntry e : copy) { + for (LeaderboardType type : LeaderboardType.values()) futures.add(loadLB(type, e)); } return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); } @@ -173,20 +158,13 @@ public CompletableFuture update() { private void addOrUpdatePlayerEntry(Kit kit, PlayerEntry newEntry, LeaderboardType leaderboardType) { synchronized (leaderboards) { Map> kitLeaderboards = leaderboards.get(kit); - if (kitLeaderboards == null) - return; + if (kitLeaderboards == null) return; List entries = kitLeaderboards.computeIfAbsent(leaderboardType, k -> new ArrayList<>()); - entries.removeIf(e -> e.uuid().equals(newEntry.uuid())); - entries.add(newEntry); - entries.sort(BY_VALUE_DESC); - - if (entries.size() > MAX_ENTRIES) { - entries.subList(MAX_ENTRIES, entries.size()).clear(); - } + if (entries.size() > MAX_ENTRIES) entries.subList(MAX_ENTRIES, entries.size()).clear(); } } @@ -201,25 +179,17 @@ private CompletableFuture loadLB(LeaderboardType leaderboardType, String username = leaderboardPlayerEntry.username(); return getKitData(playerUUID, kit).thenAccept(kitData -> { - if (kitData == null) - return; - - PlayerEntry playerEntry = new PlayerEntry(username, playerUUID, leaderboardType.get(kitData)); - addOrUpdatePlayerEntry(kit, playerEntry, leaderboardType); + if (kitData == null) return; + addOrUpdatePlayerEntry(kit, new PlayerEntry(username, playerUUID, leaderboardType.get(kitData)), leaderboardType); }); } private KitData parseKitData(DataDocument document, Kit kit) { - if (document == null) - return null; - + if (document == null) return null; DataDocument kitStatistics = document.getDataDocument("kitData"); - if (kitStatistics == null) - return null; - + if (kitStatistics == null) return null; DataDocument kitDocument = kitStatistics.getDataDocument(kit.getName()); - if (kitDocument == null) - return null; + if (kitDocument == null) return null; KitData kitData = new KitData(); kitData.setCurrentStreak(kitDocument.getInteger("WIN_STREAK_CURRENT", 0)); @@ -229,7 +199,6 @@ private KitData parseKitData(DataDocument document, Kit kit) { kitData.setDeaths(kitDocument.getInteger("DEATHS", 0)); kitData.setDivision(DivisionService.get().getDivisionByElo(kitData.getWins())); kitData.setBestStreak(kitDocument.getInteger("WIN_STREAK_BEST", 0)); - return kitData; } @@ -239,8 +208,47 @@ private CompletableFuture getKitData(UUID playerUUID, Kit kit) { return CompletableFuture.completedFuture( API.getProfile(player).getGameData().get(kit)); } - return DatabaseService.get().getDatabase().getUserData(playerUUID) .thenApply(document -> parseKitData(document, kit)); } -} \ No newline at end of file + + @Override + public List getTopPlayers(IKit kit, ILeaderboardType type, int limit) { + if (kit == null || type == null) return new ArrayList<>(); + Kit implKit = KitService.get().getKitByName(kit.getName()); + LeaderboardType implType = LeaderboardType.value(type.name()); + if (implKit == null || implType == null) return new ArrayList<>(); + + List entries = getPlayerEntries(implKit, implType); + List result = new ArrayList<>(); + int count = Math.min(limit, entries.size()); + for (int i = 0; i < count; i++) { + PlayerEntry e = entries.get(i); + result.add(new ILeaderboardEntry() { + public String getUsername() { return e.username(); } + public UUID getUuid() { return e.uuid(); } + public int getValue() { return e.value(); } + }); + } + return result; + } + + @Override + public int getPlayerRank(UUID playerUUID, IKit kit, ILeaderboardType type) { + if (kit == null || type == null) return -1; + Kit implKit = KitService.get().getKitByName(kit.getName()); + LeaderboardType implType = LeaderboardType.value(type.name()); + if (implKit == null || implType == null) return -1; + + List entries = getPlayerEntries(implKit, implType); + for (int i = 0; i < entries.size(); i++) { + if (entries.get(i).uuid().equals(playerUUID)) return i + 1; + } + return -1; + } + + @Override + public void reload() { + load(); + } +} diff --git a/Plugin/src/main/java/dev/lrxh/neptune/feature/queue/QueueService.java b/Plugin/src/main/java/dev/lrxh/neptune/feature/queue/QueueService.java index f3adc31ec..810ca54c0 100644 --- a/Plugin/src/main/java/dev/lrxh/neptune/feature/queue/QueueService.java +++ b/Plugin/src/main/java/dev/lrxh/neptune/feature/queue/QueueService.java @@ -8,6 +8,7 @@ import dev.lrxh.neptune.Neptune; import dev.lrxh.neptune.configs.impl.MessagesLocale; import dev.lrxh.neptune.game.kit.Kit; +import dev.lrxh.neptune.game.kit.KitService; import dev.lrxh.neptune.game.kit.impl.KitRule; import dev.lrxh.neptune.profile.data.ProfileState; import dev.lrxh.neptune.profile.impl.Profile; @@ -15,6 +16,7 @@ import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.bukkit.Bukkit; +import org.bukkit.entity.Player; import java.util.*; import java.util.concurrent.ConcurrentLinkedQueue; @@ -42,7 +44,7 @@ public void add(QueueEntry queueEntry, boolean add) { if (profile.getGameData().getParty() != null) return; if (queueEntry.getKit().is(KitRule.HIDDEN)) return; - kitQueues.computeIfAbsent(kit, k -> new ConcurrentLinkedQueue<>()).offer(queueEntry); + kitQueues.computeIfAbsent(kit, _ -> new ConcurrentLinkedQueue<>()).offer(queueEntry); if (!profile.hasState(ProfileState.IN_QUEUE)) profile.setState(ProfileState.IN_QUEUE); kit.addQueue(); @@ -57,6 +59,22 @@ public void add(QueueEntry queueEntry, boolean add) { } } + @Override + public void addPlayerToQueue(Player player, IKit kit) { + Kit implKit = KitService.get().getKitByName(kit.getName()); + if (implKit == null) return; + add(new QueueEntry(implKit, player.getUniqueId()), true); + } + + @Override + public boolean isInQueue(UUID playerUUID) { + return get(playerUUID) != null; + } + @Override + public boolean isInQueue(UUID playerUUID, IKit kit) { + return get(playerUUID, kit) != null; + } + public QueueEntry remove(UUID playerUUID) { QueueEntry entry = get(playerUUID); if (entry == null) return null; @@ -91,6 +109,17 @@ public QueueEntry get(UUID uuid) { } return null; } + public QueueEntry get(UUID uuid, IKit kit) { + if (kit == null) return null; + Kit implKit = KitService.get().getKitByName(kit.getName()); + if (implKit == null) return null; + Queue queue = kitQueues.get(implKit); + if (queue == null) return null; + for (QueueEntry entry : queue) { + if (entry.getUuid().equals(uuid)) return entry; + } + return null; + } public int getQueueSize() { return QueueService.get().getAllQueues().values().stream() diff --git a/Plugin/src/main/java/dev/lrxh/neptune/game/arena/ArenaService.java b/Plugin/src/main/java/dev/lrxh/neptune/game/arena/ArenaService.java index bd15402a3..689132a47 100644 --- a/Plugin/src/main/java/dev/lrxh/neptune/game/arena/ArenaService.java +++ b/Plugin/src/main/java/dev/lrxh/neptune/game/arena/ArenaService.java @@ -64,6 +64,11 @@ public List getDuplicates(IArena owner) { return result; } + @Override + public List getDuplicatesApi(IArena owner) { + return new ArrayList<>(getDuplicates(owner)); + } + public Arena getFreeDuplicate(IArena owner) { for (Arena dup : duplicates) { if (dup.getOwner() != null && dup.getOwner().getName().equalsIgnoreCase(owner.getName()) @@ -74,6 +79,11 @@ public Arena getFreeDuplicate(IArena owner) { return null; } + @Override + public IArena getFreeDuplicateApi(IArena owner) { + return getFreeDuplicate(owner); + } + public int gridDistance() { return SettingsLocale.DUPLICATE_DISTANCE.getInt(); } diff --git a/Plugin/src/main/java/dev/lrxh/neptune/game/duel/DuelRequest.java b/Plugin/src/main/java/dev/lrxh/neptune/game/duel/DuelRequest.java index 1c329009a..c34483f9a 100644 --- a/Plugin/src/main/java/dev/lrxh/neptune/game/duel/DuelRequest.java +++ b/Plugin/src/main/java/dev/lrxh/neptune/game/duel/DuelRequest.java @@ -50,8 +50,10 @@ public void normalDuel(UUID receiver) { Player sender = Bukkit.getPlayer(getSender()); Player reciverPlayer = Bukkit.getPlayer(receiver); - if (reciverPlayer == null || sender == null) + if (reciverPlayer == null || sender == null) { + if (arena != null) arena.remove(); return; + } Participant participant1 = new Participant(sender); @@ -108,6 +110,7 @@ public void partyDuel(UUID receiver) { participant.sendMessage( CC.error("Arena wasn't setup up properly! Please contact an admin if you see this.")); } + arena.remove(); return; } diff --git a/Plugin/src/main/java/dev/lrxh/neptune/game/duel/command/DuelCommand.java b/Plugin/src/main/java/dev/lrxh/neptune/game/duel/command/DuelCommand.java index 2d3e28f2e..5bee17fec 100644 --- a/Plugin/src/main/java/dev/lrxh/neptune/game/duel/command/DuelCommand.java +++ b/Plugin/src/main/java/dev/lrxh/neptune/game/duel/command/DuelCommand.java @@ -114,6 +114,10 @@ public void duel(@Sender Player player, Player target, Kit kit, int rounds) { && targetProfile.getState().equals(ProfileState.IN_PARTY); kit.getRandomArena().thenAccept(arena -> { + if (arena == null) { + MessagesLocale.QUEUE_NO_ARENAS.send(player.getUniqueId()); + return; + } DuelRequest duelRequest = new DuelRequest(player.getUniqueId(), kit, arena, party, rounds); targetProfile.sendRequest(duelRequest, false); }); diff --git a/Plugin/src/main/java/dev/lrxh/neptune/game/kit/Kit.java b/Plugin/src/main/java/dev/lrxh/neptune/game/kit/Kit.java index d73ab161f..9a4a4d7ea 100644 --- a/Plugin/src/main/java/dev/lrxh/neptune/game/kit/Kit.java +++ b/Plugin/src/main/java/dev/lrxh/neptune/game/kit/Kit.java @@ -161,7 +161,7 @@ private static int defaultRounds(boolean legacyBestOfThree) { } public static int clampRounds(int r) { - return Math.max(1, Math.min(9, r)); + return Math.clamp(r, 1, 9); } private HashMap rules() { @@ -257,6 +257,9 @@ public void removePlaying() { playing--; } } + public void removePlaying(int num) { + playing = Math.max(0, playing - num); + } @Override public HashMap getRule() { @@ -341,6 +344,9 @@ public void giveLoadout(Participant participant) { public void addPlaying() { playing++; } + public void addPlaying(int num) { + playing += num; + } public void delete() { KitService.get().kits.remove(this); diff --git a/Plugin/src/main/java/dev/lrxh/neptune/game/match/Match.java b/Plugin/src/main/java/dev/lrxh/neptune/game/match/Match.java index 91f230b4d..4c8877f8c 100644 --- a/Plugin/src/main/java/dev/lrxh/neptune/game/match/Match.java +++ b/Plugin/src/main/java/dev/lrxh/neptune/game/match/Match.java @@ -103,62 +103,14 @@ public Participant getParticipant(Player player) { return getParticipant(player.getUniqueId()); } - public void sendTitle(TextComponent header, TextComponent footer, int duration) { - forEachParticipant(participant -> PlayerUtil.sendTitle(participant.getPlayer(), header, footer, duration)); - } - - public void sendMessage(MessagesLocale message) { - forEachParticipant(participant -> message.send(participant.getPlayerUUID(), TagResolver.empty())); - forEachSpectator(player -> message.send(player.getUniqueId(), TagResolver.empty())); - } - - public void sendMessage(MessagesLocale message, TagResolver resolver) { - forEachParticipant(participant -> message.send(participant.getPlayerUUID(), resolver)); - forEachSpectator(player -> message.send(player.getUniqueId(), resolver)); + @Override + public int getCurrentRound() { + return currentRound; } - public void addSpectator(Player player, Player target, boolean sendMessage, boolean add) { - Profile profile = API.getProfile(player); - - profile.setState(ProfileState.IN_SPECTATOR); - profile.setMatch(this); - - if (add) - spectators.add(player.getUniqueId()); - - showPlayerForSpectators(); - - if (sendMessage) - broadcast(MessagesLocale.SPECTATE_START, Placeholder.unparsed("player", player.getName())); - - player.setHealth(20); - player.setFoodLevel(20); - player.setCollidable(false); - player.teleportAsync(target.getLocation()).thenAccept(success -> { - if (!success) - return; - - forEachPlayer(alivePlayer -> { - if (!alivePlayer.equals(player)) { - player.showPlayer(Neptune.get(), alivePlayer); - alivePlayer.hidePlayer(Neptune.get(), player); - } - }); - - Bukkit.getScheduler().runTaskLater(Neptune.get(), () -> { - player.setAllowFlight(true); - player.setFlying(true); - }, 5L); - }); - - player.setGameMode(GameMode.SURVIVAL); - player.setAllowFlight(true); - player.setFlying(true); - - HotbarService.get().giveItems(player); - - MatchSpectatorAddEvent event = new MatchSpectatorAddEvent(this, player); - Bukkit.getPluginManager().callEvent(event); + @Override + public boolean isSpectator(UUID playerUUID) { + return spectators.contains(playerUUID); } public void showPlayerForSpectators() { @@ -219,6 +171,64 @@ public void resetArena() { arena.restore(); } + public void sendTitle(TextComponent header, TextComponent footer, int duration) { + forEachParticipant(participant -> PlayerUtil.sendTitle(participant.getPlayer(), header, footer, duration)); + } + + public void sendMessage(MessagesLocale message) { + forEachParticipant(participant -> message.send(participant.getPlayerUUID(), TagResolver.empty())); + forEachSpectator(player -> message.send(player.getUniqueId(), TagResolver.empty())); + } + + public void sendMessage(MessagesLocale message, TagResolver resolver) { + forEachParticipant(participant -> message.send(participant.getPlayerUUID(), resolver)); + forEachSpectator(player -> message.send(player.getUniqueId(), resolver)); + } + + public void addSpectator(Player player, Player target, boolean sendMessage, boolean add) { + Profile profile = API.getProfile(player); + + profile.setState(ProfileState.IN_SPECTATOR); + profile.setMatch(this); + + if (add) + spectators.add(player.getUniqueId()); + + showPlayerForSpectators(); + + if (sendMessage) + broadcast(MessagesLocale.SPECTATE_START, Placeholder.unparsed("player", player.getName())); + + player.setHealth(20); + player.setFoodLevel(20); + player.setCollidable(false); + player.teleportAsync(target.getLocation()).thenAccept(success -> { + if (!success) + return; + + forEachPlayer(alivePlayer -> { + if (!alivePlayer.equals(player)) { + player.showPlayer(Neptune.get(), alivePlayer); + alivePlayer.hidePlayer(Neptune.get(), player); + } + }); + + Bukkit.getScheduler().runTaskLater(Neptune.get(), () -> { + player.setAllowFlight(true); + player.setFlying(true); + }, 5L); + }); + + player.setGameMode(GameMode.SURVIVAL); + player.setAllowFlight(true); + player.setFlying(true); + + HotbarService.get().giveItems(player); + + MatchSpectatorAddEvent event = new MatchSpectatorAddEvent(this, player); + Bukkit.getPluginManager().callEvent(event); + } + public List getScoreboard(UUID playerUUID) { Player player = Bukkit.getPlayer(playerUUID); if (player == null) @@ -237,51 +247,57 @@ public List getScoreboard(UUID playerUUID) { } } - if (this instanceof SoloFightMatch) { - MatchState matchState = this.getState(); + switch (this) { + case SoloFightMatch soloFightMatch -> { + MatchState matchState = this.getState(); - if (getRounds() > 1 && matchState.equals(MatchState.STARTING)) { - return CC.getComponentsArray(player, ScoreboardLocale.IN_GAME_BEST_OF.getStringList()); - } + if (getRounds() > 1 && matchState.equals(MatchState.STARTING)) { + return CC.getComponentsArray(player, ScoreboardLocale.IN_GAME_BEST_OF.getStringList()); + } - switch (matchState) { - case STARTING: - return CC.getComponentsArray(player, ScoreboardLocale.IN_GAME_STARTING.getStringList()); - case IN_ROUND: - if (this.getRounds() > 1) { - return CC.getComponentsArray(player, ScoreboardLocale.IN_GAME_BEST_OF.getStringList()); - } - if (this.getKit().is(KitRule.BOXING)) { - return CC.getComponentsArray(player, ScoreboardLocale.IN_GAME_BOXING.getStringList()); - } - if (this.getKit().is(KitRule.BED_WARS)) { - return CC.getComponentsArray(player, ScoreboardLocale.IN_GAME_BEDWARS.getStringList()); - } - return CC.getComponentsArray(player, ScoreboardLocale.IN_GAME.getStringList()); - case ENDING: - String winnerName = getWinnerName(); - String loserName = getLoserName(); - return CC.getComponentsArray(player, ScoreboardLocale.IN_GAME_ENDED.getStringList() - .stream() - .map(str -> str - .replace("", winnerName) - .replace("", loserName)) - .toList()); - default: - break; + switch (matchState) { + case STARTING: + return CC.getComponentsArray(player, ScoreboardLocale.IN_GAME_STARTING.getStringList()); + case IN_ROUND: + if (this.getRounds() > 1) { + return CC.getComponentsArray(player, ScoreboardLocale.IN_GAME_BEST_OF.getStringList()); + } + if (this.getKit().is(KitRule.BOXING)) { + return CC.getComponentsArray(player, ScoreboardLocale.IN_GAME_BOXING.getStringList()); + } + if (this.getKit().is(KitRule.BED_WARS)) { + return CC.getComponentsArray(player, ScoreboardLocale.IN_GAME_BEDWARS.getStringList()); + } + return CC.getComponentsArray(player, ScoreboardLocale.IN_GAME.getStringList()); + case ENDING: + String winnerName = getWinnerName(); + String loserName = getLoserName(); + return CC.getComponentsArray(player, ScoreboardLocale.IN_GAME_ENDED.getStringList() + .stream() + .map(str -> str + .replace("", winnerName) + .replace("", loserName)) + .toList()); + default: + break; + } } - } else if (this instanceof TeamFightMatch) { - if (this.getKit().is(KitRule.BED_WARS)) { - return CC.getComponentsArray(player, ScoreboardLocale.IN_GAME_BEDWARS_TEAM.getStringList()); - } else if (this.getKit().is(KitRule.BOXING)) { - return CC.getComponentsArray(player, ScoreboardLocale.IN_GAME_BOXING_TEAM.getStringList()); + case TeamFightMatch teamFightMatch -> { + if (this.getKit().is(KitRule.BED_WARS)) { + return CC.getComponentsArray(player, ScoreboardLocale.IN_GAME_BEDWARS_TEAM.getStringList()); + } else if (this.getKit().is(KitRule.BOXING)) { + return CC.getComponentsArray(player, ScoreboardLocale.IN_GAME_BOXING_TEAM.getStringList()); + } + return CC.getComponentsArray(player, ScoreboardLocale.IN_GAME_TEAM.getStringList()); + } + case FfaFightMatch ffaFightMatch -> { + if (this.getKit().is(KitRule.BOXING)) { + return CC.getComponentsArray(player, ScoreboardLocale.IN_GAME_BOXING_FFA.getStringList()); + } + return CC.getComponentsArray(player, ScoreboardLocale.IN_GAME_FFA.getStringList()); } - return CC.getComponentsArray(player, ScoreboardLocale.IN_GAME_TEAM.getStringList()); - } else if (this instanceof FfaFightMatch) { - if (this.getKit().is(KitRule.BOXING)) { - return CC.getComponentsArray(player, ScoreboardLocale.IN_GAME_BOXING_FFA.getStringList()); + default -> { } - return CC.getComponentsArray(player, ScoreboardLocale.IN_GAME_FFA.getStringList()); } return null; diff --git a/Plugin/src/main/java/dev/lrxh/neptune/game/match/MatchService.java b/Plugin/src/main/java/dev/lrxh/neptune/game/match/MatchService.java index 995af91a4..cad3cfdf1 100644 --- a/Plugin/src/main/java/dev/lrxh/neptune/game/match/MatchService.java +++ b/Plugin/src/main/java/dev/lrxh/neptune/game/match/MatchService.java @@ -1,15 +1,23 @@ package dev.lrxh.neptune.game.match; import dev.lrxh.api.arena.IArena; +import dev.lrxh.api.events.MatchEndEvent; import dev.lrxh.api.events.MatchReadyEvent; +import dev.lrxh.api.kit.IKit; import dev.lrxh.api.match.IMatch; import dev.lrxh.api.match.IMatchService; import dev.lrxh.neptune.API; import dev.lrxh.neptune.Neptune; +import dev.lrxh.neptune.feature.event.AutomatedEvent; +import dev.lrxh.neptune.feature.event.EventService; +import dev.lrxh.neptune.feature.event.EventState; +import dev.lrxh.neptune.feature.hotbar.HotbarService; import dev.lrxh.neptune.game.arena.Arena; import dev.lrxh.neptune.game.arena.ArenaService; import dev.lrxh.neptune.game.kit.Kit; import dev.lrxh.neptune.game.kit.KitService; +import dev.lrxh.neptune.game.kit.impl.KitRule; +import dev.lrxh.neptune.game.match.impl.MatchState; import dev.lrxh.neptune.game.match.impl.ffa.FfaFightMatch; import dev.lrxh.neptune.game.match.impl.participant.Participant; import dev.lrxh.neptune.game.match.impl.participant.ParticipantColor; @@ -17,12 +25,15 @@ import dev.lrxh.neptune.game.match.impl.team.MatchTeam; import dev.lrxh.neptune.game.match.impl.team.TeamFightMatch; import dev.lrxh.neptune.game.match.tasks.MatchStartRunnable; +import dev.lrxh.neptune.profile.data.ProfileState; import dev.lrxh.neptune.profile.impl.Profile; +import dev.lrxh.neptune.utils.PlayerUtil; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import java.util.*; import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; public class MatchService implements IMatchService { private static MatchService instance; @@ -35,9 +46,11 @@ public static MatchService get() { } public void startMatch(Participant playerRed, Participant playerBlue, Kit kit, IArena arena, boolean duel, int rounds) { - if (!Neptune.get().isAllowMatches()) return; - kit.addPlaying(); - kit.addPlaying(); + if (!Neptune.get().isAllowMatches()) { + arena.remove(); + return; + } + kit.addPlaying(2); playerRed.setOpponent(playerBlue); playerRed.setColor(ParticipantColor.RED); @@ -51,6 +64,8 @@ public void startMatch(Participant playerRed, Participant playerBlue, Kit kit, I MatchReadyEvent event = new MatchReadyEvent(match); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) { + arena.remove(); + kit.removePlaying(2); return; } matches.add(match); @@ -58,7 +73,12 @@ public void startMatch(Participant playerRed, Participant playerBlue, Kit kit, I } public void startMatch(MatchTeam teamA, MatchTeam teamB, Kit kit, IArena arena) { - if (!Neptune.get().isAllowMatches()) return; + if (!Neptune.get().isAllowMatches()) { + arena.remove(); + return; + } + int totalParticipants = teamA.participants().size() + teamB.participants().size(); + kit.addPlaying(totalParticipants); for (Participant participant : teamA.participants()) { for (Participant opponent : teamB.participants()) { participant.setOpponent(opponent); @@ -68,6 +88,7 @@ public void startMatch(MatchTeam teamA, MatchTeam teamB, Kit kit, IArena arena) } } + List participants = new ArrayList<>(teamA.participants()); participants.addAll(teamB.participants()); @@ -78,6 +99,8 @@ public void startMatch(MatchTeam teamA, MatchTeam teamB, Kit kit, IArena arena) MatchReadyEvent event = new MatchReadyEvent(match); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) { + arena.remove(); + kit.removePlaying(totalParticipants); return; } @@ -86,7 +109,11 @@ public void startMatch(MatchTeam teamA, MatchTeam teamB, Kit kit, IArena arena) } public void startMatch(List participants, Kit kit, IArena arena) { - if (!Neptune.get().isAllowMatches()) return; + if (!Neptune.get().isAllowMatches()) { + arena.remove(); + return; + } + kit.addPlaying(participants.size()); for (Participant participant : participants) { participant.setColor(ParticipantColor.RED); } @@ -96,6 +123,8 @@ public void startMatch(List participants, Kit kit, IArena arena) { MatchReadyEvent event = new MatchReadyEvent(match); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) { + arena.remove(); + kit.removePlaying(participants.size()); return; } @@ -135,6 +164,39 @@ public void startMatch(IMatch match, Player redPlayer, Player bluePlayer) { }); } + @Override + public void startFfaMatch(List players, IKit kit) { + Kit implKit = KitService.get().getKitByName(kit.getName()); + if (implKit == null) return; + List participants = new ArrayList<>(); + for (Player p : players) participants.add(new Participant(p)); + IArena arena = implKit.getRandomArena().join(); + if (arena == null) return; + startMatch(participants, implKit, arena); + } + + @Override + public void startTeamMatch(List redTeam, List blueTeam, IKit kit) { + Kit implKit = KitService.get().getKitByName(kit.getName()); + if (implKit == null) return; + MatchTeam teamA = new MatchTeam(redTeam.stream().map(Participant::new).collect(Collectors.toList())); + MatchTeam teamB = new MatchTeam(blueTeam.stream().map(Participant::new).collect(Collectors.toList())); + teamA.setOpponentTeam(teamB); + teamB.setOpponentTeam(teamA); + IArena arena = implKit.getRandomArena().join(); + if (arena == null) return; + startMatch(teamA, teamB, implKit, arena); + } + + @Override + public void startDuelMatch(Player redPlayer, Player bluePlayer, IKit kit, boolean duel, int rounds) { + Kit implKit = KitService.get().getKitByName(kit.getName()); + if (implKit == null) return; + IArena arena = implKit.getRandomArena().join(); + if (arena == null) return; + startMatch(new Participant(redPlayer), new Participant(bluePlayer), implKit, arena, duel, rounds); + } + public Optional getMatch(Player player) { Profile profile = API.getProfile(player); return Optional.ofNullable(profile) @@ -147,6 +209,64 @@ public Optional getMatch(UUID uuid) { .map(Profile::getMatch); } + @Override + public IMatch getMatchApi(Player player) { + return getMatch(player).orElse(null); + } + + @Override + public IMatch getMatchApi(UUID uuid) { + return getMatch(uuid).orElse(null); + } + + @Override + public List getActiveMatches() { + return new ArrayList<>(matches); + } + + @Override + public void stopMatch(IMatch match) { + if (!(match instanceof Match m) || !matches.remove(m)) return; + m.setState(MatchState.ENDING); + if (m.getKit().is(KitRule.SHOW_HP)) { + m.hideHealth(); + } + + for (UUID spectator : new HashSet<>(m.spectators)) { + m.removeSpectator(spectator, false); + } + + m.resetArena(); + + m.forEachParticipant(participant -> { + + Profile profile = API.getProfile(participant.getPlayerUUID()); + if (profile.getMatch() != m) return; + + PlayerUtil.reset(participant.getPlayer()); + profile.setMatch(null); + PlayerUtil.teleportToSpawn(participant.getPlayerUUID()); + + AutomatedEvent activeEvent = EventService.get().getActiveEvent(); + if (activeEvent != null && activeEvent.getState() == EventState.ACTIVE + && activeEvent.getParticipants().contains(participant.getPlayerUUID())) { + profile.setState(ProfileState.IN_EVENT); + } else { + profile.setState(profile.getGameData().getParty() == null ? ProfileState.IN_LOBBY : ProfileState.IN_PARTY); + } + + m.forEachPlayer(player -> HotbarService.get().giveItems(player)); + }); + + m.sendEndMessage(); + m.getArena().remove(); + if (m.getArena() instanceof Arena arena) arena.setInUse(false); + MatchService.get().matches.remove(m); + MatchEndEvent event = new MatchEndEvent(m); + Bukkit.getPluginManager().callEvent(event); + m.setEnded(true); + } + public void stopAllGames() { for (Match match : matches) { match.resetArena(); diff --git a/Plugin/src/main/java/dev/lrxh/neptune/game/match/impl/ffa/FfaFightMatch.java b/Plugin/src/main/java/dev/lrxh/neptune/game/match/impl/ffa/FfaFightMatch.java index f143c33a8..dac65f582 100644 --- a/Plugin/src/main/java/dev/lrxh/neptune/game/match/impl/ffa/FfaFightMatch.java +++ b/Plugin/src/main/java/dev/lrxh/neptune/game/match/impl/ffa/FfaFightMatch.java @@ -58,6 +58,8 @@ public void end(Participant loser) { loser.playKillEffect(); + getKit().removePlaying(participants.size()); + new MatchEndRunnable(this).start(0L, 20L); } @@ -104,7 +106,7 @@ public String getWinnerName() { } public String getLoserName() { - return deadParticipants.stream().map(p -> p.getNameColored()).toList().toString(); + return deadParticipants.stream().map(Participant::getNameColored).toList().toString(); } private boolean isLastPlayerStanding() { @@ -113,7 +115,7 @@ private boolean isLastPlayerStanding() { private Participant getLastPlayerStanding() { for (IParticipant participant : getParticipants()) { - if (!deadParticipants.contains(participant)) { + if (!deadParticipants.contains((Participant) participant)) { return (Participant) participant; } } diff --git a/Plugin/src/main/java/dev/lrxh/neptune/game/match/impl/team/TeamFightMatch.java b/Plugin/src/main/java/dev/lrxh/neptune/game/match/impl/team/TeamFightMatch.java index e511470a9..664750f61 100644 --- a/Plugin/src/main/java/dev/lrxh/neptune/game/match/impl/team/TeamFightMatch.java +++ b/Plugin/src/main/java/dev/lrxh/neptune/game/match/impl/team/TeamFightMatch.java @@ -80,6 +80,8 @@ public void end(Participant loser) { loser.playKillEffect(); + getKit().removePlaying(winnerTeam.participants().size() + loserTeam.participants().size()); + new MatchEndRunnable(this).start(0L, 20L); } diff --git a/Plugin/src/main/java/dev/lrxh/neptune/game/match/tasks/MatchEndRunnable.java b/Plugin/src/main/java/dev/lrxh/neptune/game/match/tasks/MatchEndRunnable.java index 79b77a2e0..601af74f7 100644 --- a/Plugin/src/main/java/dev/lrxh/neptune/game/match/tasks/MatchEndRunnable.java +++ b/Plugin/src/main/java/dev/lrxh/neptune/game/match/tasks/MatchEndRunnable.java @@ -1,24 +1,8 @@ package dev.lrxh.neptune.game.match.tasks; -import dev.lrxh.api.events.MatchEndEvent; -import dev.lrxh.neptune.API; -import dev.lrxh.neptune.feature.event.AutomatedEvent; -import dev.lrxh.neptune.feature.event.EventService; -import dev.lrxh.neptune.feature.event.EventState; -import dev.lrxh.neptune.feature.hotbar.HotbarService; -import dev.lrxh.neptune.game.arena.Arena; -import dev.lrxh.neptune.game.kit.impl.KitRule; import dev.lrxh.neptune.game.match.Match; import dev.lrxh.neptune.game.match.MatchService; -import dev.lrxh.neptune.game.match.impl.MatchState; -import dev.lrxh.neptune.profile.data.ProfileState; -import dev.lrxh.neptune.profile.impl.Profile; -import dev.lrxh.neptune.utils.PlayerUtil; import dev.lrxh.neptune.utils.tasks.NeptuneRunnable; -import org.bukkit.Bukkit; - -import java.util.HashSet; -import java.util.UUID; public class MatchEndRunnable extends NeptuneRunnable { private final Match match; @@ -37,43 +21,7 @@ public void run() { return; } if (endTimer == 0) { - match.setState(MatchState.ENDING); - if (match.getKit().is(KitRule.SHOW_HP)) { - match.hideHealth(); - } - - for (UUID spectator : new HashSet<>(match.spectators)) { - match.removeSpectator(spectator, false); - } - - match.resetArena(); - - match.forEachParticipant(participant -> { - - Profile profile = API.getProfile(participant.getPlayerUUID()); - if (profile.getMatch() != match) return; - - PlayerUtil.reset(participant.getPlayer()); - profile.setMatch(null); - PlayerUtil.teleportToSpawn(participant.getPlayerUUID()); - - AutomatedEvent activeEvent = EventService.get().getActiveEvent(); - if (activeEvent != null && activeEvent.getState() == EventState.ACTIVE - && activeEvent.getParticipants().contains(participant.getPlayerUUID())) { - profile.setState(ProfileState.IN_EVENT); - } else { - profile.setState(profile.getGameData().getParty() == null ? ProfileState.IN_LOBBY : ProfileState.IN_PARTY); - } - - match.forEachPlayer(player -> HotbarService.get().giveItems(player)); - }); - - match.sendEndMessage(); - match.getArena().remove(); - if (match.getArena() instanceof Arena arena) arena.setInUse(false); - MatchService.get().matches.remove(match); - MatchEndEvent event = new MatchEndEvent(match); - Bukkit.getPluginManager().callEvent(event); + MatchService.get().stopMatch(match); stop(); } endTimer--; diff --git a/Plugin/src/main/java/dev/lrxh/neptune/profile/ProfileService.java b/Plugin/src/main/java/dev/lrxh/neptune/profile/ProfileService.java index f0e12ce32..4cb611b62 100644 --- a/Plugin/src/main/java/dev/lrxh/neptune/profile/ProfileService.java +++ b/Plugin/src/main/java/dev/lrxh/neptune/profile/ProfileService.java @@ -72,4 +72,14 @@ public CompletableFuture _getProfile(UUID uuid) { ? CompletableFuture.completedFuture(profile) : createFakeProfile(uuid).thenApply(p -> p); } + + @Override + public IProfile getCachedProfile(UUID uuid) { + return profiles.get(uuid); + } + + @Override + public boolean isLoaded(UUID uuid) { + return profiles.containsKey(uuid); + } } diff --git a/Plugin/src/main/java/dev/lrxh/neptune/profile/impl/Profile.java b/Plugin/src/main/java/dev/lrxh/neptune/profile/impl/Profile.java index 4220dabbc..02fd5835a 100644 --- a/Plugin/src/main/java/dev/lrxh/neptune/profile/impl/Profile.java +++ b/Plugin/src/main/java/dev/lrxh/neptune/profile/impl/Profile.java @@ -1,7 +1,9 @@ package dev.lrxh.neptune.profile.impl; +import dev.lrxh.api.events.PlayerLeaveEvent; import dev.lrxh.api.profile.IProfile; import dev.lrxh.api.profile.IProfileState; +import dev.lrxh.api.match.IMatch; import dev.lrxh.neptune.API; import dev.lrxh.neptune.Neptune; import dev.lrxh.neptune.configs.impl.MessagesLocale; @@ -331,16 +333,44 @@ public Player getPlayer() { return Bukkit.getPlayer(playerUUID); } + public void forfeit() { + ProfileState state = getState(); + String previousStatus = getProfileState(); + switch (state) { + case IN_SPECTATOR: + getMatch().removeSpectator(getPlayer().getUniqueId(), true); + return; + case IN_GAME: + getMatch().onLeave(getMatch().getParticipant(getPlayer().getUniqueId()), false); + MessagesLocale.MATCH_FORFEIT.send(getPlayer()); + return; + case IN_CUSTOM: + PlayerUtil.reset(getPlayer()); + setState(ProfileState.IN_LOBBY); + PlayerUtil.teleportToSpawn(getPlayer().getUniqueId()); + return; + default: + break; + } + PlayerLeaveEvent event = new PlayerLeaveEvent(this, previousStatus); + Bukkit.getPluginManager().callEvent(event); + PlayerUtil.teleportToSpawn(getPlayer().getUniqueId()); + } + public void sendRequest(DuelRequest duelRequest, boolean rematch) { UUID senderUUID = duelRequest.getSender(); Player sender = Bukkit.getPlayer(senderUUID); - if (sender == null) + if (sender == null) { + if (duelRequest.getArena() != null) duelRequest.getArena().remove(); return; + } Player player = Bukkit.getPlayer(playerUUID); - if (player == null) + if (player == null) { + if (duelRequest.getArena() != null) duelRequest.getArena().remove(); return; + } duelRequest.sendSenderMessage(playerUUID, rematch); @@ -402,6 +432,11 @@ public Match getMatch() { return gameData.getMatch(); } + @Override + public IMatch getIMatch() { + return gameData.getMatch(); + } + public void setMatch(Match match) { gameData.setMatch(match); } diff --git a/Plugin/src/main/java/dev/lrxh/neptune/utils/TtlHashMap.java b/Plugin/src/main/java/dev/lrxh/neptune/utils/TtlHashMap.java index 08377461c..5d440286e 100644 --- a/Plugin/src/main/java/dev/lrxh/neptune/utils/TtlHashMap.java +++ b/Plugin/src/main/java/dev/lrxh/neptune/utils/TtlHashMap.java @@ -2,7 +2,6 @@ import dev.lrxh.neptune.utils.tasks.NeptuneRunnable; import org.bukkit.Bukkit; -import org.bukkit.entity.Player; import java.util.HashMap; import java.util.Map; @@ -24,10 +23,7 @@ public void put(K key, V value, TtlAction action) { public void onExpire(K key) { TtlAction action = actions.get(key); if (action != null) { - Player player = Bukkit.getPlayer(action.getPlayerUUID()); - if (player != null) { - action.getConsumer().accept(player); - } + action.getConsumer().accept(Bukkit.getPlayer(action.getPlayerUUID())); actions.remove(key); } }