diff --git a/build.gradle b/build.gradle index ff3e48c..a732184 100644 --- a/build.gradle +++ b/build.gradle @@ -19,6 +19,7 @@ repositories { maven { url 'https://maven.fabricmc.net' } maven { url 'https://maven.kyrptonaught.dev' } maven { url "https://maven.terraformersmc.com/releases" } + maven { url "https://api.modrinth.com/maven" } } dependencies { @@ -35,6 +36,10 @@ dependencies { //shulkerutils modImplementation 'net.kyrptonaught:shulkerutils:1.0.4-1.19' include 'net.kyrptonaught:shulkerutils:1.0.4-1.19' + + //optigui + modCompileOnly 'maven.modrinth:optigui:2.1.0-beta.1' + modLocalRuntime 'maven.modrinth:optigui:2.1.2' } tasks.withType(JavaCompile).configureEach { diff --git a/src/main/java/net/kyrptonaught/quickshulker/QuickShulkerMod.java b/src/main/java/net/kyrptonaught/quickshulker/QuickShulkerMod.java index f5885fa..02f6c69 100644 --- a/src/main/java/net/kyrptonaught/quickshulker/QuickShulkerMod.java +++ b/src/main/java/net/kyrptonaught/quickshulker/QuickShulkerMod.java @@ -6,6 +6,7 @@ import net.kyrptonaught.kyrptconfig.config.ConfigManager; import net.kyrptonaught.quickshulker.api.*; import net.kyrptonaught.quickshulker.config.ConfigOptions; +import net.kyrptonaught.quickshulker.network.OpenQuickiePacket; import net.kyrptonaught.quickshulker.network.OpenShulkerPacket; import net.kyrptonaught.quickshulker.network.QuickBundlePacket; import net.minecraft.block.CraftingTableBlock; @@ -15,6 +16,7 @@ import net.minecraft.entity.player.PlayerInventory; import net.minecraft.item.ItemStack; import net.minecraft.screen.*; +import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; import net.minecraft.util.Hand; import net.minecraft.util.TypedActionResult; @@ -58,8 +60,14 @@ public void registerProviders() { new QuickOpenableRegistry.Builder() .setItem(ShulkerBoxBlock.class) .supportsBundleing(true) - .setOpenAction(((player, stack) -> player.openHandledScreen(new SimpleNamedScreenHandlerFactory((i, playerInventory, playerEntity) -> - new ShulkerBoxScreenHandler(i, player.getInventory(), new ItemStackInventory(stack, 27)), stack.hasCustomName() ? stack.getName() : Text.translatable("container.shulkerBox"))))) + .setOpenAction((player, stack) -> { + ServerPlayerEntity serverPlayer = (ServerPlayerEntity) player; + serverPlayer.closeHandledScreen(); + OpenQuickiePacket.send(serverPlayer, stack); + + player.openHandledScreen(new SimpleNamedScreenHandlerFactory((i, playerInventory, playerEntity) -> + new ShulkerBoxScreenHandler(i, player.getInventory(), new ItemStackInventory(stack, 27)), stack.hasCustomName() ? stack.getName() : Text.translatable("container.shulkerBox"))); + }) .register(); if (getConfig().quickEChest) @@ -67,24 +75,42 @@ public void registerProviders() { .setItem(EnderChestBlock.class) .supportsBundleing(true) .ignoreSingleStackCheck(true) - .setOpenAction(((player, stack) -> player.openHandledScreen(new SimpleNamedScreenHandlerFactory((i, playerInventory, playerEntity) -> - GenericContainerScreenHandler.createGeneric9x3(i, playerInventory, player.getEnderChestInventory()), Text.translatable("container.enderchest"))))) + .setOpenAction((player, stack) -> { + ServerPlayerEntity serverPlayer = (ServerPlayerEntity) player; + serverPlayer.closeHandledScreen(); + OpenQuickiePacket.send(serverPlayer, stack); + + player.openHandledScreen(new SimpleNamedScreenHandlerFactory((i, playerInventory, playerEntity) -> + GenericContainerScreenHandler.createGeneric9x3(i, playerInventory, player.getEnderChestInventory()), Text.translatable("container.enderchest"))); + }) .register(); if (getConfig().quickCraftingTables) new QuickOpenableRegistry.Builder() .setItem(CraftingTableBlock.class) .ignoreSingleStackCheck(true) - .setOpenAction(((player, stack) -> player.openHandledScreen(new SimpleNamedScreenHandlerFactory((i, playerInventory, playerEntity) -> - new CraftingScreenHandler(i, playerInventory, ScreenHandlerContext.create(player.getEntityWorld(), player.getBlockPos())), Text.translatable("container.crafting"))))) + .setOpenAction((player, stack) -> { + ServerPlayerEntity serverPlayer = (ServerPlayerEntity) player; + serverPlayer.closeHandledScreen(); + OpenQuickiePacket.send(serverPlayer, stack); + + player.openHandledScreen(new SimpleNamedScreenHandlerFactory((i, playerInventory, playerEntity) -> + new CraftingScreenHandler(i, playerInventory, ScreenHandlerContext.create(player.getEntityWorld(), player.getBlockPos())), Text.translatable("container.crafting"))); + }) .register(); if (getConfig().quickStonecutter) new QuickOpenableRegistry.Builder() .setItem(StonecutterBlock.class) .ignoreSingleStackCheck(true) - .setOpenAction(((player, stack) -> player.openHandledScreen(new SimpleNamedScreenHandlerFactory((i, playerInventory, playerEntity) -> - new StonecutterScreenHandler(i, playerInventory, ScreenHandlerContext.create(player.getEntityWorld(), player.getBlockPos())), Text.translatable("container.stonecutter"))))) + .setOpenAction((player, stack) -> { + ServerPlayerEntity serverPlayer = (ServerPlayerEntity) player; + serverPlayer.closeHandledScreen(); + OpenQuickiePacket.send(serverPlayer, stack); + + player.openHandledScreen(new SimpleNamedScreenHandlerFactory((i, playerInventory, playerEntity) -> + new StonecutterScreenHandler(i, playerInventory, ScreenHandlerContext.create(player.getEntityWorld(), player.getBlockPos())), Text.translatable("container.stonecutter"))); + }) .register(); } } diff --git a/src/main/java/net/kyrptonaught/quickshulker/client/QuickShulkerModClient.java b/src/main/java/net/kyrptonaught/quickshulker/client/QuickShulkerModClient.java index df346fa..ce7b8af 100644 --- a/src/main/java/net/kyrptonaught/quickshulker/client/QuickShulkerModClient.java +++ b/src/main/java/net/kyrptonaught/quickshulker/client/QuickShulkerModClient.java @@ -12,9 +12,13 @@ import net.kyrptonaught.quickshulker.QuickShulkerMod; import net.kyrptonaught.quickshulker.api.RegisterQuickShulkerClient; import net.kyrptonaught.quickshulker.network.OpenInventoryPacket; +import net.kyrptonaught.quickshulker.network.OpenQuickiePacket; +import net.kyrptonaught.quickshulker.optigui.InteractionWrapper; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.ingame.InventoryScreen; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Hand; @Environment(EnvType.CLIENT) public class QuickShulkerModClient implements ClientModInitializer { @@ -37,6 +41,16 @@ public void onInitializeClient() { client.setScreen(new InventoryScreen(client.player)); }); }); + ClientPlayNetworking.registerGlobalReceiver(OpenQuickiePacket.OPEN_QUICKIE, (client, handler, packet, sender) -> { + ItemStack stack = packet.readItemStack(); + + client.execute(() -> { + InteractionWrapper interactor = InteractionWrapper.getInstance(); + if (interactor != null) { + interactor.startInteraction(client.player, client.world, Hand.MAIN_HAND, stack); + } + }); + }); FabricLoader.getInstance().getEntrypoints(QuickShulkerMod.MOD_ID + "_client", RegisterQuickShulkerClient.class).forEach(RegisterQuickShulkerClient::registerClient); KeyBindingHelper.registerKeyBinding(new DisplayOnlyKeyBind( diff --git a/src/main/java/net/kyrptonaught/quickshulker/network/OpenQuickiePacket.java b/src/main/java/net/kyrptonaught/quickshulker/network/OpenQuickiePacket.java new file mode 100644 index 0000000..98728f5 --- /dev/null +++ b/src/main/java/net/kyrptonaught/quickshulker/network/OpenQuickiePacket.java @@ -0,0 +1,19 @@ +package net.kyrptonaught.quickshulker.network; + +import io.netty.buffer.Unpooled; +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; +import net.kyrptonaught.quickshulker.QuickShulkerMod; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketByteBuf; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.util.Identifier; + +public class OpenQuickiePacket { + public static final Identifier OPEN_QUICKIE = new Identifier(QuickShulkerMod.MOD_ID, "open_quickie"); + + public static void send(ServerPlayerEntity player, ItemStack stack) { + PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer()); + buf.writeItemStack(stack); + ServerPlayNetworking.send(player, OPEN_QUICKIE, new PacketByteBuf(buf)); + } +} diff --git a/src/main/java/net/kyrptonaught/quickshulker/optigui/Initializer.java b/src/main/java/net/kyrptonaught/quickshulker/optigui/Initializer.java new file mode 100644 index 0000000..0718390 --- /dev/null +++ b/src/main/java/net/kyrptonaught/quickshulker/optigui/Initializer.java @@ -0,0 +1,75 @@ +package net.kyrptonaught.quickshulker.optigui; + +import net.fabricmc.loader.api.*; +import net.minecraft.client.MinecraftClient; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.registry.Registries; +import net.minecraft.util.Hand; +import net.minecraft.util.Identifier; +import net.minecraft.world.World; +import opekope2.optigui.EntryPoint; +import opekope2.optigui.InitializerContext; +import opekope2.optigui.interaction.InteractionTarget; +import opekope2.optigui.properties.DefaultProperties; +import opekope2.optigui.service.InteractionService; +import opekope2.optigui.service.RegistryLookupService; +import opekope2.optigui.service.Services; +import org.jetbrains.annotations.NotNull; + +import java.util.Optional; + +public class Initializer implements EntryPoint { + @Override + public void onInitialize(@NotNull InitializerContext initializerContext) { + if (!checkOptiGui()) return; + + InteractionWrapper.setInstance(new InteractionWrapper() { + private final InteractionService interactionService = Services.getService(InteractionService.class); + + @Override + public void startInteraction(@NotNull PlayerEntity player, @NotNull World world, @NotNull Hand hand, @NotNull ItemStack item) { + interactionService.interact(player, world, hand, new InteractionTarget.Preprocessed(getInteractionTargetData(item)), null); + } + }); + } + + private static Object getInteractionTargetData(ItemStack stack) { + MinecraftClient client = MinecraftClient.getInstance(); + RegistryLookupService lookup = Services.getService(RegistryLookupService.class); + + Identifier biome = lookup.lookupBiomeId(client.world, client.player.getBlockPos()); + String name = stack.hasCustomName() ? stack.getName().getString() : null; + + return new DefaultProperties( + Registries.ITEM.getId(stack.getItem()), + name, + biome, + client.player.getBlockY() + ); + } + + private static boolean checkOptiGui() { + final Version optiGuiMinVersion; + try { + optiGuiMinVersion = SemanticVersion.parse("2.1.0-beta.1"); + } catch (VersionParsingException e) { + // Should never happen + return false; + } + + Optional optigui = FabricLoader.getInstance().getModContainer("optigui"); + if (optigui.isEmpty()) { + // OptiGUI not loaded. Some other mod called this entry point + return false; + } + + Version optiGuiVersion = optigui.get().getMetadata().getVersion(); + if (optiGuiVersion.compareTo(optiGuiMinVersion) < 0) { + // OptiGUI too old, will crash with MethodNotFoundException or sth because of the breaking changes + return false; + } + + return true; + } +} diff --git a/src/main/java/net/kyrptonaught/quickshulker/optigui/InteractionWrapper.java b/src/main/java/net/kyrptonaught/quickshulker/optigui/InteractionWrapper.java new file mode 100644 index 0000000..f34a701 --- /dev/null +++ b/src/main/java/net/kyrptonaught/quickshulker/optigui/InteractionWrapper.java @@ -0,0 +1,24 @@ +package net.kyrptonaught.quickshulker.optigui; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Hand; +import net.minecraft.world.World; +import org.jetbrains.annotations.NotNull; + +public abstract class InteractionWrapper { + private static InteractionWrapper _instance; + + public static InteractionWrapper getInstance() { + return _instance; + } + + public static void setInstance(@NotNull InteractionWrapper instance) { + if (_instance != null) { + throw new IllegalStateException("Cannot set InteractionWrapper instance after being set."); + } + _instance = instance; + } + + public abstract void startInteraction(@NotNull PlayerEntity player, @NotNull World world, @NotNull Hand hand, @NotNull ItemStack item); +} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 3c40571..6a8edcb 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -32,6 +32,9 @@ ], "modmenu": [ "net.kyrptonaught.quickshulker.config.modmenu.ModMenuIntegration" + ], + "optigui": [ + "net.kyrptonaught.quickshulker.optigui.Initializer" ] }, "depends": {