Skip to content

Enhance block state verification and add utility methods#3545

Open
Gu-ZT wants to merge 2 commits into
dev/26.1/1.6from
port/26.1/1.6
Open

Enhance block state verification and add utility methods#3545
Gu-ZT wants to merge 2 commits into
dev/26.1/1.6from
port/26.1/1.6

Conversation

@Gu-ZT
Copy link
Copy Markdown
Contributor

@Gu-ZT Gu-ZT commented May 25, 2026

This pull request introduces important validation logic to ensure only valid block state changes are applied when using the hammer tool, and refactors utility code for state comparison and verification. The main focus is on preventing invalid or unintended block state modifications on the server.

Block state change validation

  • Added a check in HammerChangeBlockPacket.handleOnServer to verify that the requested block state transition is valid for the targeted block and property, using the new StateUtil.verifyPossibleStatesForProperty method. This prevents illegal state changes from being applied.

Utility methods for block state handling

  • Added StateUtil.equalsState, a generic method to compare two block states (or any StateHolder) for property equality.
  • Added StateUtil.verifyPossibleStatesForProperty, which checks if a target block state is a valid possible state for a given initial state and property—used to validate hammer block changes.
  • Refactored and reformatted StateUtil.findPossibleStatesForProperty for clarity and style consistency.
  • Updated imports in StateUtil.java to support new utility methods. [1] [2]

Copilot AI review requested due to automatic review settings May 25, 2026 07:26
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request adds server-side validation for hammer-triggered block state changes by checking that a requested target BlockState is reachable from the current server state via cycling the block’s hammer-modifiable property, and introduces new StateUtil helpers to support state comparison and verification.

Changes:

  • Added server-side validation in HammerChangeBlockPacket.handleOnServer to reject invalid/illegal block state transitions.
  • Added StateUtil.equalsState and StateUtil.verifyPossibleStatesForProperty to compare state property values and validate reachable target states.
  • Refactored formatting of StateUtil.findPossibleStatesForProperty for readability.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/main/java/dev/dubhe/anvilcraft/util/StateUtil.java Adds new utility methods for state equality and hammer-state transition verification; reformats possible-state enumeration.
src/main/java/dev/dubhe/anvilcraft/network/HammerChangeBlockPacket.java Adds a server-side guard to ensure only valid hammer state changes are applied before calling setBlock.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/main/java/dev/dubhe/anvilcraft/util/StateUtil.java
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (1)

src/main/java/dev/dubhe/anvilcraft/util/StateUtil.java:36

  • equalsState builds a union of properties from both states and then calls state1.getValue(property) / state2.getValue(property) for each. If the two StateHolders don't share the exact same property set, getValue will throw (it doesn't return null for missing properties). Either restrict this utility to same-property states (and assert/early-return when property sets differ), or check hasProperty before calling getValue.
        Set<Property<?>> properties = new HashSet<>();
        properties.addAll(state1.getProperties());
        properties.addAll(state2.getProperties());
        for (Property<?> property : properties) {
            E value1 = Util.cast(state1.getValue(property));
            E value2 = Util.cast(state2.getValue(property));

Comment on lines +30 to +39
public static <O, T extends StateHolder<O, T>, E extends Comparable<E>> boolean equalsState(T state1, T state2) {
Set<Property<?>> properties = new HashSet<>();
properties.addAll(state1.getProperties());
properties.addAll(state2.getProperties());
for (Property<?> property : properties) {
E value1 = Util.cast(state1.getValue(property));
E value2 = Util.cast(state2.getValue(property));
// noinspection ConstantValue
if (value1 == null || value2 == null || value1.compareTo(value2) != 0) {
return false;
Comment on lines 36 to 56
public void handleOnServer(Player player) {
Level level = player.level();
if (!level.isLoaded(this.pos)) return;
BlockState blockState = level.getBlockState(this.pos);
boolean stateVerified = StateUtil.verifyPossibleStatesForProperty(blockState, this.state);
boolean hasHammer = player.getMainHandItem().getItem() instanceof AnvilHammerItem
|| player.getOffhandItem().getItem() instanceof AnvilHammerItem;
AttributeInstance attribute = player.getAttribute(Attributes.BLOCK_INTERACTION_RANGE);
double value = attribute == null ? 5.0 : attribute.getValue();
boolean distanceVerified = this.pos.getCenter().distanceToSqr(player.getEyePosition()) <= value * value + 2;
if (!HammerChangeBlockEvent.invoke(
level,
player,
this.pos,
this.state,
blockState,
hasHammer && stateVerified && distanceVerified
)) {
return;
}
level.setBlock(this.pos, this.state, Block.UPDATE_ALL_IMMEDIATE);
Comment on lines +19 to +30
public HammerChangeBlockEvent(
LevelAccessor level,
Player player,
BlockPos pos,
BlockState state,
BlockState oldState,
boolean isVerified
) {
super(level, pos, state);
this.oldState = oldState;
this.isVerified = isVerified;
}
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.

2 participants