Skip to content

Commit 202cd8e

Browse files
committed
feat: prison utils - autosell, better baritone mine cleararea
1 parent c4fb037 commit 202cd8e

File tree

2 files changed

+239
-0
lines changed

2 files changed

+239
-0
lines changed

src/skyblock/PrisonUtils.ts

Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
import Config from '../libs/Config';
2+
import { CommandManager } from '../libs/CommandBuilderWrapper';
3+
import { BaritoneAPI } from '../libs/BaritoneAPIProvider';
4+
import { Key } from '../libs/KeyManager';
5+
6+
enum SellState {
7+
IDLE,
8+
WAIT_FOR_SCREEN,
9+
CLICK_49,
10+
WAIT_AFTER_49,
11+
CLICK_12,
12+
WAIT_AFTER_12,
13+
CLOSE,
14+
}
15+
16+
interface PrisonUtilsConfig {
17+
enabled: boolean;
18+
delaySeconds: number;
19+
}
20+
21+
export class PrisonUtils {
22+
private readonly configPath = './config/jayc331-config.json';
23+
private readonly scriptId = 'prisonUtils';
24+
private readonly defaultConfig: PrisonUtilsConfig = {
25+
enabled: false,
26+
delaySeconds: 120,
27+
};
28+
29+
private config: PrisonUtilsConfig;
30+
private state: SellState = SellState.IDLE;
31+
private stateTickCounter = 0;
32+
private lastSellTime = 0;
33+
34+
private readonly lmb = new Key('key.mouse.left');
35+
private builderProcess: any;
36+
37+
private isScreenOpen = false;
38+
private resumeAt = 0;
39+
private resumePending = false;
40+
41+
constructor() {
42+
this.config = Config.readConfig(this.configPath, this.defaultConfig, this.scriptId);
43+
// Get the builder process safely
44+
try {
45+
const provider = BaritoneAPI.getProvider();
46+
const primary = provider.getPrimaryBaritone();
47+
this.builderProcess = primary.getBuilderProcess();
48+
} catch (e) {
49+
Chat.log('§cPrisonUtils: Could not load Baritone BuilderProcess.');
50+
}
51+
52+
this.registerListeners();
53+
this.registerCommands();
54+
}
55+
56+
private registerListeners() {
57+
JsMacros.on(
58+
'Tick',
59+
JavaWrapper.methodToJava(() => this.onTick())
60+
);
61+
JsMacros.on(
62+
'OpenScreen',
63+
JavaWrapper.methodToJava((event) => this.onOpenScreen(event))
64+
);
65+
}
66+
67+
private onOpenScreen(event: any) {
68+
if (!this.config.enabled) return;
69+
70+
// If a screen opens, pause baritone and release mouse
71+
if (this.builderProcess && this.builderProcess.isActive()) {
72+
this.builderProcess.pause();
73+
this.lmb.set(false);
74+
}
75+
76+
this.isScreenOpen = true;
77+
this.resumePending = false; // Cancel any pending resume
78+
}
79+
80+
private onTick() {
81+
if (!this.config.enabled) {
82+
// Ensure key is released if disabled
83+
if (this.lmb.pressed) this.lmb.set(false);
84+
return;
85+
}
86+
87+
// Allow input even if "paused" (reflection hack from original script)
88+
try {
89+
const mc = Client.getMinecraft();
90+
const field = Reflection.getDeclaredField(mc.getClass(), 'field_1695');
91+
field.setAccessible(true);
92+
field.set(mc, true);
93+
} catch (e) {
94+
// Ignore if field doesn't exist (version diff)
95+
}
96+
97+
const currentScreen = Hud.getOpenScreen();
98+
99+
// Detect Screen Close
100+
if (this.isScreenOpen && !currentScreen) {
101+
this.isScreenOpen = false;
102+
// Screen just closed. Schedule resume.
103+
// Original script waits 20 ticks (approx 1000ms)
104+
this.resumeAt = Date.now() + 500;
105+
this.resumePending = true;
106+
}
107+
108+
// Handle Resume
109+
if (this.resumePending && Date.now() > this.resumeAt) {
110+
this.resumePending = false;
111+
if (this.builderProcess) {
112+
this.builderProcess.resume();
113+
if (this.builderProcess.isActive()) {
114+
this.lmb.set(true);
115+
}
116+
}
117+
}
118+
119+
// Periodic Sell / Mining Logic
120+
if (this.builderProcess && this.builderProcess.isActive()) {
121+
// If not in a menu, hold LMB to mine (if active)
122+
if (!currentScreen && !this.resumePending) {
123+
this.lmb.set(true);
124+
}
125+
126+
// Check for Auto Sell
127+
if (this.state === SellState.IDLE && !currentScreen) {
128+
const now = Date.now();
129+
if (now - this.lastSellTime > this.config.delaySeconds * 1000) {
130+
this.startSellSequence();
131+
}
132+
}
133+
}
134+
135+
// Handle Sell State Machine
136+
if (this.state !== SellState.IDLE) {
137+
this.handleSellState(currentScreen);
138+
}
139+
}
140+
141+
private startSellSequence() {
142+
Chat.log('§aPrisonUtils: §7Selling...');
143+
Chat.say('/sell');
144+
this.state = SellState.WAIT_FOR_SCREEN;
145+
this.stateTickCounter = 0;
146+
this.lastSellTime = Date.now();
147+
}
148+
149+
private handleSellState(currentScreen: any) {
150+
this.stateTickCounter++;
151+
const TICK_DELAY = 10; // Original used 10 ticks ~ 500ms
152+
153+
switch (this.state) {
154+
case SellState.WAIT_FOR_SCREEN:
155+
if (currentScreen) {
156+
this.state = SellState.CLICK_49;
157+
this.stateTickCounter = 0;
158+
} else if (this.stateTickCounter > 40) { // 2 seconds timeout
159+
this.state = SellState.IDLE; // Failed to open
160+
}
161+
break;
162+
163+
case SellState.CLICK_49:
164+
if (this.stateTickCounter >= TICK_DELAY) {
165+
this.clickSlot(49);
166+
this.state = SellState.WAIT_AFTER_49;
167+
this.stateTickCounter = 0;
168+
}
169+
break;
170+
171+
case SellState.WAIT_AFTER_49:
172+
if (this.stateTickCounter >= TICK_DELAY) {
173+
this.state = SellState.CLICK_12;
174+
this.stateTickCounter = 0;
175+
}
176+
break;
177+
178+
case SellState.CLICK_12:
179+
if (this.stateTickCounter >= 0) { // No extra delay needed? Original: wait 10 ticks BEFORE clicking 12 (handled by WAIT_AFTER_49)
180+
this.clickSlot(12);
181+
this.state = SellState.WAIT_AFTER_12;
182+
this.stateTickCounter = 0;
183+
}
184+
break;
185+
186+
case SellState.WAIT_AFTER_12:
187+
if (this.stateTickCounter >= TICK_DELAY) {
188+
this.state = SellState.CLOSE;
189+
}
190+
break;
191+
192+
case SellState.CLOSE:
193+
if (currentScreen) {
194+
const inv = Player.openInventory();
195+
if (inv) inv.close();
196+
}
197+
this.state = SellState.IDLE;
198+
break;
199+
}
200+
}
201+
202+
private clickSlot(slot: number) {
203+
const inv = Player.openInventory();
204+
if (inv) {
205+
inv.click(slot);
206+
}
207+
}
208+
209+
private saveConfig() {
210+
Config.writeConfig(this.configPath, this.config, this.scriptId);
211+
}
212+
213+
private registerCommands() {
214+
const cmd = CommandManager.create('prisonutils');
215+
216+
cmd.literal('toggle').executes(() => {
217+
this.config.enabled = !this.config.enabled;
218+
this.saveConfig();
219+
Chat.log(`§7PrisonUtils is now ${this.config.enabled ? '§aENABLED' : '§cDISABLED'}`);
220+
if (!this.config.enabled) {
221+
this.lmb.set(false);
222+
this.state = SellState.IDLE;
223+
}
224+
});
225+
226+
cmd.literal('delay')
227+
.argument('seconds', 'int')
228+
.executes((ctx) => {
229+
const seconds = ctx.getArg('seconds');
230+
this.config.delaySeconds = seconds;
231+
this.saveConfig();
232+
Chat.log(`§7PrisonUtils sell delay set to §a${seconds}s`);
233+
});
234+
235+
cmd.register();
236+
}
237+
}

src/skyblock/main.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { AutoClicker } from './AutoClicker';
88
import { TriggerBot } from './TriggerBot';
99
import { ArrowRefiller } from './ArrowRefiller';
1010
import { FixHand } from './FixHand';
11+
import { PrisonUtils } from './PrisonUtils';
1112
import { BaritoneAPI, BetterBlockPos } from '../libs/BaritoneAPIProvider';
1213
import { Key } from '../libs/KeyManager';
1314
import { CommandManager } from '../libs/CommandBuilderWrapper';
@@ -582,6 +583,7 @@ const autoClicker = new AutoClicker();
582583
const triggerBot = new TriggerBot();
583584
const arrowRefiller = new ArrowRefiller(strafer); // Pass strafer instance
584585
const fixHand = new FixHand();
586+
const prisonUtils = new PrisonUtils();
585587

586588
(event as any).stopListener = JavaWrapper.methodToJava(() => strafer.stop());
587589

0 commit comments

Comments
 (0)