Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[1.21] Use RegistryFriendlyByteBuf for extended menus #534

Open
wants to merge 1 commit into
base: 1.21
Choose a base branch
from

Conversation

Urkaz
Copy link

@Urkaz Urkaz commented Jul 7, 2024

Extended menus use FriendlyByteBuf, so they can't be used with StreamCodecs to serialize things as they require a RegistryFriendlyByteBuf.

Forge and NeoForge already use RegistryFriendlyByteBuf natively when calling player.openMenu, but Fabric's implementation is more custom on the Architectury side and it creates a FriendlyByteBuf.

This PR changes all FriendlyByteBuf into RegistryFriendlyByteBuf in all places I've seen it related to extended menus.

@CLAassistant
Copy link

CLAassistant commented Jul 7, 2024

CLA assistant check
All committers have signed the CLA.

Copy link
Member

@Jab125 Jab125 left a comment

Choose a reason for hiding this comment

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

Would this cause any breaking changes? Since if other mods are already using this, then they may have to recompile their mod.

@Urkaz
Copy link
Author

Urkaz commented Jul 19, 2024

Would this cause any breaking changes? Since if other mods are already using this, then they may have to recompile their mod.

I'm not sure if this will be a breaking change, but I don't know exactly how to check it to confirm it or not 😅

What I can say for sure is that RegistryFriendlyByteBuf extends from FriendlyByteBuf so all functions (writeInt, writeBoolean, writeBlockPos, etc) should still be there to use as if it were a FriendlyByteBuf.

If the type is left as a FriendlyByteBuf in ExtendedMenuProvider.java and MenuRegistry.java, then we can cast the FriendlyByteBuf to RegistryFriendlyByteBuf and use it in StreamCodecs like this:

// Overriding the ExtendedMenuProvider
@Override
public void saveExtraData(FriendlyByteBuf buffer) {
    RegistryFriendlyByteBuf b2 = (RegistryFriendlyByteBuf) buffer;
    ItemStack itemInHand = ItemHelper.getItemInHand(ownerPlayer);
    ItemStack.STREAM_CODEC.encode(b2, itemInHand);
}

// During registration
public static final RegistrySupplier<MenuType<MyMenu>> MY_MENU = MENU_TYPES.register("my_menu", () -> MenuRegistry.ofExtended((id, inventory, buffer) -> {
    RegistryFriendlyByteBuf b2 = (RegistryFriendlyByteBuf) buffer;
    ItemStack itemInHand = ItemStack.STREAM_CODEC.decode(b2);
    return new MyMenu(id, inventory, itemInHand);
}));

This example works, but that will still require the proposed changes in fabric/MenuRegistryImpl.java so the same type of buffer is returned by all mod loaders (Forge and NeoForge already use RegistryFriendlyByteBuf in their implementation), or fabric will throw a ClassCastException because of the invalid cast.

Edit: I forgot to mention that this change may be required in 1.20.6 too, as I think the codec and buffer changes were made in that version, but I may be wrong.

@Jab125
Copy link
Member

Jab125 commented Jul 19, 2024

Would this cause any breaking changes? Since if other mods are already using this, then they may have to recompile their mod.

I'm not sure if this will be a breaking change, but I don't know exactly how to check it to confirm it or not 😅

What I can say for sure is that RegistryFriendlyByteBuf extends from FriendlyByteBuf so all functions (writeInt, writeBoolean, writeBlockPos, etc) should still be there to use as if it were a FriendlyByteBuf.

If the type is left as a FriendlyByteBuf in ExtendedMenuProvider.java and MenuRegistry.java, then we can cast the FriendlyByteBuf to RegistryFriendlyByteBuf and use it in StreamCodecs like this:

// Overriding the ExtendedMenuProvider
@Override
public void saveExtraData(FriendlyByteBuf buffer) {
    RegistryFriendlyByteBuf b2 = (RegistryFriendlyByteBuf) buffer;
    ItemStack itemInHand = ItemHelper.getItemInHand(ownerPlayer);
    ItemStack.STREAM_CODEC.encode(b2, itemInHand);
}

// During registration
public static final RegistrySupplier<MenuType<MyMenu>> MY_MENU = MENU_TYPES.register("my_menu", () -> MenuRegistry.ofExtended((id, inventory, buffer) -> {
    RegistryFriendlyByteBuf b2 = (RegistryFriendlyByteBuf) buffer;
    ItemStack itemInHand = ItemStack.STREAM_CODEC.decode(b2);
    return new MyMenu(id, inventory, itemInHand);
}));

This example works, but that will still require the proposed changes in fabric/MenuRegistryImpl.java so the same type of buffer is returned by all mod loaders (Forge and NeoForge already use RegistryFriendlyByteBuf in their implementation), or fabric will throw a ClassCastException because of the invalid cast.

Edit: I forgot to mention that this change may be required in 1.20.6 too, as I think the codec and buffer changes were made in that version, but I may be wrong.

all RegistryFriendlyByteBufs are FriendlyByteBufs, but not all FriendlyByteBufs are RegistryFriendlyByteBufs, so there may be a problem on fabric.

Also, in Java bytecode, both a method's name and signature are used to figure out what method to call:

saveExtraData(Lnet/minecraft/network/FriendlyByteBuf;)V

so this would probably break all mods that currently use this.

@Urkaz
Copy link
Author

Urkaz commented Jul 21, 2024

I did a few tests on my side and I can confirm that only merging the changes from fabric/MenuRegistryImpl.java doesn't break mods and will continue to work without recompiling. Merging the changes in the other two files (MenuRegistry.java and ExtendedMenuProvider.java) breaks them.

But as I mentioned, those changes are still necessary to fix the custom Architectury's implementation of extended menus for Fabric and make it behave like Forge and NeoForge.

Should I edit this PR with something or is it OK the way it is right now? I'm just asking in case something is blocking it from being merged :)
Thanks!

@shedaniel
Copy link
Member

I don't think we can afford breaking changes right now, for now you can get the RegistryAccess from the ServerPlayer and create the RegistryFriendlyByteBuf in the consumer yourself, we can merge this change for the next major version so keep this PR open for now.

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.

5 participants