From 670fe1328bd7fce0252a8b2422fd5307dd5ad44d Mon Sep 17 00:00:00 2001 From: lukasabbe <67807954+lukasabbe@users.noreply.github.com> Date: Tue, 25 Mar 2025 17:43:17 +0100 Subject: [PATCH] graddle update --- .../Bookshelfinspector.java | 39 ++++++ .../BookshelfinspectorClient.java | 35 +++++ .../bookshelfinspector/config/Config.java | 71 ++++++++++ .../bookshelfinspector/config/ModMenu.java | 46 +++++++ .../bookshelfinspector/data/BookData.java | 20 +++ .../data/BookShelfData.java | 10 ++ .../mixin/BookshelfInvoker.java | 15 +++ .../mixin/BookshelfMixin.java | 28 ++++ .../mixin/InGameHudMixin.java | 29 ++++ .../BookShelfInspectorNetworkConstants.java | 11 ++ .../client/BookShelfInventoryHandler.java | 28 ++++ .../network/client/ModPayloadHandler.java | 19 +++ .../packets/BookShelfInventoryPayload.java | 23 ++++ .../BookShelfInventoryRequestPayload.java | 23 ++++ .../LecternInventoryRequestPayload.java | 20 +++ .../network/packets/ModCheckPayload.java | 21 +++ ...okShelfInventoryRequestPayloadHandler.java | 25 ++++ ...LecternInventoryRequestPayloadHandler.java | 26 ++++ .../util/BookshelfTools.java | 28 ++++ .../bookshelfinspector/util/HudRenderer.java | 92 +++++++++++++ .../bookshelfinspector/util/Inspector.java | 125 ++++++++++++++++++ .../bookshelfinspector/util/LecternTools.java | 25 ++++ .../util/RomanNumerals.java | 34 +++++ 23 files changed, 793 insertions(+) create mode 100644 remappedSrc/me/lukasabbe/bookshelfinspector/Bookshelfinspector.java create mode 100644 remappedSrc/me/lukasabbe/bookshelfinspector/BookshelfinspectorClient.java create mode 100644 remappedSrc/me/lukasabbe/bookshelfinspector/config/Config.java create mode 100644 remappedSrc/me/lukasabbe/bookshelfinspector/config/ModMenu.java create mode 100644 remappedSrc/me/lukasabbe/bookshelfinspector/data/BookData.java create mode 100644 remappedSrc/me/lukasabbe/bookshelfinspector/data/BookShelfData.java create mode 100644 remappedSrc/me/lukasabbe/bookshelfinspector/mixin/BookshelfInvoker.java create mode 100644 remappedSrc/me/lukasabbe/bookshelfinspector/mixin/BookshelfMixin.java create mode 100644 remappedSrc/me/lukasabbe/bookshelfinspector/mixin/InGameHudMixin.java create mode 100644 remappedSrc/me/lukasabbe/bookshelfinspector/network/BookShelfInspectorNetworkConstants.java create mode 100644 remappedSrc/me/lukasabbe/bookshelfinspector/network/client/BookShelfInventoryHandler.java create mode 100644 remappedSrc/me/lukasabbe/bookshelfinspector/network/client/ModPayloadHandler.java create mode 100644 remappedSrc/me/lukasabbe/bookshelfinspector/network/packets/BookShelfInventoryPayload.java create mode 100644 remappedSrc/me/lukasabbe/bookshelfinspector/network/packets/BookShelfInventoryRequestPayload.java create mode 100644 remappedSrc/me/lukasabbe/bookshelfinspector/network/packets/LecternInventoryRequestPayload.java create mode 100644 remappedSrc/me/lukasabbe/bookshelfinspector/network/packets/ModCheckPayload.java create mode 100644 remappedSrc/me/lukasabbe/bookshelfinspector/network/server/BookShelfInventoryRequestPayloadHandler.java create mode 100644 remappedSrc/me/lukasabbe/bookshelfinspector/network/server/LecternInventoryRequestPayloadHandler.java create mode 100644 remappedSrc/me/lukasabbe/bookshelfinspector/util/BookshelfTools.java create mode 100644 remappedSrc/me/lukasabbe/bookshelfinspector/util/HudRenderer.java create mode 100644 remappedSrc/me/lukasabbe/bookshelfinspector/util/Inspector.java create mode 100644 remappedSrc/me/lukasabbe/bookshelfinspector/util/LecternTools.java create mode 100644 remappedSrc/me/lukasabbe/bookshelfinspector/util/RomanNumerals.java diff --git a/remappedSrc/me/lukasabbe/bookshelfinspector/Bookshelfinspector.java b/remappedSrc/me/lukasabbe/bookshelfinspector/Bookshelfinspector.java new file mode 100644 index 0000000..c5fe547 --- /dev/null +++ b/remappedSrc/me/lukasabbe/bookshelfinspector/Bookshelfinspector.java @@ -0,0 +1,39 @@ +package me.lukasabbe.bookshelfinspector; + +import me.lukasabbe.bookshelfinspector.network.packets.BookShelfInventoryPayload; +import me.lukasabbe.bookshelfinspector.network.packets.BookShelfInventoryRequestPayload; +import me.lukasabbe.bookshelfinspector.network.packets.LecternInventoryRequestPayload; +import me.lukasabbe.bookshelfinspector.network.packets.ModCheckPayload; +import me.lukasabbe.bookshelfinspector.network.server.BookShelfInventoryRequestPayloadHandler; +import me.lukasabbe.bookshelfinspector.network.server.LecternInventoryRequestPayloadHandler; +import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; +import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents; +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; +import net.minecraft.server.MinecraftServer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Bookshelfinspector implements ModInitializer { + public static MinecraftServer serverInstance; + public final static String MOD_ID = "bookshelfinspector"; + + public static Logger LOGGER = LoggerFactory.getLogger(MOD_ID); + + @Override + public void onInitialize() { + PayloadTypeRegistry.playC2S().register(BookShelfInventoryRequestPayload.ID,BookShelfInventoryRequestPayload.CODEC); + PayloadTypeRegistry.playC2S().register(LecternInventoryRequestPayload.ID, LecternInventoryRequestPayload.CODEC); + PayloadTypeRegistry.playS2C().register(BookShelfInventoryPayload.ID,BookShelfInventoryPayload.CODEC); + PayloadTypeRegistry.playS2C().register(ModCheckPayload.ID, ModCheckPayload.CODEC); + + ServerPlayNetworking.registerGlobalReceiver(BookShelfInventoryRequestPayload.ID, new BookShelfInventoryRequestPayloadHandler()); + + ServerPlayNetworking.registerGlobalReceiver(LecternInventoryRequestPayload.ID, new LecternInventoryRequestPayloadHandler()); + + ServerPlayConnectionEvents.JOIN.register(((handler, sender, server) -> { + serverInstance = server; + ServerPlayNetworking.send(handler.player, new ModCheckPayload(true)); + })); + } +} diff --git a/remappedSrc/me/lukasabbe/bookshelfinspector/BookshelfinspectorClient.java b/remappedSrc/me/lukasabbe/bookshelfinspector/BookshelfinspectorClient.java new file mode 100644 index 0000000..218ba51 --- /dev/null +++ b/remappedSrc/me/lukasabbe/bookshelfinspector/BookshelfinspectorClient.java @@ -0,0 +1,35 @@ +package me.lukasabbe.bookshelfinspector; + +import me.lukasabbe.bookshelfinspector.config.Config; +import me.lukasabbe.bookshelfinspector.data.BookData; +import me.lukasabbe.bookshelfinspector.data.BookShelfData; +import me.lukasabbe.bookshelfinspector.network.client.BookShelfInventoryHandler; +import me.lukasabbe.bookshelfinspector.network.client.ModPayloadHandler; +import me.lukasabbe.bookshelfinspector.network.packets.BookShelfInventoryPayload; +import me.lukasabbe.bookshelfinspector.network.packets.ModCheckPayload; +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; + +@Environment(EnvType.CLIENT) +public class BookshelfinspectorClient implements ClientModInitializer { + + public static BookData currentBookData = BookData.empty(); + public static BookShelfData bookShelfData = new BookShelfData(); + public static boolean modAvailable = false; + public static Config config = new Config(); + + @Override + public void onInitializeClient() { + config.loadConfig(); + ClientPlayNetworking.registerGlobalReceiver(BookShelfInventoryPayload.ID, new BookShelfInventoryHandler()); + ClientPlayNetworking.registerGlobalReceiver(ModCheckPayload.ID,new ModPayloadHandler()); + + ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> { + modAvailable = false; + bookShelfData = new BookShelfData(); + }); + } +} diff --git a/remappedSrc/me/lukasabbe/bookshelfinspector/config/Config.java b/remappedSrc/me/lukasabbe/bookshelfinspector/config/Config.java new file mode 100644 index 0000000..3ffaa63 --- /dev/null +++ b/remappedSrc/me/lukasabbe/bookshelfinspector/config/Config.java @@ -0,0 +1,71 @@ +package me.lukasabbe.bookshelfinspector.config; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.loader.api.FabricLoader; +import org.yaml.snakeyaml.Yaml; + +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Map; + +@Environment(EnvType.CLIENT) +public class Config { + public boolean lecternToggle = true; + public int scale = 10; + public boolean useRoman = false; + + public void loadConfig(){ + Path configPath = FabricLoader.getInstance().getConfigDir().resolve("bookshelfinspector-config.yml"); + if(!Files.exists(configPath))createConfig(configPath); + Yaml yaml = new Yaml(); + try{ + Map configMap = yaml.load(new FileReader(configPath.toFile())); + if(configMap.containsKey("lectern-toggle")){ + lecternToggle = (boolean) configMap.get("lectern-toggle"); + } + if(configMap.containsKey("scale")){ + scale = (int) configMap.get("scale"); + } + if(configMap.containsKey("roman")){ + useRoman = (boolean) configMap.get("roman"); + } + + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + } + + private void createConfig(Path configPath){ + FabricLoader.getInstance().getModContainer("bookshelfinspector").ifPresent(modContainer -> { + Path path = modContainer.findPath("bookshelfinspector-config.yml").orElseThrow(); + try { + Files.copy(path,configPath); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + } + + public void saveConfig(){ + Path configPath = FabricLoader.getInstance().getConfigDir().resolve("bookshelfinspector-config.yml"); + if(!Files.exists(configPath))createConfig(configPath); + Yaml yaml = new Yaml(); + try{ + Map configMap = yaml.load(new FileReader(configPath.toFile())); + configMap.put("lectern-toggle",lecternToggle); + configMap.put("scale",scale); + configMap.put("roman", useRoman); + FileWriter writer = new FileWriter(configPath.toString()); + yaml.dump(configMap,writer); + writer.close(); + + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/remappedSrc/me/lukasabbe/bookshelfinspector/config/ModMenu.java b/remappedSrc/me/lukasabbe/bookshelfinspector/config/ModMenu.java new file mode 100644 index 0000000..74a74cb --- /dev/null +++ b/remappedSrc/me/lukasabbe/bookshelfinspector/config/ModMenu.java @@ -0,0 +1,46 @@ +package me.lukasabbe.bookshelfinspector.config; + +import com.terraformersmc.modmenu.api.ConfigScreenFactory; +import com.terraformersmc.modmenu.api.ModMenuApi; +import me.lukasabbe.bookshelfinspector.BookshelfinspectorClient; +import me.shedaniel.clothconfig2.api.ConfigBuilder; +import me.shedaniel.clothconfig2.api.ConfigEntryBuilder; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.text.Text; + +@Environment(EnvType.CLIENT) +public class ModMenu implements ModMenuApi { + @Override + public ConfigScreenFactory getModConfigScreenFactory() { + return parent -> { + ConfigBuilder builder = ConfigBuilder + .create() + .setParentScreen(parent) + .setTitle(Text.translatable("bookshelfinspector.config.title")); + ConfigEntryBuilder entryBuilder = builder.entryBuilder(); + + builder + .getOrCreateCategory(Text.translatable("bookshelfinspector.config.category")) + .addEntry(entryBuilder + .startBooleanToggle(Text.translatable("bookshelfinspector.config.lectern.toggle"), BookshelfinspectorClient.config.lecternToggle) + .setTooltip(Text.translatable("bookshelfinspector.config.lectern.toggle.tooltip")) + .setDefaultValue(true) + .setSaveConsumer(val -> BookshelfinspectorClient.config.lecternToggle = val).build()) + .addEntry(entryBuilder + .startIntSlider(Text.translatable("bookshelfinspector.config.scale"),BookshelfinspectorClient.config.scale,0,20) + .setTooltip(Text.translatable("bookshelfinspector.config.scale.tooltip")) + .setDefaultValue(10).setSaveConsumer(val -> BookshelfinspectorClient.config.scale = val) + .build()) + .addEntry(entryBuilder + .startBooleanToggle(Text.translatable("bookshelfinspector.config.roman_scale"), BookshelfinspectorClient.config.useRoman) + .setTooltip(Text.translatable("bookshelfinspector.config.roman_scale.tooltip")) + .setDefaultValue(false) + .setSaveConsumer(val -> BookshelfinspectorClient.config.useRoman = val) + .build()); + + builder.setSavingRunnable(BookshelfinspectorClient.config::saveConfig); + return builder.build(); + }; + } +} diff --git a/remappedSrc/me/lukasabbe/bookshelfinspector/data/BookData.java b/remappedSrc/me/lukasabbe/bookshelfinspector/data/BookData.java new file mode 100644 index 0000000..0644338 --- /dev/null +++ b/remappedSrc/me/lukasabbe/bookshelfinspector/data/BookData.java @@ -0,0 +1,20 @@ +package me.lukasabbe.bookshelfinspector.data; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; + +public class BookData { + public ItemStack itemStack; + public BlockPos pos; + public int slotId; + + public BookData(ItemStack itemStack, BlockPos pos, int slotId) { + this.itemStack = itemStack; + this.pos = pos; + this.slotId = slotId; + } + + public static BookData empty(){ + return new BookData(ItemStack.EMPTY, null, -1); + } +} diff --git a/remappedSrc/me/lukasabbe/bookshelfinspector/data/BookShelfData.java b/remappedSrc/me/lukasabbe/bookshelfinspector/data/BookShelfData.java new file mode 100644 index 0000000..d63dece --- /dev/null +++ b/remappedSrc/me/lukasabbe/bookshelfinspector/data/BookShelfData.java @@ -0,0 +1,10 @@ +package me.lukasabbe.bookshelfinspector.data; + +import net.minecraft.util.math.BlockPos; + +public class BookShelfData { + public boolean isCurrentBookDataToggled = false; + public BlockPos latestPos = null; + public boolean requestSent = false; + public int currentSlotInt = -1; +} diff --git a/remappedSrc/me/lukasabbe/bookshelfinspector/mixin/BookshelfInvoker.java b/remappedSrc/me/lukasabbe/bookshelfinspector/mixin/BookshelfInvoker.java new file mode 100644 index 0000000..5a82b55 --- /dev/null +++ b/remappedSrc/me/lukasabbe/bookshelfinspector/mixin/BookshelfInvoker.java @@ -0,0 +1,15 @@ +package me.lukasabbe.bookshelfinspector.mixin; + +import net.minecraft.block.BlockState; +import net.minecraft.block.ChiseledBookshelfBlock; +import net.minecraft.util.hit.BlockHitResult; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +import java.util.OptionalInt; + +@Mixin(ChiseledBookshelfBlock.class) +public interface BookshelfInvoker { + @Invoker("getSlotForHitPos") + OptionalInt invokerGetSlotForHitPos(BlockHitResult hit, BlockState state); +} diff --git a/remappedSrc/me/lukasabbe/bookshelfinspector/mixin/BookshelfMixin.java b/remappedSrc/me/lukasabbe/bookshelfinspector/mixin/BookshelfMixin.java new file mode 100644 index 0000000..63bdb6c --- /dev/null +++ b/remappedSrc/me/lukasabbe/bookshelfinspector/mixin/BookshelfMixin.java @@ -0,0 +1,28 @@ +package me.lukasabbe.bookshelfinspector.mixin; + +import me.lukasabbe.bookshelfinspector.util.Inspector; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.network.ClientPlayerEntity; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ClientPlayerEntity.class) +public class BookshelfMixin{ + + @Shadow @Final protected MinecraftClient client; + + @Unique + private final Inspector inspector = new Inspector(); + + @Inject(method = "tick", at= @At(value = "INVOKE", target = "Ljava/util/List;iterator()Ljava/util/Iterator;")) + public void injectTick(CallbackInfo ci){ + inspector.inspect(client); + } + + +} diff --git a/remappedSrc/me/lukasabbe/bookshelfinspector/mixin/InGameHudMixin.java b/remappedSrc/me/lukasabbe/bookshelfinspector/mixin/InGameHudMixin.java new file mode 100644 index 0000000..2786248 --- /dev/null +++ b/remappedSrc/me/lukasabbe/bookshelfinspector/mixin/InGameHudMixin.java @@ -0,0 +1,29 @@ +package me.lukasabbe.bookshelfinspector.mixin; + +import com.mojang.blaze3d.systems.RenderSystem; +import me.lukasabbe.bookshelfinspector.util.HudRenderer; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.hud.InGameHud; +import net.minecraft.client.render.RenderTickCounter; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Environment(EnvType.CLIENT) +@Mixin(InGameHud.class) +public class InGameHudMixin { + @Shadow @Final private MinecraftClient client; + + @Inject(method = "render",at=@At("RETURN")) + public void render(DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci){ + RenderSystem.enableBlend(); + HudRenderer.hudRender(context, client); + RenderSystem.disableBlend(); + } +} diff --git a/remappedSrc/me/lukasabbe/bookshelfinspector/network/BookShelfInspectorNetworkConstants.java b/remappedSrc/me/lukasabbe/bookshelfinspector/network/BookShelfInspectorNetworkConstants.java new file mode 100644 index 0000000..9923e1d --- /dev/null +++ b/remappedSrc/me/lukasabbe/bookshelfinspector/network/BookShelfInspectorNetworkConstants.java @@ -0,0 +1,11 @@ +package me.lukasabbe.bookshelfinspector.network; + +import me.lukasabbe.bookshelfinspector.Bookshelfinspector; +import net.minecraft.util.Identifier; + +public class BookShelfInspectorNetworkConstants { + public static final Identifier BOOK_SHELF_INVENTORY_REQUEST_PACKET_ID = Identifier.of(Bookshelfinspector.MOD_ID,"book_shelf_inventory_request"); + public static final Identifier BOOK_SHELF_INVENTORY_PACKET_ID = Identifier.of(Bookshelfinspector.MOD_ID,"book_shelf_inventory"); + public static final Identifier MOD_CHECK_PACKET_ID = Identifier.of(Bookshelfinspector.MOD_ID,"mod_check"); + public static final Identifier LECTERN_INVENTORY_REQUEST_PACKET_ID = Identifier.of(Bookshelfinspector.MOD_ID, "lectern_inventory_request"); +} diff --git a/remappedSrc/me/lukasabbe/bookshelfinspector/network/client/BookShelfInventoryHandler.java b/remappedSrc/me/lukasabbe/bookshelfinspector/network/client/BookShelfInventoryHandler.java new file mode 100644 index 0000000..6e1671b --- /dev/null +++ b/remappedSrc/me/lukasabbe/bookshelfinspector/network/client/BookShelfInventoryHandler.java @@ -0,0 +1,28 @@ +package me.lukasabbe.bookshelfinspector.network.client; + +import me.lukasabbe.bookshelfinspector.BookshelfinspectorClient; +import me.lukasabbe.bookshelfinspector.data.BookData; +import me.lukasabbe.bookshelfinspector.network.packets.BookShelfInventoryPayload; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; +import net.minecraft.item.Items; + +@Environment(EnvType.CLIENT) +public class BookShelfInventoryHandler implements ClientPlayNetworking.PlayPayloadHandler { + @Override + public void receive(BookShelfInventoryPayload bookShelfInventoryPayload, ClientPlayNetworking.Context context) { + context.client().execute(() ->{ + BookshelfinspectorClient.bookShelfData.requestSent = false; + if(bookShelfInventoryPayload.itemStack().isOf(Items.AIR)){ + BookshelfinspectorClient.bookShelfData.isCurrentBookDataToggled = false; + BookshelfinspectorClient.currentBookData = BookData.empty(); + BookshelfinspectorClient.currentBookData.slotId = -2; + } + else{ + BookshelfinspectorClient.bookShelfData.isCurrentBookDataToggled = true; + BookshelfinspectorClient.currentBookData = new BookData(bookShelfInventoryPayload.itemStack(),bookShelfInventoryPayload.pos(),bookShelfInventoryPayload.slotNum()); + } + }); + } +} diff --git a/remappedSrc/me/lukasabbe/bookshelfinspector/network/client/ModPayloadHandler.java b/remappedSrc/me/lukasabbe/bookshelfinspector/network/client/ModPayloadHandler.java new file mode 100644 index 0000000..58685e8 --- /dev/null +++ b/remappedSrc/me/lukasabbe/bookshelfinspector/network/client/ModPayloadHandler.java @@ -0,0 +1,19 @@ +package me.lukasabbe.bookshelfinspector.network.client; + +import me.lukasabbe.bookshelfinspector.Bookshelfinspector; +import me.lukasabbe.bookshelfinspector.BookshelfinspectorClient; +import me.lukasabbe.bookshelfinspector.network.packets.ModCheckPayload; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; + +@Environment(EnvType.CLIENT) +public class ModPayloadHandler implements ClientPlayNetworking.PlayPayloadHandler { + @Override + public void receive(ModCheckPayload modCheckPayload, ClientPlayNetworking.Context context) { + context.client().execute(() ->{ + Bookshelfinspector.LOGGER.info("[bookshelfinspector] Connected to server"); + BookshelfinspectorClient.modAvailable = true; + }); + } +} diff --git a/remappedSrc/me/lukasabbe/bookshelfinspector/network/packets/BookShelfInventoryPayload.java b/remappedSrc/me/lukasabbe/bookshelfinspector/network/packets/BookShelfInventoryPayload.java new file mode 100644 index 0000000..83719dd --- /dev/null +++ b/remappedSrc/me/lukasabbe/bookshelfinspector/network/packets/BookShelfInventoryPayload.java @@ -0,0 +1,23 @@ +package me.lukasabbe.bookshelfinspector.network.packets; + +import me.lukasabbe.bookshelfinspector.network.BookShelfInspectorNetworkConstants; +import net.minecraft.item.ItemStack; +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.network.codec.PacketCodecs; +import net.minecraft.network.packet.CustomPayload; +import net.minecraft.util.math.BlockPos; + +public record BookShelfInventoryPayload(ItemStack itemStack, BlockPos pos, int slotNum) implements CustomPayload{ + public static final CustomPayload.Id ID = new CustomPayload.Id<>(BookShelfInspectorNetworkConstants.BOOK_SHELF_INVENTORY_PACKET_ID); + public static final PacketCodec CODEC = PacketCodec.tuple( + ItemStack.OPTIONAL_PACKET_CODEC, BookShelfInventoryPayload::itemStack, + BlockPos.PACKET_CODEC, BookShelfInventoryPayload::pos, + PacketCodecs.INTEGER, BookShelfInventoryPayload::slotNum, + BookShelfInventoryPayload::new); + + @Override + public CustomPayload.Id getId() { + return ID; + } +} diff --git a/remappedSrc/me/lukasabbe/bookshelfinspector/network/packets/BookShelfInventoryRequestPayload.java b/remappedSrc/me/lukasabbe/bookshelfinspector/network/packets/BookShelfInventoryRequestPayload.java new file mode 100644 index 0000000..918dba2 --- /dev/null +++ b/remappedSrc/me/lukasabbe/bookshelfinspector/network/packets/BookShelfInventoryRequestPayload.java @@ -0,0 +1,23 @@ +package me.lukasabbe.bookshelfinspector.network.packets; + +import me.lukasabbe.bookshelfinspector.network.BookShelfInspectorNetworkConstants; +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.network.codec.PacketCodecs; +import net.minecraft.network.packet.CustomPayload; +import net.minecraft.util.math.BlockPos; + +public record BookShelfInventoryRequestPayload(BlockPos pos, int slotNum) implements CustomPayload { + + public static final CustomPayload.Id ID = new CustomPayload.Id<>(BookShelfInspectorNetworkConstants.BOOK_SHELF_INVENTORY_REQUEST_PACKET_ID); + + public static final PacketCodec CODEC = PacketCodec.tuple( + BlockPos.PACKET_CODEC,BookShelfInventoryRequestPayload::pos, + PacketCodecs.INTEGER, BookShelfInventoryRequestPayload::slotNum, + BookShelfInventoryRequestPayload::new); + + @Override + public Id getId() { + return ID; + } +} diff --git a/remappedSrc/me/lukasabbe/bookshelfinspector/network/packets/LecternInventoryRequestPayload.java b/remappedSrc/me/lukasabbe/bookshelfinspector/network/packets/LecternInventoryRequestPayload.java new file mode 100644 index 0000000..29cd8e5 --- /dev/null +++ b/remappedSrc/me/lukasabbe/bookshelfinspector/network/packets/LecternInventoryRequestPayload.java @@ -0,0 +1,20 @@ +package me.lukasabbe.bookshelfinspector.network.packets; + +import me.lukasabbe.bookshelfinspector.network.BookShelfInspectorNetworkConstants; +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.network.packet.CustomPayload; +import net.minecraft.util.math.BlockPos; + +public record LecternInventoryRequestPayload(BlockPos pos) implements CustomPayload{ + public static final CustomPayload.Id ID = new CustomPayload.Id<>(BookShelfInspectorNetworkConstants.LECTERN_INVENTORY_REQUEST_PACKET_ID); + + public static final PacketCodec CODEC = PacketCodec.tuple( + BlockPos.PACKET_CODEC,LecternInventoryRequestPayload::pos, + LecternInventoryRequestPayload::new); + + @Override + public CustomPayload.Id getId() { + return ID; + } +} diff --git a/remappedSrc/me/lukasabbe/bookshelfinspector/network/packets/ModCheckPayload.java b/remappedSrc/me/lukasabbe/bookshelfinspector/network/packets/ModCheckPayload.java new file mode 100644 index 0000000..56c4927 --- /dev/null +++ b/remappedSrc/me/lukasabbe/bookshelfinspector/network/packets/ModCheckPayload.java @@ -0,0 +1,21 @@ +package me.lukasabbe.bookshelfinspector.network.packets; + +import me.lukasabbe.bookshelfinspector.network.BookShelfInspectorNetworkConstants; +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.network.codec.PacketCodecs; +import net.minecraft.network.packet.CustomPayload; + +public record ModCheckPayload(boolean modActivated) implements CustomPayload { + public static final CustomPayload.Id ID = new CustomPayload.Id<>(BookShelfInspectorNetworkConstants.MOD_CHECK_PACKET_ID); + + public static final PacketCodec CODEC = PacketCodec.tuple( + PacketCodecs.BOOLEAN, ModCheckPayload::modActivated, + ModCheckPayload::new + ); + + @Override + public Id getId() { + return ID; + } +} diff --git a/remappedSrc/me/lukasabbe/bookshelfinspector/network/server/BookShelfInventoryRequestPayloadHandler.java b/remappedSrc/me/lukasabbe/bookshelfinspector/network/server/BookShelfInventoryRequestPayloadHandler.java new file mode 100644 index 0000000..18e211a --- /dev/null +++ b/remappedSrc/me/lukasabbe/bookshelfinspector/network/server/BookShelfInventoryRequestPayloadHandler.java @@ -0,0 +1,25 @@ +package me.lukasabbe.bookshelfinspector.network.server; + +import me.lukasabbe.bookshelfinspector.Bookshelfinspector; +import me.lukasabbe.bookshelfinspector.network.packets.BookShelfInventoryPayload; +import me.lukasabbe.bookshelfinspector.network.packets.BookShelfInventoryRequestPayload; +import me.lukasabbe.bookshelfinspector.util.BookshelfTools; +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; + +public class BookShelfInventoryRequestPayloadHandler implements ServerPlayNetworking.PlayPayloadHandler { + @Override + public void receive(BookShelfInventoryRequestPayload bookShelfInventoryRequestPayload, ServerPlayNetworking.Context context) { + context.server().execute(() -> { + if(Bookshelfinspector.serverInstance == null) return; + + ItemStack stack = BookshelfTools.getItemById(bookShelfInventoryRequestPayload.pos(),bookShelfInventoryRequestPayload.slotNum(),context.player()); + if(stack == null){ + ServerPlayNetworking.send(context.player(), new BookShelfInventoryPayload(Items.AIR.getDefaultStack(), bookShelfInventoryRequestPayload.pos(), bookShelfInventoryRequestPayload.slotNum())); + return; + } + ServerPlayNetworking.send(context.player(), new BookShelfInventoryPayload(stack, bookShelfInventoryRequestPayload.pos(), bookShelfInventoryRequestPayload.slotNum())); + }); + } +} diff --git a/remappedSrc/me/lukasabbe/bookshelfinspector/network/server/LecternInventoryRequestPayloadHandler.java b/remappedSrc/me/lukasabbe/bookshelfinspector/network/server/LecternInventoryRequestPayloadHandler.java new file mode 100644 index 0000000..6fdaa58 --- /dev/null +++ b/remappedSrc/me/lukasabbe/bookshelfinspector/network/server/LecternInventoryRequestPayloadHandler.java @@ -0,0 +1,26 @@ +package me.lukasabbe.bookshelfinspector.network.server; + +import me.lukasabbe.bookshelfinspector.Bookshelfinspector; +import me.lukasabbe.bookshelfinspector.network.packets.BookShelfInventoryPayload; +import me.lukasabbe.bookshelfinspector.network.packets.LecternInventoryRequestPayload; +import me.lukasabbe.bookshelfinspector.util.LecternTools; +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; + +public class LecternInventoryRequestPayloadHandler implements ServerPlayNetworking.PlayPayloadHandler{ + @Override + public void receive(LecternInventoryRequestPayload lecternInventoryRequestPayload, ServerPlayNetworking.Context context) { + context.server().execute(() ->{ + if(Bookshelfinspector.serverInstance == null) return; + + ItemStack stack = LecternTools.getItemStack(lecternInventoryRequestPayload.pos(), context.player()); + + if(stack == null){ + ServerPlayNetworking.send(context.player(), new BookShelfInventoryPayload(Items.AIR.getDefaultStack(), lecternInventoryRequestPayload.pos(), 0)); + return; + } + ServerPlayNetworking.send(context.player(), new BookShelfInventoryPayload(stack, lecternInventoryRequestPayload.pos(), 0)); + }); + } +} diff --git a/remappedSrc/me/lukasabbe/bookshelfinspector/util/BookshelfTools.java b/remappedSrc/me/lukasabbe/bookshelfinspector/util/BookshelfTools.java new file mode 100644 index 0000000..7a1e091 --- /dev/null +++ b/remappedSrc/me/lukasabbe/bookshelfinspector/util/BookshelfTools.java @@ -0,0 +1,28 @@ +package me.lukasabbe.bookshelfinspector.util; + +import me.lukasabbe.bookshelfinspector.Bookshelfinspector; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.block.entity.ChiseledBookshelfBlockEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import java.util.Optional; + +public class BookshelfTools { + public static ItemStack getItemById(BlockPos pos, int slotNum, PlayerEntity player){ + final World world = Bookshelfinspector.serverInstance.getPlayerManager().getPlayer(player.getUuid()).getWorld(); + + if(world == null) return null; + Optional blockEntityOptional = world.getBlockEntity(pos,BlockEntityType.CHISELED_BOOKSHELF); + if(blockEntityOptional.isEmpty()) return null; + + ChiseledBookshelfBlockEntity blockEntity = blockEntityOptional.get(); + + final ItemStack stack = blockEntity.getStack(slotNum); + if(stack.isEmpty()) return null; + + return stack; + } +} diff --git a/remappedSrc/me/lukasabbe/bookshelfinspector/util/HudRenderer.java b/remappedSrc/me/lukasabbe/bookshelfinspector/util/HudRenderer.java new file mode 100644 index 0000000..e72eb41 --- /dev/null +++ b/remappedSrc/me/lukasabbe/bookshelfinspector/util/HudRenderer.java @@ -0,0 +1,92 @@ +package me.lukasabbe.bookshelfinspector.util; + +import me.lukasabbe.bookshelfinspector.BookshelfinspectorClient; +import me.lukasabbe.bookshelfinspector.data.BookData; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.component.type.ItemEnchantmentsComponent; +import net.minecraft.enchantment.Enchantment; +import net.minecraft.item.ItemStack; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.registry.tag.EnchantmentTags; +import net.minecraft.text.MutableText; +import net.minecraft.text.Style; +import net.minecraft.text.Text; +import net.minecraft.text.Texts; +import net.minecraft.util.Formatting; + +@Environment(EnvType.CLIENT) +public class HudRenderer { + public static void hudRender(DrawContext context, MinecraftClient client){ + if(!BookshelfinspectorClient.modAvailable) return; + + if(client.options.hudHidden) return; + + if(BookshelfinspectorClient.bookShelfData.isCurrentBookDataToggled){ + final BookData currentBookData = BookshelfinspectorClient.currentBookData; + int screenWidth = client.getWindow().getScaledWidth(); + int screenHeight = client.getWindow().getScaledHeight(); + int x = screenWidth / 2; + int y = screenHeight / 2; + final ItemStack itemStack = currentBookData.itemStack; + int color = 0xFFFFFFFF; + + final Integer colorValue = itemStack.getRarity().getFormatting().getColorValue(); + if(colorValue != null){ + color = colorValue; + } + + float scaleFactor = ((float) BookshelfinspectorClient.config.scale /10); + drawScaledText(context, itemStack.getName(), x,y+((int)(10*scaleFactor)), color, client.textRenderer); + + ItemEnchantmentsComponent storedComponents = itemStack.getComponents().get(DataComponentTypes.STORED_ENCHANTMENTS); + if(storedComponents != null){ + int i = ((int)(20*scaleFactor)); + for(RegistryEntry enchantment : storedComponents.getEnchantments()){ + String lvl = ""; + final int level = storedComponents.getLevel(enchantment); + if(level != 1) + lvl = String.valueOf(level); + final MutableText enchantmentText; + + if(!BookshelfinspectorClient.config.useRoman || level == -1) + enchantmentText = enchantment.value().description().copy().append(" " + lvl); + else if (level != 1) + enchantmentText = enchantment.value().description().copy().append(" " + RomanNumerals.toRoman(level)); + else + enchantmentText = enchantment.value().description().copy(); + + if(enchantment.isIn(EnchantmentTags.CURSE)) { + Texts.setStyleIfAbsent(enchantmentText, Style.EMPTY.withColor(Formatting.RED)); + }else { + Texts.setStyleIfAbsent(enchantmentText, Style.EMPTY.withColor(Formatting.GRAY)); + } + drawScaledText(context, enchantmentText, x,y+i, 0xFFFFFFFF,client.textRenderer); + i+=(int)(10*scaleFactor); + } + } + + var writtenBookContentComponent = itemStack.getComponents().get(DataComponentTypes.WRITTEN_BOOK_CONTENT); + + if(writtenBookContentComponent != null){ + drawScaledText(context, Text.translatable("book.byAuthor",writtenBookContentComponent.author()), x,y+(int)(20*scaleFactor), 0xFFFFFFFF,client.textRenderer); + } + + } + } + private static void drawScaledText(DrawContext context, Text text, int centerX, int y, int color, TextRenderer textRenderer){ + MatrixStack stack = context.getMatrices(); + stack.push(); + stack.translate(centerX,y,0); + final float scale = (float) BookshelfinspectorClient.config.scale / 10; + stack.scale(scale, scale, scale); + stack.translate(-centerX,-y,0); + context.drawCenteredTextWithShadow(textRenderer,text,centerX,y,color); + stack.pop(); + } +} diff --git a/remappedSrc/me/lukasabbe/bookshelfinspector/util/Inspector.java b/remappedSrc/me/lukasabbe/bookshelfinspector/util/Inspector.java new file mode 100644 index 0000000..676d0bb --- /dev/null +++ b/remappedSrc/me/lukasabbe/bookshelfinspector/util/Inspector.java @@ -0,0 +1,125 @@ +package me.lukasabbe.bookshelfinspector.util; + +import me.lukasabbe.bookshelfinspector.BookshelfinspectorClient; +import me.lukasabbe.bookshelfinspector.data.BookData; +import me.lukasabbe.bookshelfinspector.mixin.BookshelfInvoker; +import me.lukasabbe.bookshelfinspector.network.packets.BookShelfInventoryRequestPayload; +import me.lukasabbe.bookshelfinspector.network.packets.LecternInventoryRequestPayload; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; +import net.fabricmc.fabric.api.tag.convention.v2.ConventionalBlockTags; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.ChiseledBookshelfBlock; +import net.minecraft.client.MinecraftClient; +import net.minecraft.registry.tag.BlockTags; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.hit.HitResult; +import net.minecraft.util.math.BlockPos; + +import java.util.OptionalInt; + +import static me.lukasabbe.bookshelfinspector.BookshelfinspectorClient.*; + +@Environment(EnvType.CLIENT) +public class Inspector { + public void inspect(MinecraftClient client){ + if(!modAvailable) return; + + if(client.cameraEntity == null || client.player == null) return; + + //Send raycast max 5 blocks + HitResult hit = client.cameraEntity.raycast(5f,0f,false); + + //find block hit, if not found block returns + final HitResult.Type type = hit.getType(); + if(type != HitResult.Type.BLOCK) { + resetBookShelfData(); + return; + } + + final BlockHitResult blockHitResult = (BlockHitResult) hit; + BlockPos pos = blockHitResult.getBlockPos(); + + if(bookShelfData.latestPos == null) + bookShelfData.latestPos = pos; + + //If you look at a new block + if(!bookShelfData.latestPos.equals(pos)){ + resetBookShelfData(); + currentBookData = BookData.empty(); + } + bookShelfData.latestPos = pos; + + + if(client.player.getWorld().getBlockState(pos).isOf(Blocks.CHISELED_BOOKSHELF)){ + bookShelfInspect(pos, blockHitResult, client); + }else if(client.player.getWorld().getBlockState(pos).isOf(Blocks.LECTERN) && config.lecternToggle){ + lecternInspect(pos); + }else{ + + bookShelfData.requestSent = false; // Just for servers that don't have the latest version of mod + + if(!bookShelfData.isCurrentBookDataToggled) return; + resetBookShelfData(); + } + } + + + private void lecternInspect(BlockPos pos){ + + //Checks if there is saved data. + final BookData currentBookData = BookshelfinspectorClient.currentBookData; + + if(currentBookData.pos != null && currentBookData.pos.equals(pos)) return; + + if(!bookShelfData.requestSent){ + bookShelfData.requestSent = true; + ClientPlayNetworking.send(new LecternInventoryRequestPayload(pos)); + } + } + + + private void bookShelfInspect(BlockPos pos, BlockHitResult blockHitResult, MinecraftClient client){ + final BlockState blockState = client.player.getWorld().getBlockState(pos); + + //Gets index position for a book in the bookshelf + ChiseledBookshelfBlock bookshelfBlock = (ChiseledBookshelfBlock) blockState.getBlock(); + OptionalInt optionalInt = ((BookshelfInvoker)bookshelfBlock).invokerGetSlotForHitPos(blockHitResult,blockState); + + //if the position is empty, return + if(optionalInt.isEmpty()) { + resetBookShelfData(); + return; + } + + //Checks if there is saved data. + final BookData currentBookData = BookshelfinspectorClient.currentBookData; + + //Changes the id for the new one if it's new. + final int temp = bookShelfData.currentSlotInt; + final int slotNum = optionalInt.getAsInt(); + bookShelfData.currentSlotInt = slotNum; + + if(currentBookData.slotId!= slotNum && currentBookData.slotId!=-2 && !bookShelfData.requestSent){ + bookShelfData.requestSent = true; + ClientPlayNetworking.send(new BookShelfInventoryRequestPayload(pos, slotNum)); + } + else { + if(temp == slotNum) + bookShelfData.isCurrentBookDataToggled = currentBookData.slotId != -2; + else{ + bookShelfData.isCurrentBookDataToggled = false; + BookshelfinspectorClient.currentBookData = BookData.empty(); + } + } + } + + private void resetBookShelfData(){ + if(!bookShelfData.isCurrentBookDataToggled) return; + + bookShelfData.isCurrentBookDataToggled = false; + currentBookData = BookData.empty(); + } +} diff --git a/remappedSrc/me/lukasabbe/bookshelfinspector/util/LecternTools.java b/remappedSrc/me/lukasabbe/bookshelfinspector/util/LecternTools.java new file mode 100644 index 0000000..4811ebf --- /dev/null +++ b/remappedSrc/me/lukasabbe/bookshelfinspector/util/LecternTools.java @@ -0,0 +1,25 @@ +package me.lukasabbe.bookshelfinspector.util; + +import me.lukasabbe.bookshelfinspector.Bookshelfinspector; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.block.entity.LecternBlockEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import java.util.Optional; + +public class LecternTools { + public static ItemStack getItemStack(BlockPos pos, PlayerEntity player){ + final World world = Bookshelfinspector.serverInstance.getPlayerManager().getPlayer(player.getUuid()).getWorld(); + + if(world == null) return null; + Optional blockEntityOptional = world.getBlockEntity(pos, BlockEntityType.LECTERN); + if(blockEntityOptional.isEmpty()) return null; + + LecternBlockEntity lecternBlock = blockEntityOptional.get(); + + return lecternBlock.getBook(); + } +} diff --git a/remappedSrc/me/lukasabbe/bookshelfinspector/util/RomanNumerals.java b/remappedSrc/me/lukasabbe/bookshelfinspector/util/RomanNumerals.java new file mode 100644 index 0000000..6105be5 --- /dev/null +++ b/remappedSrc/me/lukasabbe/bookshelfinspector/util/RomanNumerals.java @@ -0,0 +1,34 @@ +package me.lukasabbe.bookshelfinspector.util; + +import java.util.TreeMap; + +//https://stackoverflow.com/questions/12967896/converting-integers-to-roman-numerals-java +public class RomanNumerals { + private final static TreeMap map = new TreeMap<>(); + static { + map.put(1000, "M"); + map.put(900, "CM"); + map.put(500, "D"); + map.put(400, "CD"); + map.put(100, "C"); + map.put(90, "XC"); + map.put(50, "L"); + map.put(40, "XL"); + map.put(10, "X"); + map.put(9, "IX"); + map.put(5, "V"); + map.put(4, "IV"); + map.put(1, "I"); + } + + + public static String toRoman(int number){ + int key = map.floorKey(number); + + if(number == key){ + return map.get(number); + } + + return map.get(key) + toRoman(number-key); + } +}