Skip to content

feat: player abilities APIs#843

Merged
IWareQ merged 8 commits into
AllayMC:masterfrom
zernix2077:ability-refactor
Jun 7, 2026
Merged

feat: player abilities APIs#843
IWareQ merged 8 commits into
AllayMC:masterfrom
zernix2077:ability-refactor

Conversation

@zernix2077

Copy link
Copy Markdown
Contributor

Massive ability refactor.

Replaces old hardcoded game mode and permission checks with a server-tracked PlayerAbility set on each player. Abilities are now part of the player API, broadcasted to all clients, validated server-side, and persisted in player data.

The new system adds explicit ability state tracking and validating for all vanilla abilities like building and mining. Players now expose ability-focused APIs such as setAbility, setAbilities, hasAbility, client-synced gamemode-aware checkers such as canBuild, canMine, canOpenContainers, ability setters such as setCanFly, setCanMine. Maps cleanly to operator and gamemode updates.

Also improves enforcement and fixes several gameplay/security issues: blocks cannot be placed in adventure mode now, all world interactions are prevented in spectator mode, player abilities and permission are globally broadcasted and can be modified by operators.

Additional changes:

  • Added setImmutableWorld, which maps to UpdateAdventureSettingsPacket#immutableWorld (active in adventure and spectator modes)
  • Added setAlwaysFlying, which keeps the client in flight (active in spectator mode)

Events:

  • PlayerAbilitiesUpdateEvent fires after a player’s abilities change
  • PlayerAbilitiesUpdateRequestEvent fires when an operator requests an ability update for another player through the client permission UI

Breaking changes:

  • Removed Permissions.ABILITY_FLY_SURVIVAL, Permissions.ABILITY_FLY_CREATIVE, Permissions.ABILITY_FLY_ADVENTURE, since it's now tracked by abilities
  • Player#viewPlayerPermission(...) renamed to Player#viewPlayerAbilities(...)

@codecov

codecov Bot commented Mar 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 6.78466% with 316 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...in/java/org/allaymc/server/player/AllayPlayer.java 0.00% 184 Missing ⚠️
...ssor/ingame/RequestPermissionsPacketProcessor.java 0.00% 37 Missing ⚠️
...rocessor/ingame/RequestAbilityPacketProcessor.java 0.00% 14 Missing ⚠️
...ocessor/ingame/PlayerAuthInputPacketProcessor.java 0.00% 13 Missing ⚠️
...c/main/java/org/allaymc/api/player/PlayerData.java 0.00% 12 Missing ⚠️
...or/ingame/InventoryTransactionPacketProcessor.java 0.00% 12 Missing ⚠️
...i/src/main/java/org/allaymc/api/player/Player.java 0.00% 8 Missing ⚠️
...ntbus/event/server/PlayerAbilitiesUpdateEvent.java 0.00% 7 Missing ⚠️
...omponent/player/EntityPlayerBaseComponentImpl.java 0.00% 7 Missing ⚠️
...vent/server/PlayerAbilitiesUpdateRequestEvent.java 0.00% 6 Missing ⚠️
... and 8 more
Files with missing lines Coverage Δ Complexity Δ
...allaymc/api/permission/OpPermissionCalculator.java 14.28% <ø> (-5.72%) 1.00 <0.00> (ø)
...src/main/java/org/allaymc/api/player/GameMode.java 85.71% <100.00%> (ø) 1.00 <0.00> (ø)
...ain/java/org/allaymc/api/player/PlayerAbility.java 100.00% <100.00%> (ø) 1.00 <1.00> (?)
...pi/entity/component/EntityPlayerBaseComponent.java 0.00% <0.00%> (ø) 0.00 <0.00> (ø)
...c/server/item/component/ItemBaseComponentImpl.java 48.40% <0.00%> (ø) 46.00 <0.00> (ø)
...erver/network/processor/PacketProcessorHolder.java 0.00% <0.00%> (ø) 0.00 <0.00> (ø)
.../org/allaymc/server/player/AllayPlayerManager.java 16.44% <0.00%> (ø) 3.00 <0.00> (ø)
...g/allaymc/server/container/impl/BaseContainer.java 84.09% <0.00%> (-1.96%) 29.00 <0.00> (ø)
...erver/container/impl/DoubleChestContainerImpl.java 73.27% <0.00%> (-1.29%) 37.00 <0.00> (ø)
.../processor/ingame/PlayerActionPacketProcessor.java 0.00% <0.00%> (ø) 0.00 <0.00> (ø)
... and 11 more

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@smartcmd

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b1bc1675f7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread server/src/main/java/org/allaymc/server/player/AllayPlayer.java Outdated
Comment thread api/src/main/java/org/allaymc/api/player/PlayerData.java Outdated
*
* @return {@code true} if building is currently allowed, {@code false} otherwise
*/
boolean canBuild();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need the following getter/setter of each individual ability, just let the user use addAbility/removeAbility method to make the Player class clean

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getters are not simple ability lookup. even with BUILD ability present, client would still not be able (and thus server should not it allow to) to place blocks if it's in adventure mode, spectator mode, or immutableWorld is sent. getters are aware of this, while hasPermission is separate lookup with different semantics.
setters are purely setters, but with getters setters are usually expected too, and setCanBuild(false) feels cleaner than setAbility(PlayerAbility.BUILD, false), which requires user to know about the abilities API or specific enums, which might even be considered an implementation detail.

