Skip to content
Merged

Dev #332

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
ee6f64b
fixed event host bug
Nandi0813 Mar 17, 2026
79bb2cc
fixed PlayerInteractEvent NPE on tracker use
Nandi0813 Mar 18, 2026
8619062
fixed soup regen on FFA
Nandi0813 Mar 18, 2026
ed74b0a
fixed spectators stuck after rollback complete
Nandi0813 Mar 18, 2026
bb3389e
fixed NPE during boxing statistic fetching
Nandi0813 Mar 18, 2026
5d269d4
fixed non solid blocks and added rollback priority sorting
Nandi0813 Mar 18, 2026
e99b676
added new settings to FFA that lets players heal back to full HP when…
Nandi0813 Mar 18, 2026
63f9411
implemented party member limit per group
Nandi0813 Mar 18, 2026
1672b88
added armor trim cosmetics
Nandi0813 Mar 18, 2026
65ab907
updated guis.yml version
Nandi0813 Mar 18, 2026
64c8ed5
updated plugin.yml
Nandi0813 Mar 18, 2026
ab81d7d
added cosmetic permission reset in case player loses it, added reset …
Nandi0813 Mar 18, 2026
dbf2e46
added soup bowl removal mechanic
Nandi0813 Mar 18, 2026
fc5ecec
refactored single commands
Nandi0813 Mar 18, 2026
8c1b84e
added protection rules to config, making lobby interactions toggleable
Nandi0813 Mar 18, 2026
bc53924
removed weightclass toggle when ladder doesn't support both
Nandi0813 Mar 18, 2026
91ce1d6
Fix lobby protection allow-velocity and more protection setting (#339)
lokspel Mar 19, 2026
7c22820
small refactor
Nandi0813 Mar 19, 2026
6070df1
Merge branch 'dev' of https://github.com/ZoneDevelopement/ZonePractic…
Nandi0813 Mar 19, 2026
e2e4b52
added death effects and shield customization
Nandi0813 Mar 19, 2026
1c6185a
updated workflow steps
Nandi0813 Mar 19, 2026
30dee3e
Modernize default ladders (#340)
lokspel Mar 19, 2026
1cae3c1
fixed armor trim bug where it applied trim to wrong armor type
Nandi0813 Mar 19, 2026
1c225bb
Merge branch 'dev' of https://github.com/ZoneDevelopement/ZonePractic…
Nandi0813 Mar 19, 2026
52901fa
Revert "fixed armor trim bug where it applied trim to wrong armor type"
Nandi0813 Mar 19, 2026
160d4c1
updated for armor trim bug #2
Nandi0813 Mar 19, 2026
3ac80c2
fixed temporary build ladders to return to same hand
Nandi0813 Mar 19, 2026
7e9cc6d
changed version to 7.1.0-SNAPSHOT
Nandi0813 Mar 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .github/workflows/maven-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,17 @@ on:
jobs:
build:
runs-on: ubuntu-latest
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
lfs: true

- name: Set up JDK 21
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
java-version: '21'
distribution: 'temurin'
Expand All @@ -27,7 +29,7 @@ jobs:
run: mvn -B clean install --file pom.xml

- name: Upload Build Artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: ZonePractice-Plugin
path: |
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,20 @@ jobs:
release:
name: Create Release
runs-on: ubuntu-latest
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
permissions:
contents: write

steps:
- name: Checkout Code
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 0
lfs: true

- name: Set up JDK 21
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
java-version: '21'
distribution: 'temurin'
Expand Down
73 changes: 73 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,79 @@ Common commands include `/practice` (aliases: `/prac`, `/zonepractice`, `/zonepr
Permissions follow the `zpp.*` namespace, such as `zpp.admin` (default: op), `zpp.practice.*`, `zpp.staffmode`, and many
granular nodes.

### Cosmetics permissions

Some cosmetics permissions are registered dynamically at startup by `CosmeticsPermissionManager`, so they are not fully listed in `plugin.yml`.

#### Entry permission

- `zpp.cosmetics.main`
- Required to run `/cosmetics` (`CosmeticsCommand`).

#### Armor trim permissions

- Tier access:
- `zpp.cosmetics.armortrim.base.leather`
- `zpp.cosmetics.armortrim.base.gold`
- `zpp.cosmetics.armortrim.base.iron`
- `zpp.cosmetics.armortrim.base.diamond`
- `zpp.cosmetics.armortrim.base.netherite`
- wildcard: `zpp.cosmetics.armortrim.base.*`
- Pattern access:
- `zpp.cosmetics.armortrim.pattern.<id>`
- wildcard: `zpp.cosmetics.armortrim.pattern.*`
- Material access:
- `zpp.cosmetics.armortrim.material.<id>`
- wildcard: `zpp.cosmetics.armortrim.material.*`

`<id>` values come from Mojang/Paper trim registries and are sanitized to lowercase alphanumeric/underscore (for example: `sentry`, `vex`, `amethyst`, `netherite`).

#### Death effect permissions

- Per effect:
- `zpp.cosmetics.deatheffect.none`
- `zpp.cosmetics.deatheffect.flame`
- `zpp.cosmetics.deatheffect.lightning`
- `zpp.cosmetics.deatheffect.firework`
- `zpp.cosmetics.deatheffect.explosion`
- `zpp.cosmetics.deatheffect.blood`
- `zpp.cosmetics.deatheffect.enchant`
- `zpp.cosmetics.deatheffect.ender`
- `zpp.cosmetics.deatheffect.hearts`
- `zpp.cosmetics.deatheffect.ice`
- Wildcard:
- `zpp.cosmetics.deatheffect.*`

#### Shield layout permissions

- Open/use shield cosmetics:
- `zpp.cosmetics.shield.use`
- wildcard: `zpp.cosmetics.shield.*`
- Layout count limits:
- `zpp.cosmetics.shield.layouts.1` ... `zpp.cosmetics.shield.layouts.21`
- wildcard: `zpp.cosmetics.shield.layouts.*`
- unlimited alias: `zpp.cosmetics.shield.layouts.unlimited`

If none of the layout-count permissions are set, the code falls back to `1` max layout.

### Groups and cosmetics permissions

Player groups are configured in `core/src/main/resources/groups.yml` and selected by group permission:

- `zpp.group.default`
- `zpp.group.premium`
- `zpp.group.supreme`
- `zpp.group.staff`
- `zpp.group.admin`

The active group controls limits like custom kits and party capacity. You can also use your permission plugin (LuckPerms, etc.) to attach cosmetics permissions per group.

Example bundle strategy:

- `DEFAULT`: `zpp.cosmetics.main`, `zpp.cosmetics.armortrim.base.leather`, `zpp.cosmetics.deatheffect.none`, `zpp.cosmetics.shield.use`, `zpp.cosmetics.shield.layouts.1`
- `PREMIUM`: add `zpp.cosmetics.armortrim.base.gold`, selected trim/material nodes, `zpp.cosmetics.deatheffect.flame`, `zpp.cosmetics.shield.layouts.3`
- `SUPREME+`: grant broader wildcards (`zpp.cosmetics.armortrim.pattern.*`, `zpp.cosmetics.armortrim.material.*`, `zpp.cosmetics.deatheffect.*`, `zpp.cosmetics.shield.layouts.unlimited`)

## Developer API

ZonePractice Pro provides a comprehensive API for developers to interact with the core systems, retrieve player statistics, and listen to custom events.
Expand Down
2 changes: 1 addition & 1 deletion core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>dev.nandi0813</groupId>
<artifactId>practice-parent</artifactId>
<version>7.0.0-SNAPSHOT</version>
<version>7.1.0-SNAPSHOT</version>
</parent>

<artifactId>practice-core</artifactId>
Expand Down
17 changes: 7 additions & 10 deletions core/src/main/java/dev/nandi0813/practice/ZonePractice.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,16 @@
package dev.nandi0813.practice;

import com.github.retrooper.packetevents.PacketEvents;
import dev.nandi0813.practice.command.accept.AcceptCommand;
import dev.nandi0813.practice.command.arena.ArenaCommand;
import dev.nandi0813.practice.command.division.DivisionsCommand;
import dev.nandi0813.practice.command.duel.DuelCommand;
import dev.nandi0813.practice.command.event.EventCommand;
import dev.nandi0813.practice.command.ffa.FFACommand;
import dev.nandi0813.practice.command.hologram.HologramCommand;
import dev.nandi0813.practice.command.ladder.LadderCommand;
import dev.nandi0813.practice.command.matchstats.MatchStatsCommand;
import dev.nandi0813.practice.command.party.PartyCommand;
import dev.nandi0813.practice.command.practice.PracticeCommand;
import dev.nandi0813.practice.command.preview.PreviewCommand;
import dev.nandi0813.practice.command.privatemessage.MessageCommand;
import dev.nandi0813.practice.command.privatemessage.ReplyCommand;
import dev.nandi0813.practice.command.settings.SettingsCommand;
import dev.nandi0813.practice.command.setup.SetupCommand;
import dev.nandi0813.practice.command.singlecommands.*;
import dev.nandi0813.practice.command.spectate.SpectateCommand;
import dev.nandi0813.practice.command.staff.StaffCommand;
import dev.nandi0813.practice.command.statistics.StatisticsCommand;
import dev.nandi0813.practice.listener.*;
import dev.nandi0813.practice.manager.arena.ArenaManager;
import dev.nandi0813.practice.manager.arena.listener.ArenaCopyUtilListener;
Expand All @@ -47,6 +37,7 @@
import dev.nandi0813.practice.manager.nametag.NametagManager;
import dev.nandi0813.practice.manager.playerkit.PlayerKitManager;
import dev.nandi0813.practice.manager.profile.ProfileManager;
import dev.nandi0813.practice.manager.profile.cosmetics.CosmeticsPermissionManager;
import dev.nandi0813.practice.manager.server.ServerManager;
import dev.nandi0813.practice.manager.sidebar.SidebarManager;
import dev.nandi0813.practice.util.*;
Expand Down Expand Up @@ -118,6 +109,7 @@ public void onEnable() {
DivisionManager.getInstance().getData();
ArenaWorldUtil.createArenaWorld();
BackendManager.createFile(this);
CosmeticsPermissionManager.registerAllPermissions();

ZonePracticeApiImpl.setup();
StartUpUtil.loadStartUpProgressMap();
Expand Down Expand Up @@ -342,6 +334,11 @@ private void registerCommands(Server server) {
server.getPluginCommand("ignorequeue").setTabCompleter(ignoreQueueCommand);
}

CosmeticsCommand cosmeticsCommand = new CosmeticsCommand();
if (server.getPluginCommand("cosmetics") != null) {
server.getPluginCommand("cosmetics").setExecutor(cosmeticsCommand);
}

if (ConfigManager.getBoolean("CHAT.PRIVATE-CHAT-ENABLED")) {
new MessageCommand();
new ReplyCommand();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package dev.nandi0813.practice.command.accept;
package dev.nandi0813.practice.command.singlecommands;

import dev.nandi0813.practice.manager.backend.LanguageManager;
import dev.nandi0813.practice.manager.duel.DuelManager;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package dev.nandi0813.practice.command.singlecommands;

import dev.nandi0813.practice.manager.gui.guis.cosmetics.CosmeticsHubGui;
import dev.nandi0813.practice.manager.profile.Profile;
import dev.nandi0813.practice.manager.profile.ProfileManager;
import dev.nandi0813.practice.manager.profile.enums.ProfileStatus;
import dev.nandi0813.practice.util.Common;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jspecify.annotations.NonNull;

/**
* Command to open the cosmetics GUI for armor trim customization.
*/
public class CosmeticsCommand implements CommandExecutor {

@Override
public boolean onCommand(@NonNull CommandSender sender, @NonNull Command cmd, @NonNull String label, String @NonNull [] args) {
if (!(sender instanceof Player player)) {
return false;
}

if (!player.hasPermission("zpp.cosmetics.main")) {
Common.sendMMMessage(player, "<red>You don't have permission to use cosmetics!");
return false;
}

Profile profile = ProfileManager.getInstance().getProfile(player);
if (profile == null) {
Common.sendMMMessage(player, "<red>Failed to load your profile!");
return false;
}

if (!profile.getStatus().equals(ProfileStatus.LOBBY) && !profile.getStatus().equals(ProfileStatus.STAFF_MODE)) {
Common.sendMMMessage(player, "<red>You can only open cosmetics while in the lobby!");
return false;
}

// Open the main cosmetics GUI with no parent GUI (player can close it normally)
CosmeticsHubGui cosmeticsHubGui = new CosmeticsHubGui(profile);
cosmeticsHubGui.open(player);

return true;
}
}

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package dev.nandi0813.practice.command.division;
package dev.nandi0813.practice.command.singlecommands;

import dev.nandi0813.practice.manager.backend.LanguageManager;
import dev.nandi0813.practice.manager.gui.guis.DivisionGui;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package dev.nandi0813.practice.command.duel;
package dev.nandi0813.practice.command.singlecommands;

import dev.nandi0813.practice.manager.backend.LanguageManager;
import dev.nandi0813.practice.manager.duel.DuelManager;
Expand Down Expand Up @@ -96,7 +96,14 @@ public List<String> onTabComplete(CommandSender sender, Command command, String

if (args.length == 1) {
for (Player target : Bukkit.getOnlinePlayers()) {
if (player.equals(target)) continue;
if (player.equals(target)) {
continue;
}

Profile targetProfile = ProfileManager.getInstance().getProfile(target);
if (!targetProfile.getStatus().equals(ProfileStatus.LOBBY) && !targetProfile.getStatus().equals(ProfileStatus.EDITOR) && !targetProfile.getStatus().equals(ProfileStatus.SPECTATE)) {
continue;
}

arguments.add(target.getName());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package dev.nandi0813.practice.command.hologram;
package dev.nandi0813.practice.command.singlecommands;

import dev.nandi0813.practice.ZonePractice;
import dev.nandi0813.practice.manager.backend.LanguageManager;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package dev.nandi0813.practice.command.matchstats;
package dev.nandi0813.practice.command.singlecommands;

import dev.nandi0813.practice.manager.backend.LanguageManager;
import dev.nandi0813.practice.manager.fight.match.Match;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package dev.nandi0813.practice.command.preview;
package dev.nandi0813.practice.command.singlecommands;

import dev.nandi0813.practice.manager.backend.LanguageManager;
import dev.nandi0813.practice.manager.ladder.LadderManager;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package dev.nandi0813.practice.command.settings;
package dev.nandi0813.practice.command.singlecommands;

import dev.nandi0813.practice.manager.backend.LanguageManager;
import dev.nandi0813.practice.manager.profile.Profile;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package dev.nandi0813.practice.command.setup;
package dev.nandi0813.practice.command.singlecommands;

import dev.nandi0813.practice.manager.backend.LanguageManager;
import dev.nandi0813.practice.manager.gui.GUIManager;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package dev.nandi0813.practice.command.spectate;
package dev.nandi0813.practice.command.singlecommands;

import dev.nandi0813.practice.manager.backend.LanguageManager;
import dev.nandi0813.practice.manager.fight.event.EventManager;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package dev.nandi0813.practice.command.statistics;
package dev.nandi0813.practice.command.singlecommands;

import dev.nandi0813.practice.manager.backend.LanguageManager;
import dev.nandi0813.practice.manager.gui.guis.leaderboard.LbSelectorGui;
Expand Down
Loading
Loading