From e41599e9f7dd35ff90fac8b1a35e424793030fd2 Mon Sep 17 00:00:00 2001 From: John Paul R Date: Thu, 2 Oct 2025 21:41:17 -0400 Subject: [PATCH 01/11] upgrade joinpoints to 1.21.9 --- .../commands/joinpoints/JoinpointTpCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/fibermc/essentialcommands/commands/joinpoints/JoinpointTpCommand.java b/src/main/java/com/fibermc/essentialcommands/commands/joinpoints/JoinpointTpCommand.java index d7302e54..f4feedfd 100644 --- a/src/main/java/com/fibermc/essentialcommands/commands/joinpoints/JoinpointTpCommand.java +++ b/src/main/java/com/fibermc/essentialcommands/commands/joinpoints/JoinpointTpCommand.java @@ -75,7 +75,7 @@ private Consumer> sendErrorToPlayer(ServerPlayerEntity se } { // Try to find owner by name from online players first - var ownerPlayer = senderPlayer.getServer().getPlayerManager().getPlayer(ownerName); + var ownerPlayer = senderPlayer.getEntityWorld().getServer().getPlayerManager().getPlayer(ownerName); if (ownerPlayer != null) { return ownerPlayer.getUuid(); } From 11b486aff618ac83279156bf6141503ecceba787 Mon Sep 17 00:00:00 2001 From: John Paul R Date: Fri, 3 Oct 2025 00:30:43 -0400 Subject: [PATCH 02/11] joinpoint separate mod --- build.gradle | 18 ++-- joinpoints/build.gradle | 47 +++++++++ .../com/fibermc/joinpoints/Joinpoints.java | 62 ++++++++++++ .../joinpoints/JoinpointsCommandRegistry.java | 95 ++++++++++++++++++ .../fibermc/joinpoints/JoinpointsPerms.java | 58 +++++++++++ .../joinpoints/codec/JoinpointCodecs.java | 42 ++++++++ .../fibermc/joinpoints/commands}/Async.java | 2 +- .../commands}/JoinpointException.java | 4 +- .../commands}/JoinpointListCommand.java | 10 +- .../commands}/JoinpointSetCommand.java | 22 ++-- .../commands}/JoinpointShareCommand.java | 10 +- .../commands}/JoinpointTpCommand.java | 21 ++-- .../joinpoints/config/JoinpointsConfig.java | 44 ++++++++ .../joinpoints/database/DatabaseHelper.java | 31 ++++++ .../database/JoinpointDatabase.java | 4 +- .../joinpoints}/types/JoinpointLimit.java | 2 +- .../joinpoints}/types/JoinpointLocation.java | 8 +- .../main/resources/assets/joinpoints/icon.jpg | Bin 0 -> 11501 bytes .../assets/joinpoints/lang/en_us.json | 39 +++++++ joinpoints/src/main/resources/fabric.mod.json | 38 +++++++ settings.gradle | 1 + .../fibermc/essentialcommands/ECPerms.java | 8 -- .../EssentialCommandRegistry.java | 81 --------------- .../essentialcommands/ManagerLocator.java | 7 -- .../essentialcommands/codec/Codecs.java | 24 ----- .../config/EssentialCommandsConfig.java | 18 ---- .../EssentialCommandsConfigSnapshot.java | 2 - .../playerdata/PlayerDataManager.java | 31 ------ .../assets/essential_commands/lang/en_us.json | 37 ------- 29 files changed, 513 insertions(+), 253 deletions(-) create mode 100644 joinpoints/build.gradle create mode 100644 joinpoints/src/main/java/com/fibermc/joinpoints/Joinpoints.java create mode 100644 joinpoints/src/main/java/com/fibermc/joinpoints/JoinpointsCommandRegistry.java create mode 100644 joinpoints/src/main/java/com/fibermc/joinpoints/JoinpointsPerms.java create mode 100644 joinpoints/src/main/java/com/fibermc/joinpoints/codec/JoinpointCodecs.java rename {src/main/java/com/fibermc/essentialcommands/commands/joinpoints => joinpoints/src/main/java/com/fibermc/joinpoints/commands}/Async.java (97%) rename {src/main/java/com/fibermc/essentialcommands/commands/joinpoints => joinpoints/src/main/java/com/fibermc/joinpoints/commands}/JoinpointException.java (98%) rename {src/main/java/com/fibermc/essentialcommands/commands/joinpoints => joinpoints/src/main/java/com/fibermc/joinpoints/commands}/JoinpointListCommand.java (96%) rename {src/main/java/com/fibermc/essentialcommands/commands/joinpoints => joinpoints/src/main/java/com/fibermc/joinpoints/commands}/JoinpointSetCommand.java (90%) rename {src/main/java/com/fibermc/essentialcommands/commands/joinpoints => joinpoints/src/main/java/com/fibermc/joinpoints/commands}/JoinpointShareCommand.java (96%) rename {src/main/java/com/fibermc/essentialcommands/commands/joinpoints => joinpoints/src/main/java/com/fibermc/joinpoints/commands}/JoinpointTpCommand.java (92%) create mode 100644 joinpoints/src/main/java/com/fibermc/joinpoints/config/JoinpointsConfig.java create mode 100644 joinpoints/src/main/java/com/fibermc/joinpoints/database/DatabaseHelper.java rename {src/main/java/com/fibermc/essentialcommands => joinpoints/src/main/java/com/fibermc/joinpoints}/database/JoinpointDatabase.java (99%) rename {src/main/java/com/fibermc/essentialcommands => joinpoints/src/main/java/com/fibermc/joinpoints}/types/JoinpointLimit.java (99%) rename {src/main/java/com/fibermc/essentialcommands => joinpoints/src/main/java/com/fibermc/joinpoints}/types/JoinpointLocation.java (90%) create mode 100644 joinpoints/src/main/resources/assets/joinpoints/icon.jpg create mode 100644 joinpoints/src/main/resources/assets/joinpoints/lang/en_us.json create mode 100644 joinpoints/src/main/resources/fabric.mod.json diff --git a/build.gradle b/build.gradle index a924c397..c3f1d14d 100644 --- a/build.gradle +++ b/build.gradle @@ -49,8 +49,11 @@ allprojects { testImplementation "net.fabricmc:fabric-loader-junit:${project.loader_version}" subprojects.each { - implementation project(path: ":${it.name}", configuration: "namedElements") - include project("${it.name}:") + // Skip joinpoints - it's a separate mod that depends on EC, not a library to include in EC + if (it.name != 'joinpoints') { + implementation project(path: ":${it.name}", configuration: "namedElements") + include project("${it.name}:") + } } } @@ -123,17 +126,16 @@ dependencies { include "org.yaml:snakeyaml:${project.snakeyaml_version}" modImplementation "io.github.ladysnake:PlayerAbilityLib:${pal_version}" include "io.github.ladysnake:PlayerAbilityLib:${pal_version}" - - // SQLite for joinpoints storage - implementation "org.xerial:sqlite-jdbc:3.47.1.0" - include "org.xerial:sqlite-jdbc:3.47.1.0" // mod compatibility modCompileOnly "maven.modrinth:vanish:${project.vanish_version}" subprojects.each { - implementation project(path: ":${it.name}", configuration: "namedElements") - include project("${it.name}:") + // Skip joinpoints - it's a separate mod that depends on EC, not a library to include in EC + if (it.name != 'joinpoints') { + implementation project(path: ":${it.name}", configuration: "namedElements") + include project("${it.name}:") + } } } diff --git a/joinpoints/build.gradle b/joinpoints/build.gradle new file mode 100644 index 00000000..65648302 --- /dev/null +++ b/joinpoints/build.gradle @@ -0,0 +1,47 @@ +plugins { + id 'maven-publish' +} + +base.archivesName = "joinpoints" + +dependencies { + // Essential Commands dependency (joinpoints hooks into EC) + // Reference the compiled classes directories directly + compileOnly files(rootProject.sourceSets.main.output.classesDirs) + compileOnly files(project(':ec-core').sourceSets.main.output.classesDirs) + + // Fabric API - needed for command registration + modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" + + // Permissions API - used by joinpoints + modImplementation "me.lucko:fabric-permissions-api:${project.permissions_api_version}" + + // SQLite for joinpoints storage + implementation "org.xerial:sqlite-jdbc:3.47.1.0" + include "org.xerial:sqlite-jdbc:3.47.1.0" + + testImplementation platform("org.junit:junit-bom:${project.junit_bom_version}") + testImplementation 'org.junit.jupiter:junit-jupiter' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + testImplementation "net.fabricmc:fabric-loader-junit:${project.loader_version}" +} + +// Ensure EC is built before joinpoints compiles +tasks.named('compileJava').configure { + dependsOn(rootProject.tasks.named('classes')) + dependsOn(project(':ec-core').tasks.named('classes')) +} + +publishing { + publications { + mavenJava(MavenPublication) { + artifactId 'joinpoints' + groupId project.maven_group + version project.version + artifact(remapJar) { builtBy remapJar } + artifact(sourcesJar) { + builtBy remapSourcesJar + } + } + } +} diff --git a/joinpoints/src/main/java/com/fibermc/joinpoints/Joinpoints.java b/joinpoints/src/main/java/com/fibermc/joinpoints/Joinpoints.java new file mode 100644 index 00000000..202223bf --- /dev/null +++ b/joinpoints/src/main/java/com/fibermc/joinpoints/Joinpoints.java @@ -0,0 +1,62 @@ +package com.fibermc.joinpoints; + +import com.fibermc.joinpoints.config.JoinpointsConfig; +import com.fibermc.joinpoints.database.JoinpointDatabase; +import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; +import net.minecraft.server.MinecraftServer; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class Joinpoints implements ModInitializer { + public static final String MOD_ID = "joinpoints"; + public static final Logger LOGGER = LogManager.getLogger(MOD_ID); + + private static JoinpointsConfig config; + private static JoinpointDatabase database; + private static MinecraftServer server; + + @Override + public void onInitialize() { + LOGGER.info("Initializing Joinpoints mod"); + + // Register commands + JoinpointsCommandRegistry.register(); + + ServerLifecycleEvents.SERVER_STARTING.register(this::onServerStarting); + ServerLifecycleEvents.SERVER_STOPPED.register(this::onServerStopped); + } + + private void onServerStarting(MinecraftServer server) { + Joinpoints.server = server; + + // Initialize config + config = new JoinpointsConfig( + server.getSavePath(net.minecraft.util.WorldSavePath.ROOT).resolve("config").resolve("joinpoints").resolve("joinpoints.properties"), + "Joinpoints Configuration", + "https://github.com/John-Paul-R/Essential-Commands" // TODO: Update with joinpoints docs link + ); + config.loadOrCreateProperties(); + + // Initialize database + database = new JoinpointDatabase(server.getSavePath(net.minecraft.util.WorldSavePath.ROOT).toFile()); + + LOGGER.info("Joinpoints mod initialized successfully"); + } + + private void onServerStopped(MinecraftServer server) { + Joinpoints.server = null; + } + + public static JoinpointsConfig getConfig() { + return config; + } + + public static JoinpointDatabase getDatabase() { + return database; + } + + public static MinecraftServer getServer() { + return server; + } +} diff --git a/joinpoints/src/main/java/com/fibermc/joinpoints/JoinpointsCommandRegistry.java b/joinpoints/src/main/java/com/fibermc/joinpoints/JoinpointsCommandRegistry.java new file mode 100644 index 00000000..635b501a --- /dev/null +++ b/joinpoints/src/main/java/com/fibermc/joinpoints/JoinpointsCommandRegistry.java @@ -0,0 +1,95 @@ +package com.fibermc.joinpoints; + +import com.fibermc.joinpoints.commands.*; +import com.mojang.brigadier.arguments.BoolArgumentType; +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.tree.LiteralCommandNode; +import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; +import net.minecraft.command.argument.EntityArgumentType; +import net.minecraft.server.command.CommandManager; +import net.minecraft.server.command.ServerCommandSource; + +import static net.minecraft.server.command.CommandManager.argument; + +public final class JoinpointsCommandRegistry { + private JoinpointsCommandRegistry() {} + + public static void register() { + CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { + if (!Joinpoints.getConfig().ENABLE_JOINPOINT.getValue()) { + return; + } + + var joinpointBuilder = CommandManager.literal("joinpoint"); + var joinpointSetBuilder = CommandManager.literal("set"); + var joinpointTpBuilder = CommandManager.literal("tp"); + var joinpointDeleteBuilder = CommandManager.literal("delete"); + var joinpointOverwriteBuilder = CommandManager.literal("overwrite"); + var joinpointShareBuilder = CommandManager.literal("share"); + var joinpointListBuilder = CommandManager.literal("list"); + + joinpointSetBuilder + .requires(JoinpointsPerms.require(JoinpointsPerms.Registry.joinpoint_set, 0)) + .then(argument("joinpoint_name", StringArgumentType.word()) + .executes(new JoinpointSetCommand(JoinpointSetCommand.Action.SET)) + .then(argument("global", BoolArgumentType.bool()) + .executes(new JoinpointSetCommand(JoinpointSetCommand.Action.SET)))); + + joinpointTpBuilder + .requires(JoinpointsPerms.require(JoinpointsPerms.Registry.joinpoint_tp, 0)) + .then(argument(JoinpointTpCommand.OWNER_PLAYER_ARG, StringArgumentType.word()) + .suggests(JoinpointTpCommand.Suggestion.OWNERS_OF_ACCESSIBLE_JOINPOINTS) + .then(argument("joinpoint_name", StringArgumentType.word()) + .suggests(JoinpointTpCommand.Suggestion.ACCESSIBLE_TARGET_PLAYER_JOINPOINTS) + .executes(new JoinpointTpCommand()))); + + joinpointDeleteBuilder + .requires(JoinpointsPerms.require(JoinpointsPerms.Registry.joinpoint_delete, 0)) + .then(argument("joinpoint_name", StringArgumentType.word()) + .suggests(JoinpointTpCommand.Suggestion.OWNED_JOINPOINTS) + .executes(new JoinpointSetCommand(JoinpointSetCommand.Action.DELETE))); + + joinpointOverwriteBuilder + .requires(JoinpointsPerms.require(JoinpointsPerms.Registry.joinpoint_set, 0)) + .then(argument("joinpoint_name", StringArgumentType.word()) + .suggests(JoinpointTpCommand.Suggestion.OWNED_JOINPOINTS) + .executes(new JoinpointSetCommand(JoinpointSetCommand.Action.OVERWRITE)) + .then(argument("global", BoolArgumentType.bool()) + .executes(new JoinpointSetCommand(JoinpointSetCommand.Action.OVERWRITE)))); + + joinpointShareBuilder + .requires(JoinpointsPerms.require(JoinpointsPerms.Registry.joinpoint_set, 0)) + .then(argument("joinpoint_name", StringArgumentType.word()) + .suggests(JoinpointTpCommand.Suggestion.OWNED_JOINPOINTS) + .then(CommandManager.literal("add") + .then(argument("target_players", EntityArgumentType.players()) + .executes(new JoinpointShareCommand(JoinpointShareCommand.Action.ADD)))) + .then(CommandManager.literal("remove") + .then(argument("target_players", EntityArgumentType.players()) + .executes(new JoinpointShareCommand(JoinpointShareCommand.Action.REMOVE)))) + .then(CommandManager.literal("list") + .executes(new JoinpointShareCommand(JoinpointShareCommand.Action.LIST))) + .then(CommandManager.literal("clear") + .executes(new JoinpointShareCommand(JoinpointShareCommand.Action.CLEAR)))); + + joinpointListBuilder + .requires(JoinpointsPerms.require(JoinpointsPerms.Registry.joinpoint_tp, 0)) + .executes(new JoinpointListCommand()::runDefault) + .then(argument("filter", StringArgumentType.word()) + .suggests(JoinpointListCommand.Suggestion.FILTER_TYPES) + .executes(new JoinpointListCommand())); + + LiteralCommandNode joinpointNode = joinpointBuilder + .requires(JoinpointsPerms.requireAny(JoinpointsPerms.Registry.Group.joinpoint_group, 0)) + .build(); + joinpointNode.addChild(joinpointSetBuilder.build()); + joinpointNode.addChild(joinpointTpBuilder.build()); + joinpointNode.addChild(joinpointDeleteBuilder.build()); + joinpointNode.addChild(joinpointOverwriteBuilder.build()); + joinpointNode.addChild(joinpointShareBuilder.build()); + joinpointNode.addChild(joinpointListBuilder.build()); + + dispatcher.getRoot().addChild(joinpointNode); + }); + } +} diff --git a/joinpoints/src/main/java/com/fibermc/joinpoints/JoinpointsPerms.java b/joinpoints/src/main/java/com/fibermc/joinpoints/JoinpointsPerms.java new file mode 100644 index 00000000..9c730a25 --- /dev/null +++ b/joinpoints/src/main/java/com/fibermc/joinpoints/JoinpointsPerms.java @@ -0,0 +1,58 @@ +package com.fibermc.joinpoints; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Predicate; +import java.util.stream.Stream; + +import com.fibermc.joinpoints.types.JoinpointLimit; +import me.lucko.fabric.api.permissions.v0.Permissions; +import org.jetbrains.annotations.NotNull; + +import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.server.network.ServerPlayerEntity; + +public final class JoinpointsPerms { + private JoinpointsPerms() {} + + @SuppressWarnings({"checkstyle:constantname", "checkstyle:staticvariablename"}) + public static final class Registry { + public static final String joinpoint_set = "joinpoints.set"; + public static final String joinpoint_tp = "joinpoints.tp"; + public static final String joinpoint_delete = "joinpoints.delete"; + + public static final class Group { + public static final String[] joinpoint_group = {joinpoint_set, joinpoint_tp, joinpoint_delete}; + public static Map joinpoint_limit_groups = new HashMap<>(); + } + } + + public static Predicate require(String permission, int opLevel) { + return Permissions.require(permission, opLevel); + } + + public static Predicate requireAny(String[] permissions, int opLevel) { + return src -> Arrays.stream(permissions).anyMatch(perm -> Permissions.check(src, perm, opLevel)); + } + + public static String[] makeNumericPermissionGroup(String basePermission, @NotNull Collection limits) { + return limits.stream() + .map(limit -> basePermission + "." + limit) + .toArray(String[]::new); + } + + public static int getMaximumNumericalPermission(ServerPlayerEntity player, String basePermission, String[] validPermissions) { + return Stream.of(validPermissions) + .filter(perm -> Permissions.check(player, basePermission + "." + perm)) + .map(Integer::parseInt) + .max(Integer::compare) + .orElse(0); + } + + // Delegate to ECPerms for the shared permission logic + public static int getHighestNumericPermission(@NotNull ServerCommandSource source, @NotNull String[] permissionGroup) { + return com.fibermc.essentialcommands.ECPerms.getHighestNumericPermission(source, permissionGroup); + } +} diff --git a/joinpoints/src/main/java/com/fibermc/joinpoints/codec/JoinpointCodecs.java b/joinpoints/src/main/java/com/fibermc/joinpoints/codec/JoinpointCodecs.java new file mode 100644 index 00000000..87e8a8bb --- /dev/null +++ b/joinpoints/src/main/java/com/fibermc/joinpoints/codec/JoinpointCodecs.java @@ -0,0 +1,42 @@ +package com.fibermc.joinpoints.codec; + +import java.util.HashSet; +import java.util.Optional; +import java.util.UUID; + +import com.fibermc.essentialcommands.types.MinecraftLocation; +import com.fibermc.joinpoints.types.JoinpointLocation; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; + +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.world.World; + +public final class JoinpointCodecs { + private JoinpointCodecs() {} + + public static final Codec> WORLD_KEY = RegistryKey.createCodec(RegistryKeys.WORLD); + + public static final Codec JOINPOINT_LOCATION = RecordCodecBuilder.create(instance -> + instance.group( + // Inherit all fields from NamedMinecraftLocation + WORLD_KEY.fieldOf("WorldRegistryKey").forGetter(JoinpointLocation::dim), + Codec.DOUBLE.fieldOf("x").forGetter(MinecraftLocation::x), + Codec.DOUBLE.fieldOf("y").forGetter(MinecraftLocation::y), + Codec.DOUBLE.fieldOf("z").forGetter(MinecraftLocation::z), + Codec.FLOAT.optionalFieldOf("headYaw", 0.0f).forGetter(JoinpointLocation::headYaw), + Codec.FLOAT.optionalFieldOf("pitch", 0.0f).forGetter(JoinpointLocation::pitch), + // loaded from the map + Codec.STRING.optionalFieldOf("name").forGetter(joinpoint -> Optional.of(((JoinpointLocation)joinpoint).getName())), + + // Joinpoint-specific fields + Codec.STRING.xmap(UUID::fromString, UUID::toString).fieldOf("owner").forGetter(JoinpointLocation::getOwner), + Codec.BOOL.optionalFieldOf("isGlobal", false).forGetter(JoinpointLocation::isGlobal), + Codec.STRING.xmap(UUID::fromString, UUID::toString).listOf().optionalFieldOf("sharedWith", java.util.List.of()) + .xmap(HashSet::new, java.util.List::copyOf) + .forGetter(JoinpointLocation::getSharedWith) + + ).apply(instance, JoinpointLocation::new) + ); +} diff --git a/src/main/java/com/fibermc/essentialcommands/commands/joinpoints/Async.java b/joinpoints/src/main/java/com/fibermc/joinpoints/commands/Async.java similarity index 97% rename from src/main/java/com/fibermc/essentialcommands/commands/joinpoints/Async.java rename to joinpoints/src/main/java/com/fibermc/joinpoints/commands/Async.java index a30cd638..254fd1ae 100644 --- a/src/main/java/com/fibermc/essentialcommands/commands/joinpoints/Async.java +++ b/joinpoints/src/main/java/com/fibermc/joinpoints/commands/Async.java @@ -1,4 +1,4 @@ -package com.fibermc.essentialcommands.commands.joinpoints; +package com.fibermc.joinpoints.commands; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; diff --git a/src/main/java/com/fibermc/essentialcommands/commands/joinpoints/JoinpointException.java b/joinpoints/src/main/java/com/fibermc/joinpoints/commands/JoinpointException.java similarity index 98% rename from src/main/java/com/fibermc/essentialcommands/commands/joinpoints/JoinpointException.java rename to joinpoints/src/main/java/com/fibermc/joinpoints/commands/JoinpointException.java index 375b4bee..f9cb5d8e 100644 --- a/src/main/java/com/fibermc/essentialcommands/commands/joinpoints/JoinpointException.java +++ b/joinpoints/src/main/java/com/fibermc/joinpoints/commands/JoinpointException.java @@ -1,8 +1,8 @@ -package com.fibermc.essentialcommands.commands.joinpoints; +package com.fibermc.joinpoints.commands; import com.fibermc.essentialcommands.text.ECText; import com.fibermc.essentialcommands.text.TextFormatType; -import com.fibermc.essentialcommands.types.JoinpointLimit; +import com.fibermc.joinpoints.types.JoinpointLimit; import net.minecraft.text.Text; diff --git a/src/main/java/com/fibermc/essentialcommands/commands/joinpoints/JoinpointListCommand.java b/joinpoints/src/main/java/com/fibermc/joinpoints/commands/JoinpointListCommand.java similarity index 96% rename from src/main/java/com/fibermc/essentialcommands/commands/joinpoints/JoinpointListCommand.java rename to joinpoints/src/main/java/com/fibermc/joinpoints/commands/JoinpointListCommand.java index d13af50d..d24c83b8 100644 --- a/src/main/java/com/fibermc/essentialcommands/commands/joinpoints/JoinpointListCommand.java +++ b/joinpoints/src/main/java/com/fibermc/joinpoints/commands/JoinpointListCommand.java @@ -1,15 +1,15 @@ -package com.fibermc.essentialcommands.commands.joinpoints; +package com.fibermc.joinpoints.commands; import java.util.*; import java.util.function.Consumer; import java.util.function.Function; -import com.fibermc.essentialcommands.ManagerLocator; +import com.fibermc.joinpoints.Joinpoints; import com.fibermc.essentialcommands.access.ServerPlayerEntityAccess; -import com.fibermc.essentialcommands.database.JoinpointDatabase; +import com.fibermc.joinpoints.database.JoinpointDatabase; import com.fibermc.essentialcommands.playerdata.PlayerData; import com.fibermc.essentialcommands.text.ECText; -import com.fibermc.essentialcommands.types.JoinpointLocation; +import com.fibermc.joinpoints.types.JoinpointLocation; import com.mojang.brigadier.Command; import com.mojang.brigadier.arguments.StringArgumentType; @@ -67,7 +67,7 @@ private int exec(ServerPlayerEntity senderPlayer, FilterType filter) { Async.runCommand(() -> { var senderPlayerId = senderPlayer.getUuid(); PlayerData playerData = ((ServerPlayerEntityAccess) senderPlayer).ec$getPlayerData(); - JoinpointDatabase database = ManagerLocator.getInstance().getJoinpointDatabase(); + JoinpointDatabase database = Joinpoints.getDatabase(); var joinpoints = database.getAccessibleJoinpointsWithNamesAsync(senderPlayer).join(); // List ownedJoinpoints = database.getOwnedJoinpointsAsync(senderPlayer.getUuid()).join(); diff --git a/src/main/java/com/fibermc/essentialcommands/commands/joinpoints/JoinpointSetCommand.java b/joinpoints/src/main/java/com/fibermc/joinpoints/commands/JoinpointSetCommand.java similarity index 90% rename from src/main/java/com/fibermc/essentialcommands/commands/joinpoints/JoinpointSetCommand.java rename to joinpoints/src/main/java/com/fibermc/joinpoints/commands/JoinpointSetCommand.java index c0359765..baa664ec 100644 --- a/src/main/java/com/fibermc/essentialcommands/commands/joinpoints/JoinpointSetCommand.java +++ b/joinpoints/src/main/java/com/fibermc/joinpoints/commands/JoinpointSetCommand.java @@ -1,4 +1,4 @@ -package com.fibermc.essentialcommands.commands.joinpoints; +package com.fibermc.joinpoints.commands; import java.util.HashSet; import java.util.Set; @@ -6,15 +6,15 @@ import java.util.function.Consumer; import java.util.function.Function; -import com.fibermc.essentialcommands.ECPerms; -import com.fibermc.essentialcommands.ManagerLocator; +import com.fibermc.joinpoints.JoinpointsPerms; +import com.fibermc.joinpoints.Joinpoints; import com.fibermc.essentialcommands.access.ServerPlayerEntityAccess; -import com.fibermc.essentialcommands.database.JoinpointDatabase; +import com.fibermc.joinpoints.database.JoinpointDatabase; import com.fibermc.essentialcommands.playerdata.PlayerData; import com.fibermc.essentialcommands.text.ChatConfirmationPrompt; import com.fibermc.essentialcommands.text.ECText; -import com.fibermc.essentialcommands.types.JoinpointLimit; -import com.fibermc.essentialcommands.types.JoinpointLocation; +import com.fibermc.joinpoints.types.JoinpointLimit; +import com.fibermc.joinpoints.types.JoinpointLocation; import com.fibermc.essentialcommands.types.MinecraftLocation; import com.mojang.brigadier.Command; @@ -75,7 +75,7 @@ private int exec(CommandContext context, String joinpointNa Async.runCommand(() -> { PlayerData playerData = ((ServerPlayerEntityAccess) senderPlayer).ec$getPlayerData(); - JoinpointDatabase database = ManagerLocator.getInstance().getJoinpointDatabase(); + JoinpointDatabase database = Joinpoints.getDatabase(); return switch (action) { case SET -> handleSetAsync(finalIsGlobal, joinpointName, senderPlayer, playerData, database); @@ -119,11 +119,11 @@ private Void handleSetAsync( ? JoinpointLimit.JoinpointType.GLOBAL : JoinpointLimit.JoinpointType.SHARED; - var targetTypePerms = ECPerms.Registry.Group.joinpoint_limit_groups.get(joinpointType); - var anyTypePerms = ECPerms.Registry.Group.joinpoint_limit_groups.get(JoinpointLimit.JoinpointType.ANY); + var targetTypePerms = JoinpointsPerms.Registry.Group.joinpoint_limit_groups.get(joinpointType); + var anyTypePerms = JoinpointsPerms.Registry.Group.joinpoint_limit_groups.get(JoinpointLimit.JoinpointType.ANY); - int playerAllowedOfAnyType = anyTypePerms.length == 0 ? -1 : ECPerms.getHighestNumericPermission(senderPlayer.getCommandSource(), anyTypePerms); - int playerAllowedCountOfTargetType = targetTypePerms.length == 0 ? -1 : ECPerms.getHighestNumericPermission(senderPlayer.getCommandSource(), targetTypePerms); + int playerAllowedOfAnyType = anyTypePerms.length == 0 ? -1 : JoinpointsPerms.getHighestNumericPermission(senderPlayer.getCommandSource(), anyTypePerms); + int playerAllowedCountOfTargetType = targetTypePerms.length == 0 ? -1 : JoinpointsPerms.getHighestNumericPermission(senderPlayer.getCommandSource(), targetTypePerms); // any(5) -> up to 5 shared or global, any combindation // any(5),shared(3) -> no more then 3 shared. Could have 5 global:0 shared to 2 global:3 shared diff --git a/src/main/java/com/fibermc/essentialcommands/commands/joinpoints/JoinpointShareCommand.java b/joinpoints/src/main/java/com/fibermc/joinpoints/commands/JoinpointShareCommand.java similarity index 96% rename from src/main/java/com/fibermc/essentialcommands/commands/joinpoints/JoinpointShareCommand.java rename to joinpoints/src/main/java/com/fibermc/joinpoints/commands/JoinpointShareCommand.java index 517ba67f..81476561 100644 --- a/src/main/java/com/fibermc/essentialcommands/commands/joinpoints/JoinpointShareCommand.java +++ b/joinpoints/src/main/java/com/fibermc/joinpoints/commands/JoinpointShareCommand.java @@ -1,4 +1,4 @@ -package com.fibermc.essentialcommands.commands.joinpoints; +package com.fibermc.joinpoints.commands; import java.util.Collection; import java.util.HashSet; @@ -7,12 +7,12 @@ import java.util.function.Consumer; import java.util.function.Function; -import com.fibermc.essentialcommands.ManagerLocator; +import com.fibermc.joinpoints.Joinpoints; import com.fibermc.essentialcommands.access.ServerPlayerEntityAccess; -import com.fibermc.essentialcommands.database.JoinpointDatabase; +import com.fibermc.joinpoints.database.JoinpointDatabase; import com.fibermc.essentialcommands.playerdata.PlayerData; import com.fibermc.essentialcommands.text.ECText; -import com.fibermc.essentialcommands.types.JoinpointLocation; +import com.fibermc.joinpoints.types.JoinpointLocation; import com.mojang.brigadier.Command; import com.mojang.brigadier.arguments.StringArgumentType; @@ -67,7 +67,7 @@ private int exec(CommandContext context, String joinpointNa Async.runCommand(() -> { PlayerData playerData = ((ServerPlayerEntityAccess) senderPlayer).ec$getPlayerData(); - JoinpointDatabase database = ManagerLocator.getInstance().getJoinpointDatabase(); + JoinpointDatabase database = Joinpoints.getDatabase(); return switch (action) { case ADD -> handleAddAsync(finalTargetPlayers, joinpointName, senderPlayer, playerData, database); diff --git a/src/main/java/com/fibermc/essentialcommands/commands/joinpoints/JoinpointTpCommand.java b/joinpoints/src/main/java/com/fibermc/joinpoints/commands/JoinpointTpCommand.java similarity index 92% rename from src/main/java/com/fibermc/essentialcommands/commands/joinpoints/JoinpointTpCommand.java rename to joinpoints/src/main/java/com/fibermc/joinpoints/commands/JoinpointTpCommand.java index f4feedfd..e59915d1 100644 --- a/src/main/java/com/fibermc/essentialcommands/commands/joinpoints/JoinpointTpCommand.java +++ b/joinpoints/src/main/java/com/fibermc/joinpoints/commands/JoinpointTpCommand.java @@ -1,4 +1,4 @@ -package com.fibermc.essentialcommands.commands.joinpoints; +package com.fibermc.joinpoints.commands; import java.util.List; import java.util.UUID; @@ -8,14 +8,14 @@ import java.util.stream.Collectors; import com.fibermc.essentialcommands.EssentialCommands; -import com.fibermc.essentialcommands.ManagerLocator; +import com.fibermc.joinpoints.Joinpoints; import com.fibermc.essentialcommands.access.ServerPlayerEntityAccess; -import com.fibermc.essentialcommands.database.JoinpointDatabase; +import com.fibermc.joinpoints.database.JoinpointDatabase; import com.fibermc.essentialcommands.playerdata.PlayerData; import com.fibermc.essentialcommands.teleportation.PlayerTeleporter; import com.fibermc.essentialcommands.text.ECText; import com.fibermc.essentialcommands.text.TextFormatType; -import com.fibermc.essentialcommands.types.JoinpointLocation; +import com.fibermc.joinpoints.types.JoinpointLocation; import com.fibermc.essentialcommands.types.NamedMinecraftLocation; import org.apache.commons.lang3.function.TriFunction; import org.apache.logging.log4j.message.ParameterizedMessage; @@ -69,6 +69,13 @@ private Consumer> sendErrorToPlayer(ServerPlayerEntity se */ private @Nullable UUID getJoinpointOwnerIdAsync(ServerPlayerEntity senderPlayer, String ownerName) { + var server = senderPlayer.getEntityWorld().getServer(); + var apis = server.getApiServices(); + var userCache = apis.nameToIdCache(); + + // player to owned joinpoints + // player to accessible joinpoints + // If owner is self, use sender's UUID if (ownerName.equals(senderPlayer.getName().getString())) { return senderPlayer.getUuid(); @@ -82,7 +89,7 @@ private Consumer> sendErrorToPlayer(ServerPlayerEntity se } { // Go to our cached list of all player names as a last resort (particularly for offline players) - JoinpointDatabase database = ManagerLocator.getInstance().getJoinpointDatabase(); + JoinpointDatabase database = Joinpoints.getDatabase(); var ownerUuid = database.getOwnerPlayerIdByNameAsync(ownerName, senderPlayer.getUuid()).join(); if (ownerUuid != null) { return ownerUuid; @@ -96,7 +103,7 @@ private int exec(ServerPlayerEntity senderPlayer, String ownerName, String joinp { Async.runCommand(() -> { PlayerData senderPlayerData = ((ServerPlayerEntityAccess) senderPlayer).ec$getPlayerData(); - JoinpointDatabase database = ManagerLocator.getInstance().getJoinpointDatabase(); + JoinpointDatabase database = Joinpoints.getDatabase(); var ownerUuid = getJoinpointOwnerIdAsync(senderPlayer, ownerName); @@ -143,7 +150,7 @@ private static SuggestionProvider suggestFromDb( return (context, builder) -> { try { ServerPlayerEntity player = context.getSource().getPlayerOrThrow(); - JoinpointDatabase database = ManagerLocator.getInstance().getJoinpointDatabase(); + JoinpointDatabase database = Joinpoints.getDatabase(); return getSuggestionsAsync.apply(database, player, context) .thenApply(items -> { for (String item : items) { diff --git a/joinpoints/src/main/java/com/fibermc/joinpoints/config/JoinpointsConfig.java b/joinpoints/src/main/java/com/fibermc/joinpoints/config/JoinpointsConfig.java new file mode 100644 index 00000000..24f9b1dc --- /dev/null +++ b/joinpoints/src/main/java/com/fibermc/joinpoints/config/JoinpointsConfig.java @@ -0,0 +1,44 @@ +package com.fibermc.joinpoints.config; + +import java.nio.file.Path; + +import com.fibermc.joinpoints.JoinpointsPerms; +import com.fibermc.joinpoints.types.JoinpointLimit; +import dev.jpcode.eccore.config.Config; +import dev.jpcode.eccore.config.ConfigOption; +import dev.jpcode.eccore.config.Option; + +@SuppressWarnings("checkstyle:all") +public final class JoinpointsConfig extends Config { + + @ConfigOption + public final Option ENABLE_JOINPOINT = new Option<>("enable_joinpoint", true, Boolean::parseBoolean); + + @ConfigOption + public final Option JOINPOINT_LIMIT = new Option<>( + "joinpoint_limit", + JoinpointLimit.any(3, 5, 10), + JoinpointLimit::parse, + JoinpointLimit::serialize + ); + + public JoinpointsConfig(Path savePath, String displayName, String documentationLink) { + super(savePath, displayName, documentationLink); + + JOINPOINT_LIMIT.changeEvent.register(joinpointLimit -> { + JoinpointsPerms.Registry.Group.joinpoint_limit_groups.clear(); + for (var limitGroup : joinpointLimit.getLimits().entrySet()) { + var key = limitGroup.getKey(); + var limitNums = limitGroup.getValue(); + + JoinpointsPerms.Registry.Group.joinpoint_limit_groups.put( + key, + JoinpointsPerms.makeNumericPermissionGroup( + "joinpoints.limit." + key.name().toLowerCase(), + limitNums + ) + ); + } + }); + } +} diff --git a/joinpoints/src/main/java/com/fibermc/joinpoints/database/DatabaseHelper.java b/joinpoints/src/main/java/com/fibermc/joinpoints/database/DatabaseHelper.java new file mode 100644 index 00000000..817732c7 --- /dev/null +++ b/joinpoints/src/main/java/com/fibermc/joinpoints/database/DatabaseHelper.java @@ -0,0 +1,31 @@ +package com.fibermc.joinpoints.database; + +import java.sql.SQLException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; + +import com.fibermc.joinpoints.Joinpoints; + +import net.minecraft.util.Util; + +public final class DatabaseHelper { + private DatabaseHelper() {} + + private static final Executor EXECUTOR = Util.getIoWorkerExecutor(); + + public static CompletableFuture async(SqlSupplier supplier) { + return CompletableFuture.supplyAsync(() -> { + try { + return supplier.get(); + } catch (SQLException e) { + Joinpoints.LOGGER.error("Database error", e); + throw new RuntimeException("Database error", e); + } + }, EXECUTOR); + } + + @FunctionalInterface + public interface SqlSupplier { + T get() throws SQLException; + } +} diff --git a/src/main/java/com/fibermc/essentialcommands/database/JoinpointDatabase.java b/joinpoints/src/main/java/com/fibermc/joinpoints/database/JoinpointDatabase.java similarity index 99% rename from src/main/java/com/fibermc/essentialcommands/database/JoinpointDatabase.java rename to joinpoints/src/main/java/com/fibermc/joinpoints/database/JoinpointDatabase.java index a6fd48ca..e8043192 100644 --- a/src/main/java/com/fibermc/essentialcommands/database/JoinpointDatabase.java +++ b/joinpoints/src/main/java/com/fibermc/joinpoints/database/JoinpointDatabase.java @@ -1,4 +1,4 @@ -package com.fibermc.essentialcommands.database; +package com.fibermc.joinpoints.database; import java.io.File; import java.sql.*; @@ -7,7 +7,7 @@ import com.fibermc.essentialcommands.EssentialCommands; import com.fibermc.essentialcommands.playerdata.PlayerDataManager; -import com.fibermc.essentialcommands.types.JoinpointLocation; +import com.fibermc.joinpoints.types.JoinpointLocation; import com.fibermc.essentialcommands.types.MinecraftLocation; import org.apache.logging.log4j.Level; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/com/fibermc/essentialcommands/types/JoinpointLimit.java b/joinpoints/src/main/java/com/fibermc/joinpoints/types/JoinpointLimit.java similarity index 99% rename from src/main/java/com/fibermc/essentialcommands/types/JoinpointLimit.java rename to joinpoints/src/main/java/com/fibermc/joinpoints/types/JoinpointLimit.java index b4ad574d..c50b4b9f 100644 --- a/src/main/java/com/fibermc/essentialcommands/types/JoinpointLimit.java +++ b/joinpoints/src/main/java/com/fibermc/joinpoints/types/JoinpointLimit.java @@ -1,4 +1,4 @@ -package com.fibermc.essentialcommands.types; +package com.fibermc.joinpoints.types; import java.util.HashMap; import java.util.List; diff --git a/src/main/java/com/fibermc/essentialcommands/types/JoinpointLocation.java b/joinpoints/src/main/java/com/fibermc/joinpoints/types/JoinpointLocation.java similarity index 90% rename from src/main/java/com/fibermc/essentialcommands/types/JoinpointLocation.java rename to joinpoints/src/main/java/com/fibermc/joinpoints/types/JoinpointLocation.java index e4e49150..5e789690 100644 --- a/src/main/java/com/fibermc/essentialcommands/types/JoinpointLocation.java +++ b/joinpoints/src/main/java/com/fibermc/joinpoints/types/JoinpointLocation.java @@ -1,11 +1,13 @@ -package com.fibermc.essentialcommands.types; +package com.fibermc.joinpoints.types; import java.util.HashSet; import java.util.Optional; import java.util.Set; import java.util.UUID; -import com.fibermc.essentialcommands.codec.Codecs; +import com.fibermc.essentialcommands.types.MinecraftLocation; +import com.fibermc.essentialcommands.types.NamedMinecraftLocation; +import com.fibermc.joinpoints.codec.JoinpointCodecs; import com.mojang.serialization.Codec; @@ -16,7 +18,7 @@ import net.minecraft.world.World; public class JoinpointLocation extends NamedMinecraftLocation { - public static final Codec CODEC = Codecs.JOINPOINT_LOCATION; + public static final Codec CODEC = JoinpointCodecs.JOINPOINT_LOCATION; private final UUID owner; private final boolean isGlobal; diff --git a/joinpoints/src/main/resources/assets/joinpoints/icon.jpg b/joinpoints/src/main/resources/assets/joinpoints/icon.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ec6f5f017e7233fe8766a0edfbee0520edbdf3f2 GIT binary patch literal 11501 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.11.3", + "fabric": "*", + "essential_commands": "*" + }, + "suggests": { + }, + "jars": [] +} diff --git a/settings.gradle b/settings.gradle index 37e0875c..dfabe142 100644 --- a/settings.gradle +++ b/settings.gradle @@ -12,3 +12,4 @@ pluginManagement { } rootProject.name = 'essential_commands' include 'ec-core' +include 'joinpoints' diff --git a/src/main/java/com/fibermc/essentialcommands/ECPerms.java b/src/main/java/com/fibermc/essentialcommands/ECPerms.java index dc3e1a66..119f1cb8 100644 --- a/src/main/java/com/fibermc/essentialcommands/ECPerms.java +++ b/src/main/java/com/fibermc/essentialcommands/ECPerms.java @@ -2,12 +2,9 @@ import java.util.Arrays; import java.util.Collection; -import java.util.HashMap; -import java.util.Map; import java.util.function.Predicate; import java.util.stream.Stream; -import com.fibermc.essentialcommands.types.JoinpointLimit; import me.lucko.fabric.api.permissions.v0.Permissions; import org.jetbrains.annotations.NotNull; @@ -36,9 +33,6 @@ public static final class Registry { public static final String warp_delete = "essentialcommands.warp.delete"; public static final String warp_tp_named = "essentialcommands.warp.tp_named"; public static final String warp_tp_others = "essentialcommands.warp_tp_others"; - public static final String joinpoint_set = "essentialcommands.joinpoint.set"; - public static final String joinpoint_tp = "essentialcommands.joinpoint.tp"; - public static final String joinpoint_delete = "essentialcommands.joinpoint.delete"; public static final String back = "essentialcommands.back"; public static final String spawn_tp = "essentialcommands.spawn.tp"; public static final String spawn_set = "essentialcommands.spawn.set"; @@ -94,14 +88,12 @@ public static final class Group { public static final String[] tpa_group = {tpa, tpahere, tpaccept, tpdeny}; public static final String[] home_group = {home_set, home_tp, home_delete}; public static final String[] warp_group = {warp_set, warp_tp, warp_delete}; - public static final String[] joinpoint_group = {joinpoint_set, joinpoint_tp, joinpoint_delete}; public static final String[] spawn_group = {spawn_tp, spawn_set}; public static final String[] nickname_group = {nickname_self, nickname_others, nickname_reveal}; public static final String[] fly_group = {fly_self, fly_others}; public static final String[] invuln_group = {invuln_self, invuln_others}; public static final String[] config_group = {config_reload}; public static String[] home_limit_group; - public static Map joinpoint_limit_groups = new HashMap<>(); public static final String[] stateful_player_abilities = {fly_self, fly_others, invuln_self, invuln_others}; } diff --git a/src/main/java/com/fibermc/essentialcommands/EssentialCommandRegistry.java b/src/main/java/com/fibermc/essentialcommands/EssentialCommandRegistry.java index 460554ca..6ecadf62 100644 --- a/src/main/java/com/fibermc/essentialcommands/EssentialCommandRegistry.java +++ b/src/main/java/com/fibermc/essentialcommands/EssentialCommandRegistry.java @@ -8,10 +8,6 @@ import com.fibermc.essentialcommands.commands.*; import com.fibermc.essentialcommands.commands.bench.*; -import com.fibermc.essentialcommands.commands.joinpoints.JoinpointListCommand; -import com.fibermc.essentialcommands.commands.joinpoints.JoinpointSetCommand; -import com.fibermc.essentialcommands.commands.joinpoints.JoinpointShareCommand; -import com.fibermc.essentialcommands.commands.joinpoints.JoinpointTpCommand; import com.fibermc.essentialcommands.commands.suggestions.ListSuggestion; import com.fibermc.essentialcommands.commands.suggestions.NicknamePlayersSuggestion; import com.fibermc.essentialcommands.commands.suggestions.TeleportResponseSuggestion; @@ -195,83 +191,6 @@ public static void register( essentialCommandsRootNode.addChild(homeOverwriteBuilder.build()); } - if (CONFIG.ENABLE_JOINPOINT) { - LiteralArgumentBuilder joinpointBuilder = CommandManager.literal("joinpoint"); - LiteralArgumentBuilder joinpointSetBuilder = CommandManager.literal("set"); - LiteralArgumentBuilder joinpointTpBuilder = CommandManager.literal("tp"); - LiteralArgumentBuilder joinpointDeleteBuilder = CommandManager.literal("delete"); - LiteralArgumentBuilder joinpointOverwriteBuilder = CommandManager.literal("overwrite"); - LiteralArgumentBuilder joinpointShareBuilder = CommandManager.literal("share"); - LiteralArgumentBuilder joinpointListBuilder = CommandManager.literal("list"); - - joinpointSetBuilder - .requires(ECPerms.require(ECPerms.Registry.joinpoint_set, 0)) - .then(argument("joinpoint_name", StringArgumentType.word()) - .executes(new JoinpointSetCommand(JoinpointSetCommand.Action.SET)) - .then(argument("global", BoolArgumentType.bool()) - .executes(new JoinpointSetCommand(JoinpointSetCommand.Action.SET)))); - - joinpointTpBuilder - .requires(ECPerms.require(ECPerms.Registry.joinpoint_tp, 0)) - .then(argument(JoinpointTpCommand.OWNER_PLAYER_ARG, StringArgumentType.word()) - .suggests(JoinpointTpCommand.Suggestion.OWNERS_OF_ACCESSIBLE_JOINPOINTS) - .then(argument("joinpoint_name", StringArgumentType.word()) - .suggests(JoinpointTpCommand.Suggestion.ACCESSIBLE_TARGET_PLAYER_JOINPOINTS) - .executes(new JoinpointTpCommand()))); - - // this is interfering with the more-important playername suggestions -// .then(argument("joinpoint_name", StringArgumentType.word()) -// .suggests(JoinpointTpCommand.Suggestion.ACCESSIBLE_JOINPOINTS) -// .executes(new JoinpointTpCommand()::runOwnJoinpoint)) - - joinpointDeleteBuilder - .requires(ECPerms.require(ECPerms.Registry.joinpoint_delete, 0)) - .then(argument("joinpoint_name", StringArgumentType.word()) - .suggests(JoinpointTpCommand.Suggestion.OWNED_JOINPOINTS) - .executes(new JoinpointSetCommand(JoinpointSetCommand.Action.DELETE))); - - joinpointOverwriteBuilder - .requires(ECPerms.require(ECPerms.Registry.joinpoint_set, 0)) - .then(argument("joinpoint_name", StringArgumentType.word()) - .suggests(JoinpointTpCommand.Suggestion.OWNED_JOINPOINTS) - .executes(new JoinpointSetCommand(JoinpointSetCommand.Action.OVERWRITE)) - .then(argument("global", BoolArgumentType.bool()) - .executes(new JoinpointSetCommand(JoinpointSetCommand.Action.OVERWRITE)))); - - joinpointShareBuilder - .requires(ECPerms.require(ECPerms.Registry.joinpoint_set, 0)) - .then(argument("joinpoint_name", StringArgumentType.word()) - .suggests(JoinpointTpCommand.Suggestion.OWNED_JOINPOINTS) - .then(CommandManager.literal("add") - .then(argument("target_players", EntityArgumentType.players()) - .executes(new JoinpointShareCommand(JoinpointShareCommand.Action.ADD)))) - .then(CommandManager.literal("remove") - .then(argument("target_players", EntityArgumentType.players()) - .executes(new JoinpointShareCommand(JoinpointShareCommand.Action.REMOVE)))) - .then(CommandManager.literal("list") - .executes(new JoinpointShareCommand(JoinpointShareCommand.Action.LIST))) - .then(CommandManager.literal("clear") - .executes(new JoinpointShareCommand(JoinpointShareCommand.Action.CLEAR)))); - - joinpointListBuilder - .requires(ECPerms.require(ECPerms.Registry.joinpoint_tp, 0)) - .executes(new JoinpointListCommand()::runDefault) - .then(argument("filter", StringArgumentType.word()) - .suggests(JoinpointListCommand.Suggestion.FILTER_TYPES) - .executes(new JoinpointListCommand())); - - LiteralCommandNode joinpointNode = joinpointBuilder - .requires(ECPerms.requireAny(ECPerms.Registry.Group.joinpoint_group, 0)) - .build(); - joinpointNode.addChild(joinpointSetBuilder.build()); - joinpointNode.addChild(joinpointTpBuilder.build()); - joinpointNode.addChild(joinpointDeleteBuilder.build()); - joinpointNode.addChild(joinpointOverwriteBuilder.build()); - joinpointNode.addChild(joinpointShareBuilder.build()); - joinpointNode.addChild(joinpointListBuilder.build()); - - registerNode.accept(joinpointNode); - } //Back if (CONFIG.ENABLE_BACK) { diff --git a/src/main/java/com/fibermc/essentialcommands/ManagerLocator.java b/src/main/java/com/fibermc/essentialcommands/ManagerLocator.java index 83a6378d..e5b5fa20 100644 --- a/src/main/java/com/fibermc/essentialcommands/ManagerLocator.java +++ b/src/main/java/com/fibermc/essentialcommands/ManagerLocator.java @@ -4,7 +4,6 @@ import java.util.function.Consumer; import com.fibermc.essentialcommands.commands.suggestions.OfflinePlayerRepo; -import com.fibermc.essentialcommands.database.JoinpointDatabase; import com.fibermc.essentialcommands.playerdata.PlayerDataManager; import com.fibermc.essentialcommands.teleportation.TeleportManager; @@ -19,7 +18,6 @@ public final class ManagerLocator { private TeleportManager tpManager; private WorldDataManager worldDataManager; private OfflinePlayerRepo offlinePlayerRepo; - private JoinpointDatabase joinpointDatabase; private final HashMap> serverStartActions = new HashMap<>(); public static ManagerLocator instance; @@ -46,7 +44,6 @@ public void onServerStart(MinecraftServer server) { this.tpManager = TeleportManager.getInstance(); this.worldDataManager = WorldDataManager.createForServer(server); this.offlinePlayerRepo = new OfflinePlayerRepo(server); - this.joinpointDatabase = new JoinpointDatabase(server.getSavePath(net.minecraft.util.WorldSavePath.ROOT).toFile()); ServerLifecycleEvents.SERVER_STARTED.register(server1 -> { serverStartActions.values().forEach(a -> a.accept(server)); serverStarted = true; @@ -69,10 +66,6 @@ public OfflinePlayerRepo getOfflinePlayerRepo() { return offlinePlayerRepo; } - public JoinpointDatabase getJoinpointDatabase() { - return joinpointDatabase; - } - public void runAndQueue(String key, Consumer action) { serverStartActions.putIfAbsent(key, action); diff --git a/src/main/java/com/fibermc/essentialcommands/codec/Codecs.java b/src/main/java/com/fibermc/essentialcommands/codec/Codecs.java index 250312e2..99936e4a 100644 --- a/src/main/java/com/fibermc/essentialcommands/codec/Codecs.java +++ b/src/main/java/com/fibermc/essentialcommands/codec/Codecs.java @@ -1,9 +1,7 @@ package com.fibermc.essentialcommands.codec; import java.util.HashMap; -import java.util.HashSet; import java.util.Optional; -import java.util.UUID; import com.fibermc.essentialcommands.WorldData; import com.fibermc.essentialcommands.types.*; @@ -63,28 +61,6 @@ private Codecs() {} ).apply(instance, WarpLocation::new) ); - public static final Codec JOINPOINT_LOCATION = RecordCodecBuilder.create(instance -> - instance.group( - // Inherit all fields from NamedMinecraftLocation - WORLD_KEY.fieldOf("WorldRegistryKey").forGetter(JoinpointLocation::dim), - Codec.DOUBLE.fieldOf("x").forGetter(MinecraftLocation::x), - Codec.DOUBLE.fieldOf("y").forGetter(MinecraftLocation::y), - Codec.DOUBLE.fieldOf("z").forGetter(MinecraftLocation::z), - Codec.FLOAT.optionalFieldOf("headYaw", 0.0f).forGetter(JoinpointLocation::headYaw), - Codec.FLOAT.optionalFieldOf("pitch", 0.0f).forGetter(JoinpointLocation::pitch), - // loaded from the map - Codec.STRING.optionalFieldOf("name").forGetter(joinpoint -> Optional.of(((JoinpointLocation)joinpoint).getName())), - - // Joinpoint-specific fields - Codec.STRING.xmap(UUID::fromString, UUID::toString).fieldOf("owner").forGetter(JoinpointLocation::getOwner), - Codec.BOOL.optionalFieldOf("isGlobal", false).forGetter(JoinpointLocation::isGlobal), - Codec.STRING.xmap(UUID::fromString, UUID::toString).listOf().optionalFieldOf("sharedWith", java.util.List.of()) - .xmap(HashSet::new, java.util.List::copyOf) - .forGetter(JoinpointLocation::getSharedWith) - - ).apply(instance, JoinpointLocation::new) - ); - public static final Codec NAMED_LOCATION_STORAGE = Codec.unboundedMap(Codec.STRING, NAMED_MINECRAFT_LOCATION) .xmap( diff --git a/src/main/java/com/fibermc/essentialcommands/config/EssentialCommandsConfig.java b/src/main/java/com/fibermc/essentialcommands/config/EssentialCommandsConfig.java index 49235b25..ebd30217 100644 --- a/src/main/java/com/fibermc/essentialcommands/config/EssentialCommandsConfig.java +++ b/src/main/java/com/fibermc/essentialcommands/config/EssentialCommandsConfig.java @@ -11,7 +11,6 @@ import com.fibermc.essentialcommands.EssentialCommands; import com.fibermc.essentialcommands.ManagerLocator; import com.fibermc.essentialcommands.playerdata.PlayerDataManager; -import com.fibermc.essentialcommands.types.JoinpointLimit; import com.fibermc.essentialcommands.types.RespawnCondition; import com.fibermc.essentialcommands.types.RtpCenter; import org.jetbrains.annotations.NotNull; @@ -48,7 +47,6 @@ public final class EssentialCommandsConfig extends Config ENABLE_SPAWN = new Option<>("enable_spawn", true, Boolean::parseBoolean); @ConfigOption public final Option ENABLE_TPA = new Option<>("enable_tpa", true, Boolean::parseBoolean); @ConfigOption public final Option ENABLE_WARP = new Option<>("enable_warp", true, Boolean::parseBoolean); - @ConfigOption public final Option ENABLE_JOINPOINT = new Option<>("enable_joinpoint", false, Boolean::parseBoolean); @ConfigOption public final Option ENABLE_NICK = new Option<>("enable_nick", true, Boolean::parseBoolean); @ConfigOption public final Option ENABLE_RTP = new Option<>("enable_rtp", true, Boolean::parseBoolean); @ConfigOption public final Option ENABLE_FLY = new Option<>("enable_fly", true, Boolean::parseBoolean); @@ -75,7 +73,6 @@ public final class EssentialCommandsConfig extends Config ENABLE_SLEEP = new Option<>("enable_sleep", false, Boolean::parseBoolean); @ConfigOption public final Option ENABLE_DELETE_ALL_PLAYER_DATA = new Option<>("enable_delete_all_player_data", true, Boolean::parseBoolean); @ConfigOption public final Option> HOME_LIMIT = new Option<>("home_limit", List.of(1, 2, 5), arrayParser(ConfigUtil::parseInt)); - @ConfigOption public final Option JOINPOINT_LIMIT = new Option<>("joinpoint_limit", JoinpointLimit.any(3, 5, 10), JoinpointLimit::parse, JoinpointLimit::serialize); @ConfigOption public final Option TELEPORT_COOLDOWN = new Option<>("teleport_cooldown", 1.0, ConfigUtil::parseDouble); @ConfigOption public final Option TELEPORT_DELAY = new Option<>("teleport_delay", 0.0, ConfigUtil::parseDouble); @ConfigOption public final Option ALLOW_BACK_ON_DEATH = new Option<>("allow_back_on_death", false, Boolean::parseBoolean); @@ -125,21 +122,6 @@ public EssentialCommandsConfig(Path savePath, String displayName, String documen HOME_LIMIT.changeEvent.register(newValue -> ECPerms.Registry.Group.home_limit_group = ECPerms.makeNumericPermissionGroup("essentialcommands.home.limit", newValue) ); - JOINPOINT_LIMIT.changeEvent.register(joinpointLimit -> { - ECPerms.Registry.Group.joinpoint_limit_groups.clear(); - for (var limitGroup : joinpointLimit.getLimits().entrySet()) { - var key = limitGroup.getKey(); - var limitNums = limitGroup.getValue(); - - ECPerms.Registry.Group.joinpoint_limit_groups.put( - key, - ECPerms.makeNumericPermissionGroup( - "essentialcommands.joinpoint_limit." + key.name().toLowerCase(), - limitNums - ) - ); - } - }); // This value is only sent on server start/player connect and, so, cannot be updated for all // players immediately via the config reload command without a fair bit of hackery. // NICKNAME_ABOVE_HEAD.changeEvent.register(ign -> { diff --git a/src/main/java/com/fibermc/essentialcommands/config/EssentialCommandsConfigSnapshot.java b/src/main/java/com/fibermc/essentialcommands/config/EssentialCommandsConfigSnapshot.java index 4f9d1a7f..b920356a 100644 --- a/src/main/java/com/fibermc/essentialcommands/config/EssentialCommandsConfigSnapshot.java +++ b/src/main/java/com/fibermc/essentialcommands/config/EssentialCommandsConfigSnapshot.java @@ -26,7 +26,6 @@ public final class EssentialCommandsConfigSnapshot { public final boolean ENABLE_SPAWN; public final boolean ENABLE_TPA; public final boolean ENABLE_WARP; - public final boolean ENABLE_JOINPOINT; public final boolean ENABLE_NICK; public final boolean ENABLE_RTP; public final boolean ENABLE_FLY; @@ -106,7 +105,6 @@ private EssentialCommandsConfigSnapshot(EssentialCommandsConfig config) { this.ENABLE_SPAWN = config.ENABLE_SPAWN.getValue(); this.ENABLE_TPA = config.ENABLE_TPA.getValue(); this.ENABLE_WARP = config.ENABLE_WARP.getValue(); - this.ENABLE_JOINPOINT = config.ENABLE_JOINPOINT.getValue(); this.ENABLE_NICK = config.ENABLE_NICK.getValue(); this.ENABLE_RTP = config.ENABLE_RTP.getValue(); this.ENABLE_FLY = config.ENABLE_FLY.getValue(); diff --git a/src/main/java/com/fibermc/essentialcommands/playerdata/PlayerDataManager.java b/src/main/java/com/fibermc/essentialcommands/playerdata/PlayerDataManager.java index 546d03c8..f1e86548 100644 --- a/src/main/java/com/fibermc/essentialcommands/playerdata/PlayerDataManager.java +++ b/src/main/java/com/fibermc/essentialcommands/playerdata/PlayerDataManager.java @@ -6,7 +6,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import com.fibermc.essentialcommands.EssentialCommands; import com.fibermc.essentialcommands.ManagerLocator; import com.fibermc.essentialcommands.access.ServerPlayerEntityAccess; import com.fibermc.essentialcommands.commands.MotdCommand; @@ -16,12 +15,9 @@ import com.fibermc.essentialcommands.events.PlayerLeaveCallback; import com.fibermc.essentialcommands.types.MinecraftLocation; import com.fibermc.essentialcommands.types.RespawnCondition; -import com.google.gson.JsonElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import com.mojang.serialization.JsonOps; - import net.minecraft.entity.damage.DamageSource; import net.minecraft.network.ClientConnection; import net.minecraft.network.packet.s2c.play.PlayerListS2CPacket; @@ -29,7 +25,6 @@ import net.minecraft.server.PlayerManager; import net.minecraft.server.network.ServerPlayNetworkHandler; import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.text.TextCodecs; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; @@ -73,9 +68,6 @@ public static void init() { ServerPlayConnectionEvents.JOIN.register( PlayerDataManager::handleSendMotdForGameJoin ); - ServerPlayConnectionEvents.JOIN.register( - (handler, sender, server) -> updatePlayerCache(handler.player) - ); } public static final Event TICK_EVENT = @@ -101,28 +93,6 @@ private static void handleSendMotdForGameJoin( } } - private static void updatePlayerCache( - ServerPlayerEntity player - ) { - try { - var playerData = ((ServerPlayerEntityAccess) player).ec$getPlayerData(); - var database = ManagerLocator.getInstance().getJoinpointDatabase(); - - String nicknameJson = playerData.getNickname() - .map(text -> TextCodecs.CODEC.encodeStart(JsonOps.INSTANCE, text).getOrThrow()) - .map(JsonElement::toString) - .orElse(null); - database - .updatePlayerCacheAsync(player.getUuid(), player.getName().getString(), nicknameJson) - .exceptionally(err -> { - EssentialCommands.LOGGER.error(err); - return null; - }); - } catch (Exception e) { - // Log but don't crash on cache update failure - joinpoint database might not be initialized yet - EssentialCommands.LOGGER.error(e); - } - } public static boolean exists() { return instance != null; @@ -189,7 +159,6 @@ public void tick(MinecraftServer server) { changedNicknames.forEach(playerData -> { playerData.save(); - updatePlayerCache(playerData.getPlayer()); }); this.changedNicknames.clear(); diff --git a/src/main/resources/assets/essential_commands/lang/en_us.json b/src/main/resources/assets/essential_commands/lang/en_us.json index d8a2b5df..17ba07fa 100644 --- a/src/main/resources/assets/essential_commands/lang/en_us.json +++ b/src/main/resources/assets/essential_commands/lang/en_us.json @@ -20,43 +20,6 @@ "cmd.home.set.overwrite": "Home '${0}' already exists.\nWould you like to overwrite the existing home?", "cmd.home.list.start": "Your current homes are: ", "cmd.overwritehome.feedback": "Home '${0}' moved to current location.", - "cmd.joinpoint.tp.error.not_found": "No joinpoint with the name '${0}' could be found for owner '${1}'.", - "cmd.joinpoint.tp.error.owner_not_found": "Player '${0}' not found or has no accessible joinpoints.", - "cmd.joinpoint.tp.error.no_access": "You don't have access to joinpoint '${0}' owned by '${1}'.", - "cmd.joinpoint.location_name": "joinpoint: ${0}", - "cmd.joinpoint.location_name_with_owner": "joinpoint: ${0} (owned by ${1})", - "cmd.joinpoint.delete.feedback": "Joinpoint '${0}' has been deleted.", - "cmd.joinpoint.delete.error": "Joinpoint '${0}' could not be deleted.", - "cmd.joinpoint.set.feedback": "Joinpoint '${0}' set.", - "cmd.joinpoint.set.feedback.global": "Global joinpoint '${0}' set.", - "cmd.joinpoint.set.feedback.shared": "Shared joinpoint '${0}' set.", - "cmd.joinpoint.set.error.limit": "Joinpoint '${0}' could not be set. Joinpoint limit (${1}) for joinpoint type '${2}' reached.", - "cmd.joinpoint.set.error.exists": "Joinpoint '${0}' could not be set. A joinpoint with the specified name already exists.", - "cmd.joinpoint.set.overwrite": "Joinpoint '${0}' already exists.\nWould you like to overwrite the existing joinpoint?", - "cmd.joinpoint.overwrite.feedback": "Joinpoint '${0}' moved to current location.", - "cmd.joinpoint.overwrite.feedback.global": "Global joinpoint '${0}' moved to current location.", - "cmd.joinpoint.overwrite.feedback.shared": "Shared joinpoint '${0}' moved to current location.", - "cmd.joinpoint.list.header.all": "All accessible joinpoints (${0}):", - "cmd.joinpoint.list.header.owned": "Your owned joinpoints (${0}):", - "cmd.joinpoint.list.header.shared_with": "Joinpoints shared with you (${0}):", - "cmd.joinpoint.list.header.global": "Global joinpoints (${0}):", - "cmd.joinpoint.list.empty.all": "You have no accessible joinpoints.", - "cmd.joinpoint.list.empty.owned": "You don't own any joinpoints.", - "cmd.joinpoint.list.empty.shared_with": "No joinpoints have been shared with you.", - "cmd.joinpoint.list.empty.global": "No global joinpoints are available.", - "cmd.joinpoint.error.database": "Database error: ${0}", - "cmd.joinpoint.error.unknown": "Joinpoint action failed - an unknown error occurred: ${0}", - "cmd.joinpoint.error.not_found": "Joinpoint '${0}' not found.", - "cmd.joinpoint.share.error.already_global": "Joinpoint '${0}' is already global and accessible to all players.", - "cmd.joinpoint.share.error.no_new_players": "No new players to share with.", - "cmd.joinpoint.share.error.players_not_shared": "None of the specified players have access to this joinpoint.", - "cmd.joinpoint.share.error.cannot_clear_global": "Cannot clear sharing for global joinpoint '${0}'. Use '/joinpoint set' to make it private first.", - "cmd.joinpoint.share.add.feedback": "Shared joinpoint '${0}' with: ${1}", - "cmd.joinpoint.share.remove.feedback": "Removed access to joinpoint '${0}' from: ${1}", - "cmd.joinpoint.share.list.global": "Joinpoint '${0}' is global (accessible to all players).", - "cmd.joinpoint.share.list.private": "Joinpoint '${0}' is private (only accessible to you).", - "cmd.joinpoint.share.list.shared": "Joinpoint '${0}' is shared with: ${1}", - "cmd.joinpoint.share.clear.feedback": "Cleared all sharing for joinpoint '${0}' (now private).", "cmd.nickname.set.feedback": "Nickname set to '${0}'.", "cmd.nickname.set.error": "Nickname could not be set to '${0}'. Reason: ${1}", "cmd.nickname.set.error.perms": "Player has insufficient permissions for specified nickname.", From 289ee311556bc42fa378b7c3a38589cd20a20dda Mon Sep 17 00:00:00 2001 From: John Paul R Date: Fri, 3 Oct 2025 00:34:51 -0400 Subject: [PATCH 03/11] fix config init order --- .../com/fibermc/joinpoints/Joinpoints.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/joinpoints/src/main/java/com/fibermc/joinpoints/Joinpoints.java b/joinpoints/src/main/java/com/fibermc/joinpoints/Joinpoints.java index 202223bf..5d012bc2 100644 --- a/joinpoints/src/main/java/com/fibermc/joinpoints/Joinpoints.java +++ b/joinpoints/src/main/java/com/fibermc/joinpoints/Joinpoints.java @@ -8,11 +8,17 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.nio.file.Path; + public class Joinpoints implements ModInitializer { public static final String MOD_ID = "joinpoints"; public static final Logger LOGGER = LogManager.getLogger(MOD_ID); - private static JoinpointsConfig config; + private static final JoinpointsConfig config = new JoinpointsConfig( + Path.of("./config/joinpoints.properties"), + "Joinpoints Configuration", + "https://github.com/John-Paul-R/Essential-Commands" // TODO: Update with joinpoints docs link + ); private static JoinpointDatabase database; private static MinecraftServer server; @@ -20,6 +26,9 @@ public class Joinpoints implements ModInitializer { public void onInitialize() { LOGGER.info("Initializing Joinpoints mod"); + // Initialize config early + config.loadOrCreateProperties(); + // Register commands JoinpointsCommandRegistry.register(); @@ -30,14 +39,6 @@ public void onInitialize() { private void onServerStarting(MinecraftServer server) { Joinpoints.server = server; - // Initialize config - config = new JoinpointsConfig( - server.getSavePath(net.minecraft.util.WorldSavePath.ROOT).resolve("config").resolve("joinpoints").resolve("joinpoints.properties"), - "Joinpoints Configuration", - "https://github.com/John-Paul-R/Essential-Commands" // TODO: Update with joinpoints docs link - ); - config.loadOrCreateProperties(); - // Initialize database database = new JoinpointDatabase(server.getSavePath(net.minecraft.util.WorldSavePath.ROOT).toFile()); From 37cafd97f8caa364936fa8325dbdf0f994bf8583 Mon Sep 17 00:00:00 2001 From: John Paul R Date: Fri, 3 Oct 2025 01:25:22 -0400 Subject: [PATCH 04/11] register lang file and fix gradle madness --- build.gradle | 2 +- joinpoints/build.gradle | 16 +++++++ .../com/fibermc/joinpoints/Joinpoints.java | 14 ++++-- .../essentialcommands/text/ECText.java | 47 ++++++++++++++++--- 4 files changed, 68 insertions(+), 11 deletions(-) diff --git a/build.gradle b/build.gradle index c3f1d14d..9e81cab6 100644 --- a/build.gradle +++ b/build.gradle @@ -82,7 +82,7 @@ allprojects { repositories { gradlePluginPortal() mavenCentral() -// mavenLocal() + mavenLocal() maven { name 'Fabric'; url 'https://maven.fabricmc.net/' } // maven { name 'TerraformersMC'; url 'https://maven.terraformersmc.com/' } // Add repositories to retrieve artifacts from in here. diff --git a/joinpoints/build.gradle b/joinpoints/build.gradle index 65648302..4776bd96 100644 --- a/joinpoints/build.gradle +++ b/joinpoints/build.gradle @@ -10,6 +10,15 @@ dependencies { compileOnly files(rootProject.sourceSets.main.output.classesDirs) compileOnly files(project(':ec-core').sourceSets.main.output.classesDirs) + // Make EC available as a mod at runtime for testing + modLocalRuntime(project(':')) { transitive = false } + modLocalRuntime(project(':ec-core')) { transitive = false } + + // EC's transitive dependencies for runtime + modRuntimeOnly "eu.pb4:placeholder-api:${project.placeholder_api_version}" + modRuntimeOnly "org.yaml:snakeyaml:${project.snakeyaml_version}" + modRuntimeOnly "io.github.ladysnake:PlayerAbilityLib:${project.pal_version}" + // Fabric API - needed for command registration modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" @@ -32,6 +41,13 @@ tasks.named('compileJava').configure { dependsOn(project(':ec-core').tasks.named('classes')) } +// Ensure EC jars are rebuilt before running the server +// This ensures modLocalRuntime uses the latest code +tasks.matching { it.name.startsWith('run') }.configureEach { + dependsOn(rootProject.tasks.named('remapJar')) + dependsOn(project(':ec-core').tasks.named('remapJar')) +} + publishing { publications { mavenJava(MavenPublication) { diff --git a/joinpoints/src/main/java/com/fibermc/joinpoints/Joinpoints.java b/joinpoints/src/main/java/com/fibermc/joinpoints/Joinpoints.java index 5d012bc2..c7777140 100644 --- a/joinpoints/src/main/java/com/fibermc/joinpoints/Joinpoints.java +++ b/joinpoints/src/main/java/com/fibermc/joinpoints/Joinpoints.java @@ -1,14 +1,17 @@ package com.fibermc.joinpoints; +import java.nio.file.Path; + +import com.fibermc.essentialcommands.text.ECText; import com.fibermc.joinpoints.config.JoinpointsConfig; import com.fibermc.joinpoints.database.JoinpointDatabase; -import net.fabricmc.api.ModInitializer; -import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; -import net.minecraft.server.MinecraftServer; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import java.nio.file.Path; +import net.minecraft.server.MinecraftServer; + +import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; public class Joinpoints implements ModInitializer { public static final String MOD_ID = "joinpoints"; @@ -29,6 +32,9 @@ public void onInitialize() { // Initialize config early config.loadOrCreateProperties(); + // Register joinpoints lang file with ECText + ECText.registerAdditionalLangPath("/assets/joinpoints/lang/%s.json"); + // Register commands JoinpointsCommandRegistry.register(); diff --git a/src/main/java/com/fibermc/essentialcommands/text/ECText.java b/src/main/java/com/fibermc/essentialcommands/text/ECText.java index 339cfa7d..64ca388a 100644 --- a/src/main/java/com/fibermc/essentialcommands/text/ECText.java +++ b/src/main/java/com/fibermc/essentialcommands/text/ECText.java @@ -13,7 +13,6 @@ import com.fibermc.essentialcommands.playerdata.PlayerProfile; import com.fibermc.essentialcommands.types.IStyleProvider; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.google.gson.Gson; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; @@ -32,10 +31,10 @@ import static com.fibermc.essentialcommands.EssentialCommands.*; public abstract class ECText { - protected final Map stringMap; + protected final Map stringMap = new java.util.HashMap<>(); protected ECText(Map stringMap) { - this.stringMap = stringMap; + this.stringMap.putAll(stringMap); } private static final Gson GSON = new Gson(); @@ -49,12 +48,49 @@ protected ECText(Map stringMap) { BACKING_CONFIG.LANGUAGE.changeEvent.register((langId) -> instance = create(langId)); } + /** + * Register an additional lang file path to be loaded alongside Essential Commands lang files. + * @param resourcePathFormat Format string for the resource path (e.g., "/assets/mymod/lang/%s.json") + */ + public static void registerAdditionalLangPath(String resourcePathFormat) { + loadLangFile(resourcePathFormat, CONFIG.LANGUAGE, instance.stringMap::put); + } + public static void init(MinecraftServer server) { ECText.server = server; } + private static void loadLangFile(String resourcePathFormat, String langId, BiConsumer entryConsumer) { + final String resourceLocation = String.format(resourcePathFormat, langId); + try { + InputStream inputStream = ECText.class.getResourceAsStream(resourceLocation); + if (inputStream == null) { + // Try default language if specified language not found + inputStream = ECText.class.getResourceAsStream(String.format(resourcePathFormat, DEFAULT_LANGUAGE_SPEC)); + } + + if (inputStream != null) { + try { + load(inputStream, entryConsumer); + } catch (Throwable loadEx) { + try { + inputStream.close(); + } catch (Throwable closeEx) { + loadEx.addSuppressed(closeEx); + } + throw loadEx; + } + inputStream.close(); + } + } catch (JsonParseException | IOException ex) { + LOGGER.error("Couldn't read strings from {}", resourceLocation, ex); + } + } + private static ECText create(String langId) { - ImmutableMap.Builder builder = ImmutableMap.builder(); + Map map = new java.util.HashMap<>(); + + // Load Essential Commands lang file final String resourceFString = "/assets/essential_commands/lang/%s.json"; final String resourceLocation = String.format(resourceFString, langId); try { @@ -65,7 +101,7 @@ private static ECText create(String langId) { } try { - load(inputStream, builder::put); + load(inputStream, map::put); } catch (Throwable loadEx) { if (inputStream != null) { try { @@ -85,7 +121,6 @@ private static ECText create(String langId) { LOGGER.error("Couldn't read strings from {}", resourceLocation, ex); } - final Map map = builder.build(); return instance = server == null ? new ECTextImpl(map, ParserContext.of()) : ECTextImpl.forServer(map, server); From d66a84fdd9f2dda59a09a5e15141b2c5124db412 Mon Sep 17 00:00:00 2001 From: John Paul R Date: Fri, 3 Oct 2025 01:34:00 -0400 Subject: [PATCH 05/11] add jetbrains joinpoints run file --- .run/joinpoints server.run.xml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .run/joinpoints server.run.xml diff --git a/.run/joinpoints server.run.xml b/.run/joinpoints server.run.xml new file mode 100644 index 00000000..7f805263 --- /dev/null +++ b/.run/joinpoints server.run.xml @@ -0,0 +1,13 @@ + + + + \ No newline at end of file From f4df3a38cb4762cfbebb8ce105e2e6dbd769fd4e Mon Sep 17 00:00:00 2001 From: John Paul R Date: Fri, 3 Oct 2025 01:35:00 -0400 Subject: [PATCH 06/11] store run configs for base server and client too --- .run/Minecraft Client.run.xml | 13 +++++++++++++ .run/Minecraft Server.run.xml | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 .run/Minecraft Client.run.xml create mode 100644 .run/Minecraft Server.run.xml diff --git a/.run/Minecraft Client.run.xml b/.run/Minecraft Client.run.xml new file mode 100644 index 00000000..46b7a191 --- /dev/null +++ b/.run/Minecraft Client.run.xml @@ -0,0 +1,13 @@ + + + + \ No newline at end of file diff --git a/.run/Minecraft Server.run.xml b/.run/Minecraft Server.run.xml new file mode 100644 index 00000000..73ac751e --- /dev/null +++ b/.run/Minecraft Server.run.xml @@ -0,0 +1,34 @@ + + + + \ No newline at end of file From e73f3cbd042999ceaefeabdeddb01b00144ec039 Mon Sep 17 00:00:00 2001 From: John Paul R Date: Fri, 3 Oct 2025 01:40:24 -0400 Subject: [PATCH 07/11] psychotic gradle warcrimes --- build.gradle | 3 +++ joinpoints/build.gradle | 16 +++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 9e81cab6..083c5fd3 100644 --- a/build.gradle +++ b/build.gradle @@ -7,6 +7,9 @@ plugins { build { dependsOn ':ec-core:build' + // Don't build joinpoints by default since it requires EC jars to exist first + // Build joinpoints separately with: ./gradlew :joinpoints:build + // Or for testing: ./gradlew :joinpoints:runServer (which auto-builds EC jars) } ext.env = loadenv() diff --git a/joinpoints/build.gradle b/joinpoints/build.gradle index 4776bd96..accf93a6 100644 --- a/joinpoints/build.gradle +++ b/joinpoints/build.gradle @@ -2,6 +2,12 @@ plugins { id 'maven-publish' } +// Ensure EC projects are evaluated and built before joinpoints configuration +// This is needed because modLocalRuntime needs the jars to exist +evaluationDependsOnChildren() +project.evaluationDependsOn(':') +project.evaluationDependsOn(':ec-core') + base.archivesName = "joinpoints" dependencies { @@ -11,8 +17,13 @@ dependencies { compileOnly files(project(':ec-core').sourceSets.main.output.classesDirs) // Make EC available as a mod at runtime for testing - modLocalRuntime(project(':')) { transitive = false } - modLocalRuntime(project(':ec-core')) { transitive = false } + // Only add if jars exist (handles clean builds where jars don't exist yet) + def ecJar = rootProject.file("build/libs/essential_commands-${rootProject.version}.jar") + def ecCoreJar = project(':ec-core').file("build/libs/ec-core-${project(':ec-core').version}.jar") + if (ecJar.exists() && ecCoreJar.exists()) { + modLocalRuntime(project(':')) { transitive = false } + modLocalRuntime(project(':ec-core')) { transitive = false } + } // EC's transitive dependencies for runtime modRuntimeOnly "eu.pb4:placeholder-api:${project.placeholder_api_version}" @@ -42,7 +53,6 @@ tasks.named('compileJava').configure { } // Ensure EC jars are rebuilt before running the server -// This ensures modLocalRuntime uses the latest code tasks.matching { it.name.startsWith('run') }.configureEach { dependsOn(rootProject.tasks.named('remapJar')) dependsOn(project(':ec-core').tasks.named('remapJar')) From 116ac3664d2e7ebd119303cdca6f6ce07a7375ba Mon Sep 17 00:00:00 2001 From: John Paul R Date: Fri, 3 Oct 2025 02:05:37 -0400 Subject: [PATCH 08/11] builting cache clear helper --- joinpoints/build.gradle | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/joinpoints/build.gradle b/joinpoints/build.gradle index accf93a6..d17a8fde 100644 --- a/joinpoints/build.gradle +++ b/joinpoints/build.gradle @@ -52,6 +52,21 @@ tasks.named('compileJava').configure { dependsOn(project(':ec-core').tasks.named('classes')) } +// Task to clean Loom cache for EC jars when EC code changes +// Run this manually if EC changes aren't being picked up: ./gradlew :joinpoints:cleanECCache +tasks.register('cleanECCache') { + group = 'fabric' + description = 'Clears cached EC jars from Loom to pick up latest changes' + doLast { + // Only delete EC-related cached jars, not all remapped mods + delete rootProject.fileTree('.gradle/loom-cache/remapped_mods') { + include '**/essential_commands-*/**' + include '**/ec-core-*/**' + } + logger.lifecycle('Cleared EC jars from Loom cache') + } +} + // Ensure EC jars are rebuilt before running the server tasks.matching { it.name.startsWith('run') }.configureEach { dependsOn(rootProject.tasks.named('remapJar')) From c4cc720c4fb2170ffb454804eb7a485e89a98e34 Mon Sep 17 00:00:00 2001 From: John Paul R Date: Fri, 3 Oct 2025 02:28:37 -0400 Subject: [PATCH 09/11] fix: re-add nickname db cache logic --- .../com/fibermc/joinpoints/Joinpoints.java | 34 +++++++++++++++++++ .../playerdata/PlayerDataManager.java | 6 ++-- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/joinpoints/src/main/java/com/fibermc/joinpoints/Joinpoints.java b/joinpoints/src/main/java/com/fibermc/joinpoints/Joinpoints.java index c7777140..26d08731 100644 --- a/joinpoints/src/main/java/com/fibermc/joinpoints/Joinpoints.java +++ b/joinpoints/src/main/java/com/fibermc/joinpoints/Joinpoints.java @@ -2,13 +2,21 @@ import java.nio.file.Path; +import com.fibermc.essentialcommands.access.ServerPlayerEntityAccess; +import com.fibermc.essentialcommands.events.NicknameChangeCallback; +import com.fibermc.essentialcommands.events.PlayerConnectCallback; import com.fibermc.essentialcommands.text.ECText; import com.fibermc.joinpoints.config.JoinpointsConfig; import com.fibermc.joinpoints.database.JoinpointDatabase; +import com.google.gson.JsonElement; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import com.mojang.serialization.JsonOps; + import net.minecraft.server.MinecraftServer; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.TextCodecs; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; @@ -38,6 +46,12 @@ public void onInitialize() { // Register commands JoinpointsCommandRegistry.register(); + // Register player connect callback to update player cache + PlayerConnectCallback.EVENT.register((connection, player) -> updatePlayerCache(player)); + + // Register nickname change callback to update player cache + NicknameChangeCallback.EVENT.register(Joinpoints::updatePlayerCache); + ServerLifecycleEvents.SERVER_STARTING.register(this::onServerStarting); ServerLifecycleEvents.SERVER_STOPPED.register(this::onServerStopped); } @@ -66,4 +80,24 @@ public static JoinpointDatabase getDatabase() { public static MinecraftServer getServer() { return server; } + + private static void updatePlayerCache(ServerPlayerEntity player) { + try { + var playerData = ((ServerPlayerEntityAccess) player).ec$getPlayerData(); + + String nicknameJson = playerData.getNickname() + .map(text -> TextCodecs.CODEC.encodeStart(JsonOps.INSTANCE, text).getOrThrow()) + .map(JsonElement::toString) + .orElse(null); + database + .updatePlayerCacheAsync(player.getUuid(), player.getName().getString(), nicknameJson) + .exceptionally(err -> { + LOGGER.error(err); + return null; + }); + } catch (Exception e) { + // Log but don't crash on cache update failure - joinpoint database might not be initialized yet + LOGGER.error(e); + } + } } diff --git a/src/main/java/com/fibermc/essentialcommands/playerdata/PlayerDataManager.java b/src/main/java/com/fibermc/essentialcommands/playerdata/PlayerDataManager.java index f1e86548..5f275db5 100644 --- a/src/main/java/com/fibermc/essentialcommands/playerdata/PlayerDataManager.java +++ b/src/main/java/com/fibermc/essentialcommands/playerdata/PlayerDataManager.java @@ -9,10 +9,7 @@ import com.fibermc.essentialcommands.ManagerLocator; import com.fibermc.essentialcommands.access.ServerPlayerEntityAccess; import com.fibermc.essentialcommands.commands.MotdCommand; -import com.fibermc.essentialcommands.events.PlayerConnectCallback; -import com.fibermc.essentialcommands.events.PlayerDataManagerTickCallback; -import com.fibermc.essentialcommands.events.PlayerDeathCallback; -import com.fibermc.essentialcommands.events.PlayerLeaveCallback; +import com.fibermc.essentialcommands.events.*; import com.fibermc.essentialcommands.types.MinecraftLocation; import com.fibermc.essentialcommands.types.RespawnCondition; import org.jetbrains.annotations.NotNull; @@ -159,6 +156,7 @@ public void tick(MinecraftServer server) { changedNicknames.forEach(playerData -> { playerData.save(); + NicknameChangeCallback.EVENT.invoker().onNicknameChange(playerData.getPlayer()); }); this.changedNicknames.clear(); From 554a799a02a36feb63af3494c75ab61619acbd1d Mon Sep 17 00:00:00 2001 From: John Paul R Date: Fri, 3 Oct 2025 14:24:10 -0400 Subject: [PATCH 10/11] feat: add the owner names to the joinpoints because the error on packet serialization seems to be gone for some reason --- .../commands/JoinpointListCommand.java | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/joinpoints/src/main/java/com/fibermc/joinpoints/commands/JoinpointListCommand.java b/joinpoints/src/main/java/com/fibermc/joinpoints/commands/JoinpointListCommand.java index d24c83b8..7f65a032 100644 --- a/joinpoints/src/main/java/com/fibermc/joinpoints/commands/JoinpointListCommand.java +++ b/joinpoints/src/main/java/com/fibermc/joinpoints/commands/JoinpointListCommand.java @@ -4,11 +4,11 @@ import java.util.function.Consumer; import java.util.function.Function; -import com.fibermc.joinpoints.Joinpoints; import com.fibermc.essentialcommands.access.ServerPlayerEntityAccess; -import com.fibermc.joinpoints.database.JoinpointDatabase; import com.fibermc.essentialcommands.playerdata.PlayerData; import com.fibermc.essentialcommands.text.ECText; +import com.fibermc.joinpoints.Joinpoints; +import com.fibermc.joinpoints.database.JoinpointDatabase; import com.fibermc.joinpoints.types.JoinpointLocation; import com.mojang.brigadier.Command; @@ -127,15 +127,14 @@ private int exec(ServerPlayerEntity senderPlayer, FilterType filter) { message.append(" ").append(Text.literal("[Private+]").formatted(Formatting.BLUE)); } - // This causes an exception on chat packet sending due to a null text component -// message -// .append(" ") -// .append(Text.literal("by ").formatted(Formatting.GRAY)) -// .append( -// entry.isOwned -// ? ecText.literal("You") -// : entry.ownerDisplayName -// ); + message + .append(" ") + .append(Text.literal("by ").formatted(Formatting.GRAY)) + .append( + entry.isOwned + ? ecText.literal("You") + : entry.ownerDisplayName + ); senderPlayer.sendMessage(message); From e11bf184edebfbfc1053118b8e38c8de602c3cc7 Mon Sep 17 00:00:00 2001 From: John Paul R Date: Fri, 3 Oct 2025 14:24:23 -0400 Subject: [PATCH 11/11] forgot to track nicknamechangecallback --- .../events/NicknameChangeCallback.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/main/java/com/fibermc/essentialcommands/events/NicknameChangeCallback.java diff --git a/src/main/java/com/fibermc/essentialcommands/events/NicknameChangeCallback.java b/src/main/java/com/fibermc/essentialcommands/events/NicknameChangeCallback.java new file mode 100644 index 00000000..2512a981 --- /dev/null +++ b/src/main/java/com/fibermc/essentialcommands/events/NicknameChangeCallback.java @@ -0,0 +1,18 @@ +package com.fibermc.essentialcommands.events; + +import net.minecraft.server.network.ServerPlayerEntity; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; + +public interface NicknameChangeCallback { + Event EVENT = EventFactory.createArrayBacked( + NicknameChangeCallback.class, + (listeners) -> (player) -> { + for (NicknameChangeCallback event : listeners) { + event.onNicknameChange(player); + } + }); + + void onNicknameChange(ServerPlayerEntity player); +}