-
Notifications
You must be signed in to change notification settings - Fork 29
Expand file tree
/
Copy pathAutoClicker.java
More file actions
352 lines (311 loc) · 13.3 KB
/
AutoClicker.java
File metadata and controls
352 lines (311 loc) · 13.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
package pro.mikey.autoclicker;
import com.google.gson.Gson;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.render.RenderTickCounter;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.entity.LivingEntity;
import net.minecraft.item.ShieldItem;
import net.minecraft.text.Text;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Formatting;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.EntityHitResult;
import net.minecraft.util.hit.HitResult;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.lwjgl.glfw.GLFW;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class AutoClicker {
public static final String MOD_ID = "autoclicker";
public static final Logger LOGGER = LogManager.getLogger(MOD_ID);
public static final KeyBinding openConfig =
new KeyBinding("keybinding.open-gui", GLFW.GLFW_KEY_O, "category.autoclicker-fabric");
public static final KeyBinding toggleHolding =
new KeyBinding("keybinding.toggle-hold", GLFW.GLFW_KEY_I, "category.autoclicker-fabric");
private static final Path CONFIG_DIR = Paths.get(MinecraftClient.getInstance().runDirectory.getPath() + "/config");
private static final Path CONFIG_FILE = Paths.get(CONFIG_DIR + "/auto-clicker-fabric.json");
public static Holding.AttackHolding leftHolding;
public static Holding rightHolding;
public static Holding jumpHolding;
public static Config.HudConfig hudConfig;
private static AutoClicker INSTANCE;
private boolean isActive = false;
private Config config = new Config(
new Config.LeftMouseConfig(false, false, 0, false, false, false),
new Config.RightMouseConfig(false, false, 0),
new Config.JumpConfig(false, false, 0),
new Config.HudConfig(true, "top-left")
);
public AutoClicker() {
INSTANCE = this;
}
public static AutoClicker getInstance() {
return INSTANCE;
}
public void onInitialize() {
LOGGER.info("Auto Clicker Initialised");
}
public void clientReady(MinecraftClient client) {
if (!Files.exists(CONFIG_FILE)) {
try {
Files.createDirectories(CONFIG_DIR);
Files.createFile(CONFIG_FILE);
} catch (IOException e) {
e.printStackTrace();
}
this.saveConfig();
} else {
try {
FileReader json = new FileReader(CONFIG_FILE.toFile());
Config config = new Gson().fromJson(json, Config.class);
json.close();
if (config != null && config.getHudConfig() != null) {
this.config = config;
}
} catch (Exception e){
e.printStackTrace();
this.saveConfig();
}
}
leftHolding = new Holding.AttackHolding(client.options.attackKey, this.config.getLeftClick());
rightHolding = new Holding(client.options.useKey, this.config.getRightClick());
jumpHolding = new Holding(client.options.jumpKey, this.config.getJump());
hudConfig = this.config.getHudConfig();
}
public void saveConfig() {
try {
FileWriter writer = new FileWriter(CONFIG_FILE.toFile());
new Gson().toJson(this.config, writer);
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void RenderGameOverlayEvent(DrawContext context, RenderTickCounter delta) {
if ((!leftHolding.isActive() && !rightHolding.isActive() && !jumpHolding.isActive()) || !this.isActive || !config.getHudConfig().isEnabled()) {
return;
}
MinecraftClient client = MinecraftClient.getInstance();
if (leftHolding.isActive()) {
Text text = Language.HUD_HOLDING.getText(I18n.translate(leftHolding.getKey().getTranslationKey()));
int y = getHudY() + (15 * 0);
int x = getHudX(text);
context.drawTextWithShadow(client.textRenderer, text.asOrderedText(), x, y, 0xffffff);
}
if (rightHolding.isActive()) {
Text text = Language.HUD_HOLDING.getText(I18n.translate(rightHolding.getKey().getTranslationKey()));
int y = getHudY() + (15 * 1);
int x = getHudX(text);
context.drawTextWithShadow(client.textRenderer, text.asOrderedText(), x, y, 0xffffff);
}
if (jumpHolding.isActive()) {
Text text = Language.HUD_HOLDING.getText(I18n.translate(jumpHolding.getKey().getTranslationKey()));
int y = getHudY() + (15 * 2);
int x = getHudX(text);
context.drawTextWithShadow(client.textRenderer, text.asOrderedText(), x, y, 0xffffff);
}
}
public int getHudX(Text text){
MinecraftClient client = MinecraftClient.getInstance();
String location = this.config.getHudConfig().getLocation();
return switch (location) {
case "top-left", "bottom-left" -> 10;
case "top-right", "bottom-right" -> (MinecraftClient.getInstance().getWindow().getScaledWidth()) - 10 - client.textRenderer.getWidth(text);
default -> 10;
};
}
public int getHudY(){
String location = this.config.getHudConfig().getLocation();
return switch (location) {
case "top-left", "top-right" -> 10;
case "bottom-left", "bottom-right" -> (MinecraftClient.getInstance().getWindow().getScaledHeight()) - 50;
default -> 10;
};
}
public void clientTickEvent(MinecraftClient mc) {
if (mc.player == null || mc.world == null) {
return;
}
if(!mc.player.isAlive()) this.isActive = false;
if (this.isActive) {
if (leftHolding.isActive()) {
this.handleActiveHolding(mc, leftHolding);
}
if (rightHolding.isActive()) {
this.handleActiveHolding(mc, rightHolding);
}
if (jumpHolding.isActive()) {
this.handleActiveHolding(mc, jumpHolding);
}
}
this.keyInputEvent(mc);
}
private void handleActiveHolding(MinecraftClient mc, Holding key) {
assert mc.player != null;
if (!key.isActive()) {
return;
}
if (key.isSpamming()) {
// How to handle the click if it's done by spamming
if (key.getSpeed() > 0) {
if (key.getTimeout() <= 1) {
if (key.getTimeout() <= 0) {
key.resetTimeout();
}
// simulate the actual button press only if its jumping
if(key == jumpHolding) {
// Press the button twice by toggling 1 and 0
key.getKey().setPressed(key.getTimeout() == 1);
}
// for left click, attempt to attack the mob
this.attemptMobAttack(mc, key);
// for right click, attempt to interact with block or mob
this.attemptUse(mc, key);
}
key.decreaseTimeout();
} else {
// Handle the click if it's done normally
key.getKey().setPressed(!key.getKey().isPressed());
if (key.getKey().isPressed()) {
this.attemptMobAttack(mc, key);
}
}
return;
}
// Normal holding or cool down behaviour
// respect cool down
if (key.isRespectCooldown()) {
// Don't do anything if they're not looking at something
if (key instanceof Holding.AttackHolding && ((Holding.AttackHolding) key).isMobMode() && !this.isPlayerLookingAtMob(mc)) {
if (key.getKey().isPressed()) {
key.getKey().setPressed(false);
}
return;
}
if (mc.player.getAttackCooldownProgress(0) == 1.0F) {
key.getKey().setPressed(true);
this.attemptMobAttack(mc, key);
} else {
key.getKey().setPressed(false);
}
} else {
// Hold the click
key.getKey().setPressed(true);
}
}
/**
* Attempts to use items in main hand, and if it couldn't, tries offhand.
*/
private void attemptUse(MinecraftClient mc, Holding key) {
// don't interact on left click
if(key.getKey() != rightHolding.getKey() || mc.interactionManager == null || mc.player == null) {
return;
}
HitResult rayTrace = mc.crosshairTarget;
if(rayTrace == null) {
return;
}
// try with both hands
for(var hand : Hand.values()) {
if (rayTrace.getType() == HitResult.Type.ENTITY && rayTrace instanceof EntityHitResult) {
// interact with entity
ActionResult result = mc.interactionManager.interactEntity(mc.player, ((EntityHitResult) rayTrace).getEntity(), hand);
if (result.isAccepted()) {
if (result.shouldSwingHand()) {
mc.player.swingHand(hand);
}
return;
}
} else if (rayTrace.getType() == HitResult.Type.BLOCK) {
// interact with block
ActionResult result = mc.interactionManager.interactBlock(mc.player, hand, (BlockHitResult) rayTrace);
if (result.isAccepted()) {
if (result.shouldSwingHand()) {
mc.player.swingHand(hand);
}
return;
} else {
// if you cant interact with block, you could use a water bucket on it
ActionResult result1 = mc.interactionManager.interactItem(mc.player, hand);
if(result1.isAccepted()) {
if(result.shouldSwingHand()) {
mc.player.swingHand(hand);
}
return;
}
}
} else if (rayTrace.getType() == HitResult.Type.MISS) {
// no blocks and entities to interact with
// attempt to use an item (e.g. ender pearl)
ActionResult result = mc.interactionManager.interactItem(mc.player, hand);
if (result.isAccepted()) {
if (result.shouldSwingHand()) {
// cosmetic swing
mc.player.swingHand(hand);
}
return;
}
}
}
}
private void attemptMobAttack(MinecraftClient mc, Holding key) {
// Don't attack on a right click
if (key.getKey() != leftHolding.getKey()) {
return;
}
HitResult rayTrace = mc.crosshairTarget;
if (rayTrace instanceof EntityHitResult && mc.interactionManager != null && mc.player != null) {
if(!(config.getLeftClick().isRespectShield() && isShielding(mc.player))) {
mc.interactionManager.attackEntity(mc.player, ((EntityHitResult) rayTrace).getEntity());
if (mc.player != null) {
mc.player.swingHand(Hand.MAIN_HAND);
}
// it's impossible in vanilla minecraft to attack and use item at the same time
mc.interactionManager.stopUsingItem(mc.player);
}
}
}
private boolean isShielding(ClientPlayerEntity player) {
if (player.isUsingItem()) {
return player.getActiveItem().getItem() instanceof ShieldItem;
}
return false;
}
private boolean isPlayerLookingAtMob(MinecraftClient mc) {
HitResult rayTrace = mc.crosshairTarget;
return rayTrace instanceof EntityHitResult && ((EntityHitResult) rayTrace).getEntity() instanceof LivingEntity livingEntity && livingEntity.isAlive() && livingEntity.isAttackable();
}
private void keyInputEvent(MinecraftClient mc) {
assert mc.player != null;
while (toggleHolding.wasPressed()) {
this.isActive = !this.isActive;
mc.player.sendMessage(
(this.isActive ? Language.MSG_HOLDING_KEYS : Language.MSG_RELEASED_KEYS)
.getText()
.formatted(this.isActive ? Formatting.GREEN : Formatting.RED),
true
);
if (!this.isActive) {
if(leftHolding.isActive()) leftHolding.getKey().setPressed(false);
if(rightHolding.isActive()) rightHolding.getKey().setPressed(false);
if(jumpHolding.isActive()) jumpHolding.getKey().setPressed(false);
}
}
while (openConfig.wasPressed()) {
mc.setScreen(getConfigScreen());
}
}
public OptionsScreen getConfigScreen(){
return new OptionsScreen();
}
}