diff --git a/.gitignore b/.gitignore index 12f8644..bbdd0fb 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ build # other eclipse +runs run # Files from Forge MDK diff --git a/build.gradle b/build.gradle index ba66719..8be9abb 100644 --- a/build.gradle +++ b/build.gradle @@ -1,112 +1,19 @@ plugins { + id 'java-library' id 'idea' id 'maven-publish' id 'org.gradle.crypto.checksum' version '1.4.0' - id 'net.minecraftforge.gradle' version '[6.0,6.2)' + id 'net.neoforged.gradle.userdev' version '7.0.80' } // Mojang ships Java 17 to end users in 1.18+, so your mod should target Java 17. java.toolchain.languageVersion = JavaLanguageVersion.of(17) -println "Java: ${System.getProperty 'java.version'}, JVM: ${System.getProperty 'java.vm.version'} (${System.getProperty 'java.vendor'}), Arch: ${System.getProperty 'os.arch'}" -minecraft { - // The mappings can be changed at any time and must be in the following format. - // Channel: Version: - // official MCVersion Official field/method names from Mojang mapping files - // parchment YYYY.MM.DD-MCVersion Open community-sourced parameter names and javadocs layered on top of official - // - // You must be aware of the Mojang license when using the 'official' or 'parchment' mappings. - // See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md - // - // Parchment is an unofficial project maintained by ParchmentMC, separate from MinecraftForge - // Additional setup is needed to use their mappings: https://parchmentmc.org/docs/getting-started - // - // Use non-default mappings at your own risk. They may not always work. - // Simply re-run your setup task after changing the mappings to update your workspace. - mappings channel: mapping_channel, version: mapping_version - - // When true, this property will have all Eclipse/IntelliJ IDEA run configurations run the "prepareX" task for the given run configuration before launching the game. - // In most cases, it is not necessary to enable. - // enableEclipsePrepareRuns = true - // enableIdeaPrepareRuns = true - - // This property allows configuring Gradle's ProcessResources task(s) to run on IDE output locations before launching the game. - // It is REQUIRED to be set to true for this template to function. - // See https://docs.gradle.org/current/dsl/org.gradle.language.jvm.tasks.ProcessResources.html - copyIdeResources = true - - // When true, this property will add the folder name of all declared run configurations to generated IDE run configurations. - // The folder name can be set on a run configuration using the "folderName" property. - // By default, the folder name of a run configuration is the name of the Gradle project containing it. - // generateRunFolders = true - - // This property enables access transformers for use in development. - // They will be applied to the Minecraft artifact. - // The access transformer file can be anywhere in the project. - // However, it must be at "META-INF/accesstransformer.cfg" in the final mod jar to be loaded by Forge. - // This default location is a best practice to automatically put the file in the right place in the final jar. - // See https://docs.minecraftforge.net/en/latest/advanced/accesstransformers/ for more information. - accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') - - // Default run configurations. - // These can be tweaked, removed, or duplicated as needed. - runs { - // applies to all the run configs below - configureEach { - workingDirectory project.file('run') - - // Recommended logging data for a userdev environment - // The markers can be added/remove as needed separated by commas. - // "SCAN": For mods scan. - // "REGISTRIES": For firing of registry events. - // "REGISTRYDUMP": For getting the contents of all registries. - property 'forge.logging.markers', 'REGISTRIES' - - // Recommended logging level for the console - // You can set various levels here. - // Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels - property 'forge.logging.console.level', 'debug' - - mods { - "${mod_id}" { - source sourceSets.main - } - } - } - - client { - // Comma-separated list of namespaces to load gametests from. Empty = all namespaces. - property 'forge.enabledGameTestNamespaces', mod_id - } - - server { - property 'forge.enabledGameTestNamespaces', mod_id - args '--nogui' - } - - // This run config launches GameTestServer and runs all registered gametests, then exits. - // By default, the server will crash when no gametests are provided. - // The gametest system is also enabled by default for other run configs under the /test command. - gameTestServer { - property 'forge.enabledGameTestNamespaces', mod_id - } - - data { - // example of overriding the workingDirectory set in configureEach above - workingDirectory project.file('run-data') - - // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources. - args '--mod', mod_id, '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/') - } - } -} - -// Include resources generated by data generators. -sourceSets.main.resources { srcDir 'src/generated/resources' } +minecraft.accessTransformers.file rootProject.file('src/main/resources/META-INF/accesstransformer.cfg') repositories { + mavenLocal() exclusiveContent { - forRepositories(fg.repository) forRepository { maven { name "CurseMaven" @@ -119,10 +26,60 @@ repositories { } } +// Default run configurations. +// These can be tweaked, removed, or duplicated as needed. +runs { + // applies to all the run configs below + configureEach { + // Recommended logging data for a userdev environment + // The markers can be added/remove as needed separated by commas. + // "SCAN": For mods scan. + // "REGISTRIES": For firing of registry events. + // "REGISTRYDUMP": For getting the contents of all registries. + systemProperty 'forge.logging.markers', 'REGISTRIES' + + // Recommended logging level for the console + // You can set various levels here. + // Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels + systemProperty 'forge.logging.console.level', 'debug' + + modSource project.sourceSets.main + } + + client { + // Comma-separated list of namespaces to load gametests from. Empty = all namespaces. + systemProperty 'forge.enabledGameTestNamespaces', project.mod_id + } + + server { + systemProperty 'forge.enabledGameTestNamespaces', project.mod_id + programArgument '--nogui' + } + + // This run config launches GameTestServer and runs all registered gametests, then exits. + // By default, the server will crash when no gametests are provided. + // The gametest system is also enabled by default for other run configs under the /test command. + gameTestServer { + systemProperty 'forge.enabledGameTestNamespaces', project.mod_id + } + + data { + // example of overriding the workingDirectory set in configureEach above, uncomment if you want to use it + // workingDirectory project.file('run-data') + + // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources. + programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath() + } +} + + +// Include resources generated by data generators. +sourceSets.main.resources { srcDir 'src/generated/resources' } + dependencies { - minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" + implementation "net.neoforged:neoforge:${neo_version}" - implementation fg.deobf("curse.maven:jei-238222:4712868") + implementation "curse.maven:jei-238222:5101381" } // Example for how to get properties into the manifest for reading at runtime. @@ -142,10 +99,6 @@ tasks.named('jar', Jar).configure { // More information at https://docs.gradle.org/current/userguide/working_with_files.html#sec:reproducible_archives preserveFileTimestamps = false reproducibleFileOrder = true - - // Example configuration to allow publishing using the maven-publish plugin - // This is the preferred method to reobfuscate your jar file - finalizedBy('reobfJar') } // generate checksum for output jar @@ -163,12 +116,12 @@ build.finalizedBy('createChecksums') publishing { publications { register('mavenJava', MavenPublication) { - artifact jar + from components.java } } repositories { maven { - url "file://${project.projectDir}/mcmodsrepo" + url "file://${project.projectDir}/repo" } } } diff --git a/gradle.properties b/gradle.properties index 87ccba7..03f2c5b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,10 +3,13 @@ org.gradle.jvmargs=-Xmx3G org.gradle.daemon=false -minecraft_version=1.20.1 -forge_version=47.1.0 +neogradle.subsystems.parchment.minecraftVersion=1.20.3 +neogradle.subsystems.parchment.mappingsVersion=2023.12.31 + +minecraft_version=1.20.4 +neo_version=20.4.80-beta mapping_channel=official -mapping_version=1.20.1 +mapping_version=1.20.4 group=invtweaks mod_id=invtweaks diff --git a/settings.gradle b/settings.gradle index 35b7391..9fc885c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,10 +1,8 @@ pluginManagement { repositories { + mavenLocal() gradlePluginPortal() - maven { - name = 'MinecraftForge' - url = 'https://maven.minecraftforge.net/' - } + maven { url = 'https://maven.neoforged.net/releases' } } } diff --git a/src/main/java/invtweaks/InvTweaksMod.java b/src/main/java/invtweaks/InvTweaksMod.java index ebdf68f..be75119 100644 --- a/src/main/java/invtweaks/InvTweaksMod.java +++ b/src/main/java/invtweaks/InvTweaksMod.java @@ -2,10 +2,10 @@ import invtweaks.config.InvTweaksConfig; import invtweaks.network.NetworkDispatcher; -import net.minecraftforge.fml.ModLoadingContext; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.config.ModConfig; -import net.minecraftforge.fml.loading.FMLPaths; +import net.neoforged.fml.ModLoadingContext; +import net.neoforged.fml.common.Mod; +import net.neoforged.fml.config.ModConfig; +import net.neoforged.fml.loading.FMLPaths; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -17,8 +17,6 @@ public class InvTweaksMod { @SuppressWarnings("java:S1118") public InvTweaksMod() { - NetworkDispatcher.register(); - ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, InvTweaksConfig.CLIENT_CONFIG); InvTweaksConfig.loadConfig(InvTweaksConfig.CLIENT_CONFIG, FMLPaths.CONFIGDIR.get().resolve("invtweaks-client.toml")); diff --git a/src/main/java/invtweaks/config/InvTweaksConfig.java b/src/main/java/invtweaks/config/InvTweaksConfig.java index 37a4dba..0349820 100644 --- a/src/main/java/invtweaks/config/InvTweaksConfig.java +++ b/src/main/java/invtweaks/config/InvTweaksConfig.java @@ -12,7 +12,7 @@ import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.ints.IntLists; import net.minecraft.ResourceLocationException; -import net.minecraft.client.Minecraft; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; import net.minecraft.util.thread.BlockableEventLoop; @@ -22,15 +22,13 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.block.Block; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.common.ForgeConfigSpec; -import net.minecraftforge.common.util.LogicalSidedProvider; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.DistExecutor; -import net.minecraftforge.fml.LogicalSide; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.event.config.ModConfigEvent; -import net.minecraftforge.registries.ForgeRegistries; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.LogicalSide; +import net.neoforged.fml.common.Mod; +import net.neoforged.fml.event.config.ModConfigEvent; +import net.neoforged.fml.loading.FMLEnvironment; +import net.neoforged.neoforge.common.ModConfigSpec; +import net.neoforged.neoforge.common.util.LogicalSidedProvider; import javax.annotation.Nullable; import java.nio.file.Path; @@ -52,7 +50,7 @@ @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD) public class InvTweaksConfig { - public static final ForgeConfigSpec CLIENT_CONFIG; + public static final ModConfigSpec CLIENT_CONFIG; /** * Sentinel to indicate that the GUI position should be left alone. */ @@ -70,13 +68,13 @@ public class InvTweaksConfig { new Category( String.format( "/instanceof:net.minecraft.item.Food; !%s; !%s; !%s; !%s", - ForgeRegistries.ITEMS.getKey(Items.ROTTEN_FLESH), - ForgeRegistries.ITEMS.getKey(Items.SPIDER_EYE), - ForgeRegistries.ITEMS.getKey(Items.POISONOUS_POTATO), - ForgeRegistries.ITEMS.getKey(Items.PUFFERFISH)))) + BuiltInRegistries.ITEM.getKey(Items.ROTTEN_FLESH), + BuiltInRegistries.ITEM.getKey(Items.SPIDER_EYE), + BuiltInRegistries.ITEM.getKey(Items.POISONOUS_POTATO), + BuiltInRegistries.ITEM.getKey(Items.PUFFERFISH)))) .put( "torch", - new Category(ForgeRegistries.ITEMS.getKey(Items.TORCH).toString())) + new Category(BuiltInRegistries.ITEM.getKey(Items.TORCH).toString())) .put("cheapBlocks", new Category("/tag:minecraft:cobblestone", "/tag:minecraft:dirt")) .put("blocks", new Category("/instanceof:net.minecraft.item.BlockItem")) .build(); @@ -95,13 +93,13 @@ public class InvTweaksConfig { .build(); - private static final ForgeConfigSpec.ConfigValue> CATS; - private static final ForgeConfigSpec.ConfigValue> RULES; - private static final ForgeConfigSpec.BooleanValue ENABLE_AUTOREFILL; - private static final ForgeConfigSpec.BooleanValue ENABLE_QUICKVIEW; - private static final ForgeConfigSpec.IntValue ENABLE_SORT; - private static final ForgeConfigSpec.IntValue ENABLE_BUTTONS; - private static final ForgeConfigSpec.ConfigValue> + private static final ModConfigSpec.ConfigValue> CATS; + private static final ModConfigSpec.ConfigValue> RULES; + private static final ModConfigSpec.BooleanValue ENABLE_AUTOREFILL; + private static final ModConfigSpec.BooleanValue ENABLE_QUICKVIEW; + private static final ModConfigSpec.IntValue ENABLE_SORT; + private static final ModConfigSpec.IntValue ENABLE_BUTTONS; + private static final ModConfigSpec.ConfigValue> CONT_OVERRIDES; private static final Map> playerToCats = new HashMap<>(); private static final Map playerToRules = new HashMap<>(); @@ -113,7 +111,7 @@ public class InvTweaksConfig { private static boolean isDirty = false; static { - ForgeConfigSpec.Builder builder = new ForgeConfigSpec.Builder(); + ModConfigSpec.Builder builder = new ModConfigSpec.Builder(); { builder.comment("Sorting customization").push("sorting"); @@ -266,7 +264,7 @@ public static Map getSelfCompiledContOverrides() { return COMPILED_CONT_OVERRIDES; } - public static void loadConfig(ForgeConfigSpec spec, Path path) { + public static void loadConfig(ModConfigSpec spec, Path path) { final CommentedFileConfig configData = CommentedFileConfig.builder(path) .sync() @@ -299,32 +297,28 @@ public static void setPlayerContOverrides(Player ent, Map } public static Map getPlayerCats(Player ent) { - if (DistExecutor.unsafeCallWhenOn(Dist.CLIENT, () -> () -> ent == Minecraft.getInstance().player) - == Boolean.TRUE) { + if (FMLEnvironment.dist.isClient()) { return getSelfCompiledCats(); } return playerToCats.getOrDefault(ent.getUUID(), DEFAULT_CATS); } public static Ruleset getPlayerRules(Player ent) { - if (DistExecutor.unsafeCallWhenOn(Dist.CLIENT, () -> () -> ent == Minecraft.getInstance().player) - == Boolean.TRUE) { + if (FMLEnvironment.dist.isClient()) { return getSelfCompiledRules(); } return playerToRules.getOrDefault(ent.getUUID(), DEFAULT_RULES); } public static boolean getPlayerAutoRefill(Player ent) { - if (DistExecutor.unsafeCallWhenOn(Dist.CLIENT, () -> () -> ent == Minecraft.getInstance().player) - == Boolean.TRUE) { + if (FMLEnvironment.dist.isClient()) { return ENABLE_AUTOREFILL.get(); } return playerAutoRefill.contains(ent.getUUID()); } public static Map getPlayerContOverrides(Player ent) { - if (DistExecutor.unsafeCallWhenOn(Dist.CLIENT, () -> () -> ent == Minecraft.getInstance().player) - == Boolean.TRUE) { + if (FMLEnvironment.dist.isClient()) { return getSelfCompiledContOverrides(); } return playerToContOverrides.getOrDefault(ent.getUUID(), DEFAULT_CONT_OVERRIDES); @@ -397,8 +391,8 @@ private static Optional> compileClause(String clause) { String[] parts = clause.split(":", 2); if (parts[0].equals("/tag")) { - TagKey itemKey = TagKey.create(ForgeRegistries.ITEMS.getRegistryKey(), new ResourceLocation(parts[1])); - TagKey blockKey = TagKey.create(ForgeRegistries.BLOCKS.getRegistryKey(), new ResourceLocation(parts[1])); + TagKey itemKey = TagKey.create(BuiltInRegistries.ITEM.key(), new ResourceLocation(parts[1])); + TagKey blockKey = TagKey.create(BuiltInRegistries.BLOCK.key(), new ResourceLocation(parts[1])); return Optional.of(stack -> stack.is(itemKey) || ( stack.getItem() instanceof BlockItem blockItem @@ -420,7 +414,7 @@ private static Optional> compileClause(String clause) { } else { // default to standard item checking try { return Optional.of( - st -> Objects.equals(ForgeRegistries.ITEMS.getKey(st.getItem()), new ResourceLocation(clause))); + st -> Objects.equals(BuiltInRegistries.ITEM.getKey(st.getItem()), new ResourceLocation(clause))); } catch (ResourceLocationException e) { InvTweaksMod.LOGGER.warn("Invalid item resource location found."); return Optional.empty(); diff --git a/src/main/java/invtweaks/events/ClientEvents.java b/src/main/java/invtweaks/events/ClientEvents.java index e8c80bc..bbc423d 100644 --- a/src/main/java/invtweaks/events/ClientEvents.java +++ b/src/main/java/invtweaks/events/ClientEvents.java @@ -6,7 +6,6 @@ import invtweaks.InvTweaksMod; import invtweaks.config.InvTweaksConfig; import invtweaks.gui.InvTweaksButtonSort; -import invtweaks.network.NetworkDispatcher; import invtweaks.network.PacketSortInv; import invtweaks.util.ClientUtils; import invtweaks.util.Sorting; @@ -24,13 +23,14 @@ import net.minecraft.world.inventory.CraftingContainer; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.client.event.RenderGuiOverlayEvent; -import net.minecraftforge.client.event.ScreenEvent; -import net.minecraftforge.client.gui.overlay.VanillaGuiOverlay; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.items.ItemHandlerHelper; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.Mod; +import net.neoforged.neoforge.client.event.RenderGuiOverlayEvent; +import net.neoforged.neoforge.client.event.ScreenEvent; +import net.neoforged.neoforge.client.gui.overlay.VanillaGuiOverlay; +import net.neoforged.neoforge.items.ItemHandlerHelper; +import net.neoforged.neoforge.network.PacketDistributor; import javax.annotation.Nullable; import java.util.Collection; @@ -53,7 +53,7 @@ private ClientEvents() { private static void requestSort(boolean isPlayer) { if (ClientUtils.serverConnectionExists()) { - NetworkDispatcher.INSTANCE.sendToServer(new PacketSortInv(isPlayer)); + PacketDistributor.SERVER.noArg().send(new PacketSortInv(isPlayer)); } else { Sorting.executeSort(ClientUtils.safeGetPlayer(), isPlayer); } diff --git a/src/main/java/invtweaks/events/KeyMappings.java b/src/main/java/invtweaks/events/KeyMappings.java index e73e601..ecbbcc4 100644 --- a/src/main/java/invtweaks/events/KeyMappings.java +++ b/src/main/java/invtweaks/events/KeyMappings.java @@ -3,11 +3,11 @@ import com.mojang.blaze3d.platform.InputConstants; import invtweaks.InvTweaksMod; import net.minecraft.client.KeyMapping; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.client.event.RegisterKeyMappingsEvent; -import net.minecraftforge.client.settings.KeyConflictContext; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.Mod; +import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent; +import net.neoforged.neoforge.client.settings.KeyConflictContext; import org.lwjgl.glfw.GLFW; @Mod.EventBusSubscriber(modid = InvTweaksMod.MODID, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD) diff --git a/src/main/java/invtweaks/events/ServerEvents.java b/src/main/java/invtweaks/events/ServerEvents.java index 5884bc2..bf45a56 100644 --- a/src/main/java/invtweaks/events/ServerEvents.java +++ b/src/main/java/invtweaks/events/ServerEvents.java @@ -2,25 +2,25 @@ import invtweaks.InvTweaksMod; import invtweaks.config.InvTweaksConfig; -import invtweaks.network.NetworkDispatcher; import invtweaks.util.ClientUtils; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; -import net.minecraft.core.Direction; import net.minecraft.server.level.ServerPlayer; import net.minecraft.stats.Stats; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; -import net.minecraftforge.common.capabilities.ForgeCapabilities; -import net.minecraftforge.event.TickEvent; -import net.minecraftforge.event.entity.EntityJoinLevelEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.LogicalSide; -import net.minecraftforge.fml.common.Mod; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.LogicalSide; +import net.neoforged.fml.common.Mod; +import net.neoforged.neoforge.capabilities.Capabilities; +import net.neoforged.neoforge.event.TickEvent; +import net.neoforged.neoforge.event.entity.EntityJoinLevelEvent; +import net.neoforged.neoforge.items.IItemHandler; +import net.neoforged.neoforge.network.PacketDistributor; import java.util.Collections; import java.util.EnumMap; @@ -72,7 +72,7 @@ public static void onPlayerTick(TickEvent.PlayerTickEvent event) { } } else { if (InvTweaksConfig.isDirty()) { - if (ClientUtils.serverConnectionExists()) NetworkDispatcher.INSTANCE.sendToServer(InvTweaksConfig.getSyncPacket()); + if (ClientUtils.serverConnectionExists()) PacketDistributor.SERVER.noArg().send(InvTweaksConfig.getSyncPacket()); InvTweaksConfig.setDirty(false); } } @@ -99,20 +99,19 @@ private static void searchForSubstitute(Player ent, InteractionHand hand, Item i } // thank Simon for the flattening - ent.getCapability(ForgeCapabilities.ITEM_HANDLER, Direction.UP) - .ifPresent( - cap -> { - for (int i = 0; i < cap.getSlots(); ++i) { - if (Collections.binarySearch(frozen, i) >= 0) { - continue; // ignore frozen slot - } - ItemStack cand = cap.extractItem(i, Integer.MAX_VALUE, true).copy(); - if (cand.getItem() == item) { - cap.extractItem(i, Integer.MAX_VALUE, false); - ent.setItemInHand(hand, cand); - break; - } - } - }); + IItemHandler cap = ent.getCapability(Capabilities.ItemHandler.ENTITY); + if (cap != null) { + for (int i = 0; i < cap.getSlots(); ++i) { + if (Collections.binarySearch(frozen, i) >= 0) { + continue; // ignore frozen slot + } + ItemStack cand = cap.extractItem(i, Integer.MAX_VALUE, true).copy(); + if (cand.getItem() == item) { + cap.extractItem(i, Integer.MAX_VALUE, false); + ent.setItemInHand(hand, cand); + break; + } + } + } } } diff --git a/src/main/java/invtweaks/gui/InvTweaksButton.java b/src/main/java/invtweaks/gui/InvTweaksButton.java index 566c81e..5521a91 100644 --- a/src/main/java/invtweaks/gui/InvTweaksButton.java +++ b/src/main/java/invtweaks/gui/InvTweaksButton.java @@ -4,7 +4,8 @@ import net.minecraft.client.gui.GuiGraphics; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; -import net.minecraftforge.client.gui.widget.ExtendedButton; +import net.neoforged.neoforge.client.gui.widget.ExtendedButton; + public class InvTweaksButton extends ExtendedButton { protected static final ResourceLocation button = @@ -19,7 +20,7 @@ public InvTweaksButton(int x, int y, int tx, int ty, OnPress handler) { } @Override - public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { + public void renderWidget(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { isHovered = this.active && this.visible && mouseX >= this.getX() diff --git a/src/main/java/invtweaks/network/NetworkDispatcher.java b/src/main/java/invtweaks/network/NetworkDispatcher.java index 1686baf..9ec76c1 100644 --- a/src/main/java/invtweaks/network/NetworkDispatcher.java +++ b/src/main/java/invtweaks/network/NetworkDispatcher.java @@ -1,24 +1,22 @@ package invtweaks.network; import invtweaks.InvTweaksMod; -import net.minecraft.resources.ResourceLocation; -import net.minecraftforge.network.NetworkRegistry; -import net.minecraftforge.network.simple.SimpleChannel; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.Mod; +import net.neoforged.neoforge.network.event.RegisterPayloadHandlerEvent; +import net.neoforged.neoforge.network.registration.IPayloadRegistrar; +@Mod.EventBusSubscriber(modid = InvTweaksMod.MODID, bus = Mod.EventBusSubscriber.Bus.MOD) public class NetworkDispatcher { private NetworkDispatcher() { // nothing to do } - private static final String PROTOCOL_VERSION = "1"; + @SubscribeEvent + public static void register(final RegisterPayloadHandlerEvent event) { + final IPayloadRegistrar registrar = event.registrar(InvTweaksMod.MODID).optional(); - public static final SimpleChannel INSTANCE = NetworkRegistry.newSimpleChannel(new ResourceLocation(InvTweaksMod.MODID, "main"), - () -> PROTOCOL_VERSION, NetworkRegistry.acceptMissingOr(PROTOCOL_VERSION), NetworkRegistry.acceptMissingOr(PROTOCOL_VERSION)); - - public static void register() { - int packetIndex = 0; - INSTANCE.registerMessage(packetIndex++, PacketSortInv.class, PacketSortInv::encode, PacketSortInv::new, PacketSortInv::handle); - INSTANCE.registerMessage(packetIndex++, PacketUpdateConfig.class, PacketUpdateConfig::encode, PacketUpdateConfig::new, PacketUpdateConfig::handle); - InvTweaksMod.LOGGER.info("Registered {} network packets", packetIndex); + registrar.play(PacketSortInv.ID, PacketSortInv::new, handler -> handler.server(PacketSortInv::handle)); + registrar.play(PacketUpdateConfig.ID, PacketUpdateConfig::new, handler -> handler.server(PacketUpdateConfig::handle)); } } diff --git a/src/main/java/invtweaks/network/PacketSortInv.java b/src/main/java/invtweaks/network/PacketSortInv.java index b65614d..e255ce4 100644 --- a/src/main/java/invtweaks/network/PacketSortInv.java +++ b/src/main/java/invtweaks/network/PacketSortInv.java @@ -3,35 +3,33 @@ import invtweaks.InvTweaksMod; import invtweaks.util.Sorting; import net.minecraft.network.FriendlyByteBuf; -import net.minecraftforge.network.NetworkEvent; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; +import net.neoforged.neoforge.network.handling.PlayPayloadContext; +public record PacketSortInv(boolean isPlayer) implements CustomPacketPayload { + public static final ResourceLocation ID = new ResourceLocation(InvTweaksMod.MODID, "packet_sort_inv"); -import java.util.function.Supplier; - -public class PacketSortInv { - private final boolean isPlayer; - - public PacketSortInv(boolean isPlayer) { - this.isPlayer = isPlayer; - } - - public PacketSortInv(FriendlyByteBuf buf) { + public PacketSortInv(final FriendlyByteBuf buf) { this(buf.readBoolean()); } - public void handle(Supplier ctx) { - ctx.get().enqueueWork(() -> { - try { - Sorting.executeSort(ctx.get().getSender(), isPlayer); - } catch (Exception e) { - // can potentially throw exceptions which are silenced by enqueueWork - InvTweaksMod.LOGGER.error("Failed to sort inventory", e); - } - }); - ctx.get().setPacketHandled(true); + public static void handle(final PacketSortInv packet, final PlayPayloadContext ctx) { + ctx.workHandler() + .submitAsync(() -> ctx.player().ifPresent(p -> Sorting.executeSort(p, packet.isPlayer))) + .exceptionally(e -> { + InvTweaksMod.LOGGER.error("Failed to sort inventory", e); + return null; + }); } - public void encode(FriendlyByteBuf buf) { + @Override + public void write(final FriendlyByteBuf buf) { buf.writeBoolean(isPlayer); } + + @Override + public ResourceLocation id() { + return ID; + } } diff --git a/src/main/java/invtweaks/network/PacketUpdateConfig.java b/src/main/java/invtweaks/network/PacketUpdateConfig.java index 484610a..8a730a1 100644 --- a/src/main/java/invtweaks/network/PacketUpdateConfig.java +++ b/src/main/java/invtweaks/network/PacketUpdateConfig.java @@ -2,17 +2,19 @@ import com.electronwill.nightconfig.core.CommentedConfig; import com.electronwill.nightconfig.core.UnmodifiableConfig; +import invtweaks.InvTweaksMod; import invtweaks.config.InvTweaksConfig; import net.minecraft.network.FriendlyByteBuf; -import net.minecraftforge.network.NetworkEvent; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; +import net.neoforged.neoforge.network.handling.PlayPayloadContext; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Objects; -import java.util.function.Supplier; -public class PacketUpdateConfig { +public class PacketUpdateConfig implements CustomPacketPayload { + public static final ResourceLocation ID = new ResourceLocation(InvTweaksMod.MODID, "packet_update_config"); private final List cats; private final List rules; private final List contOverrides; @@ -66,26 +68,17 @@ public PacketUpdateConfig(FriendlyByteBuf buf) { this.autoRefill = buf.readBoolean(); } - public void handle(Supplier ctx) { - ctx.get() - .enqueueWork( - () -> { - InvTweaksConfig.setPlayerCats( - Objects.requireNonNull(ctx.get().getSender()), - InvTweaksConfig.cfgToCompiledCats(cats)); - InvTweaksConfig.setPlayerRules( - Objects.requireNonNull(ctx.get().getSender()), - new InvTweaksConfig.Ruleset(rules)); - InvTweaksConfig.setPlayerAutoRefill(ctx.get().getSender(), autoRefill); - InvTweaksConfig.setPlayerContOverrides( - Objects.requireNonNull(ctx.get().getSender()), - InvTweaksConfig.cfgToCompiledContOverrides(contOverrides)); - // InvTweaksMod.LOGGER.info("Received config from client!"); - }); - ctx.get().setPacketHandled(true); + public static void handle(PacketUpdateConfig packet, PlayPayloadContext ctx) { + ctx.workHandler().submitAsync(() -> ctx.player().ifPresent(p -> { + InvTweaksConfig.setPlayerCats(p, InvTweaksConfig.cfgToCompiledCats(packet.cats)); + InvTweaksConfig.setPlayerRules(p, new InvTweaksConfig.Ruleset(packet.rules)); + InvTweaksConfig.setPlayerAutoRefill(p, packet.autoRefill); + InvTweaksConfig.setPlayerContOverrides(p, InvTweaksConfig.cfgToCompiledContOverrides(packet.contOverrides)); + })); } - public void encode(FriendlyByteBuf buf) { + @Override + public void write(final FriendlyByteBuf buf) { buf.writeVarInt(cats.size()); for (UnmodifiableConfig subCfg : cats) { buf.writeUtf(subCfg.getOrElse("name", "")); @@ -109,4 +102,9 @@ public void encode(FriendlyByteBuf buf) { } buf.writeBoolean(autoRefill); } + + @Override + public ResourceLocation id() { + return ID; + } } diff --git a/src/main/java/invtweaks/util/ClientUtils.java b/src/main/java/invtweaks/util/ClientUtils.java index 7c57aad..a2e5a57 100644 --- a/src/main/java/invtweaks/util/ClientUtils.java +++ b/src/main/java/invtweaks/util/ClientUtils.java @@ -1,6 +1,7 @@ package invtweaks.util; import invtweaks.network.NetworkDispatcher; +import invtweaks.network.PacketSortInv; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; import net.minecraft.network.Connection; @@ -17,6 +18,6 @@ public static Player safeGetPlayer() { public static boolean serverConnectionExists() { LocalPlayer player = Minecraft.getInstance().player; - return player != null && NetworkDispatcher.INSTANCE.isRemotePresent(player.connection.getConnection()); + return player != null && player.connection.isConnected(PacketSortInv.ID); } } diff --git a/src/main/java/invtweaks/util/Sorting.java b/src/main/java/invtweaks/util/Sorting.java index f734e86..6ef1fa9 100644 --- a/src/main/java/invtweaks/util/Sorting.java +++ b/src/main/java/invtweaks/util/Sorting.java @@ -5,22 +5,35 @@ import com.google.common.collect.HashBiMap; import com.google.common.collect.Streams; import invtweaks.config.InvTweaksConfig; -import it.unimi.dsi.fastutil.ints.*; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; +import it.unimi.dsi.fastutil.ints.IntLists; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.MultiPlayerGameMode; import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Inventory; -import net.minecraft.world.inventory.ClickType; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.ClickType; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; -import net.minecraftforge.items.ItemHandlerHelper; +import net.neoforged.neoforge.items.ItemHandlerHelper; import org.apache.commons.lang3.tuple.Pair; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.PrimitiveIterator; +import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.IntStream; diff --git a/src/main/java/invtweaks/util/Utils.java b/src/main/java/invtweaks/util/Utils.java index fb9418f..39924e7 100644 --- a/src/main/java/invtweaks/util/Utils.java +++ b/src/main/java/invtweaks/util/Utils.java @@ -4,11 +4,12 @@ import com.google.common.collect.Streams; import it.unimi.dsi.fastutil.ints.IntArrays; import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; -import net.minecraftforge.items.ItemHandlerHelper; -import net.minecraftforge.items.ItemStackHandler; -import net.minecraftforge.registries.ForgeRegistries; +import net.neoforged.neoforge.items.ItemHandlerHelper; +import net.neoforged.neoforge.items.ItemStackHandler; + import javax.annotation.ParametersAreNonnullByDefault; import java.util.*; @@ -45,7 +46,7 @@ protected int doHash(ItemStack t) { }; // TODO improve fallback comparator public static final Comparator FALLBACK_COMPARATOR = - Comparator.comparing(is -> ForgeRegistries.ITEMS.getKey(is.getItem())); + Comparator.comparing(is -> BuiltInRegistries.ITEM.getKey(is.getItem())); public static int gridToPlayerSlot(int row, int col) { if (row < 0 || row >= 4 || col < 0 || col >= 9) { diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index ba73b13..2d092e0 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -1 +1 @@ -public net.minecraft.client.gui.Gui m_280585_(Lnet/minecraft/client/gui/GuiGraphics;IIFLnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/item/ItemStack;I)V # renderSlot \ No newline at end of file +public net.minecraft.client.gui.Gui renderSlot(Lnet/minecraft/client/gui/GuiGraphics;IIFLnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/item/ItemStack;I)V # renderSlot \ No newline at end of file diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 381dcc4..257d5c4 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -7,7 +7,7 @@ license="Apache License, Version 2.0" modLoader="javafml" #mandatory # A version range to match for said mod loader - for regular FML @Mod it will be the forge version -loaderVersion="[47,)" +loaderVersion="[2,)" # A URL to refer people to when problems occur with this mod # issueTrackerURL="https://github.com/Landmaster/InvTweaksReborn/issues" # A list of mods - how many allowed here is determined by the individual mod loader @@ -43,11 +43,11 @@ Inventory Tweaks, but for modern versions of Minecraft. # A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional. [[dependencies.invtweaks]] #optional # the modid of the dependency - modId="forge" #mandatory + modId="neoforge" #mandatory # Does this dependency have to exist - if not, ordering below must be specified - mandatory=true #mandatory + type="required" #mandatory # The version range of the dependency - versionRange="[47,)" #mandatory + versionRange="[20.4.80-beta,)" #mandatory # An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory ordering="NONE" # Side this dependency is applied on - BOTH, CLIENT or SERVER @@ -55,13 +55,13 @@ Inventory Tweaks, but for modern versions of Minecraft. # Here's another dependency [[dependencies.invtweaks]] modId="minecraft" - mandatory=true - versionRange="[1.20.1,)" + type="required" + versionRange="[1.20.4]" ordering="NONE" side="BOTH" [[dependencies.invtweaks]] modId="jei" - mandatory=false - versionRange="[jei-1.20.1-forge-15.2.0.27,)" + type="optional" + versionRange="[jei-1.20.4-neoforge-17.3.0.49,)" ordering="AFTER" side="BOTH"