diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b01da52..6f7c668 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,7 +4,26 @@ # against bad commits. name: build -on: [pull_request, push] + +on: + pull_request: + paths: &build_paths + - '.github/workflows/build.yml' + - 'build.gradle' + - 'gradle.properties' + - 'gradle/**' + - 'gradlew' + - 'gradlew.bat' + - 'settings.gradle' + - 'src/**' + + push: + branches: [main] + paths: *build_paths + +concurrency: + group: "java-build-${{ github.ref }}" + cancel-in-progress: true jobs: build: @@ -12,9 +31,9 @@ jobs: matrix: # Use these Java versions java: [ - 21, # Current Java LTS + 25, # Current Java LTS ] - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest steps: - name: checkout repository uses: actions/checkout@v4 @@ -30,8 +49,8 @@ jobs: - name: build run: ./gradlew build - name: capture build artifacts - if: ${{ matrix.java == '21' }} # Only upload artifacts built from latest java + if: ${{ matrix.java == '25' }} # Only upload artefacts built from latest java uses: actions/upload-artifact@v4 with: name: Artifacts - path: build/libs/ \ No newline at end of file + path: build/libs/ diff --git a/build.gradle b/build.gradle index a86e80a..253bd8a 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 'maven-publish' } @@ -21,11 +21,10 @@ repositories { 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_version}" + implementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}" } @@ -38,7 +37,7 @@ processResources { } tasks.withType(JavaCompile).configureEach { - it.options.release = 21 + it.options.release = 25 } java { @@ -47,8 +46,8 @@ java { // If you remove this line, sources will not be generated. withSourcesJar() - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 + sourceCompatibility = JavaVersion.VERSION_25 + targetCompatibility = JavaVersion.VERSION_25 } jar { @@ -75,4 +74,4 @@ publishing { // The repositories here will be used for publishing your artifact, not for // retrieving dependencies. } -} \ No newline at end of file +} diff --git a/gradle.properties b/gradle.properties index 114e481..5787095 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,15 +4,14 @@ org.gradle.parallel=true # Fabric Properties # check these on https://fabricmc.net/develop -minecraft_version=1.21.11 -yarn_mappings=1.21.11+build.3 +minecraft_version=26.1-snapshot-3 loader_version=0.18.4 loom_version=1.14-SNAPSHOT # Mod Properties -mod_version=1.0.4+1.21.11 +mod_version=1.0.5-beta+26.1-snapshots maven_group=me.imgalvin.playerfinder archives_base_name=player-finder # Dependencies -fabric_version=0.140.2+1.21.11 \ No newline at end of file +fabric_api_version=0.142.0+26.1 diff --git a/src/main/java/me/imgalvin/playerfinder/PlayerFinder.java b/src/main/java/me/imgalvin/playerfinder/PlayerFinder.java index 61b9f19..20d8dad 100644 --- a/src/main/java/me/imgalvin/playerfinder/PlayerFinder.java +++ b/src/main/java/me/imgalvin/playerfinder/PlayerFinder.java @@ -1,55 +1,78 @@ package me.imgalvin.playerfinder; -import com.mojang.brigadier.arguments.StringArgumentType; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.registry.RegistryKey; -import net.minecraft.server.command.CommandManager; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; +import net.minecraft.ChatFormatting; +import net.minecraft.commands.Commands; +import net.minecraft.commands.arguments.EntityArgument; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.level.Level; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class PlayerFinder implements ModInitializer { PlayerFinderUtils utils = new PlayerFinderUtils(); + public static final Logger LOGGER = LoggerFactory.getLogger("PlayerFinder"); + @Override public void onInitialize() { - CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { - dispatcher.register(CommandManager.literal("findplayer") - .then(CommandManager.argument("player", StringArgumentType.string()) - .suggests(new PlayerSuggestionProvider()) - .executes(context -> { - String playerName = StringArgumentType.getString(context, "player"); - PlayerEntity targetPlayer = context.getSource().getServer().getPlayerManager().getPlayer(playerName); - PlayerEntity sourcePlayer = context.getSource().getPlayer(); - - assert targetPlayer != null; - assert sourcePlayer != null; - - BlockPos targetBlockPos = targetPlayer.getBlockPos(); - BlockPos sourceBlockPos = sourcePlayer.getBlockPos(); - RegistryKey playerDimension = targetPlayer.getEntityWorld().getRegistryKey(); - RegistryKey sourceDimension = sourcePlayer.getEntityWorld().getRegistryKey(); - - boolean isSameDimension = sourceDimension == playerDimension; - - context.getSource().sendFeedback(() -> (Text) Text.literal(playerName + " is at ") - .append(Text.literal(targetBlockPos.getX() + ", " + targetBlockPos.getY() + ", " + targetBlockPos.getZ()) - .formatted(utils.getDimensionColor(playerDimension))) - .append(Text.literal(" in the ") - .formatted(Formatting.WHITE)) - .append(Text.literal(utils.getDimensionText(playerDimension)) - .formatted(utils.getDimensionColor(playerDimension))) - .append(Text.literal(isSameDimension - ? " (" + utils.getDistance(sourceBlockPos, targetBlockPos) + " blocks away)" - : " (Player is in a different dimension)") - .formatted(isSameDimension ? Formatting.GREEN : Formatting.RED)), false); - return 1; - }) - ) - ); - }); + LOGGER.info("PlayerFinder initialized!"); + // _ previously registryAccess, environment + CommandRegistrationCallback.EVENT.register((dispatcher, _, _) -> dispatcher.register(Commands.literal("findplayer") + .then(Commands.argument("player", EntityArgument.player()) + .executes(context -> { + LOGGER.info("Executing /findplayer command"); + + ServerPlayer targetPlayerName = EntityArgument.getPlayer(context, "player"); + String playerName = targetPlayerName.getGameProfile().name(); + + ServerPlayer targetPlayer = context.getSource().getServer().getPlayerList().getPlayer(playerName); + ServerPlayer sourcePlayer = context.getSource().getServer().getPlayerList().getPlayer(context.getSource().getTextName()); + + if (targetPlayer == null) { + context.getSource().sendSystemMessage(Component.literal("[PlayerFinder ERROR] Player " + playerName + " not found").withStyle(ChatFormatting.RED)); + return 0; + } + if (sourcePlayer == null) { + context.getSource().sendSystemMessage(Component.literal("[PlayerFinder ERROR] Could not determine command source player").withStyle(ChatFormatting.RED)); + return 0; + } + + BlockPos targetBlockPos = targetPlayer.blockPosition(); + BlockPos sourceBlockPos = sourcePlayer.blockPosition(); + + LOGGER.info("Target player position: {}", targetBlockPos); + LOGGER.info("Source player position: {}", sourceBlockPos); + + ResourceKey playerDimension = targetPlayer.level().getLevel().dimension(); + ResourceKey sourceDimension = sourcePlayer.level().getLevel().dimension(); + + LOGGER.info("Target player dimension: {}", playerDimension); + LOGGER.info("Source player dimension: {}", sourceDimension); + + boolean isSameDimension = sourceDimension == playerDimension; + + Component message = Component.literal(playerName + " is at ") + .append(Component.literal(targetBlockPos.getX() + ", " + targetBlockPos.getY() + ", " + targetBlockPos.getZ()) + .withStyle(utils.getDimensionColor(playerDimension))) + .append(Component.literal(" in the ").withStyle(ChatFormatting.WHITE)) + .append(Component.literal(utils.getDimensionText(playerDimension)) + .withStyle(utils.getDimensionColor(playerDimension))) + .append(Component.literal(isSameDimension + ? " (" + utils.getDistance(sourceBlockPos, targetBlockPos) + " blocks away)" + : " (Player is in a different dimension)") + .withStyle(isSameDimension ? ChatFormatting.GREEN : ChatFormatting.RED)); + + // Send it as a system message to the source + context.getSource().sendSystemMessage(message); + + return 1; + }) + ) + )); } } \ No newline at end of file diff --git a/src/main/java/me/imgalvin/playerfinder/PlayerFinderUtils.java b/src/main/java/me/imgalvin/playerfinder/PlayerFinderUtils.java index 5ce7a0c..68d964d 100644 --- a/src/main/java/me/imgalvin/playerfinder/PlayerFinderUtils.java +++ b/src/main/java/me/imgalvin/playerfinder/PlayerFinderUtils.java @@ -1,25 +1,26 @@ package me.imgalvin.playerfinder; -import net.minecraft.registry.RegistryKey; -import net.minecraft.util.Formatting; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.Level; import org.jetbrains.annotations.NotNull; public class PlayerFinderUtils { - public Formatting getDimensionColor(@NotNull RegistryKey playerDimension) { - return playerDimension.equals(World.OVERWORLD) ? Formatting.GREEN : - playerDimension.equals(World.NETHER) ? Formatting.RED : - playerDimension.equals(World.END) ? Formatting.LIGHT_PURPLE : - Formatting.GRAY; // Fallback color for custom or unknown dimensions + public ChatFormatting getDimensionColor(@NotNull ResourceKey playerDimension) { + return playerDimension.equals(ServerLevel.OVERWORLD) ? ChatFormatting.GREEN : + playerDimension.equals(ServerLevel.NETHER) ? ChatFormatting.RED : + playerDimension.equals(ServerLevel.END) ? ChatFormatting.LIGHT_PURPLE : + ChatFormatting.GRAY; // Fallback colour for custom or unknown dimensions } - public String getDimensionText(@NotNull RegistryKey playerDimension) { - // note: this function only works for vanilla dimensions. custom dimensions will have a slight issue - return playerDimension.getValue().toString().split(":")[1].replace("the_", ""); + public String getDimensionText(@NotNull ResourceKey playerDimension) { + return playerDimension.identifier().getPath().replace("the_", ""); } public int getDistance(@NotNull BlockPos playerPos, @NotNull BlockPos targetPos) { + System.out.println("Calculating distance between " + playerPos + " and " + targetPos); return (int) Math.sqrt(Math.pow(playerPos.getX() - targetPos.getX(), 2) + Math.pow(playerPos.getY() - targetPos.getY(), 2) + Math.pow(playerPos.getZ() - targetPos.getZ(), 2)); } } diff --git a/src/main/java/me/imgalvin/playerfinder/PlayerSuggestionProvider.java b/src/main/java/me/imgalvin/playerfinder/PlayerSuggestionProvider.java deleted file mode 100644 index f904e36..0000000 --- a/src/main/java/me/imgalvin/playerfinder/PlayerSuggestionProvider.java +++ /dev/null @@ -1,29 +0,0 @@ -package me.imgalvin.playerfinder; - -import com.mojang.brigadier.context.CommandContext; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.suggestion.SuggestionProvider; -import com.mojang.brigadier.suggestion.Suggestions; -import com.mojang.brigadier.suggestion.SuggestionsBuilder; -import net.minecraft.server.command.ServerCommandSource; - -import java.util.Collection; -import java.util.concurrent.CompletableFuture; - -public class PlayerSuggestionProvider implements SuggestionProvider { - @Override - public CompletableFuture getSuggestions(CommandContext context, SuggestionsBuilder builder) throws CommandSyntaxException { - ServerCommandSource source = context.getSource(); - - // Thankfully, the ServerCommandSource has a method to get a list of player names. - Collection playerNames = source.getPlayerNames(); - - // Add all player names to the builder. - for (String playerName : playerNames) { - builder.suggest(playerName); - } - - // Lock the suggestions after we've modified them. - return builder.buildFuture(); - } -} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 41abbd6..7053f6a 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -21,8 +21,8 @@ }, "depends": { "fabricloader": ">=0.17.3", - "minecraft": "1.21.11", - "java": ">=21", + "minecraft": "26.1-alpha.3", + "java": ">=25", "fabric-api": ">=0.139.5" } } \ No newline at end of file