optionalBoolean) {
39 | return requiredString + " " + optionalBoolean.orElse(false);
40 | }
41 |
42 | /**
43 | * sub command examples
44 | */
45 | @CommandExecutor(subCommand = "list")
46 | private String exampleList() {
47 | return String.join(", ", this.stringList);
48 | }
49 |
50 | @CommandExecutor(subCommand = "add")
51 | @CommandExecutor.Argument("string") //must set argument names
52 | private String addToExampleList(String string) {
53 | this.stringList.add(string);
54 | return "Added " + string;
55 | }
56 |
57 | @CommandExecutor(subCommand = {"remove", "del"})
58 | @CommandExecutor.Argument("string") //must set argument names
59 | private String removeFromExampleList(String string) {
60 | if(this.stringList.remove(string)) {
61 | return "Removed " + string;
62 | }
63 | return string + " not found";
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/src/main/java/org/example/ExampleHudElement.java:
--------------------------------------------------------------------------------
1 | package org.example;
2 |
3 | import org.rusherhack.client.api.feature.hud.ResizeableHudElement;
4 | import org.rusherhack.client.api.render.RenderContext;
5 | import org.rusherhack.client.api.render.graphic.TextureGraphic;
6 |
7 | /**
8 | * Example rusherhack hud element
9 | *
10 | * There are other hud element types than ResizeableHudElement, look at the other classes in the package
11 | *
12 | * @author John200410
13 | */
14 | public class ExampleHudElement extends ResizeableHudElement {
15 |
16 | private TextureGraphic graphic = null;
17 |
18 | public ExampleHudElement() {
19 | super("ExampleHudElement");
20 |
21 | //try loading graphic
22 | try {
23 | this.graphic = new TextureGraphic("exampleplugin/graphics/rh_head.png", 235, 234);
24 | } catch (Throwable t) {
25 | this.getLogger().error("Failed to load graphic", t);
26 | }
27 | }
28 |
29 | @Override
30 | public void renderContent(RenderContext context, double mouseX, double mouseY) {
31 | //positions are relative to the top left corner of the hud element, so start drawing stuff from 0,0
32 |
33 | if (this.graphic != null) {
34 | this.getRenderer().drawGraphicRectangle(this.graphic, 0, 0, this.getWidth(), this.getHeight());
35 | }
36 | }
37 |
38 | @Override
39 | public double getWidth() {
40 | return 200;
41 | }
42 |
43 | @Override
44 | public double getHeight() {
45 | return 200;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/org/example/ExampleModule.java:
--------------------------------------------------------------------------------
1 | package org.example;
2 |
3 | import net.minecraft.world.entity.Entity;
4 | import net.minecraft.world.entity.LivingEntity;
5 | import org.rusherhack.client.api.RusherHackAPI;
6 | import org.rusherhack.client.api.events.client.EventUpdate;
7 | import org.rusherhack.client.api.events.render.EventRender2D;
8 | import org.rusherhack.client.api.events.render.EventRender3D;
9 | import org.rusherhack.client.api.feature.module.ModuleCategory;
10 | import org.rusherhack.client.api.feature.module.ToggleableModule;
11 | import org.rusherhack.client.api.render.IRenderer2D;
12 | import org.rusherhack.client.api.render.IRenderer3D;
13 | import org.rusherhack.client.api.render.font.IFontRenderer;
14 | import org.rusherhack.client.api.setting.BindSetting;
15 | import org.rusherhack.client.api.setting.ColorSetting;
16 | import org.rusherhack.client.api.utils.ChatUtils;
17 | import org.rusherhack.client.api.utils.WorldUtils;
18 | import org.rusherhack.core.bind.key.NullKey;
19 | import org.rusherhack.core.event.subscribe.Subscribe;
20 | import org.rusherhack.core.setting.BooleanSetting;
21 | import org.rusherhack.core.setting.NumberSetting;
22 | import org.rusherhack.core.setting.StringSetting;
23 | import org.rusherhack.core.utils.ColorUtils;
24 |
25 | import java.awt.*;
26 |
27 | /**
28 | * Example rusherhack module
29 | *
30 | * @author John200410
31 | */
32 | public class ExampleModule extends ToggleableModule {
33 |
34 | /**
35 | * Settings
36 | */
37 | private final BooleanSetting exampleBoolean = new BooleanSetting("Boolean", "Settings can optionally have a description", true);
38 |
39 | private final NumberSetting exampleDouble = new NumberSetting<>("Double", 0.0, -10.0, 10.0)
40 |
41 | //specifies incremental step for precise numbers
42 | .incremental(0.1)
43 |
44 | //predicate that determines conditions for the setting to be visible in the clickgui
45 | .setVisibility(this.exampleBoolean::getValue)
46 |
47 | //consumer that is called when the setting is changed
48 | .onChange(d -> ChatUtils.print("Changed double to " + d));
49 |
50 | private final ColorSetting exampleColor = new ColorSetting("Color", Color.CYAN)
51 |
52 | //set whether alpha is enabled in the color picker
53 | .setAlphaAllowed(false)
54 |
55 | //sync the color with the theme color
56 | .setThemeSync(true);
57 |
58 | private final StringSetting exampleString = new StringSetting("String", "Hello World!")
59 |
60 | //disables the rendering of the setting name in the clickgui
61 | .setNameVisible(false);
62 |
63 | private final BindSetting rotate = new BindSetting("RotateBind", NullKey.INSTANCE /* unbound */);
64 | private final NumberSetting rotateYaw = new NumberSetting<>("Yaw", 0f, 0f, 360f).incremental(0.1f);
65 | private final NumberSetting rotatePitch = new NumberSetting<>("Pitch", 0f, -90f, 90f).incremental(0.1f);
66 |
67 | /**
68 | * Constructor
69 | */
70 | public ExampleModule() {
71 | super("Example", "Example plugin module", ModuleCategory.CLIENT);
72 |
73 | //subsettings
74 | this.rotate.addSubSettings(this.rotateYaw, this.rotatePitch);
75 |
76 | //register settings
77 | this.registerSettings(
78 | this.exampleBoolean,
79 | this.exampleDouble,
80 | this.exampleColor,
81 | this.exampleString,
82 | this.rotate
83 | );
84 | }
85 |
86 | /**
87 | * 2d renderer demo
88 | */
89 | @Subscribe
90 | private void onRender2D(EventRender2D event) {
91 |
92 | //renderers
93 | final IRenderer2D renderer = RusherHackAPI.getRenderer2D();
94 | final IFontRenderer fontRenderer = RusherHackAPI.fonts().getFontRenderer();
95 |
96 | //must begin renderer first
97 | renderer.begin(event.getMatrixStack(), fontRenderer);
98 |
99 | //draw stuff
100 | renderer.drawRectangle(100, 100 + this.exampleDouble.getValue(), 100, 100, this.exampleColor.getValueRGB());
101 | fontRenderer.drawString(this.exampleString.getValue(), 110, 110, Color.WHITE.getRGB());
102 |
103 | //end renderer
104 | renderer.end();
105 |
106 | }
107 |
108 | /**
109 | * Rotation demo
110 | */
111 | @Subscribe
112 | private void onUpdate(EventUpdate event) {
113 |
114 | //only rotate while bind is held
115 | if(this.rotate.getValue().isKeyDown()) {
116 |
117 | //loop through entities to find a target
118 | Entity target = null;
119 | double dist = 999d;
120 | for(Entity entity : WorldUtils.getEntitiesSorted()) {
121 | if(mc.player.distanceTo(entity) < dist && entity instanceof LivingEntity) {
122 | target = entity;
123 | dist = mc.player.distanceTo(entity);
124 | }
125 | }
126 |
127 | //rotate to target
128 | if(target != null) {
129 | RusherHackAPI.getRotationManager().updateRotation(target);
130 | } else { //or rotate to the custom yaw
131 | RusherHackAPI.getRotationManager().updateRotation(this.rotateYaw.getValue(), this.rotatePitch.getValue());
132 | }
133 | }
134 | }
135 |
136 | //3d renderer demo
137 | @Subscribe
138 | private void onRender3D(EventRender3D event) {
139 | final IRenderer3D renderer = event.getRenderer();
140 |
141 | final int color = ColorUtils.transparency(this.exampleColor.getValueRGB(), 0.5f); //fill colors look better when the alpha is not 100%
142 |
143 | //begin renderer
144 | renderer.begin(event.getMatrixStack());
145 |
146 | //highlight targets
147 | for(Entity entity : WorldUtils.getEntities()) {
148 | renderer.drawBox(entity, event.getPartialTicks(), true, true, color);
149 | }
150 |
151 | //end renderer
152 | renderer.end();
153 | }
154 |
155 | @Override
156 | public void onEnable() {
157 | if(mc.level != null) {
158 | ChatUtils.print("Hello World! Example module is enabled");
159 | }
160 | }
161 |
162 | @Override
163 | public void onDisable() {
164 | if(mc.level != null) {
165 | ChatUtils.print("Goodbye World! Example module has been disabled");
166 | }
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/src/main/java/org/example/ExamplePlugin.java:
--------------------------------------------------------------------------------
1 | package org.example;
2 |
3 | import org.rusherhack.client.api.RusherHackAPI;
4 | import org.rusherhack.client.api.plugin.Plugin;
5 |
6 | /**
7 | * Example rusherhack plugin
8 | *
9 | * @author John200410
10 | */
11 | public class ExamplePlugin extends Plugin {
12 |
13 | @Override
14 | public void onLoad() {
15 |
16 | //logger
17 | this.getLogger().info("Hello World!");
18 |
19 | //creating and registering a new module
20 | final ExampleModule exampleModule = new ExampleModule();
21 | RusherHackAPI.getModuleManager().registerFeature(exampleModule);
22 |
23 | //creating and registering a new hud element
24 | final ExampleHudElement exampleHudElement = new ExampleHudElement();
25 | RusherHackAPI.getHudManager().registerFeature(exampleHudElement);
26 |
27 | //creating and registering a new command
28 | final ExampleCommand exampleCommand = new ExampleCommand();
29 | RusherHackAPI.getCommandManager().registerFeature(exampleCommand);
30 | }
31 |
32 | @Override
33 | public void onUnload() {
34 | this.getLogger().info("Example plugin unloaded!");
35 | }
36 |
37 | }
--------------------------------------------------------------------------------
/src/main/resources/exampleplugin/graphics/rh_head.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RusherDevelopment/example-plugin/dc02b0d5d7876bc9fb8935dabdf20cbdc5da9656/src/main/resources/exampleplugin/graphics/rh_head.png
--------------------------------------------------------------------------------
/src/main/resources/rusherhack-plugin.json:
--------------------------------------------------------------------------------
1 | {
2 | "Plugin-Class": "org.example.ExamplePlugin",
3 | "Name": "${project.plugin_name}",
4 | "Version": "${project.plugin_version}",
5 | "Description": "Example rusherhack plugin",
6 | "URL": "https://github.com/RusherDevelopment/example-plugin",
7 | "Authors": [
8 | "John200410"
9 | ],
10 | "Minecraft-Versions": [
11 | "${project.minecraft_version}"
12 | ]
13 | }
--------------------------------------------------------------------------------