From da1639f2fad323ec9d3e60b7620f64f8a5764ed5 Mon Sep 17 00:00:00 2001 From: lokspel <208148594+lokspel@users.noreply.github.com> Date: Mon, 18 May 2026 10:49:34 +0400 Subject: [PATCH 1/9] fix: fix profile worldtime default value and handle offline players in leaderboards --- .../gui/guis/leaderboard/LbGuiUtil.java | 30 ++++++++++++------- .../manager/gui/guis/queue/QueueGuiUtil.java | 8 ++--- .../leaderboard/hologram/Hologram.java | 1 + .../practice/manager/profile/Profile.java | 2 +- .../practice/manager/profile/ProfileFile.java | 14 +++++++-- 5 files changed, 37 insertions(+), 18 deletions(-) diff --git a/core/src/main/java/dev/nandi0813/practice/manager/gui/guis/leaderboard/LbGuiUtil.java b/core/src/main/java/dev/nandi0813/practice/manager/gui/guis/leaderboard/LbGuiUtil.java index 2ab5400c1..de84498eb 100644 --- a/core/src/main/java/dev/nandi0813/practice/manager/gui/guis/leaderboard/LbGuiUtil.java +++ b/core/src/main/java/dev/nandi0813/practice/manager/gui/guis/leaderboard/LbGuiUtil.java @@ -158,8 +158,10 @@ public static ItemStack createEloLbItem(NormalLadder ladder) { List topPlayers = new ArrayList<>(); Map list = leaderboard.getList(); for (OfflinePlayer player : list.keySet()) { - if (topPlayers.size() < showPlayers) topPlayers.add(player); - else break; + if (player.getName() != null && ProfileManager.getInstance().getProfile(player) != null) { + topPlayers.add(player); + } + if (topPlayers.size() >= showPlayers) break; } List topStrings = new ArrayList<>(); @@ -171,7 +173,7 @@ public static ItemStack createEloLbItem(NormalLadder ladder) { int stat = list.get(target); topStrings.add(GUIFile.getString("GUIS.STATISTICS.ELO-LEADERBOARD.ICONS.LADDER-LEADERBOARD.LORE.FORMAT") .replace("%number%", String.valueOf(i)) - .replace("%player%", Objects.requireNonNull(target.getName())) + .replace("%player%", target.getName()) .replace("%ladder_elo%", String.valueOf(stat)) .replace("%division%", division != null ? Common.mmToNormal(division.getFullName()) : "") .replace("%division_short%", division != null ? Common.mmToNormal(division.getShortName()) : "")); @@ -204,8 +206,10 @@ public static ItemStack createGlobalEloLb() { List topPlayers = new ArrayList<>(); Map list = leaderboard.getList(); for (OfflinePlayer player : list.keySet()) { - if (topPlayers.size() < showPlayers) topPlayers.add(player); - else break; + if (player.getName() != null && ProfileManager.getInstance().getProfile(player) != null) { + topPlayers.add(player); + } + if (topPlayers.size() >= showPlayers) break; } List topStrings = new ArrayList<>(); @@ -219,7 +223,7 @@ public static ItemStack createGlobalEloLb() { .replace("%number%", String.valueOf(i)) .replace("%division%", division != null ? Common.mmToNormal(division.getFullName()) : "") .replace("%division_short%", division != null ? Common.mmToNormal(division.getShortName()) : "") - .replace("%player%", Objects.requireNonNull(target.getName())) + .replace("%player%", target.getName()) .replace("%global_elo%", String.valueOf(stat))); } else { topStrings.add(GUIFile.getString("GUIS.STATISTICS.ELO-LEADERBOARD.ICONS.GLOBAL-LEADERBOARD.LORE.FORMAT-NULL") @@ -250,8 +254,10 @@ public static ItemStack createWinLbItem(NormalLadder ladder) { List topPlayers = new ArrayList<>(); Map list = leaderboard.getList(); for (OfflinePlayer player : list.keySet()) { - if (topPlayers.size() < showPlayers) topPlayers.add(player); - else break; + if (player.getName() != null && ProfileManager.getInstance().getProfile(player) != null) { + topPlayers.add(player); + } + if (topPlayers.size() >= showPlayers) break; } List topStrings = new ArrayList<>(); @@ -296,8 +302,10 @@ public static ItemStack createGlobalWinLb() { List topPlayers = new ArrayList<>(); Map list = leaderboard.getList(); for (OfflinePlayer player : list.keySet()) { - if (topPlayers.size() < showPlayers) topPlayers.add(player); - else break; + if (player.getName() != null && ProfileManager.getInstance().getProfile(player) != null) { + topPlayers.add(player); + } + if (topPlayers.size() >= showPlayers) break; } List topStrings = new ArrayList<>(); @@ -311,7 +319,7 @@ public static ItemStack createGlobalWinLb() { .replace("%number%", String.valueOf(i)) .replace("%division%", division != null ? Common.mmToNormal(division.getFullName()) : "") .replace("%division_short%", division != null ? Common.mmToNormal(division.getShortName()) : "") - .replace("%player%", Objects.requireNonNull(target.getName())) + .replace("%player%", target.getName()) .replace("%global_win%", String.valueOf(stat))); } else { topStrings.add(GUIFile.getString("GUIS.STATISTICS.WIN-LEADERBOARD.ICONS.GLOBAL-LEADERBOARD.LORE.FORMAT-NULL") diff --git a/core/src/main/java/dev/nandi0813/practice/manager/gui/guis/queue/QueueGuiUtil.java b/core/src/main/java/dev/nandi0813/practice/manager/gui/guis/queue/QueueGuiUtil.java index 24ee8647e..b6ebcb8db 100644 --- a/core/src/main/java/dev/nandi0813/practice/manager/gui/guis/queue/QueueGuiUtil.java +++ b/core/src/main/java/dev/nandi0813/practice/manager/gui/guis/queue/QueueGuiUtil.java @@ -63,11 +63,11 @@ static String getLbString(String format, String s, Ladder ladder) { OfflinePlayer player = players.get(placement - 1); Profile profile = ProfileManager.getInstance().getProfile(player); - Division division = null; - if (profile != null) { - division = profile.getStats().getDivision(); + if (profile == null || player.getName() == null) { + return "&cNo player found!"; } - + + Division division = profile.getStats().getDivision(); int score = leaderboard.getList().get(player); return format diff --git a/core/src/main/java/dev/nandi0813/practice/manager/leaderboard/hologram/Hologram.java b/core/src/main/java/dev/nandi0813/practice/manager/leaderboard/hologram/Hologram.java index 88817f66a..817e7d1a7 100644 --- a/core/src/main/java/dev/nandi0813/practice/manager/leaderboard/hologram/Hologram.java +++ b/core/src/main/java/dev/nandi0813/practice/manager/leaderboard/hologram/Hologram.java @@ -347,6 +347,7 @@ private List buildSpacings(int lineCount, Leaderboard leaderboard) { private List buildPlacementStrings(Leaderboard leaderboard) { Map playerStats = leaderboard.getList(); List topPlayers = playerStats.keySet().stream() + .filter(p -> p.getName() != null && ProfileManager.getInstance().getProfile(p) != null) .limit(showStat) .collect(Collectors.toList()); diff --git a/core/src/main/java/dev/nandi0813/practice/manager/profile/Profile.java b/core/src/main/java/dev/nandi0813/practice/manager/profile/Profile.java index 51fe053ba..72a8c9325 100644 --- a/core/src/main/java/dev/nandi0813/practice/manager/profile/Profile.java +++ b/core/src/main/java/dev/nandi0813/practice/manager/profile/Profile.java @@ -62,7 +62,7 @@ public class Profile { private boolean partyInvites; private boolean allowSpectate; private boolean privateMessages; - private ProfileWorldTime worldTime; + private ProfileWorldTime worldTime = ProfileWorldTime.DAY; private boolean flying; private ProfilePrefixVisibility prefixVisibility = ProfilePrefixVisibility.PREFIX_AND_SUFFIX; diff --git a/core/src/main/java/dev/nandi0813/practice/manager/profile/ProfileFile.java b/core/src/main/java/dev/nandi0813/practice/manager/profile/ProfileFile.java index 8d24d6f93..aa4e98c4c 100644 --- a/core/src/main/java/dev/nandi0813/practice/manager/profile/ProfileFile.java +++ b/core/src/main/java/dev/nandi0813/practice/manager/profile/ProfileFile.java @@ -161,7 +161,12 @@ public void setDefaultData() { config.set("settings.allowspectate", ConfigManager.getBoolean("PLAYER.DEFAULT-SETTINGS.ALLOWSPECTATE")); config.set("settings.flying", ConfigManager.getBoolean("PLAYER.DEFAULT-SETTINGS.FLYING")); config.set("settings.messages", ConfigManager.getBoolean("PLAYER.DEFAULT-SETTINGS.PRIVATEMESSAGE")); - config.set("settings.worldtime", ProfileWorldTime.valueOf(ConfigManager.getString("PLAYER.DEFAULT-SETTINGS.WORLD-TIME")).toString()); + String defaultWorldTime = ConfigManager.getString("PLAYER.DEFAULT-SETTINGS.WORLD-TIME"); + try { + config.set("settings.worldtime", ProfileWorldTime.valueOf(defaultWorldTime.toUpperCase(Locale.ROOT)).toString()); + } catch (Exception ignored) { + config.set("settings.worldtime", ProfileWorldTime.DAY.toString()); + } String defaultPrefixVisibility = ConfigManager.getString("PLAYER.DEFAULT-SETTINGS.PREFIX-VISIBILITY"); try { @@ -214,7 +219,12 @@ public void getData() { profile.setAllowSpectate(config.getBoolean("settings.allowspectate")); profile.setFlying(config.getBoolean("settings.flying")); profile.setPrivateMessages(config.getBoolean("settings.messages")); - profile.setWorldTime(ProfileWorldTime.valueOf(config.getString("settings.worldtime"))); + String rawWorldTime = config.getString("settings.worldtime", ProfileWorldTime.DAY.toString()); + try { + profile.setWorldTime(ProfileWorldTime.valueOf(rawWorldTime.toUpperCase(Locale.ROOT))); + } catch (IllegalArgumentException ignored) { + profile.setWorldTime(ProfileWorldTime.DAY); + } String rawPrefixVisibility = config.getString("settings.prefix-visibility", ProfilePrefixVisibility.PREFIX_AND_SUFFIX.toString()); try { From 6dcf467a7b37f9ac419b97c44b70e5ae22df4b00 Mon Sep 17 00:00:00 2001 From: lokspel <208148594+lokspel@users.noreply.github.com> Date: Mon, 18 May 2026 10:57:52 +0400 Subject: [PATCH 2/9] fix: resolve party chat permission error caused by missing break --- .../practice/manager/gui/guis/party/PartySettingsGui.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/main/java/dev/nandi0813/practice/manager/gui/guis/party/PartySettingsGui.java b/core/src/main/java/dev/nandi0813/practice/manager/gui/guis/party/PartySettingsGui.java index 434850485..b50e46299 100644 --- a/core/src/main/java/dev/nandi0813/practice/manager/gui/guis/party/PartySettingsGui.java +++ b/core/src/main/java/dev/nandi0813/practice/manager/gui/guis/party/PartySettingsGui.java @@ -96,6 +96,7 @@ public void handleClickEvent(InventoryClickEvent e) { update(); } else Common.sendMMMessage(player, LanguageManager.getString("PARTY.NO-PERMISSION")); + break; case 11: if (player.hasPermission("zpp.party.changelimit")) { int groupPartyLimit = PartyManager.getInstance().resolvePartyMemberLimit(party.getLeader()); @@ -118,12 +119,14 @@ public void handleClickEvent(InventoryClickEvent e) { update(); } else Common.sendMMMessage(player, LanguageManager.getString("PARTY.NO-PERMISSION")); + break; case 14: if (player.hasPermission("zpp.party.allinvite")) { party.setAllInvite(!party.isAllInvite()); update(); } else Common.sendMMMessage(player, LanguageManager.getString("PARTY.NO-PERMISSION")); + break; case 15: if (player.hasPermission("zpp.party.public")) { if (PlayerCooldown.isActive(player, CooldownObject.PUBLIC_PARTY_CHANGE)) { From 1fa95c3d9dc2b08b32b173abe4c6d79c758fca26 Mon Sep 17 00:00:00 2001 From: lokspel <208148594+lokspel@users.noreply.github.com> Date: Mon, 18 May 2026 13:42:28 +0400 Subject: [PATCH 3/9] fix: not-won round symbols rendering as filled on scoreboard --- .../practice/manager/fight/match/type/duel/Duel.java | 5 ++++- .../practice/manager/sidebar/adapter/AdapterUtil.java | 7 ++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/dev/nandi0813/practice/manager/fight/match/type/duel/Duel.java b/core/src/main/java/dev/nandi0813/practice/manager/fight/match/type/duel/Duel.java index 9b226554c..18ad4659a 100644 --- a/core/src/main/java/dev/nandi0813/practice/manager/fight/match/type/duel/Duel.java +++ b/core/src/main/java/dev/nandi0813/practice/manager/fight/match/type/duel/Duel.java @@ -29,6 +29,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.UUID; @Getter public class Duel extends Match implements Team { @@ -108,9 +109,11 @@ public DuelRound getCurrentRound() { @Override public int getWonRounds(Player player) { + UUID playerUuid = player.getUniqueId(); int wonRounds = 0; for (Round round : this.rounds.values()) { - if (((DuelRound) round).getRoundWinner() == player) + Player winner = ((DuelRound) round).getRoundWinner(); + if (winner != null && winner.getUniqueId().equals(playerUuid)) wonRounds++; } return wonRounds; diff --git a/core/src/main/java/dev/nandi0813/practice/manager/sidebar/adapter/AdapterUtil.java b/core/src/main/java/dev/nandi0813/practice/manager/sidebar/adapter/AdapterUtil.java index ed0af6cd8..6b56bb533 100644 --- a/core/src/main/java/dev/nandi0813/practice/manager/sidebar/adapter/AdapterUtil.java +++ b/core/src/main/java/dev/nandi0813/practice/manager/sidebar/adapter/AdapterUtil.java @@ -154,20 +154,17 @@ public static Component getRoundString(int rounds, int wonRounds, Component wonC } Component component = Component.empty(); - boolean firstNotWon = true; String roundSymbol = getRoundSymbol(); Component wonSymbol = wonColor == null ? Component.text(roundSymbol) : wonColor.append(Component.text(roundSymbol)); + Component notWonSymbol = Component.text(roundSymbol, NamedTextColor.GRAY); for (int i = 1; i <= rounds; i++) { if (i <= clampedWonRounds) { component = component.append(wonSymbol); - } else if (firstNotWon) { - component = component.append(Component.text(roundSymbol, NamedTextColor.GRAY)); - firstNotWon = false; } else { - component = component.append(Component.text(roundSymbol)); + component = component.append(notWonSymbol); } } From 2ccbd300e1a41da9bd48119cd2d5dce5d3ce2272 Mon Sep 17 00:00:00 2001 From: lokspel <208148594+lokspel@users.noreply.github.com> Date: Mon, 18 May 2026 13:50:47 +0400 Subject: [PATCH 4/9] Prevent throwing ender peal if cooldown is 0.0 in the start of the match --- .../manager/fight/listener/EPCountdownListener.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/dev/nandi0813/practice/manager/fight/listener/EPCountdownListener.java b/core/src/main/java/dev/nandi0813/practice/manager/fight/listener/EPCountdownListener.java index 34d4ab44a..a39dfe041 100644 --- a/core/src/main/java/dev/nandi0813/practice/manager/fight/listener/EPCountdownListener.java +++ b/core/src/main/java/dev/nandi0813/practice/manager/fight/listener/EPCountdownListener.java @@ -102,13 +102,13 @@ public void onProjectileShoot(ProjectileLaunchEvent e) { Match match = MatchManager.getInstance().getLiveMatchByPlayer(player); if (match != null) { - double duration = match.getLadder().getEnderPearlCooldown(); - if (duration <= 0) { + if (!match.getCurrentRound().getRoundStatus().equals(RoundStatus.LIVE)) { + e.setCancelled(true); return; } - if (!match.getCurrentRound().getRoundStatus().equals(RoundStatus.LIVE)) { - e.setCancelled(true); + double duration = match.getLadder().getEnderPearlCooldown(); + if (duration <= 0) { return; } From 4c179ff186975bda253217e77540844dac27a844 Mon Sep 17 00:00:00 2001 From: lokspel <208148594+lokspel@users.noreply.github.com> Date: Mon, 18 May 2026 17:45:54 +0400 Subject: [PATCH 5/9] fix: shade MariaDB driver to prevent classpath conflict with other plugins --- .../dev/nandi0813/practice/manager/backend/MysqlManager.java | 2 +- distribution/pom.xml | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/dev/nandi0813/practice/manager/backend/MysqlManager.java b/core/src/main/java/dev/nandi0813/practice/manager/backend/MysqlManager.java index 0cb512021..79dd1c488 100644 --- a/core/src/main/java/dev/nandi0813/practice/manager/backend/MysqlManager.java +++ b/core/src/main/java/dev/nandi0813/practice/manager/backend/MysqlManager.java @@ -71,7 +71,7 @@ public static void openConnection() { try { // Explicitly load the MariaDB driver to ensure it's available for JDBC DriverManager - Class.forName("org.mariadb.jdbc.Driver"); + Class.forName("dev.nandi0813.practice.dependencies.mariadb.Driver"); HikariConfig config = new HikariConfig(); config.setJdbcUrl(url); diff --git a/distribution/pom.xml b/distribution/pom.xml index a6135c218..e1a7b7ad9 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -113,6 +113,10 @@ com.zaxxer.hikari dev.nandi0813.practice.dependencies.hikari + + org.mariadb.jdbc + dev.nandi0813.practice.dependencies.mariadb + From 7bfda7e68111e1c4316e6c6bf77fdd918e10fe02 Mon Sep 17 00:00:00 2001 From: lokspel <208148594+lokspel@users.noreply.github.com> Date: Mon, 18 May 2026 18:49:24 +0400 Subject: [PATCH 6/9] fix: remove players from live match on rejoin if they disconnected during duel acceptance --- .../dev/nandi0813/practice/listener/PlayerJoin.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/core/src/main/java/dev/nandi0813/practice/listener/PlayerJoin.java b/core/src/main/java/dev/nandi0813/practice/listener/PlayerJoin.java index a73ce4bc2..cf4b496ba 100644 --- a/core/src/main/java/dev/nandi0813/practice/listener/PlayerJoin.java +++ b/core/src/main/java/dev/nandi0813/practice/listener/PlayerJoin.java @@ -10,6 +10,8 @@ import dev.nandi0813.practice.manager.profile.enums.ProfileStatus; import dev.nandi0813.practice.manager.sidebar.SidebarManager; import dev.nandi0813.practice.telemetry.transport.stats.PracticeStatsTelemetryLogger; +import dev.nandi0813.practice.manager.fight.match.Match; +import dev.nandi0813.practice.manager.fight.match.MatchManager; import dev.nandi0813.practice.util.PermanentConfig; import dev.nandi0813.practice.util.UpdateChecker; import dev.nandi0813.practice.util.playerutil.PlayerUtil; @@ -61,6 +63,14 @@ public void onPlayerJoin(PlayerJoinEvent e) { profile1.setHideFromPlayers(true); }, 10L); + // If the player was disconnected while in a match, remove them from it + // to prevent ending up in the match with lobby items on rejoin + if (profile.getStatus() == ProfileStatus.MATCH) { + Match liveMatch = MatchManager.getInstance().getLiveMatchByPlayer(player); + if (liveMatch != null) + liveMatch.removePlayer(player, true); + } + InventoryManager.getInstance().setLobbyInventory(player, true); } else { ProfileManager.getInstance().getProfile(player).setStatus(ProfileStatus.OFFLINE); From f8a1a8a9beeb310ec48473a70e162242d6644f61 Mon Sep 17 00:00:00 2001 From: lokspel <208148594+lokspel@users.noreply.github.com> Date: Mon, 18 May 2026 20:33:09 +0400 Subject: [PATCH 7/9] Refactor Profile --- .../fight/util/KitSelectionHandler.java | 16 -- .../premadecustom/CustomLadderEditorGui.java | 12 - .../practice/manager/profile/Profile.java | 269 ++++++++++-------- .../practice/manager/profile/ProfileFile.java | 262 ++++++++--------- .../manager/profile/ProfileManager.java | 77 ++--- .../profile/cosmetics/CosmeticsData.java | 2 +- .../CosmeticsPermissionSanitizer.java | 7 +- .../enums/ProfilePrefixVisibility.java | 4 +- .../profile/enums/ProfileWorldTime.java | 4 +- .../profile/statistics/LadderStats.java | 62 ++-- .../profile/statistics/ProfileStat.java | 49 ++-- 11 files changed, 378 insertions(+), 386 deletions(-) diff --git a/core/src/main/java/dev/nandi0813/practice/manager/fight/util/KitSelectionHandler.java b/core/src/main/java/dev/nandi0813/practice/manager/fight/util/KitSelectionHandler.java index 7e144d642..12d28f419 100644 --- a/core/src/main/java/dev/nandi0813/practice/manager/fight/util/KitSelectionHandler.java +++ b/core/src/main/java/dev/nandi0813/practice/manager/fight/util/KitSelectionHandler.java @@ -128,22 +128,6 @@ public void showKitChooserOrApplyKit(TeamEnum team) { ItemStack[] inventory = kit.getInventory(); ItemStack[] armor = kit.getArmor(); - // Legacy safeguard: old kits may still have armor appended into inventory[36..39]. - if (inventory != null && inventory.length > 36) { - if (armor == null) { - armor = new ItemStack[]{ - inventory[36], - inventory.length > 37 ? inventory[37] : null, - inventory.length > 38 ? inventory[38] : null, - inventory.length > 39 ? inventory[39] : null - }; - } - - ItemStack[] trimmed = new ItemStack[36]; - System.arraycopy(inventory, 0, trimmed, 0, 36); - inventory = trimmed; - } - if (armor == null) { armor = ladder.getKitData().getArmor(); } diff --git a/core/src/main/java/dev/nandi0813/practice/manager/gui/guis/customladder/premadecustom/CustomLadderEditorGui.java b/core/src/main/java/dev/nandi0813/practice/manager/gui/guis/customladder/premadecustom/CustomLadderEditorGui.java index faf146b56..5d0217353 100644 --- a/core/src/main/java/dev/nandi0813/practice/manager/gui/guis/customladder/premadecustom/CustomLadderEditorGui.java +++ b/core/src/main/java/dev/nandi0813/practice/manager/gui/guis/customladder/premadecustom/CustomLadderEditorGui.java @@ -136,18 +136,6 @@ public void update() { // Load armor BEFORE filler logic to prevent filler items from overwriting armor slots ItemStack[] customKitArmor = customKit.getArmor(); - if (customKitArmor == null) { - // Legacy fallback for old kits where armor was appended to inventory[36..39] - ItemStack[] customKitInventory = customKit.getInventory(); - if (customKitInventory != null && customKitInventory.length > 39) { - customKitArmor = new ItemStack[]{ - customKitInventory[36], - customKitInventory[37], - customKitInventory[38], - customKitInventory[39] - }; - } - } if (customKitArmor == null) { customKitArmor = ladder.getKitData().getArmor(); diff --git a/core/src/main/java/dev/nandi0813/practice/manager/profile/Profile.java b/core/src/main/java/dev/nandi0813/practice/manager/profile/Profile.java index 72a8c9325..c9b424e6c 100644 --- a/core/src/main/java/dev/nandi0813/practice/manager/profile/Profile.java +++ b/core/src/main/java/dev/nandi0813/practice/manager/profile/Profile.java @@ -32,30 +32,36 @@ @Setter public class Profile { + // Identity private final UUID uuid; private final OfflinePlayer player; private final ProfileFile file; private final ProfileStat stats; private Group group; + // Name display private Component prefix; private String nameTemplate; private NamedTextColor nameColor; private Component suffix; + // Join timestamps private long firstJoin; private long lastJoin; + // Online state private ProfileStatus status; private boolean spectatorMode; private boolean party; private boolean hideSpectators; + // Staff state private boolean staffMode; private boolean staffChat; private boolean hideFromPlayers; private Player followTarget; + // Player settings private boolean duelRequest; private boolean sidebar; private boolean hidePlayers; @@ -66,29 +72,31 @@ public class Profile { private boolean flying; private ProfilePrefixVisibility prefixVisibility = ProfilePrefixVisibility.PREFIX_AND_SUFFIX; + // Custom kits private int allowedCustomKits; private final Map> unrankedCustomKits = new HashMap<>(); private final Map> rankedCustomKits = new HashMap<>(); - // Unranked & Ranked & Event left daily + // Daily limits private final List ignoredPlayers = new ArrayList<>(); - private int unrankedLeft = 0; - private int rankedLeft = 0; - private int eventStartLeft = 0; - private int partyBroadcastLeft = 0; + private int unrankedLeft; + private int rankedLeft; + private int eventStartLeft; + private int partyBroadcastLeft; + // Misc private RankedBan rankedBan = new RankedBan(); private ProfileSettingsGui settingsGui; private ActionBar actionBar; - // Cosmetics data for armor trims + // Cosmetics private CosmeticsData cosmeticsData = new CosmeticsData(); // Custom ladder private PlayerCustomKitSelector playerCustomKitSelector; private final List customLadders = new ArrayList<>(); private CustomLadder selectedCustomLadder; - private boolean fullDataLoaded = false; + private boolean fullDataLoaded; public Profile(UUID uuid, OfflinePlayer player) { this.uuid = uuid; @@ -117,108 +125,118 @@ public Player getOnlinePlayer() { return Bukkit.getPlayer(uuid); } + // Data persistence + public void saveData() { - this.rankedBan.set(file.getConfig(), "ranked-ban"); + rankedBan.set(file.getConfig(), "ranked-ban"); + + saveCustomLadders(); + + stats.setData(false); + file.setData(); + } + private void saveCustomLadders() { for (CustomLadder customLadder : customLadders) { customLadder.setData(); } - if (this.selectedCustomLadder != null) { - this.file.getConfig().set("selected-custom-ladder", customLadders.indexOf(this.selectedCustomLadder)); + if (selectedCustomLadder != null) { + file.getConfig().set("selected-custom-ladder", customLadders.indexOf(selectedCustomLadder)); } - - stats.setData(false); - file.setData(); } public void getData() { - this.stats.getLadderStats().clear(); + stats.getLadderStats().clear(); file.getData(); stats.getData(); - this.rankedBan.get(file.getConfig(), "ranked-ban"); - - if (this.file.getConfig().isConfigurationSection("player-custom-kit")) { - this.customLadders.clear(); - for (String ladder : Objects.requireNonNull(this.file.getConfig().getConfigurationSection("player-custom-kit")).getKeys(false)) { - try { - int i = Integer.parseInt(ladder); - if (i < 0 || i > 5) { - continue; - } - - this.customLadders.add(new CustomLadder(this, "player-custom-kit." + i, i + 1)); - } catch (NumberFormatException e) { - if (this.file.getConfig().isConfigurationSection("player-custom-kit")) { - CustomLadder oldLadderFormat = new CustomLadder(this, "player-custom-kit", 1); - this.customLadders.add(new CustomLadder(oldLadderFormat, this, "player-custom-kit.0")); - - this.file.getConfig().set("player-custom-kit", null); - this.file.saveFile(); - } - break; - } - } + rankedBan.get(file.getConfig(), "ranked-ban"); - if (!this.customLadders.isEmpty()) { - if (this.file.getConfig().isInt("selected-custom-ladder")) { - int index = this.file.getConfig().getInt("selected-custom-ladder"); - if (index < this.customLadders.size() && index >= 0) { - this.selectedCustomLadder = this.customLadders.get(index); - } - } + loadCustomLadders(); + + fullDataLoaded = true; + } + + private void loadCustomLadders() { + if (!file.getConfig().isConfigurationSection("player-custom-kit")) return; + + customLadders.clear(); + for (String key : Objects.requireNonNull( + file.getConfig().getConfigurationSection("player-custom-kit")).getKeys(false)) { + if (!tryLoadCustomLadder(key)) break; + } + + loadSelectedCustomLadder(); + } + + private boolean tryLoadCustomLadder(String key) { + try { + int i = Integer.parseInt(key); + if (i < 0 || i > 5) return true; + + customLadders.add(new CustomLadder(this, "player-custom-kit." + i, i + 1)); + return true; + } catch (NumberFormatException e) { + if (file.getConfig().isConfigurationSection("player-custom-kit")) { + CustomLadder oldFormat = new CustomLadder(this, "player-custom-kit", 1); + customLadders.add(new CustomLadder(oldFormat, this, "player-custom-kit.0")); + file.getConfig().set("player-custom-kit", null); + file.saveFile(); } + return false; + } + } + + private void loadSelectedCustomLadder() { + if (customLadders.isEmpty()) return; + if (!file.getConfig().isInt("selected-custom-ladder")) return; + + int index = file.getConfig().getInt("selected-custom-ladder"); + if (index >= 0 && index < customLadders.size()) { + selectedCustomLadder = customLadders.get(index); } - this.fullDataLoaded = true; } public synchronized void loadStatsOnlyData() { - this.file.reloadFile(); - this.stats.getLadderStats().clear(); + file.reloadFile(); + stats.getLadderStats().clear(); - if (this.file.getConfig().isLong("join.first")) - this.setFirstJoin(this.file.getConfig().getLong("join.first")); + if (file.getConfig().isLong("join.first")) + setFirstJoin(file.getConfig().getLong("join.first")); - if (this.file.getConfig().isLong("join.latest")) - this.setLastJoin(this.file.getConfig().getLong("join.latest")); + if (file.getConfig().isLong("join.latest")) + setLastJoin(file.getConfig().getLong("join.latest")); - this.stats.getData(); - this.fullDataLoaded = false; + stats.getData(); + fullDataLoaded = false; } public synchronized void ensureFullDataLoaded() { - if (this.fullDataLoaded) { - return; - } + if (fullDataLoaded) return; getData(); } public synchronized void demoteToStatsOnly() { - this.settingsGui = null; - this.playerCustomKitSelector = null; - this.selectedCustomLadder = null; - this.customLadders.clear(); - this.unrankedCustomKits.clear(); - this.rankedCustomKits.clear(); - this.ignoredPlayers.clear(); - this.followTarget = null; - this.actionBar = null; - this.fullDataLoaded = false; + settingsGui = null; + playerCustomKitSelector = null; + selectedCustomLadder = null; + customLadders.clear(); + unrankedCustomKits.clear(); + rankedCustomKits.clear(); + ignoredPlayers.clear(); + followTarget = null; + actionBar = null; + fullDataLoaded = false; } - public boolean isFullDataLoaded() { - return fullDataLoaded; - } + // Group management public void checkGroup() { Player online = getOnlinePlayer(); if (online == null || !online.isOnline()) return; Group newGroup = GroupManager.getInstance().getGroup(online); - - // If newGroup is null (shouldn't happen with our fix, but safety check) - // or if the group has changed, update it if (newGroup == null) { Common.sendConsoleMMMessage("Warning: Could not determine group for " + online.getName() + ". Assigning default (lowest weighted) group to them."); return; @@ -227,7 +245,7 @@ public void checkGroup() { if (group == newGroup) return; try { - this.setGroup(newGroup); + setGroup(newGroup); } catch (Exception e) { Common.sendConsoleMMMessage("Failed to set group for " + online.getName() + "! Error: " + e.getMessage()); } @@ -235,15 +253,9 @@ public void checkGroup() { public int getCustomKitPerm() { Player onlinePlayer = getOnlinePlayer(); + if (onlinePlayer == null) return 0; - if (onlinePlayer == null) { - return 0; - } - - if (this.group != null) { - return this.group.getModifiableKitLimit(); - } - + if (group != null) return group.getModifiableKitLimit(); return -1; } @@ -253,60 +265,62 @@ public void setGroup(Group group) throws IllegalArgumentException { } this.group = group; - this.unrankedLeft = group.getUnrankedLimit(); - this.rankedLeft = group.getRankedLimit(); - this.eventStartLeft = group.getEventStartLimit(); - this.partyBroadcastLeft = group.getPartyBroadcastLimit(); - - Player onlinePlayer = this.getOnlinePlayer(); - if (onlinePlayer != null) { - Party partyObj = PartyManager.getInstance().getParty(onlinePlayer); - if (partyObj != null && onlinePlayer.equals(partyObj.getLeader())) { - partyObj.refreshMaxPlayerLimitForLeader(); - } - } + unrankedLeft = group.getUnrankedLimit(); + rankedLeft = group.getRankedLimit(); + eventStartLeft = group.getEventStartLimit(); + partyBroadcastLeft = group.getPartyBroadcastLimit(); - while (this.customLadders.size() < this.group.getCustomKitLimit()) { - this.customLadders.add(new CustomLadder(this, "player-custom-kit." + customLadders.size(), this.customLadders.size() + 1)); - } + refreshPartyLimit(); + syncCustomLadderCount(); - while (this.customLadders.size() > this.group.getCustomKitLimit()) { - this.customLadders.removeLast(); + // Invalidate the selector so it gets recreated on next access (lazy-loading) + playerCustomKitSelector = null; + } + + private void refreshPartyLimit() { + Player onlinePlayer = getOnlinePlayer(); + if (onlinePlayer == null) return; + + Party partyObj = PartyManager.getInstance().getParty(onlinePlayer); + if (partyObj != null && onlinePlayer.equals(partyObj.getLeader())) { + partyObj.refreshMaxPlayerLimitForLeader(); } + } - // Invalidate the selector so it gets recreated on next access (lazy-loading) - this.playerCustomKitSelector = null; + private void syncCustomLadderCount() { + while (customLadders.size() < group.getCustomKitLimit()) { + customLadders.add(new CustomLadder(this, "player-custom-kit." + customLadders.size(), customLadders.size() + 1)); + } + while (customLadders.size() > group.getCustomKitLimit()) { + customLadders.removeLast(); + } } - /** - * Lazily loads and returns the PlayerCustomKitSelector. - * Creates it only when first accessed to save RAM for offline players. - */ + // Lazy-loaded accessors + public PlayerCustomKitSelector getPlayerCustomKitSelector() { - if (this.playerCustomKitSelector == null) { - this.playerCustomKitSelector = new PlayerCustomKitSelector(this); + if (playerCustomKitSelector == null) { + playerCustomKitSelector = new PlayerCustomKitSelector(this); } - return this.playerCustomKitSelector; + return playerCustomKitSelector; } public ActionBar getActionBar() { - if (this.actionBar == null) { - this.actionBar = new ActionBar(this); + if (actionBar == null) { + actionBar = new ActionBar(this); } - - return this.actionBar; + return actionBar; } + // Setters with side effects + public void setSelectedCustomLadder(CustomLadder customLadder) { - if (customLadder == null) { + if (customLadder == null) throw new IllegalArgumentException("Custom ladder cannot be null."); - } - - if (!customLadders.contains(customLadder)) { + if (!customLadders.contains(customLadder)) throw new IllegalArgumentException("Custom ladder not found in profile."); - } - this.selectedCustomLadder = customLadder; + selectedCustomLadder = customLadder; } public void setStatus(ProfileStatus status) { @@ -315,15 +329,18 @@ public void setStatus(ProfileStatus status) { Bukkit.getPluginManager().callEvent(new ProfileStatusChangeEvent(this, previous, status)); - // Leaving lobby/spectate for a new activity invalidates pending rematches. - if ((previous == ProfileStatus.LOBBY || previous == ProfileStatus.SPECTATE) - && status != ProfileStatus.LOBBY - && status != ProfileStatus.SPECTATE - && status != ProfileStatus.OFFLINE) { - Player online = getOnlinePlayer(); - if (online != null && online.isOnline()) { - MatchManager.getInstance().invalidateRematchByPlayer(online); - } + invalidateRematchIfLeftLobby(previous, status); + } + + private void invalidateRematchIfLeftLobby(ProfileStatus previous, ProfileStatus status) { + boolean wasIdle = previous == ProfileStatus.LOBBY || previous == ProfileStatus.SPECTATE; + boolean isActive = status != ProfileStatus.LOBBY && status != ProfileStatus.SPECTATE && status != ProfileStatus.OFFLINE; + + if (!wasIdle || !isActive) return; + + Player online = getOnlinePlayer(); + if (online != null && online.isOnline()) { + MatchManager.getInstance().invalidateRematchByPlayer(online); } } diff --git a/core/src/main/java/dev/nandi0813/practice/manager/profile/ProfileFile.java b/core/src/main/java/dev/nandi0813/practice/manager/profile/ProfileFile.java index aa4e98c4c..4e0e7279b 100644 --- a/core/src/main/java/dev/nandi0813/practice/manager/profile/ProfileFile.java +++ b/core/src/main/java/dev/nandi0813/practice/manager/profile/ProfileFile.java @@ -42,32 +42,56 @@ public ProfileFile(Profile profile) { @Override public void setData() { + setJoinTimestamps(); + setGroup(); + setPrefix(); + setSuffix(); + setNameTemplate(); + setCustomKitPerm(); + setSettings(); + saveCosmetics(); + saveCustomKits(); + saveFile(); + } + + private void setJoinTimestamps() { config.set("join.latest", profile.getLastJoin()); + } + private void setGroup() { if (profile.getGroup() != null) config.set("group", profile.getGroup().getName()); else config.set("group", null); + } + private void setPrefix() { if (profile.getPrefix() != null) config.set("prefix", dev.nandi0813.practice.ZonePractice.getMiniMessage().serialize(profile.getPrefix())); else config.set("prefix", null); + } + private void setSuffix() { if (profile.getSuffix() != null) config.set("suffix", dev.nandi0813.practice.ZonePractice.getMiniMessage().serialize(profile.getSuffix())); else config.set("suffix", null); + } + private void setNameTemplate() { if (profile.getNameTemplate() != null && !profile.getNameTemplate().isEmpty()) config.set("name-template", profile.getNameTemplate()); else config.set("name-template", null); + } + private void setCustomKitPerm() { int customKitPerm = profile.getCustomKitPerm(); if (customKitPerm > 0) config.set("allowed-custom-kits", customKitPerm); + } - // Basic settings + private void setSettings() { config.set("settings.duelrequest", profile.isDuelRequest()); config.set("settings.sidebar", profile.isSidebar()); config.set("settings.hideplayers", profile.isHidePlayers()); @@ -77,74 +101,67 @@ public void setData() { config.set("settings.messages", profile.isPrivateMessages()); config.set("settings.worldtime", profile.getWorldTime().toString()); config.set("settings.prefix-visibility", profile.getPrefixVisibility().toString()); + } - // Cosmetics data for armor trims - if (profile.getCosmeticsData() != null) { - config.set("cosmetics.active-tier", profile.getCosmeticsData().getActiveTier().getId()); - config.set("cosmetics.death-effect", profile.getCosmeticsData().getDeathEffect().getId()); - config.set("cosmetics.lobby-item", profile.getCosmeticsData().getLobbyItemType().name()); - config.set("cosmetics.shield.active-layout-index", profile.getCosmeticsData().getActiveShieldLayoutIndex()); + private void saveCosmetics() { + if (profile.getCosmeticsData() == null) return; - List serializedShieldLayouts = profile.getCosmeticsData().getShieldLayouts().stream() - .map(ShieldLayout::serialise) - .toList(); - config.set("cosmetics.shield.layouts", serializedShieldLayouts); + config.set("cosmetics.active-tier", profile.getCosmeticsData().getActiveTier().getId()); + config.set("cosmetics.death-effect", profile.getCosmeticsData().getDeathEffect().getId()); + config.set("cosmetics.lobby-item", profile.getCosmeticsData().getLobbyItemType().name()); + config.set("cosmetics.shield.active-layout-index", profile.getCosmeticsData().getActiveShieldLayoutIndex()); - for (ArmorTrimTier tier : ArmorTrimTier.values()) { - for (ArmorSlot slot : ArmorSlot.values()) { - String basePath = "cosmetics.tiers." + tier.getId() + "." + slot.getId(); + List serializedShieldLayouts = profile.getCosmeticsData().getShieldLayouts().stream() + .map(ShieldLayout::serialise) + .toList(); + config.set("cosmetics.shield.layouts", serializedShieldLayouts); - TrimPattern pattern = profile.getCosmeticsData().getPattern(tier, slot); - if (pattern != null) { - config.set(basePath + ".pattern", "minecraft:" + CosmeticsPermissionManager.getTrimId(pattern)); - } else { - config.set(basePath + ".pattern", null); - } + for (ArmorTrimTier tier : ArmorTrimTier.values()) { + for (ArmorSlot slot : ArmorSlot.values()) { + String basePath = "cosmetics.tiers." + tier.getId() + "." + slot.getId(); - TrimMaterial material = profile.getCosmeticsData().getMaterial(tier, slot); - if (material != null) { - config.set(basePath + ".material", "minecraft:" + CosmeticsPermissionManager.getTrimId(material)); - } else { - config.set(basePath + ".material", null); - } + TrimPattern pattern = profile.getCosmeticsData().getPattern(tier, slot); + if (pattern != null) { + config.set(basePath + ".pattern", "minecraft:" + CosmeticsPermissionManager.getTrimId(pattern)); + } else { + config.set(basePath + ".pattern", null); + } + + TrimMaterial material = profile.getCosmeticsData().getMaterial(tier, slot); + if (material != null) { + config.set(basePath + ".material", "minecraft:" + CosmeticsPermissionManager.getTrimId(material)); + } else { + config.set(basePath + ".material", null); } } } + } - // Ladder win/lose stats + private void saveCustomKits() { for (NormalLadder ladder : LadderManager.getInstance().getLadders()) { String name = ladder.getName().toLowerCase(); - for (int i = 1; i <= 4; i++) { - if (!profile.getUnrankedCustomKits().isEmpty()) { - if (profile.getUnrankedCustomKits().containsKey(ladder) && profile.getUnrankedCustomKits().get(ladder).containsKey(i)) { - CustomKit customKit = profile.getUnrankedCustomKits().get(ladder).get(i); - if (customKit != null) { - config.set("customkit." + name + ".kit" + i + ".unranked.inventory", ItemSerializationUtil.itemStackArrayToBase64(customKit.getInventory())); - config.set("customkit." + name + ".kit" + i + ".unranked.armor", ItemSerializationUtil.itemStackArrayToBase64(customKit.getArmor())); - config.set("customkit." + name + ".kit" + i + ".unranked.extra", ItemSerializationUtil.itemStackArrayToBase64(customKit.getExtra())); - } - } - } - } - - if (ladder.isRanked()) { - for (int i = 1; i <= 4; i++) { - if (!profile.getRankedCustomKits().isEmpty()) { - if (profile.getRankedCustomKits().containsKey(ladder) && profile.getRankedCustomKits().get(ladder).containsKey(i)) { - CustomKit customKit = profile.getRankedCustomKits().get(ladder).get(i); - if (customKit != null) { - config.set("customkit." + name + ".kit" + i + ".ranked.inventory", ItemSerializationUtil.itemStackArrayToBase64(customKit.getInventory())); - config.set("customkit." + name + ".kit" + i + ".ranked.armor", ItemSerializationUtil.itemStackArrayToBase64(customKit.getArmor())); - config.set("customkit." + name + ".kit" + i + ".ranked.extra", ItemSerializationUtil.itemStackArrayToBase64(customKit.getExtra())); - } - } - } - } - } + saveCustomKitSet(profile.getUnrankedCustomKits(), ladder, name, "unranked"); + if (ladder.isRanked()) + saveCustomKitSet(profile.getRankedCustomKits(), ladder, name, "ranked"); } + } - saveFile(); + private void saveCustomKitSet(Map> kits, NormalLadder ladder, String name, String type) { + if (kits.isEmpty()) return; + + Map ladderKits = kits.get(ladder); + if (ladderKits == null) return; + + for (int i = 1; i <= 4; i++) { + CustomKit customKit = ladderKits.get(i); + if (customKit == null) continue; + + String base = "customkit." + name + ".kit" + i + "." + type; + config.set(base + ".inventory", ItemSerializationUtil.itemStackArrayToBase64(customKit.getInventory())); + config.set(base + ".armor", ItemSerializationUtil.itemStackArrayToBase64(customKit.getArmor())); + config.set(base + ".extra", ItemSerializationUtil.itemStackArrayToBase64(customKit.getExtra())); + } } public void setDefaultData() { @@ -180,38 +197,62 @@ public void setDefaultData() { @Override public void getData() { + loadJoinTimestamps(); + loadGroup(); + loadPrefix(); + loadSuffix(); + loadNameTemplate(); + loadCustomKitPerm(); + loadSettings(); + loadCosmetics(); + loadCustomKits(); + } + + private void loadJoinTimestamps() { if (config.isLong("join.first")) profile.setFirstJoin(config.getLong("join.first")); if (config.isLong("join.latest")) profile.setLastJoin(config.getLong("join.latest")); + } - if (config.isSet("group")) { - Group group = GroupManager.getInstance().getGroup(config.getString("group")); - if (group != null) { - try { - profile.setGroup(group); - } catch (Exception e) { - Common.sendConsoleMMMessage("Failed to set group for " + profile.getPlayer().getName() + "! Error: " + e.getMessage()); - } - profile.setUnrankedLeft(group.getUnrankedLimit()); - profile.setRankedLeft(group.getRankedLimit()); - profile.setEventStartLeft(group.getEventStartLimit()); + private void loadGroup() { + if (!config.isSet("group")) return; + + Group group = GroupManager.getInstance().getGroup(config.getString("group")); + if (group != null) { + try { + profile.setGroup(group); + } catch (Exception e) { + Common.sendConsoleMMMessage("Failed to set group for " + profile.getPlayer().getName() + "! Error: " + e.getMessage()); } + profile.setUnrankedLeft(group.getUnrankedLimit()); + profile.setRankedLeft(group.getRankedLimit()); + profile.setEventStartLeft(group.getEventStartLimit()); } + } + private void loadPrefix() { if (config.isString("prefix")) profile.setPrefix(NameFormatUtil.parseConfiguredComponent(Objects.requireNonNull(config.getString("prefix")))); + } + private void loadSuffix() { if (config.isString("suffix")) profile.setSuffix(NameFormatUtil.parseConfiguredComponent(Objects.requireNonNull(config.getString("suffix")))); + } + private void loadNameTemplate() { if (config.isString("name-template")) profile.setNameTemplate(config.getString("name-template")); + } + private void loadCustomKitPerm() { if (config.isInt("allowed-custom-kits")) profile.setAllowedCustomKits(config.getInt("allowed-custom-kits")); + } + private void loadSettings() { profile.setDuelRequest(config.getBoolean("settings.duelrequest")); profile.setSidebar(config.getBoolean("settings.sidebar")); profile.setHidePlayers(config.getBoolean("settings.hideplayers")); @@ -219,6 +260,7 @@ public void getData() { profile.setAllowSpectate(config.getBoolean("settings.allowspectate")); profile.setFlying(config.getBoolean("settings.flying")); profile.setPrivateMessages(config.getBoolean("settings.messages")); + String rawWorldTime = config.getString("settings.worldtime", ProfileWorldTime.DAY.toString()); try { profile.setWorldTime(ProfileWorldTime.valueOf(rawWorldTime.toUpperCase(Locale.ROOT))); @@ -232,8 +274,9 @@ public void getData() { } catch (IllegalArgumentException ignored) { profile.setPrefixVisibility(ProfilePrefixVisibility.PREFIX_AND_SUFFIX); } + } - // Load cosmetics data for armor trims + private void loadCosmetics() { try { ArmorTrimTier activeTier = ArmorTrimTier.fromId(config.getString("cosmetics.active-tier", "leather")); profile.getCosmeticsData().setActiveTier(activeTier); @@ -300,76 +343,35 @@ public void getData() { } catch (Exception e) { // Handle invalid cosmetics data - silently ignore for graceful handling of removed/renamed cosmetics } + } + private void loadCustomKits() { for (NormalLadder ladder : LadderManager.getInstance().getLadders()) { String name = ladder.getName().toLowerCase(); - // Unranked custom kit - Map unrankedInventory = new HashMap<>(); - for (int i = 1; i <= 4; i++) { - ItemStack[] inventory; - ItemStack[] armor; - ItemStack[] extra; - - if (config.isString("customkit." + name.toLowerCase() + ".kit" + i + ".unranked.inventory")) { - inventory = ItemSerializationUtil.itemStackArrayFromBase64(config.getString("customkit." + name.toLowerCase() + ".kit" + i + ".unranked.inventory")); - armor = config.isString("customkit." + name.toLowerCase() + ".kit" + i + ".unranked.armor") - ? ItemSerializationUtil.itemStackArrayFromBase64(config.getString("customkit." + name.toLowerCase() + ".kit" + i + ".unranked.armor")) - : null; - extra = ItemSerializationUtil.itemStackArrayFromBase64(config.getString("customkit." + name.toLowerCase() + ".kit" + i + ".unranked.extra")); - - // Legacy migration: old format stored armor in inventory[36..39] - if (armor == null && inventory != null && inventory.length > 36) { - ItemStack[] splitInventory = new ItemStack[36]; - System.arraycopy(inventory, 0, splitInventory, 0, 36); - armor = new ItemStack[]{ - inventory.length > 36 ? inventory[36] : null, - inventory.length > 37 ? inventory[37] : null, - inventory.length > 38 ? inventory[38] : null, - inventory.length > 39 ? inventory[39] : null - }; - inventory = splitInventory; - } + profile.getUnrankedCustomKits().put(ladder, loadCustomKitSet(ladder, name, "unranked")); + if (ladder.isRanked()) + profile.getRankedCustomKits().put(ladder, loadCustomKitSet(ladder, name, "ranked")); + } + } - unrankedInventory.put(i, new CustomKit(null, inventory, armor, extra)); - } - } - profile.getUnrankedCustomKits().put(ladder, unrankedInventory); - - if (ladder.isRanked()) { - // Ranked custom kit - Map rankedInventory = new HashMap<>(); - for (int i = 1; i <= 4; i++) { - ItemStack[] inventory; - ItemStack[] armor; - ItemStack[] extra; - - if (config.isString("customkit." + name.toLowerCase() + ".kit" + i + ".ranked.inventory")) { - inventory = ItemSerializationUtil.itemStackArrayFromBase64(config.getString("customkit." + name.toLowerCase() + ".kit" + i + ".ranked.inventory")); - armor = config.isString("customkit." + name.toLowerCase() + ".kit" + i + ".ranked.armor") - ? ItemSerializationUtil.itemStackArrayFromBase64(config.getString("customkit." + name.toLowerCase() + ".kit" + i + ".ranked.armor")) - : null; - extra = ItemSerializationUtil.itemStackArrayFromBase64(config.getString("customkit." + name.toLowerCase() + ".kit" + i + ".ranked.extra")); - - // Legacy migration: old format stored armor in inventory[36..39] - if (armor == null && inventory != null && inventory.length > 36) { - ItemStack[] splitInventory = new ItemStack[36]; - System.arraycopy(inventory, 0, splitInventory, 0, 36); - armor = new ItemStack[]{ - inventory.length > 36 ? inventory[36] : null, - inventory.length > 37 ? inventory[37] : null, - inventory.length > 38 ? inventory[38] : null, - inventory.length > 39 ? inventory[39] : null - }; - inventory = splitInventory; - } + private Map loadCustomKitSet(NormalLadder ladder, String name, String type) { + Map result = new HashMap<>(); - rankedInventory.put(i, new CustomKit(null, inventory, armor, extra)); - } - } - profile.getRankedCustomKits().put(ladder, rankedInventory); - } + for (int i = 1; i <= 4; i++) { + String base = "customkit." + name + ".kit" + i + "." + type; + if (!config.isString(base + ".inventory")) continue; + + ItemStack[] inventory = ItemSerializationUtil.itemStackArrayFromBase64(config.getString(base + ".inventory")); + ItemStack[] armor = config.isString(base + ".armor") + ? ItemSerializationUtil.itemStackArrayFromBase64(config.getString(base + ".armor")) + : null; + ItemStack[] extra = ItemSerializationUtil.itemStackArrayFromBase64(config.getString(base + ".extra")); + + result.put(i, new CustomKit(null, inventory, armor, extra)); } + + return result; } public void deleteCustomKit(Ladder ladder, int kit) { diff --git a/core/src/main/java/dev/nandi0813/practice/manager/profile/ProfileManager.java b/core/src/main/java/dev/nandi0813/practice/manager/profile/ProfileManager.java index 6bd86bec0..5b67792d0 100644 --- a/core/src/main/java/dev/nandi0813/practice/manager/profile/ProfileManager.java +++ b/core/src/main/java/dev/nandi0813/practice/manager/profile/ProfileManager.java @@ -54,18 +54,19 @@ public Profile getProfile(UUID uuid) { } public Profile getProfile(Player player) { - if (player == null) return null; - + if (player == null) { + return null; + } UUID uuid = player.getUniqueId(); uuids.put(player, uuid); Profile profile = profiles.get(uuid); if (profile == null) { - profile = loadProfileIfExists(uuid, player, true); - } else if (!profile.isFullDataLoaded()) { + return loadProfileIfExists(uuid, player, true); + } + if (!profile.isFullDataLoaded()) { profile.ensureFullDataLoaded(); loadProfileInfo(profile); } - return profile; } @@ -90,14 +91,14 @@ public Profile getProfile(Entity entity) { } public Profile newProfile(Player player, UUID uuid) { - final Profile profile = new Profile(uuid); + Profile profile = new Profile(uuid); profile.getFile().setDefaultData(); profile.getData(); profile.getStats().setDivision(DivisionManager.getInstance().getDivision(profile)); - ProfileManager.getInstance().getProfiles().put(uuid, profile); - ProfileManager.getInstance().loadProfileInfo(profile); + profiles.put(uuid, profile); + loadProfileInfo(profile); Bukkit.getScheduler().runTaskLater(ZonePractice.getInstance(), () -> Bukkit.getPluginManager().callEvent(new NewPlayerJoin(player)), 20L * 2); @@ -108,34 +109,10 @@ public Profile newProfile(Player player, UUID uuid) { public void loadProfiles(final StartUpCallback startUpCallback) { Bukkit.getScheduler().runTaskAsynchronously(ZonePractice.getInstance(), () -> { - if (!folder.exists() && !folder.mkdirs()) { - Common.sendConsoleMMMessage("Error: Could not create profiles folder."); - } - - if (folder.isDirectory() && folder.listFiles() != null) { - for (File profileFile : Objects.requireNonNull(folder.listFiles())) { - if (profileFile.isFile() && profileFile.getName().endsWith(".yml")) { - YamlConfiguration config = YamlConfiguration.loadConfiguration(profileFile); - String uuidString = config.getString("uuid"); - UUID uuid = parseUuid(uuidString); - - if (uuid == null) { - Common.sendConsoleMMMessage("Warning: Skipping corrupted profile file " + profileFile.getName() + " (invalid or missing uuid: " + uuidString + ")"); - continue; - } - - OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(uuid); - Profile profile = new Profile(uuid, offlinePlayer); - profile.loadStatsOnlyData(); - profile.getStats().setDivision(DivisionManager.getInstance().getDivision(profile)); - profiles.put(uuid, profile); - } - } - } + loadProfilesFromDisk(); - Collection loadedProfiles = ProfileManager.getInstance().getProfiles().values(); - CompletableFuture loadFuture = MysqlManager.loadProfilesAsync(loadedProfiles); - loadFuture.whenComplete((ignored, throwable) -> { + Collection loadedProfiles = profiles.values(); + MysqlManager.loadProfilesAsync(loadedProfiles).whenComplete((ignored, throwable) -> { if (throwable != null) { Common.sendConsoleMMMessage("Error: " + throwable.getMessage()); } @@ -144,6 +121,36 @@ public void loadProfiles(final StartUpCallback startUpCallback) { }); } + private void loadProfilesFromDisk() { + if (!folder.exists() && !folder.mkdirs()) { + Common.sendConsoleMMMessage("Error: Could not create profiles folder."); + } + + if (!folder.isDirectory()) return; + + File[] files = folder.listFiles(); + if (files == null) return; + + for (File profileFile : files) { + if (!profileFile.isFile() || !profileFile.getName().endsWith(".yml")) continue; + + YamlConfiguration config = YamlConfiguration.loadConfiguration(profileFile); + String uuidString = config.getString("uuid"); + UUID uuid = parseUuid(uuidString); + + if (uuid == null) { + Common.sendConsoleMMMessage("Warning: Skipping corrupted profile file " + profileFile.getName() + " (invalid or missing uuid: " + uuidString + ")"); + continue; + } + + OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(uuid); + Profile profile = new Profile(uuid, offlinePlayer); + profile.loadStatsOnlyData(); + profile.getStats().setDivision(DivisionManager.getInstance().getDivision(profile)); + profiles.put(uuid, profile); + } + } + private UUID parseUuid(String uuidString) { if (uuidString == null || uuidString.isBlank()) return null; diff --git a/core/src/main/java/dev/nandi0813/practice/manager/profile/cosmetics/CosmeticsData.java b/core/src/main/java/dev/nandi0813/practice/manager/profile/cosmetics/CosmeticsData.java index 2cf6a77ec..02bff9e22 100644 --- a/core/src/main/java/dev/nandi0813/practice/manager/profile/cosmetics/CosmeticsData.java +++ b/core/src/main/java/dev/nandi0813/practice/manager/profile/cosmetics/CosmeticsData.java @@ -96,7 +96,7 @@ private SlotData getSlotData(ArmorTrimTier tier, ArmorSlot slot) { tierData.put(resolvedTier, bySlot); } - return bySlot.computeIfAbsent(slot, k -> new SlotData()); + return bySlot.computeIfAbsent(slot, _ -> new SlotData()); } public ShieldLayout getActiveShieldLayout() { diff --git a/core/src/main/java/dev/nandi0813/practice/manager/profile/cosmetics/armortrim/CosmeticsPermissionSanitizer.java b/core/src/main/java/dev/nandi0813/practice/manager/profile/cosmetics/armortrim/CosmeticsPermissionSanitizer.java index 818cb940a..b200f41c8 100644 --- a/core/src/main/java/dev/nandi0813/practice/manager/profile/cosmetics/armortrim/CosmeticsPermissionSanitizer.java +++ b/core/src/main/java/dev/nandi0813/practice/manager/profile/cosmetics/armortrim/CosmeticsPermissionSanitizer.java @@ -13,9 +13,9 @@ public enum CosmeticsPermissionSanitizer { ; - public static boolean sanitize(Player player, Profile profile) { + public static void sanitize(Player player, Profile profile) { if (player == null || profile == null || profile.getCosmeticsData() == null) { - return false; + return; } boolean changed = false; @@ -95,7 +95,7 @@ public static boolean sanitize(Player player, Profile profile) { int maxShieldLayouts = CosmeticsPermissionManager.getMaxShieldLayouts(player); var shieldLayouts = profile.getCosmeticsData().getShieldLayouts(); while (shieldLayouts.size() > maxShieldLayouts) { - shieldLayouts.remove(shieldLayouts.size() - 1); + shieldLayouts.removeLast(); changed = true; } @@ -113,7 +113,6 @@ public static boolean sanitize(Player player, Profile profile) { profile.saveData(); } - return changed; } } diff --git a/core/src/main/java/dev/nandi0813/practice/manager/profile/enums/ProfilePrefixVisibility.java b/core/src/main/java/dev/nandi0813/practice/manager/profile/enums/ProfilePrefixVisibility.java index bd90d2132..e37523844 100644 --- a/core/src/main/java/dev/nandi0813/practice/manager/profile/enums/ProfilePrefixVisibility.java +++ b/core/src/main/java/dev/nandi0813/practice/manager/profile/enums/ProfilePrefixVisibility.java @@ -33,12 +33,12 @@ public static ProfilePrefixVisibility getNext(ProfilePrefixVisibility current) { if (current != null) { int index = list.indexOf(current); if (index == list.size() - 1) { - return list.get(0); + return list.getFirst(); } return list.get(index + 1); } - return list.get(0); + return list.getFirst(); } } diff --git a/core/src/main/java/dev/nandi0813/practice/manager/profile/enums/ProfileWorldTime.java b/core/src/main/java/dev/nandi0813/practice/manager/profile/enums/ProfileWorldTime.java index 65f9d134b..2da0eb1de 100644 --- a/core/src/main/java/dev/nandi0813/practice/manager/profile/enums/ProfileWorldTime.java +++ b/core/src/main/java/dev/nandi0813/practice/manager/profile/enums/ProfileWorldTime.java @@ -31,11 +31,11 @@ public static ProfileWorldTime getNextWorldTime(ProfileWorldTime profileWorldTim int c = list.indexOf(profileWorldTime); if (list.size() - 1 == c) - return list.get(0); + return list.getFirst(); else return list.get(c + 1); } else - return list.get(0); + return list.getFirst(); } } diff --git a/core/src/main/java/dev/nandi0813/practice/manager/profile/statistics/LadderStats.java b/core/src/main/java/dev/nandi0813/practice/manager/profile/statistics/LadderStats.java index 50469fe21..c10c9baa1 100644 --- a/core/src/main/java/dev/nandi0813/practice/manager/profile/statistics/LadderStats.java +++ b/core/src/main/java/dev/nandi0813/practice/manager/profile/statistics/LadderStats.java @@ -105,51 +105,53 @@ public void increaseDeaths() { } public void setData(String ladderName, boolean ranked) { - config.set("stats.ladder-stats." + ladderName + ".unranked.wins", unRankedWins); - config.set("stats.ladder-stats." + ladderName + ".unranked.losses", unRankedLosses); - config.set("stats.ladder-stats." + ladderName + ".unranked.win-streak", unRankedWinStreak); - config.set("stats.ladder-stats." + ladderName + ".unranked.best-win-streak", unRankedBestWinStreak); - config.set("stats.ladder-stats." + ladderName + ".unranked.lose-streak", unRankedLoseStreak); - config.set("stats.ladder-stats." + ladderName + ".unranked.best-lose-streak", unRankedBestLoseStreak); + String base = "stats.ladder-stats." + ladderName; + config.set(base + ".unranked.wins", unRankedWins); + config.set(base + ".unranked.losses", unRankedLosses); + config.set(base + ".unranked.win-streak", unRankedWinStreak); + config.set(base + ".unranked.best-win-streak", unRankedBestWinStreak); + config.set(base + ".unranked.lose-streak", unRankedLoseStreak); + config.set(base + ".unranked.best-lose-streak", unRankedBestLoseStreak); if (ranked) { - config.set("stats.ladder-stats." + ladderName + ".ranked.wins", rankedWins); - config.set("stats.ladder-stats." + ladderName + ".ranked.losses", rankedLosses); - config.set("stats.ladder-stats." + ladderName + ".ranked.win-streak", rankedWinStreak); - config.set("stats.ladder-stats." + ladderName + ".ranked.best-win-streak", rankedBestWinStreak); - config.set("stats.ladder-stats." + ladderName + ".ranked.lose-streak", rankedLoseStreak); - config.set("stats.ladder-stats." + ladderName + ".ranked.best-lose-streak", rankedBestLoseStreak); - config.set("stats.ladder-stats." + ladderName + ".ranked.elo", elo != 0 ? elo : LadderManager.getDEFAULT_ELO()); + config.set(base + ".ranked.wins", rankedWins); + config.set(base + ".ranked.losses", rankedLosses); + config.set(base + ".ranked.win-streak", rankedWinStreak); + config.set(base + ".ranked.best-win-streak", rankedBestWinStreak); + config.set(base + ".ranked.lose-streak", rankedLoseStreak); + config.set(base + ".ranked.best-lose-streak", rankedBestLoseStreak); + config.set(base + ".ranked.elo", elo != 0 ? elo : LadderManager.getDEFAULT_ELO()); } - config.set("stats.ladder-stats." + ladderName + ".global.kills", kills); - config.set("stats.ladder-stats." + ladderName + ".global.deaths", deaths); + config.set(base + ".global.kills", kills); + config.set(base + ".global.deaths", deaths); } public void getData(String ladderName, boolean ranked) { - this.unRankedWins = config.getInt("stats.ladder-stats." + ladderName + ".unranked.wins"); - this.unRankedLosses = config.getInt("stats.ladder-stats." + ladderName + ".unranked.losses"); - this.unRankedWinStreak = config.getInt("stats.ladder-stats." + ladderName + ".unranked.win-streak"); - this.unRankedBestWinStreak = config.getInt("stats.ladder-stats." + ladderName + ".unranked.best-win-streak"); - this.unRankedLoseStreak = config.getInt("stats.ladder-stats." + ladderName + ".unranked.lose-streak"); - this.unRankedBestLoseStreak = config.getInt("stats.ladder-stats." + ladderName + ".unranked.best-lose-streak"); + String base = "stats.ladder-stats." + ladderName; + this.unRankedWins = config.getInt(base + ".unranked.wins"); + this.unRankedLosses = config.getInt(base + ".unranked.losses"); + this.unRankedWinStreak = config.getInt(base + ".unranked.win-streak"); + this.unRankedBestWinStreak = config.getInt(base + ".unranked.best-win-streak"); + this.unRankedLoseStreak = config.getInt(base + ".unranked.lose-streak"); + this.unRankedBestLoseStreak = config.getInt(base + ".unranked.best-lose-streak"); if (ranked) { - this.rankedWins = config.getInt("stats.ladder-stats." + ladderName + ".ranked.wins"); - this.rankedLosses = config.getInt("stats.ladder-stats." + ladderName + ".ranked.losses"); - this.rankedWinStreak = config.getInt("stats.ladder-stats." + ladderName + ".ranked.win-streak"); - this.rankedBestWinStreak = config.getInt("stats.ladder-stats." + ladderName + ".ranked.best-win-streak"); - this.rankedLoseStreak = config.getInt("stats.ladder-stats." + ladderName + ".ranked.lose-streak"); - this.rankedBestLoseStreak = config.getInt("stats.ladder-stats." + ladderName + ".ranked.best-lose-streak"); - this.elo = config.getInt("stats.ladder-stats." + ladderName + ".ranked.elo"); + this.rankedWins = config.getInt(base + ".ranked.wins"); + this.rankedLosses = config.getInt(base + ".ranked.losses"); + this.rankedWinStreak = config.getInt(base + ".ranked.win-streak"); + this.rankedBestWinStreak = config.getInt(base + ".ranked.best-win-streak"); + this.rankedLoseStreak = config.getInt(base + ".ranked.lose-streak"); + this.rankedBestLoseStreak = config.getInt(base + ".ranked.best-lose-streak"); + this.elo = config.getInt(base + ".ranked.elo"); if (this.elo == 0) { this.elo = LadderManager.getDEFAULT_ELO(); } } - this.kills = config.getInt("stats.ladder-stats." + ladderName + ".global.kills"); - this.deaths = config.getInt("stats.ladder-stats." + ladderName + ".global.deaths"); + this.kills = config.getInt(base + ".global.kills"); + this.deaths = config.getInt(base + ".global.deaths"); } public void reset() { diff --git a/core/src/main/java/dev/nandi0813/practice/manager/profile/statistics/ProfileStat.java b/core/src/main/java/dev/nandi0813/practice/manager/profile/statistics/ProfileStat.java index f193fee4e..c8780d419 100644 --- a/core/src/main/java/dev/nandi0813/practice/manager/profile/statistics/ProfileStat.java +++ b/core/src/main/java/dev/nandi0813/practice/manager/profile/statistics/ProfileStat.java @@ -86,20 +86,11 @@ public void increaseLoseStreak(NormalLadder ladder, boolean ranked) { } public void setData(boolean save) { - if (experience != 0) config.set("experience", experience); - else config.set("experience", null); - - if (winStreak != 0) config.set("winStreak", winStreak); - else config.set("winStreak", null); - - if (bestWinStreak != 0) config.set("bestWinStreak", bestWinStreak); - else config.set("bestWinStreak", null); - - if (loseStreak != 0) config.set("loseStreak", loseStreak); - else config.set("loseStreak", null); - - if (bestLoseStreak != 0) config.set("bestLoseStreak", bestLoseStreak); - else config.set("bestLoseStreak", null); + setConfigIntIfNonZero("experience", experience); + setConfigIntIfNonZero("winStreak", winStreak); + setConfigIntIfNonZero("bestWinStreak", bestWinStreak); + setConfigIntIfNonZero("loseStreak", loseStreak); + setConfigIntIfNonZero("bestLoseStreak", bestLoseStreak); for (NormalLadder ladder : LadderManager.getInstance().getLadders()) { getLadderStat(ladder).setData(ladder.getName().toLowerCase(), ladder.isRanked()); @@ -109,21 +100,19 @@ public void setData(boolean save) { profileFile.saveFile(); } - public void getData() { - if (config.isInt("experience")) - this.setExperience(config.getInt("experience")); - - if (config.isInt("winStreak")) - this.setWinStreak(config.getInt("winStreak")); - - if (config.isInt("bestWinStreak")) - this.setBestWinStreak(config.getInt("bestWinStreak")); - - if (config.isInt("loseStreak")) - this.setLoseStreak(config.getInt("loseStreak")); + private void setConfigIntIfNonZero(String path, int value) { + if (value != 0) + config.set(path, value); + else + config.set(path, null); + } - if (config.isInt("bestLoseStreak")) - this.setBestLoseStreak(config.getInt("bestLoseStreak")); + public void getData() { + setExperience(getConfigInt("experience")); + setWinStreak(getConfigInt("winStreak")); + setBestWinStreak(getConfigInt("bestWinStreak")); + setLoseStreak(getConfigInt("loseStreak")); + setBestLoseStreak(getConfigInt("bestLoseStreak")); for (NormalLadder ladder : LadderManager.getInstance().getLadders()) { LadderStats ladderStat = new LadderStats(config); @@ -132,6 +121,10 @@ public void getData() { } } + private int getConfigInt(String path) { + return config.isInt(path) ? config.getInt(path) : 0; + } + public void loadDefaultStats(NormalLadder ladder) { LadderStats ladderStat = getLadderStat(ladder); ladderStat.reset(); From 9fe526583e30ada17568797d44d6a32320954f2f Mon Sep 17 00:00:00 2001 From: lokspel <208148594+lokspel@users.noreply.github.com> Date: Mon, 18 May 2026 20:37:41 +0400 Subject: [PATCH 8/9] Refactor Profile --- .../practice/manager/profile/Profile.java | 4 +- .../practice/manager/profile/RankedBan.java | 81 ++++----- .../profile/cosmetics/CosmeticsData.java | 31 +--- .../profile/statistics/LadderStats.java | 159 +++++++++--------- 4 files changed, 128 insertions(+), 147 deletions(-) diff --git a/core/src/main/java/dev/nandi0813/practice/manager/profile/Profile.java b/core/src/main/java/dev/nandi0813/practice/manager/profile/Profile.java index c9b424e6c..6bd58f81c 100644 --- a/core/src/main/java/dev/nandi0813/practice/manager/profile/Profile.java +++ b/core/src/main/java/dev/nandi0813/practice/manager/profile/Profile.java @@ -128,7 +128,7 @@ public Player getOnlinePlayer() { // Data persistence public void saveData() { - rankedBan.set(file.getConfig(), "ranked-ban"); + rankedBan.saveToConfig(file.getConfig(), "ranked-ban"); saveCustomLadders(); @@ -150,7 +150,7 @@ public void getData() { file.getData(); stats.getData(); - rankedBan.get(file.getConfig(), "ranked-ban"); + rankedBan.loadFromConfig(file.getConfig(), "ranked-ban"); loadCustomLadders(); diff --git a/core/src/main/java/dev/nandi0813/practice/manager/profile/RankedBan.java b/core/src/main/java/dev/nandi0813/practice/manager/profile/RankedBan.java index 593fcb169..a3ffecae2 100644 --- a/core/src/main/java/dev/nandi0813/practice/manager/profile/RankedBan.java +++ b/core/src/main/java/dev/nandi0813/practice/manager/profile/RankedBan.java @@ -13,59 +13,60 @@ @Setter public class RankedBan { - private Profile banner = null; - private boolean banned = false; - private String reason = null; - private long time = 0L; + private Profile banner; + private boolean banned; + private String reason; + private long time; public boolean ban(Profile banner, String reason) { - if (!this.banned) { - this.banned = true; - this.banner = banner; - this.reason = reason; - this.time = System.currentTimeMillis(); - return true; - } - return false; + if (banned) return false; + + this.banned = true; + this.banner = banner; + this.reason = reason; + this.time = System.currentTimeMillis(); + return true; } public boolean unban() { - if (this.banned) { - this.banned = false; - this.reason = null; - return true; - } - return false; + if (!banned) return false; + + this.banned = false; + this.reason = null; + return true; } - public void set(final @NotNull YamlConfiguration config, final String path) { - if (this.isBanned()) { - if (banner != null) - config.set(path + ".banner", this.getBanner().getUuid().toString()); - config.set(path + ".banned", true); - config.set(path + ".reason", this.getReason()); - config.set(path + ".bannedAt", this.getTime()); - } else + public void saveToConfig(final @NotNull YamlConfiguration config, final String path) { + if (!isBanned()) { config.set(path, null); + return; + } + + if (banner != null) + config.set(path + ".banner", banner.getUuid().toString()); + + config.set(path + ".banned", true); + config.set(path + ".reason", reason); + config.set(path + ".bannedAt", time); } - public void get(final @NotNull YamlConfiguration config, final String path) { - if (config.isBoolean(path + ".banned")) - this.banned = config.getBoolean(path + ".banned"); + public void loadFromConfig(final @NotNull YamlConfiguration config, final String path) { + if (!config.isBoolean(path + ".banned")) return; - if (this.isBanned()) { - Bukkit.getScheduler().runTaskLater(ZonePractice.getInstance(), () -> - { - if (config.isString(path + ".banner")) - banner = ProfileManager.getInstance().getProfile(UUID.fromString(config.getString(path + ".banner"))); - }, 20L * 3); + banned = config.getBoolean(path + ".banned"); - if (config.isString(path + ".reason")) - this.reason = config.getString(path + ".reason"); + if (!isBanned()) return; - if (config.isLong(path + ".bannedAt")) - this.time = config.getLong(path + ".bannedAt"); - } + Bukkit.getScheduler().runTaskLater(ZonePractice.getInstance(), () -> { + if (config.isString(path + ".banner")) + banner = ProfileManager.getInstance().getProfile(UUID.fromString(config.getString(path + ".banner"))); + }, 20L * 3); + + if (config.isString(path + ".reason")) + reason = config.getString(path + ".reason"); + + if (config.isLong(path + ".bannedAt")) + time = config.getLong(path + ".bannedAt"); } } diff --git a/core/src/main/java/dev/nandi0813/practice/manager/profile/cosmetics/CosmeticsData.java b/core/src/main/java/dev/nandi0813/practice/manager/profile/cosmetics/CosmeticsData.java index 02bff9e22..f39e23e09 100644 --- a/core/src/main/java/dev/nandi0813/practice/manager/profile/cosmetics/CosmeticsData.java +++ b/core/src/main/java/dev/nandi0813/practice/manager/profile/cosmetics/CosmeticsData.java @@ -41,18 +41,14 @@ public String getPermissionNode() { public CosmeticsData() { for (ArmorTrimTier tier : ArmorTrimTier.values()) { Map bySlot = new EnumMap<>(ArmorSlot.class); - for (ArmorSlot armorSlot : ArmorSlot.values()) { + for (ArmorSlot armorSlot : ArmorSlot.values()) bySlot.put(armorSlot, new SlotData()); - } tierData.put(tier, bySlot); } } public TrimPattern getPattern(ArmorTrimTier tier, ArmorSlot slot) { - if (slot == null) { - return null; - } - + if (slot == null) return null; return getSlotData(tier, slot).pattern; } @@ -61,18 +57,12 @@ public TrimMaterial getMaterial(ArmorSlot slot) { } public TrimMaterial getMaterial(ArmorTrimTier tier, ArmorSlot slot) { - if (slot == null) { - return null; - } - + if (slot == null) return null; return getSlotData(tier, slot).material; } public void setPattern(ArmorTrimTier tier, ArmorSlot slot, TrimPattern pattern) { - if (slot == null) { - return; - } - + if (slot == null) return; getSlotData(tier, slot).pattern = pattern; } @@ -81,10 +71,7 @@ public void setMaterial(ArmorSlot slot, TrimMaterial material) { } public void setMaterial(ArmorTrimTier tier, ArmorSlot slot, TrimMaterial material) { - if (slot == null) { - return; - } - + if (slot == null) return; getSlotData(tier, slot).material = material; } @@ -113,14 +100,14 @@ public void setLobbyItemType(LobbyItemType lobbyItemType) { } public void setShieldLayouts(List layouts) { - this.shieldLayouts.clear(); - if (layouts != null) { - this.shieldLayouts.addAll(layouts); - } + shieldLayouts.clear(); + if (layouts != null) + shieldLayouts.addAll(layouts); } private static final class SlotData { private TrimPattern pattern; private TrimMaterial material; } + } diff --git a/core/src/main/java/dev/nandi0813/practice/manager/profile/statistics/LadderStats.java b/core/src/main/java/dev/nandi0813/practice/manager/profile/statistics/LadderStats.java index c10c9baa1..468b9a6c1 100644 --- a/core/src/main/java/dev/nandi0813/practice/manager/profile/statistics/LadderStats.java +++ b/core/src/main/java/dev/nandi0813/practice/manager/profile/statistics/LadderStats.java @@ -11,77 +11,71 @@ public class LadderStats { private final YamlConfiguration config; - private int unRankedWins = 0; - private int unRankedLosses = 0; - private int unRankedWinStreak = 0; - private int unRankedBestWinStreak = 0; - private int unRankedLoseStreak = 0; - private int unRankedBestLoseStreak = 0; - - private int rankedWins = 0; - private int rankedLosses = 0; - private int rankedWinStreak = 0; - private int rankedBestWinStreak = 0; - private int rankedLoseStreak = 0; - private int rankedBestLoseStreak = 0; + private int unRankedWins; + private int unRankedLosses; + private int unRankedWinStreak; + private int unRankedBestWinStreak; + private int unRankedLoseStreak; + private int unRankedBestLoseStreak; + + private int rankedWins; + private int rankedLosses; + private int rankedWinStreak; + private int rankedBestWinStreak; + private int rankedLoseStreak; + private int rankedBestLoseStreak; private int elo = LadderManager.getDEFAULT_ELO(); - private int kills = 0; - private int deaths = 0; + private int kills; + private int deaths; public LadderStats(YamlConfiguration config) { this.config = config; } public void increaseWins(boolean ranked) { - if (ranked) { - this.rankedWins++; - } else { - this.unRankedWins++; - } + if (ranked) + rankedWins++; + else + unRankedWins++; } public void increaseLosses(boolean ranked) { - if (ranked) { - this.rankedLosses++; - } else { - this.unRankedLosses++; - } + if (ranked) + rankedLosses++; + else + unRankedLosses++; } public void increaseWinStreak(boolean ranked) { if (ranked) { - this.rankedWinStreak++; - this.rankedLoseStreak = 0; + rankedWinStreak++; + rankedLoseStreak = 0; - if (this.rankedWinStreak > this.rankedBestWinStreak) { - this.rankedBestWinStreak = this.rankedWinStreak; - } + if (rankedWinStreak > rankedBestWinStreak) + rankedBestWinStreak = rankedWinStreak; } else { - this.unRankedWinStreak++; - this.unRankedLoseStreak = 0; + unRankedWinStreak++; + unRankedLoseStreak = 0; - if (this.unRankedWinStreak > this.unRankedBestWinStreak) { - this.unRankedBestWinStreak = this.unRankedWinStreak; - } + if (unRankedWinStreak > unRankedBestWinStreak) + unRankedBestWinStreak = unRankedWinStreak; } } public void increaseLoseStreak(boolean ranked) { if (ranked) { - this.rankedLoseStreak++; - this.rankedWinStreak = 0; + rankedLoseStreak++; + rankedWinStreak = 0; - if (this.rankedLoseStreak > this.rankedBestLoseStreak) { - this.rankedBestLoseStreak = this.rankedLoseStreak; - } + if (rankedLoseStreak > rankedBestLoseStreak) + rankedBestLoseStreak = rankedLoseStreak; } else { - this.unRankedLoseStreak++; - this.unRankedWinStreak = 0; + unRankedLoseStreak++; + unRankedWinStreak = 0; - if (this.unRankedLoseStreak > this.unRankedBestLoseStreak) { - this.unRankedBestLoseStreak = this.unRankedLoseStreak; - } + if (unRankedLoseStreak > unRankedBestLoseStreak) + unRankedBestLoseStreak = unRankedLoseStreak; } } @@ -97,11 +91,11 @@ public void decreaseElo(int elo) { } public void increaseKills() { - this.kills++; + kills++; } public void increaseDeaths() { - this.deaths++; + deaths++; } public void setData(String ladderName, boolean ranked) { @@ -129,49 +123,48 @@ public void setData(String ladderName, boolean ranked) { public void getData(String ladderName, boolean ranked) { String base = "stats.ladder-stats." + ladderName; - this.unRankedWins = config.getInt(base + ".unranked.wins"); - this.unRankedLosses = config.getInt(base + ".unranked.losses"); - this.unRankedWinStreak = config.getInt(base + ".unranked.win-streak"); - this.unRankedBestWinStreak = config.getInt(base + ".unranked.best-win-streak"); - this.unRankedLoseStreak = config.getInt(base + ".unranked.lose-streak"); - this.unRankedBestLoseStreak = config.getInt(base + ".unranked.best-lose-streak"); + unRankedWins = config.getInt(base + ".unranked.wins"); + unRankedLosses = config.getInt(base + ".unranked.losses"); + unRankedWinStreak = config.getInt(base + ".unranked.win-streak"); + unRankedBestWinStreak = config.getInt(base + ".unranked.best-win-streak"); + unRankedLoseStreak = config.getInt(base + ".unranked.lose-streak"); + unRankedBestLoseStreak = config.getInt(base + ".unranked.best-lose-streak"); if (ranked) { - this.rankedWins = config.getInt(base + ".ranked.wins"); - this.rankedLosses = config.getInt(base + ".ranked.losses"); - this.rankedWinStreak = config.getInt(base + ".ranked.win-streak"); - this.rankedBestWinStreak = config.getInt(base + ".ranked.best-win-streak"); - this.rankedLoseStreak = config.getInt(base + ".ranked.lose-streak"); - this.rankedBestLoseStreak = config.getInt(base + ".ranked.best-lose-streak"); - this.elo = config.getInt(base + ".ranked.elo"); - - if (this.elo == 0) { - this.elo = LadderManager.getDEFAULT_ELO(); - } + rankedWins = config.getInt(base + ".ranked.wins"); + rankedLosses = config.getInt(base + ".ranked.losses"); + rankedWinStreak = config.getInt(base + ".ranked.win-streak"); + rankedBestWinStreak = config.getInt(base + ".ranked.best-win-streak"); + rankedLoseStreak = config.getInt(base + ".ranked.lose-streak"); + rankedBestLoseStreak = config.getInt(base + ".ranked.best-lose-streak"); + elo = config.getInt(base + ".ranked.elo"); + + if (elo == 0) + elo = LadderManager.getDEFAULT_ELO(); } - this.kills = config.getInt(base + ".global.kills"); - this.deaths = config.getInt(base + ".global.deaths"); + kills = config.getInt(base + ".global.kills"); + deaths = config.getInt(base + ".global.deaths"); } public void reset() { - this.unRankedWins = 0; - this.unRankedLosses = 0; - this.unRankedWinStreak = 0; - this.unRankedBestWinStreak = 0; - this.unRankedLoseStreak = 0; - this.unRankedBestLoseStreak = 0; - - this.rankedWins = 0; - this.rankedLosses = 0; - this.rankedWinStreak = 0; - this.rankedBestWinStreak = 0; - this.rankedLoseStreak = 0; - this.rankedBestLoseStreak = 0; - this.elo = LadderManager.getDEFAULT_ELO(); - - this.kills = 0; - this.deaths = 0; + unRankedWins = 0; + unRankedLosses = 0; + unRankedWinStreak = 0; + unRankedBestWinStreak = 0; + unRankedLoseStreak = 0; + unRankedBestLoseStreak = 0; + + rankedWins = 0; + rankedLosses = 0; + rankedWinStreak = 0; + rankedBestWinStreak = 0; + rankedLoseStreak = 0; + rankedBestLoseStreak = 0; + elo = LadderManager.getDEFAULT_ELO(); + + kills = 0; + deaths = 0; } } From 8c9bcd01218207f488b959ae5be84cb6bd763e8b Mon Sep 17 00:00:00 2001 From: lokspel <208148594+lokspel@users.noreply.github.com> Date: Mon, 18 May 2026 21:03:16 +0400 Subject: [PATCH 9/9] Fix for https://github.com/ZoneDevelopement/ZonePractice-Pro/issues/536 --- .../nandi0813/practice/manager/fight/ffa/FFAListener.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/dev/nandi0813/practice/manager/fight/ffa/FFAListener.java b/core/src/main/java/dev/nandi0813/practice/manager/fight/ffa/FFAListener.java index 21846997b..07ae5ae2b 100644 --- a/core/src/main/java/dev/nandi0813/practice/manager/fight/ffa/FFAListener.java +++ b/core/src/main/java/dev/nandi0813/practice/manager/fight/ffa/FFAListener.java @@ -399,7 +399,10 @@ public void onPlayerDeath(PlayerDeathEvent e) { ffa.killPlayer(player, killer, cause.getMessage().replace("%killer%", killer != null ? killer.getName() : "Unknown")); if (killer != null) { - Statistic statistic = ffa.getStatistics().get(killer); + Statistic statistic = ffa.getStatistics().computeIfAbsent( + killer, + p -> new Statistic(ProfileManager.getInstance().getUuids().get(p)) + ); statistic.setKills(statistic.getKills() + 1); } }