mirror of
https://github.com/lukasabbe/bookshelf-inspector.git
synced 2026-04-30 10:40:53 +00:00
Init for multiloader
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
plugins {
|
||||
id 'multiloader-common'
|
||||
id 'net.neoforged.moddev'
|
||||
}
|
||||
|
||||
neoForge {
|
||||
neoFormVersion = neo_form_version
|
||||
// Automatically enable AccessTransformers if the file exists
|
||||
def at = file('src/main/resources/META-INF/accesstransformer.cfg')
|
||||
if (at.exists()) {
|
||||
accessTransformers.from(at.absolutePath)
|
||||
}
|
||||
parchment {
|
||||
minecraftVersion = parchment_minecraft
|
||||
mappingsVersion = parchment_version
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly group: 'org.spongepowered', name: 'mixin', version: '0.8.5'
|
||||
// fabric and neoforge both bundle mixinextras, so it is safe to use it in common
|
||||
compileOnly group: 'io.github.llamalad7', name: 'mixinextras-common', version: '0.3.5'
|
||||
annotationProcessor group: 'io.github.llamalad7', name: 'mixinextras-common', version: '0.3.5'
|
||||
implementation "org.yaml:snakeyaml:${project.YAML_snake}"
|
||||
}
|
||||
|
||||
|
||||
configurations {
|
||||
shadowCommon
|
||||
implementation.extendsFrom shadowCommon
|
||||
runtimeClasspath.extendsFrom shadowCommon
|
||||
|
||||
commonJava {
|
||||
canBeResolved = false
|
||||
canBeConsumed = true
|
||||
}
|
||||
commonResources {
|
||||
canBeResolved = false
|
||||
canBeConsumed = true
|
||||
}
|
||||
}
|
||||
|
||||
artifacts {
|
||||
commonJava sourceSets.main.java.sourceDirectories.singleFile
|
||||
commonResources sourceSets.main.resources.sourceDirectories.singleFile
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.lukasabbe.bookshelfinspector;
|
||||
|
||||
import com.lukasabbe.bookshelfinspector.network.Handlers;
|
||||
import com.lukasabbe.bookshelfinspector.network.packets.ModCheckPayload;
|
||||
import com.lukasabbe.bookshelfinspector.platform.Services;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
|
||||
public class BookshelfInspector {
|
||||
public static MinecraftServer serverInstance;
|
||||
public static Handlers networkHandlers;
|
||||
|
||||
public static void init() {
|
||||
registerEvents();
|
||||
networkHandlers = new Handlers();
|
||||
}
|
||||
|
||||
private static void registerEvents(){
|
||||
Services.EVENTS_HELPER.registerOnPlayerJoinEvent((player, server) -> {
|
||||
serverInstance = server;
|
||||
Services.NETWORK_HELPER.sendPacketFromServer(player, new ModCheckPayload(true));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.lukasabbe.bookshelfinspector;
|
||||
|
||||
import com.lukasabbe.bookshelfinspector.config.Config;
|
||||
import com.lukasabbe.bookshelfinspector.data.BookData;
|
||||
import com.lukasabbe.bookshelfinspector.data.BookShelfData;
|
||||
import com.lukasabbe.bookshelfinspector.platform.Services;
|
||||
|
||||
public class BookshelfInspectorClient {
|
||||
public static BookData currentBookData = BookData.empty();
|
||||
public static BookShelfData bookShelfData = new BookShelfData();
|
||||
public static boolean modAvailable = false;
|
||||
public static Config config = new Config();
|
||||
|
||||
public static void clientInit(){
|
||||
config.loadConfig();
|
||||
|
||||
Services.EVENTS_HELPER.registerOnPlayerDisconnect(() -> {
|
||||
modAvailable = false;
|
||||
bookShelfData = new BookShelfData();
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.lukasabbe.bookshelfinspector;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class Constants {
|
||||
public static final String MOD_ID = "bookshelfinspector";
|
||||
public static final String MOD_NAME = "Bookshelf Inspector";
|
||||
public static final Logger LOG = LoggerFactory.getLogger(MOD_NAME);
|
||||
|
||||
//Packets
|
||||
public static final ResourceLocation BOOK_SHELF_INVENTORY_REQUEST_PACKET_ID = ResourceLocation.fromNamespaceAndPath(MOD_ID,"book_shelf_inventory_request");
|
||||
public static final ResourceLocation BOOK_SHELF_INVENTORY_PACKET_ID = ResourceLocation.fromNamespaceAndPath(MOD_ID,"book_shelf_inventory");
|
||||
public static final ResourceLocation MOD_CHECK_PACKET_ID = ResourceLocation.fromNamespaceAndPath(MOD_ID,"mod_check");
|
||||
public static final ResourceLocation LECTERN_INVENTORY_REQUEST_PACKET_ID = ResourceLocation.fromNamespaceAndPath(MOD_ID, "lectern_inventory_request");
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.lukasabbe.bookshelfinspector.config;
|
||||
|
||||
import com.lukasabbe.bookshelfinspector.platform.Services;
|
||||
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;
|
||||
|
||||
public class Config {
|
||||
public boolean lecternToggle = true;
|
||||
public int scale = 10;
|
||||
public boolean useRoman = false;
|
||||
|
||||
public void loadConfig(){
|
||||
Path configPath = Services.PLATFORM.getConfigPath("bookshelfinspector-config.yml");
|
||||
if(!Files.exists(configPath))createConfig(configPath);
|
||||
Yaml yaml = new Yaml();
|
||||
try{
|
||||
Map<String, Object> 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){
|
||||
Path defaultConfigPath = Services.PLATFORM.getFileInModContainer("bookshelfinspector", "bookshelfinspector-config.yml");
|
||||
try {
|
||||
Files.copy(defaultConfigPath, configPath);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void saveConfig(){
|
||||
Path configPath = Services.PLATFORM.getConfigPath("bookshelfinspector-config.yml");
|
||||
if(!Files.exists(configPath)) createConfig(configPath);
|
||||
Yaml yaml = new Yaml();
|
||||
try{
|
||||
Map<String, Object> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.lukasabbe.bookshelfinspector.data;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.lukasabbe.bookshelfinspector.data;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
||||
public class BookShelfData {
|
||||
public boolean isCurrentBookDataToggled = false;
|
||||
public BlockPos latestPos = null;
|
||||
public boolean requestSent = false;
|
||||
public int currentSlotInt = -1;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.lukasabbe.bookshelfinspector.data;
|
||||
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
||||
public class Tags {
|
||||
public static final TagKey<Block> CHISELED_BOOKSHELVES = TagKey.create(Registries.BLOCK, ResourceLocation.fromNamespaceAndPath("c", "chiseled_bookshelves"));
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.lukasabbe.bookshelfinspector.mixin;
|
||||
|
||||
import net.minecraft.world.level.block.ChiseledBookShelfBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.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("getHitSlot")
|
||||
OptionalInt invokerGetSlotForHitPos(BlockHitResult hit, BlockState state);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.lukasabbe.bookshelfinspector.mixin;
|
||||
|
||||
import com.lukasabbe.bookshelfinspector.Constants;
|
||||
import com.lukasabbe.bookshelfinspector.renderer.Inspector;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
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(LocalPlayer.class)
|
||||
public class BookshelfMixin {
|
||||
|
||||
@Shadow @Final protected Minecraft minecraft;
|
||||
@Unique private final Inspector bookshelfInspectorMultiloader$inspector = new Inspector();
|
||||
|
||||
@Inject(method = "tick", at= @At(value = "INVOKE", target = "Ljava/util/List;iterator()Ljava/util/Iterator;"))
|
||||
public void injectTick(CallbackInfo ci){
|
||||
bookshelfInspectorMultiloader$inspector.inspect(this.minecraft);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.lukasabbe.bookshelfinspector.mixin;
|
||||
|
||||
import com.lukasabbe.bookshelfinspector.Constants;
|
||||
import com.lukasabbe.bookshelfinspector.renderer.HudRenderer;
|
||||
import net.minecraft.client.DeltaTracker;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Gui;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
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;
|
||||
|
||||
@Mixin(Gui.class)
|
||||
public class InGameHudMixin {
|
||||
@Shadow @Final private Minecraft minecraft;
|
||||
|
||||
@Inject(method = "render",at=@At("RETURN"))
|
||||
public void render(GuiGraphics context, DeltaTracker tickCounter, CallbackInfo ci){
|
||||
HudRenderer.hudRender(context, minecraft);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.lukasabbe.bookshelfinspector.network;
|
||||
|
||||
import com.lukasabbe.bookshelfinspector.network.client.BookShelfInventoryHandlerServer;
|
||||
import com.lukasabbe.bookshelfinspector.network.client.ModServerPayloadHandler;
|
||||
import com.lukasabbe.bookshelfinspector.network.server.BookShelfInventoryRequestServerPayloadHandler;
|
||||
import com.lukasabbe.bookshelfinspector.network.server.LecternInventoryRequestServerPayloadHandler;
|
||||
|
||||
public class Handlers {
|
||||
public BookShelfInventoryHandlerServer bookShelfInventoryHandlerServer;
|
||||
public ModServerPayloadHandler modServerPayloadHandler;
|
||||
public BookShelfInventoryRequestServerPayloadHandler bookShelfInventoryRequestServerPayloadHandler;
|
||||
public LecternInventoryRequestServerPayloadHandler lecternInventoryRequestServerPayloadHandler;
|
||||
|
||||
public Handlers(){
|
||||
bookShelfInventoryHandlerServer = new BookShelfInventoryHandlerServer();
|
||||
modServerPayloadHandler = new ModServerPayloadHandler();
|
||||
bookShelfInventoryRequestServerPayloadHandler = new BookShelfInventoryRequestServerPayloadHandler();
|
||||
lecternInventoryRequestServerPayloadHandler = new LecternInventoryRequestServerPayloadHandler();
|
||||
}
|
||||
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package com.lukasabbe.bookshelfinspector.network.client;
|
||||
|
||||
import com.lukasabbe.bookshelfinspector.BookshelfInspectorClient;
|
||||
import com.lukasabbe.bookshelfinspector.data.BookData;
|
||||
import com.lukasabbe.bookshelfinspector.network.packets.BookShelfInventoryPayload;
|
||||
import com.lukasabbe.bookshelfinspector.platform.handlers.ClientPayloadHandler;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.world.item.Items;
|
||||
|
||||
public class BookShelfInventoryHandlerServer implements ClientPayloadHandler<BookShelfInventoryPayload> {
|
||||
@Override
|
||||
public void receive(BookShelfInventoryPayload bookShelfInventoryPayload, LocalPlayer player) {
|
||||
BookshelfInspectorClient.bookShelfData.requestSent = false;
|
||||
if(bookShelfInventoryPayload.itemStack().is(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());
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.lukasabbe.bookshelfinspector.network.client;
|
||||
|
||||
import com.lukasabbe.bookshelfinspector.BookshelfInspectorClient;
|
||||
import com.lukasabbe.bookshelfinspector.Constants;
|
||||
import com.lukasabbe.bookshelfinspector.network.packets.ModCheckPayload;
|
||||
import com.lukasabbe.bookshelfinspector.platform.handlers.ClientPayloadHandler;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
|
||||
public class ModServerPayloadHandler implements ClientPayloadHandler<ModCheckPayload> {
|
||||
@Override
|
||||
public void receive(ModCheckPayload payload, LocalPlayer player) {
|
||||
Constants.LOG.info("[bookshelfinspector] Connected to server");
|
||||
BookshelfInspectorClient.modAvailable = true;
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.lukasabbe.bookshelfinspector.network.packets;
|
||||
|
||||
import com.lukasabbe.bookshelfinspector.Constants;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public record BookShelfInventoryPayload(ItemStack itemStack, BlockPos pos, int slotNum) implements CustomPacketPayload {
|
||||
public static final CustomPacketPayload.Type<BookShelfInventoryPayload> ID = new CustomPacketPayload.Type<>(Constants.BOOK_SHELF_INVENTORY_PACKET_ID);
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, BookShelfInventoryPayload> CODEC = StreamCodec.composite(
|
||||
ItemStack.OPTIONAL_STREAM_CODEC, BookShelfInventoryPayload::itemStack,
|
||||
BlockPos.STREAM_CODEC, BookShelfInventoryPayload::pos,
|
||||
ByteBufCodecs.INT, BookShelfInventoryPayload::slotNum,
|
||||
BookShelfInventoryPayload::new
|
||||
);
|
||||
@Override
|
||||
public @NotNull Type<? extends CustomPacketPayload> type() { return ID; }
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.lukasabbe.bookshelfinspector.network.packets;
|
||||
|
||||
import com.lukasabbe.bookshelfinspector.Constants;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public record BookShelfInventoryRequestPayload(BlockPos pos, int slotNum) implements CustomPacketPayload {
|
||||
|
||||
public static final CustomPacketPayload.Type<BookShelfInventoryRequestPayload> ID = new CustomPacketPayload.Type<>(Constants.BOOK_SHELF_INVENTORY_REQUEST_PACKET_ID);
|
||||
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, BookShelfInventoryRequestPayload> CODEC = StreamCodec.composite(
|
||||
BlockPos.STREAM_CODEC,BookShelfInventoryRequestPayload::pos,
|
||||
ByteBufCodecs.INT, BookShelfInventoryRequestPayload::slotNum,
|
||||
BookShelfInventoryRequestPayload::new);
|
||||
|
||||
@Override
|
||||
public @NotNull Type<? extends CustomPacketPayload> type() { return ID; }
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package com.lukasabbe.bookshelfinspector.network.packets;
|
||||
|
||||
import com.lukasabbe.bookshelfinspector.Constants;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public record LecternInventoryRequestPayload(BlockPos pos) implements CustomPacketPayload {
|
||||
|
||||
public static final CustomPacketPayload.Type<LecternInventoryRequestPayload> ID = new CustomPacketPayload.Type<>(Constants.LECTERN_INVENTORY_REQUEST_PACKET_ID);
|
||||
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, LecternInventoryRequestPayload> CODEC = StreamCodec.composite(
|
||||
BlockPos.STREAM_CODEC,LecternInventoryRequestPayload::pos,
|
||||
LecternInventoryRequestPayload::new);
|
||||
|
||||
@Override
|
||||
public @NotNull Type<? extends CustomPacketPayload> type() { return ID; }
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package com.lukasabbe.bookshelfinspector.network.packets;
|
||||
|
||||
import com.lukasabbe.bookshelfinspector.Constants;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public record ModCheckPayload(boolean modActivated) implements CustomPacketPayload {
|
||||
public static final CustomPacketPayload.Type<ModCheckPayload> ID = new CustomPacketPayload.Type<>(Constants.MOD_CHECK_PACKET_ID);
|
||||
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, ModCheckPayload> CODEC = StreamCodec.composite(
|
||||
ByteBufCodecs.BOOL, ModCheckPayload::modActivated,
|
||||
ModCheckPayload::new
|
||||
);
|
||||
|
||||
@Override
|
||||
public @NotNull Type<? extends CustomPacketPayload> type() { return ID; }
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package com.lukasabbe.bookshelfinspector.network.server;
|
||||
|
||||
import com.lukasabbe.bookshelfinspector.BookshelfInspector;
|
||||
import com.lukasabbe.bookshelfinspector.network.packets.BookShelfInventoryPayload;
|
||||
import com.lukasabbe.bookshelfinspector.network.packets.BookShelfInventoryRequestPayload;
|
||||
import com.lukasabbe.bookshelfinspector.platform.Services;
|
||||
import com.lukasabbe.bookshelfinspector.platform.handlers.ServerPayloadHandler;
|
||||
import com.lukasabbe.bookshelfinspector.util.BookshelfTools;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
|
||||
public class BookShelfInventoryRequestServerPayloadHandler implements ServerPayloadHandler<BookShelfInventoryRequestPayload> {
|
||||
@Override
|
||||
public void receive(BookShelfInventoryRequestPayload bookShelfInventoryRequestPayload, ServerPlayer player) {
|
||||
if(BookshelfInspector.serverInstance == null) return;
|
||||
|
||||
ItemStack stack = BookshelfTools.getItemById(bookShelfInventoryRequestPayload.pos(),bookShelfInventoryRequestPayload.slotNum(), player);
|
||||
if(stack == null){
|
||||
Services.NETWORK_HELPER.sendPacketFromServer(player, new BookShelfInventoryPayload(Items.AIR.getDefaultInstance(), bookShelfInventoryRequestPayload.pos(), bookShelfInventoryRequestPayload.slotNum()));
|
||||
return;
|
||||
}
|
||||
Services.NETWORK_HELPER.sendPacketFromServer(player, new BookShelfInventoryPayload(stack, bookShelfInventoryRequestPayload.pos(), bookShelfInventoryRequestPayload.slotNum()));
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.lukasabbe.bookshelfinspector.network.server;
|
||||
|
||||
import com.lukasabbe.bookshelfinspector.BookshelfInspector;
|
||||
import com.lukasabbe.bookshelfinspector.network.packets.BookShelfInventoryPayload;
|
||||
import com.lukasabbe.bookshelfinspector.network.packets.LecternInventoryRequestPayload;
|
||||
import com.lukasabbe.bookshelfinspector.platform.Services;
|
||||
import com.lukasabbe.bookshelfinspector.platform.handlers.ServerPayloadHandler;
|
||||
import com.lukasabbe.bookshelfinspector.util.LecternTools;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
|
||||
public class LecternInventoryRequestServerPayloadHandler implements ServerPayloadHandler<LecternInventoryRequestPayload> {
|
||||
@Override
|
||||
public void receive(LecternInventoryRequestPayload lecternInventoryRequestPayload, ServerPlayer player) {
|
||||
if(BookshelfInspector.serverInstance == null) return;
|
||||
|
||||
ItemStack stack = LecternTools.getItemStack(lecternInventoryRequestPayload.pos(), player);
|
||||
|
||||
if(stack == null){
|
||||
Services.NETWORK_HELPER.sendPacketFromServer(player, new BookShelfInventoryPayload(Items.AIR.getDefaultInstance(), lecternInventoryRequestPayload.pos(), 0));
|
||||
return;
|
||||
}
|
||||
Services.NETWORK_HELPER.sendPacketFromServer(player, new BookShelfInventoryPayload(stack, lecternInventoryRequestPayload.pos(), 0));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.lukasabbe.bookshelfinspector.platform;
|
||||
|
||||
import com.lukasabbe.bookshelfinspector.Constants;
|
||||
import com.lukasabbe.bookshelfinspector.platform.services.IEventHelper;
|
||||
import com.lukasabbe.bookshelfinspector.platform.services.INetworkHelper;
|
||||
import com.lukasabbe.bookshelfinspector.platform.services.IPlatformHelper;
|
||||
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
// Service loaders are a built-in Java feature that allow us to locate implementations of an interface that vary from one
|
||||
// environment to another. In the context of MultiLoader we use this feature to access a mock API in the common code that
|
||||
// is swapped out for the platform specific implementation at runtime.
|
||||
public class Services {
|
||||
|
||||
// In this example we provide a platform helper which provides information about what platform the mod is running on.
|
||||
// For example this can be used to check if the code is running on Forge vs Fabric, or to ask the modloader if another
|
||||
// mod is loaded.
|
||||
public static final IPlatformHelper PLATFORM = load(IPlatformHelper.class);
|
||||
public static final INetworkHelper NETWORK_HELPER = load(INetworkHelper.class);
|
||||
public static final IEventHelper EVENTS_HELPER = load(IEventHelper.class);
|
||||
|
||||
// This code is used to load a service for the current environment. Your implementation of the service must be defined
|
||||
// manually by including a text file in META-INF/services named with the fully qualified class name of the service.
|
||||
// Inside the file you should write the fully qualified class name of the implementation to load for the platform. For
|
||||
// example our file on Forge points to ForgePlatformHelper while Fabric points to FabricPlatformHelper.
|
||||
public static <T> T load(Class<T> clazz) {
|
||||
|
||||
final T loadedService = ServiceLoader.load(clazz)
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new NullPointerException("Failed to load service for " + clazz.getName()));
|
||||
Constants.LOG.debug("Loaded {} for service {}", loadedService, clazz);
|
||||
return loadedService;
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package com.lukasabbe.bookshelfinspector.platform.handlers;
|
||||
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
|
||||
public interface ClientPayloadHandler<T extends CustomPacketPayload> {
|
||||
void receive(T payload, LocalPlayer player);
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package com.lukasabbe.bookshelfinspector.platform.handlers;
|
||||
|
||||
public interface OnPlayerDisconnectEvent {
|
||||
void onDisconnect();
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package com.lukasabbe.bookshelfinspector.platform.handlers;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
||||
public interface OnPlayerJoinEvent {
|
||||
void onPlayerJoin(ServerPlayer handler, MinecraftServer server);
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package com.lukasabbe.bookshelfinspector.platform.handlers;
|
||||
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
||||
public interface ServerPayloadHandler<T extends CustomPacketPayload> {
|
||||
void receive(T payload, ServerPlayer player);
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.lukasabbe.bookshelfinspector.platform.services;
|
||||
|
||||
import com.lukasabbe.bookshelfinspector.platform.handlers.OnPlayerDisconnectEvent;
|
||||
import com.lukasabbe.bookshelfinspector.platform.handlers.OnPlayerJoinEvent;
|
||||
|
||||
public interface IEventHelper {
|
||||
void registerOnPlayerJoinEvent(OnPlayerJoinEvent event);
|
||||
void registerOnPlayerDisconnect(OnPlayerDisconnectEvent event);
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.lukasabbe.bookshelfinspector.platform.services;
|
||||
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
||||
public interface INetworkHelper {
|
||||
void sendPacketFromServer(ServerPlayer player, CustomPacketPayload payload);
|
||||
void sendPacketFromClient(CustomPacketPayload payload);
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package com.lukasabbe.bookshelfinspector.platform.services;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public interface IPlatformHelper {
|
||||
String getPlatformName();
|
||||
|
||||
boolean isModLoaded(String modId);
|
||||
|
||||
boolean isDevelopmentEnvironment();
|
||||
|
||||
Path getConfigPath(String file);
|
||||
|
||||
Path getFileInModContainer(String mod, String fileName);
|
||||
|
||||
default String getEnvironmentName() {
|
||||
|
||||
return isDevelopmentEnvironment() ? "development" : "production";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.lukasabbe.bookshelfinspector.renderer;
|
||||
|
||||
import com.lukasabbe.bookshelfinspector.BookshelfInspectorClient;
|
||||
import com.lukasabbe.bookshelfinspector.Constants;
|
||||
import com.lukasabbe.bookshelfinspector.data.BookData;
|
||||
import com.lukasabbe.bookshelfinspector.util.RomanNumerals;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.ComponentUtils;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.network.chat.Style;
|
||||
import net.minecraft.tags.EnchantmentTags;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.enchantment.Enchantment;
|
||||
import net.minecraft.world.item.enchantment.ItemEnchantments;
|
||||
|
||||
public class HudRenderer {
|
||||
public static void hudRender(GuiGraphics context, Minecraft client){
|
||||
if(!BookshelfInspectorClient.modAvailable) return;
|
||||
if(client.options.hideGui) return;
|
||||
if(!BookshelfInspectorClient.bookShelfData.isCurrentBookDataToggled) return;
|
||||
|
||||
final BookData currentBookData = BookshelfInspectorClient.currentBookData;
|
||||
final int screenWidth = client.getWindow().getGuiScaledWidth();
|
||||
final int screenHeight = client.getWindow().getGuiScaledHeight();
|
||||
final int x = screenWidth / 2;
|
||||
final int y = screenHeight / 2;
|
||||
final ItemStack itemStack = currentBookData.itemStack;
|
||||
|
||||
int color = 0xFFFFFFFF;
|
||||
|
||||
final Integer colorValue = itemStack.getRarity().color().getColor();
|
||||
|
||||
if(colorValue != null){
|
||||
color = colorValue;
|
||||
}
|
||||
|
||||
float scaleFactor = ((float) BookshelfInspectorClient.config.scale /10);
|
||||
drawScaledText(context, itemStack.getHoverName(), x,y+((int)(10*scaleFactor)), color, client.font);
|
||||
|
||||
ItemEnchantments storedComponents = itemStack.getComponents().get(DataComponents.STORED_ENCHANTMENTS);
|
||||
if(storedComponents != null){
|
||||
int i = ((int)(20*scaleFactor));
|
||||
for(Holder<Enchantment> enchantment : storedComponents.keySet()){
|
||||
String lvl = "";
|
||||
final int level = storedComponents.getLevel(enchantment);
|
||||
if(level != 1)
|
||||
lvl = String.valueOf(level);
|
||||
final MutableComponent 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.is(EnchantmentTags.CURSE)) {
|
||||
ComponentUtils.mergeStyles(enchantmentText, Style.EMPTY.withColor(ChatFormatting.RED));
|
||||
}else {
|
||||
ComponentUtils.mergeStyles(enchantmentText, Style.EMPTY.withColor(ChatFormatting.GRAY));
|
||||
}
|
||||
drawScaledText(context, enchantmentText, x,y+i, 0xFFFFFFFF,client.font);
|
||||
i+=(int)(10*scaleFactor);
|
||||
}
|
||||
}
|
||||
|
||||
var writtenBookContentComponent = itemStack.getComponents().get(DataComponents.WRITTEN_BOOK_CONTENT);
|
||||
|
||||
if(writtenBookContentComponent != null){
|
||||
drawScaledText(context, Component.translatable("book.byAuthor",writtenBookContentComponent.author()), x,y+(int)(20*scaleFactor), 0xFFFFFFFF, client.font);
|
||||
}
|
||||
}
|
||||
private static void drawScaledText(GuiGraphics context, Component text, int centerX, int y, int color, Font textRenderer){
|
||||
PoseStack stack = context.pose();
|
||||
stack.pushPose();
|
||||
stack.translate(centerX,y,0);
|
||||
final float scale = (float) BookshelfInspectorClient.config.scale / 10;
|
||||
stack.scale(scale, scale, scale);
|
||||
stack.translate(-centerX,-y,0);
|
||||
context.drawCenteredString(textRenderer,text,centerX,y,color);
|
||||
stack.popPose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
package com.lukasabbe.bookshelfinspector.renderer;
|
||||
|
||||
import com.lukasabbe.bookshelfinspector.BookshelfInspectorClient;
|
||||
import com.lukasabbe.bookshelfinspector.data.BookData;
|
||||
import com.lukasabbe.bookshelfinspector.data.Tags;
|
||||
import com.lukasabbe.bookshelfinspector.mixin.BookshelfInvoker;
|
||||
import com.lukasabbe.bookshelfinspector.network.packets.BookShelfInventoryRequestPayload;
|
||||
import com.lukasabbe.bookshelfinspector.network.packets.LecternInventoryRequestPayload;
|
||||
import com.lukasabbe.bookshelfinspector.platform.Services;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.ChiseledBookShelfBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
|
||||
import java.util.OptionalInt;
|
||||
|
||||
import static com.lukasabbe.bookshelfinspector.BookshelfInspectorClient.*;
|
||||
|
||||
public class Inspector {
|
||||
public void inspect(Minecraft client){
|
||||
if(!modAvailable) return;
|
||||
|
||||
if(client.cameraEntity == null || client.player == null) return;
|
||||
|
||||
//Send raycast max 5 blocks
|
||||
HitResult hit = client.cameraEntity.pick(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.level().getBlockState(pos).is(Tags.CHISELED_BOOKSHELVES)){
|
||||
bookShelfInspect(pos, blockHitResult, client);
|
||||
}else if(client.player.level().getBlockState(pos).is(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;
|
||||
Services.NETWORK_HELPER.sendPacketFromClient(new LecternInventoryRequestPayload(pos));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void bookShelfInspect(BlockPos pos, BlockHitResult blockHitResult, Minecraft client){
|
||||
final BlockState blockState = client.player.level().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;
|
||||
Services.NETWORK_HELPER.sendPacketFromClient(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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.lukasabbe.bookshelfinspector.util;
|
||||
|
||||
import com.lukasabbe.bookshelfinspector.BookshelfInspector;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.entity.ChiseledBookShelfBlockEntity;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class BookshelfTools {
|
||||
public static ItemStack getItemById(BlockPos pos, int slotNum, Player player){
|
||||
final Level world = BookshelfInspector.serverInstance.getPlayerList().getPlayer(player.getUUID()).level();
|
||||
|
||||
final Optional<ChiseledBookShelfBlockEntity> blockEntityOptional = world.getBlockEntity(pos, BlockEntityType.CHISELED_BOOKSHELF);
|
||||
|
||||
if(blockEntityOptional.isEmpty()) return null;
|
||||
|
||||
final ChiseledBookShelfBlockEntity blockEntity = blockEntityOptional.get();
|
||||
final ItemStack stack = blockEntity.getItem(slotNum);
|
||||
|
||||
if(stack.isEmpty()) return null;
|
||||
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.lukasabbe.bookshelfinspector.util;
|
||||
|
||||
import com.lukasabbe.bookshelfinspector.BookshelfInspector;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.entity.LecternBlockEntity;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class LecternTools {
|
||||
public static ItemStack getItemStack(BlockPos pos, Player player){
|
||||
final Level world = BookshelfInspector.serverInstance.getPlayerList().getPlayer(player.getUUID()).level();
|
||||
|
||||
Optional<LecternBlockEntity> blockEntityOptional = world.getBlockEntity(pos, BlockEntityType.LECTERN);
|
||||
if(blockEntityOptional.isEmpty()) return null;
|
||||
|
||||
LecternBlockEntity lecternBlock = blockEntityOptional.get();
|
||||
|
||||
return lecternBlock.getBook();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.lukasabbe.bookshelfinspector.util;
|
||||
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class RomanNumerals {
|
||||
private final static TreeMap<Integer, String> 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);
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 60 KiB |
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"bookshelfinspector.config.title": "Bookshelf Inspector Config",
|
||||
"bookshelfinspector.config.category": "Settings",
|
||||
"bookshelfinspector.config.lectern.toggle": "Turn OFF or ON lectern support",
|
||||
"bookshelfinspector.config.lectern.toggle.tooltip": "This will turn OFF/ON the visibility of lectern inspection",
|
||||
"bookshelfinspector.config.scale": "Change the scale of the text",
|
||||
"bookshelfinspector.config.scale.tooltip": "Change the scale of the text by dragging the slider",
|
||||
"bookshelfinspector.config.roman_scale": "Use roman numerals!",
|
||||
"bookshelfinspector.config.roman_scale.tooltip": "Use roman numerals or arabic numerals"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"bookshelfinspector.config.title": "Bookshelf Inspector Config",
|
||||
"bookshelfinspector.config.category": "Inställningar",
|
||||
"bookshelfinspector.config.lectern.toggle": "Stäng AV eller PÅ läspulpet stöd",
|
||||
"bookshelfinspector.config.lectern.toggle.tooltip": "Denna inställning kommer stänga av eller på synligeten av läspulpet inspektion",
|
||||
"bookshelfinspector.config.scale": "Ändra storleken på texten",
|
||||
"bookshelfinspector.config.scale.tooltip": "Du kan göra det igenom att dra på den nedan",
|
||||
"bookshelfinspector.config.roman_scale": "Använd romerska siffror",
|
||||
"bookshelfinspector.config.roman_scale.tooltip": "Använd romerska siffror eller arabiska siffror"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
lectern-toggle: true
|
||||
scale: 10
|
||||
roman: false
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "com.lukasabbe.bookshelfinspector.mixin",
|
||||
"refmap": "${mod_id}.refmap.json",
|
||||
"compatibilityLevel": "JAVA_18",
|
||||
"mixins": [
|
||||
],
|
||||
"client": [
|
||||
"BookshelfMixin",
|
||||
"InGameHudMixin",
|
||||
"BookshelfInvoker"
|
||||
],
|
||||
"server": [],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
"minecraft:chiseled_bookshelf"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"pack": {
|
||||
"description": "${mod_name}",
|
||||
"pack_format": 8
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user