From 77409c15e820aa7dd21a56704fbdad7e5cc8565d Mon Sep 17 00:00:00 2001 From: Big Iron <52252627+Big-Iron-Cheems@users.noreply.github.com> Date: Fri, 3 May 2024 22:36:20 +0200 Subject: [PATCH] Update template to 1.20.5/.6 and few improvements (#47) --- .github/workflows/dev_build.yml | 12 +- .github/workflows/pull_request.yml | 22 ++-- LICENSE | 121 ++++++++++++++++++ README.md | 77 ++++++++++- build.gradle | 41 ++++-- gradle.properties | 8 +- gradle/wrapper/gradle-wrapper.properties | 3 +- .../addon/{Addon.java => AddonTemplate.java} | 8 +- .../addon/commands/CommandExample.java | 13 ++ .../com/example/addon/hud/HudExample.java | 11 +- .../com/example/addon/mixin/ExampleMixin.java | 31 +++++ .../example/addon/modules/ModuleExample.java | 60 ++++++++- src/main/resources/addon-template.mixins.json | 6 +- src/main/resources/fabric.mod.json | 8 +- 14 files changed, 379 insertions(+), 42 deletions(-) create mode 100644 LICENSE rename src/main/java/com/example/addon/{Addon.java => AddonTemplate.java} (84%) create mode 100644 src/main/java/com/example/addon/mixin/ExampleMixin.java diff --git a/.github/workflows/dev_build.yml b/.github/workflows/dev_build.yml index 672d502..f58efd0 100644 --- a/.github/workflows/dev_build.yml +++ b/.github/workflows/dev_build.yml @@ -5,12 +5,16 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-java@v2 + - name: Checkout Repository + uses: actions/checkout@v4 + - name: Wrapper Validation + uses: gradle/actions/wrapper-validation@v3 + - name: Set up Java + uses: actions/setup-java@v4 with: - java-version: 17 + java-version: 21 distribution: adopt - - name: Build + - name: Build with Gradle run: ./gradlew build - name: Release uses: marvinpinto/action-automatic-releases@latest diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index e60e76d..e0b5026 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -1,19 +1,23 @@ -name: Build Pull Request +name: Build Pull Request Artifacts on: pull_request jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-java@v2 + - name: Checkout Repository + uses: actions/checkout@v4 + - name: Wrapper Validation + uses: gradle/actions/wrapper-validation@v3 + - name: Set up Java + uses: actions/setup-java@v4 with: - java-version: 17 + java-version: 21 distribution: adopt - - name: Build + - name: Build with Gradle run: ./gradlew build - - name: Upload artifacts - uses: actions/upload-artifact@v2.2.4 + - name: Release + uses: actions/upload-artifact@v4 with: - name: build-artifacts - path: build/libs + name: Artifacts + path: build/libs/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0e259d4 --- /dev/null +++ b/LICENSE @@ -0,0 +1,121 @@ +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. diff --git a/README.md b/README.md index 90b04e9..c246d08 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,80 @@ A template to allow easy usage of the Meteor Addon API. -### How to use: +### How to use + - Clone this project - Use this template to create new modules/commands -- Run the mod with Meteor. \ No newline at end of file +- Build the executable using the gradle `build` task. +- Run the mod with Meteor. + +### Project structure + +```text +. +│── .github +│ ╰── workflows +│ │── dev_build.yml +│ ╰── pull_request.yml +│── gradle +│ ╰── wrapper +│ │── gradle-wrapper.jar +│ ╰── gradle-wrapper.properties +│── src +│ ╰── main +│ │── java +│ │ ╰── com +│ │ ╰── example +│ │ ╰── addon +│ │ │── commands +│ │ │ ╰── CommandExample +│ │ │── hud +│ │ │ ╰── HudExample +│ │ │── modules +│ │ │ ╰── ModuleExample +│ │ ╰── AddonTemplate +│ ╰── resources +│ │── assets +│ │ ╰── template +│ │ ╰── icon.png +│ │── addon-template.mixins.json +│ ╰── fabric.mod.json +│── .editorconfig +│── .gitignore +│── build.gradle +│── gradle.properties +│── gradlew +│── gradlew.bat +│── LICENSE +│── README.md +╰── settings.gradle +``` + +This is the default project structure. Each folder/file has a specific purpose. +Here is a brief explanation of the ones you might need to modify: + +- `.github/workflows`: Contains the GitHub Actions configuration files. +- `gradle`: Contains the Gradle wrapper files. + Edit the `gradle.properties` file to change the version of the Gradle wrapper. +- `src/main/java/com/example/addon`: Contains the main class of the addon. + Here you can register your custom commands, modules, and HUDs. + Edit the `getPackage` method to reflect the package of your addon. +- `src/main/resources`: Contains the resources of the addon. + - `assets`: Contains the assets of the addon. + You can add your own assets here, separated in subfolders. + - `template`: Contains the assets of the template. + You can replace the `icon.png` file with your own addon icon. + Also, rename this folder to reflect the name of your addon. + - `addon-template.mixins.json`: Contains the Mixin configuration for the addon. + You can add your own mixins in the `client` array. + - `fabric.mod.json`: Contains the metadata of the addon. + Edit the various fields to reflect the metadata of your addon. +- `build.gradle`: Contains the Gradle build script. + You can manage the dependencies of the addon here. + Remember to keep the `fabric-loom` version up-to-date. +- `gradle.properties`: Contains the properties of the Gradle build. + These will be used by the build script. +- `LICENSE`: Contains the license of the addon. + You can edit this file to change the license of your addon. +- `README.md`: Contains the documentation of the addon. + You can edit this file to reflect the documentation of your addon, and showcase its features. diff --git a/build.gradle b/build.gradle index 55d4ace..5acdf0d 100644 --- a/build.gradle +++ b/build.gradle @@ -2,11 +2,11 @@ plugins { id "fabric-loom" version "1.6-SNAPSHOT" } -sourceCompatibility = targetCompatibility = JavaVersion.VERSION_17 - -archivesBaseName = project.archives_base_name -version = project.mod_version -group = project.maven_group +base { + archivesBaseName = project.archives_base_name + version = project.mod_version + group = project.maven_group +} repositories { maven { @@ -29,12 +29,31 @@ dependencies { modImplementation "meteordevelopment:meteor-client:${project.meteor_version}" } -processResources { - filesMatching("fabric.mod.json") { - expand "version": project.version, "mc_version": project.minecraft_version +tasks { + processResources { + def propertyMap = [ + "version" : project.version, + "mc_version": project.minecraft_version, + ] + + filesMatching("fabric.mod.json") { + expand(propertyMap) + } } -} -tasks.withType(JavaCompile).configureEach { - it.options.encoding("UTF-8") + jar { + from("LICENSE") { + rename { "${it}_${project.base.archivesBaseName}" } + } + } + + java { + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 + } + + tasks.withType(JavaCompile).configureEach { + it.options.encoding = "UTF-8" + it.options.release = 21 + } } diff --git a/gradle.properties b/gradle.properties index 1438b6a..ed22e78 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,9 +1,9 @@ org.gradle.jvmargs=-Xmx2G # Fabric Properties (https://fabricmc.net/develop) -minecraft_version=1.20.4 -yarn_mappings=1.20.4+build.2 -loader_version=0.15.1 +minecraft_version=1.20.6 +yarn_mappings=1.20.6+build.1 +loader_version=0.15.10 # Mod Properties mod_version=0.1.0 @@ -13,4 +13,4 @@ archives_base_name=addon-template # Dependencies # Meteor (https://maven.meteordev.org) -meteor_version=0.5.6-SNAPSHOT +meteor_version=0.5.7-SNAPSHOT diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 509c4a2..b82aa23 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/java/com/example/addon/Addon.java b/src/main/java/com/example/addon/AddonTemplate.java similarity index 84% rename from src/main/java/com/example/addon/Addon.java rename to src/main/java/com/example/addon/AddonTemplate.java index bafcd47..3bd07af 100644 --- a/src/main/java/com/example/addon/Addon.java +++ b/src/main/java/com/example/addon/AddonTemplate.java @@ -4,6 +4,7 @@ import com.example.addon.hud.HudExample; import com.example.addon.modules.ModuleExample; import com.mojang.logging.LogUtils; +import meteordevelopment.meteorclient.addons.GithubRepo; import meteordevelopment.meteorclient.addons.MeteorAddon; import meteordevelopment.meteorclient.commands.Commands; import meteordevelopment.meteorclient.systems.hud.Hud; @@ -12,7 +13,7 @@ import meteordevelopment.meteorclient.systems.modules.Modules; import org.slf4j.Logger; -public class Addon extends MeteorAddon { +public class AddonTemplate extends MeteorAddon { public static final Logger LOG = LogUtils.getLogger(); public static final Category CATEGORY = new Category("Example"); public static final HudGroup HUD_GROUP = new HudGroup("Example"); @@ -40,4 +41,9 @@ public void onRegisterCategories() { public String getPackage() { return "com.example.addon"; } + + @Override + public GithubRepo getRepo() { + return new GithubRepo("MeteorDevelopment", "meteor-addon-template"); + } } diff --git a/src/main/java/com/example/addon/commands/CommandExample.java b/src/main/java/com/example/addon/commands/CommandExample.java index 94dfdf9..06ec3ae 100644 --- a/src/main/java/com/example/addon/commands/CommandExample.java +++ b/src/main/java/com/example/addon/commands/CommandExample.java @@ -1,12 +1,19 @@ package com.example.addon.commands; +import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import meteordevelopment.meteorclient.commands.Command; import net.minecraft.command.CommandSource; import static com.mojang.brigadier.Command.SINGLE_SUCCESS; +/** + * The Meteor Client command API uses the same command system as Minecraft does. + */ public class CommandExample extends Command { + /** + * The {@code name} parameter should be in kebab-case. + */ public CommandExample() { super("example", "Sends a message."); } @@ -17,5 +24,11 @@ public void build(LiteralArgumentBuilder builder) { info("hi"); return SINGLE_SUCCESS; }); + + builder.then(literal("name").then(argument("nameArgument", StringArgumentType.word()).executes(context -> { + String argument = StringArgumentType.getString(context, "nameArgument"); + info("hi, " + argument); + return SINGLE_SUCCESS; + }))); } } diff --git a/src/main/java/com/example/addon/hud/HudExample.java b/src/main/java/com/example/addon/hud/HudExample.java index 9b2622d..bdf5928 100644 --- a/src/main/java/com/example/addon/hud/HudExample.java +++ b/src/main/java/com/example/addon/hud/HudExample.java @@ -1,13 +1,16 @@ package com.example.addon.hud; -import com.example.addon.Addon; +import com.example.addon.AddonTemplate; import meteordevelopment.meteorclient.systems.hud.HudElement; import meteordevelopment.meteorclient.systems.hud.HudElementInfo; import meteordevelopment.meteorclient.systems.hud.HudRenderer; import meteordevelopment.meteorclient.utils.render.color.Color; public class HudExample extends HudElement { - public static final HudElementInfo INFO = new HudElementInfo<>(Addon.HUD_GROUP, "example", "HUD element example.", HudExample::new); + /** + * The {@code name} parameter should be in kebab-case. + */ + public static final HudElementInfo INFO = new HudElementInfo<>(AddonTemplate.HUD_GROUP, "example", "HUD element example.", HudExample::new); public HudExample() { super(INFO); @@ -17,6 +20,10 @@ public HudExample() { public void render(HudRenderer renderer) { setSize(renderer.textWidth("Example element", true), renderer.textHeight(true)); + // Render background + renderer.quad(x, y, getWidth(), getHeight(), Color.LIGHT_GRAY); + + // Render text renderer.text("Example element", x, y, Color.WHITE, true); } } diff --git a/src/main/java/com/example/addon/mixin/ExampleMixin.java b/src/main/java/com/example/addon/mixin/ExampleMixin.java new file mode 100644 index 0000000..a5556c2 --- /dev/null +++ b/src/main/java/com/example/addon/mixin/ExampleMixin.java @@ -0,0 +1,31 @@ +package com.example.addon.mixin; + +import com.example.addon.AddonTemplate; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.RunArgs; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +/** + * Example Mixin class. + * For more resources, visit: + * + */ +@Mixin(MinecraftClient.class) +public abstract class ExampleMixin { + /** + * Example Mixin injection targeting the {@code } method (the constructor) at {@code TAIL} (end of method). + */ + @Inject(method = "", at = @At("TAIL")) + private void onGameLoaded(RunArgs args, CallbackInfo ci) { + AddonTemplate.LOG.info("Hello from ExampleMixin!"); + } +} diff --git a/src/main/java/com/example/addon/modules/ModuleExample.java b/src/main/java/com/example/addon/modules/ModuleExample.java index 2563056..10a4bb6 100644 --- a/src/main/java/com/example/addon/modules/ModuleExample.java +++ b/src/main/java/com/example/addon/modules/ModuleExample.java @@ -1,10 +1,66 @@ package com.example.addon.modules; -import com.example.addon.Addon; +import com.example.addon.AddonTemplate; +import meteordevelopment.meteorclient.events.render.Render3DEvent; +import meteordevelopment.meteorclient.renderer.ShapeMode; +import meteordevelopment.meteorclient.settings.ColorSetting; +import meteordevelopment.meteorclient.settings.DoubleSetting; +import meteordevelopment.meteorclient.settings.Setting; +import meteordevelopment.meteorclient.settings.SettingGroup; import meteordevelopment.meteorclient.systems.modules.Module; +import meteordevelopment.meteorclient.utils.render.color.Color; +import meteordevelopment.meteorclient.utils.render.color.SettingColor; +import meteordevelopment.orbit.EventHandler; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; public class ModuleExample extends Module { + private final SettingGroup sgGeneral = this.settings.getDefaultGroup(); + private final SettingGroup sgRender = this.settings.createGroup("Render"); + + /** + * Example setting. + * The {@code name} parameter should be in kebab-case. + * If you want to access the setting from another class, simply make the setting {@code public}, and use + * {@link meteordevelopment.meteorclient.systems.modules.Modules#get(Class)} to access the {@link Module} object. + */ + private final Setting scale = sgGeneral.add(new DoubleSetting.Builder() + .name("scale") + .description("The size of the marker.") + .defaultValue(2.0d) + .range(0.5d, 10.0d) + .build() + ); + + private final Setting color = sgRender.add(new ColorSetting.Builder() + .name("color") + .description("The color of the marker.") + .defaultValue(Color.MAGENTA) + .build() + ); + + /** + * The {@code name} parameter should be in kebab-case. + */ public ModuleExample() { - super(Addon.CATEGORY, "example", "An example module in a custom category."); + super(AddonTemplate.CATEGORY, "world-origin", "An example module that highlights the center of the world."); + } + + /** + * Example event handling method. + * Requires {@link AddonTemplate#getPackage()} to be setup correctly, will fail silently otherwise. + */ + @EventHandler + private void onRender3d(Render3DEvent event) { + // Create & stretch the marker object + Box marker = new Box(BlockPos.ORIGIN); + marker.stretch( + scale.get() * marker.getLengthX(), + scale.get() * marker.getLengthY(), + scale.get() * marker.getLengthZ() + ); + + // Render the marker based on the color setting + event.renderer.box(marker, color.get(), color.get(), ShapeMode.Both, 0); } } diff --git a/src/main/resources/addon-template.mixins.json b/src/main/resources/addon-template.mixins.json index 93b5dde..39d1c99 100644 --- a/src/main/resources/addon-template.mixins.json +++ b/src/main/resources/addon-template.mixins.json @@ -1,8 +1,10 @@ { "required": true, "package": "com.example.addon.mixin", - "compatibilityLevel": "JAVA_17", - "client": [], + "compatibilityLevel": "JAVA_21", + "client": [ + "ExampleMixin" + ], "injectors": { "defaultRequire": 1 } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 207242a..cff022b 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -3,7 +3,7 @@ "id": "addon-template", "version": "${version}", "name": "Addon Template", - "description": "An addon template for the Meteor addons.", + "description": "An addon template for Meteor Client addons.", "authors": [ "seasnail" ], @@ -14,7 +14,7 @@ "environment": "client", "entrypoints": { "meteor": [ - "com.example.addon.Addon" + "com.example.addon.AddonTemplate" ] }, "mixins": [ @@ -24,8 +24,8 @@ "meteor-client:color": "225,25,25" }, "depends": { - "java": ">=17", - "minecraft": ">=${mc_version}", + "java": ">=21", + "minecraft": ["1.20.5","${mc_version}"], "meteor-client": "*" } }