-
Notifications
You must be signed in to change notification settings - Fork 44
feat: joinpoint separate mod #353
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: joinpoint
Are you sure you want to change the base?
Changes from all commits
e41599e
11b486a
289ee31
37cafd9
d66a84f
f4df3a3
e73f3cb
116ac36
c4cc720
554a799
e11bf18
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| <component name="ProjectRunConfigurationManager"> | ||
| <configuration default="false" name="Minecraft Client" type="Application" factoryName="Application"> | ||
| <option name="ALTERNATIVE_JRE_PATH" value="jbr-21" /> | ||
| <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" /> | ||
| <option name="MAIN_CLASS_NAME" value="net.fabricmc.devlaunchinjector.Main" /> | ||
| <module name="essential_commands.main" /> | ||
| <option name="VM_PARAMETERS" value="-XX:+ShowCodeDetailsInExceptionMessages -XX:+AllowEnhancedClassRedefinition -Dfabric.dli.config=$PROJECT_DIR$/.gradle/loom-cache/launch.cfg -Dfabric.dli.env=client -Dfabric.dli.main=net.fabricmc.loader.launch.knot.KnotServer" /> | ||
| <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/run/" /> | ||
| <method v="2"> | ||
| <option name="Make" enabled="true" /> | ||
| </method> | ||
| </configuration> | ||
| </component> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| <component name="ProjectRunConfigurationManager"> | ||
| <configuration default="false" name="Minecraft Server" type="Application" factoryName="Application"> | ||
| <option name="ALTERNATIVE_JRE_PATH" value="jbr-21" /> | ||
| <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" /> | ||
| <classpathModifications> | ||
| <entry exclude="true" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/commons-logging/commons-logging/1.3.4/b9fc14968d63a8b8a8a2c1885fe3e90564239708/commons-logging-1.3.4.jar" /> | ||
| <entry exclude="true" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jcraft/jorbis/0.0.17/8872d22b293e8f5d7d56ff92be966e6dc28ebdc6/jorbis-0.0.17.jar" /> | ||
| <entry exclude="true" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.lwjgl/lwjgl-tinyfd/3.3.3/82d755ca94b102e9ca77283b9e2dc46d1b15fbe5/lwjgl-tinyfd-3.3.3.jar" /> | ||
| <entry exclude="true" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/commons-codec/commons-codec/1.17.1/973638b7149d333563584137ebf13a691bb60579/commons-codec-1.17.1.jar" /> | ||
| <entry exclude="true" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.lwjgl/lwjgl-glfw/3.3.3/efa1eb78c5ccd840e9f329717109b5e892d72f8e/lwjgl-glfw-3.3.3.jar" /> | ||
| <entry exclude="true" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.apache.httpcomponents/httpclient/4.5.14/1194890e6f56ec29177673f2f12d0b8e627dec98/httpclient-4.5.14.jar" /> | ||
| <entry exclude="true" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.apache.commons/commons-compress/1.27.1/a19151084758e2fbb6b41eddaa88e7b8ff4e6599/commons-compress-1.27.1.jar" /> | ||
| <entry exclude="true" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.lwjgl/lwjgl-jemalloc/3.3.3/b543467b7ff3c6920539a88ee602d34098628be5/lwjgl-jemalloc-3.3.3.jar" /> | ||
| <entry exclude="true" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.mojang/text2speech/1.18.11/e853a12cdd6ba4f4836e8f4bf3b37844a13482b6/text2speech-1.18.11.jar" /> | ||
| <entry exclude="true" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.lwjgl/lwjgl/3.3.3/29589b5f87ed335a6c7e7ee6a5775f81f97ecb84/lwjgl-3.3.3.jar" /> | ||
| <entry exclude="true" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.lwjgl/lwjgl-openal/3.3.3/daada81ceb5fc0c291fbfdd4433cb8d9423577f2/lwjgl-openal-3.3.3.jar" /> | ||
| <entry exclude="true" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.apache.httpcomponents/httpcore/4.4.16/51cf043c87253c9f58b539c9f7e44c8894223850/httpcore-4.4.16.jar" /> | ||
| <entry exclude="true" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.mojang/blocklist/1.0.10/5c685c5ffa94c4cd39496c7184c1d122e515ecef/blocklist-1.0.10.jar" /> | ||
| <entry exclude="true" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.mojang/patchy/2.2.10/da05971b07cbb379d002cf7eaec6a2048211fefc/patchy-2.2.10.jar" /> | ||
| <entry exclude="true" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.lwjgl/lwjgl-freetype/3.3.3/a0db6c84a8becc8ca05f9dbfa985edc348a824c7/lwjgl-freetype-3.3.3.jar" /> | ||
| <entry exclude="true" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.lwjgl/lwjgl-stb/3.3.3/25dd6161988d7e65f71d5065c99902402ee32746/lwjgl-stb-3.3.3.jar" /> | ||
| <entry exclude="true" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.ibm.icu/icu4j/76.1/215f3a8e936d4069344bd75f2b1368fd58112894/icu4j-76.1.jar" /> | ||
| <entry exclude="true" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.lwjgl/lwjgl-opengl/3.3.3/2f6b0147078396a58979125a4c947664e98293a/lwjgl-opengl-3.3.3.jar" /> | ||
| </classpathModifications> | ||
| <option name="MAIN_CLASS_NAME" value="net.fabricmc.devlaunchinjector.Main" /> | ||
| <module name="essential_commands.main" /> | ||
| <option name="PROGRAM_PARAMETERS" value="nogui" /> | ||
| <option name="VM_PARAMETERS" value="-XX:+ShowCodeDetailsInExceptionMessages -Dfabric.dli.config=$PROJECT_DIR$/.gradle/loom-cache/launch.cfg -Dfabric.dli.env=server -Dfabric.dli.main=net.fabricmc.loader.impl.launch.knot.KnotServer" /> | ||
| <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/run/" /> | ||
| <method v="2"> | ||
| <option name="Make" enabled="true" /> | ||
| </method> | ||
| </configuration> | ||
| </component> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| <component name="ProjectRunConfigurationManager"> | ||
| <configuration default="false" name="joinpoints server" type="Application" factoryName="Application"> | ||
| <option name="ALTERNATIVE_JRE_PATH" value="/usr/lib/jvm/java-21-jetbrains" /> | ||
| <option name="MAIN_CLASS_NAME" value="net.fabricmc.devlaunchinjector.Main" /> | ||
| <module name="essential_commands.joinpoints.main" /> | ||
| <option name="PROGRAM_PARAMETERS" value="nogui" /> | ||
| <option name="VM_PARAMETERS" value="-XX:+ShowCodeDetailsInExceptionMessages -Dfabric.dli.config=$PROJECT_DIR$/.gradle/loom-cache/launch.cfg -Dfabric.dli.env=server -Dfabric.dli.main=net.fabricmc.loader.impl.launch.knot.KnotServer" /> | ||
| <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/joinpoints/run" /> | ||
| <method v="2"> | ||
| <option name="Make" enabled="true" /> | ||
| </method> | ||
| </configuration> | ||
| </component> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| 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 { | ||
| // 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) | ||
|
|
||
| // Make EC available as a mod at runtime for testing | ||
| // 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}" | ||
| 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}" | ||
|
|
||
| // 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')) | ||
| } | ||
|
|
||
| // 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')) | ||
| dependsOn(project(':ec-core').tasks.named('remapJar')) | ||
| } | ||
|
|
||
| publishing { | ||
| publications { | ||
| mavenJava(MavenPublication) { | ||
| artifactId 'joinpoints' | ||
| groupId project.maven_group | ||
| version project.version | ||
| artifact(remapJar) { builtBy remapJar } | ||
| artifact(sourcesJar) { | ||
| builtBy remapSourcesJar | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,103 @@ | ||
| package com.fibermc.joinpoints; | ||
|
|
||
| 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; | ||
|
|
||
| public class Joinpoints implements ModInitializer { | ||
| public static final String MOD_ID = "joinpoints"; | ||
| public static final Logger LOGGER = LogManager.getLogger(MOD_ID); | ||
|
|
||
| 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 | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. todo
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (though consider merging configs)
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (though, this being "part of ec" may be a distinctly "me" thing -- whatever's decided, I should be consistent in the messaging: Is this a plugin for EC, or an entirely separate mod [that has a hard dependency]? -- is my ideal world one where the shared bits are a lib? how much really needs to be shared?) |
||
| ); | ||
| private static JoinpointDatabase database; | ||
| private static MinecraftServer server; | ||
|
|
||
| @Override | ||
| public void onInitialize() { | ||
| LOGGER.info("Initializing Joinpoints mod"); | ||
|
|
||
| // Initialize config early | ||
| config.loadOrCreateProperties(); | ||
|
|
||
| // Register joinpoints lang file with ECText | ||
| ECText.registerAdditionalLangPath("/assets/joinpoints/lang/%s.json"); | ||
|
|
||
| // 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); | ||
| } | ||
|
|
||
| private void onServerStarting(MinecraftServer server) { | ||
| Joinpoints.server = server; | ||
|
|
||
| // 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; | ||
| } | ||
|
|
||
| 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); | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ensure this sorcery is still necessary, I think the sorcery in
dependenciesis doing the heavy lifting rn