diff --git a/build.gradle b/build.gradle index 9093ce1..5320087 100644 --- a/build.gradle +++ b/build.gradle @@ -1,8 +1,9 @@ plugins { id 'java-library' - id 'maven-publish' - id 'net.neoforged.gradle.userdev' version '7.0.170' id 'idea' + id 'maven-publish' +// id 'net.neoforged.gradle.userdev' version '7.0.170' + id 'net.neoforged.moddev' } tasks.named('wrapper', Wrapper).configure { @@ -48,45 +49,58 @@ base { java.toolchain.languageVersion = JavaLanguageVersion.of(21) -//parchment { -// mappingsVersion = project.parchment_mappings_version -// minecraftVersion = project.parchment_minecraft_version -//} + // accessTransformers = project.files('src/main/resources/META-INF/accesstransformer.cfg') +neoForge { + version = project.neo_version -runs { - configureEach { - - systemProperty 'forge.logging.markers', 'REGISTRIES' - - systemProperty 'forge.logging.console.level', 'debug' - - modSource project.sourceSets.main + parchment { + mappingsVersion = project.parchment_mappings_version + minecraftVersion = project.parchment_minecraft_version } - - client { - client() - systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id + mods { + "${mod_id}" { + sourceSet sourceSets.main + } } + runs { + configureEach { + systemProperty 'forge.logging.markers', 'REGISTRIES' - server { - server() - programArgument '--nogui' - systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id - } + logLevel = org.slf4j.event.Level.DEBUG + } - gameTestServer { - systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id - } + client { + client() + systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id + } - data { - programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath() + server { + server() + programArgument '--nogui' + systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id + } + + gameTestServer { + type = "gameTestServer" + systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id + } + + data { + data() + 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' } +// Sets up a dependency configuration called 'localRuntime'. +// This configuration should be used instead of 'runtimeOnly' to declare +// a dependency that will be present for runtime testing but that is +// "optional", meaning it will not be pulled by dependents of this mod. +configurations { + runtimeClasspath.extendsFrom localRuntime +} dependencies { implementation "net.neoforged:neoforge:${neo_version}" @@ -94,21 +108,10 @@ dependencies { compileOnly "curse.maven:sophisticated-backpacks-422301:5297718" compileOnly "curse.maven:sophisticated-core-618298:5296142" - // Example mod dependency using a mod jar from ./libs with a flat dir repository - // This maps to ./libs/coolmod-${mc_version}-${coolmod_version}.jar - // The group id is ignored when searching -- in this case, it is "blank" - // implementation "blank:coolmod-${mc_version}:${coolmod_version}" - - // Example mod dependency using a file as dependency - // implementation files("libs/coolmod-${mc_version}-${coolmod_version}.jar") - - // Example project dependency using a sister or child project: - // implementation project(":myproject") - // embedd the JDBC driver in the mod using jarJar runtimeOnly "com.mysql:mysql-connector-j:${jdbc_version}" jarJar "com.mysql:mysql-connector-j:${jdbc_version}" -// runtimeClasspath "com.mysql:mysql-connector-j:${jdbc_version}" + additionalRuntimeClasspath "com.mysql:mysql-connector-j:${jdbc_version}" // For more info: // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html @@ -136,6 +139,11 @@ var generateModMetadata = tasks.register("generateModMetadata", ProcessResources from "src/main/templates" into "build/generated/sources/modMetadata" } +// Include the output of "generateModMetadata" as an input directory for the build +// this works with both building through Gradle and the IDE. +sourceSets.main.resources.srcDir generateModMetadata +// To avoid having to run "generateModMetadata" manually, make it run on every project reload +neoForge.ideSyncTask generateModMetadata // Example configuration to allow publishing using the maven-publish plugin publishing { diff --git a/gradle.properties b/gradle.properties index 087a54f..ac450e9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -40,6 +40,6 @@ mod_authors=mlus # The description of the mod. This is a simple multiline text string that is used for display purposes in the mod list. mod_description=make multiserver players' data sync - # JDBC driver version - # see https://dev.mysql.com/doc/relnotes/connector-j/en/ for latest version - jdbc_version=9.3.0 +# JDBC driver version +# see https://dev.mysql.com/doc/relnotes/connector-j/en/ for latest version +jdbc_version=9.3.0 diff --git a/settings.gradle b/settings.gradle index 90ae98f..71de311 100644 --- a/settings.gradle +++ b/settings.gradle @@ -4,6 +4,11 @@ pluginManagement { gradlePluginPortal() maven { url = 'https://maven.neoforged.net/releases' } } + plugins { + // https://projects.neoforged.net/neoforged/ModDevGradle + id 'net.neoforged.moddev' version '2.0.74' + id 'net.neoforged.moddev.repositories' version '2.0.74' + } } plugins { diff --git a/src/main/java/vip/fubuki/playersync/DataComponentTypes.java b/src/main/java/vip/fubuki/playersync/DataComponentTypes.java deleted file mode 100644 index 7ecbb86..0000000 --- a/src/main/java/vip/fubuki/playersync/DataComponentTypes.java +++ /dev/null @@ -1,18 +0,0 @@ -package vip.fubuki.playersync; - -import com.mojang.serialization.Codec; -import net.minecraft.core.component.DataComponentType; -import net.minecraft.core.registries.Registries; -import net.minecraft.network.codec.ByteBufCodecs; -import net.neoforged.neoforge.registries.DeferredHolder; -import net.neoforged.neoforge.registries.DeferredRegister; - -public class DataComponentTypes { - public static final DeferredRegister> REGISTRY = DeferredRegister.create(Registries.DATA_COMPONENT_TYPE, PlayerSync.MODID); - public static final DeferredHolder, DataComponentType> ORIGINAL_ITEM_NBT = - REGISTRY.register("original_item_nbt", () -> DataComponentType.builder().persistent(Codec.STRING).networkSynchronized(ByteBufCodecs.STRING_UTF8).build()); - public static final DeferredHolder, DataComponentType> ORIGINAL_ITEM_ID = - REGISTRY.register("original_item_id", () -> DataComponentType.builder().persistent(Codec.STRING).networkSynchronized(ByteBufCodecs.STRING_UTF8).build()); - public static final DeferredHolder, DataComponentType> UNIQUE_ID = - REGISTRY.register("unique_id", () -> DataComponentType.builder().persistent(Codec.STRING).networkSynchronized(ByteBufCodecs.STRING_UTF8).build()); -} diff --git a/src/main/java/vip/fubuki/playersync/PlayerSync.java b/src/main/java/vip/fubuki/playersync/PlayerSync.java index 4cfc588..8be22a0 100644 --- a/src/main/java/vip/fubuki/playersync/PlayerSync.java +++ b/src/main/java/vip/fubuki/playersync/PlayerSync.java @@ -27,7 +27,6 @@ public class PlayerSync { public static final Logger LOGGER = LogUtils.getLogger(); public PlayerSync(IEventBus modEventBus, ModContainer modContainer) { - DataComponentTypes.REGISTRY.register(modEventBus); modEventBus.addListener(this::commonSetup); NeoForge.EVENT_BUS.register(this); modContainer.registerConfig(ModConfig.Type.COMMON, JdbcConfig.COMMON_CONFIG); diff --git a/src/main/java/vip/fubuki/playersync/sync/VanillaSync.java b/src/main/java/vip/fubuki/playersync/sync/VanillaSync.java index 9be428e..c8530e6 100644 --- a/src/main/java/vip/fubuki/playersync/sync/VanillaSync.java +++ b/src/main/java/vip/fubuki/playersync/sync/VanillaSync.java @@ -22,6 +22,7 @@ import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; +import net.minecraft.world.item.component.CustomData; import net.minecraft.world.item.component.ItemLore; import net.minecraft.world.level.storage.WorldData; import net.neoforged.bus.api.SubscribeEvent; @@ -33,7 +34,6 @@ import net.neoforged.neoforge.event.server.ServerStoppedEvent; import net.neoforged.neoforge.event.tick.LevelTickEvent; import net.neoforged.neoforge.event.tick.ServerTickEvent; import net.neoforged.neoforge.server.ServerLifecycleHooks; -import vip.fubuki.playersync.DataComponentTypes; import vip.fubuki.playersync.PlayerSync; import vip.fubuki.playersync.config.JdbcConfig; import vip.fubuki.playersync.util.JDBCsetUp; @@ -50,7 +50,7 @@ import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -@EventBusSubscriber +@EventBusSubscriber(modid = PlayerSync.MODID) public class VanillaSync { public static void register() {} @@ -301,14 +301,16 @@ public class VanillaSync { PlayerSync.LOGGER.debug("Item {} not found in registry. Creating placeholder.", registryName); ItemStack placeholder = new ItemStack(Items.PAPER); + CompoundTag placeholderNbt = new CompoundTag(); // Store the original serialized NBT string, not the parsed CompoundTag string - placeholder.set(DataComponentTypes.ORIGINAL_ITEM_NBT.get(), serializedNbt); - placeholder.set(DataComponentTypes.ORIGINAL_ITEM_ID.get(), registryName.toString()); + placeholderNbt.putString("playersync:original_item_nbt", serializedNbt); + placeholderNbt.putString("playersync:original_item_id", registryName.toString()); // Add a unique UUID to ensure the item is unstackable // Stacked placerholders would be converted into a single item when restoring item - placeholder.set(DataComponentTypes.UNIQUE_ID.get(), UUID.randomUUID().toString()); + placeholderNbt.putUUID("playersync:unique_id", UUID.randomUUID()); + CustomData.set(DataComponents.CUSTOM_DATA,placeholder, placeholderNbt); // Add display name and lore String placeholderItemTitleOverride = JdbcConfig.ITEM_PLACEHOLDER_TITLE_OVERRIDE.get(); placeholder.set(DataComponents.ITEM_NAME, @@ -441,23 +443,24 @@ public class VanillaSync { // Helper function to get the NBT string to be saved // If item is a placeholder, get original NBT; otherwise, get current NBT private static String getNbtForStorage(ItemStack itemStack) { - if (itemStack.is(Items.PAPER) && itemStack.getComponents().has(DataComponentTypes.ORIGINAL_ITEM_NBT.get())) { + if (itemStack.is(Items.PAPER) && itemStack.getComponents().has(DataComponents.CUSTOM_DATA) + && itemStack.getComponents().get(DataComponents.CUSTOM_DATA).contains("playersync:original_item_nbt")) { // It's our placeholder, retrieve the original NBT string - return itemStack.getComponents().get(DataComponentTypes.ORIGINAL_ITEM_NBT.get()); + return itemStack.getComponents().get(DataComponents.CUSTOM_DATA).copyTag().getString("playersync:original_item_nbt"); } else { // It's a normal item or empty, serialize its current NBT return serialize(serializeNBT(itemStack).toString()); } } - public static CompoundTag serializeNBT(ItemStack itemStack) { + public static Tag serializeNBT(ItemStack itemStack) { if (itemStack == null || itemStack.isEmpty()) { return new CompoundTag(); } // Serialize the ItemStack to NBT HolderLookup.Provider provider = ServerLifecycleHooks.getCurrentServer().registryAccess(); - CompoundTag compoundTag = new CompoundTag(); - itemStack.save(provider); + Tag compoundTag; + compoundTag = itemStack.save(provider); return compoundTag; } @@ -581,7 +584,7 @@ public class VanillaSync { static int tick = 0; @SubscribeEvent - public static void onUpdate(LevelTickEvent event) throws SQLException { + public static void onUpdate(LevelTickEvent.Post event) throws SQLException { tick++; if (tick == 1800) { tick = 0; diff --git a/src/main/templates/META-INF/mods.toml b/src/main/templates/META-INF/neoforge.mods.toml similarity index 88% rename from src/main/templates/META-INF/mods.toml rename to src/main/templates/META-INF/neoforge.mods.toml index b470b26..5049468 100644 --- a/src/main/templates/META-INF/mods.toml +++ b/src/main/templates/META-INF/neoforge.mods.toml @@ -1,9 +1,3 @@ -# This is an example mods.toml file. It contains the data relating to the loading mods. -# There are several mandatory fields (#mandatory), and many more that are optional (#optional). -# The overall format is standard TOML format, v0.5.0. -# Note that there are a couple of TOML lists in this file. -# Find more information on toml format here: https://github.com/toml-lang/toml -# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml modLoader="javafml" #mandatory # A version range to match for said mod loader - for regular FML @Mod it will be the FML version. This is currently 2.