Comment thread api/src/main/java/org/allaymc/api/player/PlayerAbility.java
Comment thread server/src/main/java/org/allaymc/server/container/impl/BaseContainer.java Outdated
Comment thread api/src/main/java/org/allaymc/api/player/PlayerAbility.java Outdated
Comment thread api/src/main/java/org/allaymc/api/player/PlayerAbility.java Outdated
Comment thread api/src/main/java/org/allaymc/api/player/PlayerAbility.java Outdated
…T in favor of Permissions.ABILITY_OPERATOR_COMMAND_QUICK_BAR

@smartcmd smartcmd left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should also rename the newly added methods in Player

@smartcmd

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a86bc3bb69

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread server/src/main/java/org/allaymc/server/player/AllayPlayer.java
Comment thread api/src/main/java/org/allaymc/api/player/GameMode.java
@zernix2077

Copy link
Copy Markdown
Contributor Author

Should also rename the newly added methods in Player

done

removeViewer(viewer);
return addViewer(viewer);
}
if (viewer instanceof Player player && this instanceof BlockContainer && !player.canOpenContainers()) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't put the check here, Container.addViewer() should always success in my opinion

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why addViewer should succeed if player is not allowed to open and view containers?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handler of ContainerOpenEvent event would literally see event.getPlayer().canOpenContainers() as false, is it really expected behavior?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add canOpenContainers in container open event?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really understanding the point of that. why not invoke it when a player tries to open a chest that's blocked by a block above then? maybe plugins should use the block interaction event in such cases?

removeViewer(viewer);
return addViewer(viewer);
}
if (viewer instanceof Player player && !player.canOpenContainers()) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

@IWareQ

IWareQ commented May 11, 2026

Copy link
Copy Markdown
Member

Resolve conflicts

@codacy-production

codacy-production Bot commented Jun 7, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 45 complexity

Metric Results
Complexity 45

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

# Conflicts:
#	api/src/main/java/org/allaymc/api/player/PlayerData.java
#	server/src/main/java/org/allaymc/server/command/defaults/GameTestCommand.java
#	server/src/main/java/org/allaymc/server/network/processor/ingame/PlayerAuthInputPacketProcessor.java
@zernix2077

Copy link
Copy Markdown
Contributor Author

Resolve conflicts

done

@IWareQ IWareQ merged commit 0a7dd38 into AllayMC:master Jun 7, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants