diff --git a/build.gradle b/build.gradle index 84d0cde..eb1211f 100644 --- a/build.gradle +++ b/build.gradle @@ -10,6 +10,10 @@ version = "$project.version+${libs.versions.minecraft.get()}" group = project.maven_group repositories { + maven { + name = "Fabric" + url = "https://maven.fabricmc.net/" + } maven { name = "TerraformersMC" url = "https://maven.terraformersmc.com/" @@ -42,11 +46,11 @@ loom { } dependencies { - minecraft libs.minecraft - mappings variantOf(libs.quilt.mappings) { classifier 'intermediary-v2' } - modImplementation libs.quilt.loader + minecraft "com.mojang:minecraft:${libs.versions.minecraft.get()}" + mappings "net.fabricmc:yarn:${libs.versions.minecraft.get()}+${libs.versions.yarn.get()}:v2" + modImplementation "net.fabricmc:fabric-loader:${libs.versions.fabric.loader.get()}" - modImplementation libs.quilted.fabric.api + modImplementation "net.fabricmc.fabric-api:fabric-api:${libs.versions.fabric.api.get()}+${libs.versions.minecraft.get()}" // not JiJ because it causes its mixins to fail to load modApi "dev.emi:trinkets:${libs.versions.trinkets.get()}" @@ -59,17 +63,17 @@ dependencies { processResources { inputs.property 'version', version - inputs.property 'group', project.group inputs.property 'minecraft_version', libs.versions.minecraft.get() + inputs.property 'fabric_version', libs.versions.fabric.api.get() inputs.property 'trinkets_version', libs.versions.trinkets.get() inputs.property 'lib39_version', libs.versions.lib39.get() inputs.property 'emi_version', libs.versions.emi.get() - filesMatching('quilt.mod.json') { + filesMatching('fabric.mod.json') { expand ( "version": version, - "group": project.group, "minecraft_version": libs.versions.minecraft.get(), + "fabric_version": libs.versions.fabric.api.get(), "trinkets_version": libs.versions.trinkets.get(), "lib39_version": libs.versions.lib39.get(), "emi_version": libs.versions.emi.get() diff --git a/gradle.properties b/gradle.properties index 59af25e..eb5d274 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ # Gradle Properties -org.gradle.jvmargs = -Xmx1G +org.gradle.jvmargs = -Xmx4G org.gradle.parallel = true # Mod Properties diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 593eda4..e2abba0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,28 +1,15 @@ [versions] # The latest versions are available at https://lambdaurora.dev/tools/import_quilt.html minecraft = "1.20.1" -loom = "1.4.1" +loom = "1.5.7" -quilt_mappings = "1.20.1+build.23" -quilt_loader = "0.21.0" - -quilted_fabric_api = "7.4.0+0.90.0-1.20.1" +fabric_loader = "0.15.7" +yarn = "build.10" +fabric_api = "0.91.0" trinkets = "3.7.2" lib39 = "1.5.0-experimental6.1" emi = "1.1.3" -[libraries] -minecraft = { module = "com.mojang:minecraft", version.ref = "minecraft" } -quilt_mappings = { module = "org.quiltmc:quilt-mappings", version.ref = "quilt_mappings" } -quilt_loader = { module = "org.quiltmc:quilt-loader", version.ref = "quilt_loader" } - -quilted_fabric_api = { module = "org.quiltmc.quilted-fabric-api:quilted-fabric-api", version.ref = "quilted_fabric_api" } -quilted_fabric_api_deprecated = { module = "org.quiltmc.quilted-fabric-api:quilted-fabric-api-deprecated", version.ref = "quilted_fabric_api" } - -# If you have multiple similar dependencies, you can declare a dependency bundle and reference it on the build script with "libs.bundles.example". -[bundles] -quilted_fabric_api = ["quilted_fabric_api", "quilted_fabric_api_deprecated"] - [plugins] quilt_loom = { id = "org.quiltmc.loom", version.ref = "loom" } diff --git a/src/main/java/pm/c7/scout/Scout.java b/src/main/java/pm/c7/scout/Scout.java index 898d9f7..399bba0 100644 --- a/src/main/java/pm/c7/scout/Scout.java +++ b/src/main/java/pm/c7/scout/Scout.java @@ -1,7 +1,10 @@ package pm.c7.scout; +import java.util.Properties; + import com.unascribed.lib39.core.api.AutoRegistry; +import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup; import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; @@ -10,27 +13,28 @@ import net.minecraft.registry.Registry; import net.minecraft.text.Text; import net.minecraft.util.Identifier; -import org.quiltmc.loader.api.ModContainer; -import org.quiltmc.qsl.base.api.entrypoint.ModInitializer; +import pm.c7.scout.config.ScoutConfig; import pm.c7.scout.registry.ScoutItems; public class Scout implements ModInitializer { public static final AutoRegistry AUTOREGISTRY = AutoRegistry.of(ScoutUtil.MOD_ID); public static final ItemGroup ITEM_GROUP = FabricItemGroup.builder() .icon(() -> new ItemStack(ScoutItems.SATCHEL)) - .name(Text.translatable("itemGroup.scout.itemgroup")) + .displayName(Text.translatable("itemGroup.scout.itemgroup")) .entries((context, entries) -> { - entries.addItem(ScoutItems.TANNED_LEATHER); - entries.addItem(ScoutItems.SATCHEL_STRAP); - entries.addItem(ScoutItems.SATCHEL); - entries.addItem(ScoutItems.UPGRADED_SATCHEL); - entries.addItem(ScoutItems.POUCH); - entries.addItem(ScoutItems.UPGRADED_POUCH); + entries.add(ScoutItems.TANNED_LEATHER); + entries.add(ScoutItems.SATCHEL_STRAP); + entries.add(ScoutItems.SATCHEL); + entries.add(ScoutItems.UPGRADED_SATCHEL); + entries.add(ScoutItems.POUCH); + entries.add(ScoutItems.UPGRADED_POUCH); }) .build(); + @Override - public void onInitialize(ModContainer mod) { + public void onInitialize() { + ScoutConfig.loadConfig(); ScoutItems.init(); Registry.register(Registries.ITEM_GROUP, new Identifier(ScoutUtil.MOD_ID, "itemgroup"), ITEM_GROUP); } diff --git a/src/main/java/pm/c7/scout/ScoutConfig.java b/src/main/java/pm/c7/scout/ScoutConfig.java deleted file mode 100644 index 4b57ecb..0000000 --- a/src/main/java/pm/c7/scout/ScoutConfig.java +++ /dev/null @@ -1,16 +0,0 @@ -package pm.c7.scout; - -import org.quiltmc.config.api.ReflectiveConfig; -import org.quiltmc.config.api.annotations.Comment; -import org.quiltmc.config.api.values.TrackedValue; -import org.quiltmc.loader.api.config.v2.QuiltConfig; - -public class ScoutConfig extends ReflectiveConfig { - public static final ScoutConfig CONFIG = QuiltConfig.create("", ScoutUtil.MOD_ID, ScoutConfig.class); - - @Comment("Allow shulker boxes to be placed in bags. Bags are already blacklisted from shulker boxes with no toggle.") - public final TrackedValue allowShulkers = this.value(true); - - @Comment("Allow bags to act as a quiver and pull arrows.") - public final TrackedValue useArrows = this.value(true); -} diff --git a/src/main/java/pm/c7/scout/ScoutUtil.java b/src/main/java/pm/c7/scout/ScoutUtil.java index b5f7fe7..f9dda92 100644 --- a/src/main/java/pm/c7/scout/ScoutUtil.java +++ b/src/main/java/pm/c7/scout/ScoutUtil.java @@ -7,7 +7,6 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.BeaconScreen; import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen; -import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.client.gui.screen.ingame.MerchantScreen; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.inventory.Inventory; @@ -16,7 +15,6 @@ import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtList; import net.minecraft.screen.PlayerScreenHandler; import net.minecraft.screen.slot.Slot; -import net.minecraft.screen.slot.SlotActionType; import net.minecraft.util.Identifier; import net.minecraft.util.Pair; import net.minecraft.util.collection.DefaultedList; @@ -26,7 +24,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import pm.c7.scout.item.BaseBagItem; import pm.c7.scout.item.BaseBagItem.BagType; -import pm.c7.scout.screen.BagSlot; import java.util.Optional; diff --git a/src/main/java/pm/c7/scout/client/ScoutClient.java b/src/main/java/pm/c7/scout/client/ScoutClient.java index 6136eeb..dac134d 100644 --- a/src/main/java/pm/c7/scout/client/ScoutClient.java +++ b/src/main/java/pm/c7/scout/client/ScoutClient.java @@ -1,6 +1,10 @@ package pm.c7.scout.client; +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; +import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; import net.fabricmc.fabric.api.client.rendering.v1.LivingEntityFeatureRendererRegistrationCallback; +import net.fabricmc.fabric.api.client.rendering.v1.TooltipComponentCallback; import net.minecraft.client.gui.screen.ingame.GenericContainerScreen; import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.client.gui.screen.ingame.ShulkerBoxScreen; @@ -9,11 +13,7 @@ import net.minecraft.inventory.Inventory; import net.minecraft.item.ItemStack; import net.minecraft.screen.slot.Slot; import net.minecraft.util.collection.DefaultedList; -import org.quiltmc.loader.api.ModContainer; -import org.quiltmc.qsl.base.api.entrypoint.client.ClientModInitializer; -import org.quiltmc.qsl.networking.api.client.ClientPlayNetworking; -import org.quiltmc.qsl.screen.api.client.ScreenEvents; -import org.quiltmc.qsl.tooltip.api.client.TooltipComponentCallback; + import pm.c7.scout.ScoutNetworking; import pm.c7.scout.ScoutScreenHandler; import pm.c7.scout.ScoutUtil; @@ -28,7 +28,7 @@ import pm.c7.scout.screen.BagSlot; public class ScoutClient implements ClientModInitializer { @Override - public void onInitializeClient(ModContainer mod) { + public void onInitializeClient() { ClientPlayNetworking.registerGlobalReceiver(ScoutNetworking.ENABLE_SLOTS, (client, handler, packet, sender) -> { client.execute(() -> { assert client.player != null; @@ -108,7 +108,7 @@ public class ScoutClient implements ClientModInitializer { } }); - ScreenEvents.AFTER_INIT.register((screen, client, firstInit) -> { + ScreenEvents.AFTER_INIT.register((client, screen, scaledWidth, scaledHeight) -> { if (screen instanceof HandledScreen handledScreen && client.player != null) { if (ScoutUtil.isScreenBlacklisted(screen)) { // realistically no one is going to have a screen bigger than 2147483647 pixels diff --git a/src/main/java/pm/c7/scout/client/gui/BagTooltipComponent.java b/src/main/java/pm/c7/scout/client/gui/BagTooltipComponent.java index b876eda..53627b6 100644 --- a/src/main/java/pm/c7/scout/client/gui/BagTooltipComponent.java +++ b/src/main/java/pm/c7/scout/client/gui/BagTooltipComponent.java @@ -2,7 +2,7 @@ package pm.c7.scout.client.gui; import com.google.common.math.IntMath; import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.tooltip.TooltipComponent; import net.minecraft.item.ItemStack; import net.minecraft.util.collection.DefaultedList; @@ -31,7 +31,7 @@ public class BagTooltipComponent implements TooltipComponent { } @Override - public void drawItems(TextRenderer textRenderer, int x, int y, GuiGraphics graphics) { + public void drawItems(TextRenderer textRenderer, int x, int y, DrawContext graphics) { int originalX = x; for (int i = 0; i < slotCount; i++) { @@ -45,7 +45,7 @@ public class BagTooltipComponent implements TooltipComponent { } } - private void drawSlot(int x, int y, int index, GuiGraphics graphics, TextRenderer textRenderer) { + private void drawSlot(int x, int y, int index, DrawContext graphics, TextRenderer textRenderer) { ItemStack itemStack = this.inventory.get(index); graphics.drawTexture(ScoutUtil.SLOT_TEXTURE, x, y, 0, 46, 7, 18, 18, 256, 256); graphics.drawItem(itemStack, x + 1, y + 1, index); diff --git a/src/main/java/pm/c7/scout/client/model/SatchelModel.java b/src/main/java/pm/c7/scout/client/model/SatchelModel.java index a98a4a6..a41dd1f 100644 --- a/src/main/java/pm/c7/scout/client/model/SatchelModel.java +++ b/src/main/java/pm/c7/scout/client/model/SatchelModel.java @@ -1,7 +1,7 @@ package pm.c7.scout.client.model; -import com.mojang.blaze3d.vertex.VertexConsumer; import net.minecraft.client.model.*; +import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.entity.model.SinglePartEntityModel; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.LivingEntity; diff --git a/src/main/java/pm/c7/scout/client/render/PouchFeatureRenderer.java b/src/main/java/pm/c7/scout/client/render/PouchFeatureRenderer.java index 93fa887..81bfc74 100644 --- a/src/main/java/pm/c7/scout/client/render/PouchFeatureRenderer.java +++ b/src/main/java/pm/c7/scout/client/render/PouchFeatureRenderer.java @@ -10,7 +10,7 @@ import net.minecraft.client.render.model.json.ModelTransformationMode; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.util.math.Axis; +import net.minecraft.util.math.RotationAxis; import pm.c7.scout.ScoutUtil; import pm.c7.scout.item.BaseBagItem; @@ -29,8 +29,8 @@ public class PouchFeatureRenderer) this.getContextModel()).leftLeg.rotate(matrices); - matrices.multiply(Axis.X_POSITIVE.rotationDegrees(180.0F)); - matrices.multiply(Axis.Y_POSITIVE.rotationDegrees(-90.0F)); + matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(180.0F)); + matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-90.0F)); matrices.scale(0.325F, 0.325F, 0.325F); matrices.translate(0F, -0.325F, -0.475F); this.heldItemRenderer.renderItem(entity, leftPouch, ModelTransformationMode.FIXED, false, matrices, vertexConsumers, light); @@ -39,8 +39,8 @@ public class PouchFeatureRenderer) this.getContextModel()).rightLeg.rotate(matrices); - matrices.multiply(Axis.X_POSITIVE.rotationDegrees(180.0F)); - matrices.multiply(Axis.Y_POSITIVE.rotationDegrees(-90.0F)); + matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(180.0F)); + matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-90.0F)); matrices.scale(0.325F, 0.325F, 0.325F); matrices.translate(0F, -0.325F, 0.475F); this.heldItemRenderer.renderItem(entity, rightPouch, ModelTransformationMode.FIXED, false, matrices, vertexConsumers, light); diff --git a/src/main/java/pm/c7/scout/client/render/SatchelFeatureRenderer.java b/src/main/java/pm/c7/scout/client/render/SatchelFeatureRenderer.java index 24e143b..2de05e5 100644 --- a/src/main/java/pm/c7/scout/client/render/SatchelFeatureRenderer.java +++ b/src/main/java/pm/c7/scout/client/render/SatchelFeatureRenderer.java @@ -1,9 +1,9 @@ package pm.c7.scout.client.render; -import com.mojang.blaze3d.vertex.VertexConsumer; import net.minecraft.client.model.TexturedModelData; import net.minecraft.client.render.OverlayTexture; import net.minecraft.client.render.RenderLayer; +import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.feature.FeatureRenderer; import net.minecraft.client.render.entity.feature.FeatureRendererContext; diff --git a/src/main/java/pm/c7/scout/config/QDCSS.java b/src/main/java/pm/c7/scout/config/QDCSS.java new file mode 100644 index 0000000..0fedc6a --- /dev/null +++ b/src/main/java/pm/c7/scout/config/QDCSS.java @@ -0,0 +1,459 @@ +package pm.c7.scout.config; +//package com.unascribed.qdcss; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.AbstractList; +import java.util.AbstractMap; +import java.util.AbstractSet; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.google.common.base.Splitter; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.io.CharStreams; + +/** + * A quick-and-dirty "CSS" parser. + */ +public class QDCSS { + public static class QDCSSException extends IllegalArgumentException { + public QDCSSException() {} + public QDCSSException(String message, Throwable cause) { super(message, cause); } + public QDCSSException(String s) { super(s); } + public QDCSSException(Throwable cause) { super(cause); } + } + public static class BadValueException extends QDCSSException { + public BadValueException() {} + public BadValueException(String message, Throwable cause) { super(message, cause); } + public BadValueException(String s) { super(s); } + public BadValueException(Throwable cause) { super(cause); } + } + public static class SyntaxErrorException extends QDCSSException { + public SyntaxErrorException() {} + public SyntaxErrorException(String message, Throwable cause) { super(message, cause); } + public SyntaxErrorException(String s) { super(s); } + public SyntaxErrorException(Throwable cause) { super(cause); } + } + + private static class BlameString { + public final String value; + public final String file; + public final int line; + + private BlameString(String value) { + this(value, null, -1); + } + + private BlameString(String value, String file, int line) { + this.value = value; + this.file = file; + this.line = line; + } + public String blame() { + return line == -1 ? "" : "line "+line+" in "+file; + } + } + + private final String prelude; + private final Map> data; + + private Consumer yapLog; + + private QDCSS(String prelude, Map> data) { + this.prelude = prelude; + this.data = data; + } + + /** + * Enables "yap" mode for parse failures in this config, where rather than throwing a + * BadValueException a warning string will be sent to this Consumer and an empty Optional + * returned to the caller of get*. + *

+ * If yapLog is null, "yap" mode is turned off. + */ + public void setYapLog(Consumer yapLog) { + this.yapLog = yapLog; + } + + public boolean containsKey(String key) { + return data.containsKey(key) && !data.get(key).isEmpty(); + } + + public void put(String key, String value) { + List li = new ArrayList<>(); + li.add(new BlameString(value)); + data.put(key, li); + } + + public void put(String key, String... values) { + List li = new ArrayList<>(); + for (String v : values) { + li.add(new BlameString(v)); + } + data.put(key, li); + } + + public void put(String key, Iterable values) { + List li = new ArrayList<>(); + for (String v : values) { + li.add(new BlameString(v)); + } + data.put(key, li); + } + + /** + * Return all defined values for the given key, or an empty list if it's not defined. + */ + public List getAll(String key) { + return unwrap(data.get(key)); + } + + private List getAllBlamed(String key) { + return data.containsKey(key) ? data.get(key) : Collections.emptyList(); + } + + public String getBlame(String key) { + return getBlamed(key).map(BlameString::blame).orElse(""); + } + + public String getBlame(String key, int index) { + if (containsKey(key)) { + return getAllBlamed(key).get(index).blame(); + } + return ""; + } + + private List unwrap(List list) { + if (list == null) return Collections.emptyList(); + return new AbstractList() { + + @Override + public String get(int index) { + return unwrap(list.get(index)); + } + + @Override + public int size() { + return list.size(); + } + + }; + } + + private String unwrap(BlameString bs) { + if (bs == null) return null; + return bs.value; + } + + /** + * Return the last defined value for the given key. + */ + public Optional get(String key) { + return Optional.ofNullable(getLast(getAll(key))); + } + + private Optional getBlamed(String key) { + return Optional.ofNullable(getLast(getAllBlamed(key))); + } + + public Optional getInt(String key) throws BadValueException { + return getParsed(key, Integer::parseInt, () -> "a whole number"); + } + + public Optional getDouble(String key) throws BadValueException { + return getParsed(key, Double::parseDouble, () -> "a number"); + } + + public Optional getBoolean(String key) throws BadValueException { + return getParsed(key, this::strictParseBoolean, () -> "true/on or false/off"); + } + + private boolean strictParseBoolean(String s) { + switch (s.toLowerCase(Locale.ROOT)) { + case "on": case "true": return true; + case "off": case "false": return false; + default: throw new IllegalArgumentException(); + } + } + + public > Optional getEnum(String key, Class clazz) throws BadValueException { + return getParsed(key, s -> Enum.valueOf(clazz, s.toUpperCase(Locale.ROOT)), () -> { + StringBuilder sb = new StringBuilder("one of "); + boolean first = true; + for (E e : clazz.getEnumConstants()) { + if (first) { + first = false; + } else { + sb.append(", "); + } + sb.append(e.name().toLowerCase(Locale.ROOT)); + } + return sb.toString(); + }); + } + + private Optional getParsed(String key, Function parser, Supplier error) throws BadValueException { + Optional s = get(key); + if (!s.isPresent()) return Optional.empty(); + try { + return Optional.of(parser.apply(s.get())); + } catch (IllegalArgumentException e) { + String msg = key+" must be "+error.get()+" (got "+s.get()+") near "+getBlame(key); + if (yapLog != null) { + yapLog.accept(msg); + return Optional.empty(); + } else { + throw new BadValueException(msg, e); + } + } + } + + private T getLast(List list) { + return list == null || list.isEmpty() ? null : list.get(list.size()-1); + } + + public Set keySet() { + return data.keySet(); + } + + public Set>> entrySet() { + return new AbstractSet>>() { + + @Override + public Iterator>> iterator() { + Iterator>> delegate = data.entrySet().iterator(); + return new Iterator>>() { + + @Override + public boolean hasNext() { + return delegate.hasNext(); + } + + @Override + public Map.Entry> next() { + Map.Entry> den = delegate.next(); + return new AbstractMap.SimpleImmutableEntry<>(den.getKey(), unwrap(den.getValue())); + } + }; + } + + @Override + public int size() { + return size(); + } + + }; + } + + public int size() { + return data.size(); + } + + /** + * Lossily convert this QDCSS's data into an INI. Comments, section declarations, etc will + * be lost. + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("; Loaded from "); + sb.append(prelude); + sb.append("\r\n"); + for (Map.Entry> en : entrySet()) { + for (String v : en.getValue()) { + sb.append(en.getKey()); + sb.append("="); + sb.append(v); + sb.append("\r\n"); + } + } + return sb.toString(); + } + + /** + * Merge the given QDCSS's data with this QDCSS's data, returning a new QDCSS object. Keys + * defined in the given QDCSS will have their values appended to this one's. For usages of + * {@link #get}, this is equivalent to an override. + */ + public QDCSS merge(QDCSS that) { + Map> newData = new LinkedHashMap<>(Math.max(this.size(), that.size())); + newData.putAll(data); + for (Map.Entry> en : that.data.entrySet()) { + if (newData.containsKey(en.getKey())) { + List merged = new ArrayList<>(newData.get(en.getKey()).size()+en.getValue().size()); + merged.addAll(newData.get(en.getKey())); + merged.addAll(en.getValue()); + newData.put(en.getKey(), Collections.unmodifiableList(merged)); + } else { + newData.put(en.getKey(), en.getValue()); + } + } + return new QDCSS(prelude+", merged with "+that.prelude, Collections.unmodifiableMap(newData)); + } + + /** + * Return a view of this QDCSS's data, dropping multivalues and collapsing to a basic key-value + * mapping that returns the last defined value for any given key. + */ + public Map flatten() { + return new AbstractMap() { + + @Override + public String get(Object key) { + return QDCSS.this.get((String)key).orElse(null); + } + + @Override + public boolean containsKey(Object key) { + return QDCSS.this.containsKey((String)key); + } + + @Override + public Set keySet() { + return QDCSS.this.keySet(); + } + + @Override + public int size() { + return QDCSS.this.size(); + } + + @Override + public Set> entrySet() { + return new AbstractSet>() { + + @Override + public Iterator> iterator() { + Iterator>> delegate = QDCSS.this.entrySet().iterator(); + return new Iterator>() { + + @Override + public boolean hasNext() { + return delegate.hasNext(); + } + + @Override + public Entry next() { + Entry> den = delegate.next(); + return new SimpleImmutableEntry<>(den.getKey(), getLast(den.getValue())); + } + }; + } + + @Override + public int size() { + return size(); + } + + }; + } + + }; + } + + private static final Pattern JUNK_PATTERN = Pattern.compile("^(\\s*(/\\*.*?\\*/)?\\s*)*$", Pattern.DOTALL); + private static final Pattern RULESET_PATTERN = Pattern.compile("[#.]?(\\w+?)\\s*\\{(.*?)\\}", Pattern.DOTALL); + private static final Pattern RULE_PATTERN = Pattern.compile("(\\S+?)\\s*:\\s*(\\\".*?\\\"|'.*?'|.+?)\\s*(;|$)"); + + public static QDCSS load(String fileName, String s) throws SyntaxErrorException { + // vanilla CSS is a very simple grammar, so we can parse it using only regexes + Map> data = new LinkedHashMap<>(); + Matcher ruleset = RULESET_PATTERN.matcher(s); + int lastEnd = 0; + while (ruleset.find()) { + String skipped = s.substring(lastEnd, ruleset.start()); + if (!JUNK_PATTERN.matcher(skipped).matches()) { + throw new SyntaxErrorException("Expected a ruleset near line "+getLine(s, ruleset.start())+" in "+fileName); + } + String selector = ruleset.group(1); + String rules = ruleset.group(2); + Matcher rule = RULE_PATTERN.matcher(rules); + int lastRulesEnd = 0; + while (rule.find()) { + String skippedRule = rules.substring(lastRulesEnd, rule.start()); + if (!JUNK_PATTERN.matcher(skippedRule).matches()) { + throw new SyntaxErrorException("Expected a rule near line "+getLine(s, ruleset.start(2)+rule.start())+" in "+fileName); + } + String property = rule.group(1); + String value = rule.group(2); + String key = selector+"."+property; + if (!data.containsKey(key)) { + data.put(key, Lists.newArrayList()); + } + data.get(key).add(new BlameString(value, fileName, getLine(s, ruleset.start(2)+rule.start()))); + lastRulesEnd = rule.end(); + } + String skippedRule = rules.substring(lastRulesEnd); + if (!JUNK_PATTERN.matcher(skippedRule).matches()) { + throw new SyntaxErrorException("Expected a rule near line "+getLine(s, ruleset.start(2)+lastRulesEnd)+" in "+fileName); + } + lastEnd = ruleset.end(); + } + String skipped = s.substring(lastEnd); + if (!JUNK_PATTERN.matcher(skipped).matches()) { + throw new SyntaxErrorException("Expected a ruleset or EOF near line "+getLine(s, lastEnd)+" in "+fileName); + } + return new QDCSS(fileName, data); + } + + private static int getLine(String s, int start) { + int line = 1; + for (int i = 0; i < start; i++) { + if (s.charAt(i) == '\n') { + line++; + } + } + return line; + } + + public static QDCSS load(File f) throws IOException { + try (InputStream in = new FileInputStream(f)) { + return load(f.getName(), in); + } + } + + public static QDCSS load(Path p) throws IOException { + try (InputStream in = Files.newInputStream(p)) { + return load(p.getFileName().toString(), in); + } + } + + private static final Splitter SLASH_SPLITTER = Splitter.on('/'); + + public static QDCSS load(URL u) throws IOException { + try (InputStream in = u.openStream()) { + return load(Iterables.getLast(SLASH_SPLITTER.split(u.getPath())), in); + } + } + + public static QDCSS load(String fileName, InputStream in) throws IOException { + return load(fileName, new InputStreamReader(in, StandardCharsets.UTF_8)); + } + + public static QDCSS load(String fileName, Reader r) throws IOException { + return load(fileName, CharStreams.toString(r)); + } + +} diff --git a/src/main/java/pm/c7/scout/config/ScoutConfig.java b/src/main/java/pm/c7/scout/config/ScoutConfig.java new file mode 100644 index 0000000..b5a3c85 --- /dev/null +++ b/src/main/java/pm/c7/scout/config/ScoutConfig.java @@ -0,0 +1,232 @@ +package pm.c7.scout.config; + +import java.io.File; +import java.io.FileWriter; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.reflect.Field; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +import joptsimple.internal.Strings; + +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.client.font.TextHandler; +import net.minecraft.text.StringVisitable; +import net.minecraft.text.Style; + +import pm.c7.scout.ScoutUtil; + +// most of this is taken from EMI +public class ScoutConfig { + private static final Map, Setter> SETTERS = Maps.newHashMap(); + private static final Map, Writer> WRITERS = Maps.newHashMap(); + private static final Map> unparsed = Maps.newHashMap(); + public static final String DEFAULT_CONFIG; + public static String startupConfig; + + // {{{ config values + @Comment("Allow shulker boxes to be placed in bags. Bags are already blacklisted from shulker boxes with no toggle.") + @ConfigValue("features.allow-shulkers") + public static boolean allowShulkers = true; + + @Comment("Allow bags to act as a quiver and pull arrows.") + @ConfigValue("features.use-arrows") + public static boolean useArrows = true; + // }}} + + // {{{ methods + public static void loadConfig() { + try { + File config = getConfigFile(); + if (config.exists() && config.isFile()) { + QDCSS css = QDCSS.load(config); + loadConfig(css); + } else { + File defaultConfig = new File(FabricLoader.getInstance().getConfigDir().getParent().toFile(), "defaultconfigs/scout.css"); + if (defaultConfig.exists() && defaultConfig.isFile()) { + QDCSS css = QDCSS.load(defaultConfig); + loadConfig(css); + } + } + if (startupConfig == null) { + startupConfig = getSavedConfig(); + } + writeConfig(); + } catch (Exception e) { + ScoutUtil.LOGGER.error("[Scout] Error reading config"); + e.printStackTrace(); + } + } + + public static void loadConfig(QDCSS css) { + try { + Set consumed = Sets.newHashSet(); + for (Field field : ScoutConfig.class.getFields()) { + ConfigValue annot = field.getAnnotation(ConfigValue.class); + if (annot != null) { + if (css.containsKey(annot.value())) { + consumed.add(annot.value()); + assignField(css, annot.value(), field); + } + } + } + for (String key : css.keySet()) { + if (!consumed.contains(key)) { + unparsed.put(key, css.getAll(key)); + } + } + } catch (Exception e) { + ScoutUtil.LOGGER.error("[Scout] Error reading config"); + e.printStackTrace(); + } + } + + public static void writeConfig() { + try { + FileWriter writer = new FileWriter(getConfigFile()); + writer.write(getSavedConfig()); + writer.close(); + } catch (Exception e) { + ScoutUtil.LOGGER.error("[Scout] Error writing config"); + e.printStackTrace(); + } + } + + public static String getSavedConfig() { + Map> unparsed = Maps.newLinkedHashMap(); + TextHandler wrapper = new TextHandler((point, style) -> 1); + for (Field field : ScoutConfig.class.getFields()) { + ConfigValue annot = field.getAnnotation(ConfigValue.class); + if (annot != null) { + String[] parts = annot.value().split("\\."); + String group = parts[0]; + String key = parts[1]; + Comment comment = field.getAnnotation(Comment.class); + String commentText = ""; + if (comment != null) { + commentText += "\t/**\n"; + for (StringVisitable line : wrapper.wrapLines(comment.value(), 80, Style.EMPTY)) { + commentText += "\t * "; + commentText += line.getString(); + commentText += "\n"; + } + commentText += "\t */\n"; + } + String text = commentText; + try { + text += writeField(key, field); + } catch (Exception e) { + ScoutUtil.LOGGER.error("[Scout] Error serializing config"); + e.printStackTrace(); + } + unparsed.computeIfAbsent(group, g -> Lists.newArrayList()).add(text); + } + } + for (Map.Entry> entry : ScoutConfig.unparsed.entrySet()) { + String[] parts = entry.getKey().split("\\."); + String group = parts[0]; + String key = parts[1]; + for (String value : entry.getValue()) { + unparsed.computeIfAbsent(group, g -> Lists.newArrayList()).add("\t/** unparsed */\n\t" + key + ": " + + value + ";\n"); + } + } + String ret = ""; + boolean firstCategory = true; + for (Map.Entry> category : unparsed.entrySet()) { + if (!firstCategory) { + ret += "\n"; + } + firstCategory = false; + + ret += "#" + category.getKey() + " {\n"; + ret += Strings.join(category.getValue(), "\n"); + ret += "}\n"; + } + return ret; + } + + private static File getConfigFile() { + return new File(FabricLoader.getInstance().getConfigDir().toFile(), "scout.css"); + } + + private static void assignField(QDCSS css, String annot, Field field) throws IllegalAccessException { + Class type = field.getType(); + Setter setter = SETTERS.get(type); + if (setter != null) { + setter.setValue(css, annot, field); + } else { + throw new RuntimeException("[Scout] Unknown parsing type: " + type); + } + } + + @SuppressWarnings("unchecked") + private static String writeField(String key, Field field) throws IllegalAccessException { + String text = ""; + Class type = field.getType(); + if (WRITERS.containsKey(type)) { + text += "\t" + key + ": " + ((Writer) WRITERS.get(type)).writeValue(field.get(null)) + ";\n"; + } + return text; + } + + private static void defineType(Class clazz, Setter setter, Writer writer) { + SETTERS.put(clazz, setter); + WRITERS.put(clazz, writer); + } + + private static void defineType(Class clazz, Setter setter) { + defineType(clazz, setter, field -> field.toString()); + } + // }}} + + // {{{ static init + static { + defineType(boolean.class, (css, annot, field) -> field.setBoolean(null, css.getBoolean(annot).get())); + defineType(int.class, (css, annot, field) -> field.setInt(null, css.getInt(annot).get())); + defineType(double.class, (css, annot, field) -> field.setDouble(null, css.getDouble(annot).get())); + defineType(String.class, + (css, annot, field) -> { + String s = css.get(annot).get(); + s = s.substring(1, s.length() - 1); + field.set(null, s); + }, + (String field) -> "\"" + field + "\"" + ); + + DEFAULT_CONFIG = getSavedConfig(); + } + // }}} + + // {{{ annotations + @Target(ElementType.FIELD) + @Retention(RetentionPolicy.RUNTIME) + public static @interface ConfigValue { + public String value(); + } + + @Target(ElementType.FIELD) + @Retention(RetentionPolicy.RUNTIME) + public static @interface Comment { + public String value(); + } + // }}} + + // {{{ interfaces + private static interface Setter { + void setValue(QDCSS css, String annot, Field field) throws IllegalAccessException ; + } + + private static interface Writer { + String writeValue(T value); + } + // }}} +} diff --git a/src/main/java/pm/c7/scout/item/BaseBagItem.java b/src/main/java/pm/c7/scout/item/BaseBagItem.java index 9dc4f5d..5085840 100644 --- a/src/main/java/pm/c7/scout/item/BaseBagItem.java +++ b/src/main/java/pm/c7/scout/item/BaseBagItem.java @@ -3,6 +3,7 @@ package pm.c7.scout.item; import dev.emi.trinkets.api.SlotReference; import dev.emi.trinkets.api.TrinketItem; import io.netty.buffer.Unpooled; +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; import net.minecraft.client.item.TooltipContext; import net.minecraft.client.item.TooltipData; import net.minecraft.entity.Entity; @@ -21,7 +22,7 @@ import net.minecraft.util.Formatting; import net.minecraft.util.collection.DefaultedList; import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; -import org.quiltmc.qsl.networking.api.ServerPlayNetworking; + import pm.c7.scout.ScoutNetworking; import pm.c7.scout.ScoutScreenHandler; import pm.c7.scout.ScoutUtil; diff --git a/src/main/java/pm/c7/scout/mixin/BowItemMixin.java b/src/main/java/pm/c7/scout/mixin/BowItemMixin.java index 56ebb8f..4ff2e28 100644 --- a/src/main/java/pm/c7/scout/mixin/BowItemMixin.java +++ b/src/main/java/pm/c7/scout/mixin/BowItemMixin.java @@ -12,14 +12,14 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import pm.c7.scout.ScoutUtil; -import pm.c7.scout.ScoutConfig; +import pm.c7.scout.config.ScoutConfig; import pm.c7.scout.item.BaseBagItem; @Mixin(BowItem.class) public class BowItemMixin { @Inject(method = "onStoppedUsing", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;playSound(Lnet/minecraft/entity/player/PlayerEntity;DDDLnet/minecraft/sound/SoundEvent;Lnet/minecraft/sound/SoundCategory;FF)V"), locals = LocalCapture.CAPTURE_FAILHARD) public void scout$arrowsFromBags(ItemStack stack, World world, LivingEntity user, int remainingUseTicks, CallbackInfo ci, PlayerEntity playerEntity, boolean bl, ItemStack itemStack, int maxTime, float f) { - if (ScoutConfig.CONFIG.useArrows.value()) { + if (ScoutConfig.useArrows) { boolean infinity = bl && itemStack.isOf(Items.ARROW); boolean hasRan = false; diff --git a/src/main/java/pm/c7/scout/mixin/PlayerEntityMixin.java b/src/main/java/pm/c7/scout/mixin/PlayerEntityMixin.java index 38fdc17..90e36c0 100644 --- a/src/main/java/pm/c7/scout/mixin/PlayerEntityMixin.java +++ b/src/main/java/pm/c7/scout/mixin/PlayerEntityMixin.java @@ -8,16 +8,16 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import pm.c7.scout.ScoutUtil; -import pm.c7.scout.ScoutConfig; +import pm.c7.scout.config.ScoutConfig; import pm.c7.scout.item.BaseBagItem; import java.util.function.Predicate; @Mixin(PlayerEntity.class) public class PlayerEntityMixin { - @Inject(method = "getArrowType", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/item/RangedWeaponItem;getProjectiles()Ljava/util/function/Predicate;"), locals = LocalCapture.CAPTURE_FAILHARD, cancellable = true) - public void scout$arrowsFromBags(ItemStack stack, CallbackInfoReturnable cir, Predicate predicate, ItemStack itemStack) { - if (ScoutConfig.CONFIG.useArrows.value()) { + @Inject(method = "getProjectileType", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/item/RangedWeaponItem;getProjectiles()Ljava/util/function/Predicate;"), locals = LocalCapture.CAPTURE_FAILHARD, cancellable = true) + public void scout$arrowsFromBags(ItemStack stack, CallbackInfoReturnable cir, Predicate predicate) { + if (ScoutConfig.useArrows) { var self = (PlayerEntity) (Object) this; var leftPouch = ScoutUtil.findBagItem(self, BaseBagItem.BagType.POUCH, false); var rightPouch = ScoutUtil.findBagItem(self, BaseBagItem.BagType.POUCH, true); diff --git a/src/main/java/pm/c7/scout/mixin/PlayerScreenHandlerTransformer.java b/src/main/java/pm/c7/scout/mixin/PlayerScreenHandlerTransformer.java index fa68c4b..2d95367 100644 --- a/src/main/java/pm/c7/scout/mixin/PlayerScreenHandlerTransformer.java +++ b/src/main/java/pm/c7/scout/mixin/PlayerScreenHandlerTransformer.java @@ -1,8 +1,8 @@ package pm.c7.scout.mixin; import org.objectweb.asm.tree.*; -import org.quiltmc.loader.api.QuiltLoader; +import net.fabricmc.loader.api.FabricLoader; import pm.c7.scout.mixinsupport.ClassNodeTransformer; import static org.objectweb.asm.Opcodes.*; @@ -10,7 +10,7 @@ import static org.objectweb.asm.Opcodes.*; public class PlayerScreenHandlerTransformer implements ClassNodeTransformer { @Override public void transform(String name, ClassNode node) { - var resolver = QuiltLoader.getMappingResolver(); + var resolver = FabricLoader.getInstance().getMappingResolver(); var namespace = "intermediary"; var LPlayerScreenHandler = L(slash(name)); @@ -23,7 +23,7 @@ public class PlayerScreenHandlerTransformer implements ClassNodeTransformer { var DefaultedList = slash(resolver.mapClassName(namespace, "net.minecraft.class_2371")); for (var mn : node.methods) { - // that other comment was a half truth, you can transform mixins :^) + // fix slot checking for trinkets quick move mixin if (mn.name.endsWith("trinkets$quickMove") || mn.name.equals(quickMove)) { for (var insn : mn.instructions) { if (insn instanceof VarInsnNode vin) { diff --git a/src/main/java/pm/c7/scout/mixin/ScreenHandlerTransformer.java b/src/main/java/pm/c7/scout/mixin/ScreenHandlerTransformer.java index 21a91fc..dd32140 100644 --- a/src/main/java/pm/c7/scout/mixin/ScreenHandlerTransformer.java +++ b/src/main/java/pm/c7/scout/mixin/ScreenHandlerTransformer.java @@ -1,8 +1,8 @@ package pm.c7.scout.mixin; import org.objectweb.asm.tree.*; -import org.quiltmc.loader.api.QuiltLoader; +import net.fabricmc.loader.api.FabricLoader; import pm.c7.scout.mixinsupport.ClassNodeTransformer; import static org.objectweb.asm.Opcodes.*; @@ -12,7 +12,7 @@ public class ScreenHandlerTransformer implements ClassNodeTransformer { @Override public void transform(String name, ClassNode node) { - var resolver = QuiltLoader.getMappingResolver(); + var resolver = FabricLoader.getInstance().getMappingResolver(); var namespace = "intermediary"; var internalOnSlotClick = resolver.mapMethodName(namespace, name, "method_30010", "(IILnet/minecraft/class_1713;Lnet/minecraft/class_1657;)V"); @@ -106,9 +106,10 @@ public class ScreenHandlerTransformer implements ClassNodeTransformer { } } } - } else if (mn.name.endsWith("debugify$handleCtrlQCrafting")) { // ughghghhghghghghgh + } else if (mn.name.startsWith("handler$")) { + // fix getting slots for mixins for (var insn : mn.instructions) { - if (insn instanceof VarInsnNode vin && vin.getOpcode() == ASTORE && vin.var == 6) { + if (insn instanceof VarInsnNode vin && vin.getOpcode() == ASTORE && (vin.var == 6 || vin.var == 7)) { if (vin.getPrevious() instanceof TypeInsnNode prevInsn && prevInsn.getOpcode() == CHECKCAST && prevInsn.desc.equals(Slot)) { if (prevInsn.getPrevious() instanceof MethodInsnNode prevPrevInsn && prevPrevInsn.getOpcode() == INVOKEVIRTUAL) { if(prevPrevInsn.owner.equals(DefaultedList)) { diff --git a/src/main/java/pm/c7/scout/mixin/ServerPlayerEntityMixin.java b/src/main/java/pm/c7/scout/mixin/ServerPlayerEntityMixin.java index 2ca4095..b114300 100644 --- a/src/main/java/pm/c7/scout/mixin/ServerPlayerEntityMixin.java +++ b/src/main/java/pm/c7/scout/mixin/ServerPlayerEntityMixin.java @@ -7,7 +7,7 @@ import net.minecraft.network.PacketByteBuf; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.util.collection.DefaultedList; import net.minecraft.world.GameRules; -import org.quiltmc.qsl.networking.api.ServerPlayNetworking; +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -39,13 +39,6 @@ public class ServerPlayerEntityMixin { slot.setInventory(null); slot.setEnabled(false); } - - PacketByteBuf packet = new PacketByteBuf(Unpooled.buffer()); - packet.writeBoolean(false); - packet.writeInt(0); - packet.writeItemStack(backStack); - - ServerPlayNetworking.send(player, ScoutNetworking.ENABLE_SLOTS, packet); } ItemStack leftPouchStack = ScoutUtil.findBagItem(player, BagType.POUCH, false); @@ -60,13 +53,6 @@ public class ServerPlayerEntityMixin { slot.setInventory(null); slot.setEnabled(false); } - - PacketByteBuf packet = new PacketByteBuf(Unpooled.buffer()); - packet.writeBoolean(false); - packet.writeInt(0); - packet.writeItemStack(leftPouchStack); - - ServerPlayNetworking.send(player, ScoutNetworking.ENABLE_SLOTS, packet); } ItemStack rightPouchStack = ScoutUtil.findBagItem(player, BagType.POUCH, true); @@ -81,14 +67,10 @@ public class ServerPlayerEntityMixin { slot.setInventory(null); slot.setEnabled(false); } - - PacketByteBuf packet = new PacketByteBuf(Unpooled.buffer()); - packet.writeBoolean(false); - packet.writeInt(1); - packet.writeItemStack(rightPouchStack); - - ServerPlayNetworking.send(player, ScoutNetworking.ENABLE_SLOTS, packet); } + + PacketByteBuf packet = new PacketByteBuf(Unpooled.buffer()); + ServerPlayNetworking.send(player, ScoutNetworking.ENABLE_SLOTS, packet); } } } diff --git a/src/main/java/pm/c7/scout/mixin/client/AbstractFurnaceScreenMixin.java b/src/main/java/pm/c7/scout/mixin/client/AbstractFurnaceScreenMixin.java index ef53144..67ce94b 100644 --- a/src/main/java/pm/c7/scout/mixin/client/AbstractFurnaceScreenMixin.java +++ b/src/main/java/pm/c7/scout/mixin/client/AbstractFurnaceScreenMixin.java @@ -4,7 +4,7 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.gui.screen.ingame.AbstractFurnaceScreen; import net.minecraft.client.gui.screen.ingame.HandledScreen; -import net.minecraft.client.gui.screen.recipe.book.RecipeBookProvider; +import net.minecraft.client.gui.screen.recipebook.RecipeBookProvider; import net.minecraft.item.ItemStack; import net.minecraft.screen.AbstractFurnaceScreenHandler; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/pm/c7/scout/mixin/client/CraftingScreenMixin.java b/src/main/java/pm/c7/scout/mixin/client/CraftingScreenMixin.java index af904c8..cb50ef8 100644 --- a/src/main/java/pm/c7/scout/mixin/client/CraftingScreenMixin.java +++ b/src/main/java/pm/c7/scout/mixin/client/CraftingScreenMixin.java @@ -4,11 +4,9 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.gui.screen.ingame.CraftingScreen; import net.minecraft.client.gui.screen.ingame.HandledScreen; -import net.minecraft.client.gui.screen.recipe.book.RecipeBookProvider; -import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.client.gui.screen.recipebook.RecipeBookProvider; import net.minecraft.item.ItemStack; import net.minecraft.screen.CraftingScreenHandler; -import net.minecraft.text.Text; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; diff --git a/src/main/java/pm/c7/scout/mixin/client/HandledScreenMixin.java b/src/main/java/pm/c7/scout/mixin/client/HandledScreenMixin.java index bf39ef6..8c8d438 100644 --- a/src/main/java/pm/c7/scout/mixin/client/HandledScreenMixin.java +++ b/src/main/java/pm/c7/scout/mixin/client/HandledScreenMixin.java @@ -3,7 +3,7 @@ package pm.c7.scout.mixin.client; import com.mojang.blaze3d.systems.RenderSystem; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.GenericContainerScreen; import net.minecraft.client.gui.screen.ingame.HandledScreen; @@ -44,8 +44,8 @@ public abstract class HandledScreenMixin extends Screen @Shadow protected int backgroundHeight; - @Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/ingame/HandledScreen;drawBackground(Lnet/minecraft/client/gui/GuiGraphics;FII)V")) - private void scout$drawSatchelRow(GuiGraphics graphics, int mouseX, int mouseY, float delta, CallbackInfo ci) { + @Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/ingame/HandledScreen;drawBackground(Lnet/minecraft/client/gui/DrawContext;FII)V")) + private void scout$drawSatchelRow(DrawContext graphics, int mouseX, int mouseY, float delta, CallbackInfo ci) { if (this.client != null && this.client.player != null && !ScoutUtil.isScreenBlacklisted(this)) { ItemStack backStack = ScoutUtil.findBagItem(this.client.player, BaseBagItem.BagType.SATCHEL, false); if (!backStack.isEmpty()) { @@ -96,7 +96,7 @@ public abstract class HandledScreenMixin extends Screen } @Inject(method = "render", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;disableDepthTest()V", remap = false)) - private void scout$drawPouchSlots(GuiGraphics graphics, int mouseX, int mouseY, float delta, CallbackInfo ci) { + private void scout$drawPouchSlots(DrawContext graphics, int mouseX, int mouseY, float delta, CallbackInfo ci) { if (this.client != null && this.client.player != null && !ScoutUtil.isScreenBlacklisted(this)) { ItemStack leftPouchStack = ScoutUtil.findBagItem(this.client.player, BaseBagItem.BagType.POUCH, false); if (!leftPouchStack.isEmpty()) { @@ -270,8 +270,8 @@ public abstract class HandledScreenMixin extends Screen } } - @Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/ingame/HandledScreen;drawForeground(Lnet/minecraft/client/gui/GuiGraphics;II)V")) - public void scout$drawOurSlots(GuiGraphics graphics, int mouseX, int mouseY, float delta, CallbackInfo ci) { + @Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/ingame/HandledScreen;drawForeground(Lnet/minecraft/client/gui/DrawContext;II)V")) + public void scout$drawOurSlots(DrawContext graphics, int mouseX, int mouseY, float delta, CallbackInfo ci) { if (this.client != null && this.client.player != null && !ScoutUtil.isScreenBlacklisted(this)) { for (int i = ScoutUtil.SATCHEL_SLOT_START; i > ScoutUtil.BAG_SLOTS_END; i--) { BagSlot slot = (BagSlot) ScoutUtil.getBagSlot(i, this.client.player.playerScreenHandler); @@ -309,9 +309,9 @@ public abstract class HandledScreenMixin extends Screen } @Shadow - private void drawSlot(GuiGraphics graphics, Slot slot) {} + private void drawSlot(DrawContext graphics, Slot slot) {} @Shadow - public static void drawSlotHighlight(GuiGraphics graphics, int x, int y, int z) {} + public static void drawSlotHighlight(DrawContext graphics, int x, int y, int z) {} @Shadow private boolean isPointOverSlot(Slot slot, double pointX, double pointY) { return false; diff --git a/src/main/java/pm/c7/scout/mixin/client/HandledScreenTransformer.java b/src/main/java/pm/c7/scout/mixin/client/HandledScreenTransformer.java index 37c203f..427086f 100644 --- a/src/main/java/pm/c7/scout/mixin/client/HandledScreenTransformer.java +++ b/src/main/java/pm/c7/scout/mixin/client/HandledScreenTransformer.java @@ -1,8 +1,8 @@ package pm.c7.scout.mixin.client; import org.objectweb.asm.tree.*; -import org.quiltmc.loader.api.QuiltLoader; +import net.fabricmc.loader.api.FabricLoader; import pm.c7.scout.mixinsupport.ClassNodeTransformer; import static org.objectweb.asm.Opcodes.*; @@ -10,7 +10,7 @@ import static org.objectweb.asm.Opcodes.*; public class HandledScreenTransformer implements ClassNodeTransformer { @Override public void transform(String name, ClassNode node) { - var resolver = QuiltLoader.getMappingResolver(); + var resolver = FabricLoader.getInstance().getMappingResolver(); var namespace = "intermediary"; var drawSlot = resolver.mapMethodName(namespace, name, "method_2385", "(Lnet/minecraft/class_332;Lnet/minecraft/class_1735;)V"); diff --git a/src/main/java/pm/c7/scout/mixin/client/InventoryScreenMixin.java b/src/main/java/pm/c7/scout/mixin/client/InventoryScreenMixin.java index ca70368..39ce87e 100644 --- a/src/main/java/pm/c7/scout/mixin/client/InventoryScreenMixin.java +++ b/src/main/java/pm/c7/scout/mixin/client/InventoryScreenMixin.java @@ -4,7 +4,7 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.gui.screen.ingame.AbstractInventoryScreen; import net.minecraft.client.gui.screen.ingame.InventoryScreen; -import net.minecraft.client.gui.screen.recipe.book.RecipeBookProvider; +import net.minecraft.client.gui.screen.recipebook.RecipeBookProvider; import net.minecraft.item.ItemStack; import net.minecraft.screen.PlayerScreenHandler; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/pm/c7/scout/mixin/client/RecipeBookWidgetMixin.java b/src/main/java/pm/c7/scout/mixin/client/RecipeBookWidgetMixin.java index a116322..590f1e9 100644 --- a/src/main/java/pm/c7/scout/mixin/client/RecipeBookWidgetMixin.java +++ b/src/main/java/pm/c7/scout/mixin/client/RecipeBookWidgetMixin.java @@ -3,7 +3,7 @@ package pm.c7.scout.mixin.client; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.recipe.book.RecipeBookWidget; +import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; import net.minecraft.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; diff --git a/src/main/java/pm/c7/scout/registry/ScoutItems.java b/src/main/java/pm/c7/scout/registry/ScoutItems.java index f0258bb..403327e 100644 --- a/src/main/java/pm/c7/scout/registry/ScoutItems.java +++ b/src/main/java/pm/c7/scout/registry/ScoutItems.java @@ -1,20 +1,20 @@ package pm.c7.scout.registry; +import net.fabricmc.fabric.api.item.v1.FabricItemSettings; import net.minecraft.item.Item; import net.minecraft.registry.Registries; import net.minecraft.util.Rarity; -import org.quiltmc.qsl.item.setting.api.QuiltItemSettings; import pm.c7.scout.Scout; import pm.c7.scout.ScoutUtil; import pm.c7.scout.item.BaseBagItem; public class ScoutItems { - public static final Item TANNED_LEATHER = new Item(new QuiltItemSettings()); - public static final Item SATCHEL_STRAP = new Item(new QuiltItemSettings()); - public static final BaseBagItem SATCHEL = new BaseBagItem(new QuiltItemSettings().maxCount(1), ScoutUtil.MAX_SATCHEL_SLOTS / 2, BaseBagItem.BagType.SATCHEL); - public static final BaseBagItem UPGRADED_SATCHEL = new BaseBagItem(new QuiltItemSettings().maxCount(1).rarity(Rarity.RARE), ScoutUtil.MAX_SATCHEL_SLOTS, BaseBagItem.BagType.SATCHEL); - public static final BaseBagItem POUCH = new BaseBagItem(new QuiltItemSettings().maxCount(1), ScoutUtil.MAX_POUCH_SLOTS / 2, BaseBagItem.BagType.POUCH); - public static final BaseBagItem UPGRADED_POUCH = new BaseBagItem(new QuiltItemSettings().maxCount(1).rarity(Rarity.RARE), ScoutUtil.MAX_POUCH_SLOTS, BaseBagItem.BagType.POUCH); + public static final Item TANNED_LEATHER = new Item(new FabricItemSettings()); + public static final Item SATCHEL_STRAP = new Item(new FabricItemSettings()); + public static final BaseBagItem SATCHEL = new BaseBagItem(new FabricItemSettings().maxCount(1), ScoutUtil.MAX_SATCHEL_SLOTS / 2, BaseBagItem.BagType.SATCHEL); + public static final BaseBagItem UPGRADED_SATCHEL = new BaseBagItem(new FabricItemSettings().maxCount(1).rarity(Rarity.RARE), ScoutUtil.MAX_SATCHEL_SLOTS, BaseBagItem.BagType.SATCHEL); + public static final BaseBagItem POUCH = new BaseBagItem(new FabricItemSettings().maxCount(1), ScoutUtil.MAX_POUCH_SLOTS / 2, BaseBagItem.BagType.POUCH); + public static final BaseBagItem UPGRADED_POUCH = new BaseBagItem(new FabricItemSettings().maxCount(1).rarity(Rarity.RARE), ScoutUtil.MAX_POUCH_SLOTS, BaseBagItem.BagType.POUCH); public static void init() { Scout.AUTOREGISTRY.autoRegister(Registries.ITEM, ScoutItems.class, Item.class); diff --git a/src/main/java/pm/c7/scout/screen/BagSlot.java b/src/main/java/pm/c7/scout/screen/BagSlot.java index 564e0b3..7858081 100644 --- a/src/main/java/pm/c7/scout/screen/BagSlot.java +++ b/src/main/java/pm/c7/scout/screen/BagSlot.java @@ -6,7 +6,7 @@ import net.minecraft.inventory.Inventory; import net.minecraft.item.BlockItem; import net.minecraft.item.ItemStack; import net.minecraft.screen.slot.Slot; -import pm.c7.scout.ScoutConfig; +import pm.c7.scout.config.ScoutConfig; import pm.c7.scout.item.BaseBagItem; public class BagSlot extends Slot { @@ -38,7 +38,7 @@ public class BagSlot extends Slot { if (stack.getItem() instanceof BlockItem blockItem) { if (blockItem.getBlock() instanceof ShulkerBoxBlock) - return enabled && inventory != null && ScoutConfig.CONFIG.allowShulkers.value(); + return enabled && inventory != null && ScoutConfig.allowShulkers; } return enabled && inventory != null; @@ -67,11 +67,6 @@ public class BagSlot extends Slot { } } - @Override - public void setStackByPlayer(ItemStack stack) { - this.setStack(stack); - } - @Override public void markDirty() { if (enabled && this.inventory != null) { diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json new file mode 100644 index 0000000..648b0d1 --- /dev/null +++ b/src/main/resources/fabric.mod.json @@ -0,0 +1,42 @@ +{ + "schemaVersion": 1, + "id": "scout", + "version": "${version}", + + "name": "Scout", + "description": "A mod focused on \"physically\" extending the inventory (adding slots) through wearing various types of bags.", + "authors": ["Cynosphere"], + "contact": { + "sources": "https://gitdab.com/Cynosphere-mc/Scout" + }, + + "license": "MIT", + "icon": "assets/scout/icon.png", + + "environment": "*", + "entrypoints": { + "main": ["pm.c7.scout.Scout"], + "client": ["pm.c7.scout.client.ScoutClient"], + "emi": ["pm.c7.scout.client.compat.ScoutEmiPlugin"] + }, + "mixins": ["scout.mixins.json"], + + "depends": { + "fabric": ">=${fabric_version}", + "minecraft": ">=${minecraft_version}", + "trinkets": ">=${trinkets_version}", + "lib39-core": ">=${lib39_version}", + "lib39-dessicant": ">=${lib39_version}" + }, + "recommends": { + "emi": ">=${emi_version}" + }, + "breaks": { + "infinitory": "*", + "biginv": "*", + "extrainv": "*", + "inventory_backpack": "*", + "realistic-inventory": "*", + "inventorymod": "*" + } +} diff --git a/src/main/resources/quilt.mod.json b/src/main/resources/quilt.mod.json deleted file mode 100644 index 5366166..0000000 --- a/src/main/resources/quilt.mod.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "schema_version": 1, - "quilt_loader": { - "group": "pm.c7.scout", - "id": "scout", - "version": "${version}", - "metadata": { - "name": "Scout", - "description": "A mod focused on \"physically\" extending the inventory (adding slots) through wearing various types of bags.", - "contributors": { - "Cynosphere": "Owner, Developer", - "Kat": "Original pouch texture", - "makamys": "Original idea" - }, - "contact": { - "sources": "https://gitdab.com/Cynosphere-mc/Scout" - }, - "icon": "assets/scout/icon.png" - }, - "intermediate_mappings": "net.fabricmc:intermediary", - "entrypoints": { - "init": "pm.c7.scout.Scout", - "client_init": "pm.c7.scout.client.ScoutClient", - "emi": "pm.c7.scout.client.compat.ScoutEmiPlugin" - }, - "depends": [ - { - "id": "quilt_loader", - "versions": ">=0.17.0-" - }, - { - "id": "quilted_fabric_api", - "versions": ">=4.0.0-" - }, - { - "id": "minecraft", - "versions": ">=${minecraft_version}" - }, - { - "id": "trinkets", - "versions": ">=${trinkets_version}" - }, - { - "id": "lib39-core", - "versions": ">=${lib39_version}" - }, - { - "id": "lib39-dessicant", - "versions": ">=${lib39_version}" - }, - { - "id": "emi", - "versions": ">=${emi_version}", - "optional": true - } - ], - "breaks": [ - { - "id": "infinitory", - "versions": "*", - "reason": "Infinite/Incompatible inventory mod." - }, - { - "id": "biginv", - "versions": "*", - "reason": "Infinite/Incompatible inventory mod." - }, - { - "id": "extrainv", - "versions": "*", - "reason": "Infinite/Incompatible inventory mod." - }, - { - "id": "inventory_backpack", - "versions": "*", - "reason": "Infinite/Incompatible inventory mod." - }, - { - "id": "realistic-inventory", - "versions": "*", - "reason": "Infinite/Incompatible inventory mod." - }, - { - "id": "inventorymod", - "versions": "*", - "reason": "Infinite/Incompatible inventory mod." - } - ] - }, - "mixin": "scout.mixins.json" -}