Skip to content

Commit 8e51e72

Browse files
committed
arrow refill, autoclicker, fixhand, ghostpickaxe, triggerbot
1 parent 39f9446 commit 8e51e72

File tree

6 files changed

+505
-2
lines changed

6 files changed

+505
-2
lines changed

src/skyblock/ArrowRefiller.ts

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
import Config from '../libs/Config';
2+
import { CommandManager } from '../libs/CommandBuilderWrapper';
3+
4+
enum RefillState {
5+
IDLE,
6+
SEND_COMMAND,
7+
WAIT_FOR_SCREEN,
8+
CLICK_SLOT_15,
9+
WAIT_AFTER_CLICK_15,
10+
CLICK_SLOT_12,
11+
WAIT_AFTER_CLICK_12,
12+
CLOSE_INV,
13+
}
14+
15+
interface ArrowRefillerConfig {
16+
enabled: boolean;
17+
minArrows: number;
18+
}
19+
20+
export class ArrowRefiller {
21+
private readonly configPath = './config/jayc331-config.json';
22+
private readonly scriptId = 'arrowRefiller';
23+
private readonly defaultConfig: ArrowRefillerConfig = {
24+
enabled: true,
25+
minArrows: 64
26+
};
27+
28+
private config: ArrowRefillerConfig;
29+
private refillState: RefillState = RefillState.IDLE;
30+
private stateTickCounter: number = 0;
31+
private lastInventoryCheckTime = 0;
32+
33+
// Constants for delays
34+
private readonly MAX_SCREEN_WAIT_TICKS = 60; // 3 seconds
35+
private readonly CLICK_DELAY_TICKS = 5; // 250ms
36+
37+
constructor() {
38+
this.config = Config.readConfig(this.configPath, this.defaultConfig, this.scriptId);
39+
this.registerListeners();
40+
this.registerCommands();
41+
}
42+
43+
private registerListeners() {
44+
JsMacros.on('Tick', JavaWrapper.methodToJava(() => this.onTick()));
45+
}
46+
47+
private onTick() {
48+
if (!this.config.enabled) {
49+
// If disabled, ensure we are in IDLE state and reset counters
50+
if (this.refillState !== RefillState.IDLE) {
51+
this.resetState();
52+
}
53+
return;
54+
}
55+
56+
// --- Periodic Check for Refill Trigger (only if not currently refilling) ---
57+
if (this.refillState === RefillState.IDLE) {
58+
if (Date.now() - this.lastInventoryCheckTime > 1000) {
59+
this.lastInventoryCheckTime = Date.now();
60+
if (!Hud.getOpenScreen() && !this.hasEnoughArrows()) {
61+
this.startRefillProcess();
62+
}
63+
}
64+
}
65+
66+
// --- State Machine Execution ---
67+
if (this.refillState !== RefillState.IDLE) {
68+
this.stateTickCounter++;
69+
const player = Player.getPlayer(); // Get player once per active tick
70+
if (!player) {
71+
Chat.log('§cArrowRefiller Error: Player not found during refill process. Resetting.');
72+
this.resetState();
73+
return;
74+
}
75+
76+
switch (this.refillState) {
77+
case RefillState.SEND_COMMAND:
78+
Chat.log('§aArrowRefiller: §7Low arrows! Refilling...');
79+
Chat.say('/shop arrow');
80+
this.refillState = RefillState.WAIT_FOR_SCREEN;
81+
this.stateTickCounter = 0; // Reset counter for new state
82+
break;
83+
84+
case RefillState.WAIT_FOR_SCREEN:
85+
if (Hud.getOpenScreen()) {
86+
this.refillState = RefillState.CLICK_SLOT_15;
87+
this.stateTickCounter = 0;
88+
} else if (this.stateTickCounter >= this.MAX_SCREEN_WAIT_TICKS) {
89+
Chat.log('§cArrowRefiller: §7Shop open timed out. Resetting.');
90+
this.resetState();
91+
}
92+
break;
93+
94+
case RefillState.CLICK_SLOT_15:
95+
if (this.stateTickCounter >= this.CLICK_DELAY_TICKS) { // Wait a few ticks before clicking
96+
if (!this.clickSlot(15)) {
97+
this.resetState();
98+
return;
99+
}
100+
this.refillState = RefillState.WAIT_AFTER_CLICK_15;
101+
this.stateTickCounter = 0;
102+
}
103+
break;
104+
105+
case RefillState.WAIT_AFTER_CLICK_15:
106+
if (this.stateTickCounter >= this.CLICK_DELAY_TICKS) {
107+
this.refillState = RefillState.CLICK_SLOT_12;
108+
this.stateTickCounter = 0;
109+
}
110+
break;
111+
112+
case RefillState.CLICK_SLOT_12:
113+
if (this.stateTickCounter >= this.CLICK_DELAY_TICKS) { // Wait a few ticks before clicking
114+
if (!this.clickSlot(12)) {
115+
this.resetState();
116+
return;
117+
}
118+
this.refillState = RefillState.WAIT_AFTER_CLICK_12;
119+
this.stateTickCounter = 0;
120+
}
121+
break;
122+
123+
case RefillState.WAIT_AFTER_CLICK_12:
124+
if (this.stateTickCounter >= this.CLICK_DELAY_TICKS) {
125+
this.refillState = RefillState.CLOSE_INV;
126+
this.stateTickCounter = 0;
127+
}
128+
break;
129+
130+
case RefillState.CLOSE_INV:
131+
const inv = Player.openInventory();
132+
if (inv) inv.close();
133+
Chat.log('§aArrowRefiller: §7Refill process completed.');
134+
this.resetState();
135+
break;
136+
}
137+
}
138+
}
139+
140+
private hasEnoughArrows(): boolean {
141+
const inv = Player.openInventory();
142+
if (!inv) return true;
143+
144+
const items = inv.getItems();
145+
let count = 0;
146+
147+
for (let i = 0; i < items.size(); i++) {
148+
const item = items.get(i);
149+
if (!item.isEmpty() && item.getItemId() === 'minecraft:arrow') {
150+
count += item.getCount();
151+
}
152+
}
153+
return count >= this.config.minArrows;
154+
}
155+
156+
// New method to initiate the refilling process
157+
public startRefillProcess() {
158+
if (this.refillState === RefillState.IDLE) {
159+
this.refillState = RefillState.SEND_COMMAND;
160+
this.stateTickCounter = 0;
161+
}
162+
}
163+
164+
private clickSlot(slot: number): boolean {
165+
const inv = Player.openInventory();
166+
if (!inv) {
167+
Chat.log('§cArrowRefiller Error: Inventory not open when trying to click slot.');
168+
return false;
169+
}
170+
Chat.log(`§aArrowRefiller: §7Clicking slot ${slot}...`);
171+
inv.click(slot);
172+
return true;
173+
}
174+
175+
private resetState() {
176+
this.refillState = RefillState.IDLE;
177+
this.stateTickCounter = 0;
178+
// Optionally, ensure any keys are released or other side effects are cleaned up
179+
}
180+
181+
private saveConfig() {
182+
Config.writeConfig(this.configPath, this.config, this.scriptId);
183+
}
184+
185+
private registerCommands() {
186+
const cmd = CommandManager.create('arrowrefill');
187+
188+
cmd.literal('toggle').executes(() => {
189+
this.config.enabled = !this.config.enabled;
190+
this.saveConfig();
191+
Chat.log(`§7ArrowRefill is now ${this.config.enabled ? '§aENABLED' : '§cDISABLED'}`);
192+
if (!this.config.enabled) {
193+
this.resetState(); // Reset state if disabled mid-process
194+
}
195+
});
196+
197+
cmd.literal('threshold')
198+
.argument('amount', 'int')
199+
.executes((ctx) => {
200+
const amt = ctx.getArg('amount');
201+
this.config.minArrows = amt;
202+
this.saveConfig();
203+
Chat.log(`§7ArrowRefill threshold set to §a${amt}`);
204+
});
205+
206+
cmd.literal('buy').executes(() => {
207+
this.startRefillProcess();
208+
});
209+
210+
cmd.register();
211+
}
212+
}

