diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 22c454d..1c03825 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -26,7 +26,7 @@ jobs: - uses: actions/setup-java@v4 with: - java-version: 21 + java-version: 25 distribution: 'microsoft' - name: Setup Gradle diff --git a/build.gradle b/build.gradle index 8c77adb..9e451f6 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id "fabric-loom" version "${loom_version}" + id "net.fabricmc.fabric-loom" version "${loom_version}" id "com.modrinth.minotaur" version "2.+" } @@ -56,16 +56,15 @@ loom { dependencies { // To change the versions see the gradle.properties file minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" - modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" + implementation "net.fabricmc:fabric-loader:${project.loader_version}" // Fabric API. This is technically optional, but you probably want it anyway. - modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}" + implementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}" // Uncomment the following line to enable the deprecated Fabric API modules. // These are included in the Fabric API production distribution and allow you to update your mod to the latest modules at a later more convenient time. - // modImplementation "net.fabricmc.fabric-api:fabric-api-deprecated:${project.fabric_version}" + // implementation "net.fabricmc.fabric-api:fabric-api-deprecated:${project.fabric_version}" } processResources { @@ -77,7 +76,7 @@ processResources { } tasks.withType(JavaCompile).configureEach { - it.options.release = 21 + it.options.release = 25 } java { @@ -86,8 +85,8 @@ java { // If you remove this line, sources will not be generated. withSourcesJar() - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_25 + sourceCompatibility = JavaVersion.VERSION_25 } jar { @@ -100,7 +99,7 @@ modrinth { token = System.getenv("MODRINTH_TOKEN") projectId = "scripts-chunk-loaders" versionType = "release" - uploadFile = remapJar + uploadFile = jar gameVersions = [project.minecraft_version] dependencies { required.project "fabric-api" diff --git a/gradle.properties b/gradle.properties index b3639f3..72a9457 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,9 +4,8 @@ org.gradle.parallel=true # Fabric Properties # check these on https://fabricmc.net/develop -minecraft_version=1.21.11 -yarn_mappings=1.21.11+build.4 -loader_version=0.18.4 +minecraft_version=26.1 +loader_version=0.18.6 loom_version=1.15-SNAPSHOT # Mod Properties @@ -15,4 +14,4 @@ maven_group=io.nihlen.scriptschunkloaders archives_base_name=scripts-chunk-loaders # Dependencies -fabric_api_version=0.141.3+1.21.11 \ No newline at end of file +fabric_api_version=0.145.1+26.1 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 1b33c55..d997cfc 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index dbc3ce4..c61a118 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 23d15a9..0262dcb 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -57,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/b631911858264c0b6e4d6603d677ff5218766cee/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -114,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH="\\\"\\\"" # Determine the Java command to use to start the JVM. @@ -172,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -212,7 +210,6 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" diff --git a/gradlew.bat b/gradlew.bat index 5eed7ee..e509b2d 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -70,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH= @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/src/gametest/java/io/nihlen/scriptschunkloaders/ScriptsChunkLoadersGameTest.java b/src/gametest/java/io/nihlen/scriptschunkloaders/ScriptsChunkLoadersGameTest.java index 819b992..465f9af 100644 --- a/src/gametest/java/io/nihlen/scriptschunkloaders/ScriptsChunkLoadersGameTest.java +++ b/src/gametest/java/io/nihlen/scriptschunkloaders/ScriptsChunkLoadersGameTest.java @@ -2,14 +2,14 @@ import net.fabricmc.fabric.api.gametest.v1.GameTest; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityType; -import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; -import net.minecraft.test.TestContext; -import net.minecraft.text.Text; -import net.minecraft.util.math.BlockPos; +import net.minecraft.core.component.DataComponents; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.network.chat.Component; +import net.minecraft.core.BlockPos; import java.util.Objects; import java.util.function.Function; @@ -54,7 +54,7 @@ public class ScriptsChunkLoadersGameTest { private ItemStack createNamedItem() { ItemStack item = new ItemStack(Items.PAPER); - item.set(DataComponentTypes.CUSTOM_NAME, Text.literal(customItemName)); + item.set(DataComponents.CUSTOM_NAME, Component.literal(customItemName)); return item; } @@ -62,109 +62,109 @@ private ItemStack createUnnamedItem() { return new ItemStack(Items.EMERALD); } - private void clearTest(TestContext context) { + private void clearTest(GameTestHelper context) { context.killAllEntities(); } @GameTest(structure = "scl_tests:basic") - public void registersWithDefaultName_minecart(TestContext context) { + public void registersWithDefaultName_minecart(GameTestHelper context) { clearTest(context); - context.spawnEntity(EntityType.MINECART, 2, 1, 2); - context.putAndRemoveRedstoneBlock(new BlockPos(1, 1, 1), 1); - context.waitAndRun(4, () -> { - context.expectEntityWithData( + context.spawn(EntityType.MINECART, 2, 1, 2); + context.pulseRedstone(new BlockPos(1, 1, 1), 1); + context.runAfterDelay(4, () -> { + context.assertEntityData( new BlockPos(2, 1, 2), EntityType.MINECART, getCustomName, defaultName ); - context.complete(); + context.succeed(); }); } @GameTest(structure = "scl_tests:basic") - public void registersWithDefaultName_hopperMinecart(TestContext context) { + public void registersWithDefaultName_hopperMinecart(GameTestHelper context) { clearTest(context); - context.spawnEntity(EntityType.HOPPER_MINECART, 2, 1, 2); - context.putAndRemoveRedstoneBlock(new BlockPos(1, 1, 1), 1); - context.waitAndRun(4, () -> { - context.expectEntityWithData( + context.spawn(EntityType.HOPPER_MINECART, 2, 1, 2); + context.pulseRedstone(new BlockPos(1, 1, 1), 1); + context.runAfterDelay(4, () -> { + context.assertEntityData( new BlockPos(2, 1, 2), EntityType.HOPPER_MINECART, getCustomName, defaultName ); - context.complete(); + context.succeed(); }); } @GameTest(structure = "scl_tests:basic") - public void registersWithDefaultName_chestMinecart(TestContext context) { + public void registersWithDefaultName_chestMinecart(GameTestHelper context) { clearTest(context); - context.spawnEntity(EntityType.CHEST_MINECART, 2, 1, 2); - context.putAndRemoveRedstoneBlock(new BlockPos(1, 1, 1), 1); - context.waitAndRun(4, () -> { - context.expectEntityWithData( + context.spawn(EntityType.CHEST_MINECART, 2, 1, 2); + context.pulseRedstone(new BlockPos(1, 1, 1), 1); + context.runAfterDelay(4, () -> { + context.assertEntityData( new BlockPos(2, 1, 2), EntityType.CHEST_MINECART, getCustomName, defaultName ); - context.complete(); + context.succeed(); }); } @GameTest(structure = "scl_tests:basic") - public void registersWithDefaultName_furnaceMinecart(TestContext context) { + public void registersWithDefaultName_furnaceMinecart(GameTestHelper context) { clearTest(context); - context.spawnEntity(EntityType.FURNACE_MINECART, 2, 1, 2); - context.putAndRemoveRedstoneBlock(new BlockPos(1, 1, 1), 1); - context.waitAndRun(4, () -> { - context.expectEntityWithData( + context.spawn(EntityType.FURNACE_MINECART, 2, 1, 2); + context.pulseRedstone(new BlockPos(1, 1, 1), 1); + context.runAfterDelay(4, () -> { + context.assertEntityData( new BlockPos(2, 1, 2), EntityType.FURNACE_MINECART, getCustomName, defaultName ); - context.complete(); + context.succeed(); }); } @GameTest(structure = "scl_tests:basic") - public void registersWithDefaultName_tntMinecart(TestContext context) { + public void registersWithDefaultName_tntMinecart(GameTestHelper context) { clearTest(context); - context.spawnEntity(EntityType.TNT_MINECART, 2, 1, 2); - context.putAndRemoveRedstoneBlock(new BlockPos(1, 1, 1), 1); - context.waitAndRun(4, () -> { - context.expectEntityWithData( + context.spawn(EntityType.TNT_MINECART, 2, 1, 2); + context.pulseRedstone(new BlockPos(1, 1, 1), 1); + context.runAfterDelay(4, () -> { + context.assertEntityData( new BlockPos(2, 1, 2), EntityType.TNT_MINECART, getCustomName, defaultName ); - context.complete(); + context.succeed(); }); } @GameTest(structure = "scl_tests:basic") - public void registersWithDefaultName_commandBlockMinecart(TestContext context) { + public void registersWithDefaultName_commandBlockMinecart(GameTestHelper context) { clearTest(context); - context.spawnEntity(EntityType.COMMAND_BLOCK_MINECART, 2, 1, 2); - context.putAndRemoveRedstoneBlock(new BlockPos(1, 1, 1), 1); - context.waitAndRun(4, () -> { - context.expectEntityWithData( + context.spawn(EntityType.COMMAND_BLOCK_MINECART, 2, 1, 2); + context.pulseRedstone(new BlockPos(1, 1, 1), 1); + context.runAfterDelay(4, () -> { + context.assertEntityData( new BlockPos(2, 1, 2), EntityType.COMMAND_BLOCK_MINECART, getCustomName, defaultName ); - context.complete(); + context.succeed(); }); } @@ -190,121 +190,121 @@ public void registersWithDefaultName_commandBlockMinecart(TestContext context) { // } @GameTest(structure = "scl_tests:basic") - public void registersWithFirstItemName_chestMinecart(TestContext context) { + public void registersWithFirstItemName_chestMinecart(GameTestHelper context) { clearTest(context); context.killAllEntities(); - var entity = context.spawnEntity(EntityType.CHEST_MINECART, 2, 1, 2); - entity.setInventoryStack(0, createNamedItem()); + var entity = context.spawn(EntityType.CHEST_MINECART, 2, 1, 2); + entity.setChestVehicleItem(0, createNamedItem()); - context.putAndRemoveRedstoneBlock(new BlockPos(1, 1, 1), 1); - context.waitAndRun(4, () -> { - context.expectEntityWithData( + context.pulseRedstone(new BlockPos(1, 1, 1), 1); + context.runAfterDelay(4, () -> { + context.assertEntityData( new BlockPos(2, 1, 2), EntityType.CHEST_MINECART, getCustomName, customItemName ); - context.complete(); + context.succeed(); }); } @GameTest(structure = "scl_tests:basic") - public void registersWithDefaultNameOtherSlot_hopperMinecart(TestContext context) { + public void registersWithDefaultNameOtherSlot_hopperMinecart(GameTestHelper context) { clearTest(context); context.killAllEntities(); - var entity = context.spawnEntity(EntityType.HOPPER_MINECART, 2, 1, 2); - entity.setInventoryStack(1, createNamedItem()); + var entity = context.spawn(EntityType.HOPPER_MINECART, 2, 1, 2); + entity.setChestVehicleItem(1, createNamedItem()); - context.putAndRemoveRedstoneBlock(new BlockPos(1, 1, 1), 1); - context.waitAndRun(4, () -> { - context.expectEntityWithData( + context.pulseRedstone(new BlockPos(1, 1, 1), 1); + context.runAfterDelay(4, () -> { + context.assertEntityData( new BlockPos(2, 1, 2), EntityType.HOPPER_MINECART, getCustomName, defaultName ); - context.complete(); + context.succeed(); }); } @GameTest(structure = "scl_tests:basic") - public void registersWithDefaultNameOtherSlot_chestMinecart(TestContext context) { + public void registersWithDefaultNameOtherSlot_chestMinecart(GameTestHelper context) { clearTest(context); context.killAllEntities(); - var entity = context.spawnEntity(EntityType.CHEST_MINECART, 2, 1, 2); - entity.setInventoryStack(1, createNamedItem()); + var entity = context.spawn(EntityType.CHEST_MINECART, 2, 1, 2); + entity.setChestVehicleItem(1, createNamedItem()); - context.putAndRemoveRedstoneBlock(new BlockPos(1, 1, 1), 1); - context.waitAndRun(4, () -> { - context.expectEntityWithData( + context.pulseRedstone(new BlockPos(1, 1, 1), 1); + context.runAfterDelay(4, () -> { + context.assertEntityData( new BlockPos(2, 1, 2), EntityType.CHEST_MINECART, getCustomName, defaultName ); - context.complete(); + context.succeed(); }); } @GameTest(structure = "scl_tests:basic") - public void registersWithDefaultNameUnnamedItem_hopperMinecart(TestContext context) { + public void registersWithDefaultNameUnnamedItem_hopperMinecart(GameTestHelper context) { clearTest(context); context.killAllEntities(); - var entity = context.spawnEntity(EntityType.HOPPER_MINECART, 2, 1, 2); - entity.setInventoryStack(0, createUnnamedItem()); + var entity = context.spawn(EntityType.HOPPER_MINECART, 2, 1, 2); + entity.setChestVehicleItem(0, createUnnamedItem()); - context.putAndRemoveRedstoneBlock(new BlockPos(1, 1, 1), 1); - context.waitAndRun(4, () -> { - context.expectEntityWithData( + context.pulseRedstone(new BlockPos(1, 1, 1), 1); + context.runAfterDelay(4, () -> { + context.assertEntityData( new BlockPos(2, 1, 2), EntityType.HOPPER_MINECART, getCustomName, defaultName ); - context.complete(); + context.succeed(); }); } @GameTest(structure = "scl_tests:basic") - public void registersWithDefaultNameUnnamedItem_chestMinecart(TestContext context) { + public void registersWithDefaultNameUnnamedItem_chestMinecart(GameTestHelper context) { clearTest(context); context.killAllEntities(); - var entity = context.spawnEntity(EntityType.CHEST_MINECART, 2, 1, 2); - entity.setInventoryStack(0, createUnnamedItem()); + var entity = context.spawn(EntityType.CHEST_MINECART, 2, 1, 2); + entity.setChestVehicleItem(0, createUnnamedItem()); - context.putAndRemoveRedstoneBlock(new BlockPos(1, 1, 1), 1); - context.waitAndRun(4, () -> { - context.expectEntityWithData( + context.pulseRedstone(new BlockPos(1, 1, 1), 1); + context.runAfterDelay(4, () -> { + context.assertEntityData( new BlockPos(2, 1, 2), EntityType.CHEST_MINECART, getCustomName, defaultName ); - context.complete(); + context.succeed(); }); } @GameTest(structure = "scl_tests:basic") - public void registers_and_unregisters(TestContext context) { + public void registers_and_unregisters(GameTestHelper context) { clearTest(context); - context.spawnEntity(EntityType.MINECART, 2, 1, 2); - context.putAndRemoveRedstoneBlock(new BlockPos(1, 1, 1), 1); + context.spawn(EntityType.MINECART, 2, 1, 2); + context.pulseRedstone(new BlockPos(1, 1, 1), 1); - context.waitAndRun(4, () -> { - context.expectEntityWithData(new BlockPos(2, 1, 2), EntityType.MINECART, getCustomName, defaultName); + context.runAfterDelay(4, () -> { + context.assertEntityData(new BlockPos(2, 1, 2), EntityType.MINECART, getCustomName, defaultName); - context.waitAndRun(4, () -> { - context.putAndRemoveRedstoneBlock(new BlockPos(1, 1, 1), 1); + context.runAfterDelay(4, () -> { + context.pulseRedstone(new BlockPos(1, 1, 1), 1); - context.waitAndRun(4, () -> { - context.expectEntityWithData(new BlockPos(2, 1, 2), EntityType.MINECART, getCustomName, null); - context.complete(); + context.runAfterDelay(4, () -> { + context.assertEntityData(new BlockPos(2, 1, 2), EntityType.MINECART, getCustomName, null); + context.succeed(); }); }); }); @@ -314,41 +314,41 @@ public void registers_and_unregisters(TestContext context) { * Covers #34 */ @GameTest(structure = "scl_tests:basic") - public void registers_unregisters_and_registers(TestContext context) { + public void registers_unregisters_and_registers(GameTestHelper context) { clearTest(context); - context.spawnEntity(EntityType.MINECART, 2, 1, 2); - context.putAndRemoveRedstoneBlock(new BlockPos(1, 1, 1), 1); - context.waitAndRun(4, () -> { - context.expectEntityWithData(new BlockPos(2, 1, 2), EntityType.MINECART, getCustomName, defaultName); - context.putAndRemoveRedstoneBlock(new BlockPos(1, 1, 1), 1); + context.spawn(EntityType.MINECART, 2, 1, 2); + context.pulseRedstone(new BlockPos(1, 1, 1), 1); + context.runAfterDelay(4, () -> { + context.assertEntityData(new BlockPos(2, 1, 2), EntityType.MINECART, getCustomName, defaultName); + context.pulseRedstone(new BlockPos(1, 1, 1), 1); - context.waitAndRun(4, () -> { - context.expectEntityWithData(new BlockPos(2, 1, 2), EntityType.MINECART, getCustomName, null); - context.putAndRemoveRedstoneBlock(new BlockPos(1, 1, 1), 1); + context.runAfterDelay(4, () -> { + context.assertEntityData(new BlockPos(2, 1, 2), EntityType.MINECART, getCustomName, null); + context.pulseRedstone(new BlockPos(1, 1, 1), 1); - context.waitAndRun(4, () -> { - context.expectEntityWithData(new BlockPos(2, 1, 2), EntityType.MINECART, getCustomName, defaultName); - context.complete(); + context.runAfterDelay(4, () -> { + context.assertEntityData(new BlockPos(2, 1, 2), EntityType.MINECART, getCustomName, defaultName); + context.succeed(); }); }); }); } @GameTest(structure = "scl_tests:empty") - public void doesNotRegisterWithEmptyDispenser(TestContext context) { + public void doesNotRegisterWithEmptyDispenser(GameTestHelper context) { clearTest(context); - context.spawnEntity(EntityType.MINECART, 2, 1, 2); - context.putAndRemoveRedstoneBlock(new BlockPos(1, 1, 1), 1); - context.waitAndRun(4, () -> { - context.expectEntityWithData( + context.spawn(EntityType.MINECART, 2, 1, 2); + context.pulseRedstone(new BlockPos(1, 1, 1), 1); + context.runAfterDelay(4, () -> { + context.assertEntityData( new BlockPos(2, 1, 2), EntityType.MINECART, getCustomName, null ); - context.complete(); + context.succeed(); }); } } \ No newline at end of file diff --git a/src/main/java/io/nihlen/scriptschunkloaders/ChunkLoaderManager.java b/src/main/java/io/nihlen/scriptschunkloaders/ChunkLoaderManager.java index 229f5c6..5adcd45 100644 --- a/src/main/java/io/nihlen/scriptschunkloaders/ChunkLoaderManager.java +++ b/src/main/java/io/nihlen/scriptschunkloaders/ChunkLoaderManager.java @@ -2,12 +2,12 @@ import it.unimi.dsi.fastutil.longs.LongSet; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; -import net.minecraft.entity.Entity; -import net.minecraft.registry.RegistryKey; +import net.minecraft.world.entity.Entity; +import net.minecraft.resources.ResourceKey; import net.minecraft.server.MinecraftServer; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.math.ChunkPos; -import net.minecraft.world.World; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.Level; import java.util.*; @@ -17,7 +17,7 @@ public class ChunkLoaderManager { private boolean initialized = false; private final Set pendingRegistrations = new HashSet<>(); - public HashMap, HashMap>> forceLoadedChunks = new HashMap<>(); + public HashMap, HashMap>> forceLoadedChunks = new HashMap<>(); public void initialize(MinecraftServer _server) { server = _server; @@ -41,22 +41,22 @@ public void registerChunkLoader(Entity entity) { return; } - var chunkPos = entity.getChunkPos(); + var chunkPos = entity.chunkPosition(); removeChunkLoader(entity); - ScriptsChunkLoadersMod.LOGGER.info("Adding {} to {}", entity, entity.getEntityWorld().getRegistryKey().getValue()); + ScriptsChunkLoadersMod.LOGGER.info("Adding {} to {}", entity, entity.level().dimension().identifier()); - var worldRegistryKey = entity.getEntityWorld().getRegistryKey(); + var worldRegistryKey = entity.level().dimension(); var worldChunks = forceLoadedChunks.computeIfAbsent(worldRegistryKey, s -> new HashMap<>()); - var list = worldChunks.computeIfAbsent(chunkPos.toLong(), s -> new ArrayList<>()); - list.add(entity.getUuid()); + var list = worldChunks.computeIfAbsent(chunkPos.pack(), s -> new ArrayList<>()); + list.add(entity.getUUID()); } public void removeChunkLoader(Entity entity) { - ScriptsChunkLoadersMod.LOGGER.info("Removing {} from {}", entity, entity.getEntityWorld().getRegistryKey().getValue()); - var uuid = entity.getUuid(); + ScriptsChunkLoadersMod.LOGGER.info("Removing {} from {}", entity, entity.level().dimension().identifier()); + var uuid = entity.getUUID(); - var worldRegistryKey = entity.getEntityWorld().getRegistryKey(); + var worldRegistryKey = entity.level().dimension(); var worldChunks = forceLoadedChunks.get(worldRegistryKey); ScriptsChunkLoadersMod.LOGGER.info("worldChunks {}", worldChunks); @@ -75,8 +75,8 @@ public void removeChunkLoader(Entity entity) { } private void setupTimer() { - ServerTickEvents.END_WORLD_TICK.register((world) -> { - var time = world.getTime(); + ServerTickEvents.END_LEVEL_TICK.register((world) -> { + var time = world.getGameTime(); if (time != lastTick && time % 20 == 0) { lastTick = time; updateWorlds(); @@ -86,45 +86,45 @@ private void setupTimer() { private void updateWorlds() { forceLoadedChunks.keySet().forEach(worldRegistryKey -> { - ServerWorld world = server.getWorld(worldRegistryKey); + ServerLevel world = server.getLevel(worldRegistryKey); updateChunkLoaders(world); }); } - private void updateChunkLoaders(ServerWorld world) { + private void updateChunkLoaders(ServerLevel world) { var currentChunks = calculateLoadedChunks(world); // TODO: This can probably be optimized. We're looping over the same range twice since there usually is an // overlap between the current chunks and the loaded chunks. - final LongSet loadedChunks = world.getForcedChunks(); + final LongSet loadedChunks = world.getForceLoadedChunks(); currentChunks.forEach(chunkPos -> { - long longPos = chunkPos.toLong(); + long longPos = chunkPos.pack(); if (!loadedChunks.contains(longPos)) { // Load chunk - world.setChunkForced(chunkPos.x, chunkPos.z, true); + world.setChunkForced(chunkPos.x(), chunkPos.z(), true); } }); loadedChunks.forEach(longPos -> { - var chunkPos = new ChunkPos(longPos); + var chunkPos = ChunkPos.unpack(longPos); if (!currentChunks.contains(chunkPos)) { // Unload chunk - world.setChunkForced(chunkPos.x, chunkPos.z, false); + world.setChunkForced(chunkPos.x(), chunkPos.z(), false); } }); } - private Set calculateLoadedChunks (ServerWorld world) { + private Set calculateLoadedChunks (ServerLevel world) { Set chunks = new HashSet<>(); - var worldChunks = forceLoadedChunks.get(world.getRegistryKey()); + var worldChunks = forceLoadedChunks.get(world.dimension()); if (worldChunks != null) { worldChunks.keySet().forEach(chunkPosLong -> { - var chunkPos = new ChunkPos(chunkPosLong); + var chunkPos = ChunkPos.unpack(chunkPosLong); var surroundingChunks = buildChunkSquare(chunkPos); chunks.addAll(Arrays.asList(surroundingChunks)); }); @@ -139,7 +139,7 @@ private ChunkPos[] buildChunkSquare(ChunkPos chunkPos) { for (int i = 0; i < 9; i++) { var xOffset = i % 3 - 1; var zOffset = i / 3 - 1; - chunks[i] = new ChunkPos(chunkPos.x + xOffset, chunkPos.z + zOffset); + chunks[i] = new ChunkPos(chunkPos.x() + xOffset, chunkPos.z() + zOffset); } return chunks; diff --git a/src/main/java/io/nihlen/scriptschunkloaders/mixin/AbstractMinecartEntityMixin.java b/src/main/java/io/nihlen/scriptschunkloaders/mixin/AbstractMinecartMixin.java similarity index 59% rename from src/main/java/io/nihlen/scriptschunkloaders/mixin/AbstractMinecartEntityMixin.java rename to src/main/java/io/nihlen/scriptschunkloaders/mixin/AbstractMinecartMixin.java index f45110a..2c2ceb5 100644 --- a/src/main/java/io/nihlen/scriptschunkloaders/mixin/AbstractMinecartEntityMixin.java +++ b/src/main/java/io/nihlen/scriptschunkloaders/mixin/AbstractMinecartMixin.java @@ -1,10 +1,12 @@ package io.nihlen.scriptschunkloaders.mixin; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.entity.vehicle.*; -import net.minecraft.storage.ReadView; -import net.minecraft.storage.WriteView; -import net.minecraft.world.TeleportTarget; +import net.minecraft.core.component.DataComponents; +//import net.minecraft.entity.vehicle.*; +import net.minecraft.world.entity.vehicle.minecart.AbstractMinecart; +import net.minecraft.world.entity.vehicle.minecart.MinecartChest; +import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.level.storage.ValueOutput; +import net.minecraft.world.level.portal.TeleportTransition; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; @@ -14,17 +16,17 @@ import io.nihlen.scriptschunkloaders.ScriptsChunkLoadersMod; import io.nihlen.scriptschunkloaders.MinecartEntityExt; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityType; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.particle.ParticleTypes; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.text.Text; -import net.minecraft.util.math.ChunkPos; -import net.minecraft.world.World; - -@Mixin(AbstractMinecartEntity.class) -public abstract class AbstractMinecartEntityMixin extends Entity implements MinecartEntityExt { +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.network.chat.Component; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.Level; + +@Mixin(AbstractMinecart.class) +public abstract class AbstractMinecartMixin extends Entity implements MinecartEntityExt { @Unique private boolean isChunkLoader = false; @@ -35,11 +37,11 @@ public abstract class AbstractMinecartEntityMixin extends Entity implements Mine @Unique private ChunkPos lastChunkPos = null; - public AbstractMinecartEntityMixin(EntityType type, World world) { + public AbstractMinecartMixin(EntityType type, Level world) { super(type, world); } - @Inject(method = "(Lnet/minecraft/entity/EntityType;Lnet/minecraft/world/World;DDD)V", at = @At("TAIL")) + @Inject(method = "(Lnet/minecraft/world/entity/EntityType;Lnet/minecraft/world/level/Level;DDD)V", at = @At("TAIL")) private void injectConstructor(CallbackInfo callbackInfo) { if (isChunkLoader) { scripts_chunk_loaders$startChunkLoader(); @@ -51,11 +53,11 @@ private void injectConstructor(CallbackInfo callbackInfo) { } public void scripts_chunk_loaders$startChunkLoader() { - if (this.getEntityWorld().isClient()) return; + if (this.level().isClientSide()) return; this.isChunkLoader = true; - ScriptsChunkLoadersMod.LOGGER.info("Starting chunk loader in {}", this.getEntityWorld().getRegistryKey().getValue()); + ScriptsChunkLoadersMod.LOGGER.info("Starting chunk loader in {}", this.level().dimension().identifier()); } public void scripts_chunk_loaders$setChunkLoaderNameFromInventory() { @@ -63,13 +65,13 @@ private void injectConstructor(CallbackInfo callbackInfo) { if (minecartType == EntityType.CHEST_MINECART) { //noinspection DataFlowIssue - We're sure this is a chest because of the if statement. - var entity = (ChestMinecartEntity)(Object)this; - var firstSlot = entity.getInventory().get(0); + var entity = (MinecartChest)(Object)this; + var firstSlot = entity.getItemStacks().get(0); - var hasCustomName = firstSlot.get(DataComponentTypes.CUSTOM_NAME) != null; + var hasCustomName = firstSlot.get(DataComponents.CUSTOM_NAME) != null; if (!firstSlot.isEmpty() && hasCustomName) { - var name = firstSlot.getName().getString(); + var name = firstSlot.getHoverName().getString(); scripts_chunk_loaders$setChunkLoaderName(name); return; } @@ -79,7 +81,7 @@ private void injectConstructor(CallbackInfo callbackInfo) { } public void scripts_chunk_loaders$setChunkLoaderName(String name) { - var nameText = Text.literal(name); + var nameText = Component.literal(name); this.setCustomName(nameText); this.setCustomNameVisible(true); } @@ -100,21 +102,21 @@ private void injectConstructor(CallbackInfo callbackInfo) { } } - @Inject(method = "writeCustomData", at = @At("RETURN")) - public void writeCustomData(WriteView view, CallbackInfo ci) { + @Inject(method = "addAdditionalSaveData", at = @At("RETURN")) + public void writeCustomData(ValueOutput view, CallbackInfo ci) { view.putBoolean("chunkLoader", this.isChunkLoader); } - @Inject(method = "readCustomData", at = @At("RETURN")) - public void readCustomData(ReadView view, CallbackInfo ci) { - this.isChunkLoader = view.getBoolean("chunkLoader", false); + @Inject(method = "readAdditionalSaveData", at = @At("RETURN")) + public void readCustomData(ValueInput view, CallbackInfo ci) { + this.isChunkLoader = view.getBooleanOr("chunkLoader", false); } @Inject(method = "tick", at = @At("TAIL")) public void tick(CallbackInfo ci) { if (!isChunkLoader) return; - var chunkPos = this.getChunkPos(); + var chunkPos = this.chunkPosition(); if (lastChunkPos == null || lastChunkPos != chunkPos) { lastChunkPos = chunkPos; ScriptsChunkLoadersMod.LOGGER.info("Re-registering chunk loader"); @@ -134,15 +136,15 @@ public void remove(Entity.RemovalReason reason) { } @Override - public Entity teleportTo(TeleportTarget teleportTarget) { + public Entity teleport(TeleportTransition teleportTarget) { var wasChunkLoader = isChunkLoader; if (wasChunkLoader) this.scripts_chunk_loaders$stopChunkLoader(true); - var newEntity = super.teleportTo(teleportTarget); + var newEntity = super.teleport(teleportTarget); if (wasChunkLoader && newEntity != null) - ((AbstractMinecartEntityMixin)newEntity).scripts_chunk_loaders$startChunkLoader(); + ((AbstractMinecartMixin)newEntity).scripts_chunk_loaders$startChunkLoader(); return newEntity; } @@ -158,8 +160,8 @@ private void tickParticles() { @Unique private void spawnParticles() { - AbstractMinecartEntity entity = (AbstractMinecartEntity)(Object)this; - ServerWorld world = (ServerWorld)entity.getEntityWorld(); - world.spawnParticles(ParticleTypes.HAPPY_VILLAGER, entity.getX(), entity.getY(), entity.getZ(), 1, 0.25, 0.25, 0.25, 0.15f); + AbstractMinecart entity = (AbstractMinecart)(Object)this; + ServerLevel world = (ServerLevel)entity.level(); + world.sendParticles(ParticleTypes.HAPPY_VILLAGER, entity.getX(), entity.getY(), entity.getZ(), 1, 0.25, 0.25, 0.25, 0.15f); } } diff --git a/src/main/java/io/nihlen/scriptschunkloaders/mixin/DispenserBlockMixin.java b/src/main/java/io/nihlen/scriptschunkloaders/mixin/DispenserBlockMixin.java index c3169c4..9e4f678 100644 --- a/src/main/java/io/nihlen/scriptschunkloaders/mixin/DispenserBlockMixin.java +++ b/src/main/java/io/nihlen/scriptschunkloaders/mixin/DispenserBlockMixin.java @@ -1,18 +1,18 @@ package io.nihlen.scriptschunkloaders.mixin; import io.nihlen.scriptschunkloaders.MinecartEntityExt; -import net.minecraft.block.BlockState; -import net.minecraft.block.DispenserBlock; -import net.minecraft.block.entity.BlockEntityType; -import net.minecraft.block.entity.DispenserBlockEntity; -import net.minecraft.entity.vehicle.AbstractMinecartEntity; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; -import net.minecraft.predicate.entity.EntityPredicates; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Box; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.DispenserBlock; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.entity.DispenserBlockEntity; +import net.minecraft.world.entity.vehicle.minecart.AbstractMinecart; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.entity.EntitySelector; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.core.BlockPos; +import net.minecraft.world.phys.AABB; import org.slf4j.Logger; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -30,12 +30,12 @@ public class DispenserBlockMixin { @Inject( at = @At("HEAD"), - method = "dispense(Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;)V", + method = "dispenseFrom(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;)V", cancellable = true ) - private void dispense(ServerWorld world, BlockState state, BlockPos pos, CallbackInfo info) { - if (world.isClient()) return; + private void dispense(ServerLevel world, BlockState state, BlockPos pos, CallbackInfo info) { + if (world.isClientSide()) return; DispenserBlockEntity dispenserBlockEntity = world.getBlockEntity(pos, BlockEntityType.DISPENSER).orElse(null); if (dispenserBlockEntity == null) return; @@ -85,8 +85,8 @@ private Item[] getPattern(Item centerItem) { @Unique private boolean patternMatches(DispenserBlockEntity dispenserBlockEntity, Item[] pattern) { for (int i = 0; i < 9; i++) { - ItemStack itemStack = dispenserBlockEntity.getStack(i); - if (!itemStack.isOf(pattern[i])) { + ItemStack itemStack = dispenserBlockEntity.getItem(i); + if (!itemStack.is(pattern[i])) { return false; } } @@ -95,11 +95,11 @@ private boolean patternMatches(DispenserBlockEntity dispenserBlockEntity, Item[] } @Unique - private void applyChunkLoaderAction(ServerWorld world, BlockState state, BlockPos pos, String action) { - BlockPos blockPos = pos.offset(state.get(DispenserBlock.FACING)); - List list = world.getEntitiesByClass(AbstractMinecartEntity.class, new Box(blockPos), EntityPredicates.VALID_ENTITY); + private void applyChunkLoaderAction(ServerLevel world, BlockState state, BlockPos pos, String action) { + BlockPos blockPos = pos.relative(state.getValue(DispenserBlock.FACING)); + List list = world.getEntitiesOfClass(AbstractMinecart.class, new AABB(blockPos), EntitySelector.ENTITY_STILL_ALIVE); - for (AbstractMinecartEntity entity : list) { + for (AbstractMinecart entity : list) { MinecartEntityExt cart = (MinecartEntityExt)entity; switch (action) { diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 317d277..e6b5a35 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -23,9 +23,9 @@ "scripts-chunk-loaders.mixins.json" ], "depends": { - "fabricloader": ">=0.18.4", - "minecraft": "1.21.11", - "java": ">=21", + "fabricloader": ">=0.18.6", + "minecraft": "26.1", + "java": ">=25", "fabric-api": "*" } } diff --git a/src/main/resources/scripts-chunk-loaders.mixins.json b/src/main/resources/scripts-chunk-loaders.mixins.json index 56d2bf9..b299036 100644 --- a/src/main/resources/scripts-chunk-loaders.mixins.json +++ b/src/main/resources/scripts-chunk-loaders.mixins.json @@ -2,16 +2,16 @@ "required": true, "minVersion": "0.8", "package": "io.nihlen.scriptschunkloaders.mixin", - "compatibilityLevel": "JAVA_21", + "compatibilityLevel": "JAVA_25", "mixins": [ ], "client": [ "DispenserBlockMixin", - "AbstractMinecartEntityMixin" + "AbstractMinecartMixin" ], "server": [ "DispenserBlockMixin", - "AbstractMinecartEntityMixin" + "AbstractMinecartMixin" ], "injectors": { "defaultRequire": 1