diff --git a/build.gradle b/build.gradle index ec82465..9789f71 100644 --- a/build.gradle +++ b/build.gradle @@ -11,45 +11,49 @@ group = project.maven_group repositories { - // Add repositories to retrieve artifacts from in here. - // You should only use this when depending on other mods because - // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. - // See https://docs.gradle.org/current/userguide/declaring_repositories.html - // for more information about repositories. + mavenCentral() + maven { + // For ImageIO + name "SonaType Maven" + url "https://oss.sonatype.org/content/repositories/snapshots" + } + + maven { + // For YACL + name "Xander Maven" + url "https://maven.isxander.dev/releases" + } + + maven { + // For quilt-parsers + name "QuiltMC Maven" + url "https://maven.quiltmc.org/repository/release" + } + + maven { + // For modmenu + name "TerraformersMC Maven" + url "https://maven.terraformersmc.com/releases" + } } loom { - // Loom and Loader both use this block in order to gather more information about your mod. mods { - // This should match your mod id. "touch_grass_warning" { - // Tell Loom about each source set used by your mod here. This ensures that your mod's classes are properly transformed by Loader. sourceSet("main") - // If you shade (directly include classes, not JiJ) a dependency into your mod, include it here using one of these methods: - // dependency("com.example.shadowedmod:1.2.3") - // configuration("exampleShadedConfigurationName") } } } -// All the dependencies are declared at gradle/libs.version.toml and referenced with "libs." -// See https://docs.gradle.org/current/userguide/platforms.html for information on how version catalogs work. dependencies { minecraft libs.minecraft - mappings variantOf(libs.quilt.mappings) { classifier 'intermediary-v2' } - // Replace the above line with the block below if you want to use Mojang mappings as your primary mappings, falling back on QM for parameters and Javadocs - /* mappings loom.layered { mappings "org.quiltmc:quilt-mappings:${libs.versions.quilt.mappings.get()}:intermediary-v2" officialMojangMappings() } - */ modImplementation libs.quilt.loader - - // QSL is not a complete API; You will need Quilted Fabric API to fill in the gaps. - // Quilted Fabric API will automatically pull in the correct QSL version. modImplementation libs.quilted.fabric.api - // modImplementation libs.bundles.quilted.fabric.api // If you wish to use Fabric API's deprecated modules, you can replace the above line with this one + modImplementation "dev.isxander.yacl:yet-another-config-lib-fabric:3.2.1+1.20" } processResources { @@ -62,32 +66,22 @@ mappings variantOf(libs.quilt.mappings) { classifier 'intermediary-v2' } tasks.withType(JavaCompile).configureEach { it.options.encoding = 'UTF-8' - // Minecraft 1.18 (1.18-pre2) upwards uses Java 17. it.options.release = 17 } java { - // Still required by IDEs such as Eclipse and Visual Studio Code sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 - // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task if it is present. - // If you remove this line, sources will not be generated. withSourcesJar() - - // If this mod is going to be a library, then it should also generate Javadocs in order to aid with development. - // Uncomment this line to generate them. - // withJavadocJar() } -// If you plan to use a different file for the license, don't forget to change the file name here! jar { from('LICENSE') { rename { "${it}_${base.archivesName.get()}" } } } -// Configure the maven publication publishing { publications { mavenJava(MavenPublication) { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6665597..feca31f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,11 +1,14 @@ [versions] -# The latest versions are available at https://lambdaurora.dev/tools/import_quilt.html minecraft = "1.20.1" quilt_mappings = "1.20.1+build.23" quilt_loader = "0.22.1-beta.2" quilted_fabric_api = "7.4.0+0.90.0-1.20.1" +mixin_extras = "0.2.0" +# twelvemonkeys_imageio = "3.10.0" +quilt_parsers = "0.2.1" + [libraries] minecraft = { module = "com.mojang:minecraft", version.ref = "minecraft" } quilt_mappings = { module = "org.quiltmc:quilt-mappings", version.ref = "quilt_mappings" } @@ -14,7 +17,6 @@ quilt_loader = { module = "org.quiltmc:quilt-loader", version.ref = "quilt_loade quilted_fabric_api = { module = "org.quiltmc.quilted-fabric-api:quilted-fabric-api", version.ref = "quilted_fabric_api" } quilted_fabric_api_deprecated = { module = "org.quiltmc.quilted-fabric-api:quilted-fabric-api-deprecated", version.ref = "quilted_fabric_api" } -# If you have multiple similar dependencies, you can declare a dependency bundle and reference it on the build script with "libs.bundles.example". [bundles] quilted_fabric_api = ["quilted_fabric_api", "quilted_fabric_api_deprecated"] diff --git a/src/main/java/xyz/devcomp/touch_grass_warning/client/PlayDurationHandler.java b/src/main/java/xyz/devcomp/touch_grass_warning/client/PlayDurationHandler.java deleted file mode 100644 index 3a57610..0000000 --- a/src/main/java/xyz/devcomp/touch_grass_warning/client/PlayDurationHandler.java +++ /dev/null @@ -1,41 +0,0 @@ -package xyz.devcomp.touch_grass_warning.client; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.toast.SystemToast; -import net.minecraft.client.toast.SystemToast.Type; -import net.minecraft.text.Text; - -public class PlayDurationHandler implements Runnable { - MinecraftClient client; - SystemToast toast; - long startTime; - - public PlayDurationHandler(MinecraftClient client, long startTime) { - this.client = client; - this.startTime = startTime; - - this.toast = new SystemToast(Type.TUTORIAL_HINT, Text.literal("You've been playing for greater than 24 hours"), - Text.literal("Excessive gaming may interfere with normal daily life")); - } - - @Override - public void run() { - TouchGrassWarningClient.LOGGER.info("Started playing Minecraft at: {}", this.startTime); - - while (true) { - if (System.currentTimeMillis() - this.startTime > 24 * 60 * 60 * 1000) { - TouchGrassWarningClient.LOGGER - .info("Player has spent more than 24 hours in Minecraft. Displaying warning."); - - this.client.getToastManager().add(this.toast); - } - - try { - Thread.sleep(10 * 1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } - -} diff --git a/src/main/java/xyz/devcomp/touch_grass_warning/client/TouchGrassWarningClient.java b/src/main/java/xyz/devcomp/touch_grass_warning/client/TouchGrassWarningClient.java index 9103a8a..d504dc9 100644 --- a/src/main/java/xyz/devcomp/touch_grass_warning/client/TouchGrassWarningClient.java +++ b/src/main/java/xyz/devcomp/touch_grass_warning/client/TouchGrassWarningClient.java @@ -2,48 +2,55 @@ import java.util.UUID; +import xyz.devcomp.touch_grass_warning.config.ConfigModel; +import xyz.devcomp.touch_grass_warning.utils.PlayDurationHandler; + import org.quiltmc.loader.api.ModContainer; import org.quiltmc.qsl.base.api.entrypoint.client.ClientModInitializer; import org.quiltmc.qsl.networking.api.client.ClientPlayConnectionEvents; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import net.minecraft.client.network.ServerInfo; +import net.minecraft.client.multiplayer.ServerData; public class TouchGrassWarningClient implements ClientModInitializer { public static final Logger LOGGER = LoggerFactory.getLogger("Touch Grass Warning"); - private Thread t; + private ConfigModel config = new ConfigModel(); + private Thread thread; @Override public void onInitializeClient(ModContainer mod) { + LOGGER.info("Touch Grass Warning init; isEnabled={}, reminderFrequency={}h", config.isEnabled, config.reminderFrequency); LOGGER.info("Registering JOIN & DISCONNECT events..."); - ClientPlayConnectionEvents.JOIN.register((net, packet, client) -> { - UUID sessionId = net.getSessionId(); - ServerInfo serverInfo = net.getServerInfo() == null ? new ServerInfo("Unknown", "Unknown", false) - : net.getServerInfo(); + if (config.isEnabled) { + ClientPlayConnectionEvents.JOIN.register((net, packet, client) -> { + UUID sessionId = net.getId(); + ServerData serverInfo = net.getServerData() == null ? new ServerData("Unknown", "Unknown", false) + : net.getServerData(); - LOGGER.info( - "Player initiated connection; sessionId={}, name={}, version={}, protocolVersion={}, isLocal={}, isOnline={}", - sessionId, serverInfo.name, serverInfo.version, serverInfo.protocolVersion, serverInfo.isLocal(), - serverInfo.online); + LOGGER.info( + "Player initiated connection; sessionId={}, name={}, version={}, protocolVersion={}, isLocal={}", + sessionId, serverInfo.name, serverInfo.version, serverInfo.protocol, serverInfo.isLan()); - PlayDurationHandler worker = new PlayDurationHandler(client, System.currentTimeMillis()); + PlayDurationHandler worker = new PlayDurationHandler(client, System.currentTimeMillis(), + config.reminderFrequency * 60 * 60 * 1000); - t = new Thread(worker); - t.start(); + thread = new Thread(worker); + thread.start(); - LOGGER.info("Successfully started worker thread!"); - }); + LOGGER.info("Successfully started worker thread!"); + }); - ClientPlayConnectionEvents.DISCONNECT.register((net, client) -> { - LOGGER.info("Player initiated disconnection. Resetting grass touching timer."); + ClientPlayConnectionEvents.DISCONNECT.register((net, client) -> { + LOGGER.info("Player initiated disconnection. Resetting grass touching timer."); - if (!t.isInterrupted()) { - t.interrupt(); - } else { - LOGGER.warn("Thread is already interrupted!"); - } - }); + if (!thread.isInterrupted()) { + thread.interrupt(); + } else { + LOGGER.warn("Thread is already interrupted!"); + } + }); + } } } diff --git a/src/main/java/xyz/devcomp/touch_grass_warning/config/ConfigHandler.java b/src/main/java/xyz/devcomp/touch_grass_warning/config/ConfigHandler.java new file mode 100644 index 0000000..50e25d8 --- /dev/null +++ b/src/main/java/xyz/devcomp/touch_grass_warning/config/ConfigHandler.java @@ -0,0 +1,24 @@ +package xyz.devcomp.touch_grass_warning.config; + +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.resources.ResourceLocation; + +import org.quiltmc.loader.api.QuiltLoader; + +import dev.isxander.yacl3.config.v2.api.ConfigClassHandler; +import dev.isxander.yacl3.config.v2.api.serializer.GsonConfigSerializerBuilder; + +public class ConfigHandler { + public static final ConfigClassHandler HANDLER = ConfigClassHandler.createBuilder(ConfigModel.class) + .id(new ResourceLocation("touchgrassreminder", "config")) + .serializer(config -> GsonConfigSerializerBuilder.create(config) + .setPath(QuiltLoader.getConfigDir().resolve("touch-grass-reminder.json")) + .setJson5(true) + .build()) + .build(); + + public Screen showGui(Screen parent) { + return HANDLER.generateGui().generateScreen(parent); + } + +} diff --git a/src/main/java/xyz/devcomp/touch_grass_warning/config/ConfigModel.java b/src/main/java/xyz/devcomp/touch_grass_warning/config/ConfigModel.java new file mode 100644 index 0000000..1d399c5 --- /dev/null +++ b/src/main/java/xyz/devcomp/touch_grass_warning/config/ConfigModel.java @@ -0,0 +1,16 @@ +package xyz.devcomp.touch_grass_warning.config; + +import dev.isxander.yacl3.config.v2.api.SerialEntry; +import dev.isxander.yacl3.config.v2.api.autogen.*; + +public class ConfigModel { + @SerialEntry(comment = "Whether the mod's functionality is enabled") + @AutoGen(category = "touch_grass_warning") + @TickBox + public boolean isEnabled = true; + + @SerialEntry(comment = "Number of hours the warning should be displayed after") + @AutoGen(category = "touch_grass_warning") + @IntField(min = 1) + public int reminderFrequency = 24; +} diff --git a/src/main/java/xyz/devcomp/touch_grass_warning/integrations/ModMenuIntegration.java b/src/main/java/xyz/devcomp/touch_grass_warning/integrations/ModMenuIntegration.java new file mode 100644 index 0000000..7c3c112 --- /dev/null +++ b/src/main/java/xyz/devcomp/touch_grass_warning/integrations/ModMenuIntegration.java @@ -0,0 +1,19 @@ +package xyz.devcomp.touch_grass_warning.integrations; + +import org.quiltmc.loader.api.QuiltLoader; + +import com.terraformersmc.modmenu.api.ConfigScreenFactory; +import com.terraformersmc.modmenu.api.ModMenuApi; + +import xyz.devcomp.touch_grass_warning.config.ConfigHandler; + +public class ModMenuIntegration implements ModMenuApi { + @Override + public ConfigScreenFactory getModConfigScreenFactory() { + return (parent) -> { + if (!QuiltLoader.isModLoaded("yet_another_config_lib_v3")) + return parent; + return new ConfigHandler().showGui(parent); + }; + } +} \ No newline at end of file diff --git a/src/main/java/xyz/devcomp/touch_grass_warning/utils/PlayDurationHandler.java b/src/main/java/xyz/devcomp/touch_grass_warning/utils/PlayDurationHandler.java new file mode 100644 index 0000000..5bffe20 --- /dev/null +++ b/src/main/java/xyz/devcomp/touch_grass_warning/utils/PlayDurationHandler.java @@ -0,0 +1,45 @@ +package xyz.devcomp.touch_grass_warning.utils; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.components.toasts.SystemToast; +import net.minecraft.client.gui.components.toasts.SystemToast.SystemToastIds; +import net.minecraft.network.chat.Component; +import xyz.devcomp.touch_grass_warning.client.TouchGrassWarningClient; + +public class PlayDurationHandler implements Runnable { + Minecraft client; + SystemToast toast; + long startTime; + int reminderFrequency; // In milliseconds, converted in onInitializeClient + + public PlayDurationHandler(Minecraft client, long startTime, int reminderFrequency) { + this.client = client; + this.startTime = startTime; + + this.toast = new SystemToast(SystemToastIds.TUTORIAL_HINT, Component.literal(String.format("You've been playing for greater than %d hours", reminderFrequency)), + Component.literal("Excessive gaming may interfere with normal daily life")); + } + + @Override + public void run() { + TouchGrassWarningClient.LOGGER.info("Started playing Minecraft at: {}", this.startTime); + + while (true) { + if (System.currentTimeMillis() - this.startTime > this.reminderFrequency) { + TouchGrassWarningClient.LOGGER + .info("Player has spent more than 24 hours in Minecraft. Displaying warning."); + + this.client.getToasts().addToast(toast); + return; + } + + try { + // Check every 10 minutes + Thread.sleep(10 * 60 * 1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + +} diff --git a/src/main/resources/assets/touch_grass_warning/lang/en_us.json b/src/main/resources/assets/touch_grass_warning/lang/en_us.json new file mode 100644 index 0000000..96fd949 --- /dev/null +++ b/src/main/resources/assets/touch_grass_warning/lang/en_us.json @@ -0,0 +1,9 @@ +{ + "yacl3.config.touchgrassreminder:config.category.touch_grass_warning": "Touch Grass Reminder", + "yacl3.config.touchgrassreminder:config.isEnabled": "Enabled", + "yacl3.config.touchgrassreminder:config.isEnabled.desc.1": "Whether most of the mod's functionality is enabled", + "yacl3.config.touchgrassreminder:config.isEnabled.desc.2": "Takes effect on restart", + "yacl3.config.touchgrassreminder:config.reminderFrequency": "Reminder frequency", + "yacl3.config.touchgrassreminder:config.reminderFrequency.desc.1": "After how long the warning should appear (in hours)", + "yacl3.config.touchgrassreminder:config.reminderFrequency.desc.2": "Takes effect on restart" +} \ No newline at end of file diff --git a/src/main/resources/quilt.mod.json b/src/main/resources/quilt.mod.json index 8990d17..75fac42 100644 --- a/src/main/resources/quilt.mod.json +++ b/src/main/resources/quilt.mod.json @@ -1,41 +1,47 @@ { - "schema_version": 1, - "quilt_loader": { - "group": "xyz.devcomp", - "id": "touch_grass_warning", - "version": "${version}", - "metadata": { - "name": "Touch Grass Warning", - "description": "Client-side mod which warns players when they have been excessively playing Minecraft (more than 24 hours at a time).", - "contributors": { - "Erica Marigold": "Owner" - }, - "contact": { - "homepage": "", - "issues": "https://github.com/CompeyDev/touch-grass-warning/issues", - "sources": "https://github.com/CompeyDev/touch-grass-warning" - }, - "license": "LGPL-3.0-only", - "icon": "assets/touch_grass_warning/icon.png" - }, - "intermediate_mappings": "net.fabricmc:intermediary", - "entrypoints": { - "client_init": "xyz.devcomp.touch_grass_warning.client.TouchGrassWarningClient" - }, - "depends": [ - { - "id": "quilt_loader", - "versions": ">=0.22.1-" - }, - { - "id": "quilted_fabric_api", - "versions": ">=7.4.0+0.90.0-" - }, - { - "id": "minecraft", - "versions": "~1.20.1" - } - ] - }, - "mixin": "touch_grass_warning.mixins.json" + "schema_version": 1, + "quilt_loader": { + "group": "xyz.devcomp", + "id": "touch_grass_warning", + "version": "${version}", + "metadata": { + "name": "Touch Grass Warning", + "description": "Client-side mod which warns players when they have been excessively playing Minecraft (more than 24 hours at a time).", + "contributors": { + "Erica Marigold": "Owner" + }, + "contact": { + "homepage": "", + "issues": "https://github.com/CompeyDev/touch-grass-warning/issues", + "sources": "https://github.com/CompeyDev/touch-grass-warning" + }, + "license": "LGPL-3.0-only", + "icon": "assets/touch_grass_warning/icon.png" + }, + "intermediate_mappings": "net.fabricmc:intermediary", + "entrypoints": { + "client_init": "xyz.devcomp.touch_grass_warning.client.TouchGrassWarningClient", + "modmenu": "xyz.devcomp.touch_grass_warning.integrations.ModMenuIntegration" + }, + "depends": [ + { + "id": "quilt_loader", + "versions": ">=0.22.1-" + }, + { + "id": "quilted_fabric_api", + "versions": ">=7.4.0+0.90.0-" + }, + { + "id": "minecraft", + "versions": "~1.20.1" + }, + + { + "id": "yet_another_config_lib_v3", + "versions": ">=3.2.1+1.20-" + } + ] + }, + "mixin": "touch_grass_warning.mixins.json" }