src/skyblock/AutoClicker.ts

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import Config from '../libs/Config';
2+
import { CommandManager } from '../libs/CommandBuilderWrapper';
3+
4+
interface AutoClickerConfig {
5+
enabled: boolean;
6+
cps: number;
7+
}
8+
9+
export class AutoClicker {
10+
private readonly configPath = './config/jayc331-config.json';
11+
private readonly scriptId = 'autoClicker';
12+
private readonly defaultConfig: AutoClickerConfig = {
13+
enabled: false,
14+
cps: 10,
15+
};
16+
17+
private config: AutoClickerConfig;
18+
private nextClickTime = 0;
19+
private isKeyHeld = false;
20+
21+
constructor() {
22+
this.config = Config.readConfig(this.configPath, this.defaultConfig, this.scriptId);
23+
this.registerListeners();
24+
this.registerCommands();
25+
}
26+
27+
private registerListeners() {
28+
JsMacros.on('Tick', JavaWrapper.methodToJava(() => this.onTick()));
29+
}
30+
31+
private onTick() {
32+
if (!this.config.enabled) {
33+
this.releaseKey();
34+
return;
35+
}
36+
if (Hud.getOpenScreen()) {
37+
this.releaseKey();
38+
return;
39+
}
40+
41+
if (KeyBind.getPressedKeys().contains('key.mouse.left')) {
42+
const now = Date.now();
43+
if (now >= this.nextClickTime) {
44+
// Press the key
45+
KeyBind.key('key.mouse.right', true);
46+
this.isKeyHeld = true;
47+
48+
const baseDelay = 1000 / this.config.cps;
49+
// Add +/- 20% randomness
50+
const variance = baseDelay * 0.2;
51+
const random = Math.random() * (variance * 2) - variance;
52+
53+
this.nextClickTime = now + baseDelay + random;
54+
} else {
55+
// Release between clicks to respect CPS
56+
this.releaseKey();
57+
}
58+
} else {
59+
this.releaseKey();
60+
this.nextClickTime = 0;
61+
}
62+
}
63+
64+
private releaseKey() {
65+
if (this.isKeyHeld) {
66+
KeyBind.key('key.mouse.right', false);
67+
this.isKeyHeld = false;
68+
}
69+
}
70+
71+
private saveConfig() {
72+
Config.writeConfig(this.configPath, this.config, this.scriptId);
73+
}
74+
75+
private registerCommands() {
76+
const cmd = CommandManager.create('autoclicker');
77+
78+
cmd.literal('toggle').executes(() => {
79+
this.config.enabled = !this.config.enabled;
80+
this.saveConfig();
81+
Chat.log(`§7AutoClicker is now ${this.config.enabled ? '§aENABLED' : '§cDISABLED'}`);
82+
});
83+
84+
cmd.literal('cps')
85+
.argument('value', 'int')
86+
.executes((ctx) => {
87+
const cps = ctx.getArg('value');
88+
this.config.cps = cps;
89+
this.saveConfig();
90+
Chat.log(`§7AutoClicker CPS set to §a${cps}`);
91+
});
92+
93+
cmd.register();
94+
}
95+
}

