diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..62c5073 --- /dev/null +++ b/.clang-format @@ -0,0 +1,35 @@ +# .clang-format +BasedOnStyle: LLVM + +# never wrap +ColumnLimit: 0 +ReflowComments: false +BreakStringLiterals: false + +# keep call args/params on one line +BinPackArguments: true +BinPackParameters: true +AllowAllArgumentsOnNextLine: true +PenaltyBreakBeforeFirstCallParameter: 1000000 + +# your other prefs… +UseTab: ForIndentation +ContinuationIndentWidth: 4 +AlignAfterOpenBracket: DontAlign +AlignOperands: false +IndentWidth: 4 +TabWidth: 4 +MaxEmptyLinesToKeep: 1 +SeparateDefinitionBlocks: Always +AllowShortIfStatementsOnASingleLine: true # (or: WithoutElse on newer versions) +KeepEmptyLinesAtTheStartOfBlocks: true + +SortIncludes: true +IncludeBlocks: Preserve + +# never keep {} on one line (forces multi-line bodies) +AllowShortFunctionsOnASingleLine: false +AllowShortBlocksOnASingleLine: Never + +--- +Language: Java diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml new file mode 100644 index 0000000..7d48833 --- /dev/null +++ b/.github/workflows/cd.yml @@ -0,0 +1,45 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. +# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle +name: Continuous Deployment + +on: + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - uses: actions/checkout@v4 + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: "21" + distribution: "microsoft" + + - name: Make Gradle wrapper executable + run: chmod +x ./gradlew + + # Get version from gradle.properties setting it as an environment variable + - name: Get Version + id: get_version + run: | + version=$(grep '^plugin_version' gradle.properties | cut -d'=' -f2 | xargs) + echo "version=$version" >> $GITHUB_ENV + + - name: Build with Gradle Wrapper + run: ./gradlew build --no-daemon + + - name: Create Release + uses: softprops/action-gh-release@v1 + with: + draft: false + generate_release_notes: true + tag_name: v${{ env.version }} + files: build/libs/*.jar diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..6511a01 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "githubPullRequests.ignoredPullRequestBranches": [ + "master" + ], + "java.configuration.updateBuildConfiguration": "automatic" +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 40245ad..c6c9541 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ plugins { version = project.plugin_version group = project.maven_group -archivesBaseName = project.plugin_name +archivesBaseName = project.plugin_id configurations { rusherhackApi diff --git a/gradle.properties b/gradle.properties index e6172fb..4a75e82 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,24 +1,23 @@ # Done to increase the memory available to gradle. -org.gradle.jvmargs=-Xmx1G +org.gradle.jvmargs=-Xmx2G -# plugin name -plugin_name = example-plugin - -# plugin version +# plugin info +plugin_id = example-plugin +plugin_name = Example Plugin plugin_version = 1.0.0 maven_group = org.example # use java 17 for minecraft versions 1.20.4 and older # use java 21 for minecraft versions 1.20.5 and newer -java_version = 17 +java_version = 21 # minecraft version to compile with # other supported versions of the game can be added in rusherhack-plugin.json -minecraft_version = 1.20.1 +minecraft_version = 1.21.4 # parchment mappings -parchment_version = 1.20.1:2023.09.03 +parchment_version = 1.21.4:2025.03.23 # fabric loader version -fabric_loader_version = 0.16.9 \ No newline at end of file +fabric_loader_version = 0.17.2 \ No newline at end of file diff --git a/src/main/java/org/example/ExampleCommand.java b/src/main/java/org/example/ExampleCommand.java index 3d127a7..22da130 100644 --- a/src/main/java/org/example/ExampleCommand.java +++ b/src/main/java/org/example/ExampleCommand.java @@ -1,12 +1,11 @@ package org.example; -import org.rusherhack.client.api.feature.command.Command; -import org.rusherhack.core.command.annotations.CommandExecutor; - import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Optional; +import org.rusherhack.client.api.feature.command.Command; +import org.rusherhack.core.command.annotations.CommandExecutor; /** * Example rusherhack command @@ -14,31 +13,32 @@ * @author John200410 */ public class ExampleCommand extends Command { - + private final List stringList = new ArrayList<>(Arrays.asList("test1", "test2")); - + public ExampleCommand() { super("ExampleCommand", "description"); } - + /** * base command that takes in no arguments */ @CommandExecutor private String example() { - //when return type is String you return the message you want to return to the user + // when return type is String you return the message you want to return to + // the user return "Hello World!"; } - + /** * arguments example */ @CommandExecutor - @CommandExecutor.Argument({"string", "boolean"}) //must set argument names + @CommandExecutor.Argument({"string", "boolean"}) // must set argument names private String exampleWithArguments(String requiredString, Optional optionalBoolean) { return requiredString + " " + optionalBoolean.orElse(false); } - + /** * sub command examples */ @@ -46,21 +46,20 @@ private String exampleWithArguments(String requiredString, Optional opt private String exampleList() { return String.join(", ", this.stringList); } - + @CommandExecutor(subCommand = "add") - @CommandExecutor.Argument("string") //must set argument names + @CommandExecutor.Argument("string") // must set argument names private String addToExampleList(String string) { this.stringList.add(string); return "Added " + string; } - + @CommandExecutor(subCommand = {"remove", "del"}) - @CommandExecutor.Argument("string") //must set argument names + @CommandExecutor.Argument("string") // must set argument names private String removeFromExampleList(String string) { - if(this.stringList.remove(string)) { + if (this.stringList.remove(string)) { return "Removed " + string; } return string + " not found"; } - } diff --git a/src/main/java/org/example/ExampleHudElement.java b/src/main/java/org/example/ExampleHudElement.java index be33494..fcdb3d0 100644 --- a/src/main/java/org/example/ExampleHudElement.java +++ b/src/main/java/org/example/ExampleHudElement.java @@ -12,12 +12,12 @@ * @author John200410 */ public class ExampleHudElement extends ResizeableHudElement { - + private TextureGraphic graphic = null; - + public ExampleHudElement() { super("ExampleHudElement"); - + //try loading graphic try { this.graphic = new TextureGraphic("exampleplugin/graphics/rh_head.png", 235, 234); @@ -25,21 +25,21 @@ public ExampleHudElement() { this.getLogger().error("Failed to load graphic", t); } } - + @Override public void renderContent(RenderContext context, double mouseX, double mouseY) { //positions are relative to the top left corner of the hud element, so start drawing stuff from 0,0 - + if (this.graphic != null) { this.getRenderer().drawGraphicRectangle(this.graphic, 0, 0, this.getWidth(), this.getHeight()); } } - + @Override public double getWidth() { return 200; } - + @Override public double getHeight() { return 200; diff --git a/src/main/java/org/example/ExampleModule.java b/src/main/java/org/example/ExampleModule.java index e1ec889..f85effd 100644 --- a/src/main/java/org/example/ExampleModule.java +++ b/src/main/java/org/example/ExampleModule.java @@ -1,5 +1,6 @@ package org.example; +import java.awt.*; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; import org.rusherhack.client.api.RusherHackAPI; @@ -22,146 +23,142 @@ import org.rusherhack.core.setting.StringSetting; import org.rusherhack.core.utils.ColorUtils; -import java.awt.*; - /** * Example rusherhack module * * @author John200410 */ public class ExampleModule extends ToggleableModule { - + /** * Settings */ private final BooleanSetting exampleBoolean = new BooleanSetting("Boolean", "Settings can optionally have a description", true); - + private final NumberSetting exampleDouble = new NumberSetting<>("Double", 0.0, -10.0, 10.0) - - //specifies incremental step for precise numbers - .incremental(0.1) - - //predicate that determines conditions for the setting to be visible in the clickgui - .setVisibility(this.exampleBoolean::getValue) - - //consumer that is called when the setting is changed - .onChange(d -> ChatUtils.print("Changed double to " + d)); - + + //specifies incremental step for precise numbers + .incremental(0.1) + + //predicate that determines conditions for the setting to be visible in the clickgui + .setVisibility(this.exampleBoolean::getValue) + + //consumer that is called when the setting is changed + .onChange(d -> ChatUtils.print("Changed double to " + d)); + private final ColorSetting exampleColor = new ColorSetting("Color", Color.CYAN) - - //set whether alpha is enabled in the color picker - .setAlphaAllowed(false) - - //sync the color with the theme color - .setThemeSync(true); - + + //set whether alpha is enabled in the color picker + .setAlphaAllowed(false) + + //sync the color with the theme color + .setThemeSync(true); + private final StringSetting exampleString = new StringSetting("String", "Hello World!") - - //disables the rendering of the setting name in the clickgui - .setNameVisible(false); - + + //disables the rendering of the setting name in the clickgui + .setNameVisible(false); + private final BindSetting rotate = new BindSetting("RotateBind", NullKey.INSTANCE /* unbound */); private final NumberSetting rotateYaw = new NumberSetting<>("Yaw", 0f, 0f, 360f).incremental(0.1f); private final NumberSetting rotatePitch = new NumberSetting<>("Pitch", 0f, -90f, 90f).incremental(0.1f); - + /** * Constructor */ public ExampleModule() { super("Example", "Example plugin module", ModuleCategory.CLIENT); - + //subsettings this.rotate.addSubSettings(this.rotateYaw, this.rotatePitch); - + //register settings this.registerSettings( - this.exampleBoolean, - this.exampleDouble, - this.exampleColor, - this.exampleString, - this.rotate - ); + this.exampleBoolean, + this.exampleDouble, + this.exampleColor, + this.exampleString, + this.rotate); } - + /** * 2d renderer demo */ @Subscribe private void onRender2D(EventRender2D event) { - + //renderers final IRenderer2D renderer = RusherHackAPI.getRenderer2D(); final IFontRenderer fontRenderer = RusherHackAPI.fonts().getFontRenderer(); - + //must begin renderer first renderer.begin(event.getMatrixStack(), fontRenderer); - + //draw stuff renderer.drawRectangle(100, 100 + this.exampleDouble.getValue(), 100, 100, this.exampleColor.getValueRGB()); fontRenderer.drawString(this.exampleString.getValue(), 110, 110, Color.WHITE.getRGB()); - + //end renderer renderer.end(); - } - + /** * Rotation demo */ @Subscribe private void onUpdate(EventUpdate event) { - + //only rotate while bind is held - if(this.rotate.getValue().isKeyDown()) { - + if (this.rotate.getValue().isKeyDown()) { + //loop through entities to find a target Entity target = null; double dist = 999d; - for(Entity entity : WorldUtils.getEntitiesSorted()) { - if(mc.player.distanceTo(entity) < dist && entity instanceof LivingEntity) { + for (Entity entity : WorldUtils.getEntitiesSorted()) { + if (mc.player.distanceTo(entity) < dist && entity instanceof LivingEntity) { target = entity; dist = mc.player.distanceTo(entity); } } - + //rotate to target - if(target != null) { + if (target != null) { RusherHackAPI.getRotationManager().updateRotation(target); } else { //or rotate to the custom yaw RusherHackAPI.getRotationManager().updateRotation(this.rotateYaw.getValue(), this.rotatePitch.getValue()); } } } - + //3d renderer demo @Subscribe private void onRender3D(EventRender3D event) { final IRenderer3D renderer = event.getRenderer(); - + final int color = ColorUtils.transparency(this.exampleColor.getValueRGB(), 0.5f); //fill colors look better when the alpha is not 100% - + //begin renderer renderer.begin(event.getMatrixStack()); - + //highlight targets - for(Entity entity : WorldUtils.getEntities()) { + for (Entity entity : WorldUtils.getEntities()) { renderer.drawBox(entity, event.getPartialTicks(), true, true, color); } - + //end renderer renderer.end(); } - + @Override public void onEnable() { - if(mc.level != null) { + if (mc.level != null) { ChatUtils.print("Hello World! Example module is enabled"); } } - + @Override public void onDisable() { - if(mc.level != null) { + if (mc.level != null) { ChatUtils.print("Goodbye World! Example module has been disabled"); } } diff --git a/src/main/java/org/example/ExamplePlugin.java b/src/main/java/org/example/ExamplePlugin.java index 47c5472..7826ed7 100644 --- a/src/main/java/org/example/ExamplePlugin.java +++ b/src/main/java/org/example/ExamplePlugin.java @@ -9,29 +9,28 @@ * @author John200410 */ public class ExamplePlugin extends Plugin { - + @Override public void onLoad() { - + //logger this.getLogger().info("Hello World!"); - + //creating and registering a new module final ExampleModule exampleModule = new ExampleModule(); RusherHackAPI.getModuleManager().registerFeature(exampleModule); - + //creating and registering a new hud element final ExampleHudElement exampleHudElement = new ExampleHudElement(); RusherHackAPI.getHudManager().registerFeature(exampleHudElement); - + //creating and registering a new command final ExampleCommand exampleCommand = new ExampleCommand(); RusherHackAPI.getCommandManager().registerFeature(exampleCommand); } - + @Override public void onUnload() { this.getLogger().info("Example plugin unloaded!"); } - } \ No newline at end of file