diff --git a/.gitignore b/.gitignore index 71196bf..ec515fb 100644 --- a/.gitignore +++ b/.gitignore @@ -12,15 +12,25 @@ out *.iws *.iml .idea +.vscode/ # gradle -build -.gradle +/build/ +/.gradle/ # other eclipse -run +/run/ +/runs/ +/logs/ logs/ +*.hprof +hs_err_pid* +replay_pid* +.DS_Store # Files from Forge MDK forge*changelog.txt + +# local publishing output +/repo/ diff --git a/build.gradle b/build.gradle index b85b3c7..e0db71d 100644 --- a/build.gradle +++ b/build.gradle @@ -1,134 +1,133 @@ -plugins { - id 'eclipse' - id 'idea' - id 'maven-publish' - id 'net.neoforged.gradle' version '[6.0.18,6.2)' - id 'org.parchmentmc.librarian.forgegradle' version '1.+' -} - -if (System.getenv('VERSION') != null) { - mod_version = System.getenv('VERSION') -} else if (project.hasProperty("CI")) { - def stdout = new ByteArrayOutputStream() - exec { - commandLine 'git', 'describe', '--tags', '--abbrev=0' - standardOutput = stdout - } - mod_version = stdout.toString().replace("\n", "").replace("\r", "").trim() -} - - -version = "${minecraft_version}-${mod_version}" -group = mod_group_id - -base { - archivesName = mod_id -} - -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 { - mappings channel: mapping_channel, version: mapping_version - - copyIdeResources = true - accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') - runs { - configureEach { - workingDirectory project.file('run') - property 'forge.logging.markers', 'REGISTRIES' - property 'forge.logging.console.level', 'debug' - - mods { - "${mod_id}" { - source sourceSets.main - } - } - } - - client { - property 'forge.enabledGameTestNamespaces', mod_id - } - - server { - property 'forge.enabledGameTestNamespaces', mod_id - args '--nogui' - } - - gameTestServer { - property 'forge.enabledGameTestNamespaces', mod_id - } - - data { - workingDirectory project.file('run-data') - - args '--mod', mod_id, '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/') - } - } -} - -sourceSets.main.resources { srcDir 'src/generated/resources' } - -repositories {} - -dependencies { - minecraft "net.neoforged:forge:${minecraft_version}-${forge_version}" -} - -tasks.named('processResources', ProcessResources).configure { - var replaceProperties = [ - minecraft_version : minecraft_version, minecraft_version_range: minecraft_version_range, - forge_version : forge_version, forge_version_range: forge_version_range, - loader_version_range: loader_version_range, - mod_id : mod_id, mod_name: mod_name, mod_license: mod_license, mod_version: mod_version, - mod_authors : mod_authors, mod_description: mod_description, - ] - inputs.properties replaceProperties - - filesMatching(['META-INF/mods.toml', 'pack.mcmeta']) { - expand replaceProperties + [project: project] - } -} - -tasks.named('jar', Jar).configure { - manifest { - attributes([ - 'Specification-Title' : mod_id, - 'Specification-Vendor' : mod_authors, - 'Specification-Version' : '1', // We are version 1 of ourselves - 'Implementation-Title' : project.name, - 'Implementation-Version' : project.jar.archiveVersion, - 'Implementation-Vendor' : mod_authors, - 'Implementation-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") - ]) - } - - finalizedBy 'reobfJar' -} - -publishing { - publications { - register('mavenJava', MavenPublication) { - groupId project.group - artifactId project.archivesBaseName - version project.version - artifact jar - - pom.withXml { - asNode().dependencies.dependency.each { dep -> - println 'Surpressing artifact ' + dep.artifactId.last().value().last() + ' from maven dependencies.' - assert dep.parent().remove(dep) - } - } - } - } - repositories { - maven { - url = uri("file://${System.getenv("local_maven")}") - } - } -} - -tasks.withType(JavaCompile).configureEach { - options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation -} +plugins { + id 'java-library' + id 'maven-publish' + id 'net.neoforged.gradle.userdev' version '7.1.21' +} + +if (System.getenv('VERSION') != null) { + mod_version = System.getenv('VERSION') +} else if (project.hasProperty('CI')) { + def stdout = new ByteArrayOutputStream() + exec { + commandLine 'git', 'describe', '--tags', '--abbrev=0' + standardOutput = stdout + } + mod_version = stdout.toString().replace("\n", '').replace("\r", '').trim() +} + +version = "${minecraft_version}-${mod_version}" +group = mod_group_id + +base { + archivesName = mod_id +} + +java.toolchain.languageVersion = JavaLanguageVersion.of(21) + +println "Java: ${System.getProperty 'java.version'}, JVM: ${System.getProperty 'java.vm.version'} (${System.getProperty 'java.vendor'}), Arch: ${System.getProperty 'os.arch'}" + +sourceSets.main.resources { + srcDir('src/generated/resources') +} + +minecraft.accessTransformers.file rootProject.file('src/main/resources/META-INF/accesstransformer.cfg') + +runs { + configureEach { + systemProperty 'forge.logging.markers', 'REGISTRIES' + systemProperty 'forge.logging.console.level', 'debug' + modSource project.sourceSets.main + } + + client { + systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id + } + + server { + systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id + argument '--nogui' + } + + gameTestServer { + systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id + } + + data { + arguments.addAll '--mod', project.mod_id, '--all', + '--output', file('src/generated/resources/').getAbsolutePath(), + '--existing', file('src/main/resources/').getAbsolutePath() + } +} + +repositories { + mavenLocal() +} + +configurations { + runtimeClasspath.extendsFrom localRuntime +} + +dependencies { + implementation "net.neoforged:neoforge:${neo_version}" +} + +tasks.withType(ProcessResources).configureEach { + var replaceProperties = [ + minecraft_version : minecraft_version, + minecraft_version_range: minecraft_version_range, + neo_version : neo_version, + neo_version_range : neo_version_range, + loader_version_range : loader_version_range, + mod_id : mod_id, + mod_name : mod_name, + mod_license : mod_license, + mod_version : mod_version, + mod_authors : mod_authors, + mod_description : mod_description, + ] + inputs.properties replaceProperties + + filesMatching(['META-INF/neoforge.mods.toml']) { + expand replaceProperties + } +} + +publishing { + publications { + register('mavenJava', MavenPublication) { + from components.java + pom.withXml { + asNode().dependencies.dependency.each { dep -> + println 'Surpressing artifact ' + dep.artifactId.last().value().last() + ' from maven dependencies.' + assert dep.parent().remove(dep) + } + } + } + } + repositories { + if (System.getenv('local_maven')) { + maven { + url = uri("file://${System.getenv('local_maven')}") + } + } else { + maven { + url = uri("${project.projectDir}/repo") + } + } + } +} + +tasks.withType(JavaCompile).configureEach { + options.encoding = 'UTF-8' +} + +tasks.named('wrapper', Wrapper).configure { + distributionType = Wrapper.DistributionType.BIN +} + +idea { + module { + downloadSources = true + downloadJavadoc = true + } +} diff --git a/gradle.properties b/gradle.properties index 16059c1..948a9ba 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,17 +1,20 @@ org.gradle.jvmargs=-Xmx3G org.gradle.daemon=false -minecraft_version=1.20.1 -minecraft_version_range=[1.20.1,1.21) -forge_version=47.1.54 -forge_version_range=[47,) -loader_version_range=[47,) -mapping_channel=parchment -mapping_version=2023.07.30-1.20.1 +org.gradle.parallel=true +org.gradle.caching=true + +neogradle.subsystems.parchment.minecraftVersion=1.21.1 +neogradle.subsystems.parchment.mappingsVersion=2024.11.17 + +minecraft_version=1.21.1 +minecraft_version_range=[1.21.1] +neo_version=21.1.223 +neo_version_range=[21.1.0,) +loader_version_range=[1,) mod_id=mutil mod_name=mutil mod_license=MIT -mod_version=6.3.0 +mod_version=6.3.1 mod_group_id=se.mickelus.mutil mod_authors=Mickelus mod_description=A collection of utilities used by mods like tetra. - diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 37aef8d..23449a2 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 diff --git a/settings.gradle b/settings.gradle index caa335d..3a3e5b9 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,17 +1,10 @@ -pluginManagement { - repositories { - gradlePluginPortal() - maven { - name "NeoForge" - url "https://maven.neoforged.net/releases/" - } - maven { - name 'parchment' - url 'https://maven.parchmentmc.org' - } - } -} - -plugins { - id 'org.gradle.toolchains.foojay-resolver-convention' version '0.5.0' -} \ No newline at end of file +pluginManagement { + repositories { + gradlePluginPortal() + maven { url = 'https://maven.neoforged.net/releases' } + } +} + +plugins { + id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0' +} diff --git a/src/main/java/se/mickelus/mutil/ConfigHandler.java b/src/main/java/se/mickelus/mutil/ConfigHandler.java index 9413b41..5308ecc 100644 --- a/src/main/java/se/mickelus/mutil/ConfigHandler.java +++ b/src/main/java/se/mickelus/mutil/ConfigHandler.java @@ -1,47 +1,39 @@ -package se.mickelus.mutil; - - -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.common.ForgeConfigSpec; -import net.minecraftforge.fml.ModLoadingContext; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.config.ModConfig; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; -import net.minecraftforge.fml.loading.FMLEnvironment; -import org.apache.commons.lang3.tuple.Pair; - -import javax.annotation.ParametersAreNonnullByDefault; - -@ParametersAreNonnullByDefault -@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD) -class ConfigHandler { - public static Client client; - static ForgeConfigSpec clientSpec; - - public static void setup() { - if (FMLEnvironment.dist.isClient()) { - setupClient(); - ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, clientSpec); - FMLJavaModLoadingContext.get().getModEventBus().register(ConfigHandler.client); - } - } - - @OnlyIn(Dist.CLIENT) - private static void setupClient() { - final Pair specPair = new ForgeConfigSpec.Builder().configure(Client::new); - clientSpec = specPair.getRight(); - client = specPair.getLeft(); - } - - @OnlyIn(Dist.CLIENT) - public static class Client { - public ForgeConfigSpec.BooleanValue queryPerks; - - Client(ForgeConfigSpec.Builder builder) { - queryPerks = builder - .comment("Controls if perks data should be queried on startup") - .define("query_perks", true); +package se.mickelus.mutil; + + +import net.neoforged.fml.ModContainer; +import net.neoforged.fml.config.ModConfig; +import net.neoforged.fml.loading.FMLEnvironment; +import net.neoforged.neoforge.common.ModConfigSpec; +import org.apache.commons.lang3.tuple.Pair; + +import javax.annotation.ParametersAreNonnullByDefault; + +@ParametersAreNonnullByDefault +class ConfigHandler { + public static Client client; + static ModConfigSpec clientSpec; + + public static void setup(ModContainer modContainer) { + if (FMLEnvironment.dist.isClient()) { + setupClient(); + modContainer.registerConfig(ModConfig.Type.CLIENT, clientSpec); + } + } + + private static void setupClient() { + final Pair specPair = new ModConfigSpec.Builder().configure(Client::new); + clientSpec = specPair.getRight(); + client = specPair.getLeft(); + } + + public static class Client { + public ModConfigSpec.BooleanValue queryPerks; + + Client(ModConfigSpec.Builder builder) { + queryPerks = builder + .comment("Controls if perks data should be queried on startup") + .define("query_perks", true); } } } diff --git a/src/main/java/se/mickelus/mutil/MUtilMod.java b/src/main/java/se/mickelus/mutil/MUtilMod.java index 78b348b..0574b27 100644 --- a/src/main/java/se/mickelus/mutil/MUtilMod.java +++ b/src/main/java/se/mickelus/mutil/MUtilMod.java @@ -1,21 +1,26 @@ -package se.mickelus.mutil; - -import net.minecraft.client.Minecraft; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; - -@Mod(MUtilMod.MOD_ID) -@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD) -public class MUtilMod { - public static final String MOD_ID = "mutil"; - - public MUtilMod() { - ConfigHandler.setup(); - } - - @SubscribeEvent - public static void clientSetup(FMLClientSetupEvent event) { - Perks.init(Minecraft.getInstance().getUser().getUuid()); - } -} +package se.mickelus.mutil; + +import net.minecraft.client.Minecraft; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.ModContainer; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.fml.common.Mod; +import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; + +@Mod(MUtilMod.MOD_ID) +public class MUtilMod { + public static final String MOD_ID = "mutil"; + + public MUtilMod(ModContainer modContainer) { + ConfigHandler.setup(modContainer); + } + + @EventBusSubscriber(modid = MOD_ID, value = Dist.CLIENT) + private static class ClientEvents { + @SubscribeEvent + public static void clientSetup(FMLClientSetupEvent event) { + Perks.init(Minecraft.getInstance().getUser().getProfileId().toString()); + } + } +} diff --git a/src/main/java/se/mickelus/mutil/data/DataStore.java b/src/main/java/se/mickelus/mutil/data/DataStore.java index b6d90c5..611abd0 100644 --- a/src/main/java/se/mickelus/mutil/data/DataStore.java +++ b/src/main/java/se/mickelus/mutil/data/DataStore.java @@ -2,6 +2,7 @@ import com.google.common.collect.Maps; import com.google.gson.*; +import com.mojang.serialization.JsonOps; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.packs.resources.Resource; @@ -9,12 +10,12 @@ import net.minecraft.server.packs.resources.SimplePreparableReloadListener; import net.minecraft.util.GsonHelper; import net.minecraft.util.profiling.ProfilerFiller; -import net.minecraftforge.common.crafting.CraftingHelper; -import net.minecraftforge.common.crafting.conditions.ICondition; -import net.minecraftforge.fml.ModList; -import net.minecraftforge.forgespi.Environment; -import net.minecraftforge.forgespi.language.IModInfo; -import net.minecraftforge.server.ServerLifecycleHooks; +import net.neoforged.fml.ModList; +import net.neoforged.fml.loading.FMLEnvironment; +import net.neoforged.neoforge.common.conditions.ConditionalOps; +import net.neoforged.neoforge.common.conditions.ICondition; +import net.neoforged.neoforge.server.ServerLifecycleHooks; +import net.neoforged.neoforgespi.language.IModInfo; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -62,7 +63,7 @@ protected Map prepare(ResourceManager resourceMan } String path = entry.getKey().getPath(); - ResourceLocation location = new ResourceLocation(entry.getKey().getNamespace(), path.substring(i, path.length() - jsonExtLength)); + ResourceLocation location = ResourceLocation.fromNamespaceAndPath(entry.getKey().getNamespace(), path.substring(i, path.length() - jsonExtLength)); try (Reader reader = entry.getValue().openAsReader()) { JsonElement json; @@ -122,7 +123,7 @@ protected void apply(Map splashList, ResourceMana rawData = splashList; // PacketHandler dependencies get upset when called upon before the server has started properly - if (Environment.get().getDist().isDedicatedServer() && ServerLifecycleHooks.getCurrentServer() != null) { + if (FMLEnvironment.dist.isDedicatedServer() && ServerLifecycleHooks.getCurrentServer() != null) { syncronizer.sendToAll(directory, rawData); } @@ -175,8 +176,12 @@ protected boolean shouldLoad(JsonElement json) { } JsonObject jsonObject = json.getAsJsonObject(); - return !jsonObject.has("conditions") - || CraftingHelper.processConditions(GsonHelper.getAsJsonArray(jsonObject, "conditions"), ICondition.IContext.EMPTY); + if (jsonObject.has("conditions") && !jsonObject.has(ConditionalOps.DEFAULT_CONDITIONS_KEY)) { + jsonObject = jsonObject.deepCopy(); + jsonObject.add(ConditionalOps.DEFAULT_CONDITIONS_KEY, jsonObject.remove("conditions")); + } + + return ICondition.conditionsMatched(JsonOps.INSTANCE, jsonObject); } protected void processData() { diff --git a/src/main/java/se/mickelus/mutil/data/MergingDataStore.java b/src/main/java/se/mickelus/mutil/data/MergingDataStore.java index 2fb13c0..679e3e4 100644 --- a/src/main/java/se/mickelus/mutil/data/MergingDataStore.java +++ b/src/main/java/se/mickelus/mutil/data/MergingDataStore.java @@ -42,7 +42,7 @@ protected Map prepare(ResourceManager resourceMan } String path = entry.getKey().getPath(); - ResourceLocation location = new ResourceLocation(entry.getKey().getNamespace(), path.substring(i, path.length() - jsonExtLength)); + ResourceLocation location = ResourceLocation.fromNamespaceAndPath(entry.getKey().getNamespace(), path.substring(i, path.length() - jsonExtLength)); JsonArray allResources = new JsonArray(); diff --git a/src/main/java/se/mickelus/mutil/data/deserializer/BlockDeserializer.java b/src/main/java/se/mickelus/mutil/data/deserializer/BlockDeserializer.java index 2a425d1..4443ff7 100644 --- a/src/main/java/se/mickelus/mutil/data/deserializer/BlockDeserializer.java +++ b/src/main/java/se/mickelus/mutil/data/deserializer/BlockDeserializer.java @@ -4,9 +4,9 @@ import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.JsonParseException; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.block.Block; -import net.minecraftforge.registries.ForgeRegistries; import javax.annotation.ParametersAreNonnullByDefault; import java.lang.reflect.Type; @@ -17,9 +17,9 @@ public class BlockDeserializer implements JsonDeserializer { public Block deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { String string = json.getAsString(); if (string != null) { - ResourceLocation resourceLocation = new ResourceLocation(string); - if (ForgeRegistries.BLOCKS.containsKey(resourceLocation)) { - return ForgeRegistries.BLOCKS.getValue(resourceLocation); + ResourceLocation resourceLocation = ResourceLocation.parse(string); + if (BuiltInRegistries.BLOCK.containsKey(resourceLocation)) { + return BuiltInRegistries.BLOCK.get(resourceLocation); } } diff --git a/src/main/java/se/mickelus/mutil/data/deserializer/ItemDeserializer.java b/src/main/java/se/mickelus/mutil/data/deserializer/ItemDeserializer.java index c13ed2b..09c8083 100644 --- a/src/main/java/se/mickelus/mutil/data/deserializer/ItemDeserializer.java +++ b/src/main/java/se/mickelus/mutil/data/deserializer/ItemDeserializer.java @@ -4,9 +4,9 @@ import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.JsonParseException; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.Item; -import net.minecraftforge.registries.ForgeRegistries; import javax.annotation.ParametersAreNonnullByDefault; import java.lang.reflect.Type; @@ -17,12 +17,12 @@ public class ItemDeserializer implements JsonDeserializer { public Item deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { String string = json.getAsString(); if (string != null) { - ResourceLocation resourceLocation = new ResourceLocation(string); - if (ForgeRegistries.ITEMS.containsKey(resourceLocation)) { - return ForgeRegistries.ITEMS.getValue(resourceLocation); + ResourceLocation resourceLocation = ResourceLocation.parse(string); + if (BuiltInRegistries.ITEM.containsKey(resourceLocation)) { + return BuiltInRegistries.ITEM.get(resourceLocation); } } return null; } -} \ No newline at end of file +} diff --git a/src/main/java/se/mickelus/mutil/data/deserializer/ResourceLocationDeserializer.java b/src/main/java/se/mickelus/mutil/data/deserializer/ResourceLocationDeserializer.java index c10776d..b883129 100644 --- a/src/main/java/se/mickelus/mutil/data/deserializer/ResourceLocationDeserializer.java +++ b/src/main/java/se/mickelus/mutil/data/deserializer/ResourceLocationDeserializer.java @@ -13,11 +13,11 @@ public class ResourceLocationDeserializer implements JsonDeserializer { public static ResourceLocation deserialize(JsonElement json) throws JsonParseException { - return new ResourceLocation(json.getAsString()); + return ResourceLocation.parse(json.getAsString()); } @Override public ResourceLocation deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { return deserialize(json); } -} \ No newline at end of file +} diff --git a/src/main/java/se/mickelus/mutil/effect/EffectTooltipRenderer.java b/src/main/java/se/mickelus/mutil/effect/EffectTooltipRenderer.java index 1f99754..dcd7568 100644 --- a/src/main/java/se/mickelus/mutil/effect/EffectTooltipRenderer.java +++ b/src/main/java/se/mickelus/mutil/effect/EffectTooltipRenderer.java @@ -1,15 +1,12 @@ package se.mickelus.mutil.effect; import com.mojang.blaze3d.platform.Window; -import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.inventory.EffectRenderingInventoryScreen; import net.minecraft.network.chat.Component; import net.minecraft.world.effect.MobEffectInstance; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.client.extensions.common.IClientMobEffectExtensions; +import net.neoforged.neoforge.client.extensions.common.IClientMobEffectExtensions; import java.util.function.Function; import java.util.function.Supplier; @@ -21,7 +18,6 @@ public EffectTooltipRenderer(Function constructEffect this.constructEffectTooltip = constructEffectTooltip; } - @OnlyIn(Dist.CLIENT) public static void renderInventoryEffectTooltip(GuiGraphics graphics, int x, int y, Supplier tooltip) { Minecraft mc = Minecraft.getInstance(); Window window = mc.getWindow(); diff --git a/src/main/java/se/mickelus/mutil/gui/GuiItem.java b/src/main/java/se/mickelus/mutil/gui/GuiItem.java index 05d3354..b98bd16 100644 --- a/src/main/java/se/mickelus/mutil/gui/GuiItem.java +++ b/src/main/java/se/mickelus/mutil/gui/GuiItem.java @@ -5,6 +5,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.network.chat.Component; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.TooltipFlag; @@ -76,7 +77,7 @@ public GuiItem setRenderDecoration(boolean shouldRender) { @Override public void draw(final GuiGraphics graphics, int refX, int refY, int screenWidth, int screenHeight, int mouseX, int mouseY, float opacity) { super.draw(graphics, refX, refY, screenWidth, screenHeight, mouseX, mouseY, opacity); - if (opacity * getOpacity() >= opacityThreshold) { + if (itemStack != null && opacity * getOpacity() >= opacityThreshold) { RenderSystem.applyModelViewMatrix(); RenderSystem.enableDepthTest(); RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, @@ -84,7 +85,7 @@ public void draw(final GuiGraphics graphics, int refX, int refY, int screenWidth graphics.renderItem(itemStack, refX + x, refY + y); if (renderDecoration) { - + graphics.renderItemDecorations(mc.font, itemStack, refX + x, refY + y, getCountString()); } if (resetDepthTest) { @@ -109,7 +110,7 @@ protected String getCountString() { @Override public List getTooltipLines() { if (showTooltip && itemStack != null && hasFocus()) { - return new ArrayList<>(itemStack.getTooltipLines(Minecraft.getInstance().player, + return new ArrayList<>(itemStack.getTooltipLines(Item.TooltipContext.of(mc.level), Minecraft.getInstance().player, mc.options.advancedItemTooltips ? TooltipFlag.Default.ADVANCED : TooltipFlag.Default.NORMAL)); } diff --git a/src/main/java/se/mickelus/mutil/gui/GuiTexture.java b/src/main/java/se/mickelus/mutil/gui/GuiTexture.java index ff8741f..48f3068 100644 --- a/src/main/java/se/mickelus/mutil/gui/GuiTexture.java +++ b/src/main/java/se/mickelus/mutil/gui/GuiTexture.java @@ -61,20 +61,18 @@ public void draw(final GuiGraphics graphics, int refX, int refY, int screenWidth protected void drawTexture(final GuiGraphics graphics, ResourceLocation textureLocation, int x, int y, int width, int height, int u, int v, int color, float opacity) { - // todo 1.20: needs cleanup, simplified rendering with simple params seems to cause flickering during animations, defaultBlendFunc not needed anymore? -// if (useDefaultBlending) { -// RenderSystem.defaultBlendFunc(); -// } - -// if (color != 0xffffff || opacity != 1) { -// if (opacity > 0) { - graphics.innerBlit(textureLocation, x, x + width, y, y + height, 0, - u * 1f / textureWidth, (u + width) * 1f / textureWidth, - v * 1f / textureHeight, (v + height) * 1f / textureHeight, - (color >> 16 & 255) / 255f, (color >> 8 & 255) / 255f, (color & 255) / 255f, opacity); -// } -// } else { -// graphics.blit(textureLocation, x, y, 0, u, v, width, height, textureWidth, textureHeight); -// } + if (useDefaultBlending) { + RenderSystem.enableBlend(); + RenderSystem.defaultBlendFunc(); + } + + graphics.setColor( + (color >> 16 & 255) / 255f, + (color >> 8 & 255) / 255f, + (color & 255) / 255f, + opacity + ); + graphics.blit(textureLocation, x, y, u, v, width, height, textureWidth, textureHeight); + graphics.setColor(1, 1, 1, 1); } } diff --git a/src/main/java/se/mickelus/mutil/gui/ToggleableSlot.java b/src/main/java/se/mickelus/mutil/gui/ToggleableSlot.java index 9ba4b4f..78af01d 100644 --- a/src/main/java/se/mickelus/mutil/gui/ToggleableSlot.java +++ b/src/main/java/se/mickelus/mutil/gui/ToggleableSlot.java @@ -2,8 +2,8 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; -import net.minecraftforge.items.IItemHandler; -import net.minecraftforge.items.SlotItemHandler; +import net.neoforged.neoforge.items.IItemHandler; +import net.neoforged.neoforge.items.SlotItemHandler; import javax.annotation.Nullable; @@ -23,6 +23,13 @@ public void toggle(boolean enabled) { isEnabled = enabled; } + public void setPosition(int x, int y) { + this.x = x; + this.y = y; + realX = x; + realY = y; + } + @Override public boolean isActive() { return isEnabled; @@ -35,6 +42,6 @@ public boolean mayPickup(Player playerIn) { @Override public boolean mayPlace(@Nullable ItemStack stack) { - return isEnabled; + return isEnabled && super.mayPlace(stack == null ? ItemStack.EMPTY : stack); } } diff --git a/src/main/java/se/mickelus/mutil/network/PacketHandler.java b/src/main/java/se/mickelus/mutil/network/PacketHandler.java index 0903587..b1c4231 100644 --- a/src/main/java/se/mickelus/mutil/network/PacketHandler.java +++ b/src/main/java/se/mickelus/mutil/network/PacketHandler.java @@ -2,42 +2,54 @@ import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.network.NetworkDirection; -import net.minecraftforge.network.NetworkEvent; -import net.minecraftforge.network.NetworkRegistry; -import net.minecraftforge.network.PacketDistributor; -import net.minecraftforge.network.simple.SimpleChannel; +import net.neoforged.neoforge.network.PacketDistributor; +import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent; +import net.neoforged.neoforge.network.registration.PayloadRegistrar; +import net.neoforged.neoforge.server.ServerLifecycleHooks; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import javax.annotation.ParametersAreNonnullByDefault; import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; import java.util.function.Supplier; @ParametersAreNonnullByDefault public class PacketHandler { private static final Logger logger = LogManager.getLogger(); - private final SimpleChannel channel; - private final ArrayList> packets = new ArrayList<>(); + private final String namespace; + private final String channelId; + private final String protocolVersion; + private final List> packets = new ArrayList<>(); + private final Map, PacketRegistration> packetsByClass = new HashMap<>(); + private boolean payloadsRegistered; + + public enum PacketDirection { + CLIENTBOUND, + SERVERBOUND, + BIDIRECTIONAL + } public PacketHandler(String namespace, String channelId, String protocolVersion) { - channel = NetworkRegistry.newSimpleChannel( - new ResourceLocation(namespace, channelId), - () -> protocolVersion, - protocolVersion::equals, - protocolVersion::equals); + this.namespace = namespace; + this.channelId = channelId; + this.protocolVersion = protocolVersion; } /** - * Register your packet with the pipeline. Discriminators are automatically set. + * Register a packet type so it can later be exposed as a NeoForge payload. * * @param packetClass the class to register * @param supplier A supplier returning an object instance of packetClass @@ -45,63 +57,136 @@ public PacketHandler(String namespace, String channelId, String protocolVersion) * @return whether registration was successful. Failure may occur if 256 packets have been registered or if the registry already contains this packet */ public boolean registerPacket(Class packetClass, Supplier supplier) { + return registerPacket(packetClass, supplier, PacketDirection.BIDIRECTIONAL); + } + + public boolean registerClientBoundPacket(Class packetClass, Supplier supplier) { + return registerPacket(packetClass, supplier, PacketDirection.CLIENTBOUND); + } + + public boolean registerServerBoundPacket(Class packetClass, Supplier supplier) { + return registerPacket(packetClass, supplier, PacketDirection.SERVERBOUND); + } + + private boolean registerPacket(Class packetClass, Supplier supplier, PacketDirection direction) { + if (payloadsRegistered) { + logger.warn("Attempted to register packet after payload registration phase: {}", packetClass); + return false; + } + if (packets.size() > 256) { - logger.warn("Attempted to register packet but packet list is full: " + packetClass.toString()); + logger.warn("Attempted to register packet but packet list is full: {}", packetClass); return false; } - if (packets.contains(packetClass)) { - logger.warn("Attempted to register packet but packet is already in list: " + packetClass.toString()); + if (packetsByClass.containsKey(packetClass)) { + logger.warn("Attempted to register packet but packet is already in list: {}", packetClass); return false; } - channel.messageBuilder(packetClass, packets.size()) - .encoder(AbstractPacket::toBytes) - .decoder(buffer -> { - T packet = supplier.get(); - packet.fromBytes(buffer); - return packet; - }) - .consumerNetworkThread(this::onMessage) - .add(); - - packets.add(packetClass); + PacketRegistration registration = new PacketRegistration<>(packetClass, supplier, getPacketId(packetClass), direction); + packets.add(registration); + packetsByClass.put(packetClass, registration); return true; } - public void onMessage(AbstractPacket message, Supplier ctx) { - ctx.get().enqueueWork(() -> { - if (ctx.get().getDirection().getReceptionSide().isServer()) { - message.handle(ctx.get().getSender()); - } else { - message.handle(getClientPlayer()); - } - }); - ctx.get().setPacketHandled(true); - } + public void registerPayloads(RegisterPayloadHandlersEvent event) { + if (payloadsRegistered) { + return; + } - @OnlyIn(Dist.CLIENT) - private Player getClientPlayer() { - return Minecraft.getInstance().player; + PayloadRegistrar registrar = event.registrar(protocolVersion); + for (PacketRegistration packet : packets) { + registerPayload(registrar, packet); + } + + payloadsRegistered = true; } public void sendTo(AbstractPacket message, ServerPlayer player) { - channel.sendTo(message, player.connection.connection, NetworkDirection.PLAY_TO_CLIENT); + PacketDistributor.sendToPlayer(player, createPayload(message)); } public void sendToAllPlayers(AbstractPacket message) { - channel.send(PacketDistributor.ALL.noArg(), message); + PacketDistributor.sendToAllPlayers(createPayload(message)); } - public void sendToAllPlayersNear(AbstractPacket message, BlockPos pos, double r2, ResourceKey dim) { - channel.send(PacketDistributor.NEAR.with(PacketDistributor.TargetPoint.p(pos.getX(), pos.getY(), pos.getZ(), r2, dim)), message); + public void sendToAllPlayersNear(AbstractPacket message, BlockPos pos, double radius, ResourceKey dimension) { + ServerLevel level = ServerLifecycleHooks.getCurrentServer().getLevel(dimension); + if (level != null) { + PacketDistributor.sendToPlayersNear(level, null, pos.getX(), pos.getY(), pos.getZ(), radius, createPayload(message)); + } } - @OnlyIn(Dist.CLIENT) public void sendToServer(AbstractPacket message) { // crashes sometimes happen due to the connection being null if (Minecraft.getInstance().getConnection() != null) { - channel.sendToServer(message); + PacketDistributor.sendToServer(createPayload(message)); + } + } + + @SuppressWarnings("unchecked") + private PacketPayload createPayload(T message) { + PacketRegistration registration = (PacketRegistration) packetsByClass.get(message.getClass()); + if (registration == null) { + throw new IllegalStateException("Attempted to send unregistered packet: " + message.getClass().getName()); + } + + return new PacketPayload<>(registration, message); + } + + private void registerPayload(PayloadRegistrar registrar, PacketRegistration registration) { + switch (registration.direction) { + case CLIENTBOUND -> registrar.playToClient(registration.type, registration.codec, + (payload, context) -> payload.packet.handle(context.player())); + case SERVERBOUND -> registrar.playToServer(registration.type, registration.codec, + (payload, context) -> payload.packet.handle(context.player())); + case BIDIRECTIONAL -> registrar.playBidirectional(registration.type, registration.codec, + (payload, context) -> payload.packet.handle(context.player())); + } + } + + private ResourceLocation getPacketId(Class packetClass) { + return ResourceLocation.fromNamespaceAndPath( + namespace, + channelId + "/" + packetClass.getName() + .replace('.', '/') + .replace('$', '/') + .toLowerCase(Locale.ROOT) + ); + } + + private static class PacketPayload implements CustomPacketPayload { + private final PacketRegistration registration; + private final T packet; + + private PacketPayload(PacketRegistration registration, T packet) { + this.registration = registration; + this.packet = packet; + } + + @Override + public Type> type() { + return registration.type; + } + } + + private static class PacketRegistration { + private final CustomPacketPayload.Type> type; + private final StreamCodec> codec; + private final PacketDirection direction; + + private PacketRegistration(Class packetClass, Supplier supplier, ResourceLocation id, PacketDirection direction) { + type = new CustomPacketPayload.Type<>(id); + this.direction = direction; + codec = StreamCodec.of( + (buffer, payload) -> payload.packet.toBytes(buffer), + buffer -> { + T packet = supplier.get(); + packet.fromBytes(buffer); + return new PacketPayload<>(this, packet); + } + ); } } -} \ No newline at end of file +} diff --git a/src/main/java/se/mickelus/mutil/scheduling/AbstractScheduler.java b/src/main/java/se/mickelus/mutil/scheduling/AbstractScheduler.java index 53eb3ac..8d0884a 100644 --- a/src/main/java/se/mickelus/mutil/scheduling/AbstractScheduler.java +++ b/src/main/java/se/mickelus/mutil/scheduling/AbstractScheduler.java @@ -2,7 +2,6 @@ import com.google.common.collect.Queues; import net.minecraft.server.TickTask; -import net.minecraftforge.event.TickEvent; import javax.annotation.ParametersAreNonnullByDefault; import java.util.Iterator; @@ -22,11 +21,7 @@ public void schedule(String id, int delay, Runnable task) { queue.add(new Task(id, counter + delay, task)); } - public void tick(TickEvent event) { - if (event.phase != TickEvent.Phase.END) { - return; - } - + protected void tick() { for (Iterator it = queue.iterator(); it.hasNext(); ) { Task task = it.next(); if (task.getTick() < counter) { diff --git a/src/main/java/se/mickelus/mutil/scheduling/ClientScheduler.java b/src/main/java/se/mickelus/mutil/scheduling/ClientScheduler.java index 2f756ee..5ba902e 100644 --- a/src/main/java/se/mickelus/mutil/scheduling/ClientScheduler.java +++ b/src/main/java/se/mickelus/mutil/scheduling/ClientScheduler.java @@ -1,15 +1,15 @@ package se.mickelus.mutil.scheduling; -import net.minecraftforge.event.TickEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.neoforge.client.event.ClientTickEvent; import javax.annotation.ParametersAreNonnullByDefault; @ParametersAreNonnullByDefault public class ClientScheduler extends AbstractScheduler { @SubscribeEvent - public void onClientTick(TickEvent.ClientTickEvent event) { - this.tick(event); + public void onClientTick(ClientTickEvent.Post event) { + this.tick(); } } diff --git a/src/main/java/se/mickelus/mutil/scheduling/ServerScheduler.java b/src/main/java/se/mickelus/mutil/scheduling/ServerScheduler.java index 6b6343f..0dcda85 100644 --- a/src/main/java/se/mickelus/mutil/scheduling/ServerScheduler.java +++ b/src/main/java/se/mickelus/mutil/scheduling/ServerScheduler.java @@ -1,14 +1,14 @@ package se.mickelus.mutil.scheduling; -import net.minecraftforge.event.TickEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.neoforge.event.tick.ServerTickEvent; import javax.annotation.ParametersAreNonnullByDefault; @ParametersAreNonnullByDefault public class ServerScheduler extends AbstractScheduler { @SubscribeEvent - public void onServerTick(TickEvent.ServerTickEvent event) { - tick(event); + public void onServerTick(ServerTickEvent.Post event) { + tick(); } } diff --git a/src/main/java/se/mickelus/mutil/util/ItemHandlerWrapper.java b/src/main/java/se/mickelus/mutil/util/ItemHandlerWrapper.java index f78045d..58d7599 100644 --- a/src/main/java/se/mickelus/mutil/util/ItemHandlerWrapper.java +++ b/src/main/java/se/mickelus/mutil/util/ItemHandlerWrapper.java @@ -3,7 +3,7 @@ import net.minecraft.world.Container; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; -import net.minecraftforge.items.IItemHandler; +import net.neoforged.neoforge.items.IItemHandler; import javax.annotation.ParametersAreNonnullByDefault; @@ -37,8 +37,7 @@ public ItemStack getItem(int slot) { */ @Override public ItemStack removeItem(int slot, int count) { - ItemStack stack = inv.getStackInSlot(slot); - return stack.isEmpty() ? ItemStack.EMPTY : stack.split(count); + return inv.extractItem(slot, count, false); } /** diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index f800864..12b1263 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -1 +1,2 @@ -public net.minecraft.client.gui.GuiGraphics m_280479_(Lnet/minecraft/resources/ResourceLocation;IIIIIFFFFFFFF)V # innerBlit \ No newline at end of file +public-f net.minecraft.world.inventory.Slot x +public-f net.minecraft.world.inventory.Slot y diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/neoforge.mods.toml similarity index 71% rename from src/main/resources/META-INF/mods.toml rename to src/main/resources/META-INF/neoforge.mods.toml index 3c988be..218505e 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/neoforge.mods.toml @@ -1,6 +1,7 @@ modLoader="javafml" loaderVersion="${loader_version_range}" license="${mod_license}" + [[mods]] modId="${mod_id}" version="${mod_version}" @@ -8,15 +9,19 @@ displayName="${mod_name}" authors="${mod_authors}" description='''${mod_description}''' +[[accessTransformers]] +file="META-INF/accesstransformer.cfg" + [[dependencies.${mod_id}]] - modId="forge" - mandatory=true - versionRange="${forge_version_range}" + modId="neoforge" + type="required" + versionRange="${neo_version_range}" ordering="NONE" side="BOTH" + [[dependencies.${mod_id}]] modId="minecraft" - mandatory=true + type="required" versionRange="${minecraft_version_range}" ordering="NONE" side="BOTH" diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta index 23c861b..7f0eb93 100644 --- a/src/main/resources/pack.mcmeta +++ b/src/main/resources/pack.mcmeta @@ -1,6 +1,6 @@ { "pack": { "description": "mutil resources", - "pack_format": 15 + "pack_format": 34 } }