src/skyblock/FixHand.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import Config from '../libs/Config';
2+
import { CommandManager } from '../libs/CommandBuilderWrapper';
3+
4+
interface FixHandConfig {
5+
enabled: boolean;
6+
threshold: number;
7+
}
8+
9+
export class FixHand {
10+
private readonly configPath = './config/jayc331-config.json';
11+
private readonly scriptId = 'fixHand';
12+
private readonly defaultConfig: FixHandConfig = {
13+
enabled: true,
14+
threshold: 0.20,
15+
};
16+
17+
private config: FixHandConfig;
18+
private lastFixTime = 0;
19+
20+
constructor() {
21+
this.config = Config.readConfig(this.configPath, this.defaultConfig, this.scriptId);
22+
this.registerListeners();
23+
this.registerCommands();
24+
}
25+
26+
private registerListeners() {
27+
JsMacros.on('Tick', JavaWrapper.methodToJava(() => this.onTick()));
28+
}
29+
30+
private onTick() {
31+
if (!this.config.enabled) return;
32+
33+
// 5 seconds cooldown to prevent spamming the command
34+
if (Date.now() - this.lastFixTime < 5000) return;
35+
36+
const player = Player.getPlayer();
37+
if (!player) return;
38+
39+
const item = player.getMainHand();
40+
if (!item || item.isEmpty()) return;
41+
42+
const maxDamage = item.getMaxDamage();
43+
// If maxDamage is 0 or less, the item is likely not damageable (or unbreakable)
44+
if (maxDamage <= 0) return;
45+
46+
const currentDamage = item.getDamage();
47+
const currentDurability = maxDamage - currentDamage;
48+
const ratio = currentDurability / maxDamage;
49+
50+
if (ratio < this.config.threshold) {
51+
Chat.log(`§aFixHand: §7Durability at ${(ratio * 100).toFixed(1)}%, fixing...`);
52+
Chat.say('/fix hand');
53+
this.lastFixTime = Date.now();
54+
}
55+
}
56+
57+
private saveConfig() {
58+
Config.writeConfig(this.configPath, this.config, this.scriptId);
59+
}
60+
61+
private registerCommands() {
62+
const cmd = CommandManager.create('fixhand');
63+
64+
cmd.literal('toggle').executes(() => {
65+
this.config.enabled = !this.config.enabled;
66+
this.saveConfig();
67+
Chat.log(`§7FixHand is now ${this.config.enabled ? '§aENABLED' : '§cDISABLED'}`);
68+
});
69+
70+
cmd.literal('threshold')
71+
.argument('percent', 'double') // Expecting 0.0 - 1.0 or percentage? Usually 0.2 for 20%
72+
.executes((ctx) => {
73+
let val = ctx.getArg('percent');
74+
// Optional: normalize if user enters 20 instead of 0.2
75+
if (val > 1) val = val / 100;
76+
77+
this.config.threshold = val;
78+
this.saveConfig();
79+
Chat.log(`§7FixHand threshold set to §a${(val * 100).toFixed(1)}%`);
80+
});
81+
82+
cmd.register();
83+
}
84+
}

0 commit comments

Comments
 (0)