From bb5e26a0b02aa37b908dc4a1beb2017627fcfd72 Mon Sep 17 00:00:00 2001 From: rdbtCVS <87152661+rdbtCVS@users.noreply.github.com> Date: Sun, 2 Aug 2026 23:35:57 +0100 Subject: [PATCH 1/5] Recode utilities --- failsafes/AlertUtils.js | 30 +- failsafes/Failsafe.js | 8 +- failsafes/FailsafeManager.js | 25 +- failsafes/FailsafeUtils.js | 10 +- failsafes/impl/ChatMentionFailsafe.js | 6 +- failsafes/impl/PlayerGriefFailsafe.js | 10 +- failsafes/impl/RotationFailsafe.js | 18 +- failsafes/impl/SlotChangeFailsafe.js | 6 +- failsafes/impl/TeleportFailsafe.js | 20 +- failsafes/impl/VelocityFailsafe.js | 8 +- gui/Dashboard.js | 30 +- gui/GUI.js | 48 +- gui/GuiSave.js | 16 +- gui/MacroToggleGui.js | 18 +- gui/NotificationManager.js | 4 +- gui/OverlayUtils.js | 36 +- gui/Utils.js | 8 - gui/categories/CategoryEvents.js | 2 +- gui/categories/CategoryManager.js | 1320 ++++++++--------- gui/categories/CategoryRenderer.js | 1 - gui/categories/CategorySearchBar.js | 2 +- gui/components/TextInput.js | 2 +- gui/components/layout.js | 14 +- gui/core/GuiEvents.js | 10 +- gui/core/GuiRenderer.js | 4 +- loader.js | 5 +- modules/combat/CombatBot.js | 38 +- modules/farming/FarmingMacro.js | 52 +- modules/farming/FarmingSettings.js | 8 +- modules/farming/LoadoutHandler.js | 10 +- modules/farming/SShapeCropMacro.js | 4 +- modules/farming/WSRowMacros.js | 6 +- modules/farming/rewarp/AutoSell.js | 22 +- modules/farming/rewarp/PestKiller.js | 16 +- modules/farming/rewarp/PhilipMacro.js | 10 +- modules/farming/rewarp/RewarpHandler.js | 8 +- modules/farming/rewarp/RewarpSettings.js | 12 +- modules/farming/rewarp/VisitorMacro.js | 10 +- modules/foraging/AutoHarp.js | 6 +- modules/foraging/ForagingBot.js | 14 +- modules/foraging/HideonLeafESP.js | 6 +- modules/foraging/LushLilacEtherwarpNuker.js | 20 +- modules/foraging/MudwormMacro.js | 4 +- modules/foraging/SeaLumieMacro.js | 3 +- modules/mining/CommissionMacro.js | 76 +- modules/mining/ExcavatorMacro.js | 28 +- modules/mining/GemstoneMacro.js | 43 +- modules/mining/GlaciteCommissionMacro.js | 52 +- modules/mining/GlaciteData.js | 1 - modules/mining/GlowingMushroomMacro.js | 24 +- modules/mining/LobbyHopper.js | 6 +- modules/mining/MiningBot.js | 62 +- modules/mining/Nuker.js | 24 +- modules/mining/OreMacro.js | 114 +- modules/mining/PinglessMining.js | 10 +- modules/mining/PowderMacro.js | 24 +- modules/mining/ScathaMacro.js | 38 +- modules/mining/TunnelsMiner.js | 4 +- modules/other/AuctionHelper.js | 12 +- modules/other/AutoCombine.js | 14 +- modules/other/AutoConversation.js | 2 +- modules/other/AutoFusionRepeat.js | 6 +- modules/other/BeachBaller.js | 28 +- modules/other/DiscordIntegration.js | 30 +- modules/other/DiscordRPC.js | 12 +- modules/other/Failsafes.js | 14 +- modules/other/Freecam.js | 72 +- modules/other/Freelook.js | 30 +- modules/other/MacroControllers.js | 10 +- modules/other/MacroScheduler.js | 36 +- modules/other/PeltMacro.js | 44 +- modules/other/PeltQOL.js | 18 +- modules/other/RatMacro.js | 32 +- modules/other/SunGeckoMacro.js | 34 +- modules/other/VoidgloomHelper.js | 10 +- modules/skills/AutoExperiments.js | 14 +- modules/skills/ChocolateFactory.js | 16 +- modules/skills/FishOnMCMacro.js | 24 +- modules/skills/FishingHelper.js | 4 +- modules/skills/FishingMacroA.js | 12 +- modules/skills/JerryBoxMacro.js | 18 +- modules/skills/MinionCollector.js | 12 +- modules/skills/RouteWalker.js | 51 +- modules/skills/StridersurferMacro.js | 42 +- modules/skills/WynnProfessionMacro.js | 28 +- modules/visuals/BlockVisual.js | 4 +- modules/visuals/GIF.js | 4 +- modules/visuals/HUD.js | 24 +- modules/visuals/MusicOverlay.js | 10 +- modules/visuals/PestESP.js | 6 +- modules/visuals/ProfileHider.js | 12 +- modules/visuals/RatESP.js | 14 +- modules/visuals/StructureESP.js | 2 +- utils/BazaarUtil.js | 30 +- utils/Camera.js | 37 +- utils/Chat.js | 134 +- utils/CommissionUtils.js | 20 +- utils/Config.js | 4 +- utils/Constants.js | 52 +- utils/Etherwarp.js | 17 +- utils/FileUtils.js | 45 +- utils/Flowstate.js | 136 +- utils/MacroState.js | 280 ++-- utils/Math.js | 319 ++-- utils/MiningUtils.js | 67 +- utils/Misc.js | 36 +- utils/MixinManager.js | 196 +-- utils/ModuleBase.js | 48 +- utils/NetworkUtils.js | 16 +- utils/Notifications.js | 96 -- utils/NukerUtils.js | 218 +-- utils/Packets.js | 181 +-- utils/Raytrace.js | 613 ++------ utils/RouteState.js | 27 - utils/Router.js | 43 +- utils/ScheduleTask.js | 2 +- utils/Sign.js | 13 +- utils/SkyblockEvents.js | 4 +- utils/SkyblockItemUtil.js | 56 - utils/TabListUtils.js | 296 ++-- utils/ThreadExecutor.js | 66 +- utils/TimeUtils.js | 62 +- utils/Ungrab.js | 106 +- utils/Utils.js | 630 ++------ utils/V5Commands.js | 32 +- utils/Webhooks.js | 54 +- utils/backend/IRC.js | 16 +- utils/backend/RemoteControl.js | 1 - utils/backend/WebSocket.js | 26 +- .../dependencies/BloomCore/RaytraceBlocks.js | 6 +- utils/pathfinder/EtherwarpPathfinder.js | 40 +- utils/pathfinder/PathConfig.js | 2 +- utils/pathfinder/PathExecutor.js | 69 +- utils/pathfinder/PathFinder.js | 62 +- utils/pathfinder/PathFlyer.js | 16 +- utils/pathfinder/PathSpline.js | 338 ++--- utils/pathfinder/PathWalker/PathAote.js | 36 +- utils/pathfinder/PathWalker/PathJumps.js | 22 +- utils/pathfinder/PathWalker/PathMovement.js | 114 +- utils/pathfinder/PathWalker/PathPrediction.js | 2 +- utils/pathfinder/PathWalker/PathRecovery.js | 10 +- utils/pathfinder/PathWalker/PathRotations.js | 26 +- .../PathWalker/PathRotationsUtility.js | 20 +- utils/player/Inventory.js | 229 +-- utils/player/Keybinding.js | 180 --- utils/player/Mousemat.js | 24 +- utils/player/Movement.js | 26 +- utils/player/OreRotations.js | 22 +- utils/player/RotationGCD.js | 163 +- utils/player/Rotations.js | 45 +- utils/player/ServerInfo.js | 212 ++- 151 files changed, 3196 insertions(+), 5564 deletions(-) delete mode 100644 utils/Notifications.js delete mode 100644 utils/RouteState.js delete mode 100644 utils/SkyblockItemUtil.js delete mode 100644 utils/backend/RemoteControl.js delete mode 100644 utils/player/Keybinding.js diff --git a/failsafes/AlertUtils.js b/failsafes/AlertUtils.js index bbfe2e89..b7bebd77 100644 --- a/failsafes/AlertUtils.js +++ b/failsafes/AlertUtils.js @@ -1,7 +1,7 @@ import { drawRect, drawText } from '../gui/Utils'; -import { Chat } from '../utils/Chat'; +import { sendFailsafeMessage } from '../utils/Chat'; import { File, globalAssetsDir } from '../utils/Constants'; -import { Utils } from '../utils/Utils'; +import { getConfigFile, writeConfigFile } from '../utils/Utils'; import FailsafeUtils from './FailsafeUtils'; let failsafeSound = 'Tave Check.wav'; @@ -42,8 +42,8 @@ class AlertUtilsClass { triggerReaction() { if (this.isAlerting) return; - Chat.messageFailsafe('Suspicious activity detected, reaction occuring!'); - Chat.messageFailsafe(`Press &c&l${this.cancelKey}&r &fto disable the reaction`); + sendFailsafeMessage('Suspicious activity detected, reaction occuring!'); + sendFailsafeMessage(`Press &c&l${this.cancelKey}&r &fto disable the reaction`); this.isAlerting = true; this.playSound(); @@ -87,12 +87,12 @@ class AlertUtilsClass { drawText(line2End, currentX2, y2, fontSize, redColor); NVG.restore(); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } finally { try { NVG.endFrame(); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } } }); @@ -163,7 +163,7 @@ class AlertUtilsClass { } } catch (e) { this._closeSound(); - console.error('V5 Caught error' + e + e.stack); + console.error(e); } } @@ -173,7 +173,7 @@ class AlertUtilsClass { this.clip.stop(); this.clip.close(); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } this.clip = null; } @@ -182,7 +182,7 @@ class AlertUtilsClass { try { this.audioStream.close(); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } this.audioStream = null; } @@ -208,7 +208,7 @@ class AlertUtilsClass { */ _makeFailsafeKeybind() { const keyName = 'Cancel Reaction'; - const existingKeybinds = Utils.getConfigFile('keybinds.json') || {}; + const existingKeybinds = getConfigFile('keybinds.json') || {}; let savedKeycode = existingKeybinds[keyName]; if (savedKeycode === undefined || savedKeycode === 0 || savedKeycode === -1 || savedKeycode === 75) savedKeycode = Keyboard.KEY_K; @@ -218,16 +218,16 @@ class AlertUtilsClass { this.cancelKeyBind.registerKeyPress(() => { if (!this.isAlerting) return; - Chat.messageFailsafe('Reaction disabled due to keybind being pressed'); + sendFailsafeMessage('Reaction disabled due to keybind being pressed'); this.disableReaction(); }); register('gameUnload', () => { this.disableReaction(); this._closeSound(); - const allKeybinds = Utils.getConfigFile('keybinds.json') || {}; + const allKeybinds = getConfigFile('keybinds.json') || {}; allKeybinds[keyName] = this.cancelKeyBind.getKeyCode(); - Utils.writeConfigFile('keybinds.json', allKeybinds); + writeConfigFile('keybinds.json', allKeybinds); }); } @@ -256,8 +256,8 @@ class AlertUtilsClass { GLFW.glfwFocusWindow(windowHandle); GLFW.glfwRequestWindowAttention(windowHandle); } catch (e) { - Chat.messageFailsafe('GLFW error occured! report this. ' + e); - console.error('V5 Caught error' + e + e.stack); + sendFailsafeMessage('GLFW error occured! report this. ' + e); + console.error(e); } } } diff --git a/failsafes/Failsafe.js b/failsafes/Failsafe.js index 3cc9feab..a4b41951 100644 --- a/failsafes/Failsafe.js +++ b/failsafes/Failsafe.js @@ -1,5 +1,5 @@ -import { manager } from '../utils/SkyblockEvents'; -import { MacroState } from '../utils/MacroState'; +import { registerSkyblockEvent } from '../utils/SkyblockEvents'; +import { isFailsafeMacroRunning } from '../utils/MacroState'; import { finiteNumber } from '../utils/NumberUtils'; export class Failsafe { registered = false; @@ -15,7 +15,7 @@ export class Failsafe { return true; } isActive() { - return MacroState.isFailsafeMacroRunning(); + return isFailsafeMacroRunning(); } onTrigger() {} reset() { @@ -52,7 +52,7 @@ export class Failsafe { register('worldLoad', () => { this._setDisabled(1000); }); - ['serverchange', 'death', 'warp'].forEach((event) => manager.subscribe(event, () => this._setDisabled(1000))); + ['serverchange', 'death', 'warp'].forEach((event) => registerSkyblockEvent(event, () => this._setDisabled(1000))); } _getReactionDelay(settings) { diff --git a/failsafes/FailsafeManager.js b/failsafes/FailsafeManager.js index a99f0323..701fc93d 100644 --- a/failsafes/FailsafeManager.js +++ b/failsafes/FailsafeManager.js @@ -1,19 +1,6 @@ -import ChatMentionFailsafe from './impl/ChatMentionFailsafe'; -import PlayerGriefFailsafe from './impl/PlayerGriefFailsafe'; -import RotationFailsafe from './impl/RotationFailsafe'; -import SlotChangeFailsafe from './impl/SlotChangeFailsafe'; -import TeleportFailsafe from './impl/TeleportFailsafe'; -import VelocityFailsafe from './impl/VelocityFailsafe'; - -// just keep it here to import all the failsafes to loader :) -class FailsafeManager { - constructor() { - this.failsafes = [ChatMentionFailsafe, PlayerGriefFailsafe, RotationFailsafe, SlotChangeFailsafe, TeleportFailsafe, VelocityFailsafe]; - } - - getFailsafes() { - return this.failsafes; - } -} - -export default new FailsafeManager(); +import './impl/ChatMentionFailsafe'; +import './impl/PlayerGriefFailsafe'; +import './impl/RotationFailsafe'; +import './impl/SlotChangeFailsafe'; +import './impl/TeleportFailsafe'; +import './impl/VelocityFailsafe'; diff --git a/failsafes/FailsafeUtils.js b/failsafes/FailsafeUtils.js index eac0edc2..b4f30706 100644 --- a/failsafes/FailsafeUtils.js +++ b/failsafes/FailsafeUtils.js @@ -19,7 +19,6 @@ class FailsafeUtils { config: {}, normalized: null, }; - this._utils = null; } _getConfig() { @@ -30,8 +29,7 @@ class FailsafeUtils { return this._cache.config; } - if (!this._utils) this._utils = require('../utils/Utils').Utils; - const config = this._utils.getConfigFile('config.json'); + const config = require('../utils/Utils').getConfigFile('config.json'); this._cache.expiresAt = now + 250; this._cache.lastModified = lastModified; @@ -117,12 +115,12 @@ class FailsafeUtils { } sendFailsafeEmbed(type, severity, description, color) { - const { Webhook } = require('../utils/Webhooks'); + const { sendFailsafeEmbed, sendFailsafeScreenshot } = require('../utils/Webhooks'); const pingOnCheckValue = this.getFailsafeSettings(type).pingOnCheck; if (pingOnCheckValue === 'Ping' || pingOnCheckValue === 'Embed Only') { - Webhook.sendFailsafeEmbed( + sendFailsafeEmbed( [ { title: `**[${severity.toUpperCase()}]** ${type} Failsafe Triggered!`, @@ -136,7 +134,7 @@ class FailsafeUtils { ); } else if (pingOnCheckValue === 'Ping & Screenshot' || pingOnCheckValue === 'Screenshot Only') { Client.scheduleTask(5, () => - Webhook.sendFailsafeScreenshot( + sendFailsafeScreenshot( `**[${severity.toUpperCase()}]** ${type} Failsafe Triggered!`, description, color, diff --git a/failsafes/impl/ChatMentionFailsafe.js b/failsafes/impl/ChatMentionFailsafe.js index f1b63a54..5fb12727 100644 --- a/failsafes/impl/ChatMentionFailsafe.js +++ b/failsafes/impl/ChatMentionFailsafe.js @@ -1,4 +1,4 @@ -import { Chat } from '../../utils/Chat'; +import { sendFailsafeMessage } from '../../utils/Chat'; import { Failsafe } from '../Failsafe'; import FailsafeUtils from '../FailsafeUtils'; import { ClientboundSystemChatPacket } from '../../utils/Packets'; @@ -51,7 +51,7 @@ class ChatMentionFailsafe extends Failsafe { const severity = result.isHigh ? 'high' : 'medium'; const embedColour = result.isHigh ? 16744448 : 16776960; - Chat.messageFailsafe(`&c&lDetected blacklisted word - "${result.blockedWord}"!`); + sendFailsafeMessage(`&c&lDetected blacklisted word - "${result.blockedWord}"!`); FailsafeUtils.incrementFailsafeIntensity(pressure); FailsafeUtils.sendFailsafeEmbed( 'Chat Mention', @@ -62,4 +62,4 @@ class ChatMentionFailsafe extends Failsafe { } } -export default new ChatMentionFailsafe(); +new ChatMentionFailsafe(); diff --git a/failsafes/impl/PlayerGriefFailsafe.js b/failsafes/impl/PlayerGriefFailsafe.js index 19a1295d..d078707b 100644 --- a/failsafes/impl/PlayerGriefFailsafe.js +++ b/failsafes/impl/PlayerGriefFailsafe.js @@ -1,4 +1,4 @@ -import { Chat } from '../../utils/Chat'; +import { sendFailsafeMessage } from '../../utils/Chat'; import { File, globalAssetsDir } from '../../utils/Constants'; import { Failsafe } from '../Failsafe'; import FailsafeUtils from '../FailsafeUtils'; @@ -7,7 +7,7 @@ const warpPoints = (() => { try { return JSON.parse(FileLib.read(new File(globalAssetsDir, 'WarpPoints.json').getPath()) || '{}').warps || []; } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); return []; } })(); @@ -69,7 +69,7 @@ class PlayerGriefFailsafe extends Failsafe { const lz = look.getZ(); if (Math.trunc(lx) === Math.trunc(px) && Math.trunc(ly) === Math.trunc(py) && Math.trunc(lz) === Math.trunc(pz)) { - Chat.messageFailsafe(`&c&l${lookedName} is standing inside you!`); + sendFailsafeMessage(`&c&l${lookedName} is standing inside you!`); FailsafeUtils.incrementFailsafeIntensity(120); FailsafeUtils.sendFailsafeEmbed('Player Grief', 'very high', `${lookedName} is standing inside you!`, 16711680); @@ -101,7 +101,7 @@ class PlayerGriefFailsafe extends Failsafe { if (distanceSq <= maxDistanceSq && distanceSq > 1) { const distance = Math.sqrt(distanceSq); - Chat.messageFailsafe(`&c&l${playerName} is ${distance.toFixed(1)} blocks away from you!`); + sendFailsafeMessage(`&c&l${playerName} is ${distance.toFixed(1)} blocks away from you!`); FailsafeUtils.incrementFailsafeIntensity(20); FailsafeUtils.sendFailsafeEmbed('Player Grief', 'medium', `${playerName} is ${distance.toFixed(1)} blocks away!`, 16776960); @@ -111,4 +111,4 @@ class PlayerGriefFailsafe extends Failsafe { } } -export default new PlayerGriefFailsafe(); +new PlayerGriefFailsafe(); diff --git a/failsafes/impl/RotationFailsafe.js b/failsafes/impl/RotationFailsafe.js index e84dd034..3da919f1 100644 --- a/failsafes/impl/RotationFailsafe.js +++ b/failsafes/impl/RotationFailsafe.js @@ -1,5 +1,5 @@ -import { Chat } from '../../utils/Chat'; -import { MathUtils } from '../../utils/Math'; +import { sendDebugMessage, sendFailsafeMessage } from '../../utils/Chat'; +import { getAngleDifference } from '../../utils/Math'; import { ClientboundPlayerPositionPacket } from '../../utils/Packets'; import { Failsafe } from '../Failsafe'; import FailsafeUtils from '../FailsafeUtils'; @@ -37,12 +37,12 @@ class RotationFailsafe extends Failsafe { const dz = Math.abs(newZ - fromZ); const posDistance = Math.hypot(dx, dy, dz); - const yawDiff = Math.abs(MathUtils.getAngleDifference(currYaw, newYaw)); + const yawDiff = Math.abs(getAngleDifference(currYaw, newYaw)); const pitchDiff = Math.abs(newPitch - currPitch); // todo: this isnt what a null rotation packet is, which retard made these failsafes? if (yawDiff === 0 && pitchDiff === 0) { - Chat.messageDebug('null rotation packet ignored (yawDiff=0, pitchDiff=0)', false); + sendDebugMessage('null rotation packet ignored (yawDiff=0, pitchDiff=0)', false); return; } @@ -68,10 +68,10 @@ class RotationFailsafe extends Failsafe { const { pressure, severity, color } = tiers.find((t) => totalRotation < t.limit); - Chat.messageFailsafe(`&c&lYou were rotated by the server!`, false); - Chat.messageFailsafe(`&c&lFrom: &r&7Yaw ${fromYaw.toFixed(2)} &f| &7Pitch ${fromPitch.toFixed(2)}`, false); - Chat.messageFailsafe(`&c&lTo: &r&7Yaw ${toYaw.toFixed(2)} &f| &7Pitch ${toPitch.toFixed(2)}`, false); - Chat.messageFailsafe(`&c&lTotal Rotation: &r&7${totalRotation.toFixed(2)}°`, true); + sendFailsafeMessage(`&c&lYou were rotated by the server!`, false); + sendFailsafeMessage(`&c&lFrom: &r&7Yaw ${fromYaw.toFixed(2)} &f| &7Pitch ${fromPitch.toFixed(2)}`, false); + sendFailsafeMessage(`&c&lTo: &r&7Yaw ${toYaw.toFixed(2)} &f| &7Pitch ${toPitch.toFixed(2)}`, false); + sendFailsafeMessage(`&c&lTotal Rotation: &r&7${totalRotation.toFixed(2)}°`, true); FailsafeUtils.incrementFailsafeIntensity(pressure); FailsafeUtils.sendFailsafeEmbed( @@ -85,4 +85,4 @@ class RotationFailsafe extends Failsafe { } } -export default new RotationFailsafe(); +new RotationFailsafe(); diff --git a/failsafes/impl/SlotChangeFailsafe.js b/failsafes/impl/SlotChangeFailsafe.js index f41dca8d..abf02ce0 100644 --- a/failsafes/impl/SlotChangeFailsafe.js +++ b/failsafes/impl/SlotChangeFailsafe.js @@ -1,4 +1,4 @@ -import { Chat } from '../../utils/Chat'; +import { sendFailsafeMessage } from '../../utils/Chat'; import { ClientboundSetHeldSlotPacket } from '../../utils/Packets'; import { Failsafe } from '../Failsafe'; import FailsafeUtils from '../FailsafeUtils'; @@ -30,10 +30,10 @@ class SlotChangeFailsafe extends Failsafe { } onTrigger(fromSlot, toSlot) { - Chat.messageFailsafe(`&c&lHeld slot has changed from ${fromSlot} to slot ${toSlot}!`); + sendFailsafeMessage(`&c&lHeld slot has changed from ${fromSlot} to slot ${toSlot}!`); FailsafeUtils.incrementFailsafeIntensity(50); FailsafeUtils.sendFailsafeEmbed('Slot Change', 'high', `Slot changed from ${fromSlot} to ${toSlot}!`, 16744448); } } -export default new SlotChangeFailsafe(); +new SlotChangeFailsafe(); diff --git a/failsafes/impl/TeleportFailsafe.js b/failsafes/impl/TeleportFailsafe.js index bca7743e..9a84db13 100644 --- a/failsafes/impl/TeleportFailsafe.js +++ b/failsafes/impl/TeleportFailsafe.js @@ -1,5 +1,5 @@ -import { Chat } from '../../utils/Chat'; -import { MathUtils } from '../../utils/Math'; +import { sendDebugMessage, sendFailsafeMessage } from '../../utils/Chat'; +import { getAngleDifference } from '../../utils/Math'; import { ServerboundUseItemPacket, ClientboundPlayerPositionPacket, ServerboundChatCommandPacket } from '../../utils/Packets'; import PathConfig from '../../utils/pathfinder/PathConfig'; import { Failsafe } from '../Failsafe'; @@ -39,7 +39,7 @@ class TeleportFailsafe extends Failsafe { const command = packet.command().toLowerCase(); if (command.includes('warp')) { lastCommandTime = Date.now(); - Chat.messageDebug(`warp command used, awaiting warp-point teleport ignore`, false); + sendDebugMessage(`warp command used, awaiting warp-point teleport ignore`, false); pendingWarpIgnore = true; if (pendingWarpIgnoreTimer) clearTimeout(pendingWarpIgnoreTimer); pendingWarpIgnoreTimer = setTimeout(() => { @@ -79,7 +79,7 @@ class TeleportFailsafe extends Failsafe { const { yaw, pitch, currYaw, currPitch } = data; if (yaw === undefined || pitch === undefined) return false; - const yawDiff = Math.abs(MathUtils.getAngleDifference(currYaw, yaw)); + const yawDiff = Math.abs(getAngleDifference(currYaw, yaw)); const pitchDiff = Math.abs(pitch - currPitch); return yawDiff < 30 && pitchDiff < 30; } @@ -184,17 +184,17 @@ class TeleportFailsafe extends Failsafe { } handleNullPacket(x, y, z) { - Chat.messageFailsafe('&c&lNULL PACKET DETECTED, DO NOT REACT!', false); + sendFailsafeMessage('&c&lNULL PACKET DETECTED, DO NOT REACT!', false); FailsafeUtils.sendFailsafeEmbed('TP', 'very high - null packet', `You just recieved a null packet to ${x}, ${y}, ${z}!`, 16711680); } onTrigger(fX, fY, fZ, nX, nY, nZ, dist) { const { pressure, severity, color } = TELEPORT_TIERS.find((t) => dist < t.threshold); - Chat.messageFailsafe(`&l&cTeleport Detected!`, false); - Chat.messageFailsafe(`&c&lFrom: &r&7${fX.toFixed(2)}&f, &7${fY.toFixed(2)}&f, &7${fZ.toFixed(2)}&f`, false); - Chat.messageFailsafe(`&c&lTo: &r&7${nX.toFixed(2)}&f, &7${nY.toFixed(2)}&f, &7${nZ.toFixed(2)}&f`, false); - Chat.messageFailsafe(`&c&lTotal Blocks: &r&7${dist.toFixed(0)}`, true); + sendFailsafeMessage(`&l&cTeleport Detected!`, false); + sendFailsafeMessage(`&c&lFrom: &r&7${fX.toFixed(2)}&f, &7${fY.toFixed(2)}&f, &7${fZ.toFixed(2)}&f`, false); + sendFailsafeMessage(`&c&lTo: &r&7${nX.toFixed(2)}&f, &7${nY.toFixed(2)}&f, &7${nZ.toFixed(2)}&f`, false); + sendFailsafeMessage(`&c&lTotal Blocks: &r&7${dist.toFixed(0)}`, true); FailsafeUtils.incrementFailsafeIntensity(pressure); FailsafeUtils.sendFailsafeEmbed( @@ -208,4 +208,4 @@ class TeleportFailsafe extends Failsafe { } } -export default new TeleportFailsafe(); +new TeleportFailsafe(); diff --git a/failsafes/impl/VelocityFailsafe.js b/failsafes/impl/VelocityFailsafe.js index 8e92fe8a..806a5391 100644 --- a/failsafes/impl/VelocityFailsafe.js +++ b/failsafes/impl/VelocityFailsafe.js @@ -1,4 +1,4 @@ -import { Chat } from '../../utils/Chat'; +import { sendDebugMessage, sendFailsafeMessage } from '../../utils/Chat'; import { ClientboundSetEntityMotionPacket } from '../../utils/Packets'; import { Failsafe } from '../Failsafe'; import FailsafeUtils from '../FailsafeUtils'; @@ -65,7 +65,7 @@ class VelocityFailsafe extends Failsafe { const roundedVelocity = Math.round(velocity); if (blockBelow && !blockBelow.includes('air') && (roundedVelocity === 1 || roundedVelocity === 0)) { - Chat.messageDebug('disabling fall velocity packet'); + sendDebugMessage('disabling fall velocity packet'); this._setDisabled(1000); } @@ -82,10 +82,10 @@ class VelocityFailsafe extends Failsafe { onTrigger(speed) { const { pressure, severity, color } = VELOCITY_TIERS.find((t) => speed < t.threshold) || VELOCITY_TIERS[VELOCITY_TIERS.length - 1]; - Chat.messageFailsafe(`&c&lVelocity failsafe triggered! Velocity: ${speed.toFixed(0)}`); + sendFailsafeMessage(`&c&lVelocity failsafe triggered! Velocity: ${speed.toFixed(0)}`); FailsafeUtils.incrementFailsafeIntensity(pressure); FailsafeUtils.sendFailsafeEmbed('Velocity', severity, `Velocity change detected: ${speed.toFixed(0)}`, color); } } -export default new VelocityFailsafe(); +new VelocityFailsafe(); diff --git a/gui/Dashboard.js b/gui/Dashboard.js index 5d1b102f..1bc97403 100644 --- a/gui/Dashboard.js +++ b/gui/Dashboard.js @@ -1,8 +1,8 @@ import { FontSizes, PADDING, THEME, colorWithAlpha, drawRoundedRectangle, drawRoundedRectangleWithBorder, drawText, getTextWidth, isInside } from './Utils'; -import { MacroState } from '../utils/MacroState'; -import { TimeUtils } from '../utils/TimeUtils'; -import { Utils } from '../utils/Utils'; -import { ServerInfo } from '../utils/player/ServerInfo'; +import { modules as registeredModules } from '../utils/MacroState'; +import { formatUptime } from '../utils/TimeUtils'; +import { area, subArea } from '../utils/Utils'; +import { getPing, getPingColor, getTPS, getTpsColor } from '../utils/player/ServerInfo'; const clientStartedAt = Date.now(); @@ -23,18 +23,18 @@ const normalizeLocation = (value) => { }; const getActiveModules = () => { - const modules = []; + const activeModules = []; - MacroState.modules.forEach((module, name) => { + registeredModules.forEach((module, name) => { if (!module?.enabled) return; - modules.push({ + activeModules.push({ name, subcategory: module.subcategory || 'Other', isMacro: module.isMacro === true, }); }); - return modules.sort((a, b) => { + return activeModules.sort((a, b) => { const categorySort = a.subcategory.localeCompare(b.subcategory); if (categorySort !== 0) return categorySort; return a.name.localeCompare(b.name); @@ -43,16 +43,16 @@ const getActiveModules = () => { const getDebugRows = () => { const fps = Client.getFPS(); - const ping = ServerInfo.getPing(); - const tps = ServerInfo.getTPS(); + const ping = getPing(); + const tps = getTPS(); return [ { label: 'FPS', value: String(fps), color: getFpsColor(fps) }, - { label: 'Ping', value: `${ping}ms`, color: (0xff000000 | ServerInfo.getPingColor(ping)) >>> 0 }, - { label: 'TPS', value: tps.toFixed(2), color: (0xff000000 | ServerInfo.getTpsColor(tps)) >>> 0 }, - { label: 'Client Uptime', value: TimeUtils.formatUptime(clientStartedAt) }, - { label: 'Area', value: normalizeLocation(Utils.area()) }, - { label: 'Subarea', value: normalizeLocation(Utils.subArea()) }, + { label: 'Ping', value: `${ping}ms`, color: (0xff000000 | getPingColor(ping)) >>> 0 }, + { label: 'TPS', value: tps.toFixed(2), color: (0xff000000 | getTpsColor(tps)) >>> 0 }, + { label: 'Client Uptime', value: formatUptime(clientStartedAt) }, + { label: 'Area', value: normalizeLocation(area()) }, + { label: 'Subarea', value: normalizeLocation(subArea()) }, ]; }; diff --git a/gui/GUI.js b/gui/GUI.js index 17d40948..834a61d5 100644 --- a/gui/GUI.js +++ b/gui/GUI.js @@ -1,17 +1,6 @@ -import { Categories } from './categories/CategorySystem'; -import { openGui as open } from './core/GuiEvents'; -import { showNotification as notify } from './NotificationManager'; import './ProfileSettings'; import './ThemeSettings'; -import { - applySettings as _applySettings, - getSetting as _getSetting, - loadSettings as _loadSettings, - saveSettings as _saveSettings, - updateSettingMap as _updateSettingMap, -} from './GuiSave'; - const warmupTrigger = register('renderOverlay', () => { try { const width = Renderer.screen.getWidth(); @@ -21,42 +10,7 @@ const warmupTrigger = register('renderOverlay', () => { NVG.endFrame(); warmupTrigger.unregister(); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); warmupTrigger.unregister(); } }); - -export const saveSettings = _saveSettings; -export const loadSettings = _loadSettings; -export const getSetting = _getSetting; -export const updateSettingMap = _updateSettingMap; -export const applySettings = _applySettings; - -export const showNotification = (title, description, type = 'SUCCESS', duration = 5000) => notify(title, description, type, duration); - -export const addCategoryItem = (subcategoryName, title, description, tooltip = null) => - Categories.addCategoryItem(subcategoryName, title, description, tooltip); - -export const findItem = (categoryName, itemName) => Categories.findItem(categoryName, itemName); - -export const addToggle = (categoryName, itemName, toggleTitle, callback = null, description = null) => - Categories.addToggle(categoryName, itemName, toggleTitle, callback, description); - -export const addSlider = (categoryName, itemName, sliderTitle, min, max, defaultValue, callback = null, description = null) => - Categories.addSlider(categoryName, itemName, sliderTitle, min, max, defaultValue, callback, description); - -export const addMultiToggle = (categoryName, itemName, toggleTitle, options, singleSelect = false, callback = null, description = null) => - Categories.addMultiToggle(categoryName, itemName, toggleTitle, options, singleSelect, callback, description); - -export const addTextInput = (categoryName, itemName, title, defaultValue, callback = null, description = null) => - Categories.addTextInput(categoryName, itemName, title, defaultValue, callback, description); - -export const addButton = (categoryName, itemName, title, callback = null, description = null) => - Categories.addButton(categoryName, itemName, title, callback, description); - -export const addPopup = (categoryName, itemName, title, callback = null, description = null) => - Categories.addPopup(categoryName, itemName, title, callback, description); - -export const openGui = open; - -export const closeGui = () => Client.currentGui.close(); diff --git a/gui/GuiSave.js b/gui/GuiSave.js index c41304cc..873c46c4 100644 --- a/gui/GuiSave.js +++ b/gui/GuiSave.js @@ -1,7 +1,7 @@ -import { Chat } from '../utils/Chat'; +import { chat } from '../utils/Chat'; import { Color } from '../utils/Constants'; -import { MacroState } from '../utils/MacroState'; -import { Utils } from '../utils/Utils'; +import { getModule } from '../utils/MacroState'; +import { getConfigFile, writeConfigFile } from '../utils/Utils'; import { Categories } from './categories/CategorySystem'; import { Button } from './components/Button'; import { ColorPicker } from './components/ColorPicker'; @@ -44,7 +44,7 @@ function buildSettingsMapFromComponents() { } function storeModuleEnabledValue(moduleName) { - const module = MacroState.getModule(moduleName); + const module = getModule(moduleName); if (!module || module.showEnabledToggle === false) return; SettingsMap.set(`${moduleName}.Enabled`, !!module.enabled); } @@ -76,7 +76,7 @@ export const saveSettings = () => { settings[itemTitle][componentTitle] = value; } - Utils.writeConfigFile('config.json', settings); + writeConfigFile('config.json', settings); }; export const applySettings = () => { @@ -104,7 +104,7 @@ export const applySettings = () => { function applyModuleEnabled(moduleName, savedValue) { if (savedValue === undefined) return; - const module = MacroState.getModule(moduleName); + const module = getModule(moduleName); if (!module || module.showEnabledToggle === false) return; module.toggle(!!savedValue); @@ -124,7 +124,7 @@ function triggerComponentCallback(parentName, component) { } export const loadSettings = () => { - const settings = Utils.getConfigFile('config.json'); + const settings = getConfigFile('config.json'); if (!settings || Object.keys(settings).length === 0) { buildSettingsMapFromComponents(); @@ -157,7 +157,7 @@ export const loadSettings = () => { mergeSavedModuleEnabledStates(settings); applySettings(); } catch (e) { - Chat.message(`Error loading settings: ${e}`); + chat(`Error loading settings: ${e}`); console.error('V5 Caught error' + e + e.stack); buildSettingsMapFromComponents(); } diff --git a/gui/MacroToggleGui.js b/gui/MacroToggleGui.js index db759a16..c1058785 100644 --- a/gui/MacroToggleGui.js +++ b/gui/MacroToggleGui.js @@ -1,11 +1,11 @@ import { GuiRectangles, GuiState } from './core/GuiState'; import { FontSizes, PADDING, THEME, drawImage, drawRoundedRectangle, drawRoundedRectangleWithBorder, drawText, getTextWidth, isInside } from './Utils'; import { loadSettings } from './GuiSave'; -import { MacroState } from '../utils/MacroState'; +import { getEnabledMacros, getModule, modules as registeredModules } from '../utils/MacroState'; import { globalAssetsDir } from '../utils/Constants'; import { Categories } from './categories/CategorySystem'; import { drawSubcategoryButtons, getModuleBorderColor, getModuleNavButtonRect, getModuleNavRect, getModuleNavScrollX } from './categories/CategoryRenderer'; -import { Utils } from '../utils/Utils'; +import { getConfigFile, writeConfigFile } from '../utils/Utils'; import { v5Command } from '../utils/V5Commands'; const ROW_HEIGHT = 28; @@ -31,14 +31,14 @@ const macroCategoryState = { }; const loadFavorites = () => { - const saved = Utils.getConfigFile(FAVORITES_FILE); + const saved = getConfigFile(FAVORITES_FILE); favorites = new Set(Array.isArray(saved?.favorites) ? saved.favorites.filter((name) => typeof name === 'string') : []); }; -const saveFavorites = () => Utils.writeConfigFile(FAVORITES_FILE, { favorites: Array.from(favorites) }); +const saveFavorites = () => writeConfigFile(FAVORITES_FILE, { favorites: Array.from(favorites) }); const getMacros = () => - Array.from(MacroState.modules.values()) + Array.from(registeredModules.values()) .filter( (module) => module?.isMacro && @@ -248,16 +248,16 @@ register('guiKey', (char, keyCode, gui, event) => { }); const keyName = 'Macro Toggle GUI'; -const savedKeycode = Utils.getConfigFile('keybinds.json')?.[keyName] ?? Keyboard.KEY_M; +const savedKeycode = getConfigFile('keybinds.json')?.[keyName] ?? Keyboard.KEY_M; const keybind = new KeyBind(keyName, savedKeycode, 'v5_core'); keybind.registerKeyPress(() => { - MacroState.getEnabledMacros().forEach((name) => MacroState.getModule(name)?.toggle(false)); + getEnabledMacros().forEach((name) => getModule(name)?.toggle(false)); macroToggleGui.open(); }); register('gameUnload', () => { - const keybinds = Utils.getConfigFile('keybinds.json') || {}; + const keybinds = getConfigFile('keybinds.json') || {}; keybinds[keyName] = keybind.getKeyCode(); - Utils.writeConfigFile('keybinds.json', keybinds); + writeConfigFile('keybinds.json', keybinds); }); v5Command('macro gui', () => macroToggleGui.open()); diff --git a/gui/NotificationManager.js b/gui/NotificationManager.js index da575759..554f74a7 100644 --- a/gui/NotificationManager.js +++ b/gui/NotificationManager.js @@ -366,12 +366,12 @@ class NotificationManager { this.notifications[i].draw(); } } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } finally { try { NVG.endFrame(); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } } } diff --git a/gui/OverlayUtils.js b/gui/OverlayUtils.js index 8559ff13..7bfc74e1 100644 --- a/gui/OverlayUtils.js +++ b/gui/OverlayUtils.js @@ -1,5 +1,5 @@ -import { TimeUtils } from '../utils/TimeUtils'; -import { Utils } from '../utils/Utils'; +import { formatDurationMs, formatUptime } from '../utils/TimeUtils'; +import { getConfigFile, writeConfigFile } from '../utils/Utils'; import { BORDER_WIDTH, clamp, @@ -15,7 +15,7 @@ import { THEME, } from './Utils'; import { GuiState, Overlays } from './core/GuiState'; -import { ServerInfo } from '../utils/player/ServerInfo'; +import { getPing, getPingColor, getTPS, getTpsColor } from '../utils/player/ServerInfo'; const { loadSettings } = require('./GuiSave'); @@ -224,10 +224,10 @@ class OverlayUtils { getMacroDuration(macroName) { const saved = this.savedSessions && this.savedSessions[macroName]; - if (saved && typeof saved.elapsedMs === 'number') return TimeUtils.formatDurationMs(saved.elapsedMs); + if (saved && typeof saved.elapsedMs === 'number') return formatDurationMs(saved.elapsedMs); const startTime = this.startTimes && this.startTimes[macroName]; - return startTime ? TimeUtils.formatUptime(startTime) : ''; + return startTime ? formatUptime(startTime) : ''; } initTriggers() { @@ -530,7 +530,7 @@ class OverlayUtils { const basePadding = boxPadding; const sections = this.ensureArray(id.sections); - const uptimeVal = forceGUI ? '0.00s' : TimeUtils.formatUptime(this.startTimes[id.name]); + const uptimeVal = forceGUI ? '0.00s' : formatUptime(this.startTimes[id.name]); let contentMaxWidth = getTextWidth(id.name, fontSize); let calculatedHeight = 30 * scale; @@ -708,7 +708,7 @@ class OverlayUtils { const textWidth = getTextWidth(text, FontSizes.MEDIUM); drawText(text, (sw - textWidth) / 2, 30, FontSizes.MEDIUM, THEME.TEXT, 16); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } finally { NVG.endFrame(); } @@ -736,23 +736,23 @@ class OverlayUtils { this.renderID(id, false, { sw, sh }); }); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } finally { NVG.endFrame(); } } saveSettings() { - Utils.writeConfigFile('OverlayPositions/overlays.json', { + writeConfigFile('OverlayPositions/overlays.json', { default: this.settings, scheduler: this.schedulerSettings, }); - Utils.writeConfigFile('OverlayPositions/hud_positions.json', this.hudSettings); - Utils.writeConfigFile('OverlayPositions/music_overlay.json', this.musicSettings); + writeConfigFile('OverlayPositions/hud_positions.json', this.hudSettings); + writeConfigFile('OverlayPositions/music_overlay.json', this.musicSettings); } loadSettings() { - const data = Utils.getConfigFile('OverlayPositions/overlays.json'); + const data = getConfigFile('OverlayPositions/overlays.json'); if (data) { if (data.default && typeof data.default.x === 'number') { this.settings = { @@ -780,7 +780,7 @@ class OverlayUtils { this.updateScaleProps('scheduler'); } - const hudData = Utils.getConfigFile('OverlayPositions/hud_positions.json'); + const hudData = getConfigFile('OverlayPositions/hud_positions.json'); if (hudData && typeof hudData === 'object') { if (hudData.stats && typeof hudData.stats.x === 'number') { this.hudSettings.stats = { @@ -799,7 +799,7 @@ class OverlayUtils { } } - const musicData = Utils.getConfigFile('OverlayPositions/music_overlay.json'); + const musicData = getConfigFile('OverlayPositions/music_overlay.json'); if (musicData && typeof musicData === 'object' && typeof musicData.x === 'number' && typeof musicData.y === 'number') { this.musicSettings = { x: musicData.x, @@ -982,12 +982,12 @@ class OverlayUtils { getHudStatsLines() { const fps = Client.getFPS(); - const ping = ServerInfo.getPing(); - const tps = ServerInfo.getTPS(); + const ping = getPing(); + const tps = getTPS(); return [ { label: 'FPS', value: String(fps), color: THEME.TEXT }, - { label: 'Ping', value: `${ping}ms`, color: (0xff000000 | ServerInfo.getPingColor(ping)) >>> 0 }, - { label: 'TPS', value: tps.toFixed(2), color: (0xff000000 | ServerInfo.getTpsColor(tps)) >>> 0 }, + { label: 'Ping', value: `${ping}ms`, color: (0xff000000 | getPingColor(ping)) >>> 0 }, + { label: 'TPS', value: tps.toFixed(2), color: (0xff000000 | getTpsColor(tps)) >>> 0 }, ]; } diff --git a/gui/Utils.js b/gui/Utils.js index 0d39c4c2..4b1ee551 100644 --- a/gui/Utils.js +++ b/gui/Utils.js @@ -28,11 +28,7 @@ export const CORNER_RADIUS = 12; export const CATEGORY_HEIGHT = 30; export const CATEGORY_PADDING = 4; -export const LEFT_PANEL_TEXT_HEIGHT = 8; - -export const CATEGORY_BOX_PADDING = 8; export const ITEM_SPACING = 6; -export const SEPARATOR_HEIGHT = 24; export const SUBCATEGORY_BUTTON_HEIGHT = 24; export const SUBCATEGORY_BUTTON_SPACING = 4; @@ -197,10 +193,6 @@ export const resetScissor = () => { NVG.resetScissor(); }; -export const composite = (op) => { - NVG.setGlobalCompositeOperation(op); -}; - export const clamp = (v, min, max) => (v < min ? min : v > max ? max : v); export const interpolateColor = (from, to, progress) => diff --git a/gui/categories/CategoryEvents.js b/gui/categories/CategoryEvents.js index 752b1518..29bf2308 100644 --- a/gui/categories/CategoryEvents.js +++ b/gui/categories/CategoryEvents.js @@ -40,7 +40,7 @@ const getCategorySelectionRect = (name) => { return { ...rect, radius: 8 }; }; -export const handleDirectComponentsClick = (mouseX, mouseY, panel, scrollY, categoryName) => { +const handleDirectComponentsClick = (mouseX, mouseY, panel, scrollY, categoryName) => { const directCat = Categories.categories.find((c) => c.name === categoryName); if (!directCat || !directCat.directComponents) return false; const contentTop = directCat.subcategories.length > 0 ? getCategoryContentY(directCat, panel) : panel.y; diff --git a/gui/categories/CategoryManager.js b/gui/categories/CategoryManager.js index 3080c5c7..3c8e06d6 100644 --- a/gui/categories/CategoryManager.js +++ b/gui/categories/CategoryManager.js @@ -12,769 +12,761 @@ import { handleCategoryClick, handleCategoryScroll, updateCategoryTransitions } import { drawCategoryItems, drawDirectComponents, drawOptionsPanel, getCategoryContentY, getCategoryRect, getDiscordPfpRect } from './CategoryRenderer'; import { SearchBar } from './CategorySearchBar'; import { Categories, getVisibleDirectComponents } from './CategorySystem'; -import { MacroState } from '../../utils/MacroState'; +import { getModule } from '../../utils/MacroState'; import { drawDashboard, getDashboardContentHeight, getDashboardModuleAt } from '../Dashboard'; -export const createCategoriesManager = (deps) => { - let targetRightPanelScrollY = 0; - let currentRightPanelScrollY = 0; - - let targetOptionsScrollY = 0; - let currentOptionsScrollY = 0; - - let cachedItemLayouts = []; - let isLayoutCacheValid = false; - let cachedContentHeight = 0; - let isContentHeightCacheValid = false; - let lastQuery = ''; - let pendingSettingsComponent = null; - let pendingThemeComponent = null; - let pendingModuleComponent = null; - let autoScrollRightActive = false; - let autoScrollOptionsActive = false; - let pendingHighlightComponent = null; - let lastDrawTime = Date.now(); - const macroToggleButton = new Button( - '', - 0, - 0, - 'Enable', - () => { - const selectedItem = Categories.selectedItem; - if (!selectedItem) return; - - const module = MacroState.getModule(selectedItem.title); - if (!module) return; - - const enabledByClick = typeof module.requestToggleFromUser === 'function' ? module.requestToggleFromUser() : false; - if (module.isMacro && enabledByClick && GuiState.myGui.isOpen()) { - Client.currentGui.close(); - } - }, - { showContainer: false } - ); - - const SCROLL_SMOOTHING_FACTOR = 0.25; - const AUTO_SCROLL_SMOOTHING_FACTOR = 0.06; - const getCategorySelectionRect = (name) => { - if (name === 'Discord') { - const pfpRect = getDiscordPfpRect(); - return { x: pfpRect.x - 2, y: pfpRect.y - 2, width: pfpRect.width + 4, height: pfpRect.height + 4, radius: 16 }; +let targetRightPanelScrollY = 0; +let currentRightPanelScrollY = 0; + +let targetOptionsScrollY = 0; +let currentOptionsScrollY = 0; + +let cachedItemLayouts = []; +let isLayoutCacheValid = false; +let cachedContentHeight = 0; +let isContentHeightCacheValid = false; +let lastQuery = ''; +let pendingSettingsComponent = null; +let pendingThemeComponent = null; +let pendingModuleComponent = null; +let autoScrollRightActive = false; +let autoScrollOptionsActive = false; +let pendingHighlightComponent = null; +let lastDrawTime = Date.now(); +const macroToggleButton = new Button( + '', + 0, + 0, + 'Enable', + () => { + const selectedItem = Categories.selectedItem; + if (!selectedItem) return; + + const module = getModule(selectedItem.title); + if (!module) return; + + const enabledByClick = typeof module.requestToggleFromUser === 'function' ? module.requestToggleFromUser() : false; + if (module.isMacro && enabledByClick && GuiState.myGui.isOpen()) { + Client.currentGui.close(); } - const visibleIndex = Categories.getVisibleCategories().findIndex((category) => category.name === name); - if (visibleIndex === -1) return null; - const rect = getCategoryRect(visibleIndex); - return { - x: rect.x, - y: rect.y, - width: rect.width, - height: rect.height, - radius: 8, - }; - }; - - const setRightPanelScrollY = (value) => { - currentRightPanelScrollY = value; - targetRightPanelScrollY = value; - }; - const setTargetRightPanelScrollY = (value) => { - targetRightPanelScrollY = value; + }, + { showContainer: false } +); + +const SCROLL_SMOOTHING_FACTOR = 0.25; +const AUTO_SCROLL_SMOOTHING_FACTOR = 0.06; +const getCategorySelectionRect = (name) => { + if (name === 'Discord') { + const pfpRect = getDiscordPfpRect(); + return { x: pfpRect.x - 2, y: pfpRect.y - 2, width: pfpRect.width + 4, height: pfpRect.height + 4, radius: 16 }; + } + const visibleIndex = Categories.getVisibleCategories().findIndex((category) => category.name === name); + if (visibleIndex === -1) return null; + const rect = getCategoryRect(visibleIndex); + return { + x: rect.x, + y: rect.y, + width: rect.width, + height: rect.height, + radius: 8, }; +}; - const setOptionsScrollY = (value) => { - currentOptionsScrollY = value; - targetOptionsScrollY = value; - Categories.optionsScrollY = value; - }; - const setTargetOptionsScrollY = (value) => { - targetOptionsScrollY = value; - }; +const setRightPanelScrollY = (value) => { + currentRightPanelScrollY = value; + targetRightPanelScrollY = value; +}; +const setTargetRightPanelScrollY = (value) => { + targetRightPanelScrollY = value; +}; - const resetCategoryScroll = () => { - setRightPanelScrollY(0); - setOptionsScrollY(0); - }; +const setOptionsScrollY = (value) => { + currentOptionsScrollY = value; + targetOptionsScrollY = value; + Categories.optionsScrollY = value; +}; +const setTargetOptionsScrollY = (value) => { + targetOptionsScrollY = value; +}; - const beginCategorySwap = (targetName) => { - Categories.optionsReturnCategory = null; - Categories.previousSelected = Categories.selected; - Categories.selected = targetName; - Categories.currentPage = 'categories'; - Categories.selectedItem = null; - Categories.selectedSubcategory = null; - Categories.transitionType = 'category-swap'; - const oldRect = getCategorySelectionRect(Categories.previousSelected); - const newRect = getCategorySelectionRect(targetName); - if (oldRect && newRect) { - Categories.catAnimationRect = { - startX: oldRect.x, - startY: oldRect.y, - endX: newRect.x, - endY: newRect.y, - width: oldRect.width, - height: oldRect.height, - startRadius: oldRect.radius || 8, - endRadius: newRect.radius || 8, - radius: oldRect.radius || 8, - }; - Categories.catTransitionStart = Date.now(); - Categories.transitionDirection = newRect.y >= oldRect.y ? 1 : -1; - } else { - Categories.transitionDirection = 1; - } - Categories.transitionProgress = 0; - Categories.transitionStart = Date.now(); - playClickSound(); - isLayoutCacheValid = false; - isContentHeightCacheValid = false; - resetCategoryScroll(); - }; +const resetCategoryScroll = () => { + setRightPanelScrollY(0); + setOptionsScrollY(0); +}; - const beginModuleOptionsSwap = (moduleItem, returnCategory = null) => { - Categories.transitionType = 'page'; +const beginCategorySwap = (targetName) => { + Categories.optionsReturnCategory = null; + Categories.previousSelected = Categories.selected; + Categories.selected = targetName; + Categories.currentPage = 'categories'; + Categories.selectedItem = null; + Categories.selectedSubcategory = null; + Categories.transitionType = 'category-swap'; + const oldRect = getCategorySelectionRect(Categories.previousSelected); + const newRect = getCategorySelectionRect(targetName); + if (oldRect && newRect) { + Categories.catAnimationRect = { + startX: oldRect.x, + startY: oldRect.y, + endX: newRect.x, + endY: newRect.y, + width: oldRect.width, + height: oldRect.height, + startRadius: oldRect.radius || 8, + endRadius: newRect.radius || 8, + radius: oldRect.radius || 8, + }; + Categories.catTransitionStart = Date.now(); + Categories.transitionDirection = newRect.y >= oldRect.y ? 1 : -1; + } else { Categories.transitionDirection = 1; - Categories.transitionProgress = 0; - Categories.transitionStart = Date.now(); - Categories.selectedItem = moduleItem; - Categories.optionsReturnCategory = returnCategory; - playClickSound(); - isLayoutCacheValid = false; - isContentHeightCacheValid = false; - resetCategoryScroll(); - }; - - const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); - const getSearchRegexes = (query) => { - const tokens = query.trim().toLowerCase().split(/\s+/).filter(Boolean); - return tokens.map((token) => new RegExp(`\\b${escapeRegExp(token)}`)); - }; - const matchesSearch = (value, searchRegexes) => { - if (!value || searchRegexes.length === 0) return false; - const text = value.toLowerCase(); - return searchRegexes.every((regex) => regex.test(text)); - }; + } + Categories.transitionProgress = 0; + Categories.transitionStart = Date.now(); + playClickSound(); + isLayoutCacheValid = false; + isContentHeightCacheValid = false; + resetCategoryScroll(); +}; - const getFilteredItems = (cat, query) => { - const searchRegexes = getSearchRegexes(query); +const beginModuleOptionsSwap = (moduleItem, returnCategory = null) => { + Categories.transitionType = 'page'; + Categories.transitionDirection = 1; + Categories.transitionProgress = 0; + Categories.transitionStart = Date.now(); + Categories.selectedItem = moduleItem; + Categories.optionsReturnCategory = returnCategory; + playClickSound(); + isLayoutCacheValid = false; + isContentHeightCacheValid = false; + resetCategoryScroll(); +}; - if (searchRegexes.length === 0) { - return cat.items.filter((group) => { - if (group.type === 'separator') { - return Categories.selectedSubcategory === null || group.title === Categories.selectedSubcategory; - } - return true; - }); - } +const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); +const getSearchRegexes = (query) => { + const tokens = query.trim().toLowerCase().split(/\s+/).filter(Boolean); + return tokens.map((token) => new RegExp(`\\b${escapeRegExp(token)}`)); +}; +const matchesSearch = (value, searchRegexes) => { + if (!value || searchRegexes.length === 0) return false; + const text = value.toLowerCase(); + return searchRegexes.every((regex) => regex.test(text)); +}; - const categoryMatches = matchesSearch(cat.name, searchRegexes); - const allowComponentMatch = cat.name !== 'Modules'; +const getFilteredItems = (cat, query) => { + const searchRegexes = getSearchRegexes(query); - return cat.items.reduce((acc, group) => { + if (searchRegexes.length === 0) { + return cat.items.filter((group) => { if (group.type === 'separator') { - const subcategoryMatches = matchesSearch(group.title, searchRegexes); + return Categories.selectedSubcategory === null || group.title === Categories.selectedSubcategory; + } + return true; + }); + } - const matchingItems = group.items.filter((item) => { - const titleMatch = matchesSearch(item.title, searchRegexes); - const descMatch = matchesSearch(item.description, searchRegexes); + const categoryMatches = matchesSearch(cat.name, searchRegexes); + const allowComponentMatch = cat.name !== 'Modules'; - const componentMatch = - item.components && item.components.some((comp) => isComponentVisible(comp) && matchesSearch(comp.title, searchRegexes)); - return categoryMatches || subcategoryMatches || titleMatch || descMatch || (allowComponentMatch && componentMatch); - }); + return cat.items.reduce((acc, group) => { + if (group.type === 'separator') { + const subcategoryMatches = matchesSearch(group.title, searchRegexes); - if (matchingItems.length > 0) { - const groupCopy = Object.assign(Object.create(Object.getPrototypeOf(group)), group); - groupCopy.items = matchingItems; - acc.push(groupCopy); - } - } else { - const titleMatch = matchesSearch(group.title, searchRegexes); - const componentMatch = - group.components && group.components.some((comp) => isComponentVisible(comp) && matchesSearch(comp.title, searchRegexes)); + const matchingItems = group.items.filter((item) => { + const titleMatch = matchesSearch(item.title, searchRegexes); + const descMatch = matchesSearch(item.description, searchRegexes); - if (categoryMatches || titleMatch || (allowComponentMatch && componentMatch)) { - acc.push(group); - } + const componentMatch = item.components && item.components.some((comp) => isComponentVisible(comp) && matchesSearch(comp.title, searchRegexes)); + return categoryMatches || subcategoryMatches || titleMatch || descMatch || (allowComponentMatch && componentMatch); + }); + + if (matchingItems.length > 0) { + const groupCopy = Object.assign(Object.create(Object.getPrototypeOf(group)), group); + groupCopy.items = matchingItems; + acc.push(groupCopy); } - return acc; - }, []); - }; + } else { + const titleMatch = matchesSearch(group.title, searchRegexes); + const componentMatch = group.components && group.components.some((comp) => isComponentVisible(comp) && matchesSearch(comp.title, searchRegexes)); - const getDirectComponentMatches = (categoryName, resultTitle, resultType, query) => { - const searchRegexes = getSearchRegexes(query); - if (searchRegexes.length === 0) return []; + if (categoryMatches || titleMatch || (allowComponentMatch && componentMatch)) { + acc.push(group); + } + } + return acc; + }, []); +}; - const directCategory = Categories.categories.find((c) => c.name === categoryName); - if (!directCategory || !directCategory.directComponents) return []; +const getDirectComponentMatches = (categoryName, resultTitle, resultType, query) => { + const searchRegexes = getSearchRegexes(query); + if (searchRegexes.length === 0) return []; + + const directCategory = Categories.categories.find((c) => c.name === categoryName); + if (!directCategory || !directCategory.directComponents) return []; + + const matches = directCategory.directComponents.filter((component) => { + if (!isComponentVisible(component)) return false; + const titleMatch = matchesSearch(component.title, searchRegexes); + const descMatch = matchesSearch(component.description, searchRegexes); + const sectionMatch = matchesSearch(component.sectionName, searchRegexes); + return titleMatch || descMatch || sectionMatch; + }); + + if (matches.length === 0) return []; + + const resultGroup = new Separator(resultTitle, true); + resultGroup.items = matches.map((component) => ({ + type: resultType, + component, + title: component.title, + description: component.description, + sectionName: component.sectionName || categoryName, + tooltip: component.description || null, + })); + + return [resultGroup]; +}; - const matches = directCategory.directComponents.filter((component) => { - if (!isComponentVisible(component)) return false; - const titleMatch = matchesSearch(component.title, searchRegexes); - const descMatch = matchesSearch(component.description, searchRegexes); - const sectionMatch = matchesSearch(component.sectionName, searchRegexes); - return titleMatch || descMatch || sectionMatch; - }); +const getSettingsDirectMatches = (query) => getDirectComponentMatches('Settings', 'Settings Results', 'direct-component', query); +const getThemeDirectMatches = (query) => getDirectComponentMatches('Theme', 'Theme Results', 'theme-component', query); - if (matches.length === 0) return []; +const getModuleComponentMatches = (cat, query) => { + const searchRegexes = getSearchRegexes(query); + if (searchRegexes.length === 0 || !cat) return []; - const resultGroup = new Separator(resultTitle, true); - resultGroup.items = matches.map((component) => ({ - type: resultType, + const matches = []; + const pushMatch = (item, component) => { + matches.push({ + type: 'module-component', component, + parentItem: item, title: component.title, description: component.description, - sectionName: component.sectionName || categoryName, + moduleTitle: item.title, tooltip: component.description || null, - })); + moduleType: item.moduleType, + }); + }; - return [resultGroup]; + const checkComponent = (item, component) => { + if (!component || !isComponentVisible(component) || component instanceof Separator) return; + const titleMatch = matchesSearch(component.title, searchRegexes); + const descMatch = matchesSearch(component.description, searchRegexes); + if (titleMatch || descMatch) pushMatch(item, component); }; - const getSettingsDirectMatches = (query) => getDirectComponentMatches('Settings', 'Settings Results', 'direct-component', query); - const getThemeDirectMatches = (query) => getDirectComponentMatches('Theme', 'Theme Results', 'theme-component', query); - - const getModuleComponentMatches = (cat, query) => { - const searchRegexes = getSearchRegexes(query); - if (searchRegexes.length === 0 || !cat) return []; - - const matches = []; - const pushMatch = (item, component) => { - matches.push({ - type: 'module-component', - component, - parentItem: item, - title: component.title, - description: component.description, - moduleTitle: item.title, - tooltip: component.description || null, - moduleType: item.moduleType, + cat.items.forEach((group) => { + if (group.type === 'separator') { + group.items.forEach((item) => { + item.components?.forEach((component) => checkComponent(item, component)); }); - }; - - const checkComponent = (item, component) => { - if (!component || !isComponentVisible(component) || component instanceof Separator) return; - const titleMatch = matchesSearch(component.title, searchRegexes); - const descMatch = matchesSearch(component.description, searchRegexes); - if (titleMatch || descMatch) pushMatch(item, component); - }; - - cat.items.forEach((group) => { - if (group.type === 'separator') { - group.items.forEach((item) => { - item.components?.forEach((component) => checkComponent(item, component)); - }); - } else { - group.components?.forEach((component) => checkComponent(group, component)); - } - }); + } else { + group.components?.forEach((component) => checkComponent(group, component)); + } + }); - if (matches.length === 0) return []; + if (matches.length === 0) return []; - const resultGroup = new Separator('Module Settings', true); - resultGroup.items = matches; - return [resultGroup]; - }; - - const calculateDirectComponentsHeight = (categoryName) => { - const directCat = Categories.categories.find((c) => c.name === categoryName); - if (!directCat || !directCat.directComponents) return 0; + const resultGroup = new Separator('Module Settings', true); + resultGroup.items = matches; + return [resultGroup]; +}; - const panel = deps.rectangles.RightPanel; - return getCategoryContentY(directCat, panel) - panel.y + layoutDirectComponents(getVisibleDirectComponents(categoryName)).height; - }; +const calculateDirectComponentsHeight = (categoryName) => { + const directCat = Categories.categories.find((c) => c.name === categoryName); + if (!directCat || !directCat.directComponents) return 0; - const getDirectComponentScrollY = (categoryName, component) => { - const directCategory = Categories.categories.find((c) => c.name === categoryName); - if (!directCategory || !directCategory.directComponents) return 0; + const panel = GuiRectangles.RightPanel; + return getCategoryContentY(directCat, panel) - panel.y + layoutDirectComponents(getVisibleDirectComponents(categoryName)).height; +}; - const panel = deps.rectangles.RightPanel; - const row = layoutDirectComponents(directCategory.directComponents, getCategoryContentY(directCategory, panel) - panel.y).rows.find( - (item) => item.component === component - ); - return row ? Math.max(0, row.y - 10) : 0; - }; +const getDirectComponentScrollY = (categoryName, component) => { + const directCategory = Categories.categories.find((c) => c.name === categoryName); + if (!directCategory || !directCategory.directComponents) return 0; - const getModuleComponentScrollY = (item, component) => { - if (!item || !item.components) return 0; + const panel = GuiRectangles.RightPanel; + const row = layoutDirectComponents(directCategory.directComponents, getCategoryContentY(directCategory, panel) - panel.y).rows.find( + (item) => item.component === component + ); + return row ? Math.max(0, row.y - 10) : 0; +}; - let currentY = 78; - for (let i = 0; i < item.components.length; i++) { - const comp = item.components[i]; - if (!isComponentVisible(comp)) continue; - if (comp === component) { - return Math.max(0, currentY - 10); - } +const getModuleComponentScrollY = (item, component) => { + if (!item || !item.components) return 0; - currentY += getComponentLayoutHeight(comp); + let currentY = 78; + for (let i = 0; i < item.components.length; i++) { + const comp = item.components[i]; + if (!isComponentVisible(comp)) continue; + if (comp === component) { + return Math.max(0, currentY - 10); } - return 0; - }; + currentY += getComponentLayoutHeight(comp); + } - const getSelectedToggleModule = () => { - if (!Categories.selectedItem || Categories.selected !== 'Modules') return null; - const module = MacroState.getModule(Categories.selectedItem.title); - if (!module) return null; - return module.showEnabledToggle ? module : null; - }; - - const calculateContentHeight = () => { - if (Categories.selected === 'Dashboard') { - cachedContentHeight = getDashboardContentHeight(); - isContentHeightCacheValid = true; - return; - } + return 0; +}; - if (!isContentHeightCacheValid && Categories.selected) { - let height = 0; - const category = Categories.categories.find((c) => c.name === Categories.selected); +const getSelectedToggleModule = () => { + if (!Categories.selectedItem || Categories.selected !== 'Modules') return null; + const module = getModule(Categories.selectedItem.title); + if (!module) return null; + return module.showEnabledToggle ? module : null; +}; - if (category) { - if (category.directComponents && category.directComponents.length > 0) { - height = calculateDirectComponentsHeight(Categories.selected); - cachedContentHeight = height; - isContentHeightCacheValid = true; - return; - } - const rawQuery = SearchBar.query.trim(); - const query = rawQuery.toLowerCase(); - if (category.subcategories.length > 0 && (query.length === 0 || category.name === 'Modules')) { - height += getCategoryContentY(category, deps.rectangles.RightPanel) - deps.rectangles.RightPanel.y; +const calculateContentHeight = () => { + if (Categories.selected === 'Dashboard') { + cachedContentHeight = getDashboardContentHeight(); + isContentHeightCacheValid = true; + return; + } + + if (!isContentHeightCacheValid && Categories.selected) { + let height = 0; + const category = Categories.categories.find((c) => c.name === Categories.selected); + + if (category) { + if (category.directComponents && category.directComponents.length > 0) { + height = calculateDirectComponentsHeight(Categories.selected); + cachedContentHeight = height; + isContentHeightCacheValid = true; + return; + } + const rawQuery = SearchBar.query.trim(); + const query = rawQuery.toLowerCase(); + if (category.subcategories.length > 0 && (query.length === 0 || category.name === 'Modules')) { + height += getCategoryContentY(category, GuiRectangles.RightPanel) - GuiRectangles.RightPanel.y; + } + const itemsToDisplay = getFilteredItems(category, query); + const gridColumns = GuiRectangles.RightPanel.width < 300 ? 1 : 3; + const gridRowHeight = category.name === 'Modules' ? 46 : 54; + let nonGroupedItemCount = 0; + let hasAnyResults = itemsToDisplay.length > 0; + const processNonGrouped = () => { + if (nonGroupedItemCount > 0) { + height += Math.ceil(nonGroupedItemCount / gridColumns) * gridRowHeight; + nonGroupedItemCount = 0; } - const itemsToDisplay = getFilteredItems(category, query); - const gridColumns = deps.rectangles.RightPanel.width < 300 ? 1 : 3; - const gridRowHeight = category.name === 'Modules' ? 46 : 54; - let nonGroupedItemCount = 0; - let hasAnyResults = itemsToDisplay.length > 0; - const processNonGrouped = () => { - if (nonGroupedItemCount > 0) { - height += Math.ceil(nonGroupedItemCount / gridColumns) * gridRowHeight; - nonGroupedItemCount = 0; - } - }; - itemsToDisplay.forEach((group, index) => { - if (group.type === 'separator') { - processNonGrouped(); - if (index > 0) height += 12; - height += 22; - if (group.items.length > 0) { - height += Math.ceil(group.items.length / gridColumns) * gridRowHeight; - } - } else { - nonGroupedItemCount++; - } - }); - processNonGrouped(); - - if (category.name === 'Modules' && query.length > 0) { - const moduleMatches = getModuleComponentMatches(category, query); - const settingsMatches = getSettingsDirectMatches(query); - const themeMatches = getThemeDirectMatches(query); - - if (moduleMatches.length > 0) { - if (itemsToDisplay.length > 0) height += 12; - height += 22; - height += Math.ceil(moduleMatches[0].items.length / gridColumns) * gridRowHeight; - hasAnyResults = true; - } - - if (settingsMatches.length > 0) { - if (itemsToDisplay.length > 0 || moduleMatches.length > 0) height += 12; - height += 22; - height += Math.ceil(settingsMatches[0].items.length / gridColumns) * gridRowHeight; - hasAnyResults = true; - } - - if (themeMatches.length > 0) { - if (itemsToDisplay.length > 0 || moduleMatches.length > 0 || settingsMatches.length > 0) height += 12; - height += 22; - height += Math.ceil(themeMatches[0].items.length / gridColumns) * gridRowHeight; - hasAnyResults = true; + }; + itemsToDisplay.forEach((group, index) => { + if (group.type === 'separator') { + processNonGrouped(); + if (index > 0) height += 12; + height += 22; + if (group.items.length > 0) { + height += Math.ceil(group.items.length / gridColumns) * gridRowHeight; } + } else { + nonGroupedItemCount++; + } + }); + processNonGrouped(); + + if (category.name === 'Modules' && query.length > 0) { + const moduleMatches = getModuleComponentMatches(category, query); + const settingsMatches = getSettingsDirectMatches(query); + const themeMatches = getThemeDirectMatches(query); + + if (moduleMatches.length > 0) { + if (itemsToDisplay.length > 0) height += 12; + height += 22; + height += Math.ceil(moduleMatches[0].items.length / gridColumns) * gridRowHeight; + hasAnyResults = true; } - if (query.length > 0 && !hasAnyResults) { - height += 64; + if (settingsMatches.length > 0) { + if (itemsToDisplay.length > 0 || moduleMatches.length > 0) height += 12; + height += 22; + height += Math.ceil(settingsMatches[0].items.length / gridColumns) * gridRowHeight; + hasAnyResults = true; } - height += PADDING; + if (themeMatches.length > 0) { + if (itemsToDisplay.length > 0 || moduleMatches.length > 0 || settingsMatches.length > 0) height += 12; + height += 22; + height += Math.ceil(themeMatches[0].items.length / gridColumns) * gridRowHeight; + hasAnyResults = true; + } } - cachedContentHeight = height; - isContentHeightCacheValid = true; - } - }; - const calculateOptionsContentHeight = () => { - if (Categories.currentPage === 'options' && Categories.selectedItem) { - let height = 78 + PADDING; - const components = Categories.selectedItem.components; - if (components) { - components.forEach((component) => { - height += getComponentLayoutHeight(component); - }); + if (query.length > 0 && !hasAnyResults) { + height += 64; } + height += PADDING; - return height; } - return 0; - }; - - const drawPopups = (mouseX, mouseY) => { - const components = Categories.currentPage === 'categories' ? getVisibleDirectComponents(Categories.selected) : Categories.selectedItem?.components; - if (!components) return; - - components.forEach((component) => { - if (isComponentVisible(component) && component instanceof Popup && typeof component.drawOverlay === 'function') { - component.drawOverlay(mouseX, mouseY); - } - }); - }; + cachedContentHeight = height; + isContentHeightCacheValid = true; + } +}; - const draw = (mouseX, mouseY) => { - const now = Date.now(); - const elapsedFrames = Math.max(0, now - lastDrawTime) / (1000 / 60); - lastDrawTime = now; - - if (pendingSettingsComponent && Categories.selected === 'Settings' && Categories.currentPage === 'categories' && Categories.transitionDirection === 0) { - const targetScroll = getDirectComponentScrollY('Settings', pendingSettingsComponent); - setTargetRightPanelScrollY(targetScroll); - autoScrollRightActive = true; - pendingHighlightComponent = pendingSettingsComponent; - pendingSettingsComponent = null; +const calculateOptionsContentHeight = () => { + if (Categories.currentPage === 'options' && Categories.selectedItem) { + let height = 78 + PADDING; + const components = Categories.selectedItem.components; + if (components) { + components.forEach((component) => { + height += getComponentLayoutHeight(component); + }); } + height += PADDING; + return height; + } + return 0; +}; - if (pendingThemeComponent && Categories.selected === 'Theme' && Categories.currentPage === 'categories' && Categories.transitionDirection === 0) { - const targetScroll = getDirectComponentScrollY('Theme', pendingThemeComponent); - setTargetRightPanelScrollY(targetScroll); - autoScrollRightActive = true; - pendingHighlightComponent = pendingThemeComponent; - pendingThemeComponent = null; - } +const drawPopups = (mouseX, mouseY) => { + const components = Categories.currentPage === 'categories' ? getVisibleDirectComponents(Categories.selected) : Categories.selectedItem?.components; + if (!components) return; - if ( - pendingModuleComponent && - Categories.currentPage === 'options' && - Categories.selectedItem === pendingModuleComponent.item && - Categories.transitionDirection === 0 - ) { - const targetScroll = getModuleComponentScrollY(pendingModuleComponent.item, pendingModuleComponent.component); - setTargetOptionsScrollY(targetScroll); - autoScrollOptionsActive = true; - pendingHighlightComponent = pendingModuleComponent.component; - pendingModuleComponent = null; + components.forEach((component) => { + if (isComponentVisible(component) && component instanceof Popup && typeof component.drawOverlay === 'function') { + component.drawOverlay(mouseX, mouseY); } + }); +}; - const rawQuery = SearchBar.query.trim(); - const query = rawQuery.toLowerCase(); - if (query !== lastQuery) { - isContentHeightCacheValid = false; - isLayoutCacheValid = false; - if (query && Categories.selected !== 'Modules') beginCategorySwap('Modules'); - lastQuery = query; - } +const draw = (mouseX, mouseY) => { + const now = Date.now(); + const elapsedFrames = Math.max(0, now - lastDrawTime) / (1000 / 60); + lastDrawTime = now; + + if (pendingSettingsComponent && Categories.selected === 'Settings' && Categories.currentPage === 'categories' && Categories.transitionDirection === 0) { + const targetScroll = getDirectComponentScrollY('Settings', pendingSettingsComponent); + setTargetRightPanelScrollY(targetScroll); + autoScrollRightActive = true; + pendingHighlightComponent = pendingSettingsComponent; + pendingSettingsComponent = null; + } + + if (pendingThemeComponent && Categories.selected === 'Theme' && Categories.currentPage === 'categories' && Categories.transitionDirection === 0) { + const targetScroll = getDirectComponentScrollY('Theme', pendingThemeComponent); + setTargetRightPanelScrollY(targetScroll); + autoScrollRightActive = true; + pendingHighlightComponent = pendingThemeComponent; + pendingThemeComponent = null; + } + + if ( + pendingModuleComponent && + Categories.currentPage === 'options' && + Categories.selectedItem === pendingModuleComponent.item && + Categories.transitionDirection === 0 + ) { + const targetScroll = getModuleComponentScrollY(pendingModuleComponent.item, pendingModuleComponent.component); + setTargetOptionsScrollY(targetScroll); + autoScrollOptionsActive = true; + pendingHighlightComponent = pendingModuleComponent.component; + pendingModuleComponent = null; + } + + const rawQuery = SearchBar.query.trim(); + const query = rawQuery.toLowerCase(); + if (query !== lastQuery) { + isContentHeightCacheValid = false; + isLayoutCacheValid = false; + if (query && Categories.selected !== 'Modules') beginCategorySwap('Modules'); + lastQuery = query; + } - const cacheInvalidated = updateCategoryTransitions(); - if (cacheInvalidated) { - isLayoutCacheValid = false; - isContentHeightCacheValid = false; - } + const cacheInvalidated = updateCategoryTransitions(); + if (cacheInvalidated) { + isLayoutCacheValid = false; + isContentHeightCacheValid = false; + } - let activeComponentAnimation = false; + let activeComponentAnimation = false; - const checkComponentsForAnim = (components) => { - if (!components) return false; - return components.some((c) => (c instanceof MultiToggle || c instanceof ColorPicker) && c.animStart !== 0); - }; + const checkComponentsForAnim = (components) => { + if (!components) return false; + return components.some((c) => (c instanceof MultiToggle || c instanceof ColorPicker) && c.animStart !== 0); + }; - if (Categories.currentPage === 'categories') { - const directCat = Categories.categories.find((c) => c.name === Categories.selected); - if (directCat?.directComponents && checkComponentsForAnim(directCat.directComponents)) activeComponentAnimation = true; - } else if (Categories.currentPage === 'options' && Categories.selectedItem) { - if (checkComponentsForAnim(Categories.selectedItem.components)) activeComponentAnimation = true; - } + if (Categories.currentPage === 'categories') { + const directCat = Categories.categories.find((c) => c.name === Categories.selected); + if (directCat?.directComponents && checkComponentsForAnim(directCat.directComponents)) activeComponentAnimation = true; + } else if (Categories.currentPage === 'options' && Categories.selectedItem) { + if (checkComponentsForAnim(Categories.selectedItem.components)) activeComponentAnimation = true; + } - if (activeComponentAnimation) { - isContentHeightCacheValid = false; - isLayoutCacheValid = false; - } + if (activeComponentAnimation) { + isContentHeightCacheValid = false; + isLayoutCacheValid = false; + } - const transitionActive = Categories.transitionDirection !== 0; - const shouldDrawItems = Categories.currentPage === 'categories' || transitionActive; - const shouldDrawOptions = Categories.currentPage === 'options' || transitionActive; + const transitionActive = Categories.transitionDirection !== 0; + const shouldDrawItems = Categories.currentPage === 'categories' || transitionActive; + const shouldDrawOptions = Categories.currentPage === 'options' || transitionActive; - calculateContentHeight(); + calculateContentHeight(); - const contentViewportHeight = deps.rectangles.RightPanel.height; - const maxScroll = Math.max(0, cachedContentHeight - contentViewportHeight + PADDING); + const contentViewportHeight = GuiRectangles.RightPanel.height; + const maxScroll = Math.max(0, cachedContentHeight - contentViewportHeight + PADDING); - targetRightPanelScrollY = Math.max(0, Math.min(targetRightPanelScrollY, maxScroll)); + targetRightPanelScrollY = Math.max(0, Math.min(targetRightPanelScrollY, maxScroll)); - const prevScrollY = currentRightPanelScrollY; - const rightScrollFactor = 1 - Math.pow(1 - (autoScrollRightActive ? AUTO_SCROLL_SMOOTHING_FACTOR : SCROLL_SMOOTHING_FACTOR), elapsedFrames); - currentRightPanelScrollY += (targetRightPanelScrollY - currentRightPanelScrollY) * rightScrollFactor; - if (autoScrollRightActive && Math.abs(targetRightPanelScrollY - currentRightPanelScrollY) < 0.5) { - autoScrollRightActive = false; + const prevScrollY = currentRightPanelScrollY; + const rightScrollFactor = 1 - Math.pow(1 - (autoScrollRightActive ? AUTO_SCROLL_SMOOTHING_FACTOR : SCROLL_SMOOTHING_FACTOR), elapsedFrames); + currentRightPanelScrollY += (targetRightPanelScrollY - currentRightPanelScrollY) * rightScrollFactor; + if (autoScrollRightActive && Math.abs(targetRightPanelScrollY - currentRightPanelScrollY) < 0.5) { + autoScrollRightActive = false; + if (pendingHighlightComponent && typeof pendingHighlightComponent.startHighlight === 'function') { + pendingHighlightComponent.startHighlight(); + pendingHighlightComponent = null; + } + } + + if (Math.abs(currentRightPanelScrollY - prevScrollY) > 0.1) isLayoutCacheValid = false; + + if (shouldDrawOptions) { + const optionsContentHeight = calculateOptionsContentHeight(); + const maxOptionsScroll = Math.max(0, optionsContentHeight - GuiRectangles.RightPanel.height); + targetOptionsScrollY = Math.max(0, Math.min(targetOptionsScrollY, maxOptionsScroll)); + const optionsScrollFactor = 1 - Math.pow(1 - (autoScrollOptionsActive ? AUTO_SCROLL_SMOOTHING_FACTOR : SCROLL_SMOOTHING_FACTOR), elapsedFrames); + currentOptionsScrollY += (targetOptionsScrollY - currentOptionsScrollY) * optionsScrollFactor; + if (autoScrollOptionsActive && Math.abs(targetOptionsScrollY - currentOptionsScrollY) < 0.5) { + autoScrollOptionsActive = false; if (pendingHighlightComponent && typeof pendingHighlightComponent.startHighlight === 'function') { pendingHighlightComponent.startHighlight(); pendingHighlightComponent = null; } } - - if (Math.abs(currentRightPanelScrollY - prevScrollY) > 0.1) isLayoutCacheValid = false; - - if (shouldDrawOptions) { - const optionsContentHeight = calculateOptionsContentHeight(); - const maxOptionsScroll = Math.max(0, optionsContentHeight - deps.rectangles.RightPanel.height); - targetOptionsScrollY = Math.max(0, Math.min(targetOptionsScrollY, maxOptionsScroll)); - const optionsScrollFactor = 1 - Math.pow(1 - (autoScrollOptionsActive ? AUTO_SCROLL_SMOOTHING_FACTOR : SCROLL_SMOOTHING_FACTOR), elapsedFrames); - currentOptionsScrollY += (targetOptionsScrollY - currentOptionsScrollY) * optionsScrollFactor; - if (autoScrollOptionsActive && Math.abs(targetOptionsScrollY - currentOptionsScrollY) < 0.5) { - autoScrollOptionsActive = false; - if (pendingHighlightComponent && typeof pendingHighlightComponent.startHighlight === 'function') { - pendingHighlightComponent.startHighlight(); - pendingHighlightComponent = null; - } + Categories.optionsScrollY = currentOptionsScrollY; + } + + const panel = GuiRectangles.RightPanel; + const isMouseInsidePanel = isInside(mouseX, mouseY, panel); + const contentMouseX = isMouseInsidePanel ? mouseX : NaN; + const contentMouseY = isMouseInsidePanel ? mouseY : NaN; + scissor(panel.x, panel.y - BORDER_WIDTH, panel.width, panel.height + BORDER_WIDTH); + + if (shouldDrawItems) { + if (!isLayoutCacheValid) cachedItemLayouts = []; + + const isCategorySwap = transitionActive && Categories.transitionType === 'category-swap'; + + const drawSingleCategory = (catName, currentPanelX, isNewCategory, contentPanel = panel) => { + const cat = Categories.categories.find((c) => c.name === catName); + if (!cat) return; + const contentY = getCategoryContentY(cat, contentPanel); + let yOffset = contentY - currentRightPanelScrollY; + if (cat.name === 'Dashboard') { + drawDashboard(contentPanel, currentPanelX, contentY, contentMouseX, contentMouseY, currentRightPanelScrollY); + return; } - Categories.optionsScrollY = currentOptionsScrollY; - } - - const panel = deps.rectangles.RightPanel; - const isMouseInsidePanel = isInside(mouseX, mouseY, panel); - const contentMouseX = isMouseInsidePanel ? mouseX : NaN; - const contentMouseY = isMouseInsidePanel ? mouseY : NaN; - scissor(panel.x, panel.y - BORDER_WIDTH, panel.width, panel.height + BORDER_WIDTH); - - if (shouldDrawItems) { - if (!isLayoutCacheValid) cachedItemLayouts = []; - - const isCategorySwap = transitionActive && Categories.transitionType === 'category-swap'; - - const drawSingleCategory = (catName, currentPanelX, isNewCategory, contentPanel = panel) => { - const cat = Categories.categories.find((c) => c.name === catName); - if (!cat) return; - const contentY = getCategoryContentY(cat, contentPanel); - let yOffset = contentY - currentRightPanelScrollY; - if (cat.name === 'Dashboard') { - drawDashboard(contentPanel, currentPanelX, contentY, contentMouseX, contentMouseY, currentRightPanelScrollY); - return; - } - if (cat.directComponents && cat.directComponents.length > 0) { - drawDirectComponents(contentPanel, currentPanelX, contentY, contentMouseX, contentMouseY, currentRightPanelScrollY, catName); - return; - } - const itemsToDisplay = getFilteredItems(cat, query); - if (catName === 'Modules' && query.length > 0) { - const moduleMatches = getModuleComponentMatches(cat, query); - const settingsMatches = getSettingsDirectMatches(query); - const themeMatches = getThemeDirectMatches(query); - if (moduleMatches.length > 0) itemsToDisplay.push(...moduleMatches); - if (settingsMatches.length > 0) itemsToDisplay.push(...settingsMatches); - if (themeMatches.length > 0) itemsToDisplay.push(...themeMatches); - } - drawCategoryItems( - cat, - contentPanel, - currentPanelX, - yOffset, - contentMouseX, - contentMouseY, - itemsToDisplay, - cachedItemLayouts, - isLayoutCacheValid || !isNewCategory, - rawQuery - ); - }; + if (cat.directComponents && cat.directComponents.length > 0) { + drawDirectComponents(contentPanel, currentPanelX, contentY, contentMouseX, contentMouseY, currentRightPanelScrollY, catName); + return; + } + const itemsToDisplay = getFilteredItems(cat, query); + if (catName === 'Modules' && query.length > 0) { + const moduleMatches = getModuleComponentMatches(cat, query); + const settingsMatches = getSettingsDirectMatches(query); + const themeMatches = getThemeDirectMatches(query); + if (moduleMatches.length > 0) itemsToDisplay.push(...moduleMatches); + if (settingsMatches.length > 0) itemsToDisplay.push(...settingsMatches); + if (themeMatches.length > 0) itemsToDisplay.push(...themeMatches); + } + drawCategoryItems( + cat, + contentPanel, + currentPanelX, + yOffset, + contentMouseX, + contentMouseY, + itemsToDisplay, + cachedItemLayouts, + isLayoutCacheValid || !isNewCategory, + rawQuery + ); + }; - if (isCategorySwap && Categories.previousSelected) { - const progress = Categories.transitionProgress; - const dir = Categories.transitionDirection; - - const incomingX = panel.x + (dir === 1 ? panel.width * (1 - progress) : -panel.width * (1 - progress)); - drawSingleCategory(Categories.selected, incomingX, true); - const outgoingX = panel.x + (dir === 1 ? -panel.width * progress : panel.width * progress); - drawSingleCategory(Categories.previousSelected, outgoingX, false); - } else { - let panelX = panel.x; - if (transitionActive && Categories.transitionType === 'page') { - if (Categories.transitionDirection === 1) panelX -= panel.width * Categories.transitionProgress; - else if (Categories.transitionDirection === -1) panelX -= panel.width * (1 - Categories.transitionProgress); - } + if (isCategorySwap && Categories.previousSelected) { + const progress = Categories.transitionProgress; + const dir = Categories.transitionDirection; - const transitionCategory = - transitionActive && Categories.transitionType === 'page' && Categories.optionsReturnCategory - ? Categories.optionsReturnCategory - : Categories.selected; - drawSingleCategory(transitionCategory, panelX, true); - if (!isLayoutCacheValid && !transitionActive) isLayoutCacheValid = true; + const incomingX = panel.x + (dir === 1 ? panel.width * (1 - progress) : -panel.width * (1 - progress)); + drawSingleCategory(Categories.selected, incomingX, true); + const outgoingX = panel.x + (dir === 1 ? -panel.width * progress : panel.width * progress); + drawSingleCategory(Categories.previousSelected, outgoingX, false); + } else { + let panelX = panel.x; + if (transitionActive && Categories.transitionType === 'page') { + if (Categories.transitionDirection === 1) panelX -= panel.width * Categories.transitionProgress; + else if (Categories.transitionDirection === -1) panelX -= panel.width * (1 - Categories.transitionProgress); } - } - const toggleModule = getSelectedToggleModule(); - if (toggleModule) { - macroToggleButton.setButtonText(toggleModule.enabled ? 'Disable' : 'Enable'); + const transitionCategory = + transitionActive && Categories.transitionType === 'page' && Categories.optionsReturnCategory + ? Categories.optionsReturnCategory + : Categories.selected; + drawSingleCategory(transitionCategory, panelX, true); + if (!isLayoutCacheValid && !transitionActive) isLayoutCacheValid = true; } + } - if (shouldDrawOptions) drawOptionsPanel(panel, contentMouseX, contentMouseY, toggleModule ? macroToggleButton : null); - resetScissor(); - }; + const toggleModule = getSelectedToggleModule(); + if (toggleModule) { + macroToggleButton.setButtonText(toggleModule.enabled ? 'Disable' : 'Enable'); + } - const handleClick = (mouseX, mouseY) => { - const finishedTextInput = TextInput.handleGlobalClick(mouseX, mouseY); - const finishedSlider = Slider.handleGlobalClick(mouseX, mouseY); - if (finishedTextInput || finishedSlider) return; + if (shouldDrawOptions) drawOptionsPanel(panel, contentMouseX, contentMouseY, toggleModule ? macroToggleButton : null); + resetScissor(); +}; - const panel = deps.rectangles.RightPanel; - const components = Categories.currentPage === 'categories' ? getVisibleDirectComponents(Categories.selected) : Categories.selectedItem?.components; - const openPopup = components?.find((component) => component instanceof Popup && component.isOpen); - if (openPopup && typeof openPopup.handleOverlayClick === 'function' && openPopup.handleOverlayClick(mouseX, mouseY)) { +const handleClick = (mouseX, mouseY) => { + const finishedTextInput = TextInput.handleGlobalClick(mouseX, mouseY); + const finishedSlider = Slider.handleGlobalClick(mouseX, mouseY); + if (finishedTextInput || finishedSlider) return; + + const panel = GuiRectangles.RightPanel; + const components = Categories.currentPage === 'categories' ? getVisibleDirectComponents(Categories.selected) : Categories.selectedItem?.components; + const openPopup = components?.find((component) => component instanceof Popup && component.isOpen); + if (openPopup && typeof openPopup.handleOverlayClick === 'function' && openPopup.handleOverlayClick(mouseX, mouseY)) { + return; + } + + const shouldHandleSearch = Categories.currentPage === 'categories' && Categories.transitionDirection === 0; + const searchY = GuiRectangles.LeftPanel.y + PADDING; + if (shouldHandleSearch && SearchBar.handleClick(mouseX, mouseY, GuiRectangles.ModuleSearch, searchY)) { + isLayoutCacheValid = false; + isContentHeightCacheValid = false; + resetCategoryScroll(); + return; + } + + const toggleModule = getSelectedToggleModule(); + if (toggleModule && macroToggleButton.handleClick(mouseX, mouseY)) { + return; + } + + if ( + Categories.selected === 'Dashboard' && + Categories.currentPage === 'categories' && + Categories.transitionDirection === 0 && + isInside(mouseX, mouseY, panel) + ) { + const moduleName = getDashboardModuleAt(mouseX, mouseY); + const moduleItem = moduleName ? Categories.findItem('Modules', moduleName) : null; + if (moduleItem) { + Categories.previousSelected = Categories.selected; + const oldRect = getCategorySelectionRect(Categories.previousSelected); + const newRect = getCategorySelectionRect('Modules'); + if (oldRect && newRect) { + Categories.catAnimationRect = { + startX: oldRect.x, + startY: oldRect.y, + endX: newRect.x, + endY: newRect.y, + width: oldRect.width, + height: oldRect.height, + startRadius: oldRect.radius || 8, + endRadius: newRect.radius || 8, + radius: oldRect.radius || 8, + }; + Categories.catTransitionStart = Date.now(); + } + Categories.selected = 'Modules'; + Categories.currentPage = 'categories'; + Categories.selectedSubcategory = null; + beginModuleOptionsSwap(moduleItem, 'Dashboard'); return; } - - const shouldHandleSearch = Categories.currentPage === 'categories' && Categories.transitionDirection === 0; - const searchY = GuiRectangles.LeftPanel.y + PADDING; - if (shouldHandleSearch && SearchBar.handleClick(mouseX, mouseY, GuiRectangles.ModuleSearch, searchY)) { - isLayoutCacheValid = false; - isContentHeightCacheValid = false; - resetCategoryScroll(); + } + + const canUseCachedLayouts = Categories.currentPage === 'categories' && Categories.transitionDirection === 0 && isInside(mouseX, mouseY, panel); + if (canUseCachedLayouts) { + const directMatch = cachedItemLayouts.find((layout) => layout?.item?.type === 'direct-component' && isInside(mouseX, mouseY, layout.rect)); + if (directMatch) { + pendingSettingsComponent = directMatch.item.component; + beginCategorySwap('Settings'); return; } - const toggleModule = getSelectedToggleModule(); - if (toggleModule && macroToggleButton.handleClick(mouseX, mouseY)) { + const themeMatch = cachedItemLayouts.find((layout) => layout?.item?.type === 'theme-component' && isInside(mouseX, mouseY, layout.rect)); + if (themeMatch) { + pendingThemeComponent = themeMatch.item.component; + beginCategorySwap('Theme'); return; } - if ( - Categories.selected === 'Dashboard' && - Categories.currentPage === 'categories' && - Categories.transitionDirection === 0 && - isInside(mouseX, mouseY, panel) - ) { - const moduleName = getDashboardModuleAt(mouseX, mouseY); - const moduleItem = moduleName ? Categories.findItem('Modules', moduleName) : null; - if (moduleItem) { - Categories.previousSelected = Categories.selected; - const oldRect = getCategorySelectionRect(Categories.previousSelected); - const newRect = getCategorySelectionRect('Modules'); - if (oldRect && newRect) { - Categories.catAnimationRect = { - startX: oldRect.x, - startY: oldRect.y, - endX: newRect.x, - endY: newRect.y, - width: oldRect.width, - height: oldRect.height, - startRadius: oldRect.radius || 8, - endRadius: newRect.radius || 8, - radius: oldRect.radius || 8, - }; - Categories.catTransitionStart = Date.now(); - } - Categories.selected = 'Modules'; - Categories.currentPage = 'categories'; - Categories.selectedSubcategory = null; - beginModuleOptionsSwap(moduleItem, 'Dashboard'); - return; - } + const moduleMatch = cachedItemLayouts.find((layout) => layout?.item?.type === 'module-component' && isInside(mouseX, mouseY, layout.rect)); + if (moduleMatch) { + pendingModuleComponent = { item: moduleMatch.item.parentItem, component: moduleMatch.item.component }; + beginModuleOptionsSwap(moduleMatch.item.parentItem); + return; } + } + + handleCategoryClick( + mouseX, + mouseY, + panel, + currentRightPanelScrollY, + cachedItemLayouts, + getCategoryRect, + () => { + isLayoutCacheValid = false; + resetCategoryScroll(); + }, + () => { + isContentHeightCacheValid = false; + resetCategoryScroll(); + }, + resetCategoryScroll + ); +}; - const canUseCachedLayouts = Categories.currentPage === 'categories' && Categories.transitionDirection === 0 && isInside(mouseX, mouseY, panel); - if (canUseCachedLayouts) { - const directMatch = cachedItemLayouts.find((layout) => layout?.item?.type === 'direct-component' && isInside(mouseX, mouseY, layout.rect)); - if (directMatch) { - pendingSettingsComponent = directMatch.item.component; - beginCategorySwap('Settings'); - return; - } - - const themeMatch = cachedItemLayouts.find((layout) => layout?.item?.type === 'theme-component' && isInside(mouseX, mouseY, layout.rect)); - if (themeMatch) { - pendingThemeComponent = themeMatch.item.component; - beginCategorySwap('Theme'); - return; - } +const handleScroll = (mouseX, mouseY, dir) => { + autoScrollRightActive = false; + autoScrollOptionsActive = false; + handleCategoryScroll( + mouseX, + mouseY, + dir, + GuiRectangles.RightPanel, + cachedContentHeight, + currentRightPanelScrollY, + setTargetRightPanelScrollY, + currentOptionsScrollY, + setTargetOptionsScrollY, + calculateOptionsContentHeight() + ); + isLayoutCacheValid = false; +}; - const moduleMatch = cachedItemLayouts.find((layout) => layout?.item?.type === 'module-component' && isInside(mouseX, mouseY, layout.rect)); - if (moduleMatch) { - pendingModuleComponent = { item: moduleMatch.item.parentItem, component: moduleMatch.item.component }; - beginModuleOptionsSwap(moduleMatch.item.parentItem); - return; - } +const handleMouseDrag = (mouseX, mouseY) => { + isLayoutCacheValid = false; + const components = Categories.currentPage === 'categories' ? getVisibleDirectComponents(Categories.selected) : Categories.selectedItem?.components; + components?.forEach((c) => { + if (typeof c.handleMouseDrag === 'function') { + c.handleMouseDrag(mouseX, mouseY); } + }); +}; - handleCategoryClick( - mouseX, - mouseY, - panel, - currentRightPanelScrollY, - cachedItemLayouts, - getCategoryRect, - () => { - isLayoutCacheValid = false; - resetCategoryScroll(); - }, - () => { - isContentHeightCacheValid = false; - resetCategoryScroll(); - }, - resetCategoryScroll - ); - }; - - const handleScroll = (mouseX, mouseY, dir) => { - autoScrollRightActive = false; - autoScrollOptionsActive = false; - handleCategoryScroll( - mouseX, - mouseY, - dir, - deps.rectangles.RightPanel, - cachedContentHeight, - currentRightPanelScrollY, - setTargetRightPanelScrollY, - currentOptionsScrollY, - setTargetOptionsScrollY, - calculateOptionsContentHeight() - ); - isLayoutCacheValid = false; - }; +const handleMouseRelease = () => { + const components = Categories.currentPage === 'categories' ? getVisibleDirectComponents(Categories.selected) : Categories.selectedItem?.components; + components?.forEach((c) => { + if (typeof c.handleMouseRelease === 'function') c.handleMouseRelease(); + }); +}; - const handleMouseDrag = (mouseX, mouseY) => { +export const categoryManager = { + draw, + drawPopups, + handleClick, + handleScroll, + handleMouseDrag, + handleMouseRelease, + invalidateLayoutCache: () => { isLayoutCacheValid = false; - const components = Categories.currentPage === 'categories' ? getVisibleDirectComponents(Categories.selected) : Categories.selectedItem?.components; - components?.forEach((c) => { - if (typeof c.handleMouseDrag === 'function') { - c.handleMouseDrag(mouseX, mouseY); - } - }); - }; - - const handleMouseRelease = () => { - const components = Categories.currentPage === 'categories' ? getVisibleDirectComponents(Categories.selected) : Categories.selectedItem?.components; - components?.forEach((c) => { - if (typeof c.handleMouseRelease === 'function') c.handleMouseRelease(); - }); - }; - - return { - draw, - drawPopups, - handleClick, - handleScroll, - handleMouseDrag, - handleMouseRelease, - invalidateLayoutCache: () => { - isLayoutCacheValid = false; - }, - invalidateContentHeightCache: () => { - isContentHeightCacheValid = false; - }, - resetScroll: resetCategoryScroll, - getRightPanelScrollY: () => currentRightPanelScrollY, - setRightPanelScrollY: (v) => setRightPanelScrollY(v), - }; + }, + invalidateContentHeightCache: () => { + isContentHeightCacheValid = false; + }, + resetScroll: resetCategoryScroll, + getRightPanelScrollY: () => currentRightPanelScrollY, + setRightPanelScrollY: (v) => setRightPanelScrollY(v), }; - -export const categoryManager = createCategoriesManager({ - rectangles: GuiRectangles, -}); diff --git a/gui/categories/CategoryRenderer.js b/gui/categories/CategoryRenderer.js index 2cb95fb2..a2604f84 100644 --- a/gui/categories/CategoryRenderer.js +++ b/gui/categories/CategoryRenderer.js @@ -4,7 +4,6 @@ import { FontSizes, ITEM_SPACING, PADDING, - SUBCATEGORY_BUTTON_HEIGHT, SUBCATEGORY_BUTTON_SPACING, THEME, colorWithAlpha, diff --git a/gui/categories/CategorySearchBar.js b/gui/categories/CategorySearchBar.js index b9cb6836..7aec8529 100644 --- a/gui/categories/CategorySearchBar.js +++ b/gui/categories/CategorySearchBar.js @@ -255,7 +255,7 @@ export const SearchBar = { } } } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } return true; } diff --git a/gui/components/TextInput.js b/gui/components/TextInput.js index 27e5f5b5..93aaec2b 100644 --- a/gui/components/TextInput.js +++ b/gui/components/TextInput.js @@ -232,7 +232,7 @@ export class TextInput { } } } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } return true; } diff --git a/gui/components/layout.js b/gui/components/layout.js index c1b8387d..0eb1b081 100644 --- a/gui/components/layout.js +++ b/gui/components/layout.js @@ -4,16 +4,16 @@ import { MultiToggle } from './Dropdown'; import { Separator } from './Separator'; import { PADDING } from '../Utils'; -export const SEPARATOR_HEIGHT = 16; -export const COMPONENT_HEIGHT = 26; -export const BUTTON_ONLY_HEIGHT = 24; -export const DIRECT_SECTION_GAP = 8; -export const DIRECT_SECTION_HEADER_HEIGHT = 26; -export const DIRECT_SECTION_PADDING = 8; +const SEPARATOR_HEIGHT = 16; +const COMPONENT_HEIGHT = 26; +const BUTTON_ONLY_HEIGHT = 24; +const DIRECT_SECTION_GAP = 8; +const DIRECT_SECTION_HEADER_HEIGHT = 26; +const DIRECT_SECTION_PADDING = 8; export const isComponentVisible = (component) => component.visible !== false; -export const getComponentExpansionHeight = (component, useExpandedHeightWhenStatic = false) => { +const getComponentExpansionHeight = (component, useExpandedHeightWhenStatic = false) => { if (!(component instanceof MultiToggle || component instanceof ColorPicker) || typeof component.getExpandedHeight !== 'function') { return 0; } diff --git a/gui/core/GuiEvents.js b/gui/core/GuiEvents.js index 2aff7ffb..6318bf94 100644 --- a/gui/core/GuiEvents.js +++ b/gui/core/GuiEvents.js @@ -1,4 +1,4 @@ -import { Utils } from '../../utils/Utils'; +import { getConfigFile, writeConfigFile } from '../../utils/Utils'; import { v5Command } from '../../utils/V5Commands'; import { categoryManager } from '../categories/CategoryManager'; import { SearchBar } from '../categories/CategorySearchBar'; @@ -68,7 +68,7 @@ const handleGuiClosed = () => { saveSettings(); }; -export const openGui = () => { +const openGui = () => { GuiState.isOpening = true; GuiState.openStartTime = Date.now(); loadSettings(); @@ -98,7 +98,7 @@ NVG.registerV5Render(() => { const handleKeybind = () => { const keyName = 'GUI'; - const existingKeybinds = Utils.getConfigFile('keybinds.json') || {}; + const existingKeybinds = getConfigFile('keybinds.json') || {}; let savedKeycode = existingKeybinds[keyName]; if (savedKeycode === undefined || savedKeycode === 0 || savedKeycode === -1) savedKeycode = Keyboard.KEY_NONE; @@ -106,9 +106,9 @@ const handleKeybind = () => { const GUIKeyBind = new KeyBind(keyName, savedKeycode, 'v5_core'); register('gameUnload', () => { - const allKeybinds = Utils.getConfigFile('keybinds.json') || {}; + const allKeybinds = getConfigFile('keybinds.json') || {}; allKeybinds[keyName] = GUIKeyBind.getKeyCode(); - Utils.writeConfigFile('keybinds.json', allKeybinds); + writeConfigFile('keybinds.json', allKeybinds); }); GUIKeyBind.registerKeyPress(() => { diff --git a/gui/core/GuiRenderer.js b/gui/core/GuiRenderer.js index e5d67a88..817e8310 100644 --- a/gui/core/GuiRenderer.js +++ b/gui/core/GuiRenderer.js @@ -108,12 +108,12 @@ export const drawGUI = (mouseX, mouseY) => { NVG.restore(); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } finally { try { NVG.endFrame(); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } } }; diff --git a/loader.js b/loader.js index ab2a75dd..1f3ec3fb 100644 --- a/loader.js +++ b/loader.js @@ -17,14 +17,13 @@ register('packetSent', (packet, event) => { }).setFilteredClass(ServerboundCommandSuggestionPacket); /* Utils */ -import { MacroState } from './utils/MacroState'; +import { setupLastMacroToggleKey } from './utils/MacroState'; import './modules/other/MacroScheduler'; import './modules/other/MacroControllers'; import './modules/other/DiscordIntegration'; import './utils/pathfinder/PathFinder'; import './utils/pathfinder/EtherwarpPathfinder'; import './utils/Misc'; -import './utils/SkyblockItemUtil'; import './failsafes/FailsafeManager'; import './utils/SkyblockEvents'; @@ -34,7 +33,7 @@ import './utils/UserScripts'; import { loadSettings } from './gui/GuiSave'; registerV5Commands(); -MacroState.setupLastMacroToggleKey(); +setupLastMacroToggleKey(); loadSettings(); import './utils/DeveloperModeState'; diff --git a/modules/combat/CombatBot.js b/modules/combat/CombatBot.js index f97b9cad..4ee51103 100644 --- a/modules/combat/CombatBot.js +++ b/modules/combat/CombatBot.js @@ -1,10 +1,10 @@ import { ArmorStandEntity, Vec3d } from '../../utils/Constants'; -import { MathUtils } from '../../utils/Math'; +import { angleToPlayer, getDistance, getDistanceToPlayer } from '../../utils/Math'; import { ModuleBase } from '../../utils/ModuleBase'; import Pathfinder from '../../utils/pathfinder/PathFinder'; -import { Movement } from '../../utils/player/Movement'; +import { setKeysForStraightLineCoords } from '../../utils/player/Movement'; import { Rotations } from '../../utils/player/Rotations'; -import { Raytrace } from '../../utils/Raytrace'; +import { isLookingAtEntity } from '../../utils/Raytrace'; const BLACKHOLE_TEXTURES = new Set([ 'ewogICJ0aW1lc3RhbXAiIDogMTczNjE4NDg2Nzc3MywKICAicHJvZmlsZUlkIiA6ICJjNmViMzdjNmE4YjM0MDI3OGJjN2FmZGE3ZjMxOWJmMyIsCiAgInByb2ZpbGVOYW1lIiA6ICJFbFJleUNhbGFiYXphbCIsCiAgInNpZ25hdHVyZVJlcXVpcmVkIiA6IHRydWUsCiAgInRleHR1cmVzIiA6IHsKICAgICJTS0lOIiA6IHsKICAgICAgInVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS81NWI3MGYwOTRlMDE2Nzk1MDhkZDViY2EzOTY0MGVkOWVjNWM2YzY3OTJmYmQ4ZjU3YzAzYjNhMTJmOWMwYTkyIiwKICAgICAgIm1ldGFkYXRhIiA6IHsKICAgICAgICAibW9kZWwiIDogInNsaW0iCiAgICAgIH0KICAgIH0KICB9Cn0=', @@ -154,7 +154,7 @@ class Combat extends ModuleBase { try { this.scanBlackholes(); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } const now = Date.now(); @@ -227,7 +227,7 @@ class Combat extends ModuleBase { visibleBlackholes.push({ x: stand.getX(), y: stand.getY(), z: stand.getZ() }); } } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } } @@ -268,7 +268,7 @@ class Combat extends ModuleBase { if (profileString.includes(base64)) return true; } } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } return false; } @@ -306,7 +306,7 @@ class Combat extends ModuleBase { try { visible = playerMP.canSeeEntity(entity); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); return true; } @@ -350,7 +350,7 @@ class Combat extends ModuleBase { const rad = (yaw * Math.PI) / 180; return { x: -Math.sin(rad), z: Math.cos(rad) }; } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); return { x: 0, z: 1 }; } } @@ -458,9 +458,9 @@ class Combat extends ModuleBase { isAimingAtTarget() { if (!this.target) return false; try { - return Raytrace.isLookingAtEntity(this.target, this.attackRange + 0.5); + return isLookingAtEntity(this.target, this.attackRange + 0.5); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); return false; } } @@ -553,7 +553,7 @@ class Combat extends ModuleBase { return; } - Movement.setKeysForStraightLineCoords(pos.x, pos.y, pos.z, true, true); + setKeysForStraightLineCoords(pos.x, pos.y, pos.z, true, true); Client.setKey('sprint', true); this.startRotationToTarget(); } @@ -572,7 +572,7 @@ class Combat extends ModuleBase { if (distanceData) this.tryAttack(); this.startRotationToTarget(); - Movement.setKeysForStraightLineCoords(pos.x, pos.y, pos.z, true, true); + setKeysForStraightLineCoords(pos.x, pos.y, pos.z, true, true); if (distanceData.distanceFlat <= 2) Client.stopMovement(); if (distanceData.distanceY < -3) { Client.setKey('space', true); @@ -645,7 +645,7 @@ class Combat extends ModuleBase { if (mcTarget?.getUUID) return mcTarget.getUUID().toString(); return null; } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); return null; } } @@ -703,17 +703,17 @@ class Combat extends ModuleBase { return !this.targets.some((t) => this.getTargetUuid(t) === targetUUID); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); return true; } } getDistanceToPlayer(pos) { - return MathUtils.getDistanceToPlayer(pos.x, pos.y, pos.z); + return getDistanceToPlayer(pos.x, pos.y, pos.z); } getDistanceBetween(pos1, pos2) { - return MathUtils.getDistance(pos1.x, pos1.y, pos1.z, pos2.x, pos2.y, pos2.z); + return getDistance(pos1.x, pos1.y, pos1.z, pos2.x, pos2.y, pos2.z); } getTargets() { @@ -739,7 +739,7 @@ class Combat extends ModuleBase { const entity = target.toMC ? target.toMC() : target; if (entity && typeof entity.getX === 'function') return { x: entity.getX(), y: entity.getY(), z: entity.getZ() }; } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } return null; @@ -763,7 +763,7 @@ class Combat extends ModuleBase { if (!this.isPositionSafe(pos.x, pos.y, pos.z)) return; const distanceData = this.getDistanceToPlayer(pos); - const angles = MathUtils.angleToPlayer([pos.x, pos.y, pos.z]); + const angles = angleToPlayer([pos.x, pos.y, pos.z]); const cost = distanceData.distance * 10 + angles.distance * 0.5; if (cost < lowestCost) { @@ -806,7 +806,7 @@ class Combat extends ModuleBase { mobs.push(entity); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } }); diff --git a/modules/farming/FarmingMacro.js b/modules/farming/FarmingMacro.js index 1cc0d477..3a0c31f4 100644 --- a/modules/farming/FarmingMacro.js +++ b/modules/farming/FarmingMacro.js @@ -2,17 +2,17 @@ import { ModuleBase } from '../../utils/ModuleBase'; import { Mousemat } from '../../utils/player/Mousemat'; import { Rotations } from '../../utils/player/Rotations'; import { ScheduleTask } from '../../utils/ScheduleTask'; -import { TabListUtils } from '../../utils/TabListUtils'; -import { Mouse } from '../../utils/Ungrab'; -import { Utils } from '../../utils/Utils'; -import { Guis } from '../../utils/player/Inventory'; +import { getPestCooldown, getTabListNames, stripTabFormatting } from '../../utils/TabListUtils'; +import { regrab, ungrab } from '../../utils/Ungrab'; +import { getConfigFile, getGardenPestStatus, randomInt, writeConfigFile } from '../../utils/Utils'; +import { findItemInHotbar, setItemSlot } from '../../utils/player/Inventory'; import { farmingSettings } from './FarmingSettings'; import { farmingDelays } from './FarmingDelays'; import { rewarpHandler } from './rewarp/RewarpHandler'; import { rewarpSettings } from './rewarp/RewarpSettings'; import { getNearbyPest } from '../visuals/PestESP'; import { loadoutHandler } from './LoadoutHandler'; -import { manager } from '../../utils/SkyblockEvents'; +import { registerSkyblockEvent } from '../../utils/SkyblockEvents'; const MAX_PEST_TRACK_DISTANCE = 14; const PEST_STALL_GRACE_TICKS = 20; @@ -30,7 +30,7 @@ export class FarmingMacro extends ModuleBase { super({ subcategory: 'Farming', isMacro: true, ...options, autoDisableOnWorldUnload: true }); this.pointsPath = `FarmingMacro/${commandPrefix.replaceAll(' ', '_')}_points.json`; - this.points = Utils.getConfigFile(this.pointsPath) || {}; + this.points = getConfigFile(this.pointsPath) || {}; this.bindToggleKey(); const rewarpStart = this.addButton('Set Rewarp Start', () => this.saveRewarpPoint('start'), 'Stand at the position reached by the rewarp command.'); @@ -44,13 +44,13 @@ export class FarmingMacro extends ModuleBase { ]); this.on('tick', () => this.handleTick()); - manager.subscribe('sprayonatorunavailable', () => { + registerSkyblockEvent('sprayonatorunavailable', () => { if (this.enabled && farmingSettings.useSprayonator) this.sprayonatorUnavailable = true; }); } onEnable() { - if ((farmingSettings.killNearbyPests || rewarpSettings.pestKiller) && Guis.findItemInHotbar('Vacuum') < 0) { + if ((farmingSettings.killNearbyPests || rewarpSettings.pestKiller) && findItemInHotbar('Vacuum') < 0) { this.message('&cNo Vacuum found in hotbar.'); this.toggle(false); return; @@ -73,15 +73,13 @@ export class FarmingMacro extends ModuleBase { this.sprayonatorAction = null; this.mode = FARMING; this.stallGraceTicks = 0; - Mouse.ungrab(); + ungrab(); this.startDelayTicks = 1; const player = Player.getPlayer(); if (!player) return; this.farmingSlot = Player.getHeldItemIndex(); - loadoutHandler.select( - TabListUtils.getPestCooldown() <= loadoutHandler.pestSpawnSwapCooldown ? loadoutHandler.pestSpawningSlot : loadoutHandler.farmingSlot - ); + loadoutHandler.select(getPestCooldown() <= loadoutHandler.pestSpawnSwapCooldown ? loadoutHandler.pestSpawningSlot : loadoutHandler.farmingSlot); this.startFarming(player); } @@ -90,13 +88,13 @@ export class FarmingMacro extends ModuleBase { Mousemat.stop(); Rotations.stop(); Client.unpressKeys(); - Mouse.regrab(); + regrab(); this.mode = FARMING; this.pestTarget = null; this.pestRotation = null; this.pestFarmState = null; this.stallGraceTicks = 0; - if (this.sprayonatorAction) Guis.setItemSlot(this.sprayonatorOriginalSlot); + if (this.sprayonatorAction) setItemSlot(this.sprayonatorOriginalSlot); this.sprayonatorAction = null; farmingSettings.restoreSlot(); } @@ -135,7 +133,7 @@ export class FarmingMacro extends ModuleBase { if (farmingSettings.killNearbyPests && !rewarpSettings.pestKiller && this.handlePest(player)) return; const looping = rewarpSettings.looping; - if (rewarpSettings.pestKiller && Utils.getGardenPestStatus().gardenPests >= rewarpSettings.pestThreshold) { + if (rewarpSettings.pestKiller && getGardenPestStatus().gardenPests >= rewarpSettings.pestThreshold) { const pestColumnClear = this.isPestColumnClear(player); if (looping || pestColumnClear) { const returnPoint = { x: player.getX(), y: player.getY(), z: player.getZ() }; @@ -144,14 +142,14 @@ export class FarmingMacro extends ModuleBase { } } if (!looping && this.isAtPoint(player, this.points.end)) { - return this.beginRewarp(this.points.start, rewarpSettings.pestKiller && Utils.getGardenPestStatus().gardenPests >= rewarpSettings.pestThreshold); + return this.beginRewarp(this.points.start, rewarpSettings.pestKiller && getGardenPestStatus().gardenPests >= rewarpSettings.pestThreshold); } if (looping && this.shouldRunBarnTasks()) { ChatLib.command('sethome'); return this.beginRewarp({ x: player.getX(), y: player.getY(), z: player.getZ() }); } - const slot = TabListUtils.getPestCooldown() <= loadoutHandler.pestSpawnSwapCooldown ? loadoutHandler.pestSpawningSlot : loadoutHandler.farmingSlot; + const slot = getPestCooldown() <= loadoutHandler.pestSpawnSwapCooldown ? loadoutHandler.pestSpawningSlot : loadoutHandler.farmingSlot; if (!loadoutHandler.select(slot)) return Client.unpressKeys(); if (this.trySprayonator()) return; @@ -175,20 +173,20 @@ export class FarmingMacro extends ModuleBase { return false; } - const slot = Guis.findItemInHotbar('Sprayonator'); + const slot = findItemInHotbar('Sprayonator'); if (slot < 0) return false; this.sprayonatorOriginalSlot = this.farmingSlot; const action = {}; this.sprayonatorAction = action; Client.unpressKeys(); - Guis.setItemSlot(slot); - ScheduleTask(Utils.randomInt(farmingDelays.sprayonatorActionDelayMin, farmingDelays.sprayonatorActionDelayMax), () => { + setItemSlot(slot); + ScheduleTask(randomInt(farmingDelays.sprayonatorActionDelayMin, farmingDelays.sprayonatorActionDelayMax), () => { if (this.sprayonatorAction !== action) return; Client.rightClick(); - ScheduleTask(Utils.randomInt(farmingDelays.sprayonatorActionDelayMin, farmingDelays.sprayonatorActionDelayMax), () => { + ScheduleTask(randomInt(farmingDelays.sprayonatorActionDelayMin, farmingDelays.sprayonatorActionDelayMax), () => { if (this.sprayonatorAction !== action) return; - Guis.setItemSlot(this.sprayonatorOriginalSlot); + setItemSlot(this.sprayonatorOriginalSlot); this.startDelayTicks = Math.max(this.startDelayTicks, SPRAY_RESTORE_DELAY_TICKS); this.nextSprayCheckAt = Date.now() + SPRAY_CHECK_COOLDOWN_MS; this.sprayonatorAction = null; @@ -198,7 +196,7 @@ export class FarmingMacro extends ModuleBase { } hasNoSpray() { - return TabListUtils.getNames().some((line) => /\bSpray:\s*None\b/.test(TabListUtils.stripFormatting(line?.getName?.() ?? line))); + return getTabListNames().some((line) => /\bSpray:\s*None\b/.test(stripTabFormatting(line?.getName?.() ?? line))); } beginRewarp(rewarpStartPoint = this.points.start, runPestKiller = false) { @@ -223,7 +221,7 @@ export class FarmingMacro extends ModuleBase { finishRewarp(player) { if (!loadoutHandler.select(loadoutHandler.farmingSlot)) return; if (Player.getHeldItemIndex() !== this.farmingSlot) { - Guis.setItemSlot(this.farmingSlot); + setItemSlot(this.farmingSlot); return; } this.mode = FARMING; @@ -283,7 +281,7 @@ export class FarmingMacro extends ModuleBase { const player = Player.getPlayer(); if (this.enabled && player) this.resumeFarming(player, farmState, rotation); }; - ScheduleTask(Utils.randomInt(farmingDelays.pestRestoreDelayMin, farmingDelays.pestRestoreDelayMax), () => { + ScheduleTask(randomInt(farmingDelays.pestRestoreDelayMin, farmingDelays.pestRestoreDelayMax), () => { if (!farmingSettings.useMousemat) { if (!this.rotateTo(rotation.yaw, rotation.pitch, resume)) resume(); return; @@ -352,7 +350,7 @@ export class FarmingMacro extends ModuleBase { if (!player) return; this.points[name] = { x: player.getX(), y: player.getY(), z: player.getZ() }; - Utils.writeConfigFile(this.pointsPath, this.points); + writeConfigFile(this.pointsPath, this.points); this.message(`&aRewarp ${name} saved.`); if (this.rewarpPointsOverlap()) this.message('Rewarp point currently overlap. The macro will not work.'); } @@ -376,7 +374,7 @@ export class FarmingMacro extends ModuleBase { } getLaneSwitchDelayTicks() { - return Math.round(Utils.randomInt(this.laneSwitchDelayMin, this.laneSwitchDelayMax) / 50); + return Math.round(randomInt(this.laneSwitchDelayMin, this.laneSwitchDelayMax) / 50); } addLaneSwitchDelaySettings() { diff --git a/modules/farming/FarmingSettings.js b/modules/farming/FarmingSettings.js index d3c3e0b9..58ceec9b 100644 --- a/modules/farming/FarmingSettings.js +++ b/modules/farming/FarmingSettings.js @@ -1,5 +1,5 @@ import { ModuleBase } from '../../utils/ModuleBase'; -import { Guis } from '../../utils/player/Inventory'; +import { findItemInHotbar, setItemSlot } from '../../utils/player/Inventory'; class FarmingSettings extends ModuleBase { constructor() { @@ -25,12 +25,12 @@ class FarmingSettings extends ModuleBase { } restoreSlot() { - if (this.originalSlot !== -1) Guis.setItemSlot(this.originalSlot); + if (this.originalSlot !== -1) setItemSlot(this.originalSlot); this.originalSlot = -1; } selectVacuum() { - const slot = Guis.findItemInHotbar('Vacuum'); + const slot = findItemInHotbar('Vacuum'); if (slot < 0) { if (!this.hasReportedMissingVacuum) this.message('&cNo Vacuum found in hotbar.'); this.hasReportedMissingVacuum = true; @@ -38,7 +38,7 @@ class FarmingSettings extends ModuleBase { } this.hasReportedMissingVacuum = false; if (Player.getHeldItemIndex() === slot) return true; - Guis.setItemSlot(slot); + setItemSlot(slot); return false; } } diff --git a/modules/farming/LoadoutHandler.js b/modules/farming/LoadoutHandler.js index 948686e6..1f2749ff 100644 --- a/modules/farming/LoadoutHandler.js +++ b/modules/farming/LoadoutHandler.js @@ -1,5 +1,5 @@ import { ModuleBase } from '../../utils/ModuleBase'; -import { Guis } from '../../utils/player/Inventory'; +import { clickSlot, closeInventory, getGuiName } from '../../utils/player/Inventory'; import { ScheduleTask } from '../../utils/ScheduleTask'; const LOADOUT_SLOTS = [14, 15, 16, 23, 24, 25, 32, 33, 34, 41, 42, 43]; @@ -44,19 +44,19 @@ class LoadoutHandler extends ModuleBase { if (slot === this.currentSlot && this.targetSlot === null) return true; if (this.targetSlot !== slot) { this.targetSlot = slot; - if (!Guis.guiName()?.includes('(1/3) Loadouts')) ChatLib.command('loadouts'); + if (!getGuiName()?.includes('(1/3) Loadouts')) ChatLib.command('loadouts'); } return false; } tick() { - if (this.targetSlot === null || !Guis.guiName()?.includes('(1/3) Loadouts')) return; - if (!Guis.clickSlot(LOADOUT_SLOTS[this.targetSlot - 1])) return; + if (this.targetSlot === null || !getGuiName()?.includes('(1/3) Loadouts')) return; + if (!clickSlot(LOADOUT_SLOTS[this.targetSlot - 1])) return; this.currentSlot = this.targetSlot; this.targetSlot = null; this.switching = true; ScheduleTask(5, () => { - if (Guis.guiName()?.includes('(1/3) Loadouts')) Guis.closeInv(); + if (getGuiName()?.includes('(1/3) Loadouts')) closeInventory(); ScheduleTask(4, () => (this.switching = false)); }); } diff --git a/modules/farming/SShapeCropMacro.js b/modules/farming/SShapeCropMacro.js index bbfd114d..ccdf7b37 100644 --- a/modules/farming/SShapeCropMacro.js +++ b/modules/farming/SShapeCropMacro.js @@ -1,6 +1,6 @@ import { FarmingMacro } from './FarmingMacro'; import { farmingSettings } from './FarmingSettings'; -import { Utils } from '../../utils/Utils'; +import { randomFloat } from '../../utils/Utils'; const STATES = { LEFT: 'Left', @@ -51,7 +51,7 @@ class SShapeCropMacro extends FarmingMacro { this.state = this.lastDirection; this.ignoreTicks = 10; this.yaw = this.snapYaw(player.getYRot(), 0); - const pitch = farmingSettings.useMousemat ? (this.pitchMin + this.pitchMax) / 2 : Utils.randomFloat(this.pitchMin, this.pitchMax); + const pitch = farmingSettings.useMousemat ? (this.pitchMin + this.pitchMax) / 2 : randomFloat(this.pitchMin, this.pitchMax); this.rotateTo(this.yaw, pitch); } diff --git a/modules/farming/WSRowMacros.js b/modules/farming/WSRowMacros.js index b3335f5e..5b7e393d 100644 --- a/modules/farming/WSRowMacros.js +++ b/modules/farming/WSRowMacros.js @@ -1,6 +1,6 @@ import { FarmingMacro } from './FarmingMacro'; import { farmingSettings } from './FarmingSettings'; -import { Utils } from '../../utils/Utils'; +import { randomFloat } from '../../utils/Utils'; const LANE_DELAY = 'lane'; const WS_MOVEMENTS = [ @@ -60,8 +60,8 @@ class CycleMacro extends FarmingMacro { onFarmStart(player) { this.laneChanging = false; this.ignoreTicks = this.initialDelay; - this.yaw = farmingSettings.useMousemat ? (this.yawMin + this.yawMax) / 2 : Utils.randomFloat(this.yawMin, this.yawMax); - const pitch = farmingSettings.useMousemat ? (this.pitchMin + this.pitchMax) / 2 : Utils.randomFloat(this.pitchMin, this.pitchMax); + this.yaw = farmingSettings.useMousemat ? (this.yawMin + this.yawMax) / 2 : randomFloat(this.yawMin, this.yawMax); + const pitch = farmingSettings.useMousemat ? (this.pitchMin + this.pitchMax) / 2 : randomFloat(this.pitchMin, this.pitchMax); this.rotateTo(this.snapYaw(player.getYRot(), this.yaw), pitch); } diff --git a/modules/farming/rewarp/AutoSell.js b/modules/farming/rewarp/AutoSell.js index e375878d..c7c30938 100644 --- a/modules/farming/rewarp/AutoSell.js +++ b/modules/farming/rewarp/AutoSell.js @@ -1,5 +1,5 @@ -import { Guis } from '../../../utils/player/Inventory'; -import { Utils } from '../../../utils/Utils'; +import { clickItem, clickSlot, closeInventory, getGuiName } from '../../../utils/player/Inventory'; +import { randomInt } from '../../../utils/Utils'; import { farmingDelays } from '../FarmingDelays'; const TARGETS = [ @@ -42,7 +42,7 @@ class AutoSell { finish() { this.state = null; - Guis.closeInv(); + closeInventory(); return true; } @@ -53,7 +53,7 @@ class AutoSell { switch (this.state) { case 'trades': { - if (Guis.guiName() !== 'Trades') { + if (getGuiName() !== 'Trades') { ChatLib.command('trades'); this.nextActionAt = Date.now() + 1000; return; @@ -64,15 +64,15 @@ class AutoSell { for (let i = 54; i < items.length; i++) { const item = items[i]; if (item && TARGETS.some((name) => ChatLib.removeFormatting(String(item.getName())).includes(name))) { - Guis.clickSlot(i, false, 'LEFT'); - this.nextActionAt = Date.now() + Utils.randomInt(farmingDelays.visitorAutoSellDelayMin, farmingDelays.visitorAutoSellDelayMax) * 50; + clickSlot(i, false, 'LEFT'); + this.nextActionAt = Date.now() + randomInt(farmingDelays.visitorAutoSellDelayMin, farmingDelays.visitorAutoSellDelayMax) * 50; return; } } if (this.shouldRun()) { this.state = 'bazaar'; - Guis.closeInv(); + closeInventory(); this.nextActionAt = Date.now() + 1000; return; } @@ -81,7 +81,7 @@ class AutoSell { } case 'bazaar': if ( - !String(Guis.guiName() || '') + !String(getGuiName() || '') .toLowerCase() .includes('bazaar') ) { @@ -90,12 +90,12 @@ class AutoSell { return; } - if (!Guis.clickItem('Sell Inventory Now')) return; + if (!clickItem('Sell Inventory Now')) return; this.state = 'selling whole inventory'; - this.nextActionAt = Date.now() + Utils.randomInt(farmingDelays.bazaarActionDelayMin, farmingDelays.bazaarActionDelayMax); + this.nextActionAt = Date.now() + randomInt(farmingDelays.bazaarActionDelayMin, farmingDelays.bazaarActionDelayMax); return; case 'selling whole inventory': - if (!Guis.clickItem('Selling whole inventory')) return; + if (!clickItem('Selling whole inventory')) return; this.state = 'closing inventory'; this.nextActionAt = Date.now() + 10 * 50; diff --git a/modules/farming/rewarp/PestKiller.js b/modules/farming/rewarp/PestKiller.js index ea45a3e7..9e43b8c5 100644 --- a/modules/farming/rewarp/PestKiller.js +++ b/modules/farming/rewarp/PestKiller.js @@ -1,12 +1,12 @@ import { ClientboundLevelParticlesPacket } from '../../../utils/Packets'; import Pathfinder from '../../../utils/pathfinder/PathFinder'; import { Rotations } from '../../../utils/player/Rotations'; -import { TabListUtils } from '../../../utils/TabListUtils'; +import { readPests } from '../../../utils/TabListUtils'; import { getLoadedPests } from '../../visuals/PestESP'; import { farmingSettings } from '../FarmingSettings'; -import { MathUtils } from '../../../utils/Math'; -import { Utils } from '../../../utils/Utils'; -import { manager } from '../../../utils/SkyblockEvents'; +import { angleToPlayer } from '../../../utils/Math'; +import { getGardenPestStatus } from '../../../utils/Utils'; +import { registerSkyblockEvent } from '../../../utils/SkyblockEvents'; const ANGRY_VILLAGER = net.minecraft.core.particles.ParticleTypes.ANGRY_VILLAGER; const PEST_RANGE_SQ = 12.5 ** 2; @@ -26,7 +26,7 @@ const STATES = { class PestKiller { constructor() { register('packetReceived', (packet) => this.onParticle(packet)).setFilteredClass(ClientboundLevelParticlesPacket); - manager.subscribe('plotteleport', () => this.onTeleport()); + registerSkyblockEvent('plotteleport', () => this.onTeleport()); } start() { @@ -41,7 +41,7 @@ class PestKiller { tick() { if (!this.running) return true; - const { gardenPests, currentPlot, currentPlotPests } = Utils.getGardenPestStatus(); + const { gardenPests, currentPlot, currentPlotPests } = getGardenPestStatus(); if (gardenPests === 0 || !gardenPests) { this.stop(); return true; @@ -105,7 +105,7 @@ class PestKiller { } findNewPlot() { - const { infestedPlots } = TabListUtils.readPests(); + const { infestedPlots } = readPests(); let plot = infestedPlots.find((candidate) => !this.visitedPlots.has(candidate)); if (!plot && infestedPlots.length) { this.visitedPlots.clear(); @@ -166,7 +166,7 @@ class PestKiller { this.state = STATES.KILLING; Client.unpressKeys(); if (!farmingSettings.selectVacuum()) return false; - if (MathUtils.angleToPlayer(pest).distance >= PEST_ANGLE) Rotations.lookAtVector(pest, { precision: 5 }); + if (angleToPlayer(pest).distance >= PEST_ANGLE) Rotations.lookAtVector(pest, { precision: 5 }); Client.setKey('rightclick', true); return false; } diff --git a/modules/farming/rewarp/PhilipMacro.js b/modules/farming/rewarp/PhilipMacro.js index 910ed5aa..2a30371b 100644 --- a/modules/farming/rewarp/PhilipMacro.js +++ b/modules/farming/rewarp/PhilipMacro.js @@ -1,8 +1,8 @@ import Pathfinder from '../../../utils/pathfinder/PathFinder'; -import { Guis } from '../../../utils/player/Inventory'; +import { clickItem, closeInventory } from '../../../utils/player/Inventory'; import { Rotations } from '../../../utils/player/Rotations'; import { ScheduleTask } from '../../../utils/ScheduleTask'; -import { Utils } from '../../../utils/Utils'; +import { randomInt } from '../../../utils/Utils'; import { farmingDelays } from '../FarmingDelays'; const STATES = { @@ -112,12 +112,12 @@ class PhilipMacro { } emptyVacuum() { - if (!Client.isInGui() || !Guis.clickItem('Empty Vacuum Bag', false, 'LEFT')) return this.retry(); + if (!Client.isInGui() || !clickItem('Empty Vacuum Bag', false, 'LEFT')) return this.retry(); this.nextActionAt = Infinity; ScheduleTask(1, () => { if (!this.running || this.state !== STATES.EMPTYING) return; - Guis.closeInv(); + closeInventory(); this.stop(); }); } @@ -129,7 +129,7 @@ class PhilipMacro { retry() { Client.stopMovement(); - this.transition(STATES.SEEKING, Utils.randomInt(farmingDelays.visitorRetryDelayMin, farmingDelays.visitorRetryDelayMax)); + this.transition(STATES.SEEKING, randomInt(farmingDelays.visitorRetryDelayMin, farmingDelays.visitorRetryDelayMax)); } stop() { diff --git a/modules/farming/rewarp/RewarpHandler.js b/modules/farming/rewarp/RewarpHandler.js index 985dc09f..e88a9087 100644 --- a/modules/farming/rewarp/RewarpHandler.js +++ b/modules/farming/rewarp/RewarpHandler.js @@ -2,12 +2,12 @@ import { autoSell } from './AutoSell'; import { philipMacro } from './PhilipMacro'; import { visitorMacro } from './VisitorMacro'; import { rewarpSettings } from './RewarpSettings'; -import { Utils } from '../../../utils/Utils'; +import { randomInt } from '../../../utils/Utils'; import Pathfinder from '../../../utils/pathfinder/PathFinder'; import { pestKiller } from './PestKiller'; import { loadoutHandler } from '../LoadoutHandler'; import { farmingDelays } from '../FarmingDelays'; -import { manager } from '../../../utils/SkyblockEvents'; +import { registerSkyblockEvent } from '../../../utils/SkyblockEvents'; const PHASES = { BARN: 'Warping to barn', @@ -24,7 +24,7 @@ const BARN_SETTLE_MS = 250; class RewarpHandler { constructor() { - manager.subscribe('barnteleport', () => { + registerSkyblockEvent('barnteleport', () => { if (this.phase !== PHASES.WAITING_FOR_BARN) return; this.phase = PHASES.LANDING_AT_BARN; this.nextActionAt = Date.now() + BARN_SETTLE_MS; @@ -47,7 +47,7 @@ class RewarpHandler { const hasBarnTasks = this.tasks.length > 0; if (runPestKiller) this.tasks.push(pestKiller, autoSell); this.phase = hasBarnTasks ? PHASES.BARN : this.tasks.length ? PHASES.DECIDING : PHASES.REWARP; - this.nextActionAt = runPestKiller && !hasBarnTasks ? 0 : Date.now() + Utils.randomInt(farmingDelays.rewarpDelayMin, farmingDelays.rewarpDelayMax); + this.nextActionAt = runPestKiller && !hasBarnTasks ? 0 : Date.now() + randomInt(farmingDelays.rewarpDelayMin, farmingDelays.rewarpDelayMax); } stop() { diff --git a/modules/farming/rewarp/RewarpSettings.js b/modules/farming/rewarp/RewarpSettings.js index 1f7a6b0a..9cde2ae7 100644 --- a/modules/farming/rewarp/RewarpSettings.js +++ b/modules/farming/rewarp/RewarpSettings.js @@ -1,6 +1,6 @@ import { ModuleBase } from '../../../utils/ModuleBase'; -import { Guis } from '../../../utils/player/Inventory'; -import { TabListUtils } from '../../../utils/TabListUtils'; +import { stripItemFormatting } from '../../../utils/player/Inventory'; +import { findTabListIndex, getTabListNames, readVisitors } from '../../../utils/TabListUtils'; class RewarpSettings extends ModuleBase { constructor() { @@ -97,16 +97,16 @@ class RewarpSettings extends ModuleBase { } shouldRunVisitorMacro() { - return this.runVisitorMacro && TabListUtils.readVisitors().length >= this.minimumVisitors; + return this.runVisitorMacro && readVisitors().length >= this.minimumVisitors; } shouldRunPhilipBonus() { - if (!this.autoPhilipBonus || TabListUtils.findIndex(TabListUtils.getNames(), 'Bonus: INACTIVE') === -1) return false; + if (!this.autoPhilipBonus || findTabListIndex(getTabListNames(), 'Bonus: INACTIVE') === -1) return false; const vacuum = Player.getInventory() ?.getItems?.() - .find((item) => String(Guis.stripFormatting(item?.getName?.() || '')).includes('Vacuum')); + .find((item) => String(stripItemFormatting(item?.getName?.() || '')).includes('Vacuum')); const vacuumLine = String(vacuum?.getLore?.().find((line) => String(line).includes('Vacuum Bag:')) || ''); - return (Number.parseInt(Guis.stripFormatting(vacuumLine).replace(/[^\d]/g, ''), 10) || 0) >= 40; + return (Number.parseInt(stripItemFormatting(vacuumLine).replace(/[^\d]/g, ''), 10) || 0) >= 40; } } diff --git a/modules/farming/rewarp/VisitorMacro.js b/modules/farming/rewarp/VisitorMacro.js index 6dab8b78..54cae015 100644 --- a/modules/farming/rewarp/VisitorMacro.js +++ b/modules/farming/rewarp/VisitorMacro.js @@ -1,5 +1,5 @@ import { bazaarUtil } from '../../../utils/BazaarUtil'; -import { Chat } from '../../../utils/Chat'; +import { chat } from '../../../utils/Chat'; import Pathfinder from '../../../utils/pathfinder/PathFinder'; import { Guis } from '../../../utils/player/Inventory'; import { Rotations } from '../../../utils/player/Rotations'; @@ -44,12 +44,12 @@ class VisitorMacro { this.running = true; this.visitors = TabListUtils.readVisitors(); if (!this.visitors.length) { - Chat.message('&eNo visitors found.'); + chat('&eNo visitors found.'); this.running = false; return false; } - Chat.message(`&aFound ${this.visitors.length} visitors.`); + chat(`&aFound ${this.visitors.length} visitors.`); this.visitorIndex = 0; this.firstSeek = true; this.declineCurrentVisitor = false; @@ -97,7 +97,7 @@ class VisitorMacro { this.declineCurrentVisitor = false; this.visitorStartedAt = Date.now(); if (this.visitorIndex >= this.visitors.length) { - Chat.message('&aAll stored visitors completed.'); + chat('&aAll stored visitors completed.'); return this.stop(); } this.transition(STATES.SEEKING); @@ -223,7 +223,7 @@ class VisitorMacro { Rotations.stop(); Client.stopMovement(); Guis.closeInv(); - Chat.message('&eVisitor timed out, skipping.'); + chat('&eVisitor timed out, skipping.'); bazaarUtil.cancel(); this.advanceVisitor(); } diff --git a/modules/foraging/AutoHarp.js b/modules/foraging/AutoHarp.js index 955db400..9daca52f 100644 --- a/modules/foraging/AutoHarp.js +++ b/modules/foraging/AutoHarp.js @@ -1,5 +1,5 @@ import { ModuleBase } from '../../utils/ModuleBase'; -import { Guis } from '../../utils/player/Inventory'; +import { clickSlot, getGuiName } from '../../utils/player/Inventory'; class AutoHarp extends ModuleBase { constructor() { @@ -15,7 +15,7 @@ class AutoHarp extends ModuleBase { this.notes = [37, 38, 39, 40, 41, 42, 43].map((slot) => ({ slot, clicked: false, DELAY: 0 })); this.on('tick', () => { - const invName = Guis.guiName(); + const invName = getGuiName(); if (!invName?.includes('Harp')) return; const container = Player.getContainer(); @@ -40,7 +40,7 @@ class AutoHarp extends ModuleBase { note.clicked = true; } - Guis.clickSlot(note.slot, false, 'MIDDLE'); + clickSlot(note.slot, false, 'MIDDLE'); }); }); diff --git a/modules/foraging/ForagingBot.js b/modules/foraging/ForagingBot.js index 5da6fc36..d5cd51f8 100644 --- a/modules/foraging/ForagingBot.js +++ b/modules/foraging/ForagingBot.js @@ -1,10 +1,10 @@ import { isDeveloperModeEnabled } from '../../utils/DeveloperModeState'; import { Vec3d } from '../../utils/Constants'; -import { MathUtils } from '../../utils/Math'; +import { angleToPlayer, getDistanceToPlayerEyes } from '../../utils/Math'; import { ModuleBase } from '../../utils/ModuleBase'; import Pathfinder from '../../utils/pathfinder/PathFinder'; import { Rotations } from '../../utils/player/Rotations'; -import { Raytrace } from '../../utils/Raytrace'; +import { getPointOnBlock } from '../../utils/Raytrace'; import { ScheduleTask } from '../../utils/ScheduleTask'; const MAX_SCAN = 500; @@ -288,7 +288,7 @@ class ForagingBot extends ModuleBase { addHitPoints(list) { return list.map((block) => ({ ...block, - hitPoint: Raytrace.getPointOnBlock(block, false), + hitPoint: getPointOnBlock(block, false), })); } @@ -299,7 +299,7 @@ class ForagingBot extends ModuleBase { filterInRange(list) { return list.filter((block) => { const point = block.hitPoint || [block.x + 0.5, block.y + 0.5, block.z + 0.5]; - const distData = MathUtils.getDistanceToPlayerEyes(point[0], point[1], point[2]); + const distData = getDistanceToPlayerEyes(point[0], point[1], point[2]); return (distData?.distance ?? Infinity) <= MAX_DISTANCE; }); } @@ -310,8 +310,8 @@ class ForagingBot extends ModuleBase { const scoredBlocks = blocksToScore.map((block) => { const point = block.hitPoint || [block.x + 0.5, block.y + 0.5, block.z + 0.5]; - const angleData = MathUtils.angleToPlayer(point); - const distanceData = MathUtils.getDistanceToPlayerEyes(point[0], point[1], point[2]); + const angleData = angleToPlayer(point); + const distanceData = getDistanceToPlayerEyes(point[0], point[1], point[2]); return { ...block, @@ -351,4 +351,4 @@ class ForagingBot extends ModuleBase { } } -export const ForagingB = isDeveloperModeEnabled() ? new ForagingBot() : null; +if (isDeveloperModeEnabled()) new ForagingBot(); diff --git a/modules/foraging/HideonLeafESP.js b/modules/foraging/HideonLeafESP.js index 601214fe..2854ca42 100644 --- a/modules/foraging/HideonLeafESP.js +++ b/modules/foraging/HideonLeafESP.js @@ -1,6 +1,6 @@ import { Vec3d } from '../../utils/Constants'; import { ModuleBase } from '../../utils/ModuleBase'; -import { Utils } from '../../utils/Utils'; +import { area } from '../../utils/Utils'; const ShulkerEntity = net.minecraft.world.entity.monster.Shulker; @@ -20,7 +20,7 @@ class HideonLeafESP extends ModuleBase { this.on('step', () => this.scanTargets()).setFps(5); this.when( - () => this.enabled && World.isLoaded() && Utils.area() === 'Galatea' && this.targets.length > 0, + () => this.enabled && World.isLoaded() && area() === 'Galatea' && this.targets.length > 0, 'postRenderWorld', () => this.renderTargets() ); @@ -31,7 +31,7 @@ class HideonLeafESP extends ModuleBase { } scanTargets() { - if (!this.enabled || !World.isLoaded() || Utils.area() !== 'Galatea') { + if (!this.enabled || !World.isLoaded() || area() !== 'Galatea') { this.targets = []; return; } diff --git a/modules/foraging/LushLilacEtherwarpNuker.js b/modules/foraging/LushLilacEtherwarpNuker.js index 9804110e..00bebc72 100644 --- a/modules/foraging/LushLilacEtherwarpNuker.js +++ b/modules/foraging/LushLilacEtherwarpNuker.js @@ -1,11 +1,11 @@ import { OverlayManager } from '../../gui/OverlayUtils'; import { ModuleBase } from '../../utils/ModuleBase'; -import { MacroState } from '../../utils/MacroState'; -import { NukerUtils } from '../../utils/NukerUtils'; +import { getModuleElapsedMs } from '../../utils/MacroState'; +import { closestDirection, createBlockPosition, isBlockInRange, sendBreakPackets } from '../../utils/NukerUtils'; import { EtherwarpPathfinder } from '../../utils/pathfinder/EtherwarpPathfinder'; import { ScheduleTask } from '../../utils/ScheduleTask'; -import { Executor } from '../../utils/ThreadExecutor'; -import { Utils } from '../../utils/Utils'; +import { executeAsync } from '../../utils/ThreadExecutor'; +import { getCurrentMana } from '../../utils/Utils'; const TARGET_TYPE = new BlockType('minecraft:flowering_azalea'); const TARGET_BLACKLIST_MS = 5000; @@ -55,7 +55,7 @@ class LushLilacEtherwarpNuker extends ModuleBase { tick() { if (this.rewarping || !World.isLoaded()) return; - const mana = Utils.getCurrentMana(); + const mana = getCurrentMana(); if (mana !== null && mana < 100) return this.rewarp(); this.refreshTargets(); @@ -63,11 +63,11 @@ class LushLilacEtherwarpNuker extends ModuleBase { const now = Date.now(); const targets = this.targets.filter((target) => (this.blacklistedTargets.get(this.key(target)) || 0) <= now); - const inRange = targets.filter((target) => NukerUtils.isBlockInRange([target.x, target.y, target.z])); + const inRange = targets.filter((target) => isBlockInRange([target.x, target.y, target.z])); if (inRange.length) { const target = this.closest(inRange); - const blockPos = NukerUtils.createBlockPosition([target.x, target.y, target.z]); - NukerUtils.sendBreakPackets(blockPos, NukerUtils.closestDirection(blockPos)); + const blockPos = createBlockPosition([target.x, target.y, target.z]); + sendBreakPackets(blockPos, closestDirection(blockPos)); OverlayManager.incrementTrackedValue(this.oid, 'blocksNuked'); this.blacklistedTargets.set(this.key(target), now + TARGET_BLACKLIST_MS); this.startPath(this.closest(targets.filter((candidate) => this.key(candidate) !== this.key(target))), now); @@ -114,7 +114,7 @@ class LushLilacEtherwarpNuker extends ModuleBase { this.scanActive = true; this.lastScanAt = now; const token = ++this.scanToken; - Executor.execute(() => { + executeAsync(() => { try { const targets = World.getBlocksInBox(-535, 150, 110, -760, 80, -90, [TARGET_TYPE]).map(({ x, y, z }) => ({ x, y, z })); if (this.enabled && token === this.scanToken) this.targets = targets; @@ -137,7 +137,7 @@ class LushLilacEtherwarpNuker extends ModuleBase { } getHourlyForestWhispers() { - const elapsedMs = MacroState.getModuleElapsedMs(this.name); + const elapsedMs = getModuleElapsedMs(this.name); return elapsedMs > 0 ? Math.round((OverlayManager.getTrackedValue(this.oid, 'blocksNuked', 0) * 100 * 3600000) / elapsedMs) : 0; } diff --git a/modules/foraging/MudwormMacro.js b/modules/foraging/MudwormMacro.js index b2562518..eb19a5c5 100644 --- a/modules/foraging/MudwormMacro.js +++ b/modules/foraging/MudwormMacro.js @@ -1,6 +1,6 @@ import { OverlayManager } from '../../gui/OverlayUtils'; import { ModuleBase } from '../../utils/ModuleBase'; -import { MacroState } from '../../utils/MacroState'; +import { getModuleElapsedMs } from '../../utils/MacroState'; import { EtherwarpPathfinder } from '../../utils/pathfinder/EtherwarpPathfinder'; import { Rotations } from '../../utils/player/Rotations'; import { ScheduleTask } from '../../utils/ScheduleTask'; @@ -189,7 +189,7 @@ class MudwormMacro extends ModuleBase { } getHourlyRate(key) { - const elapsedMs = MacroState.getModuleElapsedMs(this.name); + const elapsedMs = getModuleElapsedMs(this.name); if (elapsedMs <= 0) return 0; return Math.round((OverlayManager.getTrackedValue(this.oid, key, 0) * 3600000) / elapsedMs); } diff --git a/modules/foraging/SeaLumieMacro.js b/modules/foraging/SeaLumieMacro.js index 7b444d02..fd2fbf41 100644 --- a/modules/foraging/SeaLumieMacro.js +++ b/modules/foraging/SeaLumieMacro.js @@ -1,6 +1,7 @@ import { isDeveloperModeEnabled } from '../../utils/DeveloperModeState'; import { Vec3d } from '../../utils/Constants'; import { ModuleBase } from '../../utils/ModuleBase'; +import { calculateDistance } from '../../utils/Math'; class SeaLumie extends ModuleBase { constructor() { @@ -169,7 +170,7 @@ class SeaLumie extends ModuleBase { if (block?.type?.getRegistryName()?.includes("pickle")) { // get if the block iss still there if ( - MathUtils.calculateDistance( + calculateDistance( [Player.getX(), Player.getY(), Player.getZ()], [ this.closestPickle.x, diff --git a/modules/mining/CommissionMacro.js b/modules/mining/CommissionMacro.js index 748c7f05..f2d63898 100644 --- a/modules/mining/CommissionMacro.js +++ b/modules/mining/CommissionMacro.js @@ -1,18 +1,18 @@ import { OverlayManager } from '../../gui/OverlayUtils'; import { notificationManager } from '../../gui/NotificationManager'; import { CommissionClaimer } from '../../utils/CommissionUtils'; -import { MathUtils } from '../../utils/Math'; -import { MacroState } from '../../utils/MacroState'; -import { MiningUtils } from '../../utils/MiningUtils'; +import { fastDistance } from '../../utils/Math'; +import { getModuleElapsedMs } from '../../utils/MacroState'; +import { getDrills, getMiningSpeed, readCommissionsFromGui, refuel } from '../../utils/MiningUtils'; import { ModuleBase } from '../../utils/ModuleBase'; import { finiteNumber } from '../../utils/NumberUtils'; import { EtherwarpPathfinder } from '../../utils/pathfinder/EtherwarpPathfinder'; import Pathfinder from '../../utils/pathfinder/PathFinder'; -import { Guis } from '../../utils/player/Inventory'; -import { manager } from '../../utils/SkyblockEvents'; -import { TabListUtils } from '../../utils/TabListUtils'; -import { Mouse } from '../../utils/Ungrab'; -import { Utils } from '../../utils/Utils'; +import { clickSlot, closeInventory, getGuiName, setItemSlot } from '../../utils/player/Inventory'; +import { registerSkyblockEvent } from '../../utils/SkyblockEvents'; +import { readCommissions } from '../../utils/TabListUtils'; +import { regrab, ungrab } from '../../utils/Ungrab'; +import { area } from '../../utils/Utils'; import { CombatBot } from '../combat/CombatBot'; import { COMMISSION_DATA, EMISSARY_LOCATIONS, MOB_CONFIGS, TRASH_ITEMS } from './CommissionData'; import { MiningBot } from './MiningBot'; @@ -78,7 +78,7 @@ class CommissionMacro extends ModuleBase { delay: (ticks) => this.delay(ticks), onClaimsExhausted: (container) => { this.updateCommissionsFromGui(container); - Guis.closeInv(); + closeInventory(); this.setState(STATES.WAITING_GUI_CLOSE); }, onPathStart: () => { @@ -129,31 +129,31 @@ class CommissionMacro extends ModuleBase { ); this.on('step', () => { - const newCommissions = TabListUtils.readCommissions(); + const newCommissions = readCommissions(); this.updateCommissionsIfChanged(newCommissions); }).setDelay(1); this.on('tick', () => this.runLogic()); - manager.subscribe('commissioncomplete', () => { + registerSkyblockEvent('commissioncomplete', () => { if (!this.enabled) return; OverlayManager.incrementTrackedValue(this.oid, 'commissionsCompleted'); this.onCommissionComplete(); }); - manager.subscribe('fullinventory', () => { + registerSkyblockEvent('fullinventory', () => { if (this.enabled && this.currentState === STATES.MINING) this.onInventoryFull(); }); - manager.subscribe('emptydrill', () => { + registerSkyblockEvent('emptydrill', () => { if (this.enabled && (this.currentState === STATES.MINING || this.currentState === STATES.CLAIMING)) this.onDrillEmpty(); }); - manager.subscribe('death', () => { + registerSkyblockEvent('death', () => { if (this.enabled) this.delayedReset(10); }); - manager.subscribe('serverchange', () => { + registerSkyblockEvent('serverchange', () => { if (this.enabled) this.delayedReset(67); }); @@ -200,7 +200,7 @@ class CommissionMacro extends ModuleBase { } getCommissionsPerHourDisplay() { - const elapsedMs = MacroState.getModuleElapsedMs(this.name); + const elapsedMs = getModuleElapsedMs(this.name); if (elapsedMs <= 0) return '0.00'; const hours = elapsedMs / 3600000; const rate = this.getCompletedCommissions() / hours; @@ -254,7 +254,7 @@ class CommissionMacro extends ModuleBase { this.message('&aEnabled'); this.emissariesUnlocked = true; - const drills = MiningUtils.getDrills(); + const drills = getDrills(); this.drill = drills.drill; this.pickaxe = this.drill; @@ -272,14 +272,14 @@ class CommissionMacro extends ModuleBase { notificationManager.add(`No weapon found in slot ${this.goblinWeaponSlot}`, 'Goblin commissions will be skipped.', 'ERROR', '5000'); } - this.miningSpeed = MiningUtils.getMiningSpeed('Dwarven Mines'); + this.miningSpeed = getMiningSpeed('Dwarven Mines'); if (!this.miningSpeed) { notificationManager.add('No mining speed saved!', "Run '/v5 mining stats' first.", 'ERROR', '5000'); this.toggle(false); return; } - Mouse.ungrab(); + ungrab(); this.resetState(); } @@ -287,7 +287,7 @@ class CommissionMacro extends ModuleBase { this.message('&cDisabled'); this.resetState(); - Mouse.regrab(); + regrab(); } resetState() { @@ -368,9 +368,9 @@ class CommissionMacro extends ModuleBase { } handleChoosing() { - const area = Utils.area(); + const areaName = area(); const now = Date.now(); - if (area !== 'Dwarven Mines') { + if (areaName !== 'Dwarven Mines') { if (!this.areaCheckTime) { this.message('&eNot in Dwarven Mines, warping...'); ChatLib.command('warpforge'); @@ -385,7 +385,7 @@ class CommissionMacro extends ModuleBase { } this.areaCheckTime = null; - const newCommissions = TabListUtils.readCommissions(); + const newCommissions = readCommissions(); this.updateCommissionsIfChanged(newCommissions); if (this.shouldWaitForLastCompleted()) return; @@ -585,7 +585,7 @@ class CommissionMacro extends ModuleBase { handleSelling() { // COMPLETELY UNTESTED :) - if (Guis.guiName() !== 'Trades') { + if (getGuiName() !== 'Trades') { ChatLib.command('trades'); this.delay(10); return; @@ -595,7 +595,7 @@ class CommissionMacro extends ModuleBase { if (soldItem) return; // No more items to sell - Guis.closeInv(); + closeInventory(); this.restoreStateAfterSelling(); } @@ -615,7 +615,7 @@ class CommissionMacro extends ModuleBase { const isNotEquipment = !name.includes('Drill') && !name.includes('Pickaxe') && !name.includes('Minecart') && !name.includes('Tasty'); if (isTrash && isNotEquipment) { - Guis.clickSlot(i, false); + clickSlot(i, false); return true; } } @@ -638,7 +638,7 @@ class CommissionMacro extends ModuleBase { ensureDrillEquippedForEmissaryClaim() { if (!this.drill) { - const drills = MiningUtils.getDrills(); + const drills = getDrills(); this.drill = drills.drill; this.pickaxe = this.drill; } @@ -646,7 +646,7 @@ class CommissionMacro extends ModuleBase { if (!this.drill) return true; if (Player.getHeldItemIndex() !== this.drill.slot) { - Guis.setItemSlot(this.drill.slot); + setItemSlot(this.drill.slot); this.delay(3); return false; } @@ -668,7 +668,7 @@ class CommissionMacro extends ModuleBase { } updateCommissionsFromGui(container) { - const newCommissions = MiningUtils.readCommissionsFromGui(container, (name) => COMMISSION_DATA.some((d) => d.names.includes(name))); + const newCommissions = readCommissionsFromGui(container, (name) => COMMISSION_DATA.some((d) => d.names.includes(name))); if (newCommissions.length > 0) { this.commissions = newCommissions; @@ -694,14 +694,14 @@ class CommissionMacro extends ModuleBase { } refreshDrillReference() { - const drills = MiningUtils.getDrills(); + const drills = getDrills(); this.drill = drills.drill; this.pickaxe = this.drill; if (this.drill) { const itemName = ChatLib.removeFormatting(this.drill.item.getName()); this.isActualDrill = itemName.includes('Drill') || itemName.includes('Gauntlet'); - Guis.setItemSlot(this.drill.slot); + setItemSlot(this.drill.slot); } } @@ -765,7 +765,7 @@ class CommissionMacro extends ModuleBase { } getDistance(x1, y1, z1, x2, y2, z2) { - return MathUtils.fastDistance(x1, y1, z1, x2, y2, z2); + return fastDistance(x1, y1, z1, x2, y2, z2); } updateCurrentPathWaypointFromResult() { @@ -843,7 +843,7 @@ class CommissionMacro extends ModuleBase { return; } - const drills = MiningUtils.getDrills(); + const drills = getDrills(); this.drill = drills.drill; if (!this.drill) { @@ -855,7 +855,7 @@ class CommissionMacro extends ModuleBase { const itemName = ChatLib.removeFormatting(this.drill.item.getName()); this.isActualDrill = itemName.includes('Drill') || itemName.includes('Gauntlet'); - Guis.setItemSlot(this.drill.slot); + setItemSlot(this.drill.slot); const isTitaniumCommission = this.currentCommission.name.includes('Titanium'); MiningBot.setPrioritizeTitanium(isTitaniumCommission); @@ -870,10 +870,10 @@ class CommissionMacro extends ModuleBase { if (name === 'Goblin Slayer') { mobType = 'goblin'; - Guis.setItemSlot(this.weapon.slot); + setItemSlot(this.weapon.slot); } else if (name === 'Glacite Walker Slayer' || name === 'Mines Slayer' || name === 'Treasure Hoarder Puncher') { mobType = name === 'Glacite Walker Slayer' || name === 'Mines Slayer' ? 'icewalker' : 'treasure'; - Guis.setItemSlot(this.pickaxe.slot); + setItemSlot(this.pickaxe.slot); } else { this.toggle(false); return; @@ -929,7 +929,7 @@ class CommissionMacro extends ModuleBase { MiningBot.toggle(false, true); this.setState(STATES.REFUELING); - MiningUtils.doRefueling(true, (success) => { + refuel(true, (success) => { if (!success) { this.message('&cRefueling failed!'); this.toggle(false); @@ -937,7 +937,7 @@ class CommissionMacro extends ModuleBase { } this.message('&aRefueling successful!'); - const drills = MiningUtils.getDrills(); + const drills = getDrills(); this.drill = drills.drill; if (this.drill) { diff --git a/modules/mining/ExcavatorMacro.js b/modules/mining/ExcavatorMacro.js index 0971f873..bcd9b1b5 100644 --- a/modules/mining/ExcavatorMacro.js +++ b/modules/mining/ExcavatorMacro.js @@ -1,9 +1,9 @@ import { ModuleBase } from '../../utils/ModuleBase'; -import { MathUtils } from '../../utils/Math'; -import { Guis } from '../../utils/player/Inventory'; +import { fastDistance } from '../../utils/Math'; +import { clickItem, clickSlot, closeInventory, getGuiName } from '../../utils/player/Inventory'; import Pathfinder from '../../utils/pathfinder/PathFinder'; import { Rotations } from '../../utils/player/Rotations'; -import { Utils } from '../../utils/Utils'; +import { area } from '../../utils/Utils'; class ExcavatorMacro extends ModuleBase { constructor() { @@ -73,7 +73,7 @@ class ExcavatorMacro extends ModuleBase { } if (this.inExcavator) { - if (Guis.guiName() !== 'Fossil Excavator') { + if (getGuiName() !== 'Fossil Excavator') { this.message('Excavator closed.'); this.toggle(false); return; @@ -92,15 +92,15 @@ class ExcavatorMacro extends ModuleBase { break; case this.STATES.SETUP: - if (Guis.guiName() !== 'Fossil Excavator') return; + if (getGuiName() !== 'Fossil Excavator') return; this.inExcavator = true; if (!this.clickDelay()) return; - Guis.clickItem('Start Excavator', true, 'MIDDLE'); + clickItem('Start Excavator', true, 'MIDDLE'); this.state = this.STATES.EXCAVATING; break; case this.STATES.EXCAVATING: - if (Guis.guiName() !== 'Fossil Excavator') return; + if (getGuiName() !== 'Fossil Excavator') return; const brownSlots = []; const container = Player.getContainer(); @@ -116,7 +116,7 @@ class ExcavatorMacro extends ModuleBase { } if (slot?.type?.getRegistryName()?.includes('yellow_stained')) { - Guis.closeInv(); + closeInventory(); this.inExcavator = false; this.state = this.STATES.OPENING; return; @@ -124,7 +124,7 @@ class ExcavatorMacro extends ModuleBase { if (slot?.type?.getRegistryName()?.includes('lime_stained')) { if (!this.clickDelay()) return; - Guis.clickSlot(i); + clickSlot(i); this.blacklistSlot(i, 10); return; } @@ -138,7 +138,7 @@ class ExcavatorMacro extends ModuleBase { if (!this.clickDelay()) return; - Guis.clickSlot(randomBrownSlot); + clickSlot(randomBrownSlot); this.blacklistSlot(randomBrownSlot, 10); return; } @@ -148,8 +148,8 @@ class ExcavatorMacro extends ModuleBase { } handleAutoTravel() { - if (Utils.area() !== 'Dwarven Mines') { - if (Player.getContainer()) Guis.closeInv(); + if (area() !== 'Dwarven Mines') { + if (Player.getContainer()) closeInventory(); if (Pathfinder.isPathing()) Pathfinder.resetPath(); Rotations.stop(); @@ -165,10 +165,10 @@ class ExcavatorMacro extends ModuleBase { this.warpCooldownTicks = 0; - const distance = MathUtils.fastDistance(Player.getX(), Player.getY(), Player.getZ(), 19, 120, 227); + const distance = fastDistance(Player.getX(), Player.getY(), Player.getZ(), 19, 120, 227); if (distance > 3) { - if (Player.getContainer()) Guis.closeInv(); + if (Player.getContainer()) closeInventory(); Rotations.stop(); if (!Pathfinder.isPathing()) { diff --git a/modules/mining/GemstoneMacro.js b/modules/mining/GemstoneMacro.js index eab7b129..3fed2f5a 100644 --- a/modules/mining/GemstoneMacro.js +++ b/modules/mining/GemstoneMacro.js @@ -1,17 +1,16 @@ import { isDeveloperModeEnabled } from '../../utils/DeveloperModeState'; import { MCHand, Vec3d } from '../../utils/Constants'; -import { MathUtils } from '../../utils/Math'; +import { distanceToPlayerFeet, getDistanceToPlayer } from '../../utils/Math'; import { ModuleBase } from '../../utils/ModuleBase'; import { ServerboundUseItemPacket } from '../../utils/Packets'; -import { Raytrace } from '../../utils/Raytrace'; -import RouteState from '../../utils/RouteState'; -import { Router } from '../../utils/Router'; +import { isLineClear } from '../../utils/Raytrace'; +import { getFileFromCallback, getFilesInDir, loadRouteFromFile } from '../../utils/Router'; import { ScheduleTask } from '../../utils/ScheduleTask'; -import { Mouse } from '../../utils/Ungrab'; -import { Utils } from '../../utils/Utils'; -import { Guis } from '../../utils/player/Inventory'; +import { regrab, ungrab } from '../../utils/Ungrab'; +import { area } from '../../utils/Utils'; +import { findItemInHotbar, setItemSlot } from '../../utils/player/Inventory'; import { Rotations } from '../../utils/player/Rotations'; -import { ServerInfo } from '../../utils/player/ServerInfo'; +import { getTPS } from '../../utils/player/ServerInfo'; import { MiningBot } from './MiningBot'; class GemstoneMacro extends ModuleBase { @@ -65,7 +64,7 @@ class GemstoneMacro extends ModuleBase { this.state = this.STATES.WAITING; - this.routesDir = Router.getFilesInDir('GemstoneRoutes'); + this.routesDir = getFilesInDir('GemstoneRoutes'); this.route = null; this.loadedFile = null; @@ -94,13 +93,13 @@ class GemstoneMacro extends ModuleBase { }, 'Route Progress': () => (this.route ? `${this.closestPointIndex || 0}/${this.route.length + 1}` : 'No Route'), 'Targets Found': () => MiningBot.foundLocations.length, - TPS: () => ServerInfo.getTPS().toFixed(1), + TPS: () => getTPS().toFixed(1), }, }, ]); this.when( - () => Utils.area() === 'Crystal Hollows', + () => area() === 'Crystal Hollows', 'postRenderWorld', () => { if (!this.route || this.route.length < 1) return; @@ -156,7 +155,7 @@ class GemstoneMacro extends ModuleBase { case this.STATES.ETHERWARPING: MiningBot.toggle(false); Client.setKey('leftclick', false); - let aotv = Guis.findItemInHotbar('Aspect of the Void'); + let aotv = findItemInHotbar('Aspect of the Void'); if (aotv === -1) { this.message('&cAspect of the Void not found in hotbar!'); @@ -192,7 +191,7 @@ class GemstoneMacro extends ModuleBase { this.attemptedEtherwarp = false; } - this.dist = MathUtils.distanceToPlayerFeet([this.closestPoint.x, this.closestPoint.y, this.closestPoint.z]); + this.dist = distanceToPlayerFeet([this.closestPoint.x, this.closestPoint.y, this.closestPoint.z]); if (this.dist.distance < 2) { this.message(`Arrived at point ${this.closestPointIndex + 1}.`); @@ -208,7 +207,7 @@ class GemstoneMacro extends ModuleBase { } if (!this.rotatedToPoint) { - Guis.setItemSlot(aotv); + setItemSlot(aotv); Client.setKey('shift', true); const player = Player.getPlayer(); if (!player?.isSneaking()) return; @@ -280,9 +279,8 @@ class GemstoneMacro extends ModuleBase { this.routesDir, true, (selected) => { - this.loadedFile = Router.getFilefromCallback(selected); - this.route = Router.loadRouteFromFile('GemstoneRoutes/', this.loadedFile); - RouteState.setRoute(this.route, 'Gemstone Macro'); + this.loadedFile = getFileFromCallback(selected); + this.route = loadRouteFromFile('GemstoneRoutes/', this.loadedFile); }, 'The route the macro will use' ); @@ -395,7 +393,7 @@ class GemstoneMacro extends ModuleBase { shortest = Infinity; for (const face of faces) { const [tx, ty, tz] = face.target; - if (Raytrace.isLineClear(start.x(), start.y(), start.z(), tx, ty, tz)) { + if (isLineClear(start.x(), start.y(), start.z(), tx, ty, tz)) { let d = Math.hypot(tx - start.x(), ty - start.y(), tz - start.z()); if (d < shortest) { shortest = d; @@ -411,7 +409,7 @@ class GemstoneMacro extends ModuleBase { let closest = null, shortest = Infinity; for (let i = 0; i < this.route.length; i++) { - let d = MathUtils.getDistanceToPlayer(this.route[i].x, this.route[i].y, this.route[i].z).distance; + let d = getDistanceToPlayer(this.route[i].x, this.route[i].y, this.route[i].z).distance; if (d < shortest) { shortest = d; closest = { index: i }; @@ -432,9 +430,7 @@ class GemstoneMacro extends ModuleBase { } onEnable() { - if (this.route) RouteState.setRoute(this.route, 'Gemstone Macro'); - - Mouse.ungrab(); + ungrab(); this.state = this.STATES.DECIDING; this.resetRuntimeState(); @@ -443,12 +439,11 @@ class GemstoneMacro extends ModuleBase { } onDisable() { - RouteState.clearRoute(); Rotations.stop(); MiningBot.toggle(false, true); MiningBot.foundLocations = []; Client.unpressKeys(); - Mouse.regrab(); + regrab(); this.state = this.STATES.WAITING; this.resetRuntimeState(); diff --git a/modules/mining/GlaciteCommissionMacro.js b/modules/mining/GlaciteCommissionMacro.js index dea441de..d90a2e01 100644 --- a/modules/mining/GlaciteCommissionMacro.js +++ b/modules/mining/GlaciteCommissionMacro.js @@ -1,19 +1,19 @@ import { isDeveloperModeEnabled } from '../../utils/DeveloperModeState'; import { OverlayManager } from '../../gui/OverlayUtils'; import { CommissionClaimer } from '../../utils/CommissionUtils'; -import { MacroState } from '../../utils/MacroState'; -import { MiningUtils } from '../../utils/MiningUtils'; +import { getModuleElapsedMs } from '../../utils/MacroState'; +import { getDebuff, getDrills, readCommissionsFromGui } from '../../utils/MiningUtils'; import { ModuleBase } from '../../utils/ModuleBase'; import { finiteNumber } from '../../utils/NumberUtils'; import { EtherwarpPathfinder } from '../../utils/pathfinder/EtherwarpPathfinder'; import Pathfinder from '../../utils/pathfinder/PathFinder'; -import { Guis } from '../../utils/player/Inventory'; -import { manager } from '../../utils/SkyblockEvents'; -import { TabListUtils } from '../../utils/TabListUtils'; -import { Mouse } from '../../utils/Ungrab'; +import { closeInventory, setItemSlot } from '../../utils/player/Inventory'; +import { registerSkyblockEvent } from '../../utils/SkyblockEvents'; +import { readCommissions } from '../../utils/TabListUtils'; +import { regrab, ungrab } from '../../utils/Ungrab'; import { MiningBot } from './MiningBot'; import { tunnelsMiner } from './TunnelsMiner'; -import { Utils } from '../../utils/Utils'; +import { area, subArea } from '../../utils/Utils'; const STATES = { IDLE: 'Idle', @@ -65,7 +65,7 @@ class GlaciteCommissionMacro extends ModuleBase { delay: (ticks) => this.delay(ticks), onClaimsExhausted: (container) => { this.updateCommissionsFromGui(container); - Guis.closeInv(); + closeInventory(); this.setState(STATES.WAITING_GUI_CLOSE); }, onPathFailed: () => { @@ -117,23 +117,23 @@ class GlaciteCommissionMacro extends ModuleBase { this.on('step', () => { if (!this.enabled) return; - const newCommissions = TabListUtils.readCommissions(); + const newCommissions = readCommissions(); this.updateCommissionsIfChanged(newCommissions); }).setDelay(1); this.on('tick', () => this.runLogic()); - manager.subscribe('commissioncomplete', () => { + registerSkyblockEvent('commissioncomplete', () => { if (!this.enabled) return; OverlayManager.incrementTrackedValue(this.oid, 'commissionsCompleted'); this.onCommissionComplete(); }); - manager.subscribe('death', () => { + registerSkyblockEvent('death', () => { if (this.enabled) this.delayedReset(10); }); - manager.subscribe('serverchange', () => { + registerSkyblockEvent('serverchange', () => { if (this.enabled) this.delayedReset(40); }); @@ -144,7 +144,7 @@ class GlaciteCommissionMacro extends ModuleBase { onEnable() { this.message('&aEnabled'); - Mouse.ungrab(); + ungrab(); this.resetState(); this.refreshDrillReference(); @@ -158,7 +158,7 @@ class GlaciteCommissionMacro extends ModuleBase { onDisable() { this.message('&cDisabled'); this.resetState(); - Mouse.regrab(); + regrab(); } resetState() { @@ -192,7 +192,7 @@ class GlaciteCommissionMacro extends ModuleBase { if (!this.enabled) return; if (!Player.getPlayer()) return; - const cold = MiningUtils.getDebuff('cold'); + const cold = getDebuff('cold'); if (this.currentState === STATES.WAITING_COLD) { if (cold > 0) return; this.setState(STATES.CHOOSING); @@ -234,11 +234,11 @@ class GlaciteCommissionMacro extends ModuleBase { } handleChoosing() { - const area = Utils.area(); - const subarea = Utils.subArea(); + const areaName = area(); + const subarea = subArea(); const now = Date.now(); const validSubareas = ['Glacite Tunnels', 'Fossil Research Center', 'Dwarven Base Camp']; - if (area !== 'Dwarven Mines' || !validSubareas.includes(subarea)) { + if (areaName !== 'Dwarven Mines' || !validSubareas.includes(subarea)) { if (!this.areaCheckTime) { this.message('&eNot in the Glacite area, warping to camp...'); ChatLib.command('warp camp'); @@ -252,7 +252,7 @@ class GlaciteCommissionMacro extends ModuleBase { return; } this.areaCheckTime = null; - const newCommissions = TabListUtils.readCommissions(); + const newCommissions = readCommissions(); this.updateCommissionsIfChanged(newCommissions); if (this.shouldWaitForLastCompleted()) return; @@ -279,7 +279,7 @@ class GlaciteCommissionMacro extends ModuleBase { } handleMining() { - const newCommissions = TabListUtils.readCommissions(); + const newCommissions = readCommissions(); this.updateCommissionsIfChanged(newCommissions); if (this.shouldWaitForLastCompleted()) return; @@ -341,7 +341,7 @@ class GlaciteCommissionMacro extends ModuleBase { this.noSupportedMessageAt = 0; if (Client.isInGui()) { this.pendingMiningStart = true; - Guis.closeInv(); + closeInventory(); this.setState(STATES.WAITING_GUI_CLOSE); return; } @@ -377,7 +377,7 @@ class GlaciteCommissionMacro extends ModuleBase { } updateCommissionsFromGui(container) { - const newCommissions = MiningUtils.readCommissionsFromGui(container, (name) => this.isSupportedCommissionName(name)); + const newCommissions = readCommissionsFromGui(container, (name) => this.isSupportedCommissionName(name)); if (!newCommissions.length) return; this.commissions = newCommissions; @@ -393,9 +393,9 @@ class GlaciteCommissionMacro extends ModuleBase { } refreshDrillReference() { - const drills = MiningUtils.getDrills(); + const drills = getDrills(); this.drill = drills.drill; - if (this.drill) Guis.setItemSlot(this.drill.slot); + if (this.drill) setItemSlot(this.drill.slot); } ensureDrillEquippedForClaim() { @@ -403,7 +403,7 @@ class GlaciteCommissionMacro extends ModuleBase { if (!this.drill) return true; if (Player.getHeldItemIndex() !== this.drill.slot) { - Guis.setItemSlot(this.drill.slot); + setItemSlot(this.drill.slot); this.delay(3); return false; } @@ -516,7 +516,7 @@ class GlaciteCommissionMacro extends ModuleBase { } getCommissionsPerHourDisplay() { - const elapsedMs = MacroState.getModuleElapsedMs(this.name); + const elapsedMs = getModuleElapsedMs(this.name); if (elapsedMs <= 0) return '0.00'; const hours = elapsedMs / 3600000; diff --git a/modules/mining/GlaciteData.js b/modules/mining/GlaciteData.js index faef2406..00f3a9c3 100644 --- a/modules/mining/GlaciteData.js +++ b/modules/mining/GlaciteData.js @@ -13,4 +13,3 @@ const onyx = [[[7, 128, 304], [6, 128, 305], [6, 129, 305], [7, 127, 304], [7, 1 // prettier-ignore const citrine = [[[30, 120, 387], [29, 119, 387], [29, 119, 388], [29, 120, 387], [29, 120, 388], [29, 121, 387], [29, 121, 388], [30, 120, 388], [30, 121, 387], [30, 121, 388], [28, 119, 388], [28, 120, 387], [28, 120, 388], [28, 121, 388], [29, 121, 389], [30, 121, 389], [28, 122, 387], [29, 122, 388], [30, 122, 388], [29, 122, 389], [30, 122, 389], [27, 121, 387], [27, 122, 387], [27, 123, 387], [28, 123, 387], [30, 123, 389], [26, 120, 387], [26, 121, 387], [26, 122, 387], [25, 120, 388], [25, 121, 387], [25, 121, 388], [25, 122, 388], [25, 123, 388], [24, 120, 388], [24, 120, 389], [24, 121, 388], [24, 121, 389], [25, 120, 389], [25, 121, 389], [24, 122, 387], [24, 122, 388], [24, 122, 389], [25, 122, 389], [25, 123, 389], [26, 123, 389], [25, 124, 389], [26, 124, 389], [23, 121, 388], [23, 122, 388], [25, 123, 390], [26, 123, 390], [25, 124, 390], [26, 124, 390], [25, 125, 389], [25, 125, 390], [26, 125, 389], [26, 125, 390], [26, 126, 390], [26, 126, 391], [26, 127, 390], [26, 127, 391],], [[28, 119, 398], [28, 118, 398], [28, 118, 399], [28, 119, 399], [29, 118, 398], [29, 118, 399], [29, 119, 398], [29, 119, 399], [29, 120, 399], [29, 120, 400], [29, 121, 399], [29, 121, 400],], [[27, 119, 396], [27, 120, 395], [27, 120, 396], [28, 120, 395], [28, 120, 396], [27, 121, 396], [28, 121, 395], [28, 121, 396], [28, 122, 395], [29, 122, 395], [28, 123, 395], [29, 123, 395],], [[35, 120, 400], [35, 120, 401], [35, 121, 400], [35, 121, 401], [36, 120, 400], [36, 120, 401], [36, 121, 400], [34, 122, 400], [35, 122, 400], [34, 123, 400], [35, 123, 400],], [[23, 120, 407], [22, 120, 407], [22, 120, 408], [22, 121, 407], [22, 121, 408], [23, 120, 408], [23, 121, 406], [23, 121, 407], [23, 121, 408], [22, 122, 407], [22, 122, 408], [23, 122, 406], [23, 122, 407], [23, 122, 408], [24, 122, 406], [24, 122, 407], [23, 123, 406], [23, 123, 407], [24, 123, 406], [24, 123, 407], [24, 124, 406], [25, 124, 406], [24, 125, 406], [25, 125, 406],], [[17, 121, 398], [16, 120, 398], [16, 120, 399], [16, 121, 398], [17, 120, 398], [17, 120, 399], [17, 121, 399], [17, 122, 399], [17, 122, 400], [17, 123, 399], [17, 123, 400],], [[18, 121, 394], [18, 120, 393], [18, 120, 394], [18, 121, 393], [18, 122, 393], [18, 122, 394], [19, 120, 393], [19, 121, 393], [19, 121, 394], [19, 122, 393], [19, 122, 394], [19, 123, 394], [19, 123, 395], [19, 124, 394], [19, 124, 395],], [[23, 120, 394], [23, 120, 395], [23, 121, 394], [23, 121, 395], [23, 122, 393], [23, 122, 394], [23, 122, 395], [23, 123, 393], [23, 123, 394],], [[-48, 128, 415], [-49, 127, 414], [-49, 127, 415], [-49, 128, 414], [-49, 128, 415], [-48, 127, 414], [-48, 127, 415], [-48, 128, 414], [-48, 129, 414], [-48, 129, 415], [-49, 126, 415], [-48, 130, 415], [-47, 130, 415], [-48, 131, 415], [-47, 131, 415],], [[-52, 127, 418], [-53, 126, 418], [-53, 127, 418], [-53, 127, 419], [-53, 128, 418], [-53, 128, 419], [-52, 127, 419], [-52, 128, 418], [-52, 128, 419], [-52, 129, 419], [-52, 129, 420], [-52, 130, 419], [-52, 130, 420],], [[87, 151, 331], [87, 151, 332], [87, 152, 331], [87, 152, 332], [88, 150, 332], [88, 151, 331], [88, 151, 332], [88, 152, 331], [88, 152, 332], [87, 153, 330], [87, 153, 331], [87, 154, 330], [87, 154, 331],], [[86, 151, 334], [85, 152, 335], [86, 150, 334], [86, 150, 335], [86, 151, 335], [86, 152, 334], [86, 152, 335], [87, 150, 334], [87, 150, 335], [87, 151, 334], [87, 151, 335], [87, 152, 334], [87, 152, 335], [85, 152, 336], [85, 153, 335], [85, 153, 336], [86, 152, 336], [86, 153, 335], [86, 153, 336], [84, 154, 336], [85, 154, 336], [84, 155, 336], [85, 155, 336],], [[92, 152, 342], [92, 151, 342], [92, 151, 343], [92, 152, 343], [92, 153, 341], [92, 153, 342], [92, 153, 343], [93, 151, 342], [93, 151, 343], [93, 152, 342], [93, 152, 343], [93, 153, 342], [93, 153, 343], [92, 154, 341], [92, 154, 342], [92, 155, 341], [92, 155, 342],], [[93, 152, 336], [92, 152, 335], [93, 151, 335], [93, 152, 335], [93, 153, 335], [93, 153, 336], [94, 152, 335], [94, 153, 335], [94, 153, 336], [93, 151, 334], [93, 152, 334], [93, 153, 334], [93, 154, 335], [93, 154, 336], [94, 154, 336], [94, 155, 336], [95, 155, 336], [94, 156, 336], [95, 156, 336],], [[92, 152, 331], [91, 151, 331], [91, 151, 332], [91, 152, 330], [91, 152, 331], [91, 152, 332], [91, 153, 331], [92, 152, 330], [92, 153, 330], [92, 153, 331], [90, 151, 331], [90, 152, 331], [92, 154, 330], [93, 154, 330], [92, 155, 330], [93, 155, 330],], [[97, 152, 343], [96, 151, 343], [96, 151, 344], [96, 152, 343], [96, 152, 344], [96, 153, 343], [96, 153, 344], [97, 151, 343], [97, 151, 344], [97, 152, 344], [97, 153, 343], [97, 153, 344], [95, 151, 343], [95, 151, 344], [95, 152, 343], [95, 152, 344], [95, 153, 343], [96, 154, 343], [96, 154, 344], [97, 154, 342], [97, 154, 343], [97, 154, 344], [98, 154, 342], [98, 154, 343], [97, 155, 342], [97, 155, 343], [98, 155, 342], [98, 155, 343], [98, 156, 342], [99, 156, 342], [98, 157, 342], [99, 157, 342],], [[104, 151, 343], [104, 152, 343], [105, 150, 343], [105, 151, 343], [105, 152, 343],], [[98, 152, 347], [97, 151, 348], [97, 152, 348], [97, 153, 348], [98, 151, 347], [98, 151, 348], [98, 152, 348], [98, 153, 348], [99, 152, 348], [96, 152, 349], [97, 151, 349], [98, 151, 349], [98, 152, 349], [98, 153, 349], [97, 154, 349], [98, 154, 348], [98, 154, 349], [99, 152, 349], [99, 153, 349], [99, 154, 349], [95, 151, 350], [95, 152, 350], [96, 152, 350], [99, 155, 349], [99, 155, 350], [94, 151, 351], [94, 152, 351], [95, 151, 351], [95, 152, 351], [96, 151, 351], [96, 152, 351], [95, 153, 351], [96, 153, 351], [99, 156, 349], [99, 156, 350], [95, 151, 352], [95, 152, 352], [95, 153, 352], [96, 151, 352], [96, 152, 352], [96, 153, 352], [95, 154, 352], [96, 154, 351], [96, 154, 352], [96, 155, 352], [96, 155, 353], [96, 156, 352], [96, 156, 353],], [[103, 153, 367], [103, 154, 367], [104, 152, 366], [104, 152, 367], [104, 153, 367], [104, 154, 367], [104, 151, 366], [104, 151, 367], [105, 151, 366], [105, 151, 367], [105, 152, 366], [105, 152, 367],], [[110, 151, 383], [110, 151, 382], [110, 152, 382], [110, 152, 383], [111, 151, 382], [111, 151, 383], [111, 151, 384], [111, 152, 382], [111, 152, 383], [110, 153, 381], [110, 153, 382], [111, 153, 382], [111, 153, 383], [112, 151, 382], [112, 151, 383], [112, 152, 382], [112, 152, 383], [112, 151, 384], [111, 151, 385], [111, 152, 385], [110, 154, 381], [110, 154, 382], [111, 154, 382], [110, 153, 385], [111, 153, 385], [109, 155, 381], [110, 155, 381], [110, 155, 382], [110, 154, 385], [111, 154, 385], [109, 156, 381], [110, 156, 381],], [[108, 152, 389], [108, 151, 389], [108, 151, 390], [108, 153, 388], [108, 153, 389], [109, 151, 389], [109, 151, 390], [109, 152, 389], [109, 152, 390], [108, 154, 388], [108, 154, 389],], [[78, 152, 380], [78, 151, 379], [78, 151, 380], [78, 152, 379], [78, 153, 379], [78, 153, 380], [79, 151, 379], [79, 151, 380], [79, 152, 379], [79, 152, 380], [79, 153, 380], [79, 153, 381], [79, 154, 380], [79, 154, 381], [80, 153, 380], [80, 153, 381], [80, 154, 380], [80, 154, 381], [80, 155, 381], [81, 155, 381], [80, 156, 381], [81, 156, 381],], [[80, 152, 377], [80, 151, 377], [80, 153, 377], [81, 152, 377], [81, 153, 377], [81, 154, 377], [82, 153, 377], [82, 154, 377],], [[77, 152, 391], [77, 151, 391], [77, 151, 392], [77, 152, 392], [77, 153, 391], [77, 153, 392], [78, 152, 391], [78, 152, 392], [78, 153, 391], [78, 153, 392], [78, 154, 391], [79, 154, 391], [78, 155, 391], [79, 155, 391],], [[66, 152, 392], [65, 151, 391], [65, 151, 392], [65, 152, 391], [65, 152, 392], [66, 151, 391], [66, 151, 392], [66, 153, 392], [66, 153, 393], [66, 154, 392], [66, 154, 393],], [[67, 152, 397], [67, 153, 396], [67, 153, 397], [68, 151, 397], [68, 151, 398], [68, 152, 396], [68, 152, 397], [68, 152, 398], [68, 153, 396], [68, 153, 397], [68, 153, 398], [67, 154, 396], [67, 154, 397], [68, 154, 396], [68, 154, 397], [69, 152, 396], [69, 152, 397], [69, 153, 396], [69, 153, 397], [69, 153, 398], [69, 154, 396], [67, 155, 395], [67, 155, 396], [67, 155, 397], [68, 155, 396], [68, 155, 397], [67, 156, 395], [67, 156, 396], [68, 156, 396], [67, 157, 395], [67, 157, 396],], [[60, 152, 400], [59, 152, 401], [59, 153, 400], [59, 153, 401], [60, 151, 401], [60, 152, 401], [60, 153, 400], [60, 153, 401], [61, 151, 401], [61, 152, 401], [61, 153, 401], [60, 151, 402], [60, 152, 402], [59, 154, 400], [59, 154, 401], [60, 154, 400], [60, 154, 401], [61, 151, 402], [61, 152, 402], [58, 155, 400], [59, 155, 400], [58, 156, 400], [59, 156, 400],], [[-57, 145, 431], [-58, 145, 430], [-58, 145, 431], [-58, 146, 430], [-58, 146, 431], [-57, 144, 430], [-57, 144, 431], [-57, 145, 430], [-57, 146, 430], [-57, 146, 431], [-56, 145, 431], [-56, 146, 430], [-57, 145, 429], [-59, 147, 431], [-58, 147, 430], [-58, 147, 431], [-57, 147, 430], [-57, 147, 431], [-59, 147, 432], [-58, 147, 432], [-58, 146, 428], [-59, 148, 431], [-59, 148, 432], [-58, 148, 431], [-58, 148, 432], [-59, 146, 427], [-59, 146, 428], [-59, 147, 427], [-59, 147, 428], [-58, 145, 427], [-58, 146, 427], [-58, 147, 427], [-58, 147, 428], [-60, 149, 432], [-59, 149, 431], [-59, 149, 432], [-60, 148, 428], [-59, 148, 428], [-60, 150, 432], [-59, 150, 432], [-60, 149, 428], [-59, 149, 428], [-60, 151, 432], [-59, 151, 432],], [[-50, 144, 417], [-51, 145, 416], [-50, 143, 416], [-50, 143, 417], [-50, 144, 416], [-50, 145, 416], [-50, 145, 417], [-49, 143, 416], [-49, 144, 416], [-49, 144, 417], [-49, 145, 417], [-51, 145, 415], [-51, 146, 415], [-51, 146, 416], [-50, 145, 415], [-50, 146, 415], [-50, 146, 416], [-52, 147, 415], [-51, 147, 415], [-52, 148, 415], [-51, 148, 415],], [[-59, 144, 412], [-60, 144, 412], [-60, 144, 413], [-60, 145, 413], [-59, 143, 413], [-59, 144, 413], [-59, 145, 412], [-59, 145, 413], [-59, 146, 412], [-58, 146, 412], [-59, 147, 412], [-58, 147, 412],], [[-61, 144, 410], [-62, 143, 409], [-62, 143, 410], [-62, 144, 409], [-62, 144, 410], [-62, 145, 409], [-61, 143, 409], [-61, 143, 410], [-61, 144, 409], [-61, 145, 409], [-60, 145, 409], [-61, 145, 408], [-61, 146, 409], [-60, 145, 408], [-60, 146, 408], [-60, 146, 409], [-60, 147, 408], [-59, 147, 408], [-60, 148, 408], [-59, 148, 408],], [[-58, 144, 404], [-58, 144, 403], [-58, 145, 403], [-58, 145, 404], [-58, 146, 404], [-58, 146, 405], [-58, 147, 404], [-58, 147, 405],], [[-56, 144, 403], [-56, 143, 402], [-56, 143, 403], [-56, 144, 402], [-55, 143, 402], [-55, 143, 403], [-55, 144, 403], [-55, 145, 403], [-55, 145, 404], [-55, 146, 403], [-55, 146, 404],], [[-48, 144, 405], [-48, 143, 405], [-48, 143, 406], [-48, 144, 406], [-48, 145, 405], [-48, 145, 406], [-47, 143, 405], [-47, 143, 406], [-47, 144, 405], [-47, 144, 406], [-47, 145, 406], [-49, 146, 406], [-48, 146, 406], [-46, 143, 406], [-49, 147, 406], [-48, 147, 406],], [[-46, 144, 408], [-46, 144, 409], [-46, 145, 408], [-46, 145, 409], [-45, 144, 408], [-45, 144, 409], [-45, 145, 408], [-45, 145, 409], [-46, 146, 409], [-46, 146, 410], [-46, 147, 409], [-46, 147, 410],], [[-46, 144, 413], [-47, 143, 414], [-47, 144, 413], [-47, 144, 414], [-47, 145, 413], [-47, 145, 414], [-46, 144, 414], [-46, 145, 413], [-46, 145, 414], [-47, 143, 415], [-47, 144, 415], [-48, 145, 413], [-47, 145, 415], [-48, 146, 412], [-48, 146, 413], [-47, 146, 412], [-47, 146, 413], [-47, 146, 414], [-46, 146, 413], [-46, 146, 414], [-48, 147, 412], [-48, 147, 413], [-47, 147, 412], [-47, 147, 413], [-48, 148, 411], [-48, 148, 412], [-47, 148, 412], [-48, 149, 411], [-48, 149, 412],], [[-101, 145, 269], [-102, 144, 270], [-102, 145, 269], [-102, 145, 270], [-102, 146, 269], [-102, 146, 270], [-101, 145, 270], [-101, 146, 269], [-101, 146, 270], [-103, 145, 270], [-101, 147, 269], [-100, 147, 269], [-101, 148, 269], [-100, 148, 269],], [[-95, 146, 254], [-95, 147, 254], [-94, 145, 254], [-94, 146, 254], [-94, 147, 254],], [[-100, 145, 254], [-101, 144, 254], [-101, 145, 253], [-101, 145, 254], [-101, 146, 254], [-100, 145, 253], [-100, 146, 253], [-100, 146, 254], [-102, 145, 254], [-100, 147, 253], [-99, 147, 253], [-100, 148, 253], [-99, 148, 253],], [[-95, 144, 248], [-95, 144, 249], [-95, 145, 248], [-95, 145, 249], [-94, 143, 248], [-94, 144, 248], [-94, 144, 249], [-94, 145, 248], [-94, 145, 249], [-96, 146, 249], [-95, 146, 249], [-96, 147, 249], [-95, 147, 249],], [[-101, 145, 234], [-102, 144, 233], [-102, 145, 233], [-102, 145, 234], [-102, 146, 234], [-101, 144, 233], [-101, 144, 234], [-101, 145, 233], [-101, 146, 234], [-103, 146, 234], [-103, 147, 234], [-102, 147, 234],], [[-115, 145, 228], [-116, 145, 228], [-116, 146, 228], [-116, 146, 229], [-115, 146, 228], [-115, 146, 229], [-115, 147, 228], [-115, 147, 229], [-115, 148, 229], [-115, 148, 230], [-115, 149, 229], [-115, 149, 230],], [[-116, 146, 240], [-117, 146, 240], [-117, 146, 241], [-117, 147, 240], [-116, 146, 241], [-116, 147, 240], [-116, 147, 241], [-117, 148, 239], [-117, 148, 240], [-116, 148, 240], [-117, 149, 239], [-117, 149, 240],], [[-117, 147, 248], [-117, 146, 248], [-117, 146, 249], [-117, 148, 247], [-117, 148, 248], [-116, 146, 248], [-116, 146, 249], [-116, 147, 248], [-116, 147, 249], [-117, 149, 247], [-117, 149, 248],], [[-110, 146, 244], [-110, 147, 243], [-110, 147, 244], [-110, 147, 245], [-109, 147, 244], [-109, 147, 245], [-110, 148, 244], [-109, 148, 244], [-110, 148, 245], [-109, 148, 245], [-109, 149, 245], [-109, 149, 246], [-109, 150, 245], [-109, 150, 246],], [[-110, 146, 241], [-111, 145, 240], [-111, 145, 241], [-111, 146, 240], [-111, 146, 241], [-110, 145, 240], [-110, 145, 241], [-110, 146, 240], [-110, 147, 240], [-111, 144, 241], [-110, 146, 239], [-110, 147, 239], [-110, 148, 239], [-110, 148, 238], [-110, 149, 238], [-110, 149, 239],], [[-105, 145, 251], [-106, 144, 252], [-106, 145, 251], [-106, 145, 252], [-105, 144, 251], [-105, 144, 252], [-105, 145, 252], [-105, 146, 251], [-104, 146, 251], [-105, 147, 251], [-104, 147, 251],], [[-85, 146, 266], [-86, 146, 265], [-86, 147, 265], [-86, 147, 266], [-85, 146, 265], [-85, 147, 265], [-85, 147, 266], [-84, 145, 266], [-84, 146, 266], [-87, 148, 264], [-87, 148, 265], [-86, 148, 265], [-87, 149, 263], [-87, 149, 264], [-87, 149, 265], [-86, 149, 265], [-87, 150, 263], [-87, 150, 264],], [[90, 153, 402], [89, 152, 402], [89, 152, 403], [89, 153, 402], [89, 153, 403], [90, 152, 402], [90, 152, 403], [90, 154, 402], [91, 154, 402], [90, 155, 402], [91, 155, 402],], [[98, 152, 403], [98, 152, 402], [98, 153, 402], [99, 151, 403], [99, 152, 402], [99, 152, 403], [99, 153, 402], [99, 153, 403], [98, 154, 401], [98, 154, 402], [98, 155, 401], [98, 155, 402],], [[-58, 132, 415], [-59, 132, 415], [-59, 132, 416], [-59, 133, 415], [-59, 133, 416], [-58, 131, 415], [-58, 131, 416], [-58, 132, 416], [-58, 133, 415], [-58, 133, 416], [-57, 132, 416], [-59, 131, 417], [-59, 132, 417], [-59, 134, 415], [-58, 134, 415], [-59, 135, 414], [-59, 135, 415], [-58, 135, 415], [-59, 136, 414], [-59, 136, 415],], [[-59, 132, 409], [-60, 132, 408], [-60, 132, 409], [-60, 133, 408], [-60, 133, 409], [-59, 132, 408], [-59, 133, 408], [-59, 133, 409], [-58, 133, 409], [-60, 133, 407], [-59, 132, 407], [-59, 133, 407], [-60, 134, 408], [-60, 134, 409], [-59, 134, 408], [-59, 134, 409], [-59, 134, 410], [-58, 134, 409], [-58, 134, 410], [-59, 135, 409], [-59, 135, 410], [-58, 135, 409], [-58, 135, 410], [-58, 136, 410], [-58, 136, 411], [-58, 137, 410], [-58, 137, 411],], [[-64, 132, 416], [-64, 131, 416], [-64, 131, 417], [-64, 132, 417], [-63, 131, 416], [-63, 131, 417], [-63, 132, 416], [-63, 132, 417], [-63, 133, 416], [-63, 133, 417], [-63, 131, 418], [-63, 132, 418], [-62, 132, 417], [-62, 133, 417], [-63, 134, 417], [-62, 134, 417], [-61, 134, 417], [-62, 135, 417], [-61, 135, 417],],]; export const Veins = { glacite, peridot, umber, tungsten, aquamarine, onyx, citrine }; -export default Veins; diff --git a/modules/mining/GlowingMushroomMacro.js b/modules/mining/GlowingMushroomMacro.js index 92b2b586..1f75fbb5 100644 --- a/modules/mining/GlowingMushroomMacro.js +++ b/modules/mining/GlowingMushroomMacro.js @@ -5,13 +5,13 @@ // love it import { isDeveloperModeEnabled } from '../../utils/DeveloperModeState'; import { ModuleBase } from '../../utils/ModuleBase'; -import { manager } from '../../utils/SkyblockEvents'; -import { MacroState } from '../../utils/MacroState'; +import { registerSkyblockEvent } from '../../utils/SkyblockEvents'; +import { getModule } from '../../utils/MacroState'; import Pathfinder from '../../utils/pathfinder/PathFinder'; import { Rotations } from '../../utils/player/Rotations'; -import { Raytrace } from '../../utils/Raytrace'; -import { NukerUtils } from '../../utils/NukerUtils'; -import { Utils } from '../../utils/Utils'; +import { getVisiblePoint, isLineClear } from '../../utils/Raytrace'; +import { queueNuke } from '../../utils/NukerUtils'; +import { area } from '../../utils/Utils'; import { getTrackedGlowingMushrooms, isGlowingMushroomBlock } from '../visuals/GlowingMushroomESP'; import { ScheduleTask } from '../../utils/ScheduleTask'; @@ -61,7 +61,7 @@ class GlowingMushroomMacro extends ModuleBase { this.reachableCount = 0; this.blacklistedMushrooms = new Map(); this.on('tick', () => this.runLoop(this.loopToken)); - manager.subscribe('fasttravellocked', () => { + registerSkyblockEvent('fasttravellocked', () => { if (!this.enabled || !this.warpStartedAt) return; this.message("&cYou haven't unlocked the Glowing Mushroom Cave warp."); @@ -125,7 +125,7 @@ class GlowingMushroomMacro extends ModuleBase { } ensureEspEnabled() { - const espModule = MacroState.getModule('Glowing Mushroom ESP'); + const espModule = getModule('Glowing Mushroom ESP'); if (!espModule || espModule.enabled) return; this.autoEnabledEsp = true; @@ -135,7 +135,7 @@ class GlowingMushroomMacro extends ModuleBase { restoreEspState() { if (!this.autoEnabledEsp) return; - const espModule = MacroState.getModule('Glowing Mushroom ESP'); + const espModule = getModule('Glowing Mushroom ESP'); if (espModule?.enabled) espModule.toggle(false); this.autoEnabledEsp = false; } @@ -212,7 +212,7 @@ class GlowingMushroomMacro extends ModuleBase { } ensureFarmingIslands() { - if (Utils.area() === 'The Farming Islands') { + if (area() === 'The Farming Islands') { this.warpStartedAt = 0; return true; } @@ -399,7 +399,7 @@ class GlowingMushroomMacro extends ModuleBase { for (const target of targets) { if (!isGlowingMushroomBlock(target.x, target.y, target.z)) continue; - NukerUtils.nukeQueueAdd([target.x, target.y, target.z], 1); + queueNuke([target.x, target.y, target.z], 1); onDone(1); return; } @@ -475,12 +475,12 @@ class GlowingMushroomMacro extends ModuleBase { }; if (!this.isPointWithinReach(point, eye)) continue; - if (!Raytrace.isLineClear(eye.x(), eye.y(), eye.z(), point.x, point.y, point.z, mushroom.x, mushroom.y, mushroom.z)) continue; + if (!isLineClear(eye.x(), eye.y(), eye.z(), point.x, point.y, point.z, mushroom.x, mushroom.y, mushroom.z)) continue; return point; } - const fallback = Raytrace.getVisiblePoint(mushroom.x, mushroom.y, mushroom.z, true); + const fallback = getVisiblePoint(mushroom.x, mushroom.y, mushroom.z, true); if (!fallback) return null; const point = { x: fallback[0], y: fallback[1], z: fallback[2] }; diff --git a/modules/mining/LobbyHopper.js b/modules/mining/LobbyHopper.js index 91785b7f..ff89e698 100644 --- a/modules/mining/LobbyHopper.js +++ b/modules/mining/LobbyHopper.js @@ -1,6 +1,6 @@ import { ModuleBase } from '../../utils/ModuleBase'; import { Timer } from '../../utils/TimeUtils'; -import { Utils } from '../../utils/Utils'; +import { area, getDay } from '../../utils/Utils'; class LobbyHopper extends ModuleBase { constructor() { @@ -23,7 +23,7 @@ class LobbyHopper extends ModuleBase { this.on('step', () => { if (!this.enabled) return; - let isInCh = Utils.area() === 'Crystal Hollows'; + let isInCh = area() === 'Crystal Hollows'; if (this.said && !this.cooldown.hasPassed(3000)) return; @@ -33,7 +33,7 @@ class LobbyHopper extends ModuleBase { this.reset(); } else { - if (Utils.getDay() > this.maxDay) { + if (getDay() > this.maxDay) { this.message('Crystal Hollows day is too high! Warping to new lobby.'); ChatLib.command('is'); diff --git a/modules/mining/MiningBot.js b/modules/mining/MiningBot.js index eb4e901a..0ab9759e 100644 --- a/modules/mining/MiningBot.js +++ b/modules/mining/MiningBot.js @@ -1,16 +1,16 @@ import { BP, MCHand, Vec3d } from '../../utils/Constants'; -import { MathUtils } from '../../utils/Math'; -import { MiningUtils } from '../../utils/MiningUtils'; +import { calculateAbsoluteAngles, calculateAngles, getDistanceToPlayerEyes } from '../../utils/Math'; +import { getDrills, getMineTime, getMiningSpeed, getSpeedWithCold, refreshMiningStatsIfNeeded } from '../../utils/MiningUtils'; import { ModuleBase } from '../../utils/ModuleBase'; -import { NukerUtils } from '../../utils/NukerUtils'; -import { Raytrace } from '../../utils/Raytrace'; -import { manager } from '../../utils/SkyblockEvents'; -import { Utils } from '../../utils/Utils'; -import { Guis } from '../../utils/player/Inventory'; +import { nuke, queueNuke } from '../../utils/NukerUtils'; +import { isLineClear } from '../../utils/Raytrace'; +import { registerSkyblockEvent } from '../../utils/SkyblockEvents'; +import { getConfigFile } from '../../utils/Utils'; +import { setItemSlot } from '../../utils/player/Inventory'; import { Rotations } from '../../utils/player/Rotations'; -import { ServerInfo } from '../../utils/player/ServerInfo'; -import { TabListUtils } from '../../utils/TabListUtils'; -import { Mouse } from '../../utils/Ungrab'; +import { getTPS } from '../../utils/player/ServerInfo'; +import { getPickaxeAbilityStatus } from '../../utils/TabListUtils'; +import { regrab, ungrab } from '../../utils/Ungrab'; const ORTHO_FACE_AXES = { x: ['y', 'z'], @@ -253,7 +253,7 @@ class Bot extends ModuleBase { } }); - manager.subscribe('abilityready', () => { + registerSkyblockEvent('abilityready', () => { if (!this.enabled || this.refreshingMiningStats) return; this.resetTickCounters(); this.abilityFromChat = true; @@ -261,7 +261,7 @@ class Bot extends ModuleBase { if (this.DEBUG_MODE) this.message(`&a[DEBUG] abilityready → state=ABILITY, abilityFromChat=true`); }); - manager.subscribe('abilityused', () => { + registerSkyblockEvent('abilityused', () => { if (!this.enabled) return; if (this.ability === 'SpeedBoost') this.speedBoost = true; this.abilityFromChat = false; @@ -270,7 +270,7 @@ class Bot extends ModuleBase { if (this.DEBUG_MODE) this.message(`&e[DEBUG] abilityused → abilityFromChat=false, lastUse=${this.lastUse}`); }); - manager.subscribe('abilitygone', () => { + registerSkyblockEvent('abilitygone', () => { if (!this.enabled) return; this.speedBoost = false; this.abilityFromChat = false; @@ -279,7 +279,7 @@ class Bot extends ModuleBase { if (this.DEBUG_MODE) this.message(`&e[DEBUG] abilitygone → abilityFromChat=false, lastUse=${this.lastUse}`); }); - manager.subscribe('abilitycooldown', () => { + registerSkyblockEvent('abilitycooldown', () => { if (!this.enabled) return; this.lastUse = Date.now(); this.state = this.STATES.MINING; @@ -441,14 +441,14 @@ class Bot extends ModuleBase { ensureDrillEquipped(drill) { if (!drill || drill.slot === undefined || drill.slot === null) return false; if (Player.getHeldItemIndex() !== drill.slot) { - Guis.setItemSlot(drill.slot); + setItemSlot(drill.slot); return true; } return false; } loadAbilitySetting() { - const file = Utils.getConfigFile('miningstats.json'); + const file = getConfigFile('miningstats.json'); this.ability = file?.ability || null; } @@ -547,8 +547,8 @@ class Bot extends ModuleBase { const pos = [this.currentTarget.x, this.currentTarget.y, this.currentTarget.z]; if (fakeLookMode === 'Instant') { // Instant nuker might be bad dont use it - //NukerUtils.nuke(pos, this.totalTicks); - } else if (fakeLookMode === 'Queued') NukerUtils.nukeQueueAdd(pos, this.totalTicks); + //nuke(pos, this.totalTicks); + } else if (fakeLookMode === 'Queued') queueNuke(pos, this.totalTicks); this.nukedBlock = true; } } @@ -592,7 +592,7 @@ class Bot extends ModuleBase { if (this.SCAN_ONLY) return (this.state = this.STATES.MINING); const now = Date.now(); - const abilityStatus = TabListUtils.getPickaxeAbilityStatus(); + const abilityStatus = getPickaxeAbilityStatus(); if (this.DEBUG_MODE) { this.message( @@ -701,8 +701,8 @@ class Bot extends ModuleBase { if (!this.currentTarget) return; const tunnelMode = this.isTunnelMode(); - this.miningspeed = (tunnelMode ? MiningUtils.getSpeedWithCold() : MiningUtils.getMiningSpeed()) || 1; - this.totalTicks = MiningUtils.getMineTime(this.currentTarget, this.miningspeed, this.speedBoost) + this.glideDelay(); + this.miningspeed = (tunnelMode ? getSpeedWithCold() : getMiningSpeed()) || 1; + this.totalTicks = getMineTime(this.currentTarget, this.miningspeed, this.speedBoost) + this.glideDelay(); this.handleBreaking(blockName, fakeLookMode); @@ -1071,7 +1071,7 @@ class Bot extends ModuleBase { else if (fy > y + AIM_POINT_HI) fy = y + AIM_POINT_HI; } - if (Raytrace.isLineClear(eyeX, eyeY, eyeZ, tx, ty, tz, x, y, z)) { + if (isLineClear(eyeX, eyeY, eyeZ, tx, ty, tz, x, y, z)) { resultX = fx; resultY = fy; resultZ = fz; @@ -1136,7 +1136,7 @@ class Bot extends ModuleBase { else if (fy > y + AIM_POINT_HI) fy = y + AIM_POINT_HI; } - if (Raytrace.isLineClear(eyeX, eyeY, eyeZ, tx, ty, tz, x, y, z)) { + if (isLineClear(eyeX, eyeY, eyeZ, tx, ty, tz, x, y, z)) { resultX = fx; resultY = fy; resultZ = fz; @@ -1207,7 +1207,7 @@ class Bot extends ModuleBase { y: target.aimY ?? target.y + 0.5, z: target.aimZ ?? target.z + 0.5, }; - const { pitch } = MathUtils.calculateAbsoluteAngles(targetPoint); + const { pitch } = calculateAbsoluteAngles(targetPoint); return pitch <= -Math.abs(minUpwardPitchDeg); } @@ -1232,8 +1232,8 @@ class Bot extends ModuleBase { z: this.currentTarget.aimZ ?? this.currentTarget.z + 0.5, }; - const values = MathUtils.getDistanceToPlayerEyes(targetPoint); - const yaw = MathUtils.calculateAngles(targetPoint).yaw; + const values = getDistanceToPlayerEyes(targetPoint); + const yaw = calculateAngles(targetPoint).yaw; if (!this._movementHumanizer) { this._movementHumanizer = { @@ -1401,11 +1401,11 @@ class Bot extends ModuleBase { } glideDelay() { - return Math.max(0, 20 + this.ADDITIONAL_LAG_COMP - Math.trunc(ServerInfo.getTPS())); + return Math.max(0, 20 + this.ADDITIONAL_LAG_COMP - Math.trunc(getTPS())); } onEnable() { - this.drill = MiningUtils.getDrills()?.drill; + this.drill = getDrills()?.drill; if (!this.drill) { this.message('&cNo drill detected!'); this.toggle(false); @@ -1422,12 +1422,12 @@ class Bot extends ModuleBase { this.setCost(); if (!this.isParentManaged) { this.message('&aEnabled'); - Mouse.ungrab(); + ungrab(); this.manualScan = false; } this.allowScan = true; this.FOVPenalty = true; - MiningUtils.refreshMiningStatsIfNeeded(() => { + refreshMiningStatsIfNeeded(() => { if (!this.enabled || refreshToken !== this.miningStatsRefreshToken) return; this.loadAbilitySetting(); this.refreshingMiningStats = false; @@ -1439,7 +1439,7 @@ class Bot extends ModuleBase { onDisable() { if (!this.isParentManaged) { this.message('&cDisabled'); - Mouse.regrab(); + regrab(); } this.state = this.STATES.WAITING; diff --git a/modules/mining/Nuker.js b/modules/mining/Nuker.js index 8129e196..de6d4bd6 100644 --- a/modules/mining/Nuker.js +++ b/modules/mining/Nuker.js @@ -1,10 +1,10 @@ import { BP, BlockHitResult, Direction, MCHand, Vec3d } from '../../utils/Constants'; import { ModuleBase } from '../../utils/ModuleBase'; -import { NukerUtils } from '../../utils/NukerUtils'; +import { nukeQueue, queueNuke } from '../../utils/NukerUtils'; import { ServerboundUseItemOnPacket } from '../../utils/Packets'; -import { manager } from '../../utils/SkyblockEvents'; -import { Executor } from '../../utils/ThreadExecutor'; -import { TabListUtils } from '../../utils/TabListUtils'; +import { registerSkyblockEvent } from '../../utils/SkyblockEvents'; +import { executeAsync } from '../../utils/ThreadExecutor'; +import { getPickaxeAbilityStatus, stripTabFormatting } from '../../utils/TabListUtils'; import { v5Command } from '../../utils/V5Commands'; class NukerClass extends ModuleBase { @@ -126,12 +126,12 @@ class NukerClass extends ModuleBase { } } - Executor.execute(() => { + executeAsync(() => { const target = this.scanForBlock(); if (target) { const posArr = [target.getX(), target.getY(), target.getZ()]; - NukerUtils.nukeQueueAdd(posArr, delay); + queueNuke(posArr, delay); this.target = target; this.minedBlocks.set(this.posToString(target), this.tickCounter); @@ -149,12 +149,12 @@ class NukerClass extends ModuleBase { }); }); - manager.subscribe('abilityready', () => { + registerSkyblockEvent('abilityready', () => { if (!this.enabled || !this.usePickaxeAbility) return; this.abilityFromChat = true; }); - manager.subscribe('abilityused', () => { + registerSkyblockEvent('abilityused', () => { if (!this.enabled || !this.usePickaxeAbility) return; this.lastUse = Date.now(); this.abilityFromChat = false; @@ -203,7 +203,7 @@ class NukerClass extends ModuleBase { title: 'Status', data: { 'Target Mode': () => this.targetMode, - 'Blocks Queued': () => NukerUtils.nukeQueue.length, + 'Blocks Queued': () => nukeQueue.length, }, }, ]); @@ -278,7 +278,7 @@ class NukerClass extends ModuleBase { } isHoldingMiningTool() { - const heldName = TabListUtils.stripFormatting(Player.getHeldItem()?.getName?.() ?? ''); + const heldName = stripTabFormatting(Player.getHeldItem()?.getName?.() ?? ''); return this.REQUIRED_ITEMS.some((name) => heldName.includes(name)); } @@ -287,7 +287,7 @@ class NukerClass extends ModuleBase { if (!this.isHoldingMiningTool()) return false; const now = Date.now(); - const abilityStatus = TabListUtils.getPickaxeAbilityStatus(); + const abilityStatus = getPickaxeAbilityStatus(); return abilityStatus.includes('Available') || this.abilityFromChat || this.lastUse + this.ABILITY_COOLDOWN_MS < now; } @@ -350,4 +350,4 @@ class NukerClass extends ModuleBase { } } -export const Nuker = new NukerClass(); +new NukerClass(); diff --git a/modules/mining/OreMacro.js b/modules/mining/OreMacro.js index 638d00db..3fdd85b6 100644 --- a/modules/mining/OreMacro.js +++ b/modules/mining/OreMacro.js @@ -1,17 +1,17 @@ import { File, V5ConfigFile, Vec3d } from '../../utils/Constants'; import { getEtherwarpEyeCoords } from '../../utils/Etherwarp'; -import { MathUtils } from '../../utils/Math'; +import { angleToPlayer, blockCenter, distanceToPlayerPoint } from '../../utils/Math'; import { ModuleBase } from '../../utils/ModuleBase'; -import { Raytrace, visibilityChecker } from '../../utils/Raytrace'; -import { Router } from '../../utils/Router'; -import { manager } from '../../utils/SkyblockEvents'; -import { TabListUtils } from '../../utils/TabListUtils'; -import { Utils } from '../../utils/Utils'; +import { getLookingAt, getPlayerEyePosition, testPointVisibility } from '../../utils/Raytrace'; +import { getFilesInDir } from '../../utils/Router'; +import { registerSkyblockEvent } from '../../utils/SkyblockEvents'; +import { getPickaxeAbilityStatus } from '../../utils/TabListUtils'; +import { getConfigFile, writeConfigFile } from '../../utils/Utils'; import { v5Command } from '../../utils/V5Commands'; import { EtherwarpPathfinder } from '../../utils/pathfinder/EtherwarpPathfinder'; import { MiningBot } from './MiningBot'; -import { Guis } from '../../utils/player/Inventory'; -import { Keybind } from '../../utils/player/Keybinding'; +import { findItemInHotbar, setItemSlot } from '../../utils/player/Inventory'; +import { setKeysForStraightLineCoords } from '../../utils/player/Movement'; import { OreRotations } from '../../utils/player/OreRotations'; const MINE_REACH_SQ = 4.49 * 4.49; @@ -187,21 +187,21 @@ class OreMiner extends ModuleBase { this.on('tick', () => this.tick()); register('postRenderWorld', () => this.render()); - manager.subscribe('abilityready', () => { + registerSkyblockEvent('abilityready', () => { if (!this.routeActive) return; this.abilityFromChat = true; this.abilityAvailabilityConsumed = false; this.scheduleAbilityUseDelay(); }); - manager.subscribe('abilityused', () => { + registerSkyblockEvent('abilityused', () => { if (!this.routeActive) return; this.abilityFromChat = false; this.abilityAvailabilityConsumed = true; this.abilityUseReadyAt = 0; }); - manager.subscribe('abilitygone', () => { + registerSkyblockEvent('abilitygone', () => { if (!this.routeActive) return; this.abilityFromChat = false; this.abilityAvailabilityConsumed = true; @@ -300,7 +300,7 @@ class OreMiner extends ModuleBase { return this.message('&cAdd a waypoint first, or provide a valid waypoint index.'); } - const hit = Raytrace.getLookingAt(10); + const hit = getLookingAt(10); const pos = hit?.getPos?.(); if (!pos) return this.message('&cLook at a block within 10 blocks.'); @@ -361,7 +361,7 @@ class OreMiner extends ModuleBase { saveRoute(name) { const cleanName = sanitizeRouteName(name); if (!cleanName || !this.loadedWaypoints || !this.loadedWaypoints.length) return this.message('&cUsage: /v5 mining ore save '); - Utils.writeConfigFile(`${ROUTE_DIR_RELATIVE}/${cleanName}.json`, this.loadedWaypoints); + writeConfigFile(`${ROUTE_DIR_RELATIVE}/${cleanName}.json`, this.loadedWaypoints); this.loadedPath = String(new File(ORE_ROUTES_DIR, `${cleanName}.json`).getAbsolutePath()); this.undoStack = []; this.message(`&aSaved ${this.loadedWaypoints.length} waypoints as &f${cleanName}&a.`); @@ -390,7 +390,7 @@ class OreMiner extends ModuleBase { } listRoutes() { - const files = Router.getFilesInDir(ROUTE_DIR_RELATIVE); + const files = getFilesInDir(ROUTE_DIR_RELATIVE); this.message(`&bOre Miner Routes &7(${files.length})`); files.forEach((name) => this.message(` &f${name} &7- /v5 mining ore load ${name}`)); } @@ -404,7 +404,7 @@ class OreMiner extends ModuleBase { return false; } - const data = Utils.getConfigFile(`${ROUTE_DIR_RELATIVE}/${resolved.name}.json`); + const data = getConfigFile(`${ROUTE_DIR_RELATIVE}/${resolved.name}.json`); if (!data) { this.message(`&cCould not read route: &f${resolved.path}`); return false; @@ -545,7 +545,7 @@ class OreMiner extends ModuleBase { this.message('&cNo Aspect of the Void/End found in your hotbar.'); return this.toggle(false); } - Guis.setItemSlot(this.aotvSlot); + setItemSlot(this.aotvSlot); this.ensureShiftHeld(); this.teleportRetries = 0; this.teleportAimCandidates = []; @@ -569,7 +569,7 @@ class OreMiner extends ModuleBase { case 'TP_CLICK': if (Player.getHeldItemIndex() !== this.aotvSlot) { - Guis.setItemSlot(this.aotvSlot); + setItemSlot(this.aotvSlot); this.waitTicks = 0; return; } @@ -598,7 +598,7 @@ class OreMiner extends ModuleBase { case 'TP_RETRY_DELAY': if (++this.waitTicks >= this.retryDelay) { - Guis.setItemSlot(this.aotvSlot); + setItemSlot(this.aotvSlot); this.teleportAimCandidates = []; this.teleportAimIndex = 0; this.enterState('TP_ROTATE'); @@ -622,7 +622,7 @@ class OreMiner extends ModuleBase { Client.setKey('leftclick', false); if (waypoint.isDeployable && this.deployableWaypointsEnabled && !this.hasNearbyDeployable(waypoint.pos)) this.enterState('DEPLOYABLE'); else { - Guis.setItemSlot(this.drillSlot); + setItemSlot(this.drillSlot); Client.setKey('leftclick', true); this.enterState('MINE_NEXT'); } @@ -754,9 +754,9 @@ class OreMiner extends ModuleBase { const eye = { x: eyes.x(), y: eyes.y(), z: eyes.z() }; const aimPoint = this.teleportAimCandidates[this.teleportAimIndex]; if (aimPoint && !this.hasEtherwarpRayClearance(x, y, z, [aimPoint.x, aimPoint.y, aimPoint.z], eye)) return false; - const center = MathUtils.blockCenter(x, y, z); + const center = blockCenter(x, y, z); const distance = Math.min(61, Math.hypot(center.x - eyes.x(), center.y - eyes.y(), center.z - eyes.z()) + 0.25); - const pos = Raytrace.getLookingAt(distance)?.getPos?.(); + const pos = getLookingAt(distance)?.getPos?.(); return !!pos && pos.getX() === x && pos.getY() === y && pos.getZ() === z; } catch (error) { return false; @@ -765,7 +765,7 @@ class OreMiner extends ModuleBase { getStrafeAimPoint(waypoint) { const { x, y, z } = waypoint.pos; - const eye = visibilityChecker.getPlayerEyePosition(); + const eye = getPlayerEyePosition(); if (!eye) return { x: x + 0.5, y: y + 0.5, z: z + ETHERWARP_FACE_DEPTH }; const dx = eye.x - (x + 0.5); @@ -803,15 +803,15 @@ class OreMiner extends ModuleBase { return; } - Keybind.stopMovement(); - Keybind.setKey('shift', false); + Client.stopMovement(); + Client.setKey('shift', false); OreRotations.stop(); this.enterState('WAYPOINT'); return; } - Keybind.stopMovement(); - Keybind.setKey('shift', false); + Client.stopMovement(); + Client.setKey('shift', false); OreRotations.stop(); this.enterState('MINE_INIT'); return; @@ -820,9 +820,9 @@ class OreMiner extends ModuleBase { const previousWaypoint = this.loadedWaypoints[(this.waypointIndex - 1 + this.loadedWaypoints.length) % this.loadedWaypoints.length]; const intentionalDrop = previousWaypoint?.pos?.y > y; const nearEdge = !intentionalDrop && this.hasEdgeAhead(x, y, z); - Keybind.setKeysForStraightLineCoords(x, y, z, !nearEdge); - Keybind.setKey('shift', nearEdge); - Keybind.setKey('sprint', !nearEdge && dx * dx + dz * dz > 2); + setKeysForStraightLineCoords(x, y, z, !nearEdge); + Client.setKey('shift', nearEdge); + Client.setKey('sprint', !nearEdge && dx * dx + dz * dz > 2); this.waitTicks++; this.updateWalkWaypointLookAhead(); if (this.waitTicks >= 300) { @@ -841,7 +841,7 @@ class OreMiner extends ModuleBase { if (target.walkGuide) { Client.setKey('leftclick', false); - if (MathUtils.angleToPlayer(target.vector).distance <= 15) { + if (angleToPlayer(target.vector).distance <= 15) { OreRotations.stop(); return true; } @@ -852,20 +852,20 @@ class OreMiner extends ModuleBase { return true; } - const distance = MathUtils.distanceToPlayerPoint(target.vector); + const distance = distanceToPlayerPoint(target.vector); if (target.block && distance <= 5) { const aim = this.getMineAim(target.block); if (aim) { const canHoldMine = !target.block.oneTap && !target.block.rOneTap; if (target.sneakMine && canHoldMine) { this.ensureShiftHeld(); - Keybind.setKey('shift', true); + Client.setKey('shift', true); if (!Player.isSneaking()) { Client.setKey('leftclick', false); return OreRotations.trackVector(aim, this.oreMineSpeed); } } - if (canHoldMine && Player.getHeldItemIndex() !== this.drillSlot) Guis.setItemSlot(this.drillSlot); + if (canHoldMine && Player.getHeldItemIndex() !== this.drillSlot) setItemSlot(this.drillSlot); Client.setKey('leftclick', canHoldMine); return OreRotations.trackVector(aim, this.oreMineSpeed); } @@ -873,7 +873,7 @@ class OreMiner extends ModuleBase { Client.setKey('leftclick', false); const looseTolerance = (Math.atan2(1.5, Math.max(1, distance)) * 180) / Math.PI; - if (MathUtils.angleToPlayer(target.vector).distance <= looseTolerance) { + if (angleToPlayer(target.vector).distance <= looseTolerance) { OreRotations.stop(); return true; } @@ -890,7 +890,7 @@ class OreMiner extends ModuleBase { if (waypoint.type === 'Tp') { return { - vector: MathUtils.blockCenter(waypoint.pos.x, waypoint.pos.y, waypoint.pos.z), + vector: blockCenter(waypoint.pos.x, waypoint.pos.y, waypoint.pos.z), teleport: true, }; } @@ -899,14 +899,14 @@ class OreMiner extends ModuleBase { const deepDrop = Player.getY() - waypoint.pos.y >= 5; if (offset === 0 && deepDrop && block?.y < waypoint.pos.y) { return { - vector: MathUtils.blockCenter(waypoint.pos.x, waypoint.pos.y, waypoint.pos.z), + vector: blockCenter(waypoint.pos.x, waypoint.pos.y, waypoint.pos.z), walkGuide: true, }; } if (block) { return { block, - vector: MathUtils.blockCenter(block.x, block.y, block.z), + vector: blockCenter(block.x, block.y, block.z), sneakMine: block.y < waypoint.pos.y, }; } @@ -916,10 +916,10 @@ class OreMiner extends ModuleBase { } tickDeployable() { - if (this.waitTicks === 0) Guis.setItemSlot(this.deployableSlot); + if (this.waitTicks === 0) setItemSlot(this.deployableSlot); if (this.waitTicks === 2) Client.rightClick(); if (++this.waitTicks >= 4) { - Guis.setItemSlot(this.drillSlot); + setItemSlot(this.drillSlot); Client.setKey('leftclick', true); this.enterState('MINE_NEXT'); } @@ -981,7 +981,7 @@ class OreMiner extends ModuleBase { } this.ensureShiftHeld(); - OreRotations.trackVector(MathUtils.blockCenter(block.x, block.y, block.z), this.oreMineSpeed); + OreRotations.trackVector(blockCenter(block.x, block.y, block.z), this.oreMineSpeed); const aim = this.getMineAim(block); if (aim) { this.stopMiningStrafe(false); @@ -1002,7 +1002,7 @@ class OreMiner extends ModuleBase { } if (!Player.isSneaking()) return; - Keybind.setKeysForStraightLineCoords(this.mineStrafeTarget.x, Player.getY(), this.mineStrafeTarget.z, false); + setKeysForStraightLineCoords(this.mineStrafeTarget.x, Player.getY(), this.mineStrafeTarget.z, false); this.ensureShiftHeld(); } @@ -1019,7 +1019,7 @@ class OreMiner extends ModuleBase { this.mineStrafeTarget = target; this.strafedForBlock = true; this.ensureShiftHeld(); - OreRotations.trackVector(MathUtils.blockCenter(block.x, block.y, block.z), this.oreMineSpeed); + OreRotations.trackVector(blockCenter(block.x, block.y, block.z), this.oreMineSpeed); this.enterState('MINE_STRAFE'); return true; } @@ -1111,19 +1111,19 @@ class OreMiner extends ModuleBase { }; if (this.miningAbilityEnabled || this.abilityDrillSwapEnabled) { - const rodSlot = Guis.findItemInHotbar('rod'); + const rodSlot = findItemInHotbar('rod'); if (rodSlot >= 0) { - add(() => Guis.setItemSlot(rodSlot), 2); + add(() => setItemSlot(rodSlot), 2); add(() => Client.rightClick(), 4); } - add(() => Guis.setItemSlot(this.abilityDrillSwapEnabled ? this.abilityDrillSlot : this.drillSlot), 2); + add(() => setItemSlot(this.abilityDrillSwapEnabled ? this.abilityDrillSlot : this.drillSlot), 2); add(() => Client.rightClick(), 4); } add(() => { Client.setKey('leftclick', false); - Guis.setItemSlot(this.drillSlot); + setItemSlot(this.drillSlot); }, 2); add(() => Client.setKey('leftclick', true), 2); @@ -1139,7 +1139,7 @@ class OreMiner extends ModuleBase { } isMiningAbilityReady() { - const tabAvailable = TabListUtils.getPickaxeAbilityStatus().includes('Available'); + const tabAvailable = getPickaxeAbilityStatus().includes('Available'); if (tabAvailable && !this.abilityTabWasAvailable) { this.abilityAvailabilityConsumed = false; this.scheduleAbilityUseDelay(); @@ -1186,7 +1186,7 @@ class OreMiner extends ModuleBase { if (distance * distance > MINE_REACH_SQ) return null; const point = [eye.x, faceY, eye.z]; - if (!visibilityChecker.testPointCustom(block.x, block.y, block.z, point, eye)) return null; + if (!testPointVisibility(block.x, block.y, block.z, point, eye)) return null; return { x: eye.x, y: faceY, z: eye.z }; } @@ -1199,14 +1199,14 @@ class OreMiner extends ModuleBase { } raytraceVisiblePoints(x, y, z, eyeOverride = null, maxResults = Infinity, maxChecks = Infinity, startIndex = 0) { - const eye = eyeOverride || visibilityChecker.getPlayerEyePosition(); + const eye = eyeOverride || getPlayerEyePosition(); if (!eye) return []; const visible = []; const checks = Math.min(ETHERWARP_FACE_OFFSETS.length, maxChecks); for (let checked = 0; checked < checks; checked++) { const offset = ETHERWARP_FACE_OFFSETS[(startIndex + checked) % ETHERWARP_FACE_OFFSETS.length]; const point = [x + offset[0], y + offset[1], z + offset[2]]; - if (!visibilityChecker.testPointCustom(x, y, z, point, eye)) continue; + if (!testPointVisibility(x, y, z, point, eye)) continue; if (!this.hasEtherwarpRayClearance(x, y, z, point, eye)) continue; visible.push({ point: { x: point[0], y: point[1], z: point[2] } }); if (visible.length >= maxResults) break; @@ -1233,7 +1233,7 @@ class OreMiner extends ModuleBase { shifted[axis] += direction * ETHERWARP_RAY_CLEARANCE; const shiftedLocal = shifted[axis] - [x, y, z][axis]; if (shiftedLocal < ETHERWARP_EDGE_INSET || shiftedLocal > 1 - ETHERWARP_EDGE_INSET) return false; - if (!visibilityChecker.testPointCustom(x, y, z, shifted, eye)) return false; + if (!testPointVisibility(x, y, z, shifted, eye)) return false; } } return true; @@ -1259,7 +1259,7 @@ class OreMiner extends ModuleBase { const eye = { x: eyeCoords[0], y: eyeCoords[1], z: eyeCoords[2] }; const { x, y, z } = waypoint.pos; - const center = MathUtils.blockCenter(x, y, z); + const center = blockCenter(x, y, z); const dx = center.x - eye.x; const dz = center.z - eye.z; const length = Math.hypot(dx, dz); @@ -1283,9 +1283,9 @@ class OreMiner extends ModuleBase { findMiningStrafeTarget(x, y, z) { const crouchedEye = getEtherwarpEyeCoords(true); - const eye = crouchedEye ? { x: crouchedEye[0], y: crouchedEye[1], z: crouchedEye[2] } : visibilityChecker.getPlayerEyePosition(); + const eye = crouchedEye ? { x: crouchedEye[0], y: crouchedEye[1], z: crouchedEye[2] } : getPlayerEyePosition(); if (!eye) return null; - const center = MathUtils.blockCenter(x, y, z); + const center = blockCenter(x, y, z); const dx = center.x - eye.x; const dz = center.z - eye.z; const length = Math.hypot(dx, dz); @@ -1394,8 +1394,8 @@ class OreMiner extends ModuleBase { } stopMiningStrafe(releaseSneak = true) { - Keybind.stopMovement(); - if (releaseSneak) Keybind.setKey('shift', false); + Client.stopMovement(); + if (releaseSneak) Client.setKey('shift', false); this.mineStrafeTarget = null; OreRotations.stop(); } @@ -1437,4 +1437,4 @@ class OreMiner extends ModuleBase { } } -export default new OreMiner(); +new OreMiner(); diff --git a/modules/mining/PinglessMining.js b/modules/mining/PinglessMining.js index 6d852fa1..0de773c8 100644 --- a/modules/mining/PinglessMining.js +++ b/modules/mining/PinglessMining.js @@ -1,9 +1,9 @@ // Credits: Kash - MiningModules -import { MiningUtils } from '../../utils/MiningUtils'; +import { setGhostBlock } from '../../utils/MiningUtils'; import { ModuleBase } from '../../utils/ModuleBase'; import { ServerboundSwingPacket, ServerboundPlayerActionPacket } from '../../utils/Packets'; -import { Utils } from '../../utils/Utils'; +import { area } from '../../utils/Utils'; class Pingless extends ModuleBase { constructor() { @@ -19,7 +19,7 @@ class Pingless extends ModuleBase { this.tickCount = 0; this.on('packetSent', (packet) => { - if (Utils.area() !== 'Crystal Hollows') return; + if (area() !== 'Crystal Hollows') return; let action = packet?.getAction()?.toString(); if (action === 'START_DESTROY_BLOCK') { @@ -51,13 +51,13 @@ class Pingless extends ModuleBase { }).setFilteredClass(ServerboundPlayerActionPacket); this.on('packetSent', () => { - if (Utils.area() !== 'Crystal Hollows') return; + if (area() !== 'Crystal Hollows') return; if (!this.mining || !this.pos) return; if (this.tickCount > 0) { this.tickCount--; } else { - MiningUtils.GhostBlock(this.pos); + setGhostBlock(this.pos); this.mining = false; this.pos = null; } diff --git a/modules/mining/PowderMacro.js b/modules/mining/PowderMacro.js index 7c176932..8206735f 100644 --- a/modules/mining/PowderMacro.js +++ b/modules/mining/PowderMacro.js @@ -1,9 +1,9 @@ import { isDeveloperModeEnabled } from '../../utils/DeveloperModeState'; -import { MathUtils } from '../../utils/Math'; +import { wrapTo180 } from '../../utils/Math'; import { ModuleBase } from '../../utils/ModuleBase'; import { Rotations } from '../../utils/player/Rotations'; -import { RotationGCD } from '../../utils/player/RotationGCD'; -import { manager } from '../../utils/SkyblockEvents'; +import { angleDifference, applyToPlayer } from '../../utils/player/RotationGCD'; +import { registerSkyblockEvent } from '../../utils/SkyblockEvents'; const CHEST_BLOCK_IDS = new Set([54, 146]); const CHEST_SEARCH_RADIUS = 3; @@ -82,8 +82,8 @@ class PowderMacro extends ModuleBase { } registerSkyblockEvents() { - manager.subscribe('chestspawn', () => this.onChestSpawn()); - manager.subscribe('chestopen', () => this.onChestOpen()); + registerSkyblockEvent('chestspawn', () => this.onChestSpawn()); + registerSkyblockEvent('chestopen', () => this.onChestOpen()); } onChestSpawn() { @@ -92,7 +92,7 @@ class PowderMacro extends ModuleBase { if (!player) return; this.savedRotation = { - yaw: MathUtils.wrapTo180(player.getYRot()), + yaw: wrapTo180(player.getYRot()), pitch: player.getXRot(), }; @@ -127,7 +127,7 @@ class PowderMacro extends ModuleBase { Client.setKey('shift', true); this.pivot = { - yaw: MathUtils.wrapTo180(player.getYRot()), + yaw: wrapTo180(player.getYRot()), pitch: player.getXRot(), }; this.startTime = Date.now(); @@ -169,7 +169,7 @@ class PowderMacro extends ModuleBase { break; } } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } setTimeout(() => this.rotateLoop(token), TICK_INTERVAL_MS); @@ -185,7 +185,7 @@ class PowderMacro extends ModuleBase { const targetYaw = this.pivot.yaw + Math.cos(angle) * this.width; const targetPitch = Math.min(this.pivot.pitch + dPitch, this.maxPitch); - RotationGCD.applyToPlayer(targetYaw, targetPitch); + applyToPlayer(targetYaw, targetPitch); } tickChest() { @@ -205,10 +205,10 @@ class PowderMacro extends ModuleBase { const player = Player.getPlayer(); if (!player) return; - const current = { yaw: MathUtils.wrapTo180(player.getYRot()), pitch: player.getXRot() }; + const current = { yaw: wrapTo180(player.getYRot()), pitch: player.getXRot() }; const target = this.savedRotation ?? this.pivot; - const diffYaw = RotationGCD.angleDifference(target.yaw, current.yaw); + const diffYaw = angleDifference(target.yaw, current.yaw); const diffPitch = target.pitch - current.pitch; const distance = Math.hypot(diffYaw, diffPitch); @@ -216,7 +216,7 @@ class PowderMacro extends ModuleBase { this.syncLoopAngle(current); this.setState(State.MINING); } else { - RotationGCD.applyToPlayer(current.yaw + diffYaw * RETURN_SPEED, current.pitch + diffPitch * RETURN_SPEED); + applyToPlayer(current.yaw + diffYaw * RETURN_SPEED, current.pitch + diffPitch * RETURN_SPEED); } } diff --git a/modules/mining/ScathaMacro.js b/modules/mining/ScathaMacro.js index e9f2e67d..1b4b5215 100644 --- a/modules/mining/ScathaMacro.js +++ b/modules/mining/ScathaMacro.js @@ -1,9 +1,9 @@ import { isDeveloperModeEnabled } from '../../utils/DeveloperModeState'; import { ModuleBase } from '../../utils/ModuleBase'; -import { Guis } from '../../utils/player/Inventory'; -import { Utils } from '../../utils/Utils'; -import { manager } from '../../utils/SkyblockEvents'; -import { MiningUtils } from '../../utils/MiningUtils'; +import { clickSlot, closeInventory, findItemInHotbar, getGuiName, setItemSlot } from '../../utils/player/Inventory'; +import { area, getConfigFile } from '../../utils/Utils'; +import { registerSkyblockEvent } from '../../utils/SkyblockEvents'; +import { getDrills } from '../../utils/MiningUtils'; import Pathfinder from '../../utils/pathfinder/PathFinder'; import { Rotations } from '../../utils/player/Rotations'; @@ -102,12 +102,12 @@ class ScathaMacro extends ModuleBase { this.state = this.STATES.WAITING; - manager.subscribe('warp', () => { + registerSkyblockEvent('warp', () => { if (!this.enabled) return; this.isWarping = true; }); - manager.subscribe('fasttravellocked', () => { + registerSkyblockEvent('fasttravellocked', () => { if (!this.enabled) return; if (this.goingToCH) { this.message("&cCan't start macro outside CH because you dont have the warp!"); @@ -139,10 +139,10 @@ class ScathaMacro extends ModuleBase { } handleWarping() { - if (Utils.area() === 'Crystal Hollows') return (this.state = this.STATES.DIGGING); + if (area() === 'Crystal Hollows') return (this.state = this.STATES.DIGGING); if (this.isWarping && this.travelledToCH) return (this.goingToCH = true); - if (Utils.area() !== 'Crystal Hollows' && !this.travelledToCH) { + if (area() !== 'Crystal Hollows' && !this.travelledToCH) { ChatLib.command('warp ch'); this.travelledToCH = true; } @@ -167,7 +167,7 @@ class ScathaMacro extends ModuleBase { if (!this.handleAOTV.rotated) { this.handleAOTV.rotated = true; - Guis.setItemSlot(this.items.aspect); + setItemSlot(this.items.aspect); Rotations.lookAtAngles(Player.getYaw(), 90); Rotations.onComplete(() => { @@ -178,7 +178,7 @@ class ScathaMacro extends ModuleBase { if (!this.handleAOTV.usedAOTV) return; - Guis.setItemSlot(this.items.drill); + setItemSlot(this.items.drill); Client.setKey('leftclick', true); // check for chests @@ -197,7 +197,7 @@ class ScathaMacro extends ModuleBase { } if (this.applySet(this.MINING_SET)) { - Guis.closeInv(); + closeInventory(); this.state = this.STATES.DECIDEDIRECTION; return; } @@ -246,7 +246,7 @@ class ScathaMacro extends ModuleBase { togglePerks(isEnabling) { const container = Player.getContainer(); - if (Guis.guiName() !== 'Heart of the Mountain' || !container) { + if (getGuiName() !== 'Heart of the Mountain' || !container) { if (!this.HOTMState.opened) { ChatLib.command('hotm'); this.HOTMState.opened = true; @@ -268,7 +268,7 @@ class ScathaMacro extends ModuleBase { if (!item) continue; if (slot === 8) { - Guis.clickSlot(slot, false, 'RIGHT'); + clickSlot(slot, false, 'RIGHT'); this.lastActionTime = now; return false; } @@ -278,7 +278,7 @@ class ScathaMacro extends ModuleBase { const shouldClick = isEnabling ? isRedstone : !isRedstone; if (shouldClick) { - Guis.clickSlot(slot, false, 'RIGHT'); + clickSlot(slot, false, 'RIGHT'); this.lastActionTime = now; return false; } @@ -293,7 +293,7 @@ class ScathaMacro extends ModuleBase { } applySet(slot) { - if (Guis.guiName() !== 'Wardrobe (1/3)') return false; + if (getGuiName() !== 'Wardrobe (1/3)') return false; const now = Date.now(); if (now - this.lastActionTime < this.CLICK_DELAY) return false; @@ -313,15 +313,15 @@ class ScathaMacro extends ModuleBase { return true; } - Guis.clickSlot(targetSlot, false, 'LEFT'); + clickSlot(targetSlot, false, 'LEFT'); this.lastActionTime = now; return true; } getAllRequiredItems() { const items = { - 'Aspect of the Void': { slot: Guis.findItemInHotbar('Aspect of the Void'), include: true }, - 'Mining Tool': { slot: MiningUtils.getDrills().drill?.slot ?? -1, include: null }, + 'Aspect of the Void': { slot: findItemInHotbar('Aspect of the Void'), include: true }, + 'Mining Tool': { slot: getDrills().drill?.slot ?? -1, include: null }, }; this.items.aspect = items['Aspect of the Void'].slot; @@ -338,7 +338,7 @@ class ScathaMacro extends ModuleBase { } hasMaxGE() { - if (Utils.getConfigFile('miningstats.json')?.maxge !== true) { + if (getConfigFile('miningstats.json')?.maxge !== true) { this.message("&cYou don't have max GE!"); this.toggle(false); return false; diff --git a/modules/mining/TunnelsMiner.js b/modules/mining/TunnelsMiner.js index 8bb6fbc2..2ac3235a 100644 --- a/modules/mining/TunnelsMiner.js +++ b/modules/mining/TunnelsMiner.js @@ -1,6 +1,6 @@ import { isDeveloperModeEnabled } from '../../utils/DeveloperModeState'; import { Vec3d } from '../../utils/Constants'; -import { MiningUtils } from '../../utils/MiningUtils'; +import { getDebuff } from '../../utils/MiningUtils'; import { ModuleBase } from '../../utils/ModuleBase'; import { EtherwarpPathfinder } from '../../utils/pathfinder/EtherwarpPathfinder'; import Pathfinder from '../../utils/pathfinder/PathFinder'; @@ -148,7 +148,7 @@ class TunnelsMiner extends ModuleBase { } handleCold() { - const cold = MiningUtils.getDebuff('cold'); + const cold = getDebuff('cold'); if (!this.waitingForCold && cold <= this.coldThreshold) return false; if (cold === 0) { this.waitingForCold = false; diff --git a/modules/other/AuctionHelper.js b/modules/other/AuctionHelper.js index 69c4d1a3..154438e2 100644 --- a/modules/other/AuctionHelper.js +++ b/modules/other/AuctionHelper.js @@ -1,5 +1,5 @@ import { ModuleBase } from '../../utils/ModuleBase'; -import { Guis } from '../../utils/player/Inventory'; +import { clickItem, getGuiName } from '../../utils/player/Inventory'; class AuctionHelper extends ModuleBase { constructor() { @@ -25,21 +25,21 @@ class AuctionHelper extends ModuleBase { } onTick() { - const guiName = Guis.guiName(); + const guiName = getGuiName(); if (this.auto2Day) { - if (guiName === 'Create BIN Auction' && Guis.clickItem('Duration: 6 Hours', false, 'LEFT', true, true)) { + if (guiName === 'Create BIN Auction' && clickItem('Duration: 6 Hours', false, 'LEFT', true, true)) { this.selectingDuration = true; - } else if (this.selectingDuration && Guis.clickItem('2 Days', false, 'LEFT', true, true)) { + } else if (this.selectingDuration && clickItem('2 Days', false, 'LEFT', true, true)) { this.selectingDuration = false; } } if (!this.quickCreate) return; if (guiName === 'Confirm BIN Auction') { - if (Guis.clickItem('Confirm BIN Auction', false, 'LEFT', true, true)) this.lastBinConfirmAt = Date.now(); + if (clickItem('Confirm BIN Auction', false, 'LEFT', true, true)) this.lastBinConfirmAt = Date.now(); } else if (guiName === 'BIN Auction View' && Date.now() - this.lastBinConfirmAt < 1000) { - Guis.clickItem('Go Back', false, 'LEFT', true, true); + clickItem('Go Back', false, 'LEFT', true, true); } } } diff --git a/modules/other/AutoCombine.js b/modules/other/AutoCombine.js index cc2fefdd..e654cd87 100644 --- a/modules/other/AutoCombine.js +++ b/modules/other/AutoCombine.js @@ -1,5 +1,5 @@ import { ModuleBase } from '../../utils/ModuleBase'; -import { Guis } from '../../utils/player/Inventory'; +import { clickSlot, closeInventory } from '../../utils/player/Inventory'; const BASE_BOOK_LEVELS = ['I', 'II', 'III', 'IV']; const EXTENDED_BOOK_LEVELS = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X']; @@ -91,7 +91,7 @@ class AutoCombine extends ModuleBase { const pair = this.findNextCombinePair(); if (!pair) { this.message('No combineable pair found'); - Guis.closeInv(); + closeInventory(); this.toggle(false); return; } @@ -109,7 +109,7 @@ class AutoCombine extends ModuleBase { return; } - Guis.clickSlot(firstSlot, true); + clickSlot(firstSlot, true); this.setState(this.STATES.SECOND_BOOK); } @@ -122,7 +122,7 @@ class AutoCombine extends ModuleBase { return; } - Guis.clickSlot(secondSlot, true); + clickSlot(secondSlot, true); this.setState(this.STATES.COMBINE_BOOKS); } @@ -133,7 +133,7 @@ class AutoCombine extends ModuleBase { const combineItem = items[22]; if (!combineItem?.getLore()?.join('')?.includes('Cost')) return this.timeout(); - Guis.clickSlot(22); + clickSlot(22); this.setState(this.STATES.EXTRACT_BOOK); } @@ -145,7 +145,7 @@ class AutoCombine extends ModuleBase { if (!extractItem) return this.timeout(); if (!items[22]?.getLore()?.join('')?.includes('Claim the result')) return this.timeout(); - Guis.clickSlot(13, true); + clickSlot(13, true); this.reset(); } @@ -215,7 +215,7 @@ class AutoCombine extends ModuleBase { this.second = null; this.tickCounter = 0; this.setState(this.STATES.OPEN_ANVIL); - if (close) Guis.closeInv(); + if (close) closeInventory(); } onEnable() { diff --git a/modules/other/AutoConversation.js b/modules/other/AutoConversation.js index 772936a3..8c8729c4 100644 --- a/modules/other/AutoConversation.js +++ b/modules/other/AutoConversation.js @@ -29,7 +29,7 @@ class AutoConversation extends ModuleBase { try { value = clickEvent.command(); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } if (value) commands.push(value); diff --git a/modules/other/AutoFusionRepeat.js b/modules/other/AutoFusionRepeat.js index a0189e8f..f495002f 100644 --- a/modules/other/AutoFusionRepeat.js +++ b/modules/other/AutoFusionRepeat.js @@ -1,5 +1,5 @@ import { ModuleBase } from '../../utils/ModuleBase'; -import { Guis } from '../../utils/player/Inventory'; +import { clickItem } from '../../utils/player/Inventory'; class AutoFusionRepeat extends ModuleBase { constructor() { @@ -12,8 +12,8 @@ class AutoFusionRepeat extends ModuleBase { this.bindToggleKey(); this.on('tick', () => { - if (Guis.clickItem('Repeat Previous Fusion', false, 'LEFT', true, true)) return; - Guis.clickItem('Fusion', false, 'LEFT', true, true); + if (clickItem('Repeat Previous Fusion', false, 'LEFT', true, true)) return; + clickItem('Fusion', false, 'LEFT', true, true); }); } } diff --git a/modules/other/BeachBaller.js b/modules/other/BeachBaller.js index 33279bee..23101594 100644 --- a/modules/other/BeachBaller.js +++ b/modules/other/BeachBaller.js @@ -1,11 +1,11 @@ import { OverlayManager } from '../../gui/OverlayUtils'; import { ArmorStandEntity, Vec3d } from '../../utils/Constants'; -import { MathUtils } from '../../utils/Math'; +import { calculateDistance, getDistanceToPlayer } from '../../utils/Math'; import { ModuleBase } from '../../utils/ModuleBase'; -import { Guis } from '../../utils/player/Inventory'; -import { Movement } from '../../utils/player/Movement'; +import { findItemInHotbar, setItemSlot } from '../../utils/player/Inventory'; +import { setKeysForStraightLineCoords } from '../../utils/player/Movement'; import { ScheduleTask } from '../../utils/ScheduleTask'; -import { Mouse } from '../../utils/Ungrab'; +import { regrab, ungrab } from '../../utils/Ungrab'; const SMALL_BEACHBALL_BASE64 = 'ewogICJ0aW1lc3RhbXAiIDogMTczNjQyNzQ4ODAwNCwKICAicHJvZmlsZUlkIiA6ICIzN2JhNjRkYzkxOTg0OGI4YjZhNDdiYTg0ZDgwNDM3MCIsCiAgInByb2ZpbGVOYW1lIiA6ICJTb3lLb3NhIiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzJhZGY5ZDcxMzY3Y2Q2ZTUwNWZiNDhjYWFhNWFjZGNkZmYyYTA5ZjY2YzQ4OGRhZjA0ZDA0NWVlMGJmNTI4ZTEiLAogICAgICAibWV0YWRhdGEiIDogewogICAgICAgICJtb2RlbCIgOiAic2xpbSIKICAgICAgfQogICAgfQogIH0KfQ=='; @@ -332,12 +332,12 @@ class Beachballer extends ModuleBase { const ballY = this.trackedBall.getY(); const playerPos = [Player.getX(), Player.getY(), Player.getZ()]; - const distance = MathUtils.calculateDistance(playerPos, [dx, ballY, dz]); + const distance = calculateDistance(playerPos, [dx, ballY, dz]); Client.setKey('shift', this.holdShift); if (distance.distanceFlat > 0.5) { - Movement.setKeysForStraightLineCoords(dx, ballY, dz); + setKeysForStraightLineCoords(dx, ballY, dz); } if (distance.distanceFlat < 0.2) { Client.stopMovement(); @@ -356,7 +356,7 @@ class Beachballer extends ModuleBase { this.trackedBall = null; const playerPos = [Player.getX(), Player.getY(), Player.getZ()]; - const distanceToStart = MathUtils.calculateDistance(playerPos, this.startPos); + const distanceToStart = calculateDistance(playerPos, this.startPos); if (distanceToStart.distance < 2) { Client.rightClick(); @@ -364,7 +364,7 @@ class Beachballer extends ModuleBase { return; } - Movement.setKeysForStraightLineCoords(this.startPos[0], this.startPos[1], this.startPos[2]); + setKeysForStraightLineCoords(this.startPos[0], this.startPos[1], this.startPos[2]); } handlePlaceState() { @@ -380,14 +380,14 @@ class Beachballer extends ModuleBase { } } - const ballSlot = Guis.findItemInHotbar('Bouncy Beach Ball'); + const ballSlot = findItemInHotbar('Bouncy Beach Ball'); if (ballSlot === -1) { this.message('&cNo bouncy balls in hotbar!'); this.toggle(false); return; } - Guis.setItemSlot(ballSlot); + setItemSlot(ballSlot); this.tickCounter++; if (this.tickCounter % 10 === 0) { @@ -404,7 +404,7 @@ class Beachballer extends ModuleBase { const ey = element.getY(); const ez = element.getZ(); - const distance = MathUtils.getDistanceToPlayer(ex, ey, ez).distance; + const distance = getDistanceToPlayer(ex, ey, ez).distance; if (distance > radius) continue; const headItem = element.getStackInSlot(5); @@ -427,7 +427,7 @@ class Beachballer extends ModuleBase { return data.includes(SMALL_BEACHBALL_BASE64) || data.includes(LARGE_BEACHBALL_BASE64); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); return false; } } @@ -462,7 +462,7 @@ class Beachballer extends ModuleBase { this.ballDescending = false; this.lastVelocityY = 0; this.hasActiveRun = false; - Mouse.ungrab(); + ungrab(); this.message('&aEnabled'); } @@ -475,7 +475,7 @@ class Beachballer extends ModuleBase { this.predictedPath = []; this.landingPoint = null; this.ballDescending = false; - Mouse.regrab(); + regrab(); this.message('&cDisabled'); } } diff --git a/modules/other/DiscordIntegration.js b/modules/other/DiscordIntegration.js index 25077952..f8e09c0f 100644 --- a/modules/other/DiscordIntegration.js +++ b/modules/other/DiscordIntegration.js @@ -1,7 +1,7 @@ import { Categories } from '../../gui/categories/CategorySystem'; -import { MacroState } from '../../utils/MacroState'; +import { getEnabledMacros, getLastDisableMeta, getModule, getModuleDuration, getModuleStartTime } from '../../utils/MacroState'; import { ModuleBase } from '../../utils/ModuleBase'; -import { Webhook } from '../../utils/Webhooks'; +import { getWebhookData, sendScreenshot, setFailsafeEmbedsEnabled, setLoadEmbedsEnabled, setWebhook, setWebhookUserId } from '../../utils/Webhooks'; class DiscordIntegration extends ModuleBase { constructor() { @@ -17,7 +17,7 @@ class DiscordIntegration extends ModuleBase { this.lastSendTime = 0; this.lastActiveMacro = null; - const settings = Webhook.getData() || {}; + const settings = getWebhookData() || {}; this.URL = String(settings.url ?? ''); this.ID = String(settings.userId ?? '').trim(); @@ -37,7 +37,7 @@ class DiscordIntegration extends ModuleBase { Categories.addSettingsToggle( 'Send Embed on CT load', - (v) => Webhook.sendLoadEmbeds(!!v), + (v) => setLoadEmbedsEnabled(!!v), 'Sends an embed to your webhook when CT loads', true, this.sectionName, @@ -63,7 +63,7 @@ class DiscordIntegration extends ModuleBase { 'Failsafe Embeds', (v) => { this.FAILSAFE_EMBEDS = !!v; - Webhook.sendFailsafeEmbeds(this.FAILSAFE_EMBEDS); + setFailsafeEmbedsEnabled(this.FAILSAFE_EMBEDS); }, 'Sends failsafe embeds and screenshots to your webhook', true, @@ -97,14 +97,14 @@ class DiscordIntegration extends ModuleBase { if (!currentMacro || !this.MACRO_EMBEDS) return (this.lastSendTime = 0); if (this.lastActiveMacro && this.lastActiveMacro !== currentMacro) { - const stillEnabled = MacroState.getEnabledMacros().includes(this.lastActiveMacro); + const stillEnabled = getEnabledMacros().includes(this.lastActiveMacro); if (!stillEnabled) this.trySendDisableEmbed(this.lastActiveMacro); this.lastSendTime = 0; } this.lastActiveMacro = currentMacro; - const startTime = MacroState.getModuleStartTime(currentMacro); + const startTime = getModuleStartTime(currentMacro); if (!startTime) return; const now = Date.now(); @@ -121,24 +121,24 @@ class DiscordIntegration extends ModuleBase { } trySendDisableEmbed(macroName) { - const meta = MacroState.getLastDisableMeta(macroName); + const meta = getLastDisableMeta(macroName); if (meta && meta.context === 'scheduler') return; this.sendDisableEmbed(macroName); } sendDisableEmbed(macroName) { - Webhook.sendScreenshot(`Disabled ${macroName}`, MacroState.getModuleDuration(macroName)); + sendScreenshot(`Disabled ${macroName}`, getModuleDuration(macroName)); } sendIntervalEmbed(macroName) { if (!macroName) return; - const duration = MacroState.getModuleDuration(macroName); - Webhook.sendScreenshot(`Update of ${macroName}`, duration ? `**Runtime:** ${duration}` : ''); + const duration = getModuleDuration(macroName); + sendScreenshot(`Update of ${macroName}`, duration ? `**Runtime:** ${duration}` : ''); } getActiveMacro() { - return MacroState.getEnabledMacros().find((name) => { - const mod = MacroState.getModule(name); + return getEnabledMacros().find((name) => { + const mod = getModule(name); return mod && !mod.isParentManaged; }); } @@ -152,7 +152,7 @@ class DiscordIntegration extends ModuleBase { if (!valid) return this.message('&cInvalid Discord webhook format.'); this.URL = trimmed; - Webhook.setWebhook(trimmed); + setWebhook(trimmed); this.message('&aDiscord webhook endpoint updated.'); } @@ -160,7 +160,7 @@ class DiscordIntegration extends ModuleBase { const trimmed = String(id ?? '').trim(); if (trimmed === String(this.ID ?? '').trim()) return; this.ID = trimmed; - Webhook.setUserId(trimmed); + setWebhookUserId(trimmed); this.message('&aDiscord webhook ID updated.'); } } diff --git a/modules/other/DiscordRPC.js b/modules/other/DiscordRPC.js index 017222f5..d83ecbeb 100644 --- a/modules/other/DiscordRPC.js +++ b/modules/other/DiscordRPC.js @@ -1,7 +1,7 @@ import { Categories } from '../../gui/categories/CategorySystem'; -import { MacroState } from '../../utils/MacroState'; +import { getActiveMacro, isMacroRunning } from '../../utils/MacroState'; import { ModuleBase } from '../../utils/ModuleBase'; -import { Utils } from '../../utils/Utils'; +import { area } from '../../utils/Utils'; class RPC extends ModuleBase { constructor() { @@ -25,17 +25,17 @@ class RPC extends ModuleBase { if (Date.now() - this.lastUpdate < 1000) return; this.lastUpdate = Date.now(); - if (MacroState.isMacroRunning()) { - const macroName = MacroState.getActiveMacro() || 'Unknown Macro'; + if (isMacroRunning()) { + const macroName = getActiveMacro() || 'Unknown Macro'; if (this.lastState !== 'RUNNING') { DiscordRPC.resetTimestamp(); this.lastState = 'RUNNING'; } - const area = Utils.area() || 'Unknown Area'; + const areaName = area() || 'Unknown Area'; - DiscordRPC.updatePresence(`Macroing: ${macroName}`, `Location: ${area}`); + DiscordRPC.updatePresence(`Macroing: ${macroName}`, `Location: ${areaName}`); } else { if (this.lastState !== 'IDLE') { DiscordRPC.revertToIdle(); diff --git a/modules/other/Failsafes.js b/modules/other/Failsafes.js index 9c55bbe6..0ee43101 100644 --- a/modules/other/Failsafes.js +++ b/modules/other/Failsafes.js @@ -3,8 +3,8 @@ import { getSetting } from '../../gui/GuiSave'; import { File, globalAssetsDir } from '../../utils/Constants'; import { ModuleBase } from '../../utils/ModuleBase'; import { ClientboundDisconnectPacket, ClientboundLoginDisconnectPacket } from '../../utils/Packets'; -import { MacroState } from '../../utils/MacroState'; -import { TimeUtils } from '../../utils/TimeUtils'; +import { getLastActiveMacros, getLastDisableMeta, getStartTime, isMacroRunning } from '../../utils/MacroState'; +import { formatUptime } from '../../utils/TimeUtils'; const JURL = Java.type('java.net.URL'); const JOutputStreamWriter = Java.type('java.io.OutputStreamWriter'); @@ -155,16 +155,16 @@ class Failsafes extends ModuleBase { conn.setRequestProperty('Authorization', `Bearer ${jwt}`); conn.setRequestProperty('Content-Type', 'application/json; charset=UTF-8'); - const lastMacros = MacroState.getLastActiveMacros(); - const lastMacroMeta = MacroState.getLastDisableMeta(lastMacros[0]); + const lastMacros = getLastActiveMacros(); + const lastMacroMeta = getLastDisableMeta(lastMacros[0]); const lastDisableTimestamp = lastMacroMeta?.timestamp; const within5Minutes = typeof lastDisableTimestamp === 'number' && Date.now() - lastDisableTimestamp <= 5 * 60 * 1000; const body = JSON.stringify({ reason, lastMacro: lastMacros.join(', ') || 'None', - currentlyMacroing: MacroState.isMacroRunning() || within5Minutes, - macroRuntime: MacroState.isMacroRunning() ? TimeUtils.formatUptime(MacroState.getStartTime()) : null, + currentlyMacroing: isMacroRunning() || within5Minutes, + macroRuntime: isMacroRunning() ? formatUptime(getStartTime()) : null, ingame_username: Player?.getName?.() || 'unknown', config_contents: this.getConfigFileContents(), installed_mods: new File('./mods').listFiles().join('\n'), @@ -216,4 +216,4 @@ class Failsafes extends ModuleBase { } } -export default new Failsafes(); +new Failsafes(); diff --git a/modules/other/Freecam.js b/modules/other/Freecam.js index 65d2bd21..90b604ff 100644 --- a/modules/other/Freecam.js +++ b/modules/other/Freecam.js @@ -1,10 +1,10 @@ import { GLFW, Vec3d } from '../../utils/Constants'; -import { Camera } from '../../utils/Camera'; -import { Mixin } from '../../utils/MixinManager'; +import { clearCameraPosition, setCameraPosition } from '../../utils/Camera'; +import { deleteMixinValue, getMixinValue, setMixinValue } from '../../utils/MixinManager'; import { ModuleBase } from '../../utils/ModuleBase'; -import { MathUtils } from '../../utils/Math'; -import { MacroState } from '../../utils/MacroState'; -import { Mouse } from '../../utils/Ungrab'; +import { wrapTo180 } from '../../utils/Math'; +import { getModule } from '../../utils/MacroState'; +import { forceGrab, releaseForcedGrab } from '../../utils/Ungrab'; import { mc } from '../../utils/Utils'; const Perspective = net.minecraft.client.CameraType; @@ -54,21 +54,21 @@ class Freecam extends ModuleBase { this.resetCameraState(); return; } - MacroState.getModule('Freelook')?.toggle(false); + getModule('Freelook')?.toggle(false); this.message('&aEnabled &7(Right-click an entity to spectate)'); - this.cameraPos = this.getInitialCameraPos(player, MathUtils.wrapTo180(player.getYRot()), player.getXRot()); + this.cameraPos = this.getInitialCameraPos(player, wrapTo180(player.getYRot()), player.getXRot()); this.velocity = new Vec3d(0, 0, 0); this.savedPerspective = mc.options.getCameraType(); this.lastRenderAt = Date.now(); this.possessedUUID = null; this.rightClickWasDown = this.isRightClickDown(); - Mouse.forceGrab(); - Mixin.set('cameraOverrideYaw', MathUtils.wrapTo180(player.getYRot())); - Mixin.set('cameraOverridePitch', player.getXRot()); - Mixin.set('freecamEnabled', true); + forceGrab(); + setMixinValue('cameraOverrideYaw', wrapTo180(player.getYRot())); + setMixinValue('cameraOverridePitch', player.getXRot()); + setMixinValue('freecamEnabled', true); mc.setCameraEntity(player); mc.options.setCameraType(Perspective.THIRD_PERSON_BACK); - Camera.setCameraPosition(this.cameraPos); + setCameraPosition(this.cameraPos); mc.levelRenderer.allChanged(); } @@ -76,7 +76,7 @@ class Freecam extends ModuleBase { this.message('&cDisabled'); this.resetCameraState(); if (World.isLoaded()) mc.levelRenderer.allChanged(); - Mouse.releaseForcedGrab(); + releaseForcedGrab(); } resetCameraState() { @@ -87,12 +87,12 @@ class Freecam extends ModuleBase { this.velocity = new Vec3d(0, 0, 0); this.possessedUUID = null; this.rightClickWasDown = false; - Mixin.set('ungrabbed', false); - Mixin.set('freecamEnabled', false); - Mixin.delete('freecamSpectatedEntity'); - Mixin.delete('cameraOverrideYaw'); - Mixin.delete('cameraOverridePitch'); - Camera.clearCameraPosition(); + setMixinValue('ungrabbed', false); + setMixinValue('freecamEnabled', false); + deleteMixinValue('freecamSpectatedEntity'); + deleteMixinValue('cameraOverrideYaw'); + deleteMixinValue('cameraOverridePitch'); + clearCameraPosition(); if (this.savedPerspective) mc.options.setCameraType(this.savedPerspective); this.savedPerspective = null; @@ -109,7 +109,7 @@ class Freecam extends ModuleBase { if (!player) return; if (!this.cameraPos) { - this.cameraPos = this.getInitialCameraPos(player, MathUtils.wrapTo180(player.getYRot()), player.getXRot()); + this.cameraPos = this.getInitialCameraPos(player, wrapTo180(player.getYRot()), player.getXRot()); } if (mc.options.getCameraType() !== Perspective.THIRD_PERSON_BACK) { @@ -117,7 +117,7 @@ class Freecam extends ModuleBase { } const options = mc.options; - const yaw = (Number(Mixin.get('cameraOverrideYaw', player.getYRot())) * Math.PI) / 180; + const yaw = (Number(getMixinValue('cameraOverrideYaw', player.getYRot())) * Math.PI) / 180; let moveX = 0; let moveY = 0; @@ -165,7 +165,7 @@ class Freecam extends ModuleBase { if (Math.hypot(this.velocity.x(), this.velocity.y(), this.velocity.z()) < 0.0005) { this.velocity = new Vec3d(0, 0, 0); - Camera.setCameraPosition(this.cameraPos); + setCameraPosition(this.cameraPos); return; } @@ -174,7 +174,7 @@ class Freecam extends ModuleBase { this.cameraPos.y() + this.velocity.y() * frames, this.cameraPos.z() + this.velocity.z() * frames ); - Camera.setCameraPosition(this.cameraPos); + setCameraPosition(this.cameraPos); } tryPossessPlayer() { @@ -183,8 +183,8 @@ class Freecam extends ModuleBase { this.possessedUUID = target.getUUID(); this.velocity = new Vec3d(0, 0, 0); - Mixin.set('ungrabbed', true); - Mixin.set('freecamSpectatedEntity', target.toMC()); + setMixinValue('ungrabbed', true); + setMixinValue('freecamSpectatedEntity', target.toMC()); this.syncPossessedCamera(); this.message(`&aSpectating &f${target.getName()} &7(Right-click to release)`); } @@ -194,18 +194,18 @@ class Freecam extends ModuleBase { if (entity) { const partialTicks = mc.getDeltaTracker().getGameTimeDeltaPartialTick(false); this.cameraPos = entity.getEyePosition(partialTicks); - Mixin.set('cameraOverrideYaw', entity.getViewYRot(partialTicks)); - Mixin.set('cameraOverridePitch', entity.getViewXRot(partialTicks)); + setMixinValue('cameraOverrideYaw', entity.getViewYRot(partialTicks)); + setMixinValue('cameraOverridePitch', entity.getViewXRot(partialTicks)); } this.possessedUUID = null; this.velocity = new Vec3d(0, 0, 0); - Mixin.set('ungrabbed', false); - Mixin.delete('freecamSpectatedEntity'); - Mouse.forceGrab(); + setMixinValue('ungrabbed', false); + deleteMixinValue('freecamSpectatedEntity'); + forceGrab(); mc.setCameraEntity(Player.getPlayer()); mc.options.setCameraType(Perspective.THIRD_PERSON_BACK); - if (this.cameraPos) Camera.setCameraPosition(this.cameraPos); + if (this.cameraPos) setCameraPosition(this.cameraPos); if (!silent) this.message('&7Released spectating'); } @@ -220,9 +220,9 @@ class Freecam extends ModuleBase { const partialTicks = mc.getDeltaTracker().getGameTimeDeltaPartialTick(false); this.cameraPos = entity.getEyePosition(partialTicks); mc.options.setCameraType(Perspective.FIRST_PERSON); - Camera.setCameraPosition(this.cameraPos); - Mixin.set('cameraOverrideYaw', entity.getViewYRot(partialTicks)); - Mixin.set('cameraOverridePitch', entity.getViewXRot(partialTicks)); + setCameraPosition(this.cameraPos); + setMixinValue('cameraOverrideYaw', entity.getViewYRot(partialTicks)); + setMixinValue('cameraOverridePitch', entity.getViewXRot(partialTicks)); } getPossessedPlayer() { @@ -233,8 +233,8 @@ class Freecam extends ModuleBase { getPlayerUnderCrosshair() { if (!this.cameraPos) return null; - const yaw = Number(Mixin.get('cameraOverrideYaw', 0)); - const pitch = Number(Mixin.get('cameraOverridePitch', 0)); + const yaw = Number(getMixinValue('cameraOverrideYaw', 0)); + const pitch = Number(getMixinValue('cameraOverridePitch', 0)); const yawRad = (yaw * Math.PI) / 180; const pitchRad = (pitch * Math.PI) / 180; const cosPitch = Math.cos(pitchRad); diff --git a/modules/other/Freelook.js b/modules/other/Freelook.js index 3ebdb5bc..5d855d96 100644 --- a/modules/other/Freelook.js +++ b/modules/other/Freelook.js @@ -1,8 +1,8 @@ -import { Mixin } from '../../utils/MixinManager'; +import { deleteMixinValue, setMixinValue } from '../../utils/MixinManager'; import { ModuleBase } from '../../utils/ModuleBase'; -import { MathUtils } from '../../utils/Math'; -import { MacroState } from '../../utils/MacroState'; -import { Mouse } from '../../utils/Ungrab'; +import { wrapTo180 } from '../../utils/Math'; +import { getModule } from '../../utils/MacroState'; +import { forceGrab, releaseForcedGrab } from '../../utils/Ungrab'; import { mc } from '../../utils/Utils'; const Perspective = net.minecraft.client.CameraType; @@ -28,28 +28,28 @@ class Freelook extends ModuleBase { const player = Player.getPlayer(); if (!World.isLoaded() || !player) return this.toggle(false); - MacroState.getModule('Freecam')?.toggle(false); + getModule('Freecam')?.toggle(false); this.message('&aEnabled'); this.savedPerspective = mc.options.getCameraType(); - Mouse.forceGrab(); - Mixin.set('cameraOverrideYaw', MathUtils.wrapTo180(player.getYRot())); - Mixin.set('cameraOverridePitch', player.getXRot()); - Mixin.set('freelookCameraDistance', 4.0); - Mixin.set('freelookEnabled', true); + forceGrab(); + setMixinValue('cameraOverrideYaw', wrapTo180(player.getYRot())); + setMixinValue('cameraOverridePitch', player.getXRot()); + setMixinValue('freelookCameraDistance', 4.0); + setMixinValue('freelookEnabled', true); mc.options.setCameraType(Perspective.THIRD_PERSON_BACK); } onDisable() { this.message('&cDisabled'); - Mixin.set('freelookEnabled', false); - Mixin.delete('cameraOverrideYaw'); - Mixin.delete('cameraOverridePitch'); - Mixin.delete('freelookCameraDistance'); + setMixinValue('freelookEnabled', false); + deleteMixinValue('cameraOverrideYaw'); + deleteMixinValue('cameraOverridePitch'); + deleteMixinValue('freelookCameraDistance'); if (this.savedPerspective) mc.options.setCameraType(this.savedPerspective); this.savedPerspective = null; - Mouse.releaseForcedGrab(); + releaseForcedGrab(); } updateCamera() { diff --git a/modules/other/MacroControllers.js b/modules/other/MacroControllers.js index 6c99f84a..5a9c839b 100644 --- a/modules/other/MacroControllers.js +++ b/modules/other/MacroControllers.js @@ -1,5 +1,5 @@ import { ModuleBase } from '../../utils/ModuleBase'; -import { Mixin } from '../../utils/MixinManager'; +import { setMixinValue } from '../../utils/MixinManager'; class Controller extends ModuleBase { constructor() { @@ -14,20 +14,20 @@ class Controller extends ModuleBase { this.addDirectToggle( 'Auto-Perspective', - (value) => Mixin.set('forcePerspective', value), + (value) => setMixinValue('forcePerspective', value), 'Automatically switches to third person while macro is running.', false, sectionName ); - this.addDirectToggle('Limit FPS', (value) => Mixin.set('limitFps', value), 'Limits FPS while macro is running.', false, sectionName); - this.addDirectToggle('Mute Game', (value) => Mixin.set('muteGame', value), 'Mutes game audio while macro is running.', false, sectionName); + this.addDirectToggle('Limit FPS', (value) => setMixinValue('limitFps', value), 'Limits FPS while macro is running.', false, sectionName); + this.addDirectToggle('Mute Game', (value) => setMixinValue('muteGame', value), 'Mutes game audio while macro is running.', false, sectionName); this.addDirectMultiToggle( 'Render Limiters', ['Off', 'Limit Chunks', 'No Render'], true, - (value) => Mixin.set('renderLimiter', value?.find?.((option) => option.enabled)?.name || 'Off'), + (value) => setMixinValue('renderLimiter', value?.find?.((option) => option.enabled)?.name || 'Off'), 'Limits render distance or cancels rendering while macro is running.', 'Off', sectionName diff --git a/modules/other/MacroScheduler.js b/modules/other/MacroScheduler.js index 514d4602..d8c55204 100644 --- a/modules/other/MacroScheduler.js +++ b/modules/other/MacroScheduler.js @@ -1,9 +1,9 @@ import { OverlayManager } from '../../gui/OverlayUtils'; -import { MacroState } from '../../utils/MacroState'; +import { getEnabledMacros, getLastDisableMeta, getModule, getModuleDuration } from '../../utils/MacroState'; import { ModuleBase } from '../../utils/ModuleBase'; -import { TimeUtils, Timer } from '../../utils/TimeUtils'; -import { Utils } from '../../utils/Utils'; -import { Webhook } from '../../utils/Webhooks'; +import { formatDurationMs, Timer } from '../../utils/TimeUtils'; +import { getConfigFile, writeConfigFile } from '../../utils/Utils'; +import { sendEmbed, sendScreenshot } from '../../utils/Webhooks'; const STATE = { IDLE: 'Idle', @@ -81,7 +81,7 @@ class MacroScheduler extends ModuleBase { } loadState() { - const data = Utils.getConfigFile(this.configPath); + const data = getConfigFile(this.configPath); if (!data) return; this.state = Object.values(STATE).includes(data.state) ? data.state : STATE.IDLE; @@ -92,7 +92,7 @@ class MacroScheduler extends ModuleBase { } saveState() { - Utils.writeConfigFile(this.configPath, { + writeConfigFile(this.configPath, { state: this.state, trackedMacros: this.trackedMacros, timerEnd: this.timerEnd, @@ -284,7 +284,7 @@ class MacroScheduler extends ModuleBase { endSession() { this.breakDurationMs = this.randomDuration(this.breakTimeMin, this.breakTimeMax); - const breakTime = TimeUtils.formatDurationMs(this.breakDurationMs); + const breakTime = formatDurationMs(this.breakDurationMs); const cleanBreakTime = breakTime.includes(' ') ? breakTime.replace(/ (?=[^ ]+$)/, ' and ') : breakTime; this.stopTrackedMacros(); @@ -315,7 +315,7 @@ class MacroScheduler extends ModuleBase { this.trackedMacros.splice(index, 1); - Webhook.sendScreenshot(`Disabled ${macroName}`, MacroState.getModuleDuration(macroName)); + sendScreenshot(`Disabled ${macroName}`, getModuleDuration(macroName)); if (this.trackedMacros.length === 0) { this.state = STATE.IDLE; @@ -334,14 +334,14 @@ class MacroScheduler extends ModuleBase { startTrackedMacros() { this.trackedMacros.forEach((name) => { - const module = MacroState.getModule(name); + const module = getModule(name); if (module && module.isMacro && !module.enabled) module.toggle(true, false, 'scheduler'); }); } stopTrackedMacros() { this.trackedMacros.forEach((name) => { - const module = MacroState.getModule(name); + const module = getModule(name); if (module && module.isMacro) module.toggle(false, true, 'scheduler'); }); } @@ -350,11 +350,11 @@ class MacroScheduler extends ModuleBase { const lines = []; this.trackedMacros.forEach((name) => { - const meta = MacroState.getLastDisableMeta(name); + const meta = getLastDisableMeta(name); if (!meta || meta.context !== 'scheduler') return; const macroLines = []; - const runtime = MacroState.getModuleDuration(name); + const runtime = getModuleDuration(name); if (runtime) macroLines.push(`Runtime: ${runtime}`); const stats = this.getMacroOverlayStats(name); @@ -373,7 +373,7 @@ class MacroScheduler extends ModuleBase { } sendSchedulerEmbed(title, description, color) { - Webhook.sendEmbed( + sendEmbed( [ { title, @@ -388,7 +388,7 @@ class MacroScheduler extends ModuleBase { } getMacroOverlayStats(macroName) { - const module = MacroState.getModule(macroName); + const module = getModule(macroName); if (!module) return []; const overlayName = module.oid || macroName; @@ -406,7 +406,7 @@ class MacroScheduler extends ModuleBase { if (resolved === undefined || resolved === null || String(resolved).trim() === '') return; lines.push(`${key}: ${resolved}`); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } }); }); @@ -415,8 +415,8 @@ class MacroScheduler extends ModuleBase { } getSchedulableMacros() { - return MacroState.getEnabledMacros().filter((name) => { - const module = MacroState.getModule(name); + return getEnabledMacros().filter((name) => { + const module = getModule(name); return module && module.isMacro && !module.isParentManaged; }); } @@ -443,7 +443,7 @@ class MacroScheduler extends ModuleBase { if (this.state === STATE.IDLE) return 'Waiting'; const remaining = Math.max(0, this.timerEnd - Date.now()); - const timeStr = TimeUtils.formatDurationMs(remaining); + const timeStr = formatDurationMs(remaining); return this.state === STATE.RETURNING ? `Returning (${timeStr})` : timeStr; } diff --git a/modules/other/PeltMacro.js b/modules/other/PeltMacro.js index 561bc61a..be683227 100644 --- a/modules/other/PeltMacro.js +++ b/modules/other/PeltMacro.js @@ -1,20 +1,20 @@ import { OverlayManager } from '../../gui/OverlayUtils'; import { MCHand, Vec3d } from '../../utils/Constants'; -import { MacroState } from '../../utils/MacroState'; +import { getModuleElapsedMs } from '../../utils/MacroState'; import { ModuleBase } from '../../utils/ModuleBase'; import { formatRoundedNumber } from '../../utils/NumberUtils'; import { ServerboundUseItemPacket } from '../../utils/Packets'; import { ScheduleTask } from '../../utils/ScheduleTask'; import Pathfinder from '../../utils/pathfinder/PathFinder'; import { EtherwarpPathfinder } from '../../utils/pathfinder/EtherwarpPathfinder'; -import { PathExecutor } from '../../utils/pathfinder/PathExecutor'; -import { MathUtils } from '../../utils/Math'; -import { Utils } from '../../utils/Utils'; -import { Guis } from '../../utils/player/Inventory'; +import { destroyPathExecutor } from '../../utils/pathfinder/PathExecutor'; +import { angleToPlayer, fastDistance } from '../../utils/Math'; +import { area } from '../../utils/Utils'; +import { findItemInHotbar, setItemSlot } from '../../utils/player/Inventory'; import { Rotations } from '../../utils/player/Rotations'; -import { RotationGCD } from '../../utils/player/RotationGCD'; +import { applyToPlayer } from '../../utils/player/RotationGCD'; import { PeltQOLModule } from './PeltQOL'; -import { Mouse } from '../../utils/Ungrab'; +import { regrab, ungrab } from '../../utils/Ungrab'; // this is complete codex vibecoded slop, but it works so who cares! @@ -208,7 +208,7 @@ class PeltMacro extends ModuleBase { onEnable() { PeltQOLModule.ensureForceEnabled(); - Mouse.ungrab(); + ungrab(); this.status = 'Calling Trevor'; this.resetMobTracking(); this.resetAreaTravelState(); @@ -221,7 +221,7 @@ class PeltMacro extends ModuleBase { handleTick() { PeltQOLModule.ensureForceEnabled(); - const areaName = Utils.area(); + const areaName = area(); this.syncMobJumpHold(this.enabled && this.shouldHoldMobJump()); if (!this.enabled || !areaName) return; if (areaName != 'The Farming Islands') { @@ -310,7 +310,7 @@ class PeltMacro extends ModuleBase { } getActiveHours() { - const elapsedMs = MacroState.getModuleElapsedMs(this.name); + const elapsedMs = getModuleElapsedMs(this.name); if (elapsedMs <= 0) return 0; return elapsedMs / 3600000; } @@ -490,7 +490,7 @@ class PeltMacro extends ModuleBase { this.mobPathToken++; if (EtherwarpPathfinder.isPathing()) EtherwarpPathfinder.cancel(true); Pathfinder.resetPath(); - PathExecutor.destroy(); + destroyPathExecutor(); } stopMovement() { @@ -502,7 +502,7 @@ class PeltMacro extends ModuleBase { prepareForTravel() { if (EtherwarpPathfinder.isPathing()) EtherwarpPathfinder.cancel(true); Pathfinder.resetPath(); - PathExecutor.destroy(); + destroyPathExecutor(); this.cancelRestartSequence(); this.cancelTravelSequence(); this.resetAreaTravelState(); @@ -510,8 +510,8 @@ class PeltMacro extends ModuleBase { } getAOTESlot() { - const aotvSlot = Guis.findItemInHotbar('Aspect of the Void'); - return aotvSlot !== -1 ? aotvSlot : Guis.findItemInHotbar('Aspect of the End'); + const aotvSlot = findItemInHotbar('Aspect of the Void'); + return aotvSlot !== -1 ? aotvSlot : findItemInHotbar('Aspect of the End'); } isAOTETravelMode(mode = this.travelMode) { @@ -604,7 +604,7 @@ class PeltMacro extends ModuleBase { sequenceToken: this.travelSequenceToken, }; - Guis.setItemSlot(slot); + setItemSlot(slot); if (atTrapWarp) { this.status = `AOTEing ${target.name}`; @@ -650,7 +650,7 @@ class PeltMacro extends ModuleBase { if (this.travelState?.sequenceToken !== token) return; if (!direction || !Number.isFinite(direction.yaw) || !Number.isFinite(direction.pitch)) return; - RotationGCD.applyToPlayer(direction.yaw, direction.pitch); + applyToPlayer(direction.yaw, direction.pitch); const yaw = Number.parseFloat(Player.getYaw()); const pitch = Number.parseFloat(Player.getPitch()); @@ -733,7 +733,7 @@ class PeltMacro extends ModuleBase { } getMobDistance(entity) { - return MathUtils.fastDistance(entity.getX(), entity.getY(), entity.getZ(), Player.getX(), Player.getY(), Player.getZ()); + return fastDistance(entity.getX(), entity.getY(), entity.getZ(), Player.getX(), Player.getY(), Player.getZ()); } getGoalKey(goal) { @@ -941,8 +941,8 @@ class PeltMacro extends ModuleBase { ScheduleTask(120, () => { if (!this.enabled || token !== this.restartToken) return; - let area = Utils.area(); - if (area == 'unknown') { + const areaName = area(); + if (areaName == 'unknown') { ChatLib.command('play skyblock'); ScheduleTask(120, () => { if (!this.enabled || token !== this.restartToken) return; @@ -1042,7 +1042,7 @@ class PeltMacro extends ModuleBase { this.status = 'Shooting Mob'; const aimPoint = this.getAimPoint(entity); - Guis.setItemSlot(this.weaponSlot); + setItemSlot(this.weaponSlot); if (!Rotations.active) Rotations.trackEntity(entity); if (Date.now() - this.lastShotAt < SHOOT_COOLDOWN_MS) return; @@ -1108,7 +1108,7 @@ class PeltMacro extends ModuleBase { } isAimedAt(point) { - const angleData = MathUtils.angleToPlayer(point); + const angleData = angleToPlayer(point); return angleData.yawAbs <= AIM_TOLERANCE && angleData.pitchAbs <= AIM_TOLERANCE; } @@ -1122,7 +1122,7 @@ class PeltMacro extends ModuleBase { this.resetAreaTravelState(); this.resetMobTracking(); this.stopMovement(); - Mouse.regrab(); + regrab(); } } diff --git a/modules/other/PeltQOL.js b/modules/other/PeltQOL.js index b5a54a5f..34b3c0e1 100644 --- a/modules/other/PeltQOL.js +++ b/modules/other/PeltQOL.js @@ -1,8 +1,8 @@ import { Vec3d } from '../../utils/Constants'; import { ModuleBase } from '../../utils/ModuleBase'; import { ScheduleTask } from '../../utils/ScheduleTask'; -import { Utils } from '../../utils/Utils'; -import { Guis } from '../../utils/player/Inventory'; +import { area } from '../../utils/Utils'; +import { clickSlot, findFirstItem, getGuiName, setItemSlot } from '../../utils/player/Inventory'; const NAMES = new Set(['Cow', 'Pig', 'Sheep', 'Chicken', 'Rabbit', 'Horse', 'Mooshroom', 'Dinnerbone']); const HP = new Set([100, 200, 500, 1000, 2000, 5000, 10000, 1024, 20000, 30000, 60000]); @@ -85,7 +85,7 @@ class PeltQOL extends ModuleBase { }); this.on('worldUnload', () => this.reset()); this.when( - () => this.enabled && this.renderESP && Utils.area() === 'The Farming Islands' && this.animals.length, + () => this.enabled && this.renderESP && area() === 'The Farming Islands' && this.animals.length, 'postRenderWorld', () => this.render() ); @@ -170,7 +170,7 @@ class PeltQOL extends ModuleBase { } } if (this.abiphoneSlot !== -1) { - Guis.setItemSlot(this.abiphoneSlot); + setItemSlot(this.abiphoneSlot); this.abiphoneWait = 5; this.abiphoneState = ABIPHONE.RIGHT_CLICK; return; @@ -186,8 +186,8 @@ class PeltQOL extends ModuleBase { break; } case ABIPHONE.FIND_TREVOR: { - if (Guis.guiName()?.includes('Abiphone')) { - this.trevorSlot = Guis.findFirst(Player.getContainer(), 'Trevor'); + if (getGuiName()?.includes('Abiphone')) { + this.trevorSlot = findFirstItem(Player.getContainer(), 'Trevor'); if (this.trevorSlot !== -1) { this.abiphoneWait = 5; this.abiphoneState = ABIPHONE.CLICK_TREVOR; @@ -198,7 +198,7 @@ class PeltQOL extends ModuleBase { break; } case ABIPHONE.CLICK_TREVOR: { - Guis.clickSlot(this.trevorSlot, false, 'LEFT'); + clickSlot(this.trevorSlot, false, 'LEFT'); this.abiphoneWait = 5; this.abiphoneState = ABIPHONE.DONE; break; @@ -211,7 +211,7 @@ class PeltQOL extends ModuleBase { } handleChat(message) { - if (!this.enabled || Utils.area() !== 'The Farming Islands') return; + if (!this.enabled || area() !== 'The Farming Islands') return; const formatted = message.getFormattedText(); const lower = ChatLib.removeFormatting(message.getUnformattedText()).trim().toLowerCase(); @@ -245,7 +245,7 @@ class PeltQOL extends ModuleBase { } scan() { - if (!this.enabled || Utils.area() !== 'The Farming Islands' || this.huntCompleted) return (this.animals = []); + if (!this.enabled || area() !== 'The Farming Islands' || this.huntCompleted) return (this.animals = []); this.animals = World.getAllEntities().filter((e) => { if (!NAMES.has(e.getName()) || e.isDead()) return false; const maxHp = e.getMaxHP(); diff --git a/modules/other/RatMacro.js b/modules/other/RatMacro.js index 0d5cf4e5..5e8db1a5 100644 --- a/modules/other/RatMacro.js +++ b/modules/other/RatMacro.js @@ -1,17 +1,17 @@ //Vibecoded SLOP, STILL WORKS FINE :3 import { isDeveloperModeEnabled } from '../../utils/DeveloperModeState'; import { OverlayManager } from '../../gui/OverlayUtils'; -import { Chat } from '../../utils/Chat'; +import { sendDebugMessage } from '../../utils/Chat'; import { MCHand } from '../../utils/Constants'; import { finiteNumber, formatRoundedNumber } from '../../utils/NumberUtils'; import { ModuleBase } from '../../utils/ModuleBase'; import { ServerboundUseItemPacket } from '../../utils/Packets'; import { EtherwarpPathfinder } from '../../utils/pathfinder/EtherwarpPathfinder'; -import { Guis } from '../../utils/player/Inventory'; +import { clickSlot, closeInventory, setItemSlot } from '../../utils/player/Inventory'; import { Rotations } from '../../utils/player/Rotations'; import { ScheduleTask } from '../../utils/ScheduleTask'; -import { Mouse } from '../../utils/Ungrab'; -import { Utils } from '../../utils/Utils'; +import { regrab, ungrab } from '../../utils/Ungrab'; +import { area } from '../../utils/Utils'; import PathConfig from '../../utils/pathfinder/PathConfig'; import { getHubRats, getRatId, getRawHubRats } from '../visuals/RatESP'; @@ -148,7 +148,7 @@ class RatMacro extends ModuleBase { } debug(message) { - Chat.messageDebug(`&6Rat Macro:&f ${message}`); + sendDebugMessage(`&6Rat Macro:&f ${message}`); } setState(nextState, reason = null) { @@ -175,7 +175,7 @@ class RatMacro extends ModuleBase { if (!this.enabled) return; if (!Player.getPlayer() || !World.isLoaded()) return; if (!Client.isInChat() && Client.isInGui() && !this.isHandlingSwapGui()) { - Guis.closeInv(); + closeInventory(); return; } @@ -183,10 +183,10 @@ class RatMacro extends ModuleBase { if (this.handleLobbySwap()) return; - if (Utils.area() !== 'Hub') { + if (area() !== 'Hub') { this.cancelPathing(); Client.stopMovement(); - this.setState(STATES.WAITING, `left hub for ${Utils.area() || 'unknown area'}`); + this.setState(STATES.WAITING, `left hub for ${area() || 'unknown area'}`); return; } @@ -339,7 +339,7 @@ class RatMacro extends ModuleBase { this.setState(STATES.ENGAGING, `preparing shot for ${this.formatRatRef()}`); Client.stopMovement(); Rotations.stop(); - Guis.setItemSlot(this.weaponSlot); + setItemSlot(this.weaponSlot); this.debug(`queued attack on rat &e${this.formatRatRef()}&f using slot &e${this.weaponSlot + 1}`); const attackToken = ++this.pendingAttackToken; @@ -833,7 +833,7 @@ class RatMacro extends ModuleBase { if (this.swapStage !== SWAP_STAGES.NONE) return; this.debug(`no rat candidates left, beginning ${this.swapMode} lobby swap`); - if (Utils.area() === 'Hub') { + if (area() === 'Hub') { if (this.swapMode === SWAP_MODES.VIP) { this.swapStage = SWAP_STAGES.WAIT_VIP_MENU; this.swapUntil = Date.now() + VIP_SWAP_TIMEOUT_MS; @@ -867,7 +867,7 @@ class RatMacro extends ModuleBase { const shouldWaitForGuiClose = Client.isInGui() && this.isHandlingSwapGui(); if (shouldWaitForGuiClose) { - Guis.closeInv(); + closeInventory(); } this.cancelPathing(); @@ -884,7 +884,7 @@ class RatMacro extends ModuleBase { if (this.swapStage === SWAP_STAGES.NONE) return false; if (this.swapStage === SWAP_STAGES.WAIT_HUB_SCAN) { - if (Utils.area() === 'Hub') { + if (area() === 'Hub') { const shouldWaitForGuiClose = this.resumeNormalModeIfRatsExist('rats found after swap'); if (shouldWaitForGuiClose !== null) { return shouldWaitForGuiClose; @@ -934,7 +934,7 @@ class RatMacro extends ModuleBase { if (Client.isInGui()) { this.cancelPathing(); - Guis.clickSlot(VIP_SWAP_SLOT, false, 'RIGHT'); + clickSlot(VIP_SWAP_SLOT, false, 'RIGHT'); this.swapStage = SWAP_STAGES.WAIT_VIP_TRANSFER; this.swapUntil = Date.now() + VIP_SWAP_TRANSFER_TIMEOUT_MS; this.lastSwapActionAt = Date.now(); @@ -978,7 +978,7 @@ class RatMacro extends ModuleBase { return true; } - if (Utils.area() !== 'Hub') { + if (area() !== 'Hub') { if (Date.now() < this.swapUntil) return true; this.cancelPathing(); @@ -1155,7 +1155,7 @@ class RatMacro extends ModuleBase { this.lastWorldUnloadAt = 0; this.invalidateVipRotation(); this.setState(STATES.WAITING); - Mouse.ungrab(); + ungrab(); this.debug(`enabled with swap mode &e${this.swapMode}&f and weapon slot &e${this.weaponSlot + 1}`); this.message('&aEnabled'); } @@ -1183,7 +1183,7 @@ class RatMacro extends ModuleBase { Rotations.stop(); this.debug('disabled, cleared targeting/pathing state'); this.setState(STATES.WAITING, 'module disabled'); - Mouse.regrab(); + regrab(); this.message('&cDisabled'); } } diff --git a/modules/other/SunGeckoMacro.js b/modules/other/SunGeckoMacro.js index 47dcf2ac..d5a323a3 100644 --- a/modules/other/SunGeckoMacro.js +++ b/modules/other/SunGeckoMacro.js @@ -1,15 +1,15 @@ import { OverlayManager } from '../../gui/OverlayUtils'; import { CombatBot } from '../combat/CombatBot'; -import { MacroState } from '../../utils/MacroState'; -import { MathUtils } from '../../utils/Math'; +import { getModuleElapsedMs } from '../../utils/MacroState'; +import { fastDistance } from '../../utils/Math'; import { ModuleBase } from '../../utils/ModuleBase'; import { formatRoundedNumber } from '../../utils/NumberUtils'; import Pathfinder from '../../utils/pathfinder/PathFinder'; -import { Guis } from '../../utils/player/Inventory'; -import { Movement } from '../../utils/player/Movement'; +import { findItemInHotbar, getGuiName, setItemSlot } from '../../utils/player/Inventory'; +import { setKeysForStraightLineCoords } from '../../utils/player/Movement'; import { Rotations } from '../../utils/player/Rotations'; import { ScheduleTask } from '../../utils/ScheduleTask'; -import { Mouse } from '../../utils/Ungrab'; +import { regrab, ungrab } from '../../utils/Ungrab'; // this module was completely ai coded // good luck anyone trying to maintain it in the future @@ -241,7 +241,7 @@ class SunGecko extends ModuleBase { for (const entity of World.getAllEntities()) { if (ChatLib.removeFormatting(String(entity.getName?.() || '')).trim() !== name) continue; - const distance = MathUtils.fastDistance(entity.getX(), entity.getY(), entity.getZ(), x, y, z); + const distance = fastDistance(entity.getX(), entity.getY(), entity.getZ(), x, y, z); if (distance >= closestDistance) continue; closestDistance = distance; @@ -278,7 +278,7 @@ class SunGecko extends ModuleBase { let closestDistance = Infinity; for (const point of Points) { - const distance = MathUtils.fastDistance(Player.getX(), Player.getY(), Player.getZ(), point.x, point.y, point.z); + const distance = fastDistance(Player.getX(), Player.getY(), Player.getZ(), point.x, point.y, point.z); if (distance < closestDistance) { closestDistance = distance; @@ -291,7 +291,7 @@ class SunGecko extends ModuleBase { } else if (closestPoint == 'Rift Spawn Exit') { this.handleRiftSpawnExit(); } else if (closestPoint == 'Eye Teleporter') { - if (Guis.guiName() !== null) { + if (getGuiName() !== null) { this.clickMenuItem(EYE_TELEPORTER.menuItem); return; } @@ -310,7 +310,7 @@ class SunGecko extends ModuleBase { return; } - if (Guis.guiName() !== null) { + if (getGuiName() !== null) { this.clickMenuItem(ORUO.menuItem); return; } @@ -333,13 +333,13 @@ class SunGecko extends ModuleBase { if (Pathfinder.isPathing()) Pathfinder.resetPath(); this.pathRequestActive = false; - const distanceToLadder = MathUtils.fastDistance(Player.getX(), 0, Player.getZ(), RIFT_SPAWN_LADDER_WAYPOINT.x, 0, RIFT_SPAWN_LADDER_WAYPOINT.z); + const distanceToLadder = fastDistance(Player.getX(), 0, Player.getZ(), RIFT_SPAWN_LADDER_WAYPOINT.x, 0, RIFT_SPAWN_LADDER_WAYPOINT.z); if (distanceToLadder > 0.25) { Client.setKey('shift', true); Client.setKey('sprint', false); Rotations.lookAtVector(RIFT_SPAWN_LADDER_AIM_POINT); - Movement.setKeysForStraightLineCoords(RIFT_SPAWN_LADDER_WAYPOINT.x, RIFT_SPAWN_LADDER_WAYPOINT.y, RIFT_SPAWN_LADDER_WAYPOINT.z, false, true); + setKeysForStraightLineCoords(RIFT_SPAWN_LADDER_WAYPOINT.x, RIFT_SPAWN_LADDER_WAYPOINT.y, RIFT_SPAWN_LADDER_WAYPOINT.z, false, true); return; } @@ -363,7 +363,7 @@ class SunGecko extends ModuleBase { if (distanceToExit > 1) { Client.setKey('shift', false); Client.setKey('sprint', false); - Movement.setKeysForStraightLineCoords(RIFT_SPAWN_EXIT_WAYPOINT.x, RIFT_SPAWN_EXIT_WAYPOINT.y, RIFT_SPAWN_EXIT_WAYPOINT.z, false, true); + setKeysForStraightLineCoords(RIFT_SPAWN_EXIT_WAYPOINT.x, RIFT_SPAWN_EXIT_WAYPOINT.y, RIFT_SPAWN_EXIT_WAYPOINT.z, false, true); return; } @@ -397,9 +397,9 @@ class SunGecko extends ModuleBase { CombatBot.setExternalTargets(mobs); if (!CombatBot.enabled) { - const holyIceSlot = Guis.findItemInHotbar('Holy Ice'); + const holyIceSlot = findItemInHotbar('Holy Ice'); if (holyIceSlot !== -1) { - Guis.setItemSlot(holyIceSlot); + setItemSlot(holyIceSlot); } CombatBot.toggle(true, true); } @@ -425,7 +425,7 @@ class SunGecko extends ModuleBase { } getActiveHours() { - const elapsedMs = MacroState.getModuleElapsedMs(this.name); + const elapsedMs = getModuleElapsedMs(this.name); if (elapsedMs <= 0) return 0; return elapsedMs / 3600000; } @@ -441,7 +441,7 @@ class SunGecko extends ModuleBase { this.actionCooldownUntil = 0; this.terracottaClickCooldownUntil = 0; this.setState(States.DETERMIN); - Mouse.ungrab(); + ungrab(); this.message('&aEnabled'); } @@ -454,7 +454,7 @@ class SunGecko extends ModuleBase { CombatBot.clearExternalTargets(); if (CombatBot.enabled) CombatBot.toggle(false, true); this.state = States.WAITING; - Mouse.regrab(); + regrab(); this.message('&cDisabled'); } } diff --git a/modules/other/VoidgloomHelper.js b/modules/other/VoidgloomHelper.js index b7ff8832..6b7a360d 100644 --- a/modules/other/VoidgloomHelper.js +++ b/modules/other/VoidgloomHelper.js @@ -1,6 +1,6 @@ import { ArmorStandEntity } from '../../utils/Constants'; import { ModuleBase } from '../../utils/ModuleBase'; -import { Guis } from '../../utils/player/Inventory'; +import { findItemInHotbar, setItemSlot } from '../../utils/player/Inventory'; const ACTION = { IDLE: 'idle', @@ -135,7 +135,7 @@ class VoidgloomHelper extends ModuleBase { return; } - const katanaSlot = Guis.findItemInHotbar('Katana'); + const katanaSlot = findItemInHotbar('Katana'); if (this.enableSoulcry && (!this.soulcryBossOnly || this.bossActive) && katanaSlot !== -1 && this.canSoulcry(katanaSlot)) { this.beginAction(FEATURE.SOULCRY, katanaSlot); } @@ -160,7 +160,7 @@ class VoidgloomHelper extends ModuleBase { switch (this.actionPhase) { case ACTION.USE: if (Player.getHeldItemIndex() !== this.targetSlot) { - Guis.setItemSlot(this.targetSlot); + setItemSlot(this.targetSlot); return; } if (this.currentFeature === FEATURE.SOULCRY) this.lastSoulcry = Date.now(); @@ -171,7 +171,7 @@ class VoidgloomHelper extends ModuleBase { break; case ACTION.RETURN: if (this.swapBackSlot !== -1 && this.swapBackSlot !== Player.getHeldItemIndex()) { - Guis.setItemSlot(this.swapBackSlot); + setItemSlot(this.swapBackSlot); return; } this.resetAction(); @@ -212,7 +212,7 @@ class VoidgloomHelper extends ModuleBase { findDeployableSlot() { const targets = ['Power Orb', 'Flare']; for (const target of targets) { - const slot = Guis.findItemInHotbar(target); + const slot = findItemInHotbar(target); if (slot !== -1) return slot; } return -1; diff --git a/modules/skills/AutoExperiments.js b/modules/skills/AutoExperiments.js index ec0b3bbf..be10fc79 100644 --- a/modules/skills/AutoExperiments.js +++ b/modules/skills/AutoExperiments.js @@ -1,5 +1,5 @@ import { ModuleBase } from '../../utils/ModuleBase'; -import { Guis } from '../../utils/player/Inventory'; +import { clickSlot, closeInventory } from '../../utils/player/Inventory'; /** * @typedef {com.chattriggers.ctjs.api.inventory.Item} item @@ -155,7 +155,7 @@ class AutoExperiments extends ModuleBase { if (this.buyXpTargetLevel > 0) return this.clickSlot(SLOTS.BOTTLE_MENU); if (this.onCooldown(items[SLOTS.SUPERPAIRS])) { - Guis.closeInv(); + closeInventory(); this.reset(); return this.message('Experiments complete'); } @@ -183,7 +183,7 @@ class AutoExperiments extends ModuleBase { this.captureUltrasequencerOrder(items); this.ultraPatternCaptured = true; this.clicks = 0; - if (this.ultrasequencerOrder.size > maxDepth) Guis.closeInv(); + if (this.ultrasequencerOrder.size > maxDepth) closeInventory(); } if (control.isClock && this.ultraPatternCaptured && this.canClick() && this.ultrasequencerOrder.has(this.clicks)) { @@ -206,7 +206,7 @@ class AutoExperiments extends ModuleBase { const guiRound = this.getChronomatronRound(items); const expectedLen = Math.min(maxDepth, guiRound || this.chronomatronOrder.length + 1); - if (guiRound && guiRound - 1 === maxDepth) Guis.closeInv(); + if (guiRound && guiRound - 1 === maxDepth) closeInventory(); if (control.isClock && this.chronomatronOrder.length < expectedLen) { this.clicks = 0; @@ -277,7 +277,7 @@ class AutoExperiments extends ModuleBase { this.boughtXP = false; return this.startReopenSequence(); } - Guis.closeInv(); + closeInventory(); return this.message('Not enough bits!'); } @@ -295,7 +295,7 @@ class AutoExperiments extends ModuleBase { if (!this.canClick()) return; if (!this.reopeningStarted) { - Guis.closeInv(); + closeInventory(); this.reopeningStarted = true; this.lastClickTime = Date.now(); } else { @@ -420,7 +420,7 @@ class AutoExperiments extends ModuleBase { } clickSlot(slot, clickType = 'MIDDLE') { - if (Guis.clickSlot(slot, false, clickType)) { + if (clickSlot(slot, false, clickType)) { this.lastClickTime = Date.now(); return true; } diff --git a/modules/skills/ChocolateFactory.js b/modules/skills/ChocolateFactory.js index b79ad6eb..559ac115 100644 --- a/modules/skills/ChocolateFactory.js +++ b/modules/skills/ChocolateFactory.js @@ -1,7 +1,7 @@ import { ArmorStandEntity, Vec3d } from '../../utils/Constants'; -import { MathUtils } from '../../utils/Math'; +import { fastDistance } from '../../utils/Math'; import { ModuleBase } from '../../utils/ModuleBase'; -import { Guis } from '../../utils/player/Inventory'; +import { clickSlot, getGuiName } from '../../utils/player/Inventory'; const COOKIE_SLOT = 13; const MAX_TRACKED_EGGS = 6; @@ -134,7 +134,7 @@ class ChocolateFactory extends ModuleBase { onTick() { const container = Player.getContainer(); if (!container) return; - if (Guis.guiName() !== 'Chocolate Factory') return; + if (getGuiName() !== 'Chocolate Factory') return; const now = Date.now(); if ((this.clickFactory || this.claimStrays) && now - this.lastActionAt >= this.actionDelayMs) { @@ -145,7 +145,7 @@ class ChocolateFactory extends ModuleBase { performFactoryActions(container) { if (this.clickFactory) { - Guis.clickSlot(COOKIE_SLOT, false, 'RIGHT'); + clickSlot(COOKIE_SLOT, false, 'RIGHT'); } if (!this.claimStrays) return; @@ -159,7 +159,7 @@ class ChocolateFactory extends ModuleBase { if (!name) continue; if (name.includes('CLICK ME!') || name.includes('Golden Rabbit')) { - Guis.clickSlot(slot, false, 'LEFT'); + clickSlot(slot, false, 'LEFT'); return; } } @@ -210,7 +210,7 @@ class ChocolateFactory extends ModuleBase { return EGG_TYPES.find((egg) => profileString.includes(egg.texture)) || null; } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); return null; } } @@ -255,7 +255,7 @@ class ChocolateFactory extends ModuleBase { this.detectedEggs.forEach((egg) => { if (!egg || egg.isFound || !egg.entity) return; - const distance = MathUtils.fastDistance(player.getX(), player.getY(), player.getZ(), egg.entity.getX(), egg.entity.getY(), egg.entity.getZ()); + const distance = fastDistance(player.getX(), player.getY(), player.getZ(), egg.entity.getX(), egg.entity.getY(), egg.entity.getZ()); const priority = `${egg.eggType}`.toLowerCase() === targetType ? 0 : 1; if (priority < closestPriority || (priority === closestPriority && distance < closestDistance)) { closest = egg; @@ -270,7 +270,7 @@ class ChocolateFactory extends ModuleBase { } onSoundPlay(_pos, name, _volume, _pitch, _category, event) { - if (Guis.guiName() !== 'Chocolate Factory' || !name) return; + if (getGuiName() !== 'Chocolate Factory' || !name) return; if (!this.cancelSound) return; const soundName = `${name}`.toLowerCase(); diff --git a/modules/skills/FishOnMCMacro.js b/modules/skills/FishOnMCMacro.js index 921ff526..19fbfa69 100644 --- a/modules/skills/FishOnMCMacro.js +++ b/modules/skills/FishOnMCMacro.js @@ -1,11 +1,11 @@ import { ModuleBase } from '../../utils/ModuleBase'; import { ClientboundSetTitleTextPacket } from '../../utils/Packets'; import Pathfinder from '../../utils/pathfinder/PathFinder'; -import { Guis } from '../../utils/player/Inventory'; +import { clickSlot, closeInventory } from '../../utils/player/Inventory'; import { Rotations } from '../../utils/player/Rotations'; import { ScheduleTask } from '../../utils/ScheduleTask'; -import { manager } from '../../utils/SkyblockEvents'; -import { Mouse } from '../../utils/Ungrab'; +import { registerSkyblockEvent } from '../../utils/SkyblockEvents'; +import { regrab, ungrab } from '../../utils/Ungrab'; const FISH_POSITIONS = [ 0xfa07, 0xfa12, 0xfa18, 0xfa36, 0xfa40, 0xfa51, 0xfa52, 0xfa59, 0xfa60, 0xfa63, 0xfa64, 0xfa77, 0xfa00, 0xfa15, 0xfa24, 0xfa35, 0xfa70, 0xfa79, 0xfa85, @@ -80,7 +80,7 @@ class FishOnMCMacro extends ModuleBase { if (title === 'BITE!') Client.rightClick(); }).setFilteredClass(ClientboundSetTitleTextPacket); - manager.subscribe('fishquestready', () => { + registerSkyblockEvent('fishquestready', () => { if (!this.enabled) return; this.questPending = true; this.message('&eQuest queued.'); @@ -124,7 +124,7 @@ class FishOnMCMacro extends ModuleBase { this.lastFishAt = 0; }); - manager.subscribe('fullinventory', () => { + registerSkyblockEvent('fullinventory', () => { if (this.enabled && this.state === STATES.FISHING) this.sellInventory(); }); } @@ -143,7 +143,7 @@ class FishOnMCMacro extends ModuleBase { pitch: Player.getPitch(), }; Client.setKey('shift', false); - Mouse.ungrab(); + ungrab(); this.castRod(); } @@ -153,8 +153,8 @@ class FishOnMCMacro extends ModuleBase { Client.setKey('shift', false); Pathfinder.resetPath(); Rotations.stop(); - if (this.state === STATES.OPENING_MERCHANT || this.state === STATES.SELLING || this.state >= STATES.QUEST_OPENING) Guis.closeInv(); - Mouse.regrab(); + if (this.state === STATES.OPENING_MERCHANT || this.state === STATES.SELLING || this.state >= STATES.QUEST_OPENING) closeInventory(); + regrab(); } sellInventory() { @@ -223,7 +223,7 @@ class FishOnMCMacro extends ModuleBase { for (let slot = items.length - 36; slot < items.length; slot++) { const item = items[slot]; if (item?.getLore?.()?.some((line) => ChatLib.removeFormatting(String(line)).includes(VALUE_LORE))) { - Guis.clickSlot(slot, false, 'LEFT'); + clickSlot(slot, false, 'LEFT'); return true; } } @@ -231,7 +231,7 @@ class FishOnMCMacro extends ModuleBase { } returnToStart() { - Guis.closeInv(); + closeInventory(); if (!this.start) { this.state = STATES.FISHING; return; @@ -298,7 +298,7 @@ class FishOnMCMacro extends ModuleBase { return this.clickQuestSlot(typeSlots[0]); } - Guis.closeInv(); + closeInventory(); this.resumeFishing(); return; } @@ -330,7 +330,7 @@ class FishOnMCMacro extends ModuleBase { } clickQuestSlot(slot) { - if (Guis.clickSlot(slot, false, 'LEFT')) this.lastQuestActionAt = Date.now(); + if (clickSlot(slot, false, 'LEFT')) this.lastQuestActionAt = Date.now(); } castRod() { diff --git a/modules/skills/FishingHelper.js b/modules/skills/FishingHelper.js index 42b7e3ef..b9ea4224 100644 --- a/modules/skills/FishingHelper.js +++ b/modules/skills/FishingHelper.js @@ -1,6 +1,6 @@ import { ArmorStandEntity } from '../../utils/Constants'; import { ModuleBase } from '../../utils/ModuleBase'; -import { Guis } from '../../utils/player/Inventory'; +import { clickSlot } from '../../utils/player/Inventory'; class FishingHelper extends ModuleBase { constructor() { @@ -77,7 +77,7 @@ class FishingHelper extends ModuleBase { this.tickDelay = 5 + this.randomTickDelay(); break; case 31: - Guis.clickSlot(this.pendingPetSlot); + clickSlot(this.pendingPetSlot); this.resetSequence(); this.step = 0; break; diff --git a/modules/skills/FishingMacroA.js b/modules/skills/FishingMacroA.js index 4c6f621e..8488e25e 100644 --- a/modules/skills/FishingMacroA.js +++ b/modules/skills/FishingMacroA.js @@ -1,7 +1,7 @@ import { isDeveloperModeEnabled } from '../../utils/DeveloperModeState'; import { ArmorStandEntity } from '../../utils/Constants'; import { ModuleBase } from '../../utils/ModuleBase'; -import { Guis } from '../../utils/player/Inventory'; +import { clickSlot, setItemSlot } from '../../utils/player/Inventory'; class FishingMacro extends ModuleBase { constructor() { @@ -82,7 +82,7 @@ class FishingMacro extends ModuleBase { this.tickDelay = Math.round(this.cooldown + this.randomCooldown * Math.random()); switch (this.step) { case -2: - Guis.setItemSlot(this.rodSlot); + setItemSlot(this.rodSlot); this.step++; break; case -1: @@ -97,7 +97,7 @@ class FishingMacro extends ModuleBase { this.step++; break; case 1: // swap to hype - Guis.setItemSlot(this.hypeSlot); + setItemSlot(this.hypeSlot); this.hypeClicksRemaining = this.hypeClickAmount; this.step++; break; @@ -119,7 +119,7 @@ class FishingMacro extends ModuleBase { } break; case 3: - Guis.setItemSlot(this.deployableSlot); + setItemSlot(this.deployableSlot); this.step++; break; case 4: @@ -128,7 +128,7 @@ class FishingMacro extends ModuleBase { this.step++; break; case 5: - Guis.setItemSlot(this.rodSlot); + setItemSlot(this.rodSlot); this.step++; break; case 6: @@ -149,7 +149,7 @@ class FishingMacro extends ModuleBase { this.step++; break; case 8: - Guis.clickSlot(this.petSlot); + clickSlot(this.petSlot); this.step = 0; break; } diff --git a/modules/skills/JerryBoxMacro.js b/modules/skills/JerryBoxMacro.js index 879f2c9d..727fa59a 100644 --- a/modules/skills/JerryBoxMacro.js +++ b/modules/skills/JerryBoxMacro.js @@ -1,6 +1,6 @@ import { ModuleBase } from '../../utils/ModuleBase'; -import { Guis } from '../../utils/player/Inventory'; -import { Mouse } from '../../utils/Ungrab'; +import { clickSlot, findItemInHotbar, getGuiName, setItemSlot } from '../../utils/player/Inventory'; +import { regrab, ungrab } from '../../utils/Ungrab'; class JerryBoxMacro extends ModuleBase { constructor() { super({ @@ -46,21 +46,21 @@ class JerryBoxMacro extends ModuleBase { const isHoldingJerry = held?.getName()?.toString()?.includes('Jerry Box'); if (!isHoldingJerry) { - const slot = Guis.findItemInHotbar('Jerry Box'); + const slot = findItemInHotbar('Jerry Box'); if (slot === -1) { this.message('&cOut of Jerry Boxes. Disabling.'); this.toggle(false); return; } - Guis.setItemSlot(slot); + setItemSlot(slot); this.setState(this.STATES.RIGHT_CLICK); return; } } // If a GUI is open, handle Jerry Box GUI or close others if (Client.isInGui() && !Client.isInChat()) { - if (Guis.guiName()?.includes('Open a Jerry Box')) { + if (getGuiName()?.includes('Open a Jerry Box')) { this.waitLeft = this.guiWaitMax; return this.setState(this.STATES.CLICK_BUTTON); } @@ -77,7 +77,7 @@ class JerryBoxMacro extends ModuleBase { case this.STATES.CLICK_BUTTON: { const container = Player.getContainer(); // Check container exists, GUI is jerry box, and Open button exists - if (!container || !container.getStackInSlot(22) || !Guis.guiName()?.includes('Open a Jerry Box')) { + if (!container || !container.getStackInSlot(22) || !getGuiName()?.includes('Open a Jerry Box')) { if (this.waitLeft > 0) { this.waitLeft--; } else { @@ -86,7 +86,7 @@ class JerryBoxMacro extends ModuleBase { break; } // Center slot (22) is the Open button - Guis.clickSlot(22, false, 'MIDDLE'); + clickSlot(22, false, 'MIDDLE'); this.setState(this.STATES.CLOSE_GUI); break; } @@ -105,14 +105,14 @@ class JerryBoxMacro extends ModuleBase { this.message('&aEnabled'); this.state = this.STATES.IDLE; this.cooldown = 0; - Mouse.ungrab(); + ungrab(); } onDisable() { this.message('&cDisabled'); this.state = this.STATES.IDLE; this.cooldown = 0; - Mouse.regrab(); + regrab(); } setState(newState, waitTicks = this.delay) { diff --git a/modules/skills/MinionCollector.js b/modules/skills/MinionCollector.js index dcc62b95..0cfea1d9 100644 --- a/modules/skills/MinionCollector.js +++ b/modules/skills/MinionCollector.js @@ -1,8 +1,8 @@ import { ArmorStandEntity, MCHand, Vec3d } from '../../utils/Constants'; import { ModuleBase } from '../../utils/ModuleBase'; -import { Utils } from '../../utils/Utils'; +import { area } from '../../utils/Utils'; import { ServerboundInteractPacket } from '../../utils/Packets'; -import { Guis } from '../../utils/player/Inventory'; +import { clickSlot, closeInventory, getGuiName } from '../../utils/player/Inventory'; class MinionCollector extends ModuleBase { constructor() { @@ -19,7 +19,7 @@ class MinionCollector extends ModuleBase { this.lastCollection = 0; this.when( - () => this.enabled && Utils.area() === 'Private Island', + () => this.enabled && area() === 'Private Island', 'tick', () => { this.clickSlot(); @@ -85,17 +85,17 @@ class MinionCollector extends ModuleBase { clickSlot() { if (!this.inMinion) return; - const name = Guis.guiName(); + const name = getGuiName(); if (!name || !name.includes('Minion')) return; if (this.lastCollection === 0) { - Guis.clickSlot(48); + clickSlot(48); this.lastCollection = Date.now(); return; } if (Date.now() - this.lastCollection >= 500) { - Guis.closeInv(); + closeInventory(); this.inMinion = false; this.lastCollection = 0; } diff --git a/modules/skills/RouteWalker.js b/modules/skills/RouteWalker.js index 1fb0485e..ccb7f3bb 100644 --- a/modules/skills/RouteWalker.js +++ b/modules/skills/RouteWalker.js @@ -1,15 +1,14 @@ import { isDeveloperModeEnabled } from '../../utils/DeveloperModeState'; import { Vec3d } from '../../utils/Constants'; -import { MathUtils } from '../../utils/Math'; +import { calculateAbsoluteAngles, getDistanceToPlayer } from '../../utils/Math'; import { ModuleBase } from '../../utils/ModuleBase'; -import { Guis } from '../../utils/player/Inventory'; -import { Movement } from '../../utils/player/Movement'; +import { findItemInHotbar, setItemSlot } from '../../utils/player/Inventory'; +import { setKeysForStraightLineCoords } from '../../utils/player/Movement'; import { Rotations } from '../../utils/player/Rotations'; -import { Raytrace } from '../../utils/Raytrace'; -import { Router } from '../../utils/Router'; -import RouteState from '../../utils/RouteState'; +import { getVisiblePoint } from '../../utils/Raytrace'; +import { editRoute, getFileFromCallback, getFilesInDir, loadRouteFromFile, saveRouteToFile } from '../../utils/Router'; import { ScheduleTask } from '../../utils/ScheduleTask'; -import { Mouse } from '../../utils/Ungrab'; +import { regrab, ungrab } from '../../utils/Ungrab'; import { v5Command } from '../../utils/V5Commands'; class RouteWalkerer extends ModuleBase { @@ -26,7 +25,7 @@ class RouteWalkerer extends ModuleBase { this.bindToggleKey(); - this.routesDir = Router.getFilesInDir('RoutewalkerRoutes'); + this.routesDir = getFilesInDir('RoutewalkerRoutes'); this.LEFTCLICK = false; this.SNEAK = false; @@ -59,13 +58,12 @@ class RouteWalkerer extends ModuleBase { const createdRouteName = `${createdRouteId}.json`; const createdRoutePath = `RoutewalkerRoutes/${createdRouteName}`; - if (!Router.saveRouteToFile(createdRoutePath, [])) return; + if (!saveRouteToFile(createdRoutePath, [])) return; this.loadedFile = createdRouteName; this.route = []; this.invalidateEtherwarpClick(); this.refreshRoutesToggle(); - RouteState.setRoute(this.route, 'Route Walker'); this.message(`&aCreated route: &f${createdRouteName}`); return; } @@ -76,7 +74,7 @@ class RouteWalkerer extends ModuleBase { if (!Number.isNaN(parsedNum) && parsedNum >= 1) indexNum = parsedNum; } - this.route = Router.Edit( + this.route = editRoute( actionUpper, this.route, 'RoutewalkerRoutes/' + this.loadedFile, @@ -158,20 +156,20 @@ class RouteWalkerer extends ModuleBase { if (!this.point) return; this.action = this.ACTIONS[this.point.movements]; - let distData = MathUtils.getDistanceToPlayer(this.point.x, this.point.y, this.point.z); + let distData = getDistanceToPlayer(this.point.x, this.point.y, this.point.z); let currentDistance = distData.distance; switch (this.action) { case this.ACTIONS.WALK: - Movement.setKeysForStraightLineCoords(this.point.x, this.point.y, this.point.z, true, true); + setKeysForStraightLineCoords(this.point.x, this.point.y, this.point.z, true, true); Client.setKey('shift', this.SNEAK); Client.setKey('leftclick', this.LEFTCLICK); Client.setKey('sprint', true); - if (this.LEFTCLICK) Guis.setItemSlot(this.LEFTCLICKSLOT - 1); + if (this.LEFTCLICK) setItemSlot(this.LEFTCLICKSLOT - 1); - let angle = MathUtils.calculateAbsoluteAngles(new Vec3d(this.point.x + 0.5, this.point.y + 2, this.point.z + 0.5)); + let angle = calculateAbsoluteAngles(new Vec3d(this.point.x + 0.5, this.point.y + 2, this.point.z + 0.5)); Rotations.lookAtAngles(angle.yaw, this.LOCKPITCH ? this.PITCH : player.getXRot(), { speedMultiplier: 1.0 }); @@ -189,8 +187,8 @@ class RouteWalkerer extends ModuleBase { Client.stopMovement(); Client.setKey('shift', true); - let aotv = Guis.findItemInHotbar('Aspect of the Void'); - if (aotv === -1) aotv = Guis.findItemInHotbar('Aspect of the End'); // can aote etherwarp? + let aotv = findItemInHotbar('Aspect of the Void'); + if (aotv === -1) aotv = findItemInHotbar('Aspect of the End'); // can aote etherwarp? if (aotv === -1) { this.toggle(false); @@ -198,13 +196,13 @@ class RouteWalkerer extends ModuleBase { return; } - Guis.setItemSlot(aotv); + setItemSlot(aotv); const targetBlockPos = new BlockPos(this.point.x, this.point.y, this.point.z); if (Math.abs(player.getMotionX()) + Math.abs(player.getMotionZ()) > 0.1) return; - const point = Raytrace.getVisiblePoint(targetBlockPos.getX(), targetBlockPos.getY(), targetBlockPos.getZ(), false); + const point = getVisiblePoint(targetBlockPos.getX(), targetBlockPos.getY(), targetBlockPos.getZ(), false); if (!this.etherwarpReady) { if (point) { @@ -243,12 +241,11 @@ class RouteWalkerer extends ModuleBase { this.routesDir, true, (selected) => { - this.loadedFile = Router.getFilefromCallback(selected); - this.route = Router.loadRouteFromFile('RoutewalkerRoutes/', this.loadedFile); + this.loadedFile = getFileFromCallback(selected); + this.route = loadRouteFromFile('RoutewalkerRoutes/', this.loadedFile); this.invalidateEtherwarpClick(); this.currentIndex = 0; this.foundpoint = false; - RouteState.setRoute(this.route, 'Route Walker'); }, 'The route the macro will use' ); @@ -319,7 +316,7 @@ class RouteWalkerer extends ModuleBase { } refreshRoutesToggle() { - const routes = Router.getFilesInDir('RoutewalkerRoutes').map((name) => String(name)); + const routes = getFilesInDir('RoutewalkerRoutes').map((name) => String(name)); if (!this.routesToggle) return; const prevState = new Map((this.routesToggle.options || []).map((option) => [option.name, !!option.enabled])); @@ -349,7 +346,7 @@ class RouteWalkerer extends ModuleBase { const point = this.route[i]; if (point && typeof point.x === 'number' && typeof point.y === 'number' && typeof point.z === 'number') { - let distData = MathUtils.getDistanceToPlayer(point.x, point.y, point.z); + let distData = getDistanceToPlayer(point.x, point.y, point.z); let currentDistance = distData.distance; if (currentDistance < shortestDistance) { @@ -373,7 +370,7 @@ class RouteWalkerer extends ModuleBase { onEnable() { this.message('&aEnabled'); - Mouse.ungrab(); + ungrab(); } onDisable() { @@ -382,10 +379,10 @@ class RouteWalkerer extends ModuleBase { Client.unpressKeys(); Client.setKey('leftclick', false); Rotations.stop(); - Mouse.regrab(); + regrab(); this.foundpoint = false; this.currentIndex = 0; } } -export const RouteWalker = isDeveloperModeEnabled() ? new RouteWalkerer() : null; +if (isDeveloperModeEnabled()) new RouteWalkerer(); diff --git a/modules/skills/StridersurferMacro.js b/modules/skills/StridersurferMacro.js index 105e6b5c..4a635c69 100644 --- a/modules/skills/StridersurferMacro.js +++ b/modules/skills/StridersurferMacro.js @@ -1,12 +1,12 @@ import { OverlayManager } from '../../gui/OverlayUtils'; import { ArmorStandEntity } from '../../utils/Constants'; -import { MacroState } from '../../utils/MacroState'; -import { MathUtils } from '../../utils/Math'; +import { getModuleElapsedMs } from '../../utils/MacroState'; +import { wrapTo180 } from '../../utils/Math'; import { ModuleBase } from '../../utils/ModuleBase'; import { formatRoundedNumber } from '../../utils/NumberUtils'; -import { Guis } from '../../utils/player/Inventory'; +import { clickItem, closeInventory, setItemSlot } from '../../utils/player/Inventory'; import { Rotations } from '../../utils/player/Rotations'; -import { Mouse } from '../../utils/Ungrab'; +import { regrab, ungrab } from '../../utils/Ungrab'; const STEPS = { WAITING_FOR_BITE: 0, @@ -110,7 +110,7 @@ class StridersurferMacro extends ModuleBase { if (this.hasBiteWaitTimedOut()) { const rodSlot = this.getRodSlot(); if (rodSlot !== -1) { - Guis.setItemSlot(rodSlot); + setItemSlot(rodSlot); this.biteWaitStartedAt = 0; this.transitionTo(STEPS.RECOVERY_SWAP_BACK_TO_ROD, 1 + this.randomTickDelay()); } @@ -132,10 +132,10 @@ class StridersurferMacro extends ModuleBase { const closeStridersurfer = this.getNearbyStridersurfer(armorStands); if (closeStridersurfer) { - this.previousYaw = MathUtils.wrapTo180(Player.getPlayer().getYRot()); + this.previousYaw = wrapTo180(Player.getPlayer().getYRot()); this.previousPitch = Player.getPlayer().getXRot(); this.stridersurferTarget = closeStridersurfer; - Guis.setItemSlot(this.getAxeSlot()); + setItemSlot(this.getAxeSlot()); this.transitionTo(STEPS.SNAP_TO_STRIDER, 0); return; } @@ -143,7 +143,7 @@ class StridersurferMacro extends ModuleBase { this.transitionTo(STEPS.CAST_ROD); break; case STEPS.RECOVERY_SWAP_BACK_TO_ROD: - Guis.setItemSlot(this.getRodSlot()); + setItemSlot(this.getRodSlot()); this.transitionTo(STEPS.RECOVERY_RECAST_ROD, 1 + this.randomTickDelay()); break; case STEPS.RECOVERY_RECAST_ROD: @@ -152,7 +152,7 @@ class StridersurferMacro extends ModuleBase { this.transitionTo(STEPS.WAITING_FOR_BITE, 1 + this.randomTickDelay()); break; case STEPS.EQUIP_FLAY: - Guis.setItemSlot(this.getFlaySlot()); + setItemSlot(this.getFlaySlot()); if (this.shouldSwapPet(this.petNameKill)) { this.startPetSwap(this.petNameKill, 'kill'); @@ -168,12 +168,12 @@ class StridersurferMacro extends ModuleBase { this.transitionTo(STEPS.EQUIP_AXE_AFTER_OPEN, 1); break; case STEPS.EQUIP_AXE_AFTER_OPEN: - Guis.setItemSlot(this.getAxeSlot()); + setItemSlot(this.getAxeSlot()); Client.setKey('shift', true); this.transitionTo(STEPS.RE_EQUIP_FLAY, 7 + this.randomTickDelay()); break; case STEPS.RE_EQUIP_FLAY: - Guis.setItemSlot(this.getFlaySlot()); + setItemSlot(this.getFlaySlot()); Client.setKey('shift', true); this.transitionTo(STEPS.FINISH_KILL_COMBO); break; @@ -183,12 +183,12 @@ class StridersurferMacro extends ModuleBase { this.transitionTo(STEPS.RESET_STANCE, 0); break; case STEPS.RESET_STANCE: - Guis.setItemSlot(this.getAxeSlot()); + setItemSlot(this.getAxeSlot()); Client.setKey('shift', false); this.transitionTo(STEPS.EQUIP_ROD, 4 + this.randomTickDelay()); break; case STEPS.EQUIP_ROD: - Guis.setItemSlot(this.getRodSlot()); + setItemSlot(this.getRodSlot()); this.transitionTo(STEPS.CAST_ROD, 1 + this.randomTickDelay()); break; case STEPS.CAST_ROD: @@ -207,8 +207,8 @@ class StridersurferMacro extends ModuleBase { this.transitionTo(STEPS.CLICK_PET_SLOT, 4 + this.randomTickDelay()); break; case STEPS.CLICK_PET_SLOT: - if (!this.shouldSwapPet(this.pendingPetName) || !Guis.clickItem(this.pendingPetName, false, 'LEFT', true, false)) { - Guis.closeInv(); + if (!this.shouldSwapPet(this.pendingPetName) || !clickItem(this.pendingPetName, false, 'LEFT', true, false)) { + closeInventory(); } if (this.pendingPetPhase === 'kill') { @@ -353,7 +353,7 @@ class StridersurferMacro extends ModuleBase { const distance = this.distanceFromEyes(entity, eyes); return distance !== null && distance <= 3; } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); return false; } }); @@ -407,12 +407,12 @@ class StridersurferMacro extends ModuleBase { const name = typeof entity.getName === 'function' ? entity.getName() : null; if (name && String(name).includes('Stridersurfer')) return acc + 1; } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } return acc; }, 0); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); return null; } } @@ -428,7 +428,7 @@ class StridersurferMacro extends ModuleBase { } getActiveHours() { - const elapsedMs = MacroState.getModuleElapsedMs(this.name); + const elapsedMs = getModuleElapsedMs(this.name); if (elapsedMs <= 0) return 0; return elapsedMs / 3600000; } @@ -477,7 +477,7 @@ class StridersurferMacro extends ModuleBase { this.clearStriderState(); this.transitionTo(STEPS.EQUIP_ROD); Client.setKey('shift', false); - Mouse.ungrab(); + ungrab(); } onDisable() { @@ -486,7 +486,7 @@ class StridersurferMacro extends ModuleBase { Rotations.stop(); this.lastStriderCount = null; this.biteWaitStartedAt = 0; - Mouse.regrab(); + regrab(); } } diff --git a/modules/skills/WynnProfessionMacro.js b/modules/skills/WynnProfessionMacro.js index dfc6e114..ebd1349a 100644 --- a/modules/skills/WynnProfessionMacro.js +++ b/modules/skills/WynnProfessionMacro.js @@ -1,15 +1,15 @@ import { OverlayManager } from '../../gui/OverlayUtils'; -import { MacroState } from '../../utils/MacroState'; -import { MathUtils } from '../../utils/Math'; +import { getModuleElapsedMs } from '../../utils/MacroState'; +import { fastDistance } from '../../utils/Math'; import { ModuleBase } from '../../utils/ModuleBase'; import { formatRoundedNumber } from '../../utils/NumberUtils'; import Pathfinder from '../../utils/pathfinder/PathFinder'; -import { Guis } from '../../utils/player/Inventory'; +import { clickSlot, closeInventory } from '../../utils/player/Inventory'; import { Rotations } from '../../utils/player/Rotations'; import { ScheduleTask } from '../../utils/ScheduleTask'; -import { Utils } from '../../utils/Utils'; +import { writeConfigFile } from '../../utils/Utils'; import { v5Command } from '../../utils/V5Commands'; -import { manager } from '../../utils/SkyblockEvents'; +import { registerSkyblockEvent } from '../../utils/SkyblockEvents'; import { File, Vec3d } from '../../utils/Constants'; const CONFIG_DIR = 'V5Config'; @@ -136,7 +136,7 @@ class WynnProfessionMacro extends ModuleBase { this.on('tick', () => this.onTick()); this.on('soundPlay', (_pos, name) => this.onSoundPlay(name)); - manager.subscribe('wynndurability', () => { + registerSkyblockEvent('wynndurability', () => { if (this.enabled) this.startRepairDetour(); }); @@ -396,7 +396,7 @@ class WynnProfessionMacro extends ModuleBase { const slot = this.findSlotByName(container, 'Repair Items'); if (slot < 0) return; - if (Guis.clickSlot(slot, false, 'LEFT')) { + if (clickSlot(slot, false, 'LEFT')) { this.state = STATES.REPAIR_SELECTING_ITEM; this.lastRepairActionAt = now; } @@ -407,7 +407,7 @@ class WynnProfessionMacro extends ModuleBase { const slot = this.findFirstRepairableSlot(container); if (slot < 0) return; - if (Guis.clickSlot(slot, false, 'LEFT')) { + if (clickSlot(slot, false, 'LEFT')) { this.lastRepairActionAt = now; ScheduleTask(3, () => this.finishRepairDetour()); } @@ -417,7 +417,7 @@ class WynnProfessionMacro extends ModuleBase { finishRepairDetour() { if (!this.enabled || this.state !== STATES.REPAIR_SELECTING_ITEM) return; - Guis.closeInv(); + closeInventory(); this.currentIndex = this.getClosestPointIndex(); this.lastRepairActionAt = 0; this.state = STATES.IDLE; @@ -441,7 +441,7 @@ class WynnProfessionMacro extends ModuleBase { let closestDistance = Infinity; for (const point of BLACKSMITH_LOCATIONS) { - const distance = MathUtils.fastDistance(Player.getX(), Player.getY(), Player.getZ(), point.x, point.y, point.z); + const distance = fastDistance(Player.getX(), Player.getY(), Player.getZ(), point.x, point.y, point.z); if (distance < closestDistance) { closest = point; closestDistance = distance; @@ -459,7 +459,7 @@ class WynnProfessionMacro extends ModuleBase { const point = this.route[i]; if (!this.isValidPoint(point)) continue; - const distance = MathUtils.fastDistance(Player.getX(), Player.getY(), Player.getZ(), point.x, point.y, point.z); + const distance = fastDistance(Player.getX(), Player.getY(), Player.getZ(), point.x, point.y, point.z); if (distance < closestDistance) { closestDistance = distance; closestIndex = i; @@ -521,7 +521,7 @@ class WynnProfessionMacro extends ModuleBase { } getPerHour() { - const elapsedMs = MacroState.getModuleElapsedMs(this.name); + const elapsedMs = getModuleElapsedMs(this.name); if (elapsedMs <= 0) return '0'; return formatRoundedNumber(this.getTotal() / (elapsedMs / 3600000)); @@ -537,7 +537,7 @@ class WynnProfessionMacro extends ModuleBase { data = raw && raw.trim() ? JSON.parse(raw) : []; } catch (e) { this.message('&cFailed to read Wynn route. Resetting to an empty route.'); - console.error('V5 Caught error' + e + e.stack); + console.error(e); return []; } @@ -547,7 +547,7 @@ class WynnProfessionMacro extends ModuleBase { } saveRoute() { - Utils.writeConfigFile('WynnProfession/route.json', this.route); + writeConfigFile('WynnProfession/route.json', this.route); } normalizePoint(point) { diff --git a/modules/visuals/BlockVisual.js b/modules/visuals/BlockVisual.js index 170a6690..e315c532 100644 --- a/modules/visuals/BlockVisual.js +++ b/modules/visuals/BlockVisual.js @@ -1,6 +1,6 @@ import { Vec3d } from '../../utils/Constants'; import { ModuleBase } from '../../utils/ModuleBase'; -import { Raytrace } from '../../utils/Raytrace'; +import { getLookingAt } from '../../utils/Raytrace'; class BlockVisual extends ModuleBase { constructor() { @@ -50,7 +50,7 @@ class BlockVisual extends ModuleBase { if (lookingAt instanceof Entity) lookingAt = null; if (!lookingAt || lookingAt?.type?.id === 0) { - lookingAt = Raytrace.getLookingAt(this.getDistance()); + lookingAt = getLookingAt(this.getDistance()); } this.currentBlock = lookingAt; diff --git a/modules/visuals/GIF.js b/modules/visuals/GIF.js index 8c408978..1747dd48 100644 --- a/modules/visuals/GIF.js +++ b/modules/visuals/GIF.js @@ -1,4 +1,4 @@ -import { Chat } from '../../utils/Chat'; +import { chat } from '../../utils/Chat'; import { File } from '../../utils/Constants'; import { ModuleBase } from '../../utils/ModuleBase'; import { Utils } from '../../utils/Utils'; @@ -59,7 +59,7 @@ class GifInstance { const gifData = NVG.loadGif(this.absPath); if (!gifData) { - Chat.message(`&c[GIF] Failed to load ${this.name}. This is likely an invalid gif file.`); + chat(`&c[GIF] Failed to load ${this.name}. This is likely an invalid gif file.`); return; } diff --git a/modules/visuals/HUD.js b/modules/visuals/HUD.js index a3a8ffb0..dee05433 100644 --- a/modules/visuals/HUD.js +++ b/modules/visuals/HUD.js @@ -1,7 +1,7 @@ import { BORDER_WIDTH, CORNER_RADIUS, FontSizes, THEME, colorWithAlpha, drawRoundedRectangleWithBorder, drawText, getTextWidth } from '../../gui/Utils'; import { ModuleBase } from '../../utils/ModuleBase'; -import { Utils } from '../../utils/Utils'; -import { ServerInfo } from '../../utils/player/ServerInfo'; +import { getConfigFile, writeConfigFile } from '../../utils/Utils'; +import { getPing, getPingColor, getTPS, getTpsColor } from '../../utils/player/ServerInfo'; import { OverlayManager } from '../../gui/OverlayUtils'; import { GuiState } from '../../gui/core/GuiState'; @@ -22,7 +22,7 @@ class HUD extends ModuleBase { this.addToggle('Stats Hud', (v) => (this.STATS_HUD = !!v), 'Shows FPS, TPS, Ping etc.', true); this.addToggle('Inventory Hud', (v) => (this.INVENTORY_HUD = !!v), 'Turns on the inventory Hud', true); - this.positionConfig = Utils.getConfigFile('OverlayPositions/hud_positions.json') || {}; + this.positionConfig = getConfigFile('OverlayPositions/hud_positions.json') || {}; this.stats = this.loadOverlayState('stats', { x: 10, y: 10, scale: 1.0 }); this.inventory = this.loadOverlayState('inventory', { x: 50, y: 100, scale: 1.0 }); @@ -75,7 +75,7 @@ class HUD extends ModuleBase { } syncFromOverlayEditor() { - const latest = Utils.getConfigFile('OverlayPositions/hud_positions.json'); + const latest = getConfigFile('OverlayPositions/hud_positions.json'); if (!latest || typeof latest !== 'object') return; if (latest.stats && typeof latest.stats === 'object') { @@ -95,7 +95,7 @@ class HUD extends ModuleBase { stats: this.getSaveData(this.stats), inventory: this.getSaveData(this.inventory), }; - Utils.writeConfigFile('OverlayPositions/hud_positions.json', this.positionConfig); + writeConfigFile('OverlayPositions/hud_positions.json', this.positionConfig); } clamp(v, min, max) { @@ -115,13 +115,13 @@ class HUD extends ModuleBase { getStatsLines() { const fps = Client.getFPS(); - const ping = ServerInfo.getPing(); - const tps = ServerInfo.getTPS(); + const ping = getPing(); + const tps = getTPS(); return [ { label: 'FPS', value: String(fps), color: THEME.TEXT }, - { label: 'Ping', value: `${ping}ms`, color: (0xff000000 | ServerInfo.getPingColor(ping)) >>> 0 }, - { label: 'TPS', value: tps.toFixed(2), color: (0xff000000 | ServerInfo.getTpsColor(tps)) >>> 0 }, + { label: 'Ping', value: `${ping}ms`, color: (0xff000000 | getPingColor(ping)) >>> 0 }, + { label: 'TPS', value: tps.toFixed(2), color: (0xff000000 | getTpsColor(tps)) >>> 0 }, ]; } @@ -180,12 +180,12 @@ class HUD extends ModuleBase { NVG.beginFrame(sw, sh); draw.call(this); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } finally { try { NVG.endFrame(); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } } } @@ -333,7 +333,7 @@ class HUD extends ModuleBase { try { this.drawInventoryHudItems(); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } } diff --git a/modules/visuals/MusicOverlay.js b/modules/visuals/MusicOverlay.js index bcf97985..a170a3f0 100644 --- a/modules/visuals/MusicOverlay.js +++ b/modules/visuals/MusicOverlay.js @@ -1,7 +1,7 @@ import requestV2 from 'requestV2'; import { BORDER_WIDTH, CORNER_RADIUS, drawImageFromURL, drawRoundedRectangleWithBorder, drawText, FontSizes, getTextWidth, THEME } from '../../gui/Utils'; import { File, InputStreamReader, isWindows, ProcessBuilder, Runtime, Scanner, globalAssetsDir } from '../../utils/Constants'; -import { Chat } from '../../utils/Chat'; +import { chat } from '../../utils/Chat'; import { streamDownloadToFile } from '../../utils/FileUtils'; import { ModuleBase } from '../../utils/ModuleBase'; import { Executor } from '../../utils/ThreadExecutor'; @@ -314,17 +314,17 @@ class Music extends ModuleBase { Executor.execute(() => { try { - Chat.message('&7WindowsMusicHelper.exe not found. Downloading...'); + chat('&7WindowsMusicHelper.exe not found. Downloading...'); let lastUpdate = -25; streamDownloadToFile(this.windowsExeDownloadUrl, this.exePath, (percent) => { if (percent >= lastUpdate + 25) { - Chat.message(`&7Music helper download: &b${percent}%`); + chat(`&7Music helper download: &b${percent}%`); lastUpdate = percent; } }); - Chat.message('&aWindows music helper installed.'); + chat('&aWindows music helper installed.'); } catch (e) { - Chat.message(`&cWindows music helper download failed: ${e}`); + chat(`&cWindows music helper download failed: ${e}`); console.error(`[Music] Download error: ${e}`); try { if (this.exePath.exists() && this.exePath.length() <= 0) this.exePath.delete(); diff --git a/modules/visuals/PestESP.js b/modules/visuals/PestESP.js index 22adc51b..e78dda05 100644 --- a/modules/visuals/PestESP.js +++ b/modules/visuals/PestESP.js @@ -1,6 +1,6 @@ import { Vec3d } from '../../utils/Constants'; import { ModuleBase } from '../../utils/ModuleBase'; -import { Utils } from '../../utils/Utils'; +import { area } from '../../utils/Utils'; const PEST_NAMES = ['Silverfish', 'Bat']; const PEST_KILL_RADIUS_SQ = 12 ** 2; @@ -38,7 +38,7 @@ class PestESP extends ModuleBase { this.persistentPests = new Map(); this.on('tick', () => { - if (Utils.area() !== 'Garden') return; + if (area() !== 'Garden') return; const now = Date.now(); @@ -58,7 +58,7 @@ class PestESP extends ModuleBase { }); this.when( - () => this.enabled && Utils.area() === 'Garden', + () => this.enabled && area() === 'Garden', 'postRenderWorld', () => { this.persistentPests.forEach((data) => { diff --git a/modules/visuals/ProfileHider.js b/modules/visuals/ProfileHider.js index 65b9decd..661039d6 100644 --- a/modules/visuals/ProfileHider.js +++ b/modules/visuals/ProfileHider.js @@ -1,6 +1,6 @@ -import { Mixin } from '../../utils/MixinManager'; +import { setMixinMethod } from '../../utils/MixinManager'; import { ModuleBase } from '../../utils/ModuleBase'; -import { Utils } from '../../utils/Utils'; +import { getConfigFile } from '../../utils/Utils'; class ProfileHider extends ModuleBase { constructor() { @@ -17,7 +17,7 @@ class ProfileHider extends ModuleBase { this.addToggle('Custom Username', (v) => (this.HIDE_USERNAME = v), 'Allows for custom usernames', true); this.addTextInput('Username', ' ', (v) => (this.USERNAME = v), 'The username you want to use'); - Mixin.setMethod('nameProcessor', (text) => this.getModifiedText(text)); + setMixinMethod('nameProcessor', (text) => this.getModifiedText(text)); } getModifiedText(originalTextComponent) { @@ -38,7 +38,7 @@ class ProfileHider extends ModuleBase { return Text.literal(nameText).styled((s) => s.withColor(colorInt)); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); return Text.literal(rawCustomInput); } } @@ -87,10 +87,10 @@ class ProfileHider extends ModuleBase { getUsername() { try { - const saved = Utils.getConfigFile('AuthCache/do_not_share_this_file')?.username; + const saved = getConfigFile('AuthCache/do_not_share_this_file')?.username; if (saved) return saved; } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); console.error('Failed to load saved username'); } return null; diff --git a/modules/visuals/RatESP.js b/modules/visuals/RatESP.js index 4f607447..c0adfae5 100644 --- a/modules/visuals/RatESP.js +++ b/modules/visuals/RatESP.js @@ -1,6 +1,6 @@ import { ZombieEntity, Vec3d } from '../../utils/Constants'; import { ModuleBase } from '../../utils/ModuleBase'; -import { Utils } from '../../utils/Utils'; +import { area } from '../../utils/Utils'; const RAT_WIDTH = 0.49; const RAT_HEIGHT = 0.99; @@ -9,11 +9,11 @@ const WORLD_TICK_MS = 50; const approxEqual = (a, b, epsilon = EPSILON) => Math.abs(a - b) <= epsilon; -export function isRatEntity(entity) { +function isRatEntity(entity) { return !!entity && !entity.isDead() && isRawRatEntity(entity); } -export function isRawRatEntity(entity) { +function isRawRatEntity(entity) { return !!entity && approxEqual(entity.getWidth(), RAT_WIDTH) && approxEqual(entity.getHeight(), RAT_HEIGHT); } @@ -22,12 +22,12 @@ export function getRatId(entity) { } export function getHubRats() { - if (!World.isLoaded() || Utils.area() !== 'Hub') return []; + if (!World.isLoaded() || area() !== 'Hub') return []; return getRawHubRats().filter((entity) => isRatEntity(entity)); } export function getRawHubRats() { - if (!World.isLoaded() || Utils.area() !== 'Hub') return []; + if (!World.isLoaded() || area() !== 'Hub') return []; return World.getAllEntitiesOfType(ZombieEntity).filter((entity) => isRawRatEntity(entity)); } @@ -51,7 +51,7 @@ class RatESP extends ModuleBase { }); this.when( - () => this.enabled && World.isLoaded() && Utils.area() === 'Hub' && this.rats.length > 0, + () => this.enabled && World.isLoaded() && area() === 'Hub' && this.rats.length > 0, 'postRenderWorld', () => this.renderRats() ); @@ -63,7 +63,7 @@ class RatESP extends ModuleBase { } scanRats() { - if (!this.enabled || !World.isLoaded() || Utils.area() !== 'Hub') { + if (!this.enabled || !World.isLoaded() || area() !== 'Hub') { this.rats = []; return; } diff --git a/modules/visuals/StructureESP.js b/modules/visuals/StructureESP.js index c4cb0efe..e4a0f863 100644 --- a/modules/visuals/StructureESP.js +++ b/modules/visuals/StructureESP.js @@ -72,7 +72,7 @@ class StructureESP extends ModuleBase { RenderUtils.drawText(name, pos.add(0, 8.5, 0), 7.5, true, false, true); } } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } } } diff --git a/utils/BazaarUtil.js b/utils/BazaarUtil.js index 21ff5f09..4082d2ea 100644 --- a/utils/BazaarUtil.js +++ b/utils/BazaarUtil.js @@ -1,6 +1,6 @@ -import { Guis } from './player/Inventory'; -import { Sign } from './Sign'; -import { Utils } from './Utils'; +import { clickSlot, closeInventory, getGuiName } from './player/Inventory'; +import { setSignLine } from './Sign'; +import { randomInt } from './Utils'; import { farmingDelays } from '../modules/farming/FarmingDelays'; const TIMEOUT = 10_000; @@ -42,10 +42,10 @@ class BazaarUtil { switch (this.state) { case 'bazaar': { - if (!this.clean(Guis.guiName()).includes('bazaar')) return; + if (!this.clean(getGuiName()).includes('bazaar')) return; const slot = this.findSlot(this.itemName, 10, 42); if (slot === -1) return; - if (!Guis.clickSlot(slot)) return this.finish(false); + if (!clickSlot(slot)) return this.finish(false); this.setState('buy instantly'); return; } @@ -55,7 +55,7 @@ class BazaarUtil { return this.clickNamed('Custom Amount', 'sign'); case 'sign': if (!this.isSignOpen()) return; - Sign.setLine(1, this.amount); + setSignLine(1, this.amount); Client.currentGui.close(); this.setState('confirm amount'); return; @@ -66,7 +66,7 @@ class BazaarUtil { if (!Number.isFinite(price)) return; if (!Number.isFinite(this.maxPrice) || price > this.maxPrice) return this.finish(false); this.confirmSlot = slot; - if (!Guis.clickSlot(slot)) return this.finish(false); + if (!clickSlot(slot)) return this.finish(false); this.setState('warning', 500); return; } @@ -75,11 +75,11 @@ class BazaarUtil { this.setState('warning change'); return; } - Guis.closeInv(); + closeInventory(); return this.finish(true); case 'warning change': if (this.isSlotNamed(this.confirmSlot, 'Warning')) return; - if (!Guis.clickSlot(this.confirmSlot)) return this.finish(false); + if (!clickSlot(this.confirmSlot)) return this.finish(false); return this.finish(true); } } @@ -87,7 +87,7 @@ class BazaarUtil { clickNamed(name, nextState) { const slot = this.findSlot(name); if (slot === -1) return false; - if (!Guis.clickSlot(slot)) return false; + if (!clickSlot(slot)) return false; this.setState(nextState); return true; } @@ -123,7 +123,7 @@ class BazaarUtil { .toLowerCase(); } - setState(state, delay = Utils.randomInt(farmingDelays.bazaarActionDelayMin, farmingDelays.bazaarActionDelayMax)) { + setState(state, delay = randomInt(farmingDelays.bazaarActionDelayMin, farmingDelays.bazaarActionDelayMax)) { this.state = state; this.deadline = Date.now() + TIMEOUT; this.waitUntil = Date.now() + delay; @@ -134,9 +134,13 @@ class BazaarUtil { this.state = 'idle'; this.callback = null; this.confirmSlot = -1; - if (Client.isInGui()) Guis.closeInv(); + if (Client.isInGui()) closeInventory(); if (typeof callback === 'function') callback(success); } } -export const bazaarUtil = new BazaarUtil(); +const bazaar = new BazaarUtil(); + +export const buyFromBazaar = (...args) => bazaar.buy(...args); +export const cancelBazaarPurchase = () => bazaar.cancel(); +export const bazaarUtil = { buy: buyFromBazaar, cancel: cancelBazaarPurchase }; diff --git a/utils/Camera.js b/utils/Camera.js index b179430c..ae1c8333 100644 --- a/utils/Camera.js +++ b/utils/Camera.js @@ -1,32 +1,17 @@ -import { Mixin } from './MixinManager'; -import { Utils } from './Utils'; +import { deleteMixinValue, setMixinValue } from './MixinManager'; +import { convertToVector } from './Utils'; -class CameraUtils { - /** - * Override the player's camera position. Pass null/undefined to clear. - * @param {Vec3d|Object|Array|Player|Entity|BlockPos} vec - * @returns {boolean} true when a valid override was set, false otherwise - */ - setCameraPosition(vec) { - if (vec == null) { - Mixin.delete('cameraOverridePos'); - return false; - } - - const converted = Utils.convertToVector(vec); - if (!converted) return false; - - Mixin.set('cameraOverridePos', converted); - return true; +export function setCameraPosition(vec) { + if (vec == null) { + clearCameraPosition(); + return false; } - clearCameraPosition() { - Mixin.delete('cameraOverridePos'); - } + const converted = convertToVector(vec); + if (!converted) return false; - getCameraPosition() { - return Mixin.get('cameraOverridePos', null); - } + setMixinValue('cameraOverridePos', converted); + return true; } -export const Camera = new CameraUtils(); +export const clearCameraPosition = () => deleteMixinValue('cameraOverridePos'); diff --git a/utils/Chat.js b/utils/Chat.js index a1ea28c6..2f376409 100644 --- a/utils/Chat.js +++ b/utils/Chat.js @@ -1,124 +1,30 @@ import FailsafeUtils from '../failsafes/FailsafeUtils'; import { isDeveloperModeEnabled } from './DeveloperModeState'; -class ChatClass { - message(msg) { - this._sendGradient('V5 »', msg); - } +const sendGradient = (prefix, ...args) => { + if (!args.length) return; + Client.getMinecraft().execute(() => GradientChat.sendGradientMsg(prefix, 0x05b9f9, 0x0539f9, ...args)); +}; - messageDebug(msg) { - if (!isDeveloperModeEnabled()) return; +export const chat = (message) => sendGradient('V5 »', message); - this._sendGradient(`V5 Debug »`, msg); - } - - messageClip(msg) { - this._sendGradient('V5 Clipping »', msg); - } - - messageIrc(msg) { - this._sendGradient('IRC »', msg); - } - - sendAnnouncement(msg) { - if (!msg) return; - Client.getMinecraft().execute(() => { - GradientChat.sendGradientMsg('V5 Announcement »', 0xf4a261, 0xe76f51, msg); - }); - } - - messageFailsafe(msg, sendIntensity = true) { - this._sendGradient('V5 Failsafes »', msg); - if (sendIntensity) this._sendGradient('V5 Failsafes »', '&c&lCurrent intensity: ' + FailsafeUtils.getIntensity()); - } - - messagePathfinder(msg) { - this._sendGradient('V5 Pathfinding »', msg); - } - - messageScheduler(msg) { - this._sendGradient('V5 Scheduler »', msg); - } - - _sendGradient(prefix, ...args) { - if (args.length === 0) return; - - Client.getMinecraft().execute(() => { - GradientChat.sendGradientMsg(prefix, 0x05b9f9, 0x0539f9, ...args); - }); - } - - log(msg) { - if (!msg) return; - console.log('V5 » ' + msg); - } - - /** - * Formats a message with clickable links. - * @param {string[]} args - * @returns {TextComponent} The formatted message - */ - formatLink(...args) { - if (args.length === 3 && typeof args[2] === 'string' && args[2].includes('http')) { - const [message, label, url] = args; +export function sendDebugMessage(message) { + if (isDeveloperModeEnabled()) sendGradient('V5 Debug »', message); +} - return new TextComponent( - `${message} `, - new TextComponent({ - text: `§9§n${label}§r`, - clickEvent: { - action: 'open_url', - value: url, - }, - hoverEvent: { - action: 'show_text', - value: `§7Click to open`, - }, - }) - ); - } +export function sendFailsafeMessage(message, includeIntensity = true) { + sendGradient('V5 Failsafes »', message); + if (includeIntensity) sendGradient('V5 Failsafes »', '&c&lCurrent intensity: ' + FailsafeUtils.getIntensity()); +} - let components = []; - for (const [i, component] of args.entries()) { - if (typeof component === 'string' && !component.includes('http')) { - components.push(component); - } else { - components.push( - new TextComponent({ - text: `§9§n${component}§r`, - clickEvent: { action: 'open_url', value: component }, - hoverEvent: { action: 'show_text', value: '§7Click to open' }, - }) - ); - } - if (i < args.length - 1) components.push(' '); - } - return new TextComponent(...components); - } +export const sendIrcMessage = (message) => sendGradient('IRC »', message); +export const sendPathfinderMessage = (message) => sendGradient('V5 Pathfinding »', message); - /** - * Creates a clickable text component - * @param {string} actionText - The text shown in chat - * @param {string} actionValue - The path, URL, or command - * @param {string} hoverText - The tooltip shown on hover - * @param {string} actionType - Defaults to 'open_file', can be 'open_url' or 'run_command' - */ - clickAction(message, actionText, actionValue, hoverText = '§7Click to open', actionType = 'open_file') { - return new TextComponent( - `${message} `, - new TextComponent({ - text: `§9§n${actionText}§r`, - clickEvent: { - action: actionType, - value: actionValue, - }, - hoverEvent: { - action: 'show_text', - value: hoverText, - }, - }) - ); - } +export function sendAnnouncement(message) { + if (!message) return; + Client.getMinecraft().execute(() => GradientChat.sendGradientMsg('V5 Announcement »', 0xf4a261, 0xe76f51, message)); } -export const Chat = new ChatClass(); +export function logMessage(message) { + if (message) console.log('V5 » ' + message); +} diff --git a/utils/CommissionUtils.js b/utils/CommissionUtils.js index 8aba1be1..5c2f4dec 100644 --- a/utils/CommissionUtils.js +++ b/utils/CommissionUtils.js @@ -1,7 +1,7 @@ -import { MathUtils } from './Math'; +import { distanceToPlayerPoint, fastDistance } from './Math'; import { EtherwarpPathfinder } from './pathfinder/EtherwarpPathfinder'; import Pathfinder from './pathfinder/PathFinder'; -import { Guis } from './player/Inventory'; +import { clickSlot, findItemInHotbar, getGuiName, setItemSlot } from './player/Inventory'; import { Rotations } from './player/Rotations'; export class CommissionClaimer { @@ -22,7 +22,7 @@ export class CommissionClaimer { handle() { if (!Player.getPlayer()) return; - if (Guis.guiName() === 'Commissions') { + if (getGuiName() === 'Commissions') { const container = Player.getContainer(); if (!container) return; @@ -34,10 +34,10 @@ export class CommissionClaimer { return; } - const pigeonSlot = Guis.findItemInHotbar('Royal Pigeon'); + const pigeonSlot = findItemInHotbar('Royal Pigeon'); if (pigeonSlot !== -1) { if (Player.getHeldItemIndex() !== pigeonSlot) { - Guis.setItemSlot(pigeonSlot); + setItemSlot(pigeonSlot); this.delay(3); } else { Client.rightClick(); @@ -50,7 +50,7 @@ export class CommissionClaimer { if (!locations.length) return; const closest = this.getClosestLocation(locations); - const closestDist = MathUtils.fastDistance(Player.getX(), Player.getY(), Player.getZ(), ...closest); + const closestDist = fastDistance(Player.getX(), Player.getY(), Player.getZ(), ...closest); const target = [closest[0] + 0.5, closest[1] + 1.8, closest[2] + 0.5]; if (closest[1] - Player.getY() > 3 && closestDist < 10) { @@ -58,7 +58,7 @@ export class CommissionClaimer { return; } - if (MathUtils.distanceToPlayerPoint(target) <= 3 && !this.isPathing()) { + if (distanceToPlayerPoint(target) <= 3 && !this.isPathing()) { if (!this.ensureToolEquipped()) return; if (Math.abs(Player.getMotionX()) + Math.abs(Player.getMotionZ()) >= 0.04) return; @@ -117,8 +117,8 @@ export class CommissionClaimer { getClosestLocation(locations) { return locations.reduce((closest, location) => { - const closestDist = MathUtils.fastDistance(Player.getX(), Player.getY(), Player.getZ(), ...closest); - const locationDist = MathUtils.fastDistance(Player.getX(), Player.getY(), Player.getZ(), ...location); + const closestDist = fastDistance(Player.getX(), Player.getY(), Player.getZ(), ...closest); + const locationDist = fastDistance(Player.getX(), Player.getY(), Player.getZ(), ...location); return locationDist < closestDist ? location : closest; }); } @@ -142,7 +142,7 @@ function claimCompletedCommission(container) { if (!stack) continue; if (!(stack.getLore() || []).some((line) => String(line).includes('COMPLETED'))) continue; - Guis.clickSlot(i, false); + clickSlot(i, false); return true; } return false; diff --git a/utils/Config.js b/utils/Config.js index e03dace2..16fea29b 100644 --- a/utils/Config.js +++ b/utils/Config.js @@ -1,4 +1,4 @@ -import { Chat } from './Chat'; +import { chat } from './Chat'; import { File, Files, StandardCopyOption, globalAssetsDir } from './Constants'; const SOURCE_SOUNDS_DIR = new File('./config/ChatTriggers/modules/V5/failsafes/sounds'); @@ -41,7 +41,7 @@ function isValidJson(path) { JSON.parse(FileLib.read(CONFIG_ROOT, path)); return true; } catch (e) { - Chat.message(`§cRepairing corrupted data: ${path}`); + chat(`§cRepairing corrupted data: ${path}`); console.error('V5 Caught error' + e + e.stack); FileLib.delete(CONFIG_ROOT, path); return false; diff --git a/utils/Constants.js b/utils/Constants.js index fcfa0c1f..a70924e4 100644 --- a/utils/Constants.js +++ b/utils/Constants.js @@ -1,91 +1,51 @@ -export const SharedConstants = net.minecraft.SharedConstants; -export const MinecraftClient = net.minecraft.client.Minecraft; export const MCHand = net.minecraft.world.InteractionHand; export const CLIENT_VERSION = '1.0.0'; -export const UMatrixStack = Java.type('gg.essential.universal.UMatrixStack').Compat.INSTANCE; -export const ConcurrentLinkedQueue = java.util.concurrent.ConcurrentLinkedQueue; -export const AtomicBoolean = java.util.concurrent.atomic.AtomicBoolean; export const StandardCharsets = java.nio.charset.StandardCharsets; export const BufferedInputStream = java.io.BufferedInputStream; export const DataFlavor = java.awt.datatransfer.DataFlavor; export const InputStreamReader = java.io.InputStreamReader; export const BufferedReader = java.io.BufferedReader; -export const FileWriter = java.io.FileWriter; export const FileOutputStream = java.io.FileOutputStream; -export const FileInputStream = java.io.FileInputStream; -export const DataOutputStream = java.io.DataOutputStream; -export const MessageType = java.awt.TrayIcon.MessageType; export const ProcessBuilder = java.lang.ProcessBuilder; -export const TimeUnit = java.util.concurrent.TimeUnit; export const Files = java.nio.file.Files; export const StandardCopyOption = java.nio.file.StandardCopyOption; -export const ArrayLists = java.util.ArrayList; -export const SystemTray = java.awt.SystemTray; -export const TrayIcon = java.awt.TrayIcon; export const Runtime = java.lang.Runtime; export const Scanner = java.util.Scanner; export const Toolkit = java.awt.Toolkit; export const GLFW = org.lwjgl.glfw.GLFW; -export const Desktop = java.awt.Desktop; export const System = java.lang.System; -export const Base64 = java.util.Base64; export const Color = java.awt.Color; export const File = java.io.File; export const URL = java.net.URL; -export const OS = System.getProperty('os.name').toLowerCase(); -export const isWindows = OS.includes('win'); -export const isMac = OS.includes('mac'); -export const isLinux = OS.includes('nux') || OS.includes('nix'); +const os = System.getProperty('os.name').toLowerCase(); +export const isWindows = os.includes('win'); +export const isLinux = os.includes('nux') || os.includes('nix'); +export const isMac = os.includes('mac'); export const globalAssetsDir = new File('./config/ChatTriggers/assets'); -export const FFMPEG_URLS = { - WIN_ZIP: 'https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-win64-gpl.zip', - LINUX_TAR_XZ: 'https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-linux64-gpl.tar.xz', - MAC_BINARY: 'https://evermeet.cx/ffmpeg/ffmpeg-8.0.1', -}; - export const BP = net.minecraft.core.BlockPos; export const Vec3d = net.minecraft.world.phys.Vec3; export const Direction = net.minecraft.core.Direction; export const BlockHitResult = net.minecraft.world.phys.BlockHitResult; -export const VoxelShapes = net.minecraft.world.phys.shapes.Shapes; export const Blocks = net.minecraft.world.level.block.Blocks; export const SnowBlock = net.minecraft.world.level.block.SnowLayerBlock; -export const StainedGlassPaneBlock = net.minecraft.world.level.block.StainedGlassPaneBlock; export const ArmorStandEntity = net.minecraft.world.entity.decoration.ArmorStand; export const ZombieEntity = net.minecraft.world.entity.monster.zombie.Zombie; -export const EndermanEntity = net.minecraft.world.entity.monster.EnderMan; -export const BatEntity = net.minecraft.world.entity.ambient.Bat; -export const PortalParticle = net.minecraft.client.particle.PortalParticle; // pls rename to the correct name idk what it is +export const PortalParticle = net.minecraft.client.particle.PortalParticle; -export const MinecraftText = net.minecraft.network.chat.Component; -export const Formatting = net.minecraft.ChatFormatting; export const SoundCategory = net.minecraft.sounds.SoundSource; export const Identifier = net.minecraft.resources.Identifier; export const SoundEvent = net.minecraft.sounds.SoundEvent; -export const NativeImage = com.mojang.blaze3d.platform.NativeImage; -export const Transferable = java.awt.datatransfer.Transferable; export const Consumer = java.util.function.Consumer; export const ScreenshotRecorder = net.minecraft.client.Screenshot; -export const ImageIO = Java.type('javax.imageio.ImageIO'); -export const BufferedImage = Java.type('java.awt.image.BufferedImage'); -export const AlphaComposite = Java.type('java.awt.AlphaComposite'); -export const Matrix = UMatrixStack.get(); -export const modulesDir = new File('./config/ChatTriggers/modules'); -export const V5ConfigFile = new File(`${modulesDir}/V5Config/config.json`); +export const V5ConfigFile = new File('./config/ChatTriggers/modules/V5Config/config.json'); export const Links = { WEBSOCKET_URL: 'wss://backend.rdbt.top/api/chat', BASE_API_URL: 'https://backend.rdbt.top', PATHFINDER_API_URL: 'http://localhost:3000', }; - -// export const Links = { -// WEBSOCKET_URL: 'ws://127.0.0.1:8787/api/chat', -// BASE_API_URL: 'http://127.0.0.1:8787', -// PATHFINDER_API_URL: 'http://localhost:3000', -// }; diff --git a/utils/Etherwarp.js b/utils/Etherwarp.js index 3a634a12..21524865 100644 --- a/utils/Etherwarp.js +++ b/utils/Etherwarp.js @@ -1,4 +1,4 @@ -import { Utils } from './Utils'; +import { area } from './Utils'; const MODERN_ETHERWARP_AREAS = new Set([ 'Hub', @@ -18,19 +18,18 @@ const ETHERWARP_PLAYER_EYE_HEIGHT = 1.62; const ETHERWARP_LEGACY_SNEAK_OFFSET = 0.08; const ETHERWARP_MODERN_SNEAK_OFFSET = 0.35; -export const EtherwarpPathState = { - handler: null, -}; +let pathHandler = null; -export const isModernEtherwarpArea = (area = Utils.area()) => MODERN_ETHERWARP_AREAS.has(area || ''); +export const setEtherwarpPathHandler = (handler) => (pathHandler = handler); +export const getEtherwarpPathHandler = () => pathHandler; -export const getEtherwarpSneakOffset = (area = Utils.area()) => (isModernEtherwarpArea(area) ? ETHERWARP_MODERN_SNEAK_OFFSET : ETHERWARP_LEGACY_SNEAK_OFFSET); +const isModernEtherwarpArea = (areaName = area()) => MODERN_ETHERWARP_AREAS.has(areaName || ''); -export const getEtherwarpEyeHeight = (player = Player.getPlayer(), area = Utils.area()) => 1 + ETHERWARP_PLAYER_EYE_HEIGHT - getEtherwarpSneakOffset(area); +const getEtherwarpSneakOffset = (areaName = area()) => (isModernEtherwarpArea(areaName) ? ETHERWARP_MODERN_SNEAK_OFFSET : ETHERWARP_LEGACY_SNEAK_OFFSET); -export const getEtherwarpEyeCoords = (forceSneak = false, player = Player.getPlayer(), area = Utils.area()) => { +export const getEtherwarpEyeCoords = (forceSneak = false, player = Player.getPlayer(), areaName = area()) => { if (!player) return null; - const eyeY = forceSneak ? player.getY() + ETHERWARP_PLAYER_EYE_HEIGHT - getEtherwarpSneakOffset(area) : player.getEyePosition().y(); + const eyeY = forceSneak ? player.getY() + ETHERWARP_PLAYER_EYE_HEIGHT - getEtherwarpSneakOffset(areaName) : player.getEyePosition().y(); return [player.getX(), eyeY, player.getZ()]; }; diff --git a/utils/FileUtils.js b/utils/FileUtils.js index 42623455..add3bd85 100644 --- a/utils/FileUtils.js +++ b/utils/FileUtils.js @@ -13,7 +13,7 @@ function closeQuietly(resource) { try { resource.close(); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } } @@ -29,7 +29,7 @@ function resolveDestinationPath(destination) { return destination && typeof destination.getAbsolutePath === 'function' ? destination.getAbsolutePath() : String(destination); } -export function ensureDirectory(dir) { +function ensureDirectory(dir) { if (!dir) return; if (typeof dir.mkdirs !== 'function' || typeof dir.exists !== 'function') return; if (!dir.exists()) dir.mkdirs(); @@ -76,7 +76,7 @@ export function streamDownloadToFile(url, destination, onProgress = null, buffer } } -export function streamDownloadToFileAsync(url, destination, options = {}) { +export function downloadFile(url, destination, options = {}) { options = options || {}; const { onProgress = null, onError = null, onComplete = null, bufferSize = DEFAULT_DOWNLOAD_BUFFER_SIZE } = options; @@ -86,7 +86,7 @@ export function streamDownloadToFileAsync(url, destination, options = {}) { if (onComplete) onComplete(); } catch (e) { if (onError) onError(e); - else console.error('V5 Caught error' + e + e.stack); + else console.error(e); } }); @@ -94,40 +94,3 @@ export function streamDownloadToFileAsync(url, destination, options = {}) { t.start(); return t; } - -export const downloadFile = streamDownloadToFileAsync; - -export function findFileRecursive(rootDir, fileName) { - if (!rootDir || typeof rootDir.listFiles !== 'function') return null; - const files = rootDir.listFiles(); - if (!files) return null; - - for (const file of files) { - if (file.isDirectory()) { - const nested = findFileRecursive(file, fileName); - if (nested) return nested; - continue; - } - - if (file.getName() === fileName) return file; - } - - return null; -} - -export function deleteRecursive(target) { - if (!target || !target.exists()) return; - - if (target.isDirectory()) { - const children = target.listFiles(); - if (children) { - for (const child of children) deleteRecursive(child); - } - } - - try { - target.delete(); - } catch (e) { - console.error('V5 Caught error' + e + e.stack); - } -} diff --git a/utils/Flowstate.js b/utils/Flowstate.js index f8a2b54b..310d1a54 100644 --- a/utils/Flowstate.js +++ b/utils/Flowstate.js @@ -1,86 +1,60 @@ -import { Chat } from './Chat'; +import { chat } from './Chat'; import { ClientboundBlockUpdatePacket } from './Packets'; -class FlowstateUtilsClass { - constructor() { - this.countdown = 0; - this.multiplier = 1; - this.flowstateBlocksBroken = 0; - this.isMax = false; - - this.block = { x: 0, y: 0, z: 0 }; - this.currentBlock = null; - - register('playerInteract', (action, object) => { - if (String(action) === 'AttackBlock') { - const typeName = object?.type?.name ? String(object.type.name).toLowerCase() : ''; - if (typeName && !typeName.includes('bedrock')) { - this.block.x = object.getX(); - this.block.y = object.getY(); - this.block.z = object.getZ(); - this.currentBlock = object; - } else { - this.block.x = this.block.y = this.block.z = 0; - } - } - }); - - register('packetReceived', (packet) => { - const heldItem = Player.getHeldItem(); - if (!heldItem) return; - - let lore = heldItem - .getLore() - .map((l) => ChatLib.removeFormatting(l)) - .join(' '); - - let match = lore.match(/flowstate\s*(i{1,3})/i); - const roman = { I: 1, II: 2, III: 3 }; - let bonus = match ? roman[match[1].toUpperCase()] || 0 : 0; - - if ( - match && - packet?.getPos()?.getX() == this.block.x && - packet?.getPos()?.getY() == this.block.y && - packet?.getPos()?.getZ() == this.block.z && - (packet?.getBlockState()?.getBlock()?.toString()?.includes('bedrock') || packet?.getBlockState()?.getBlock()?.toString()?.includes('air')) - ) { - this.flowstateBlocksBroken += bonus; - this.countdown = 10; - - if (this.isMax) return; - - if (this.flowstateBlocksBroken > 100 * this.multiplier) { - if (this.multiplier === 6) { - this.isMax = true; - return Chat.message('Reached max Flowstate!'); - } - - this.multiplier++; - - let rounded = Math.floor(this.flowstateBlocksBroken / 100) * 100; - Chat.message(`Current Flowstate: ${rounded}`); - } - } - }).setFilteredClass(ClientboundBlockUpdatePacket); - - register('step', () => { - if (this.countdown === 0) { - if (this.flowstateBlocksBroken > 100) { - Chat.message(`Flowstate lost at ${this.flowstateBlocksBroken} blocks`); - } - this.isMax = false; - this.flowstateBlocksBroken = 0; - } - - if (this.countdown > 0) this.countdown--; - if (this.isMax) this.flowstateBlocksBroken = 600; - }).setFps(1); +let countdown = 0; +let multiplier = 1; +let blocksBroken = 0; +let isMax = false; +let block = { x: 0, y: 0, z: 0 }; + +register('playerInteract', (action, target) => { + if (String(action) !== 'AttackBlock') return; + const type = String(target?.type?.name || '').toLowerCase(); + block = type && !type.includes('bedrock') ? { x: target.getX(), y: target.getY(), z: target.getZ() } : { x: 0, y: 0, z: 0 }; +}); + +register('packetReceived', (packet) => { + const heldItem = Player.getHeldItem(); + if (!heldItem) return; + const match = heldItem + .getLore() + .map((line) => ChatLib.removeFormatting(line)) + .join(' ') + .match(/flowstate\s*(i{1,3})/i); + const bonus = match ? { I: 1, II: 2, III: 3 }[match[1].toUpperCase()] || 0 : 0; + const position = packet?.getPos?.(); + const state = String(packet?.getBlockState?.()?.getBlock?.() || ''); + if ( + !match || + position?.getX() != block.x || + position?.getY() != block.y || + position?.getZ() != block.z || + (!state.includes('bedrock') && !state.includes('air')) + ) + return; + + blocksBroken += bonus; + countdown = 10; + if (isMax || blocksBroken <= 100 * multiplier) return; + if (multiplier === 6) { + isMax = true; + chat('Reached max Flowstate!'); + return; } - - CurrentFlowstate() { - return Math.min(600, this.flowstateBlocksBroken); + multiplier++; + chat(`Current Flowstate: ${Math.floor(blocksBroken / 100) * 100}`); +}).setFilteredClass(ClientboundBlockUpdatePacket); + +register('step', () => { + if (countdown === 0) { + if (blocksBroken > 100) chat(`Flowstate lost at ${blocksBroken} blocks`); + isMax = false; + blocksBroken = 0; + } else { + countdown--; } -} + if (isMax) blocksBroken = 600; +}).setFps(1); -export const Flowstate = new FlowstateUtilsClass(); +export const getCurrentFlowstate = () => Math.min(600, blocksBroken); +export const Flowstate = { CurrentFlowstate: getCurrentFlowstate }; diff --git a/utils/MacroState.js b/utils/MacroState.js index 5cc2cfcf..f1bdc426 100644 --- a/utils/MacroState.js +++ b/utils/MacroState.js @@ -1,196 +1,122 @@ -import { Chat } from './Chat'; -import { TimeUtils } from './TimeUtils'; -import { Utils } from './Utils'; - -class MacroStateClass { - constructor() { - this.running = false; - this.activeMacro = null; - this.startTime = 0; - this.enabledMacros = new Set(); - this.macroStartTimes = new Map(); - this.sessionResumeWindowMs = 5 * 60 * 1000; - - this.modules = new Map(); - this.lastDisableMeta = new Map(); - this.lastActiveMacros = []; - - this.lastMacroToggleKey = null; - this.hasBoundLastMacroToggleKey = false; - this.lastMacroToggleTitle = 'Global Toggle Last Used Macro'; - } +import { chat } from './Chat'; +import { formatDurationMs, formatUptime } from './TimeUtils'; +import { getConfigFile, writeConfigFile } from './Utils'; + +const SESSION_RESUME_WINDOW_MS = 5 * 60 * 1000; +const LAST_MACRO_TOGGLE_TITLE = 'Global Toggle Last Used Macro'; + +export const modules = new Map(); +const enabledMacros = new Set(); +const macroStartTimes = new Map(); +const lastDisableMeta = new Map(); +let lastActiveMacros = []; +let running = false; +let activeMacro = null; +let startTime = 0; +let lastMacroToggleKey = null; +let hasBoundLastMacroToggleKey = false; + +const getLastActiveMacro = () => lastActiveMacros[0] || null; +export const getLastActiveMacros = () => lastActiveMacros; +export const getModule = (name) => modules.get(name); +export const isMacroRunning = () => running; +export const getActiveMacro = () => activeMacro; +export const getStartTime = () => startTime; +export const getEnabledMacros = () => Array.from(enabledMacros); +export const getLastDisableMeta = (name) => (name ? lastDisableMeta.get(name) || null : null); +export const getModuleStartTime = (name) => (name ? macroStartTimes.get(name) || 0 : 0); + +export function registerModule(module) { + if (module.name) modules.set(module.name, module); +} - getLastActiveMacro() { - return this.lastActiveMacros[0] || null; +export function isFailsafeMacroRunning() { + for (const name of enabledMacros) { + const module = getModule(name); + if (module?.isMacro && module.ignoreFailsafes !== true) return true; } + return false; +} - getLastActiveMacros() { - return this.lastActiveMacros; - } +export function onModuleEnabled(moduleName) { + const module = getModule(moduleName); + if (!moduleName || !module?.isMacro) return; - registerModule(module) { - if (module.name) { - this.modules.set(module.name, module); - } + const wasEmpty = enabledMacros.size === 0; + const now = Date.now(); + enabledMacros.add(moduleName); + if (!macroStartTimes.has(moduleName)) { + const last = getLastDisableMeta(moduleName); + const canResume = last && typeof last.timestamp === 'number' && typeof last.durationMs === 'number' && now - last.timestamp <= SESSION_RESUME_WINDOW_MS; + macroStartTimes.set(moduleName, canResume ? now - last.durationMs : now); } - getModule(name) { - return this.modules.get(name); - } + if (wasEmpty) startTime = getModuleStartTime(moduleName); + running = true; + activeMacro = moduleName; + lastActiveMacros = lastActiveMacros.filter((name) => name !== moduleName); + lastActiveMacros.unshift(moduleName); +} - getMacroNames() { - const names = []; - this.modules.forEach((module, name) => { - if (module.isMacro) names.push(name); - }); - return names; - } +export function onModuleDisabled(moduleName, context = 'user') { + if (!moduleName || !enabledMacros.has(moduleName)) return; - isMacroRunning() { - return this.running; - } + const now = Date.now(); + const moduleStart = getModuleStartTime(moduleName); + lastDisableMeta.set(moduleName, { context: context || 'user', timestamp: now, durationMs: moduleStart ? now - moduleStart : 0 }); + enabledMacros.delete(moduleName); + macroStartTimes.delete(moduleName); - getActiveMacro() { - return this.activeMacro; + if (!enabledMacros.size) { + running = false; + activeMacro = null; + startTime = 0; + } else { + activeMacro = Array.from(enabledMacros).pop(); } +} - getStartTime() { - return this.startTime; - } +export function getModuleDuration(moduleName) { + const moduleStart = getModuleStartTime(moduleName); + if (moduleStart) return formatUptime(moduleStart); + const duration = getLastDisableMeta(moduleName)?.durationMs || 0; + return duration > 0 ? formatDurationMs(duration) : ''; +} - getEnabledMacros() { - return Array.from(this.enabledMacros); - } +export function getModuleElapsedMs(moduleName) { + const moduleStart = getModuleStartTime(moduleName); + return moduleStart ? Date.now() - moduleStart : getLastDisableMeta(moduleName)?.durationMs || 0; +} - isFailsafeMacroRunning() { - for (const macroName of this.enabledMacros) { - const module = this.getModule(macroName); - if (!module?.isMacro) continue; - if (module.ignoreFailsafes === true) continue; - return true; - } +function toggleLastUsedMacroFromUser() { + const macroName = getLastActiveMacro(); + if (!macroName) { + chat('&eNo recently used macro to toggle.'); return false; } - onModuleEnabled(moduleName) { - if (!moduleName) return; - const module = this.getModule(moduleName); - if (!module || !module.isMacro) return; - - const wasEmpty = this.enabledMacros.size === 0; - const now = Date.now(); - this.enabledMacros.add(moduleName); - if (!this.macroStartTimes.has(moduleName)) { - const lastMeta = this.getLastDisableMeta(moduleName); - const canResume = - lastMeta && - typeof lastMeta.timestamp === 'number' && - typeof lastMeta.durationMs === 'number' && - now - lastMeta.timestamp <= this.sessionResumeWindowMs; - this.macroStartTimes.set(moduleName, canResume ? now - lastMeta.durationMs : now); - } - - if (wasEmpty) { - this.startTime = this.getModuleStartTime(moduleName); - } - - this.running = true; - this.activeMacro = moduleName; - this.trackLastActiveMacro(moduleName); - } - - onModuleDisabled(moduleName, context = 'user') { - if (!moduleName) return; - if (!this.enabledMacros.has(moduleName)) return; - - this.lastDisableMeta.set(moduleName, this.captureDisableMeta(moduleName, context)); - this.enabledMacros.delete(moduleName); - this.macroStartTimes.delete(moduleName); - - if (this.enabledMacros.size === 0) { - this.running = false; - this.activeMacro = null; - this.startTime = 0; - } else { - const remaining = Array.from(this.enabledMacros); - this.activeMacro = remaining[remaining.length - 1]; - } - } - - getLastDisableMeta(moduleName) { - return moduleName ? this.lastDisableMeta.get(moduleName) || null : null; - } - - getModuleStartTime(moduleName) { - return moduleName ? this.macroStartTimes.get(moduleName) || 0 : 0; - } - - getModuleDuration(moduleName) { - const startTime = this.getModuleStartTime(moduleName); - if (startTime) return TimeUtils.formatUptime(startTime); - const durationMs = this.getLastDisableMeta(moduleName)?.durationMs || 0; - return durationMs > 0 ? TimeUtils.formatDurationMs(durationMs) : ''; - } - - getModuleElapsedMs(moduleName) { - const startTime = this.getModuleStartTime(moduleName); - if (startTime) return Date.now() - startTime; - return this.getLastDisableMeta(moduleName)?.durationMs || 0; - } - - captureDisableMeta(moduleName, context = 'user') { - const startTime = this.getModuleStartTime(moduleName); - const now = Date.now(); - return { - context: context || 'user', - timestamp: now, - durationMs: startTime ? now - startTime : 0, - }; - } - - trackLastActiveMacro(moduleName) { - this.lastActiveMacros = this.lastActiveMacros.filter((name) => name !== moduleName); - this.lastActiveMacros.unshift(moduleName); - } - - setupLastMacroToggleKey() { - if (this.hasBoundLastMacroToggleKey) return; - this.hasBoundLastMacroToggleKey = true; - - const existingKeybinds = Utils.getConfigFile('keybinds.json') || {}; - const savedKeycode = existingKeybinds[this.lastMacroToggleTitle] || Keyboard.KEY_NONE; - this.lastMacroToggleKey = new KeyBind(this.lastMacroToggleTitle, savedKeycode, 'v5_core'); - - this.lastMacroToggleKey.registerKeyPress(() => { - this.toggleLastUsedMacroFromUser(); - }); - - register('gameUnload', () => { - const keycode = this.lastMacroToggleKey?.getKeyCode(); - if (typeof keycode !== 'number') return; - - const allKeybinds = Utils.getConfigFile('keybinds.json') || {}; - allKeybinds[this.lastMacroToggleTitle] = keycode; - Utils.writeConfigFile('keybinds.json', allKeybinds); - }); - } - - toggleLastUsedMacroFromUser() { - const macroName = this.getLastActiveMacro(); - if (!macroName) { - Chat.message('&eNo recently used macro to toggle.'); - return false; - } - - const macroModule = this.getModule(macroName); - if (!macroModule || !macroModule.isMacro || typeof macroModule.requestToggleFromUser !== 'function') { - Chat.message(`&cUnable to toggle last macro: ${macroName}.`); - return false; - } - - macroModule.requestToggleFromUser(); - return true; + const module = getModule(macroName); + if (!module?.isMacro || typeof module.requestToggleFromUser !== 'function') { + chat(`&cUnable to toggle last macro: ${macroName}.`); + return false; } + module.requestToggleFromUser(); + return true; } -export const MacroState = new MacroStateClass(); +export function setupLastMacroToggleKey() { + if (hasBoundLastMacroToggleKey) return; + hasBoundLastMacroToggleKey = true; + + const keybinds = getConfigFile('keybinds.json') || {}; + lastMacroToggleKey = new KeyBind(LAST_MACRO_TOGGLE_TITLE, keybinds[LAST_MACRO_TOGGLE_TITLE] || Keyboard.KEY_NONE, 'v5_core'); + lastMacroToggleKey.registerKeyPress(toggleLastUsedMacroFromUser); + + register('gameUnload', () => { + const keycode = lastMacroToggleKey?.getKeyCode(); + if (typeof keycode !== 'number') return; + const savedKeybinds = getConfigFile('keybinds.json') || {}; + savedKeybinds[LAST_MACRO_TOGGLE_TITLE] = keycode; + writeConfigFile('keybinds.json', savedKeybinds); + }); +} diff --git a/utils/Math.js b/utils/Math.js index 4e95b625..7de6e606 100644 --- a/utils/Math.js +++ b/utils/Math.js @@ -1,245 +1,116 @@ -import { Utils } from './Utils'; +import { convertToVector } from './Utils'; const RAD_TO_DEG = 180 / Math.PI; -const DEG_TO_RAD = Math.PI / 180; - const point = (x, y, z) => ({ x: x || 0, y: y || 0, z: z || 0 }); const distance = (a, b) => Math.hypot(a.x - b.x, a.y - b.y, a.z - b.z); const horizontalDistance = (a, b) => Math.hypot(a.x - b.x, a.z - b.z); -class DistanceCalculator { - getPointFromInput(input, y, z) { - if (typeof input === 'number') { - return point(input, y, z); - } - const vec = Utils.convertToVector(input); - return vec ? point(vec.x(), vec.y(), vec.z()) : null; - } - - getPlayerPos() { - return Player.getPlayer() ? point(Player.getX(), Player.getY(), Player.getZ()) : null; - } - - getPlayerEyes() { - const eyePos = Player.getPlayer()?.getEyePosition(); - return eyePos ? point(eyePos.x(), eyePos.y(), eyePos.z()) : null; - } - - computeDistance(point1, point2) { - return { - distance: distance(point1, point2), - distanceFlat: horizontalDistance(point1, point2), - distanceY: point1.y - point2.y, - differenceY: point1.y - point2.y, - }; - } +const toPoint = (input, y, z) => { + if (typeof input === 'number') return point(input, y, z); + const vec = convertToVector(input); + return vec ? point(vec.x(), vec.y(), vec.z()) : null; +}; + +const playerPosition = () => (Player.getPlayer() ? point(Player.getX(), Player.getY(), Player.getZ()) : null); + +const playerEyes = () => { + const eyes = Player.getPlayer()?.getEyePosition(); + return eyes ? point(eyes.x(), eyes.y(), eyes.z()) : null; +}; + +const distances = (a, b) => ({ + distance: distance(a, b), + distanceFlat: horizontalDistance(a, b), + distanceY: a.y - b.y, + differenceY: a.y - b.y, +}); + +const emptyDistance = () => ({ distance: 0, distanceFlat: 0, distanceY: 0 }); + +export function wrapTo180(angle) { + angle %= 360; + if (angle >= 180) angle -= 360; + if (angle < -180) angle += 360; + return angle; } -class AngleCalculator { - wrapAngle180(angle) { - angle %= 360; - if (angle >= 180) angle -= 360; - if (angle < -180) angle += 360; - return angle; - } +export function distanceToPlayerPoint(targetInput) { + const eyes = playerEyes(); + const target = toPoint(targetInput); + return eyes && target ? distance(eyes, target) : 0; +} - calculateRelativeAngles(targetVec) { - if (!targetVec) return { yaw: 0, pitch: 0 }; - const eyes = Player.getPlayer()?.getEyePosition(); - if (!eyes) return { yaw: 0, pitch: 0 }; +export function distanceToPlayerFeet(targetInput) { + const feet = playerPosition(); + const target = toPoint(targetInput); + return feet && target ? distances(feet, target) : 0; +} - const dx = targetVec.x - eyes.x(); - const dy = targetVec.y - eyes.y(); - const dz = targetVec.z - eyes.z(); +export function calculateDistance(a, b) { + const first = toPoint(a); + const second = toPoint(b); + return first && second ? distances(first, second) : emptyDistance(); +} - const horizontalDist = Math.hypot(dx, dz); +export function getDistanceToPlayer(x, y, z) { + const feet = playerPosition(); + const target = toPoint(x, y, z); + return feet && target ? distances(feet, target) : emptyDistance(); +} - let pitch = -Math.atan2(dy, horizontalDist) * RAD_TO_DEG; - let yaw = Math.atan2(dz, dx) * RAD_TO_DEG - 90; +export function getDistanceToPlayerEyes(x, y, z) { + const eyes = playerEyes(); + const target = toPoint(x, y, z); + return eyes && target ? distances(eyes, target) : { distance: 0, distanceFlat: 0, differenceY: 0 }; +} - let relativeYaw = this.wrapAngle180(yaw - Player.getYaw()); - let relativePitch = pitch - Player.getPitch(); +export function getDistance(x1, y1, z1, x2, y2, z2) { + const first = toPoint(x1, y1, z1); + const second = toPoint(x2, y2, z2); + return first && second ? distances(first, second) : emptyDistance(); +} - return { yaw: relativeYaw, pitch: relativePitch }; - } +export const fastDistance = (x1, y1, z1, x2, y2, z2) => Math.hypot(x1 - x2, y1 - y2, z1 - z2); - calculateAbsoluteAngles(targetVec) { - if (!targetVec) return { yaw: 0, pitch: 0 }; - const eyes = Player.getPlayer()?.getEyePosition(); - if (!eyes) return { yaw: 0, pitch: 0 }; +export const blockCenter = (x, y, z) => point(x + 0.5, y + 0.5, z + 0.5); - const dx = targetVec.x - eyes.x(); - const dy = targetVec.y - eyes.y(); - const dz = targetVec.z - eyes.z(); +const relativeAngles = (target) => { + const eyes = Player.getPlayer()?.getEyePosition(); + if (!target || !eyes) return { yaw: 0, pitch: 0 }; - const horizontalDist = Math.hypot(dx, dz); + const dx = target.x - eyes.x(); + const dy = target.y - eyes.y(); + const dz = target.z - eyes.z(); + return { + yaw: wrapTo180(Math.atan2(dz, dx) * RAD_TO_DEG - 90 - Player.getYaw()), + pitch: -Math.atan2(dy, Math.hypot(dx, dz)) * RAD_TO_DEG - Player.getPitch(), + }; +}; - let pitch = -Math.atan2(dy, horizontalDist) * RAD_TO_DEG; - let yaw = Math.atan2(dz, dx) * RAD_TO_DEG - 90; +export function angleToPlayer(targetInput) { + const target = toPoint(targetInput); + if (!target) return { distance: 0, yaw: 0, pitch: 0, yawAbs: 0, pitchAbs: 0 }; + const { yaw, pitch } = relativeAngles(target); + return { distance: Math.hypot(yaw, pitch), yaw, pitch, yawAbs: Math.abs(yaw), pitchAbs: Math.abs(pitch) }; +} + +export const getAngleDifference = (current, target) => wrapTo180(target - current); - return { - yaw: this.wrapAngle180(yaw), - pitch: Math.max(-90, Math.min(90, pitch)), - }; - } +export function calculateAngles(vec) { + const target = toPoint(vec); + return target ? relativeAngles(target) : { yaw: 0, pitch: 0 }; } -const distCalc = new DistanceCalculator(); -const angleCalc = new AngleCalculator(); - -export const MathUtils = { - distanceToPlayerPoint: function (point) { - const eyes = distCalc.getPlayerEyes(); - const target = distCalc.getPointFromInput(point); - return eyes && target ? distance(eyes, target) : 0; - }, - - distanceToPlayer: function (point) { - const eyes = distCalc.getPlayerEyes(); - if (!eyes) return 0; - const target = distCalc.getPointFromInput(point); - if (!target) return 0; - return distCalc.computeDistance(eyes, target); - }, - - distanceToPlayerFeet: function (point) { - const feet = distCalc.getPlayerPos(); - if (!feet) return 0; - const target = distCalc.getPointFromInput(point); - if (!target) return 0; - return distCalc.computeDistance(feet, target); - }, - - distanceToPlayerCenter: function (targetPoint) { - const eyes = distCalc.getPlayerEyes(); - if (!eyes) return 0; - const target = distCalc.getPointFromInput(targetPoint); - if (!target) return 0; - const centerY = Player.getY() + Player.asPlayerMP().getHeight() / 2; - return distCalc.computeDistance(point(eyes.x, centerY, eyes.z), target); - }, - - distanceToPlayerCT: function (entity) { - const eyes = distCalc.getPlayerEyes(); - if (!eyes || !entity) return 0; - return distCalc.computeDistance(eyes, point(entity.getX(), entity.getY(), entity.getZ())); - }, - - distanceToPlayerMC: function (entity) { - return MathUtils.distanceToPlayerCT(entity); - }, - - calculateDistanceBP: function (pos1, pos2) { - const p1 = distCalc.getPointFromInput(pos1); - const p2 = distCalc.getPointFromInput(pos2); - if (!p1 || !p2) return { distance: 0, distanceFlat: 0, distanceY: 0 }; - return { - distance: distance(p1, p2), - distanceFlat: horizontalDistance(p1, p2), - distanceY: p1.y - p2.y, - }; - }, - - calculateDistance: function (p1, p2) { - const point1 = distCalc.getPointFromInput(p1); - const point2 = distCalc.getPointFromInput(p2); - if (!point1 || !point2) return { distance: 0, distanceFlat: 0, distanceY: 0 }; - return distCalc.computeDistance(point1, point2); - }, - - getDistanceToPlayer: function (x, y, z) { - const feet = distCalc.getPlayerPos(); - const target = distCalc.getPointFromInput(x, y, z); - if (!feet || !target) return { distance: 0, distanceFlat: 0, distanceY: 0 }; - return distCalc.computeDistance(feet, target); - }, - - getDistanceToPlayerEyes: function (x, y, z) { - const eyes = distCalc.getPlayerEyes(); - if (!eyes) return { distance: 0, distanceFlat: 0, differenceY: 0 }; - const target = distCalc.getPointFromInput(x, y, z); - if (!target) return { distance: 0, distanceFlat: 0, differenceY: 0 }; - return distCalc.computeDistance(eyes, target); - }, - - getDistance: function (x1, y1, z1, x2, y2, z2) { - const p1 = distCalc.getPointFromInput(x1, y1, z1); - const p2 = distCalc.getPointFromInput(x2, y2, z2); - if (!p1 || !p2) return { distance: 0, distanceFlat: 0, distanceY: 0 }; - return distCalc.computeDistance(p1, p2); - }, - - fastDistance: function (x1, y1, z1, x2, y2, z2) { - const dx = x1 - x2; - const dy = y1 - y2; - const dz = z1 - z2; - return Math.hypot(dx, dy, dz); - }, - - blockCenter: function (x, y, z) { - return point(x + 0.5, y + 0.5, z + 0.5); - }, - - distanceToBlockCenter: function (x, y, z) { - return MathUtils.distanceToPlayerFeet(MathUtils.blockCenter(x, y, z)); - }, - - distanceToBox: function (pos, min, max) { - const p = distCalc.getPointFromInput(pos); - const lo = distCalc.getPointFromInput(min); - const hi = distCalc.getPointFromInput(max); - if (!p || !lo || !hi) return 0; - const dx = Math.max(lo.x - p.x, 0, p.x - hi.x); - const dy = Math.max(lo.y - p.y, 0, p.y - hi.y); - const dz = Math.max(lo.z - p.z, 0, p.z - hi.z); - return Math.hypot(dx, dy, dz); - }, - - toFixed: function (val) { - return Math.round(val * 10) / 10; - }, - - angleToPlayer: function (point) { - const target = distCalc.getPointFromInput(point); - if (!target) return { distance: 0, yaw: 0, pitch: 0, yawAbs: 0, pitchAbs: 0 }; - const rel = angleCalc.calculateRelativeAngles(target); - const dist = Math.hypot(rel.yaw, rel.pitch); - return { - distance: dist, - yaw: rel.yaw, - pitch: rel.pitch, - yawAbs: Math.abs(rel.yaw), - pitchAbs: Math.abs(rel.pitch), - }; - }, - - degreeToRad: function (deg) { - return deg * DEG_TO_RAD; - }, - - getAngleDifference: function (cur, target) { - return angleCalc.wrapAngle180(target - cur); - }, - - wrapTo180: function (angle) { - return angleCalc.wrapAngle180(angle); - }, - - calculateAngles: function (vec) { - const target = distCalc.getPointFromInput(vec); - if (!target) return { yaw: 0, pitch: 0 }; - return angleCalc.calculateRelativeAngles(target); - }, - - calculateAbsoluteAngles: function (vec) { - const target = distCalc.getPointFromInput(vec); - if (!target) return { yaw: 0, pitch: 0 }; - return angleCalc.calculateAbsoluteAngles(target); - }, - - getNumbersFromString: function (str) { - if (!str) return 0; - const match = str.match(/\d+/g); - return match ? Number.parseInt(match.join('')) : 0; - }, -}; +export function calculateAbsoluteAngles(vec) { + const target = toPoint(vec); + const eyes = Player.getPlayer()?.getEyePosition(); + if (!target || !eyes) return { yaw: 0, pitch: 0 }; + + const dx = target.x - eyes.x(); + const dy = target.y - eyes.y(); + const dz = target.z - eyes.z(); + return { + yaw: wrapTo180(Math.atan2(dz, dx) * RAD_TO_DEG - 90), + pitch: Math.max(-90, Math.min(90, -Math.atan2(dy, Math.hypot(dx, dz)) * RAD_TO_DEG)), + }; +} diff --git a/utils/MiningUtils.js b/utils/MiningUtils.js index ece61071..f86e3ad2 100644 --- a/utils/MiningUtils.js +++ b/utils/MiningUtils.js @@ -1,4 +1,4 @@ -import { Chat } from './Chat'; +import { chat } from './Chat'; import { Blocks, BP } from './Constants'; import { Flowstate } from './Flowstate'; import { Executor } from './ThreadExecutor'; @@ -80,13 +80,13 @@ class MiningStatsCollector { beginCollection() { if (this.isCollecting) { - Chat.message('Already collecting stats. Wait a moment.'); + chat('Already collecting stats. Wait a moment.'); return false; } let toolData = ToolFinder.findBest(); if (!toolData) { - Chat.message('No mining tool found!'); + chat('No mining tool found!'); return false; } @@ -143,7 +143,7 @@ class MiningStatsCollector { this.finishCollection(); return true; } catch (e) { - Chat.message('Error collecting stats: ' + e); + chat('Error collecting stats: ' + e); console.error('V5 Caught error' + e + e.stack); return false; } finally { @@ -176,7 +176,7 @@ class MiningStatsCollector { } timeout() { - Chat.message('Failed to get mining stats.'); + chat('Failed to get mining stats.'); Guis.closeInv(); return false; } @@ -233,15 +233,15 @@ class MiningStatsCollector { this.stats = finalStats; this.checkedThisSession = true; - Chat.message('Drill: &e' + (finalStats.drill || 'Unknown')); - Chat.message('Speed: &6' + finalStats.speed + ' Mining Speed'); - Chat.message('Lapidary: &6+' + finalStats.lapidary + ' Mining Speed'); - Chat.message('Professional: &6+' + finalStats.professional + ' Mining Speed'); - Chat.message('Strong Arm: &6+' + finalStats.strongarm + ' Mining Speed'); - Chat.message('Ability: &e' + finalStats.ability); - Chat.message('Cold Resistance: &b' + finalStats.coldres); - Chat.message('COTM Level: &e' + finalStats.cotm); - Chat.message('Max Great Explorer: ' + (finalStats.maxge ? '&aYes' : '&cNo')); + chat('Drill: &e' + (finalStats.drill || 'Unknown')); + chat('Speed: &6' + finalStats.speed + ' Mining Speed'); + chat('Lapidary: &6+' + finalStats.lapidary + ' Mining Speed'); + chat('Professional: &6+' + finalStats.professional + ' Mining Speed'); + chat('Strong Arm: &6+' + finalStats.strongarm + ' Mining Speed'); + chat('Ability: &e' + finalStats.ability); + chat('Cold Resistance: &b' + finalStats.coldres); + chat('COTM Level: &e' + finalStats.cotm); + chat('Max Great Explorer: ' + (finalStats.maxge ? '&aYes' : '&cNo')); } extractNumericFromSlot(slot, pattern) { @@ -502,7 +502,7 @@ class RefuelService { refuel(callback) { if (this.state !== this.STATES.IDLE) { - Chat.message('Refuel already running!'); + chat('Refuel already running!'); if (callback) callback(false); return; } @@ -587,7 +587,7 @@ class RefuelService { this.targetHotbarSlot = targetSlot; this.setState(this.STATES.OPEN_PLAYER_INV_SWAP, 0); } else { - Chat.message('Abiphone not found. Walking to Drill Mechanic...'); + chat('Abiphone not found. Walking to Drill Mechanic...'); this.setState(this.STATES.WALK_TO_MECHANIC); } break; @@ -670,7 +670,7 @@ class RefuelService { case this.STATES.ADD_FUEL: if (!Guis.clickItems(['Volta', 'Oil Barrel', 'Biofuel', 'Sunflower Oil', 'Goblin Egg'], true)) { - Chat.message('No fuel detected!'); + chat('No fuel detected!'); this.setState(this.STATES.FAIL_CLEANUP, 10); return; } @@ -782,7 +782,7 @@ class RefuelService { } fail(message) { - if (message) Chat.message(message); + if (message) chat(message); this.finish(false); } @@ -814,12 +814,12 @@ class ExplorerUpgrade { let stats = self.collector.getStoredStats(); if (stats?.maxge) { - Chat.message('Great Explorer already maxed!'); + chat('Great Explorer already maxed!'); return callback(true); } if (stats?.maxge === undefined) { - Chat.message('Run /getminingstats first!'); + chat('Run /getminingstats first!'); return callback(false); } @@ -830,7 +830,7 @@ class ExplorerUpgrade { if (msg.includes('You must first unlock')) { failed = true; Thread.sleep(300); - Chat.message("great explorer can't be unlocked!"); + chat("great explorer can't be unlocked!"); Guis.closeInv(); chatWatcher.unregister(); return callback(false); @@ -839,7 +839,7 @@ class ExplorerUpgrade { if (msg.includes("You don't have enough Gemstone Powder!")) { failed = true; Thread.sleep(300); - Chat.message('insufficient powder!'); + chat('insufficient powder!'); Guis.closeInv(); chatWatcher.unregister(); return callback(false); @@ -850,7 +850,7 @@ class ExplorerUpgrade { Thread.sleep(1000); if (Guis.guiName() !== 'Heart of the Mountain') { - Chat.message('HOTM failed to open!'); + chat('HOTM failed to open!'); chatWatcher.unregister(); return callback(false); } @@ -993,7 +993,7 @@ class BlockUtils { let blockPos = new BP(x, y, z); Client.getMinecraft().level.setBlockAndUpdate(blockPos, Blocks.AIR.defaultBlockState()); } catch (e) { - Chat.message('error setting ghost block'); + chat('error setting ghost block'); console.error('V5 Caught error' + e + e.stack); } } @@ -1007,9 +1007,9 @@ const explorer = new ExplorerUpgrade(miningStatsCollector); v5Command('mining refuel', () => { refueler.refuel((success) => { if (success) { - Chat.message('Refueling completed'); + chat('Refueling completed'); } else { - Chat.message('Refueling failed'); + chat('Refueling failed'); } }); }); @@ -1066,12 +1066,23 @@ export const MiningUtils = { }, }; +export const getMiningSpeed = (...args) => MiningUtils.getMiningSpeed(...args); +export const getSpeedWithCold = (...args) => MiningUtils.getSpeedWithCold(...args); +export const getMineTime = (...args) => MiningUtils.getMineTime(...args); +export const getBlockInfo = (...args) => MiningUtils.getBlockInfo(...args); +export const refreshMiningStatsIfNeeded = (...args) => MiningUtils.refreshMiningStatsIfNeeded(...args); +export const getDrills = (...args) => MiningUtils.getDrills(...args); +export const refuel = (...args) => MiningUtils.doRefueling(...args); +export const getDebuff = (...args) => MiningUtils.getDebuff(...args); +export const setGhostBlock = (...args) => MiningUtils.GhostBlock(...args); +export const readCommissionsFromGui = (...args) => MiningUtils.readCommissionsFromGui(...args); + v5Command('mining maxge', () => { MiningUtils.MaxGreatExplorer((success) => { if (success) { - Chat.message('Great Explorer upgrade completed'); + chat('Great Explorer upgrade completed'); } else { - Chat.message('Great Explorer upgrade failed'); + chat('Great Explorer upgrade failed'); } }); }); diff --git a/utils/Misc.js b/utils/Misc.js index 64ff99f1..ceebd963 100644 --- a/utils/Misc.js +++ b/utils/Misc.js @@ -1,42 +1,42 @@ -import { Chat } from './Chat'; -import { MiningUtils } from './MiningUtils'; +import { chat } from './Chat'; +import { getBlockInfo } from './MiningUtils'; import { v5Command } from './V5Commands'; v5Command('debug info', () => { let target = Player.lookingAt(); if (!target) { - Chat.message('You are not looking at anything'); + chat('You are not looking at anything'); return; } if (target instanceof Block) { const registryName = target.type?.getRegistryName?.(); - const blockInfo = MiningUtils.getBlockInfo(registryName); + const blockInfo = getBlockInfo(registryName); const displayRegistry = registryName || 'unknown'; - Chat.message('blockid: ' + (target.type?.getID?.() ?? 'unknown')); - Chat.message('registry: ' + displayRegistry); - Chat.message('x: ' + target.x + ' y: ' + target.y + ' z:' + target.z); + chat('blockid: ' + (target.type?.getID?.() ?? 'unknown')); + chat('registry: ' + displayRegistry); + chat('x: ' + target.x + ' y: ' + target.y + ' z:' + target.z); if (blockInfo) { - Chat.message('block name: ' + blockInfo.name); - Chat.message('block hardness: ' + blockInfo.hardness); + chat('block name: ' + blockInfo.name); + chat('block hardness: ' + blockInfo.hardness); } } else if (target instanceof Entity) { - Chat.message('name: ' + target?.getName()); - Chat.message('entity type: ' + target?.toMC()?.getType()); - Chat.message('x: ' + target?.getX().toFixed(4) + ' y: ' + target?.getY().toFixed(4) + ' z:' + target?.getZ().toFixed(4)); - Chat.message('health: ' + target?.toMC()?.getHealth()); - Chat.message('max health: ' + target?.toMC()?.getMaxHealth()); - Chat.message('UUID: ' + target?.getUUID()); + chat('name: ' + target?.getName()); + chat('entity type: ' + target?.toMC()?.getType()); + chat('x: ' + target?.getX().toFixed(4) + ' y: ' + target?.getY().toFixed(4) + ' z:' + target?.getZ().toFixed(4)); + chat('health: ' + target?.toMC()?.getHealth()); + chat('max health: ' + target?.toMC()?.getMaxHealth()); + chat('UUID: ' + target?.getUUID()); } else { - Chat.message('You are not looking at a block or item'); + chat('You are not looking at a block or item'); } }); v5Command('debug istranslucent', () => { const block = Player.lookingAt(); if (!block) { - Chat.message('You are not looking at a block'); + chat('You are not looking at a block'); return; } - Chat.message(block?.type?.isTranslucent()); + chat(block?.type?.isTranslucent()); }); diff --git a/utils/MixinManager.js b/utils/MixinManager.js index 29d7d3c0..fd07ca71 100644 --- a/utils/MixinManager.js +++ b/utils/MixinManager.js @@ -1,190 +1,24 @@ -const internalMixin = global.Mixin; -const internalAt = global.At; const V5MixinStorage = Java.type('com.v5.storage.V5MixinStorage'); +const STORAGE_KEY = 'V5Mixin.storage'; +const properties = java.lang.System.getProperties(); +const existing = properties.get(STORAGE_KEY); +const storage = existing instanceof java.util.HashMap ? existing : new java.util.HashMap(); -class MixinStorage { - constructor() { - // This is a workaround because ChatTriggers resets data on load. - // Mixins always keep the same instance of a class, on ct load a complete new class is created - // meaning when using Mixin.get in a file that is not a mixin it will return null. - // By doing this we can persist data between reloads. - // its the simplest and fastest way imo - const storageKey = 'V5Mixin.storage'; - let existingStorage = java.lang.System.getProperties().get(storageKey); +if (storage !== existing) properties.put(STORAGE_KEY, storage); - if (existingStorage instanceof java.util.HashMap) { - this._storage = existingStorage; - } else { - this._storage = new java.util.HashMap(); - java.lang.System.getProperties().put(storageKey, this._storage); - } - } - - set(key, value) { - this._storage.put(key, value); - V5MixinStorage.set(key, value); - } - - get(key, defaultValue = null) { - return V5MixinStorage.get(key, defaultValue); - } - - setMethod(name, fn) { - if (typeof fn !== 'function') return; - this._storage.put(`method_${name}`, fn); - V5MixinStorage.set(`method_${name}`, fn); - } - - getMethod(name) { - const fn = V5MixinStorage.get(`method_${name}`, null); - return typeof fn === 'function' ? fn : () => {}; - } - - exists(key) { - return V5MixinStorage.get(key, null) !== null; - } - - delete(key) { - this._storage.remove(key); - V5MixinStorage.set(key, null); - } - - clear() { - this._storage.clear(); - V5MixinStorage.clear(); - } +export function setMixinValue(key, value) { + storage.put(key, value); + V5MixinStorage.set(key, value); } -const managerInstance = new MixinStorage(); +export const getMixinValue = (key, defaultValue = null) => V5MixinStorage.get(key, defaultValue); -export function attachMixin(mixin, name, callback) { - try { - mixin.attach(callback); - } catch (e) { - console.error(`Failed to attach ${name}: ${e}`); - } +export function setMixinMethod(name, callback) { + if (typeof callback !== 'function') return; + setMixinValue(`method_${name}`, callback); } -class MixinEngine { - constructor(className) { - this.className = className; - this.realMixin = new internalMixin(this.className); - this.lastInjection = null; - } - - _processConfig(config) { - const { at, slice, ...others } = config; - const result = { ...others }; - if (at) result.at = at instanceof internalAt ? at : new internalAt(at); - if (slice) result.slice = slice instanceof Slice ? slice : new Slice(slice); - return result; - } - - // Standard code injection at a specific point (e.g., HEAD, RETURN, INVOKE) - inject(config) { - this.lastInjection = this.realMixin.inject(this._processConfig(config)); - return this; - } - - // Intercepts a method call and replaces it with your own logic - redirect(config) { - this.lastInjection = this.realMixin.redirect(this._processConfig(config)); - return this; - } - - // Modifies a single argument being passed into a method - modifyArg(config) { - this.lastInjection = this.realMixin.modifyArg(this._processConfig(config)); - return this; - } - - // Modifies multiple arguments at once using an Args bundle - modifyArgs(config) { - this.lastInjection = this.realMixin.modifyArgs(this._processConfig(config)); - return this; - } - - // Changes the value of a local variable within the method body - modifyVariable(config) { - this.lastInjection = this.realMixin.modifyVariable(this._processConfig(config)); - return this; - } - - // Replaces a constant value (like a string or number) with a different one - modifyConstant(config) { - const { constant, ...others } = config; - const constObj = constant instanceof Constant ? constant : new Constant(constant); - this.lastInjection = this.realMixin.modifyConstant({ ...this._processConfig(others), constant: constObj }); - return this; - } - - // Intercepts and changes the value a method is about to return - modifyReturnValue(config) { - this.lastInjection = this.realMixin.modifyReturnValue(this._processConfig(config)); - return this; - } - - // Modifies the result of an expression (like a math operation or boolean check) - modifyExpressionValue(config) { - this.lastInjection = this.realMixin.modifyExpressionValue(this._processConfig(config)); - return this; - } - - // Changes the object instance (the receiver) on which a method is being called - modifyReceiver(config) { - this.lastInjection = this.realMixin.modifyReceiver(this._processConfig(config)); - return this; - } - - // Surrounds a method call or operation, allowing you to run code before and after - wrapOperation(config) { - this.lastInjection = this.realMixin.wrapOperation(this._processConfig(config)); - return this; - } - - // Wraps an operation with a conditional check to decide if it should execute - wrapWithCondition(config) { - this.lastInjection = this.realMixin.wrapWithCondition(this._processConfig(config)); - return this; - } - - // Widens access to a private or protected field; set 'mutable' true to allow editing - field(name, mutable = true) { - this.realMixin.widenField(name, mutable); - return this; - } - - // Widens access to a private or protected method so it can be called externally - method(name) { - this.realMixin.widenMethod(name, true); - return this; - } - - public(name) { - if (name.includes('(')) return this.method(name); - return this.field(name); - } - - put(name, value) { - managerInstance.set(name, value); - return this; - } - - hook(callback) { - if (!this.lastInjection) return this; - this.lastInjection.attach((...args) => callback(managerInstance, ...args)); - return this; - } +export function deleteMixinValue(key) { + storage.remove(key); + V5MixinStorage.set(key, null); } - -export function Mixin(className) { - return new MixinEngine(className); -} - -Mixin.set = (key, val) => managerInstance.set(key, val); -Mixin.get = (key, def) => managerInstance.get(key, def); -Mixin.setMethod = (name, fn) => managerInstance.setMethod(name, fn); -Mixin.getMethod = (name) => managerInstance.getMethod(name); -Mixin.exists = (key) => managerInstance.exists(key); -Mixin.delete = (key) => managerInstance.delete(key); -Mixin.clear = () => managerInstance.clear(); diff --git a/utils/ModuleBase.js b/utils/ModuleBase.js index 600185fd..4f8f26a8 100644 --- a/utils/ModuleBase.js +++ b/utils/ModuleBase.js @@ -1,12 +1,12 @@ import { notificationManager } from '../gui/NotificationManager'; import { OverlayManager } from '../gui/OverlayUtils'; import { Categories } from '../gui/categories/CategorySystem'; -import { Chat } from './Chat'; -import { MacroState } from './MacroState'; -import { Mixin } from './MixinManager'; +import { chat } from './Chat'; +import { getActiveMacro, getModule, getStartTime, isMacroRunning, onModuleDisabled, onModuleEnabled, registerModule } from './MacroState'; +import { setMixinValue } from './MixinManager'; import { ScheduleTask } from './ScheduleTask'; -import { manager } from './SkyblockEvents'; -import { Utils } from './Utils'; +import { registerSkyblockEvent } from './SkyblockEvents'; +import { getConfigFile, writeConfigFile } from './Utils'; export class ModuleBase { static conditions = []; @@ -50,7 +50,7 @@ export class ModuleBase { this.ignoreFailsafes = opts.ignoreFailsafes === true; - MacroState.registerModule(this); + registerModule(this); this._registers = []; @@ -65,17 +65,17 @@ export class ModuleBase { } if (opts.isMacro) { - manager.subscribe('limbo', () => { + registerSkyblockEvent('limbo', () => { if (!this.enabled) return; this.toggle(false); - Chat.message('&cYou were spawned in limbo! Attempting to recover...'); + chat('&cYou were spawned in limbo! Attempting to recover...'); ChatLib.command('leave'); ScheduleTask(20, () => { ChatLib.command('play skyblock'); }); ScheduleTask(60, () => { this.toggle(true); - Chat.message('&aRecovered from limbo?'); + chat('&aRecovered from limbo?'); }); }); } @@ -151,8 +151,8 @@ export class ModuleBase { this.isParentManaged = parentManaged; if (this.isMacro) { - Mixin.set('macroEnabled', true); - MacroState.onModuleEnabled(this.name, toggleContext); + setMixinValue('macroEnabled', true); + onModuleEnabled(this.name, toggleContext); } if (this.oid && !this.isParentManaged) { @@ -169,8 +169,8 @@ export class ModuleBase { this._registers.forEach((h) => h.register()); } else { if (this.isMacro) { - MacroState.onModuleDisabled(this.name, toggleContext); - Mixin.set('macroEnabled', MacroState.isMacroRunning()); + onModuleDisabled(this.name, toggleContext); + setMixinValue('macroEnabled', isMacroRunning()); } if (this.oid) { @@ -209,15 +209,15 @@ export class ModuleBase { } message(message) { - if (!this.name) return Chat.message('&cModule message error!'); + if (!this.name) return chat('&cModule message error!'); const theme = this.hexCode || `&${ModuleBase.getDefaultTheme(this.subcategory)}`; if (theme.startsWith('&#')) { - return Chat.message(new TextComponent({ text: `${this.name}: `, color: `#${theme.slice(2)}` }, `&f${message}`)); + return chat(new TextComponent({ text: `${this.name}: `, color: `#${theme.slice(2)}` }, `&f${message}`)); } if (theme.startsWith('#')) { - return Chat.message(new TextComponent({ text: `${this.name}: `, color: theme }, `&f${message}`)); + return chat(new TextComponent({ text: `${this.name}: `, color: theme }, `&f${message}`)); } - Chat.message(`${theme}${this.name}: &f${message}`); + chat(`${theme}${this.name}: &f${message}`); } /** @@ -225,7 +225,7 @@ export class ModuleBase { * @returns {boolean} */ isAnyMacroRunning() { - return MacroState.isMacroRunning(); + return isMacroRunning(); } /** @@ -233,7 +233,7 @@ export class ModuleBase { * @returns {string|null} */ getActiveMacroName() { - return MacroState.getActiveMacro(); + return getActiveMacro(); } /** @@ -241,11 +241,11 @@ export class ModuleBase { * @returns {number} */ getMacroStartTime() { - return MacroState.getStartTime(); + return getStartTime(); } bindToggleKey(title = `Toggle ${this.name}`) { - const existingKeybinds = Utils.getConfigFile('keybinds.json') || {}; + const existingKeybinds = getConfigFile('keybinds.json') || {}; const savedKeycode = existingKeybinds[title] || Keyboard.KEY_NONE; this._wrappedKeyTitle = title; this._wrappedKey = new KeyBind(title, savedKeycode, `v5_${this.subcategory.toLowerCase()}`); @@ -267,7 +267,7 @@ export class ModuleBase { */ requestToggleFromUser() { if (this.isMacro && !this.enabled) { - const scheduler = MacroState.getModule('Scheduler'); + const scheduler = getModule('Scheduler'); if (scheduler && typeof scheduler.cancelScheduledMacro === 'function') { if (scheduler.cancelScheduledMacro(this.name)) return false; } @@ -512,8 +512,8 @@ export class ModuleBase { * Saves a specific keybind description and keycode. */ _saveKey(description, keycode) { - let allKeybinds = Utils.getConfigFile('keybinds.json') || {}; + let allKeybinds = getConfigFile('keybinds.json') || {}; allKeybinds[description] = keycode; - Utils.writeConfigFile('keybinds.json', allKeybinds); + writeConfigFile('keybinds.json', allKeybinds); } } diff --git a/utils/NetworkUtils.js b/utils/NetworkUtils.js index 3cbaebb4..7447bcb5 100644 --- a/utils/NetworkUtils.js +++ b/utils/NetworkUtils.js @@ -1,8 +1,8 @@ -import { Chat } from './Chat'; +import { logMessage, chat } from './Chat'; import { BufferedReader, File, InputStreamReader, Links, StandardCharsets, URL, globalAssetsDir } from './Constants'; import { downloadFile } from './FileUtils'; -export const fetchURL = (url, headers = {}) => { +const fetchURL = (url, headers = {}) => { try { const conn = new URL(url).openConnection(); conn.setConnectTimeout(5000); @@ -43,7 +43,7 @@ export const returnDiscord = (authToken) => { }); if (!responseText || responseText.trim() === '') { - Chat.message('Failed to get a valid response for Discord PFP.'); + chat('Failed to get a valid response for Discord PFP.'); return; } @@ -51,14 +51,14 @@ export const returnDiscord = (authToken) => { try { data = JSON.parse(responseText); } catch (e) { - Chat.message('Failed to parse Discord PFP data. Check console for error.'); - Chat.log('Invalid JSON received: ' + responseText); + chat('Failed to parse Discord PFP data. Check console for error.'); + logMessage('Invalid JSON received: ' + responseText); console.error('V5 Caught error' + e + e.stack); return; } if (!data || !data.discord || !data.discord.avatar) { - Chat.message('Failed to download your Discord pfp: Invalid data format.'); + chat('Failed to download your Discord pfp: Invalid data format.'); return; } @@ -67,7 +67,7 @@ export const returnDiscord = (authToken) => { discordPfpPath = profilePath.getAbsolutePath(); }, onError: (e) => { - Chat.message('Download failed: ' + e); + chat('Download failed: ' + e); console.error('V5 Caught error' + e + e.stack); }, }); @@ -78,7 +78,7 @@ export const returnDiscord = (authToken) => { discordPfpPath = profilePath.getAbsolutePath(); } } catch (e) { - Chat.message('An unexpected error occurred while fetching Discord PFP: ' + e); + chat('An unexpected error occurred while fetching Discord PFP: ' + e); console.error('V5 Caught error' + e + e.stack); } }; diff --git a/utils/Notifications.js b/utils/Notifications.js deleted file mode 100644 index 68415a0d..00000000 --- a/utils/Notifications.js +++ /dev/null @@ -1,96 +0,0 @@ -import { Chat } from './Chat'; -import { File, MessageType, System, SystemTray, Toolkit, TrayIcon, globalAssetsDir } from './Constants'; - -class AlertManager { - constructor() { - this.trayIcon = null; - this.appName = 'V5 Client'; - this.setupTray(); - - register('gameUnload', () => { - this.cleanup(); - }); - } - - setupTray() { - if (!System.getProperty('os.name').toLowerCase().includes('win')) return; - - try { - const tray = SystemTray.getSystemTray(); - const existingIcons = tray.getTrayIcons(); - const existingIcon = Array.from(existingIcons).find((icon) => icon.getToolTip() === this.appName); - - if (existingIcon) { - this.trayIcon = existingIcon; - return; - } - - const iconPath = new File(globalAssetsDir, 'icon.png').getPath(); - const img = Toolkit.getDefaultToolkit().createImage(iconPath); - - this.trayIcon = new TrayIcon(img, this.appName); - this.trayIcon.setImageAutoSize(true); - this.trayIcon.setToolTip(this.appName); - tray.add(this.trayIcon); - } catch (e) { - Chat.messageDebug('Desktop tray initialization failed: ' + e); - console.error('V5 Caught error' + e + e.stack); - } - } - - cleanup() { - if (this.trayIcon) { - try { - SystemTray.getSystemTray().remove(this.trayIcon); - } catch (e) { - Chat.messageDebug('Tray cleanup failed: ' + e); - console.error('V5 Caught error' + e + e.stack); - } - this.trayIcon = null; - } - } - - dispatch(content) { - const platform = System.getProperty('os.name').toLowerCase(); - - if (platform.includes('win')) { - this.sendWin(content); - } else if (platform.includes('mac')) { - this.sendMac(content); - } else if (platform.includes('nix') || platform.includes('nux')) { - this.sendLinux(content); - } - } - - sendWin(msg) { - if (this.trayIcon) { - this.trayIcon.displayMessage(this.appName, msg, MessageType.WARNING); - } - } - - sendMac(msg) { - const safeMsg = String(msg).replace(/\\/g, '\\\\').replace(/"/g, '\\"'); - const safeTitle = String(this.appName).replace(/\\/g, '\\\\').replace(/"/g, '\\"'); - this.runCmd(['/usr/bin/osascript', '-e', `display notification "${safeMsg}" with title "${safeTitle}"`]); - } - - sendLinux(msg) { - this.runCmd(['notify-send', '-u', 'critical', '-a', this.appName, msg]); - } - - runCmd(args) { - try { - const pb = new java.lang.ProcessBuilder(args.map(String)); - pb.start(); - } catch (e) { - Chat.messageDebug('Notification command failed: ' + e); - console.error('V5 Caught error' + e + e.stack); - } - } -} - -const manager = new AlertManager(); - -export const Notifications = { - sendAlert: (msg) => manager.dispatch(msg), -}; diff --git a/utils/NukerUtils.js b/utils/NukerUtils.js index b7aca45f..9f9868e3 100644 --- a/utils/NukerUtils.js +++ b/utils/NukerUtils.js @@ -1,155 +1,89 @@ import { BP, Direction, MCHand, Vec3d } from './Constants'; -import { MathUtils } from './Math'; -import { ServerboundSwingPacket, ServerboundPlayerActionPacket, ServerboundPlayerActionPacket$Action } from './Packets'; +import { ServerboundPlayerActionPacket, ServerboundPlayerActionPacket$Action, ServerboundSwingPacket } from './Packets'; import { ScheduleTask } from './ScheduleTask'; -class NukerUtilsClass { - static MAX_REACH_DISTANCE = 6; - static MIN_NUKE_INTERVAL = 50; - static SWING_DELAY = 10; - - constructor() { - this.initialize(); - this.registerTickHandler(); - } - - initialize() { - this.lastNukeTime = Date.now(); - this.nukeQueue = []; - this.tickCounter = 0; - this.delay = 0; - this.fakelookMode = 'Queue'; - this.currentBreakingBlockPos = null; - } - - registerTickHandler() { - register('tick', () => { - if (this.nukeQueue.length > 0) { - this.processNextQueuedAction(); - } else if (this.tickCounter > 0) { - this.tickCounter--; - Client.sendPacket(new ServerboundSwingPacket(MCHand.MAIN_HAND)); - } - }); - } - - processNextQueuedAction() { - const nextAction = this.nukeQueue.pop(); - if (!nextAction || !Array.isArray(nextAction) || nextAction.length < 2) return; - const blockCoords = nextAction[0]; - const ticksToWait = nextAction[1]; - this.nukeQueue = []; - - const blockPos = this.createBlockPosition(blockCoords); - if (!this.isBlockInRange(blockCoords)) return; - - const facing = this.closestDirection(blockPos); - - this.sendBreakPackets(blockPos, facing); - this.tickCounter = ticksToWait; - } - - sendBreakPackets(blockPos, facing) { - Client.sendSequencedPacket( - (sequence) => new ServerboundPlayerActionPacket(ServerboundPlayerActionPacket$Action.START_DESTROY_BLOCK, blockPos, facing, sequence) - ); - Client.sendPacket(new ServerboundSwingPacket(MCHand.MAIN_HAND)); - } - - nukeQueueAdd(blockPos, ticks) { - this.nukeQueue.push([blockPos, ticks]); - } - - // THIS IS DETECTED I THINK DONT USE IT IT RAPES YOU BRUTALLY - // TIMEDEO WILL COME TO YOU HOME ADDRESS - // AND FORCE HIS BIG BLACK 4 INCH COCK DOWN YOUR THROAT - nuke(blockPos, ticks = 1) { - if (!this.isBlockInRange(blockPos)) return; - - this.updateDelayIfNeeded(ticks); - this.lastNukeTime = Date.now(); - this.tickCounter = ticks; - - setTimeout(() => { - this.executeNuke(blockPos); - }, this.delay); - - this.delay += NukerUtilsClass.SWING_DELAY; - } - - updateDelayIfNeeded(ticks) { - const timeSinceLastNuke = Date.now() - this.lastNukeTime; - const threshold = NukerUtilsClass.MIN_NUKE_INTERVAL + ticks * 50; - - if (timeSinceLastNuke > threshold || ticks === 1 || this.delay >= NukerUtilsClass.MIN_NUKE_INTERVAL) { - if (this.delay > NukerUtilsClass.MIN_NUKE_INTERVAL) { - ScheduleTask(1, () => { - if (typeof MiningBot !== 'undefined' && MiningBot) { - MiningBot.ticksMined--; - } - }); - } - this.delay = 0; +const MAX_REACH_DISTANCE = 6; +const MIN_NUKE_INTERVAL = 50; +const SWING_DELAY = 10; + +export const nukeQueue = []; +let lastNukeTime = Date.now(); +let tickCounter = 0; +let delay = 0; + +export const createBlockPosition = (coords) => new BP(Math.floor(coords[0]), Math.floor(coords[1]), Math.floor(coords[2])); + +const getFaceCenterPosition = (blockPos, face) => + new Vec3d(blockPos.getX() + 0.5 + face.getStepX() * 0.5, blockPos.getY() + 0.5 + face.getStepY() * 0.5, blockPos.getZ() + 0.5 + face.getStepZ() * 0.5); + +export function closestDirection(blockPos) { + const eye = Player.getPlayer()?.getEyePosition(); + if (!eye) return Direction.UP; + let closest = Direction.UP; + let closestDistance = Infinity; + for (const face of [Direction.UP, Direction.DOWN, Direction.NORTH, Direction.SOUTH, Direction.EAST, Direction.WEST]) { + const distance = eye.distanceTo(getFaceCenterPosition(blockPos, face)); + if (distance < closestDistance) { + closestDistance = distance; + closest = face; } } + return closest; +} - executeNuke(blockPos) { - const blockPosition = this.createBlockPosition(blockPos); - const facing = this.closestDirection(blockPosition); - - Client.sendSequencedPacket( - (sequence) => new ServerboundPlayerActionPacket(ServerboundPlayerActionPacket$Action.START_DESTROY_BLOCK, blockPosition, facing, sequence) - ); - - this.currentBreakingBlockPos = blockPos; - } - - isBlockInRange(blockPos) { - const eyePos = Player.getPlayer()?.getEyePosition(); - if (!eyePos) return false; - - const clampedX = Math.max(blockPos[0], Math.min(eyePos.x(), blockPos[0] + 1)); - const clampedY = Math.max(blockPos[1], Math.min(eyePos.y(), blockPos[1] + 1)); - const clampedZ = Math.max(blockPos[2], Math.min(eyePos.z(), blockPos[2] + 1)); - const { distance } = MathUtils.calculateDistance([eyePos.x(), eyePos.y(), eyePos.z()], [clampedX, clampedY, clampedZ]); - return distance <= NukerUtilsClass.MAX_REACH_DISTANCE; - } - - createBlockPosition(coords) { - return new BP(Math.floor(coords[0]), Math.floor(coords[1]), Math.floor(coords[2])); - } - - closestDirection(blockPos) { - const player = Player.getPlayer(); - if (!player) return Direction.UP; - - const playerEyePos = player.getEyePosition(); - if (!playerEyePos) return Direction.UP; - const faces = [Direction.UP, Direction.DOWN, Direction.NORTH, Direction.SOUTH, Direction.EAST, Direction.WEST]; - - let minDistance = Infinity; - let closestFace = Direction.UP; +export function isBlockInRange(blockPos) { + const eye = Player.getPlayer()?.getEyePosition(); + if (!eye) return false; + const x = Math.max(blockPos[0], Math.min(eye.x(), blockPos[0] + 1)); + const y = Math.max(blockPos[1], Math.min(eye.y(), blockPos[1] + 1)); + const z = Math.max(blockPos[2], Math.min(eye.z(), blockPos[2] + 1)); + return Math.hypot(eye.x() - x, eye.y() - y, eye.z() - z) <= MAX_REACH_DISTANCE; +} - for (const face of faces) { - const faceCenter = this.getFaceCenterPosition(blockPos, face); - const distance = playerEyePos.distanceTo(faceCenter); +export function sendBreakPackets(blockPos, facing) { + Client.sendSequencedPacket( + (sequence) => new ServerboundPlayerActionPacket(ServerboundPlayerActionPacket$Action.START_DESTROY_BLOCK, blockPos, facing, sequence) + ); + Client.sendPacket(new ServerboundSwingPacket(MCHand.MAIN_HAND)); +} - if (distance < minDistance) { - minDistance = distance; - closestFace = face; - } - } +export const queueNuke = (blockPos, ticks) => nukeQueue.push([blockPos, ticks]); - return closestFace; +const updateDelay = (ticks) => { + if (Date.now() - lastNukeTime <= MIN_NUKE_INTERVAL + ticks * 50 && ticks !== 1 && delay < MIN_NUKE_INTERVAL) return; + if (delay > MIN_NUKE_INTERVAL) { + ScheduleTask(1, () => { + if (typeof MiningBot !== 'undefined' && MiningBot) MiningBot.ticksMined--; + }); } - - getFaceCenterPosition(blockPos, face) { - return new Vec3d( - blockPos.getX() + 0.5 + face.getStepX() * 0.5, - blockPos.getY() + 0.5 + face.getStepY() * 0.5, - blockPos.getZ() + 0.5 + face.getStepZ() * 0.5 + delay = 0; +}; + +export function nuke(blockPos, ticks = 1) { + if (!isBlockInRange(blockPos)) return; + updateDelay(ticks); + lastNukeTime = Date.now(); + tickCounter = ticks; + setTimeout(() => { + const position = createBlockPosition(blockPos); + Client.sendSequencedPacket( + (sequence) => + new ServerboundPlayerActionPacket(ServerboundPlayerActionPacket$Action.START_DESTROY_BLOCK, position, closestDirection(position), sequence) ); - } + }, delay); + delay += SWING_DELAY; } -export const NukerUtils = new NukerUtilsClass(); +register('tick', () => { + if (nukeQueue.length) { + const action = nukeQueue.pop(); + nukeQueue.length = 0; + if (!Array.isArray(action) || action.length < 2 || !isBlockInRange(action[0])) return; + const position = createBlockPosition(action[0]); + sendBreakPackets(position, closestDirection(position)); + tickCounter = action[1]; + } else if (tickCounter > 0) { + tickCounter--; + Client.sendPacket(new ServerboundSwingPacket(MCHand.MAIN_HAND)); + } +}); diff --git a/utils/Packets.js b/utils/Packets.js index 0964bf6e..807d6c5a 100644 --- a/utils/Packets.js +++ b/utils/Packets.js @@ -1,202 +1,29 @@ -// client to server -export const ServerboundAcceptCodeOfConductPacket = net.minecraft.network.protocol.configuration.ServerboundAcceptCodeOfConductPacket; -export const ServerboundChunkBatchReceivedPacket = net.minecraft.network.protocol.game.ServerboundChunkBatchReceivedPacket; -export const ServerboundConfigurationAcknowledgedPacket = net.minecraft.network.protocol.game.ServerboundConfigurationAcknowledgedPacket; -export const ServerboundSeenAdvancementsPacket = net.minecraft.network.protocol.game.ServerboundSeenAdvancementsPacket; -export const ServerboundPaddleBoatPacket = net.minecraft.network.protocol.game.ServerboundPaddleBoatPacket; -export const ServerboundEditBookPacket = net.minecraft.network.protocol.game.ServerboundEditBookPacket; -export const ServerboundSelectBundleItemPacket = net.minecraft.network.protocol.game.ServerboundSelectBundleItemPacket; -export const ServerboundContainerButtonClickPacket = net.minecraft.network.protocol.game.ServerboundContainerButtonClickPacket; -export const ServerboundChangeGameModePacket = net.minecraft.network.protocol.game.ServerboundChangeGameModePacket; -export const ServerboundChatCommandSignedPacket = net.minecraft.network.protocol.game.ServerboundChatCommandSignedPacket; +// Client to server export const ServerboundChatPacket = net.minecraft.network.protocol.game.ServerboundChatPacket; export const ServerboundContainerClickPacket = net.minecraft.network.protocol.game.ServerboundContainerClickPacket; -export const ClientboundContainerSetSlotPacket = net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket; -export const ServerboundPlayerCommandPacket = net.minecraft.network.protocol.game.ServerboundPlayerCommandPacket; -export const ServerboundClientInformationPacket = net.minecraft.network.protocol.common.ServerboundClientInformationPacket; export const ServerboundClientCommandPacket = net.minecraft.network.protocol.game.ServerboundClientCommandPacket; -export const ServerboundClientTickEndPacket = net.minecraft.network.protocol.game.ServerboundClientTickEndPacket; export const ServerboundContainerClosePacket = net.minecraft.network.protocol.game.ServerboundContainerClosePacket; export const ServerboundChatCommandPacket = net.minecraft.network.protocol.game.ServerboundChatCommandPacket; -export const ServerboundPongPacket = net.minecraft.network.protocol.common.ServerboundPongPacket; -export const ServerboundCookieResponsePacket = net.minecraft.network.protocol.cookie.ServerboundCookieResponsePacket; -export const ServerboundPlaceRecipePacket = net.minecraft.network.protocol.game.ServerboundPlaceRecipePacket; -export const ServerboundSetCreativeModeSlotPacket = net.minecraft.network.protocol.game.ServerboundSetCreativeModeSlotPacket; -export const ServerboundCustomClickActionPacket = net.minecraft.network.protocol.common.ServerboundCustomClickActionPacket; -export const ServerboundCustomPayloadPacket = net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket; -export const ServerboundDebugSubscriptionRequestPacket = net.minecraft.network.protocol.game.ServerboundDebugSubscriptionRequestPacket; -export const ServerboundLoginAcknowledgedPacket = net.minecraft.network.protocol.login.ServerboundLoginAcknowledgedPacket; export const ServerboundSwingPacket = net.minecraft.network.protocol.game.ServerboundSwingPacket; -export const ClientIntentionPacket = net.minecraft.network.protocol.handshake.ClientIntentionPacket; -export const ServerboundJigsawGeneratePacket = net.minecraft.network.protocol.game.ServerboundJigsawGeneratePacket; -export const ServerboundKeepAlivePacket = net.minecraft.network.protocol.common.ServerboundKeepAlivePacket; -export const ServerboundHelloPacket = net.minecraft.network.protocol.login.ServerboundHelloPacket; -export const ServerboundKeyPacket = net.minecraft.network.protocol.login.ServerboundKeyPacket; -export const ServerboundCustomQueryAnswerPacket = net.minecraft.network.protocol.login.ServerboundCustomQueryAnswerPacket; -export const ServerboundChatAckPacket = net.minecraft.network.protocol.game.ServerboundChatAckPacket; -export const ServerboundPickItemFromBlockPacket = net.minecraft.network.protocol.game.ServerboundPickItemFromBlockPacket; -export const ServerboundPickItemFromEntityPacket = net.minecraft.network.protocol.game.ServerboundPickItemFromEntityPacket; export const ServerboundPlayerActionPacket = net.minecraft.network.protocol.game.ServerboundPlayerActionPacket; -export const ServerboundPlayerInputPacket = net.minecraft.network.protocol.game.ServerboundPlayerInputPacket; export const ServerboundUseItemOnPacket = net.minecraft.network.protocol.game.ServerboundUseItemOnPacket; export const ServerboundInteractPacket = net.minecraft.network.protocol.game.ServerboundInteractPacket; export const ServerboundUseItemPacket = net.minecraft.network.protocol.game.ServerboundUseItemPacket; -export const ServerboundPlayerLoadedPacket = net.minecraft.network.protocol.game.ServerboundPlayerLoadedPacket; -export const ServerboundMovePlayerPacket = net.minecraft.network.protocol.game.ServerboundMovePlayerPacket; -export const ServerboundChatSessionUpdatePacket = net.minecraft.network.protocol.game.ServerboundChatSessionUpdatePacket; export const ServerboundPlayerActionPacket$Action = net.minecraft.network.protocol.game.ServerboundPlayerActionPacket$Action; -export const ServerboundBlockEntityTagQueryPacket = net.minecraft.network.protocol.game.ServerboundBlockEntityTagQueryPacket; -export const ServerboundEntityTagQueryPacket = net.minecraft.network.protocol.game.ServerboundEntityTagQueryPacket; -export const ServerboundPingRequestPacket = net.minecraft.network.protocol.ping.ServerboundPingRequestPacket; -export const ServerboundStatusRequestPacket = net.minecraft.network.protocol.status.ServerboundStatusRequestPacket; -export const ServerboundFinishConfigurationPacket = net.minecraft.network.protocol.configuration.ServerboundFinishConfigurationPacket; -export const ServerboundRecipeBookSeenRecipePacket = net.minecraft.network.protocol.game.ServerboundRecipeBookSeenRecipePacket; -export const ServerboundRecipeBookChangeSettingsPacket = net.minecraft.network.protocol.game.ServerboundRecipeBookChangeSettingsPacket; -export const ServerboundRenameItemPacket = net.minecraft.network.protocol.game.ServerboundRenameItemPacket; export const ServerboundCommandSuggestionPacket = net.minecraft.network.protocol.game.ServerboundCommandSuggestionPacket; -export const ServerboundResourcePackPacket = net.minecraft.network.protocol.common.ServerboundResourcePackPacket; -export const ServerboundSelectKnownPacks = net.minecraft.network.protocol.configuration.ServerboundSelectKnownPacks; -export const ServerboundSelectTradePacket = net.minecraft.network.protocol.game.ServerboundSelectTradePacket; -export const ServerboundSetTestBlockPacket = net.minecraft.network.protocol.game.ServerboundSetTestBlockPacket; -export const ServerboundContainerSlotStateChangedPacket = net.minecraft.network.protocol.game.ServerboundContainerSlotStateChangedPacket; -export const ServerboundTeleportToEntityPacket = net.minecraft.network.protocol.game.ServerboundTeleportToEntityPacket; -export const ServerboundAcceptTeleportationPacket = net.minecraft.network.protocol.game.ServerboundAcceptTeleportationPacket; -export const ServerboundTestInstanceBlockActionPacket = net.minecraft.network.protocol.game.ServerboundTestInstanceBlockActionPacket; -export const ServerboundSetBeaconPacket = net.minecraft.network.protocol.game.ServerboundSetBeaconPacket; -export const ServerboundSetCommandBlockPacket = net.minecraft.network.protocol.game.ServerboundSetCommandBlockPacket; -export const ServerboundSetCommandMinecartPacket = net.minecraft.network.protocol.game.ServerboundSetCommandMinecartPacket; -export const ServerboundChangeDifficultyPacket = net.minecraft.network.protocol.game.ServerboundChangeDifficultyPacket; -export const ServerboundLockDifficultyPacket = net.minecraft.network.protocol.game.ServerboundLockDifficultyPacket; -export const ServerboundSetJigsawBlockPacket = net.minecraft.network.protocol.game.ServerboundSetJigsawBlockPacket; -export const ServerboundPlayerAbilitiesPacket = net.minecraft.network.protocol.game.ServerboundPlayerAbilitiesPacket; -export const ServerboundSetCarriedItemPacket = net.minecraft.network.protocol.game.ServerboundSetCarriedItemPacket; -export const ServerboundSignUpdatePacket = net.minecraft.network.protocol.game.ServerboundSignUpdatePacket; -export const ServerboundSetStructureBlockPacket = net.minecraft.network.protocol.game.ServerboundSetStructureBlockPacket; -export const ServerboundMoveVehiclePacket = net.minecraft.network.protocol.game.ServerboundMoveVehiclePacket; -// server to client -export const ClientboundUpdateAdvancementsPacket = net.minecraft.network.protocol.game.ClientboundUpdateAdvancementsPacket; -export const ClientboundBlockDestructionPacket = net.minecraft.network.protocol.game.ClientboundBlockDestructionPacket; -export const ClientboundBlockEntityDataPacket = net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; -export const ClientboundBlockEventPacket = net.minecraft.network.protocol.game.ClientboundBlockEventPacket; +// Server to client export const ClientboundBlockUpdatePacket = net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket; -export const ClientboundDebugBlockValuePacket = net.minecraft.network.protocol.game.ClientboundDebugBlockValuePacket; -export const ClientboundBossEventPacket = net.minecraft.network.protocol.game.ClientboundBossEventPacket; -export const ClientboundPlayerChatPacket = net.minecraft.network.protocol.game.ClientboundPlayerChatPacket; -export const ClientboundCustomChatCompletionsPacket = net.minecraft.network.protocol.game.ClientboundCustomChatCompletionsPacket; -export const ClientboundChunksBiomesPacket = net.minecraft.network.protocol.game.ClientboundChunksBiomesPacket; -export const ClientboundLevelChunkWithLightPacket = net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; -export const ClientboundSectionBlocksUpdatePacket = net.minecraft.network.protocol.game.ClientboundSectionBlocksUpdatePacket; -export const ClientboundSetChunkCacheRadiusPacket = net.minecraft.network.protocol.game.ClientboundSetChunkCacheRadiusPacket; -export const ClientboundSetChunkCacheCenterPacket = net.minecraft.network.protocol.game.ClientboundSetChunkCacheCenterPacket; -export const ClientboundChunkBatchFinishedPacket = net.minecraft.network.protocol.game.ClientboundChunkBatchFinishedPacket; -export const ClientboundDebugChunkValuePacket = net.minecraft.network.protocol.game.ClientboundDebugChunkValuePacket; -export const ClientboundClearDialogPacket = net.minecraft.network.protocol.common.ClientboundClearDialogPacket; -export const ClientboundClearTitlesPacket = net.minecraft.network.protocol.game.ClientboundClearTitlesPacket; -export const ClientboundContainerClosePacket = net.minecraft.network.protocol.game.ClientboundContainerClosePacket; -export const ClientboundCodeOfConductPacket = net.minecraft.network.protocol.configuration.ClientboundCodeOfConductPacket; -export const ClientboundCommandSuggestionsPacket = net.minecraft.network.protocol.game.ClientboundCommandSuggestionsPacket; -export const ClientboundCommandsPacket = net.minecraft.network.protocol.game.ClientboundCommandsPacket; export const ClientboundPingPacket = net.minecraft.network.protocol.common.ClientboundPingPacket; -export const ClientboundCookieRequestPacket = net.minecraft.network.protocol.cookie.ClientboundCookieRequestPacket; -export const ClientboundCooldownPacket = net.minecraft.network.protocol.game.ClientboundCooldownPacket; -export const ClientboundPlaceGhostRecipePacket = net.minecraft.network.protocol.game.ClientboundPlaceGhostRecipePacket; -export const ClientboundCustomPayloadPacket = net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket; -export const ClientboundCustomReportDetailsPacket = net.minecraft.network.protocol.common.ClientboundCustomReportDetailsPacket; -export const ClientboundHurtAnimationPacket = net.minecraft.network.protocol.game.ClientboundHurtAnimationPacket; -export const ClientboundPlayerCombatKillPacket = net.minecraft.network.protocol.game.ClientboundPlayerCombatKillPacket; -export const ClientboundDebugSamplePacket = net.minecraft.network.protocol.game.ClientboundDebugSamplePacket; -export const ClientboundChangeDifficultyPacket = net.minecraft.network.protocol.game.ClientboundChangeDifficultyPacket; export const ClientboundDisconnectPacket = net.minecraft.network.protocol.common.ClientboundDisconnectPacket; -export const ClientboundRegistryDataPacket = net.minecraft.network.protocol.configuration.ClientboundRegistryDataPacket; -export const ClientboundPlayerCombatEndPacket = net.minecraft.network.protocol.game.ClientboundPlayerCombatEndPacket; -export const ClientboundPlayerCombatEnterPacket = net.minecraft.network.protocol.game.ClientboundPlayerCombatEnterPacket; -export const ClientboundFinishConfigurationPacket = net.minecraft.network.protocol.configuration.ClientboundFinishConfigurationPacket; -export const ClientboundStartConfigurationPacket = net.minecraft.network.protocol.game.ClientboundStartConfigurationPacket; -export const ClientboundRemoveEntitiesPacket = net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket; -export const ClientboundAnimatePacket = net.minecraft.network.protocol.game.ClientboundAnimatePacket; -export const ClientboundSetEntityLinkPacket = net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket; -export const ClientboundUpdateAttributesPacket = net.minecraft.network.protocol.game.ClientboundUpdateAttributesPacket; -export const ClientboundDamageEventPacket = net.minecraft.network.protocol.game.ClientboundDamageEventPacket; -export const ClientboundSetEquipmentPacket = net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket; -export const ClientboundSetPassengersPacket = net.minecraft.network.protocol.game.ClientboundSetPassengersPacket; -export const ClientboundTeleportEntityPacket = net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket; -export const ClientboundMoveEntityPacket = net.minecraft.network.protocol.game.ClientboundMoveEntityPacket; -export const ClientboundRotateHeadPacket = net.minecraft.network.protocol.game.ClientboundRotateHeadPacket; -export const ClientboundAddEntityPacket = net.minecraft.network.protocol.game.ClientboundAddEntityPacket; -export const ClientboundEntityEventPacket = net.minecraft.network.protocol.game.ClientboundEntityEventPacket; -export const ClientboundUpdateMobEffectPacket = net.minecraft.network.protocol.game.ClientboundUpdateMobEffectPacket; -export const ClientboundSetEntityDataPacket = net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; export const ClientboundSetEntityMotionPacket = net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket; -export const ClientboundSetExperiencePacket = net.minecraft.network.protocol.game.ClientboundSetExperiencePacket; -// ponytail: removed dedicated experience-orb spawn packet in current protocol; use ClientboundAddEntityPacket if this ever needs reviving. -export const ClientboundExplodePacket = net.minecraft.network.protocol.game.ClientboundExplodePacket; -export const ClientboundUpdateEnabledFeaturesPacket = net.minecraft.network.protocol.configuration.ClientboundUpdateEnabledFeaturesPacket; export const ClientboundLoginPacket = net.minecraft.network.protocol.game.ClientboundLoginPacket; export const ClientboundSystemChatPacket = net.minecraft.network.protocol.game.ClientboundSystemChatPacket; -export const ClientboundGameEventPacket = net.minecraft.network.protocol.game.ClientboundGameEventPacket; -export const ClientboundSetHealthPacket = net.minecraft.network.protocol.game.ClientboundSetHealthPacket; -export const ClientboundContainerSetContentPacket = net.minecraft.network.protocol.game.ClientboundContainerSetContentPacket; -export const ClientboundTakeItemEntityPacket = net.minecraft.network.protocol.game.ClientboundTakeItemEntityPacket; -export const ClientboundLightUpdatePacket = net.minecraft.network.protocol.game.ClientboundLightUpdatePacket; -export const ClientboundLoginCompressionPacket = net.minecraft.network.protocol.login.ClientboundLoginCompressionPacket; export const ClientboundLoginDisconnectPacket = net.minecraft.network.protocol.login.ClientboundLoginDisconnectPacket; -export const ClientboundCustomQueryPacket = net.minecraft.network.protocol.login.ClientboundCustomQueryPacket; -export const ClientboundLoginFinishedPacket = net.minecraft.network.protocol.login.ClientboundLoginFinishedPacket; -export const ClientboundPlayerLookAtPacket = net.minecraft.network.protocol.game.ClientboundPlayerLookAtPacket; -export const ClientboundMapItemDataPacket = net.minecraft.network.protocol.game.ClientboundMapItemDataPacket; -export const ClientboundTagQueryPacket = net.minecraft.network.protocol.game.ClientboundTagQueryPacket; -export const ClientboundMountScreenOpenPacket = net.minecraft.network.protocol.game.ClientboundMountScreenOpenPacket; export const ClientboundOpenScreenPacket = net.minecraft.network.protocol.game.ClientboundOpenScreenPacket; -export const ClientboundOpenBookPacket = net.minecraft.network.protocol.game.ClientboundOpenBookPacket; export const ClientboundLevelParticlesPacket = net.minecraft.network.protocol.game.ClientboundLevelParticlesPacket; -export const ClientboundPlayerAbilitiesPacket = net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket; -export const ClientboundBlockChangedAckPacket = net.minecraft.network.protocol.game.ClientboundBlockChangedAckPacket; -export const ClientboundTabListPacket = net.minecraft.network.protocol.game.ClientboundTabListPacket; -export const ClientboundPlayerInfoUpdatePacket = net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket; export const ClientboundPlayerPositionPacket = net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket; -export const ClientboundPlayerInfoRemovePacket = net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket; -export const ClientboundRespawnPacket = net.minecraft.network.protocol.game.ClientboundRespawnPacket; -export const ClientboundPlayerRotationPacket = net.minecraft.network.protocol.game.ClientboundPlayerRotationPacket; -export const ClientboundSetDefaultSpawnPositionPacket = net.minecraft.network.protocol.game.ClientboundSetDefaultSpawnPositionPacket; -export const ClientboundDisguisedChatPacket = net.minecraft.network.protocol.game.ClientboundDisguisedChatPacket; -export const ClientboundProjectilePowerPacket = net.minecraft.network.protocol.game.ClientboundProjectilePowerPacket; -export const ClientboundPongResponsePacket = net.minecraft.network.protocol.ping.ClientboundPongResponsePacket; -export const ClientboundStatusResponsePacket = net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; -export const ClientboundRecipeBookAddPacket = net.minecraft.network.protocol.game.ClientboundRecipeBookAddPacket; -export const ClientboundRecipeBookRemovePacket = net.minecraft.network.protocol.game.ClientboundRecipeBookRemovePacket; -export const ClientboundRecipeBookSettingsPacket = net.minecraft.network.protocol.game.ClientboundRecipeBookSettingsPacket; -export const ClientboundRemoveMobEffectPacket = net.minecraft.network.protocol.game.ClientboundRemoveMobEffectPacket; -export const ClientboundResetScorePacket = net.minecraft.network.protocol.game.ClientboundResetScorePacket; -export const ClientboundResourcePackPopPacket = net.minecraft.network.protocol.common.ClientboundResourcePackPopPacket; -export const ClientboundResourcePackPushPacket = net.minecraft.network.protocol.common.ClientboundResourcePackPushPacket; -export const ClientboundSetDisplayObjectivePacket = net.minecraft.network.protocol.game.ClientboundSetDisplayObjectivePacket; -export const ClientboundSetObjectivePacket = net.minecraft.network.protocol.game.ClientboundSetObjectivePacket; -export const ClientboundServerDataPacket = net.minecraft.network.protocol.game.ClientboundServerDataPacket; -export const ClientboundTransferPacket = net.minecraft.network.protocol.common.ClientboundTransferPacket; -export const ClientboundSetCameraPacket = net.minecraft.network.protocol.game.ClientboundSetCameraPacket; -export const ClientboundSetCursorItemPacket = net.minecraft.network.protocol.game.ClientboundSetCursorItemPacket; -export const ClientboundSetPlayerInventoryPacket = net.minecraft.network.protocol.game.ClientboundSetPlayerInventoryPacket; -export const ClientboundTestInstanceBlockStatus = net.minecraft.network.protocol.game.ClientboundTestInstanceBlockStatus; -export const ClientboundMerchantOffersPacket = net.minecraft.network.protocol.game.ClientboundMerchantOffersPacket; -export const ClientboundOpenSignEditorPacket = net.minecraft.network.protocol.game.ClientboundOpenSignEditorPacket; -export const ClientboundSetSimulationDistancePacket = net.minecraft.network.protocol.game.ClientboundSetSimulationDistancePacket; -export const ClientboundAwardStatsPacket = net.minecraft.network.protocol.game.ClientboundAwardStatsPacket; -export const ClientboundStopSoundPacket = net.minecraft.network.protocol.game.ClientboundStopSoundPacket; -export const ClientboundStoreCookiePacket = net.minecraft.network.protocol.common.ClientboundStoreCookiePacket; -export const ClientboundSetSubtitleTextPacket = net.minecraft.network.protocol.game.ClientboundSetSubtitleTextPacket; -export const ClientboundUpdateRecipesPacket = net.minecraft.network.protocol.game.ClientboundUpdateRecipesPacket; -export const ClientboundUpdateTagsPacket = net.minecraft.network.protocol.common.ClientboundUpdateTagsPacket; -export const ClientboundSetPlayerTeamPacket = net.minecraft.network.protocol.game.ClientboundSetPlayerTeamPacket; export const ClientboundSetTitleTextPacket = net.minecraft.network.protocol.game.ClientboundSetTitleTextPacket; -export const ClientboundSetTitlesAnimationPacket = net.minecraft.network.protocol.game.ClientboundSetTitlesAnimationPacket; -export const ClientboundForgetLevelChunkPacket = net.minecraft.network.protocol.game.ClientboundForgetLevelChunkPacket; export const ClientboundSetHeldSlotPacket = net.minecraft.network.protocol.game.ClientboundSetHeldSlotPacket; -export const ClientboundTickingStatePacket = net.minecraft.network.protocol.game.ClientboundTickingStatePacket; -export const ClientboundSetBorderCenterPacket = net.minecraft.network.protocol.game.ClientboundSetBorderCenterPacket; -export const ClientboundSetBorderLerpSizePacket = net.minecraft.network.protocol.game.ClientboundSetBorderLerpSizePacket; -export const ClientboundSetBorderSizePacket = net.minecraft.network.protocol.game.ClientboundSetBorderSizePacket; -export const ClientboundSetBorderWarningDistancePacket = net.minecraft.network.protocol.game.ClientboundSetBorderWarningDistancePacket; -export const ClientboundSetBorderWarningDelayPacket = net.minecraft.network.protocol.game.ClientboundSetBorderWarningDelayPacket; -export const ClientboundLevelEventPacket = net.minecraft.network.protocol.game.ClientboundLevelEventPacket; -export const ClientboundSetTimePacket = net.minecraft.network.protocol.game.ClientboundSetTimePacket; +export const ClientboundAwardStatsPacket = net.minecraft.network.protocol.game.ClientboundAwardStatsPacket; +export const ClientboundLevelChunkWithLightPacket = net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; diff --git a/utils/Raytrace.js b/utils/Raytrace.js index 2f28b14f..874cf546 100644 --- a/utils/Raytrace.js +++ b/utils/Raytrace.js @@ -1,484 +1,191 @@ +import { Vec3d } from './Constants'; +import { wrapTo180 } from './Math'; import { raytraceBlocks } from './dependencies/BloomCore/RaytraceBlocks'; import { Vector3 } from './dependencies/BloomCore/Vector3'; -import { Vec3d } from './Constants'; -import { MathUtils } from './Math'; -export const SAMPLE_POINTS_PER_FACE = 9; -export const MAX_DDA_ITERATIONS = 300; -export const AIR_BLOCK_ID = 0; -export const PASSABLE_BLOCKS = new Set([0, 513]); +const SAMPLE_POINTS_PER_FACE = 9; +const MAX_DDA_ITERATIONS = 300; +const AIR_BLOCK_ID = 0; +const PASSABLE_BLOCKS = new Set([0, 513]); const RaycastContext = net.minecraft.world.level.ClipContext; - -class VisibilityChecker { - constructor() { - this.faceOffsets = this.generateFaceOffsets(); - this.eyeCache = { pos: null, time: 0 }; - } - - generateFaceOffsets() { - let offsets = []; - - offsets.push([0.5, 0.5, 0.5]); - - let faceConfigs = [ - { axis: 0, value: 0.05, otherAxes: [1, 2] }, - { axis: 0, value: 0.95, otherAxes: [1, 2] }, - { axis: 1, value: 0.05, otherAxes: [0, 2] }, - { axis: 1, value: 0.95, otherAxes: [0, 2] }, - { axis: 2, value: 0.05, otherAxes: [0, 1] }, - { axis: 2, value: 0.95, otherAxes: [0, 1] }, - ]; - - for (const config of faceConfigs) { - let step = 0.8 / (SAMPLE_POINTS_PER_FACE - 1); - - for (var j = 0; j < SAMPLE_POINTS_PER_FACE; j++) { - let offset1 = 0.1 + j * step; - - for (var k = 0; k < SAMPLE_POINTS_PER_FACE; k++) { - let offset2 = 0.1 + k * step; - let point = [0.5, 0.5, 0.5]; - - point[config.axis] = config.value; - point[config.otherAxes[0]] = offset1; - point[config.otherAxes[1]] = offset2; - - offsets.push(point); - } - } - } - - return offsets; - } - - getPlayerEyePosition() { - let now = Date.now(); - if (this.eyeCache.pos && now - this.eyeCache.time < 50) { - return this.eyeCache.pos; +const faceOffsets = [[0.5, 0.5, 0.5]]; +let eyeCache = { pos: null, time: 0 }; + +for (const { axis, value, otherAxes } of [ + { axis: 0, value: 0.05, otherAxes: [1, 2] }, + { axis: 0, value: 0.95, otherAxes: [1, 2] }, + { axis: 1, value: 0.05, otherAxes: [0, 2] }, + { axis: 1, value: 0.95, otherAxes: [0, 2] }, + { axis: 2, value: 0.05, otherAxes: [0, 1] }, + { axis: 2, value: 0.95, otherAxes: [0, 1] }, +]) { + const step = 0.8 / (SAMPLE_POINTS_PER_FACE - 1); + for (let first = 0; first < SAMPLE_POINTS_PER_FACE; first++) { + for (let second = 0; second < SAMPLE_POINTS_PER_FACE; second++) { + const point = [0.5, 0.5, 0.5]; + point[axis] = value; + point[otherAxes[0]] = 0.1 + first * step; + point[otherAxes[1]] = 0.1 + second * step; + faceOffsets.push(point); } - - let player = Player.getPlayer(); - if (!player) return null; - - let eyePos = player.getEyePosition(); - if (!eyePos) return null; - - this.eyeCache.pos = { x: eyePos.x(), y: eyePos.y(), z: eyePos.z() }; - this.eyeCache.time = now; - - return this.eyeCache.pos; - } - - checkBlockVisibility(blockX, blockY, blockZ, useMinecraftRaycast) { - let eyePos = this.getPlayerEyePosition(); - if (!eyePos) return null; - - let dx = blockX + 0.5 - eyePos.x; - let dy = blockY + 0.5 - eyePos.y; - let dz = blockZ + 0.5 - eyePos.z; - let distanceSq = dx * dx + dy * dy + dz * dz; - - if (distanceSq > 4096) { - return null; - } - - for (const offset of this.faceOffsets) { - let testPoint = [blockX + offset[0], blockY + offset[1], blockZ + offset[2]]; - - let visible = useMinecraftRaycast - ? this.testPointNative(blockX, blockY, blockZ, testPoint, eyePos) - : this.testPointCustom(blockX, blockY, blockZ, testPoint, eyePos); - - if (visible) { - return testPoint; - } - } - - return null; - } - - testPointNative(targetX, targetY, targetZ, point, eyePos) { - try { - const player = Player.getPlayer(); - const world = World.getWorld(); - if (!player || !world) return false; - - const start = new Vec3d(eyePos.x, eyePos.y, eyePos.z); - const end = new Vec3d(...point); - const result = world.clip(new RaycastContext(start, end, RaycastContext.Block.OUTLINE, RaycastContext.Fluid.NONE, player)); - if (!result || String(result.getType?.()) === 'MISS') return false; - - const hitPos = result.getBlockPos(); - if (!hitPos) return false; - - return hitPos.getX() === targetX && hitPos.getY() === targetY && hitPos.getZ() === targetZ; - } catch (e) { - console.error('V5 Caught error' + e + e.stack); - return false; - } - } - - testPointCustom(targetX, targetY, targetZ, point, eyePos) { - try { - let dx = point[0] - eyePos.x; - let dy = point[1] - eyePos.y; - let dz = point[2] - eyePos.z; - let dist = Math.hypot(dx, dy, dz); - - let dir = new Vector3(dx / dist, dy / dist, dz / dist); - - let hit = raytraceBlocks([eyePos.x, eyePos.y, eyePos.z], dir, dist + 0.2, this.nonAirFilter, true); - - return hit && hit[0] === targetX && hit[1] === targetY && hit[2] === targetZ; - } catch (e) { - console.error('V5 Caught error' + e + e.stack); - return false; - } - } - - nonAirFilter(block) { - return block && block.type && block.type.getID() !== AIR_BLOCK_ID; } } -class VoxelTraverser { - checkLineClearance(startX, startY, startZ, endX, endY, endZ, ignoreX, ignoreY, ignoreZ) { - let currentX = Math.floor(startX); - let currentY = Math.floor(startY); - let currentZ = Math.floor(startZ); - - let goalX = Math.floor(endX); - let goalY = Math.floor(endY); - let goalZ = Math.floor(endZ); - - if (currentX === goalX && currentY === goalY && currentZ === goalZ) { - return true; - } - - let deltaX = endX - startX; - let deltaY = endY - startY; - let deltaZ = endZ - startZ; - - let stepDirectionX = 0; - let stepDirectionY = 0; - let stepDirectionZ = 0; - let nextCrossingX = Infinity; - let nextCrossingY = Infinity; - let nextCrossingZ = Infinity; - let crossingIncrementX = Infinity; - let crossingIncrementY = Infinity; - let crossingIncrementZ = Infinity; - - if (deltaX > 0) { - stepDirectionX = 1; - nextCrossingX = (currentX + 1 - startX) / deltaX; - crossingIncrementX = 1 / deltaX; - } else if (deltaX < 0) { - stepDirectionX = -1; - nextCrossingX = (startX - currentX) / -deltaX; - crossingIncrementX = 1 / -deltaX; - } - - if (deltaY > 0) { - stepDirectionY = 1; - nextCrossingY = (currentY + 1 - startY) / deltaY; - crossingIncrementY = 1 / deltaY; - } else if (deltaY < 0) { - stepDirectionY = -1; - nextCrossingY = (startY - currentY) / -deltaY; - crossingIncrementY = 1 / -deltaY; - } - - if (deltaZ > 0) { - stepDirectionZ = 1; - nextCrossingZ = (currentZ + 1 - startZ) / deltaZ; - crossingIncrementZ = 1 / deltaZ; - } else if (deltaZ < 0) { - stepDirectionZ = -1; - nextCrossingZ = (startZ - currentZ) / -deltaZ; - crossingIncrementZ = 1 / -deltaZ; - } - - let iterationCount = 0; - - while (currentX !== goalX || currentY !== goalY || currentZ !== goalZ) { - if (iterationCount++ > MAX_DDA_ITERATIONS) { - return false; - } - - let minCrossing = Math.min(nextCrossingX, nextCrossingY, nextCrossingZ); - - if (minCrossing === nextCrossingX) { - currentX = currentX + stepDirectionX; - nextCrossingX = nextCrossingX + crossingIncrementX; - } else if (minCrossing === nextCrossingY) { - currentY = currentY + stepDirectionY; - nextCrossingY = nextCrossingY + crossingIncrementY; - } else { - currentZ = currentZ + stepDirectionZ; - nextCrossingZ = nextCrossingZ + crossingIncrementZ; - } - - if (currentX !== ignoreX || currentY !== ignoreY || currentZ !== ignoreZ) { - const block = World.getBlockAt(currentX, currentY, currentZ); - if (!block || !block.type) return false; - - let blockId = block.type.getID(); - - if (!PASSABLE_BLOCKS.has(blockId)) { - return false; - } - } - - if (currentX === goalX && currentY === goalY && currentZ === goalZ) { - break; - } - } - - return true; - } +export function getPlayerEyePosition() { + const now = Date.now(); + if (eyeCache.pos && now - eyeCache.time < 50) return eyeCache.pos; + const eye = Player.getPlayer()?.getEyePosition(); + if (!eye) return null; + eyeCache = { pos: { x: eye.x(), y: eye.y(), z: eye.z() }, time: now }; + return eyeCache.pos; } -class BlockScanner { - constructor() { - this.visibilityChecker = new VisibilityChecker(); - } - - scanPlayerView(maxDistance, filterFunction) { - let eyePos = this.visibilityChecker.getPlayerEyePosition(); - if (!eyePos) return []; - - let filterFunc = - filterFunction || - function (block) { - return block && block.type && block.type.getID() !== AIR_BLOCK_ID; - }; - - return raytraceBlocks([eyePos.x, eyePos.y, eyePos.z], null, maxDistance, filterFunc, false, false); - } - - scanBetweenPoints(point1, point2) { - let dx = point2[0] - point1[0]; - let dy = point2[1] - point1[1]; - let dz = point2[2] - point1[2]; - let distance = Math.hypot(dx, dy, dz); - - if (distance === 0) return []; - - let direction = new Vector3(dx / distance, dy / distance, dz / distance); - - return raytraceBlocks(point1, direction, distance, null, false, false); +const testPointNative = (targetX, targetY, targetZ, point, eye) => { + try { + const player = Player.getPlayer(); + const world = World.getWorld(); + if (!player || !world) return false; + const result = world.clip( + new RaycastContext(new Vec3d(eye.x, eye.y, eye.z), new Vec3d(...point), RaycastContext.Block.OUTLINE, RaycastContext.Fluid.NONE, player) + ); + if (!result || String(result.getType?.()) === 'MISS') return false; + const hit = result.getBlockPos(); + return hit?.getX() === targetX && hit?.getY() === targetY && hit?.getZ() === targetZ; + } catch (error) { + console.error(error); + return false; } +}; - findLookingAtBlock(maxDistance) { - maxDistance = maxDistance || 5; - - try { - let player = Player.getPlayer(); - if (!player) return null; - - let result = player.pick(maxDistance, 0, false); - if (!result) return null; - - let blockPos = result.getBlockPos(); - if (!blockPos) return null; - - let block = World.getBlockAt(blockPos.getX(), blockPos.getY(), blockPos.getZ()); - - return block && block.type.getID() !== AIR_BLOCK_ID ? block : null; - } catch (e) { - console.error('V5 Caught error' + e + e.stack); - return null; - } +export function testPointVisibility(targetX, targetY, targetZ, point, eye) { + try { + const dx = point[0] - eye.x; + const dy = point[1] - eye.y; + const dz = point[2] - eye.z; + const distance = Math.hypot(dx, dy, dz); + if (!distance) return false; + const hit = raytraceBlocks( + [eye.x, eye.y, eye.z], + new Vector3(dx / distance, dy / distance, dz / distance), + distance + 0.2, + (block) => !!block?.type && block.type.getID() !== AIR_BLOCK_ID, + true + ); + return hit && hit[0] === targetX && hit[1] === targetY && hit[2] === targetZ; + } catch (error) { + console.error(error); + return false; } } -class EntityRaytracer { - constructor() { - this.visibilityChecker = new VisibilityChecker(); - } +export function getVisiblePoint(blockX, blockY, blockZ, useNative = true) { + const eye = getPlayerEyePosition(); + if (!eye || Math.hypot(blockX + 0.5 - eye.x, blockY + 0.5 - eye.y, blockZ + 0.5 - eye.z) > 64) return null; - getPlayerLookDirection() { - let player = Player.getPlayer(); - if (!player) return null; - - let yaw = MathUtils.wrapTo180(player.getYRot()); - let pitch = player.getXRot(); - - let yawRad = (-yaw * Math.PI) / 180; - let pitchRad = (-pitch * Math.PI) / 180; - - let cosPitch = Math.cos(pitchRad); - - return { - x: Math.sin(yawRad) * cosPitch, - y: Math.sin(pitchRad), - z: Math.cos(yawRad) * cosPitch, - }; + for (const offset of faceOffsets) { + const point = [blockX + offset[0], blockY + offset[1], blockZ + offset[2]]; + if (useNative ? testPointNative(blockX, blockY, blockZ, point, eye) : testPointVisibility(blockX, blockY, blockZ, point, eye)) return point; } + return null; +} - rayIntersectsAABB(ox, oy, oz, dx, dy, dz, minX, minY, minZ, maxX, maxY, maxZ, maxDist) { - let tMin = 0; - let tMax = maxDist; - - // X axis slab - if (Math.abs(dx) < 1e-8) { - if (ox < minX || ox > maxX) return false; - } else { - let t1 = (minX - ox) / dx; - let t2 = (maxX - ox) / dx; - if (t1 > t2) { - let temp = t1; - t1 = t2; - t2 = temp; - } - tMin = Math.max(tMin, t1); - tMax = Math.min(tMax, t2); - if (tMin > tMax) return false; - } - - // Y axis slab - if (Math.abs(dy) < 1e-8) { - if (oy < minY || oy > maxY) return false; +export const getPointOnBlock = (block, useNative = true) => getVisiblePoint(block.x, block.y, block.z, useNative); + +export function isLineClear(startX, startY, startZ, endX, endY, endZ, ignoreX, ignoreY, ignoreZ) { + let x = Math.floor(startX); + let y = Math.floor(startY); + let z = Math.floor(startZ); + const goalX = Math.floor(endX); + const goalY = Math.floor(endY); + const goalZ = Math.floor(endZ); + if (x === goalX && y === goalY && z === goalZ) return true; + + const dx = endX - startX; + const dy = endY - startY; + const dz = endZ - startZ; + const stepX = Math.sign(dx); + const stepY = Math.sign(dy); + const stepZ = Math.sign(dz); + const deltaX = dx ? Math.abs(1 / dx) : Infinity; + const deltaY = dy ? Math.abs(1 / dy) : Infinity; + const deltaZ = dz ? Math.abs(1 / dz) : Infinity; + let maxX = dx ? (stepX > 0 ? x + 1 - startX : startX - x) / Math.abs(dx) : Infinity; + let maxY = dy ? (stepY > 0 ? y + 1 - startY : startY - y) / Math.abs(dy) : Infinity; + let maxZ = dz ? (stepZ > 0 ? z + 1 - startZ : startZ - z) / Math.abs(dz) : Infinity; + + for (let iterations = 0; iterations < MAX_DDA_ITERATIONS; iterations++) { + if (maxX <= maxY && maxX <= maxZ) { + x += stepX; + maxX += deltaX; + } else if (maxY <= maxZ) { + y += stepY; + maxY += deltaY; } else { - let t1 = (minY - oy) / dy; - let t2 = (maxY - oy) / dy; - if (t1 > t2) { - let temp = t1; - t1 = t2; - t2 = temp; - } - tMin = Math.max(tMin, t1); - tMax = Math.min(tMax, t2); - if (tMin > tMax) return false; + z += stepZ; + maxZ += deltaZ; } - // Z axis slab - if (Math.abs(dz) < 1e-8) { - if (oz < minZ || oz > maxZ) return false; - } else { - let t1 = (minZ - oz) / dz; - let t2 = (maxZ - oz) / dz; - if (t1 > t2) { - let temp = t1; - t1 = t2; - t2 = temp; - } - tMin = Math.max(tMin, t1); - tMax = Math.min(tMax, t2); - if (tMin > tMax) return false; + if (x !== ignoreX || y !== ignoreY || z !== ignoreZ) { + const block = World.getBlockAt(x, y, z); + if (!block?.type || !PASSABLE_BLOCKS.has(block.type.getID())) return false; } - - return tMin <= tMax && tMin >= 0; + if (x === goalX && y === goalY && z === goalZ) return true; } + return false; +} - isLookingAtEntity(entity, maxDistance) { - maxDistance = maxDistance || 6; - - let eyePos = this.visibilityChecker.getPlayerEyePosition(); - if (!eyePos) return false; - - let dir = this.getPlayerLookDirection(); - if (!dir) return false; - - try { - let mcEntity = entity.toMC ? entity.toMC() : entity; - let box = mcEntity.getBoundingBox(); - - if (!box) return false; - - return this.rayIntersectsAABB( - eyePos.x, - eyePos.y, - eyePos.z, - dir.x, - dir.y, - dir.z, - box.minX, - box.minY, - box.minZ, - box.maxX, - box.maxY, - box.maxZ, - maxDistance - ); - } catch (e) { - console.error('V5 Caught error' + e + e.stack); - return false; - } - } - - getEntityHitboxCenter(entity) { - try { - let mcEntity = entity.toMC ? entity.toMC() : entity; - let box = mcEntity.getBoundingBox(); - - if (box) { - return { - x: (box.minX + box.maxX) / 2, - y: (box.minY + box.maxY) / 2, - z: (box.minZ + box.maxZ) / 2, - }; - } - } catch (e) { - console.error('V5 Caught error' + e + e.stack); - } - - // fallback if it doesn't work (this shouldn't EVER happen) - if (typeof entity.getX === 'function') { - return { - x: entity.getX(), - y: entity.getY() + 1, - z: entity.getZ(), - }; - } - +export function getLookingAt(distance = 5) { + try { + const position = Player.getPlayer()?.pick(distance, 0, false)?.getBlockPos(); + if (!position) return null; + const block = World.getBlockAt(position.getX(), position.getY(), position.getZ()); + return block?.type && block.type.getID() !== AIR_BLOCK_ID ? block : null; + } catch (error) { + console.error(error); return null; } } -export const visibilityChecker = new VisibilityChecker(); -export const voxelTraverser = new VoxelTraverser(); -export const blockScanner = new BlockScanner(); -export const entityRaytracer = new EntityRaytracer(); - -export const Raytrace = { - getVisiblePoint: function (blockX, blockY, blockZ, useNative) { - useNative = useNative !== false; - return visibilityChecker.checkBlockVisibility(blockX, blockY, blockZ, useNative); - }, - - isBlockVisible: function (blockX, blockY, blockZ, useNative) { - useNative = useNative !== false; - return visibilityChecker.checkBlockVisibility(blockX, blockY, blockZ, useNative) !== null; - }, - - isLineClear: function (startX, startY, startZ, endX, endY, endZ, ignoreX, ignoreY, ignoreZ) { - return voxelTraverser.checkLineClearance(startX, startY, startZ, endX, endY, endZ, ignoreX, ignoreY, ignoreZ); - }, - - scanBlocks: function (maxDistance, filter) { - return blockScanner.scanPlayerView(maxDistance, filter); - }, - - scanPath: function (start, end) { - return blockScanner.scanBetweenPoints(start, end); - }, - - getLookingAt: function (distance) { - return blockScanner.findLookingAtBlock(distance); - }, - - isLookingAtEntity: function (entity, maxDistance) { - return entityRaytracer.isLookingAtEntity(entity, maxDistance); - }, - - getEntityHitboxCenter: function (entity) { - return entityRaytracer.getEntityHitboxCenter(entity); - }, +const playerLookDirection = () => { + const player = Player.getPlayer(); + if (!player) return null; + const yaw = (-wrapTo180(player.getYRot()) * Math.PI) / 180; + const pitch = (-player.getXRot() * Math.PI) / 180; + const cosPitch = Math.cos(pitch); + return { x: Math.sin(yaw) * cosPitch, y: Math.sin(pitch), z: Math.cos(yaw) * cosPitch }; +}; - clearCache: function () { - visibilityChecker.eyeCache = { pos: null, time: 0 }; - }, +const rayIntersectsBox = (origin, direction, box, maxDistance) => { + let minDistance = 0; + let max = maxDistance; + for (const [position, delta, min, upper] of [ + [origin.x, direction.x, box.minX, box.maxX], + [origin.y, direction.y, box.minY, box.maxY], + [origin.z, direction.z, box.minZ, box.maxZ], + ]) { + if (Math.abs(delta) < 1e-8) { + if (position < min || position > upper) return false; + continue; + } + const first = (min - position) / delta; + const second = (upper - position) / delta; + minDistance = Math.max(minDistance, Math.min(first, second)); + max = Math.min(max, Math.max(first, second)); + if (minDistance > max) return false; + } + return minDistance <= max; }; + +export function isLookingAtEntity(entity, maxDistance = 6) { + const eye = getPlayerEyePosition(); + const direction = playerLookDirection(); + if (!eye || !direction) return false; + try { + const box = (entity.toMC ? entity.toMC() : entity).getBoundingBox(); + return !!box && rayIntersectsBox(eye, direction, box, maxDistance); + } catch (error) { + console.error(error); + return false; + } +} diff --git a/utils/RouteState.js b/utils/RouteState.js deleted file mode 100644 index e46809df..00000000 --- a/utils/RouteState.js +++ /dev/null @@ -1,27 +0,0 @@ -class RouteState { - constructor() { - this.route = null; - this.currentIndex = 0; - this.macroName = null; - this.isActive = false; - } - - setRoute(route, macroName) { - this.route = route; - this.macroName = macroName; - this.currentIndex = 0; - this.isActive = !!route?.length; - } - - clearRoute() { - this.route = null; - this.currentIndex = 0; - this.macroName = null; - this.isActive = false; - } -} - -const routeState = new RouteState(); - -export { routeState }; -export default routeState; diff --git a/utils/Router.js b/utils/Router.js index 43a4ce79..17324178 100644 --- a/utils/Router.js +++ b/utils/Router.js @@ -1,4 +1,4 @@ -import { Chat } from './Chat'; +import { chat } from './Chat'; import { File } from './Constants'; import { Utils } from './Utils'; @@ -49,7 +49,7 @@ class Routes { let configPath = new File(mcDir, 'config/ChatTriggers/modules/V5Config/' + folder); if (!configPath.exists() || !configPath.isDirectory()) { - Chat.message(`&cError: Directory not found.`); + chat(`&cError: Directory not found.`); return []; } @@ -109,7 +109,7 @@ class Routes { */ saveRouteToFile(fileName, routeData) { if (!this._canSaveRoute(fileName)) { - Chat.message('&cNo route file selected. Select a route before editing.'); + chat('&cNo route file selected. Select a route before editing.'); return false; } @@ -140,13 +140,13 @@ class Routes { } if (!this._canSaveRoute(file)) { - Chat.message('&cNo route file selected. Select one in the settings first.'); + chat('&cNo route file selected. Select one in the settings first.'); return this._normalizeRoute(route); } let normalizedRoute = this._normalizeRoute(route); if (route !== null && route !== undefined && !Array.isArray(route)) { - Chat.message('Invalid route data. Resetting to an empty route.'); + chat('Invalid route data. Resetting to an empty route.'); } let routeModified = false; @@ -159,7 +159,7 @@ class Routes { if (addPoinToLook) { let looking = Player.lookingAt(); if (!looking) { - Chat.message('You are not looking at anything'); + chat('You are not looking at anything'); return normalizedRoute; } point.x = Math.floor(looking.x); @@ -177,7 +177,7 @@ class Routes { let movementToVerify = Array.isArray(userMovementInput) ? userMovementInput[0] : userMovementInput; if (!movementToVerify) { - Chat.message('ERROR: Movement type required. Waypoint not added.'); + chat('ERROR: Movement type required. Waypoint not added.'); return normalizedRoute; } @@ -186,7 +186,7 @@ class Routes { if (allowedMovementsSet.has(userMovementUpper)) { point.movements = userMovementUpper; } else { - Chat.message(`ERROR: Movement type '${movementToVerify}' not supported.`); + chat(`ERROR: Movement type '${movementToVerify}' not supported.`); return normalizedRoute; } } @@ -197,16 +197,16 @@ class Routes { if (arrayIndex >= 0 && arrayIndex <= normalizedRoute.length) { normalizedRoute.splice(arrayIndex, 0, point); routeModified = true; - Chat.message(`Added waypoint ${indexToUse}`); + chat(`Added waypoint ${indexToUse}`); } else { normalizedRoute.push(point); routeModified = true; - Chat.message(`Invalid waypoint position, adding to the end.`); + chat(`Invalid waypoint position, adding to the end.`); } } else { normalizedRoute.push(point); routeModified = true; - Chat.message(`Added waypoint to the end of the route.`); + chat(`Added waypoint to the end of the route.`); } break; @@ -217,23 +217,23 @@ class Routes { if (arrayIndex >= 0 && arrayIndex < normalizedRoute.length) { normalizedRoute.splice(arrayIndex, 1); routeModified = true; - Chat.message(`Removed waypoint ${indexToUse}`); + chat(`Removed waypoint ${indexToUse}`); } else { if (normalizedRoute.length > 0) { normalizedRoute.pop(); routeModified = true; - Chat.message(`Invalid waypoint position, removing the last waypoint.`); + chat(`Invalid waypoint position, removing the last waypoint.`); } else { - Chat.message('Route is already empty!'); + chat('Route is already empty!'); } } } else { if (normalizedRoute.length > 0) { normalizedRoute.pop(); routeModified = true; - Chat.message(`Removed the last waypoint.`); + chat(`Removed the last waypoint.`); } else { - Chat.message('Route is already empty!'); + chat('Route is already empty!'); } } break; @@ -244,14 +244,14 @@ class Routes { routeModified = true; const filename = this._toDisplayFileName(file); - Chat.message(`Cleared all waypoints from the route ${filename}`); + chat(`Cleared all waypoints from the route ${filename}`); } else { - Chat.message('Route is already empty!'); + chat('Route is already empty!'); } break; default: - Chat.message('You did not state an action!'); + chat('You did not state an action!'); return normalizedRoute; } @@ -262,3 +262,8 @@ class Routes { } export const Router = new Routes(); +export const getFilesInDir = (...args) => Router.getFilesInDir(...args); +export const getFileFromCallback = (...args) => Router.getFilefromCallback(...args); +export const loadRouteFromFile = (...args) => Router.loadRouteFromFile(...args); +export const saveRouteToFile = (...args) => Router.saveRouteToFile(...args); +export const editRoute = (...args) => Router.Edit(...args); diff --git a/utils/ScheduleTask.js b/utils/ScheduleTask.js index 6d20fa40..3a54399d 100644 --- a/utils/ScheduleTask.js +++ b/utils/ScheduleTask.js @@ -22,7 +22,7 @@ register('tick', () => { try { callback(); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } } }); diff --git a/utils/Sign.js b/utils/Sign.js index 80fff8ef..d39ed2b4 100644 --- a/utils/Sign.js +++ b/utils/Sign.js @@ -1,10 +1,5 @@ -class SignClass { - setLine(line, text) { - const i = Number(line) - 1; - if (!Number.isFinite(i) || Math.floor(i) !== i || i < 0 || i > 3) return; - - Client.setSignLine(i, String(text == null ? '' : text)); - } +export function setSignLine(line, text) { + const index = Number(line) - 1; + if (!Number.isInteger(index) || index < 0 || index > 3) return; + Client.setSignLine(index, String(text ?? '')); } - -export const Sign = new SignClass(); diff --git a/utils/SkyblockEvents.js b/utils/SkyblockEvents.js index 5080b650..b1bfe07b 100644 --- a/utils/SkyblockEvents.js +++ b/utils/SkyblockEvents.js @@ -48,9 +48,7 @@ const getEventName = (event) => { * @param {string} name * @param {function} callback */ -export const registerEventSB = (name, callback) => +export const registerSkyblockEvent = (name, callback) => register('chat', (event) => { if (getEventName(event) === name.toLowerCase()) callback(event); }); - -export const manager = { subscribe: registerEventSB }; diff --git a/utils/SkyblockItemUtil.js b/utils/SkyblockItemUtil.js deleted file mode 100644 index 36c1ad0e..00000000 --- a/utils/SkyblockItemUtil.js +++ /dev/null @@ -1,56 +0,0 @@ -import { fetchURL } from './NetworkUtils'; - -const ITEMS_URL = 'https://api.hypixel.net/v2/resources/skyblock/items'; -const PRICE_URL = 'https://sky.coflnet.com/api/item/price/'; - -class SkyblockItemUtil { - constructor() { - this.items = new Map(); - this.values = new Map(); - this.loadItems(); - } - - loadItems() { - try { - const response = fetchURL(ITEMS_URL); - const items = JSON.parse(response || '{}').items || []; - this.items = new Map(items.map((item) => [this.clean(item.name), item])); - } catch (e) { - console.error('Failed to load SkyBlock items: ' + e); - } - } - - get(name) { - const key = this.clean(name); - return this.items.get(key) ?? null; - } - - getPrice(name) { - const key = this.clean(name); - const cached = this.values.get(key); - if (cached) return cached; - - const item = this.get(name); - if (!item) return null; - - try { - const response = fetchURL(`${PRICE_URL}${encodeURIComponent(item.id)}/current?count=1`); - if (!response) return null; - const bazaar = JSON.parse(response); - const value = { NPC: item.npc_sell_price ?? null, SELL: bazaar.sell ?? null, BUY: bazaar.buy ?? null }; - this.values.set(key, value); - return value; - } catch (e) { - console.error(`Failed to load price for ${item.name}: ` + e); - return null; - } - } - - clean(name) { - return ChatLib.removeFormatting(String(name ?? '')) - .trim() - .toLowerCase(); - } -} - -export const skyblockItem = new SkyblockItemUtil(); diff --git a/utils/TabListUtils.js b/utils/TabListUtils.js index 8d143a2e..5036fd5a 100644 --- a/utils/TabListUtils.js +++ b/utils/TabListUtils.js @@ -1,214 +1,134 @@ -const FORMATTING_CODE_REGEX = /§[0-9a-fk-or]/gi; - -class TabListUtilsClass { - constructor() { - this.currentArea = 'unknown'; - this.areaLastChecked = 0; - this.hasCookieBuff = false; - this.cookieLastChecked = 0; - this.pickaxeAbilityCache = { expiresAt: 0, value: '' }; - this.AREA_CACHE_MS = 1000; - this.COOKIE_CACHE_MS = 2000; - this.PICKAXE_ABILITY_CACHE_MS = 200; - } - - stripFormatting(text) { - if (text == null) return ''; - return String(text).replace(FORMATTING_CODE_REGEX, ''); - } - - getNames() { - return TabList.getNames() || []; - } - - getArea() { - const now = Date.now(); - if (now - this.areaLastChecked < this.AREA_CACHE_MS) return this.currentArea; - - this.areaLastChecked = now; - this.currentArea = 'unknown'; - - try { - const tabLines = this.getNames(); - for (const line of tabLines) { - const cleanLine = this.stripFormatting(line).trim(); - if (!cleanLine.includes('Area:')) continue; +const AREA_CACHE_MS = 1000; +const PICKAXE_ABILITY_CACHE_MS = 200; - const parts = cleanLine.split('Area:'); - if (parts.length <= 1) continue; +let currentArea = 'unknown'; +let areaLastChecked = 0; +let pickaxeAbility = ''; +let pickaxeAbilityExpiresAt = 0; - const detectedArea = parts[1].trim(); - if (!detectedArea) continue; +export const stripTabFormatting = (text) => ChatLib.removeFormatting(String(text ?? '')); +export const getTabListNames = () => TabList.getNames() || []; - this.currentArea = detectedArea; - return this.currentArea; - } - } catch (e) { - console.error('V5 Caught error' + e + e.stack); - } - - return this.currentArea; - } +export function getArea() { + const now = Date.now(); + if (now - areaLastChecked < AREA_CACHE_MS) return currentArea; - resetAreaCache() { - this.currentArea = 'unknown'; - this.areaLastChecked = 0; - } + areaLastChecked = now; + currentArea = 'unknown'; - hasCookie() { - const now = Date.now(); - if (now - this.cookieLastChecked < this.COOKIE_CACHE_MS) return this.hasCookieBuff; - this.cookieLastChecked = now; - - try { - const footer = TabList.getFooter(); - if (!footer) return this.hasCookieBuff; - - const raw = ChatLib.removeFormatting(footer); - if (raw.includes('Cookie Buff') && raw.includes('Not active! Obtain booster cookies')) { - this.hasCookieBuff = false; - } else if (raw.includes('Cookie Buff')) { - this.hasCookieBuff = true; - } - } catch (e) { - console.error('V5 Caught error checking cookie: ' + e); + try { + for (const line of getTabListNames()) { + const [, area] = stripTabFormatting(line).split('Area:'); + if (area?.trim()) return (currentArea = area.trim()); } - - return this.hasCookieBuff; + } catch (error) { + console.error(error); } - getPickaxeAbilityStatus() { - const now = Date.now(); - if (now < this.pickaxeAbilityCache.expiresAt) return this.pickaxeAbilityCache.value; - - const tabNames = this.getNames(); - for (const [i, tabName] of tabNames.entries()) { - const line = this.stripFormatting(tabName?.getName?.() ?? tabName).trim(); - if (!line.includes('Pickaxe Ability') || !tabNames[i + 1]) continue; - - const ability = this.stripFormatting(tabNames[i + 1]?.getName?.() ?? tabNames[i + 1]).trim(); - this.pickaxeAbilityCache.expiresAt = now + this.PICKAXE_ABILITY_CACHE_MS; - this.pickaxeAbilityCache.value = ability; - return ability; - } + return currentArea; +} - this.pickaxeAbilityCache.expiresAt = now + this.PICKAXE_ABILITY_CACHE_MS; - this.pickaxeAbilityCache.value = ''; - return ''; +export function getPickaxeAbilityStatus() { + const now = Date.now(); + if (now < pickaxeAbilityExpiresAt) return pickaxeAbility; + + const names = getTabListNames(); + pickaxeAbility = ''; + for (let i = 0; i < names.length - 1; i++) { + const line = stripTabFormatting(names[i]?.getName?.() ?? names[i]).trim(); + if (!line.includes('Pickaxe Ability')) continue; + pickaxeAbility = stripTabFormatting(names[i + 1]?.getName?.() ?? names[i + 1]).trim(); + break; } + pickaxeAbilityExpiresAt = now + PICKAXE_ABILITY_CACHE_MS; + return pickaxeAbility; +} - readCommissions() { - try { - const tabNames = this.getNames(); - const startIdx = this.findIndex(tabNames, 'Commissions:'); - if (startIdx === -1) return []; - - let endIdx = this.findIndex(tabNames, 'Powders:', startIdx + 1); - if (endIdx === -1) endIdx = tabNames.length; - - const commissions = []; - - for (let i = startIdx + 1; i < endIdx; i++) { - const text = this.stripFormatting(tabNames[i]).trim(); - if (!text.includes(':')) continue; - - const parts = text.split(':'); - const name = parts[0]?.trim(); - const progressText = parts[1]?.trim() || ''; - - if (!name) continue; - - let progress = null; - if (progressText.includes('DONE')) { - progress = 1; - } else if (progressText.includes('%')) { - progress = Number.parseFloat(progressText.replace(/[ %]/g, '')) / 100; - } - - if (progress == null || !Number.isFinite(progress)) continue; - commissions.push({ name: name, progress: progress }); - } - - return commissions; - } catch (e) { - console.error('V5 Caught error' + e + e.stack); - return []; - } +export function findTabListIndex(items, target, start = 0) { + for (let i = start; i < items.length; i++) { + if (stripTabFormatting(items[i]).trim() === target) return i; } + return -1; +} - readVisitors() { - try { - const tabNames = this.getNames(); - const startIdx = tabNames.findIndex((line) => this.stripFormatting(line?.getName?.() ?? line).includes('Visitors:')); - if (startIdx === -1) return []; - - const visitors = []; - for (let i = startIdx + 1; i < tabNames.length && visitors.length < 5; i++) { - const text = this.stripFormatting(tabNames[i]?.getName?.() ?? tabNames[i]).trim(); - if (!text || text.includes('Next Visitor')) break; - - const name = text.replace(/\s*NEW!$/i, '').trim(); - if (name) visitors.push(name); - } - - return visitors.reverse(); - } catch (e) { - console.error('V5 Caught error' + e + e.stack); - return []; +export function readCommissions() { + try { + const names = getTabListNames(); + const start = findTabListIndex(names, 'Commissions:'); + if (start === -1) return []; + const powderIndex = findTabListIndex(names, 'Powders:', start + 1); + const commissions = []; + + for (let i = start + 1; i < (powderIndex === -1 ? names.length : powderIndex); i++) { + const [name, progressText = ''] = stripTabFormatting(names[i]).split(':'); + if (!name?.trim()) continue; + const progress = progressText.includes('DONE') ? 1 : progressText.includes('%') ? Number.parseFloat(progressText.replace(/[ %]/g, '')) / 100 : NaN; + if (Number.isFinite(progress)) commissions.push({ name: name.trim(), progress }); } + return commissions; + } catch (error) { + console.error(error); + return []; } +} - readPests() { - try { - const tabNames = this.getNames(); - const startIdx = tabNames.findIndex((line) => this.stripFormatting(line?.getName?.() ?? line).includes('Pests:')); - if (startIdx === -1) return { alivePestCount: 0, infestedPlots: [] }; - - let alivePestCount = 0; - let infestedPlots = []; - for (let i = startIdx + 1; i < tabNames.length; i++) { - const text = this.stripFormatting(tabNames[i]?.getName?.() ?? tabNames[i]).trim(); - if (text.includes('Pest Traps:')) break; - - const aliveMatch = text.match(/^Alive:\s*(\d+)/); - if (aliveMatch) alivePestCount = Number(aliveMatch[1]); - - const plotsMatch = text.match(/^Plots:\s*(.*)/); - if (plotsMatch) infestedPlots = plotsMatch[1].match(/\d+/g)?.map(Number) ?? []; - } - - return { alivePestCount: alivePestCount, infestedPlots: infestedPlots }; - } catch (e) { - console.error('V5 Caught error' + e + e.stack); - return { alivePestCount: 0, infestedPlots: [] }; +export function readVisitors() { + try { + const names = getTabListNames(); + const start = names.findIndex((line) => stripTabFormatting(line?.getName?.() ?? line).includes('Visitors:')); + if (start === -1) return []; + + const visitors = []; + for (let i = start + 1; i < names.length && visitors.length < 5; i++) { + const text = stripTabFormatting(names[i]?.getName?.() ?? names[i]).trim(); + if (!text || text.includes('Next Visitor')) break; + const name = text.replace(/\s*NEW!$/i, '').trim(); + if (name) visitors.push(name); } + return visitors.reverse(); + } catch (error) { + console.error(error); + return []; } +} - getPestCooldown() { - try { - const tabNames = this.getNames(); - const startIdx = tabNames.findIndex((line) => this.stripFormatting(line?.getName?.() ?? line).includes('Pests:')); - if (startIdx === -1) return 0; - - for (let i = startIdx + 1; i < tabNames.length; i++) { - const text = this.stripFormatting(tabNames[i]?.getName?.() ?? tabNames[i]).trim(); - const match = text.match(/^Cooldown:\s*(?:(\d+)m\s*)?(?:(\d+)s)?$/); - if (match) return Number(match[1] ?? 0) * 60 + Number(match[2] ?? 0); - } - } catch (e) { - console.error('V5 Caught error' + e + e.stack); +export function readPests() { + try { + const names = getTabListNames(); + const start = names.findIndex((line) => stripTabFormatting(line?.getName?.() ?? line).includes('Pests:')); + if (start === -1) return { alivePestCount: 0, infestedPlots: [] }; + + let alivePestCount = 0; + let infestedPlots = []; + for (let i = start + 1; i < names.length; i++) { + const text = stripTabFormatting(names[i]?.getName?.() ?? names[i]).trim(); + if (text.includes('Pest Traps:')) break; + const alive = text.match(/^Alive:\s*(\d+)/); + const plots = text.match(/^Plots:\s*(.*)/); + if (alive) alivePestCount = Number(alive[1]); + if (plots) infestedPlots = plots[1].match(/\d+/g)?.map(Number) ?? []; } - - return 0; + return { alivePestCount, infestedPlots }; + } catch (error) { + console.error(error); + return { alivePestCount: 0, infestedPlots: [] }; } +} - findIndex(items, target, start = 0) { - for (let i = start; i < items.length; i++) { - const cleaned = this.stripFormatting(items[i]).trim(); - if (cleaned === target) return i; +export function getPestCooldown() { + try { + const names = getTabListNames(); + const start = names.findIndex((line) => stripTabFormatting(line?.getName?.() ?? line).includes('Pests:')); + for (let i = start + 1; start !== -1 && i < names.length; i++) { + const match = stripTabFormatting(names[i]?.getName?.() ?? names[i]) + .trim() + .match(/^Cooldown:\s*(?:(\d+)m\s*)?(?:(\d+)s)?$/); + if (match) return Number(match[1] ?? 0) * 60 + Number(match[2] ?? 0); } - return -1; + } catch (error) { + console.error(error); } + return 0; } -export const TabListUtils = new TabListUtilsClass(); +export const TabListUtils = { readCommissions, readVisitors }; diff --git a/utils/ThreadExecutor.js b/utils/ThreadExecutor.js index 889b96a5..4281078c 100644 --- a/utils/ThreadExecutor.js +++ b/utils/ThreadExecutor.js @@ -1,47 +1,25 @@ -const Executors = java.util.concurrent.Executors; -const AtomicInteger = java.util.concurrent.atomic.AtomicInteger; - -class ThreadExecutor { - constructor() { - this.threadNumber = new AtomicInteger(1); - - this.service = Executors.newCachedThreadPool((runnable) => { - const thread = new java.lang.Thread(runnable); - - thread.setDaemon(true); - thread.setName(`V5-Executor-${this.threadNumber.getAndIncrement()}`); - - return thread; - }); - - register('gameUnload', () => { - this.shutdown(); - }); - } - - /** - * Offloads a task to a background thread. - * @param {Function} task - The function to run. - */ - execute(task) { - if (this.service.isShutdown() || typeof task !== 'function') return; +const threadNumber = new java.util.concurrent.atomic.AtomicInteger(1); +const service = java.util.concurrent.Executors.newCachedThreadPool((runnable) => { + const thread = new java.lang.Thread(runnable); + thread.setDaemon(true); + thread.setName(`V5-Executor-${threadNumber.getAndIncrement()}`); + return thread; +}); + +export function executeAsync(task) { + if (service.isShutdown() || typeof task !== 'function') return; + service.execute(() => { + try { + task(); + } catch (error) { + console.error('[V5 Thread Error]:'); + console.error(error); + } + }); +} - this.service.execute(() => { - try { - task(); - } catch (e) { - console.error(`[V5 Thread Error]:`); - console.error('V5 Caught error' + e + e.stack); - } - }); - } +export const Executor = { execute: executeAsync }; - /** - * Shuts down the executor properly. - */ - shutdown() { - this.service.shutdownNow(); - } -} +const shutdownExecutor = () => service.shutdownNow(); -export const Executor = new ThreadExecutor(); +register('gameUnload', shutdownExecutor); diff --git a/utils/TimeUtils.js b/utils/TimeUtils.js index 04454f4c..2f240bc7 100644 --- a/utils/TimeUtils.js +++ b/utils/TimeUtils.js @@ -58,42 +58,28 @@ export class Timer { } } -export const TimeUtils = { - /** - * Formats a duration in ms into the good looking string - * Examples: 0.00s, 12.34s, 1m 2s, 3h 4m 5s, 2d 3h 4m 5s - */ - formatDurationMs: (durationMs) => { - if (!durationMs || durationMs <= 0) return '0.00s'; - - const totalSeconds = Math.floor(durationMs / 1000); - - const s = totalSeconds % 60; - const m = Math.floor(totalSeconds / 60) % 60; - const h = Math.floor(totalSeconds / 3600) % 24; - const d = Math.floor(totalSeconds / 86400); - - const parts = []; - if (d > 0) parts.push(`${d}d`); - if (h > 0) parts.push(`${h}h`); - if (m > 0) parts.push(`${m}m`); - - if (totalSeconds < 60) { - const cs = Math.floor((durationMs % 1000) / 10); - const csStr = String(cs).padStart(2, '0'); - parts.push(`${s}.${csStr}s`); - } else { - parts.push(`${s}s`); - } +export function formatDurationMs(durationMs) { + if (!durationMs || durationMs <= 0) return '0.00s'; + + const totalSeconds = Math.floor(durationMs / 1000); + + const seconds = totalSeconds % 60; + const minutes = Math.floor(totalSeconds / 60) % 60; + const hours = Math.floor(totalSeconds / 3600) % 24; + const days = Math.floor(totalSeconds / 86400); + + const parts = []; + if (days) parts.push(`${days}d`); + if (hours) parts.push(`${hours}h`); + if (minutes) parts.push(`${minutes}m`); + + if (totalSeconds < 60) { + parts.push(`${seconds}.${String(Math.floor((durationMs % 1000) / 10)).padStart(2, '0')}s`); + } else { + parts.push(`${seconds}s`); + } + + return parts.join(' '); +} - return parts.join(' '); - }, - - /** - * Time since start timestamp - */ - formatUptime: (startTimeMs) => { - if (!startTimeMs) return '0.00s'; - return TimeUtils.formatDurationMs(Date.now() - startTimeMs); - }, -}; +export const formatUptime = (startTimeMs) => (startTimeMs ? formatDurationMs(Date.now() - startTimeMs) : '0.00s'); diff --git a/utils/Ungrab.js b/utils/Ungrab.js index 77db9400..f8d20075 100644 --- a/utils/Ungrab.js +++ b/utils/Ungrab.js @@ -1,70 +1,46 @@ import { GLFW, isLinux } from './Constants'; -import { Mixin } from './MixinManager'; - -class UngrabManager { - constructor() { - this.requestedUngrab = false; - this.forcedGrab = false; - Mixin.set('ungrabbed', false); - Mixin.set('inputLocked', false); - } - - /** - * Prevents the player from controlling the camera and locks inventory interaction. - */ - ungrab() { - this.requestedUngrab = true; - if (this.forcedGrab) return; - if (Mixin.get('ungrabbed')) return; - - this.applyUngrab(); - } - - applyUngrab() { - Mixin.set('ungrabbed', true); - Mixin.set('inputLocked', true); - - const mc = Client.getMinecraft(); - if (mc.mouseHandler) { - mc.mouseHandler.releaseMouse(); - - if (isLinux) { - GLFW.glfwSetInputMode(mc.getWindow().handle(), GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_NORMAL); - } - } - } - - /** - * Returns control to the player. - */ - regrab() { - this.requestedUngrab = false; - if (this.forcedGrab) return; - if (!Mixin.get('ungrabbed')) return; - - this.applyRegrab(); - } - - forceGrab() { - this.forcedGrab = true; - this.applyRegrab(); - } - - releaseForcedGrab() { - this.forcedGrab = false; - if (this.requestedUngrab) this.applyUngrab(); - } +import { getMixinValue, setMixinValue } from './MixinManager'; + +let requestedUngrab = false; +let forcedGrab = false; + +setMixinValue('ungrabbed', false); +setMixinValue('inputLocked', false); + +const applyUngrab = () => { + setMixinValue('ungrabbed', true); + setMixinValue('inputLocked', true); + const mc = Client.getMinecraft(); + if (!mc.mouseHandler) return; + mc.mouseHandler.releaseMouse(); + if (isLinux) GLFW.glfwSetInputMode(mc.getWindow().handle(), GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_NORMAL); +}; + +const applyRegrab = () => { + setMixinValue('ungrabbed', false); + setMixinValue('inputLocked', false); + const mc = Client.getMinecraft(); + if (mc.screen != null) return; + mc.mouseHandler.grabMouse(); + GLFW.glfwSetInputMode(mc.getWindow().handle(), GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_DISABLED); +}; + +export function ungrab() { + requestedUngrab = true; + if (!forcedGrab && !getMixinValue('ungrabbed')) applyUngrab(); +} - applyRegrab() { - Mixin.set('ungrabbed', false); - Mixin.set('inputLocked', false); +export function regrab() { + requestedUngrab = false; + if (!forcedGrab && getMixinValue('ungrabbed')) applyRegrab(); +} - const mc = Client.getMinecraft(); - if (mc.screen == null) { - mc.mouseHandler.grabMouse(); - GLFW.glfwSetInputMode(mc.getWindow().handle(), GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_DISABLED); - } - } +export function forceGrab() { + forcedGrab = true; + applyRegrab(); } -export const Mouse = new UngrabManager(); +export function releaseForcedGrab() { + forcedGrab = false; + if (requestedUngrab) applyUngrab(); +} diff --git a/utils/Utils.js b/utils/Utils.js index 750c2568..58239067 100644 --- a/utils/Utils.js +++ b/utils/Utils.js @@ -1,532 +1,156 @@ -import { Chat } from './Chat'; -import { BP, isLinux, isMac, isWindows, Vec3d } from './Constants'; +import { chat } from './Chat'; +import { BP, Vec3d } from './Constants'; import { ClientboundSystemChatPacket } from './Packets'; -import { TabListUtils } from './TabListUtils'; +import { getArea } from './TabListUtils'; export const mc = Client.getMinecraft(); - -export const CONFIG_DIR_NAME = 'V5Config'; -export const CACHE_DURATION_MS = 1000; - -class ConfigFileManager { - constructor(dirName) { - this.directory = dirName; - this.cache = new Map(); - } - - read(fileName) { - let rawContent = FileLib.read(this.directory, fileName); - if (!rawContent || rawContent.trim() === '') { - return {}; - } - - try { - return JSON.parse(rawContent); - } catch (e) { - Chat.message('Config read error for ' + fileName + ': ' + e.message); - console.error('V5 Caught error' + e + e.stack); - - return {}; - } - } - - write(fileName, data) { - try { - let jsonString = JSON.stringify(data, null, 2); - FileLib.write(this.directory, fileName, jsonString); - this.cache.set(fileName, { data: data, timestamp: Date.now() }); - return true; - } catch (e) { - Chat.message('Config write error for ' + fileName + ': ' + e.message); - console.error('V5 Caught error' + e + e.stack); - return false; - } - } - - readWithCache(fileName, ttl) { - ttl = ttl || 5000; - let cached = this.cache.get(fileName); - - if (cached && cached.timestamp && Date.now() - cached.timestamp < ttl) { - return cached.data; - } - - let data = this.read(fileName); - this.cache.set(fileName, { data: data, timestamp: Date.now() }); - return data; - } - - clearCache(fileName) { - if (fileName) { - this.cache.delete(fileName); - } else { - this.cache.clear(); - } - } +const CONFIG_DIR_NAME = 'V5Config'; + +const configCache = new Map(); +let currentSubArea = 'Unknown'; +let subAreaLastChecked = 0; +let currentMana = null; + +const readConfig = (fileName) => { + const content = FileLib.read(CONFIG_DIR_NAME, fileName); + if (!content?.trim()) return {}; + + try { + return JSON.parse(content); + } catch (error) { + chat('Config read error for ' + fileName + ': ' + error.message); + console.error('V5 Caught error' + error + error.stack); + return {}; + } +}; + +export function getConfigFile(fileName) { + if (fileName !== 'config.json') return readConfig(fileName); + + const cached = configCache.get(fileName); + if (cached && Date.now() - cached.timestamp < 200) return cached.data; + const data = readConfig(fileName); + configCache.set(fileName, { data, timestamp: Date.now() }); + return data; } -class LocationDetector { - constructor() { - this.currentSubArea = 'Unknown'; - this.subAreaLastChecked = 0; - } - - getArea() { - return TabListUtils.getArea(); - } - - getSubArea() { - let now = Date.now(); - - if (now - this.subAreaLastChecked < CACHE_DURATION_MS) { - return this.currentSubArea; - } - - this.subAreaLastChecked = now; - - try { - let scoreLines = Scoreboard.getLines(); - if (!scoreLines) return this.currentSubArea; - - for (const line of scoreLines) { - let lineStr = String(line); - - if (lineStr.includes('')) { - let cleaned = this.stripFormatting(lineStr); - let segments = cleaned.split(''); - - if (segments.length > 1) { - this.currentSubArea = segments[1].trim(); - return this.currentSubArea; - } - } - } - } catch (e) { - console.error('V5 Caught error' + e + e.stack); - return this.currentSubArea; - } - - return this.currentSubArea; - } - - getLobbyDay() { - const world = Client.getMinecraft()?.level; - if (!world) return 0; - return Math.floor(world.getOverworldClockTime() / 24000); - } - - stripFormatting(text) { - if (text == null) return ''; - return text.replace(/§[0-9A-FK-OR]/gi, ''); - } - - reset() { - this.currentSubArea = 'Unknown'; - this.subAreaLastChecked = 0; - TabListUtils.resetAreaCache(); +export function writeConfigFile(fileName, data) { + try { + FileLib.write(CONFIG_DIR_NAME, fileName, JSON.stringify(data, null, 2)); + configCache.set(fileName, { data, timestamp: Date.now() }); + return true; + } catch (error) { + chat('Config write error for ' + fileName + ': ' + error.message); + console.error('V5 Caught error' + error + error.stack); + return false; } } -class ManaDetector { - constructor() { - this.currentMana = null; - this.manaPatternWithColors = /(?:\u00A7b)?([\d,]+)\/([\d,]+)(?:\u270E|\uE003)\s*(?:Mana|(?:\u00A73)?([\d,]+)\u02AC)\s*/; - this.manaPattern = /([\d,]+)\/([\d,]+)(?:\u270E|\uE003)\s*(?:Mana|([\d,]+)\u02AC)\s*/; - - register('worldLoad', () => this.reset()); - register('packetReceived', (packet) => { - this.onGameMessage(packet); - }).setFilteredClass(ClientboundSystemChatPacket); - } - - onGameMessage(packet) { - if (!packet || !packet.overlay || !packet.overlay()) return; - - const content = packet.content(); - const actionBar = content?.getString(); - if (!actionBar) return; +export const area = getArea; - let match = actionBar.match(this.manaPatternWithColors); +export function subArea() { + const now = Date.now(); + if (now - subAreaLastChecked < 1000) return currentSubArea; + subAreaLastChecked = now; - if (!match) { - const stripped = actionBar.replace(/\u00A7[0-9A-FK-ORa-fk-or]/g, ''); - match = stripped.match(this.manaPattern); + try { + for (const line of Scoreboard.getLines() || []) { + const text = ChatLib.removeFormatting(String(line)); + if (!text.includes('')) continue; + const detected = text.split('')[1]?.trim(); + if (detected) return (currentSubArea = detected); } - if (!match) return; - - this.currentMana = Number(match[1].replace(/,/g, '')); - } - - getCurrentMana() { - return this.currentMana; - } - - reset() { - this.currentMana = null; + } catch (error) { + console.error('V5 Caught error' + error + error.stack); } + return currentSubArea; } -class CollisionChecker { - checkPlayerCollision() { - try { - let player = Player.getPlayer(); - if (!player) return false; - - let bbox = player.getBoundingBox(); - let expanded = bbox.inflate(0.01, 0, 0.01); - - let xMin = Math.floor(expanded.minX); - let yMin = Math.floor(expanded.minY); - let zMin = Math.floor(expanded.minZ); - let xMax = Math.floor(expanded.maxX); - let yMax = Math.floor(expanded.maxY); - let zMax = Math.floor(expanded.maxZ); - - const blocks = World.getBlocksInBox(xMin, yMin, zMin, xMax, yMax, zMax); - for (const block of blocks) { - if (!block || !block.type || block.type.getID() === 0) continue; - - if (this.hasCollision(block.x, block.y, block.z)) { - return true; - } - } - - return false; - } catch (e) { - console.error('V5 Caught error' + e + e.stack); - return false; - } - } - - hasCollision(x, y, z) { - try { - const world = World.getWorld(); - if (!world) return false; - - let blockPos = new BP(x, y, z); - let blockState = world.getBlockState(blockPos); - if (!blockState) return false; - - let shape = blockState.getCollisionShape(world, blockPos); - return !shape.isEmpty(); - } catch (e) { - console.error('V5 Caught error' + e + e.stack); - return false; - } - } +export function getDay() { + const world = mc?.level; + return world ? Math.floor(world.getOverworldClockTime() / 24000) : 0; } -class VectorConverter { - convert(input) { - if (!input) return null; +export const randomInt = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; +export const randomFloat = (min, max) => Math.random() * (max - min) + min; - let coordinates; - if (this.hasXYZ(input)) { - coordinates = [input.x, input.y, input.z]; - } else if (this.hasXYZMethods(input)) { - coordinates = [input.x(), input.y(), input.z()]; - } else if (Array.isArray(input) && input.length >= 3) { - coordinates = input; - } else if (this.hasPositionMethods(input)) { - coordinates = [input.getX(), input.getY(), input.getZ()]; - } +export function convertToVector(input) { + if (!input) return null; - const vector = coordinates?.slice(0, 3); - return vector?.every(Number.isFinite) ? new Vec3d(...vector) : null; + let coordinates; + if (typeof input.x === 'number' && typeof input.y === 'number' && typeof input.z === 'number') { + coordinates = [input.x, input.y, input.z]; + } else if (typeof input.x === 'function' && typeof input.y === 'function' && typeof input.z === 'function') { + coordinates = [input.x(), input.y(), input.z()]; + } else if (Array.isArray(input) && input.length >= 3) { + coordinates = input; + } else if (typeof input.getX === 'function' && typeof input.getY === 'function' && typeof input.getZ === 'function') { + coordinates = [input.getX(), input.getY(), input.getZ()]; } - hasXYZ(obj) { - return obj && typeof obj.x === 'number' && typeof obj.y === 'number' && typeof obj.z === 'number'; - } - - hasXYZMethods(obj) { - return obj && typeof obj.x === 'function' && typeof obj.y === 'function' && typeof obj.z === 'function'; - } - - hasPositionMethods(obj) { - return obj && typeof obj.getX === 'function' && typeof obj.getY === 'function' && typeof obj.getZ === 'function'; - } + const vector = coordinates?.slice(0, 3); + return vector?.every(Number.isFinite) ? new Vec3d(...vector) : null; } -let configManager = new ConfigFileManager(CONFIG_DIR_NAME); -let locationDetector = new LocationDetector(); -let collisionChecker = new CollisionChecker(); -let vectorConverter = new VectorConverter(); -let manaDetector = new ManaDetector(); - -class UtilsClass { - constructor() { - this.configName = CONFIG_DIR_NAME; - } - - noCollision(blockVec) { - const world = World.getWorld(); - if (!blockVec || !world) return false; - const blockPosNMS = new BP(blockVec.x, blockVec.y, blockVec.z); - const blockState = world.getBlockState(blockPosNMS); - if (!blockState) return false; - const collisionShape = blockState.getCollisionShape(world, blockPosNMS); - return collisionShape.isEmpty(); - } - - playerIsCollided(ignoreBottomSlab) { - const shouldIgnoreBottomSlab = !!ignoreBottomSlab; - const player = Player.getPlayer(); - const world = World.getWorld(); - if (!player || !world) return false; - - const playerBox = player.getBoundingBox(); - // Use a small epsilon to avoid "ghost" collisions with adjacent blocks - const expandedBox = playerBox.inflate(0.01, 0, 0.01); - - let minX = Math.floor(expandedBox.minX); - let minY = Math.floor(expandedBox.minY); - let minZ = Math.floor(expandedBox.minZ); - let maxX = Math.floor(expandedBox.maxX); - let maxY = Math.floor(expandedBox.maxY); - let maxZ = Math.floor(expandedBox.maxZ); - - const blocks = World.getBlocksInBox(minX, minY, minZ, maxX, maxY, maxZ); - for (const block of blocks) { - if (!block || !block.type || block.type.getID() === 0) continue; - - const blockPosNMS = new BP(block.x, block.y, block.z); - const blockState = world.getBlockState(blockPosNMS); - const registryName = block.type.getRegistryName()?.toLowerCase?.(); - - if (!registryName || !blockState) continue; - - if (registryName.includes('carpet')) continue; - - if (shouldIgnoreBottomSlab) { - if (registryName.includes('farmland')) continue; - - if (registryName.includes('slab')) { - const stateString = blockState.toString(); - if (stateString.includes('type=bottom')) continue; - } - } - - const collisionShape = blockState.getCollisionShape(world, blockPosNMS); - if (collisionShape.isEmpty()) continue; - - return true; - } - - return false; - } - - sidesOfCollision() { - const player = Player.getPlayer(); - const mcWorld = World.getWorld(); - if (!player || !mcWorld) return { front: false, back: false, left: false, right: false }; - - const playerBox = player.getBoundingBox(); - const expandedBox = playerBox.inflate(0.01, 0.01, 0.01); - - let yaw = ((player.getYRot() % 360) + 360) % 360; - const collisionSides = { NORTH: false, SOUTH: false, WEST: false, EAST: false }; - - let minX = Math.floor(expandedBox.minX); - let minY = Math.floor(expandedBox.minY); - let minZ = Math.floor(expandedBox.minZ); - let maxX = Math.floor(expandedBox.maxX); - let maxY = Math.floor(expandedBox.maxY); - let maxZ = Math.floor(expandedBox.maxZ); - - const blocks = World.getBlocksInBox(minX, minY, minZ, maxX, maxY, maxZ); - for (let blockIndex = 0; blockIndex < blocks.length; blockIndex++) { - const block = blocks[blockIndex]; - if (!block || !block.type || block.type.getID() === 0) continue; - - let blockPos = new BP(block.x, block.y, block.z); - let blockState = mcWorld.getBlockState(blockPos); - if (!blockState) continue; - let voxelShape = blockState.getCollisionShape(mcWorld, blockPos); - - if (!voxelShape || voxelShape.isEmpty()) continue; - - let collisionBoxes = voxelShape.toAabbs(); - - for (let i = 0; i < collisionBoxes.size(); i++) { - let blockBox = collisionBoxes.get(i).move(block.x, block.y, block.z); - - if (expandedBox.intersects(blockBox)) { - if (blockBox.maxX <= playerBox.minX + 0.05) collisionSides.WEST = true; - if (blockBox.minX >= playerBox.maxX - 0.05) collisionSides.EAST = true; - if (blockBox.maxZ <= playerBox.minZ + 0.05) collisionSides.NORTH = true; - if (blockBox.minZ >= playerBox.maxZ - 0.05) collisionSides.SOUTH = true; - } - } - } - - let res = { front: false, back: false, left: false, right: false }; - - if (yaw >= 315 || yaw < 45) { - res.front = collisionSides.SOUTH; - res.back = collisionSides.NORTH; - res.left = collisionSides.EAST; - res.right = collisionSides.WEST; - } else if (yaw >= 45 && yaw < 135) { - res.front = collisionSides.WEST; - res.back = collisionSides.EAST; - res.left = collisionSides.SOUTH; - res.right = collisionSides.NORTH; - } else if (yaw >= 135 && yaw < 225) { - res.front = collisionSides.NORTH; - res.back = collisionSides.SOUTH; - res.left = collisionSides.WEST; - res.right = collisionSides.EAST; - } else if (yaw >= 225 && yaw < 315) { - res.front = collisionSides.EAST; - res.back = collisionSides.WEST; - res.left = collisionSides.NORTH; - res.right = collisionSides.SOUTH; - } - - return res; - } - - /** - * @param {Object} input - * @returns {Vec3d} - */ - convertToVector(input) { - return vectorConverter.convert(input); - } - - getConfigFile(fileName) { - if (fileName === 'config.json') { - return configManager.readWithCache(fileName, 200); - } - return configManager.read(fileName); - } - - writeConfigFile(fileName, data) { - return configManager.write(fileName, data); - } - - getConfigFileCached(fileName, ttl) { - return configManager.readWithCache(fileName, ttl); - } - - clearConfigCache(fileName) { - configManager.clearCache(fileName); - } - - area() { - return locationDetector.getArea(); - } - - subArea() { - return locationDetector.getSubArea(); - } - - getDay() { - return locationDetector.getLobbyDay(); - } - - resetLocationCache() { - locationDetector.reset(); - } - - randomInt(min, max) { - return Math.floor(Math.random() * (max - min + 1)) + min; - } - - randomFloat(min, max) { - return Math.random() * (max - min) + min; - } - - clamp(value, min, max) { - return Math.max(min, Math.min(max, value)); - } - - lerp(start, end, progress) { - return start + (end - start) * progress; - } - - isPointInBox(point, boxMin, boxMax) { - return point.x >= boxMin.x && point.x <= boxMax.x && point.y >= boxMin.y && point.y <= boxMax.y && point.z >= boxMin.z && point.z <= boxMax.z; - } - - distance3D(x1, y1, z1, x2, y2, z2) { - let dx = x2 - x1; - let dy = y2 - y1; - let dz = z2 - z1; - return Math.hypot(dx, dy, dz); - } - - distance2D(x1, z1, x2, z2) { - let dx = x2 - x1; - let dz = z2 - z1; - return Math.hypot(dx, dz); - } - - openBrowser(url) { - const t = new java.lang.Thread(() => { - try { - if (isMac) { - java.lang.Runtime.getRuntime().exec(['open', url]); - return; - } - - try { - if (java.awt.Desktop.isDesktopSupported() && java.awt.Desktop.getDesktop().isSupported(java.awt.Desktop.Action.BROWSE)) { - java.awt.Desktop.getDesktop().browse(new java.net.URI(url)); - return; - } - } catch (ignored) {} +export function playerIsCollided(ignoreBottomSlab = false) { + const player = Player.getPlayer(); + const world = World.getWorld(); + if (!player || !world) return false; + + const box = player.getBoundingBox().inflate(0.01, 0, 0.01); + const blocks = World.getBlocksInBox( + Math.floor(box.minX), + Math.floor(box.minY), + Math.floor(box.minZ), + Math.floor(box.maxX), + Math.floor(box.maxY), + Math.floor(box.maxZ) + ); + + for (const block of blocks) { + if (!block?.type || block.type.getID() === 0) continue; + const position = new BP(block.x, block.y, block.z); + const state = world.getBlockState(position); + const name = block.type.getRegistryName()?.toLowerCase?.(); + if (!state || !name || name.includes('carpet')) continue; + if (ignoreBottomSlab && (name.includes('farmland') || (name.includes('slab') && state.toString().includes('type=bottom')))) continue; + if (!state.getCollisionShape(world, position).isEmpty()) return true; + } + return false; +} - if (isWindows) { - java.lang.Runtime.getRuntime().exec(['rundll32', 'url.dll,FileProtocolHandler', url]); - } else if (isLinux) { - java.lang.Runtime.getRuntime().exec(['xdg-open', url]); - } - } catch (e) { - console.error('V5 Caught error in openBrowser: ' + e + e.stack); +export function getGardenPestStatus() { + let gardenPests = null; + let currentPlot = null; + let currentPlotPests = null; + + try { + for (const line of Scoreboard.getLines() || []) { + const text = ChatLib.removeFormatting(String(line.getName?.() ?? line)).trim(); + const isGarden = text.includes('The Garden'); + const gardenMatch = isGarden && text.match(/\bx\s*(\d+)\s*$/); + const plotMatch = text.match(/\bPlot\s*-\s*(\d+)\b(?:.*?\bx\s*(\d+))?/); + if (isGarden) gardenPests = Number(gardenMatch?.[1] || 0); + if (plotMatch) { + currentPlot = Number(plotMatch[1]); + currentPlotPests = Number(plotMatch[2] || 0); } - }); - t.setDaemon(true); - t.start(); - } - - hasCookie() { - return TabListUtils.hasCookie(); - } - - getGardenPestStatus() { - let gardenPests = null; - let currentPlot = null; - let currentPlotPests = null; - - try { - Scoreboard.getLines()?.forEach((line) => { - const text = ChatLib.removeFormatting(String(line.getName?.() ?? line)).trim(); - const isGarden = text.includes('The Garden'); - const gardenMatch = isGarden && text.match(/\bx\s*(\d+)\s*$/); - const plotMatch = text.match(/\bPlot\s*-\s*(\d+)\b(?:.*?\bx\s*(\d+))?/); - if (isGarden) gardenPests = Number(gardenMatch?.[1] || 0); - if (plotMatch) { - currentPlot = Number(plotMatch[1]); - currentPlotPests = Number(plotMatch[2] || 0); - } - }); - } catch (e) { - console.error('V5 Caught error' + e + e.stack); } - - return { gardenPests, currentPlot, currentPlotPests }; + } catch (error) { + console.error('V5 Caught error' + error + error.stack); } + return { gardenPests, currentPlot, currentPlotPests }; +} - // This doesnt work for some users. please fix. - getCurrentMana() { - return manaDetector.getCurrentMana(); - } +export const getCurrentMana = () => currentMana; - checkPlayerCollision() { - return collisionChecker.checkPlayerCollision(); - } -} +export const Utils = { area, convertToVector, getConfigFile, randomInt, writeConfigFile }; -export const Utils = new UtilsClass(); +register('worldLoad', () => (currentMana = null)); +register('packetReceived', (packet) => { + if (!packet?.overlay?.()) return; + const actionBar = packet.content()?.getString(); + if (!actionBar) return; + const match = actionBar.replace(/\u00A7[0-9A-FK-OR]/gi, '').match(/([\d,]+)\/([\d,]+)(?:\u270E|\uE003)\s*(?:Mana|([\d,]+)\u02AC)\s*/); + if (match) currentMana = Number(match[1].replace(/,/g, '')); +}).setFilteredClass(ClientboundSystemChatPacket); diff --git a/utils/V5Commands.js b/utils/V5Commands.js index d1e35252..395e3164 100644 --- a/utils/V5Commands.js +++ b/utils/V5Commands.js @@ -1,7 +1,7 @@ -import { Chat } from './Chat'; +import { chat } from './Chat'; import { File } from './Constants'; import { isDeveloperModeEnabled, setDeveloperModeEnabled } from './DeveloperModeState'; -import { ServerInfo } from './player/ServerInfo'; +import { getPingColor, getServerInfo, getTpsColor } from './player/ServerInfo'; const commandRegistry = new Map(); let developerModeEnableConfirmationPending = false; @@ -14,7 +14,7 @@ const callCommand = function (name) { if (args.length === 1 && typeof args[0] === 'string') args = args[0].trim().split(/\s+/).filter(Boolean); handler(...args); } catch (error) { - Chat.message(`&cInternal command failed: &f${name}`); + chat(`&cInternal command failed: &f${name}`); console.error('V5 command execution failed:', name, error); } }; @@ -69,8 +69,8 @@ export const v5Command = (name, handler, argumentTypes = []) => { }; v5Command('help', () => { - Chat.message('&bV5 Commands:'); - for (const name of Array.from(commandRegistry.keys()).sort()) Chat.message(`&7/v5 ${name}`); + chat('&bV5 Commands:'); + for (const name of Array.from(commandRegistry.keys()).sort()) chat(`&7/v5 ${name}`); }); v5Command('config', () => { @@ -78,12 +78,12 @@ v5Command('config', () => { }); const showServerInfo = () => { - const { tps, ping } = ServerInfo.getServerInfo(); + const { tps, ping } = getServerInfo(); const toColor = (value) => { const hex = Number(value).toString(16).padStart(6, '0'); return `§x§${hex[0]}§${hex[1]}§${hex[2]}§${hex[3]}§${hex[4]}§${hex[5]}`; }; - Chat.message(`TPS ${toColor(ServerInfo.getTpsColor(tps))}${tps}&f | Ping ${toColor(ServerInfo.getPingColor(ping))}${ping}ms`); + chat(`TPS ${toColor(getTpsColor(tps))}${tps}&f | Ping ${toColor(getPingColor(ping))}${ping}ms`); }; v5Command('tps', showServerInfo); @@ -92,7 +92,7 @@ v5Command('ping', showServerInfo); v5Command( 'mining gemstone', (...args) => { - if (!args.length) return Chat.message('&cUsage: &7/v5 mining gemstone '); + if (!args.length) return chat('&cUsage: &7/v5 mining gemstone '); ChatLib.command(`gemstone ${args.join(' ')}`); }, ['greedyString'] @@ -102,7 +102,7 @@ v5Command('visuals gif list', () => ChatLib.command('gif list')); v5Command( 'visuals gif pick', (index) => { - if (index === undefined) return Chat.message('&cUsage: &7/v5 visuals gif pick '); + if (index === undefined) return chat('&cUsage: &7/v5 visuals gif pick '); ChatLib.command(`gif pick ${index}`); }, ['integer'] @@ -112,28 +112,26 @@ v5Command('visuals gif toggle', () => ChatLib.command('gif toggle')); const setDeveloperMode = (enabled) => { if (!enabled) { developerModeEnableConfirmationPending = false; - if (!isDeveloperModeEnabled()) return Chat.message('&cDeveloper Mode is already disabled.'); + if (!isDeveloperModeEnabled()) return chat('&cDeveloper Mode is already disabled.'); setDeveloperModeEnabled(false); - Chat.message('&aDeveloper Mode disabled.'); + chat('&aDeveloper Mode disabled.'); ChatLib.command('ct load', true); return; } - if (isDeveloperModeEnabled()) return Chat.message("&cDeveloper Mode enabled. Run '/V5 developerMode false' to disable."); + if (isDeveloperModeEnabled()) return chat("&cDeveloper Mode enabled. Run '/V5 developerMode false' to disable."); if (!developerModeEnableConfirmationPending) { developerModeEnableConfirmationPending = true; - Chat.message( - '&cDeveloper Mode should only be enabled if you know what your doing. It will disable auto updates, unlock WIP modules, and potentially ban you.' - ); - Chat.message("&cRun '/V5 developerMode true' again to confirm."); + chat('&cDeveloper Mode should only be enabled if you know what your doing. It will disable auto updates, unlock WIP modules, and potentially ban you.'); + chat("&cRun '/V5 developerMode true' again to confirm."); return; } developerModeEnableConfirmationPending = false; setDeveloperModeEnabled(true); - Chat.message('&cDeveloper Mode enabled. Auto updates are disabled and WIP modules are unlocked.'); + chat('&cDeveloper Mode enabled. Auto updates are disabled and WIP modules are unlocked.'); ChatLib.command('ct load', true); }; diff --git a/utils/Webhooks.js b/utils/Webhooks.js index acab80c8..f2696213 100644 --- a/utils/Webhooks.js +++ b/utils/Webhooks.js @@ -1,7 +1,7 @@ -import { Chat } from './Chat'; +import { sendDebugMessage } from './Chat'; import { CLIENT_VERSION, Consumer, ScreenshotRecorder, URL } from './Constants'; -import { Executor } from './ThreadExecutor'; -import { Utils } from './Utils'; +import { executeAsync } from './ThreadExecutor'; +import { area, getConfigFile, subArea, writeConfigFile } from './Utils'; class DiscordNotifier { constructor() { @@ -18,7 +18,7 @@ class DiscordNotifier { loadSettings() { try { - const cfg = Utils.getConfigFile('webhook.json'); + const cfg = getConfigFile('webhook.json'); if (cfg) { this.endpoint = cfg.url || null; this.mentionId = cfg.userId || null; @@ -27,19 +27,19 @@ class DiscordNotifier { if (this.active) return { url: this.endpoint, userId: this.mentionId }; } } catch (e) { - console.error('V5 Caught error' + e + e.stack); - Chat.messageDebug('Failed to initialize webhook settings.'); + console.error(e); + sendDebugMessage('Failed to initialize webhook settings.'); } } persistSettings() { try { - Utils.writeConfigFile('webhook.json', { + writeConfigFile('webhook.json', { url: this.endpoint, userId: this.mentionId, }); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } } @@ -82,7 +82,7 @@ class DiscordNotifier { .orElse(null); if (!latestFile) return; - const finalTitle = title || 'Screenshot captured from ' + Utils.area(); + const finalTitle = title || 'Screenshot captured from ' + area(); this.uploadScreenshot(latestFile, finalTitle, description, color, footer, ping); }); @@ -100,7 +100,7 @@ class DiscordNotifier { const playerName = Player.getName ? Player.getName() : 'V5'; const playerUuid = Player.getUUID ? Player.getUUID().toString().replace(/-/g, '') : ''; - Executor.execute(() => { + executeAsync(() => { try { const connection = new URL(this.endpoint).openConnection(); connection.setRequestMethod('POST'); @@ -124,16 +124,16 @@ class DiscordNotifier { connection.getInputStream().close(); } catch (e) { - console.error('V5 Caught error' + e + e.stack); - Chat.messageDebug('Webhook transmission failed: ' + e); + console.error(e); + sendDebugMessage('Webhook transmission failed: ' + e); } }); } onStartup() { if (!this.sendLoadEmbeds) return; - const areaName = Utils.area(); - const subAreaName = Utils.subArea(); + const areaName = area(); + const subAreaName = subArea(); const embed = { title: areaName ? '**Client Initialized**' : '**Environment Loaded**', @@ -175,7 +175,7 @@ class DiscordNotifier { const playerName = Player.getName ? Player.getName() : 'V5'; const playerUuid = Player.getUUID ? Player.getUUID().toString().replace(/-/g, '') : ''; - Executor.execute(() => { + executeAsync(() => { try { const boundary = '----------' + java.lang.Long.toString(java.lang.System.currentTimeMillis(), 16); const connection = new URL(this.endpoint).openConnection(); @@ -238,16 +238,14 @@ class DiscordNotifier { } } -export const notifier = new DiscordNotifier(); - -export const Webhook = { - setWebhook: (url) => notifier.updateEndpoint(url), - setUserId: (id) => notifier.updateMention(id), - sendEmbed: (e, p) => notifier.publish(e, p), - sendFailsafeEmbed: (e, p) => notifier.publishFailsafe(e, p), - getData: () => notifier.loadSettings(), - sendLoadEmbeds: (v) => notifier.setLoadEmbeds(v), - sendFailsafeEmbeds: (v) => notifier.setFailsafeEmbeds(v), - sendScreenshot: (t, d, c, f, p) => notifier.takeScreenshot(t, d, c, f, p), - sendFailsafeScreenshot: (t, d, c, f, p) => notifier.takeFailsafeScreenshot(t, d, c, f, p), -}; +const notifier = new DiscordNotifier(); + +export const setWebhook = (url) => notifier.updateEndpoint(url); +export const setWebhookUserId = (id) => notifier.updateMention(id); +export const sendEmbed = (embeds, shouldMention) => notifier.publish(embeds, shouldMention); +export const sendFailsafeEmbed = (embeds, shouldMention) => notifier.publishFailsafe(embeds, shouldMention); +export const getWebhookData = () => notifier.loadSettings(); +export const setLoadEmbedsEnabled = (enabled) => notifier.setLoadEmbeds(enabled); +export const setFailsafeEmbedsEnabled = (enabled) => notifier.setFailsafeEmbeds(enabled); +export const sendScreenshot = (...args) => notifier.takeScreenshot(...args); +export const sendFailsafeScreenshot = (...args) => notifier.takeFailsafeScreenshot(...args); diff --git a/utils/backend/IRC.js b/utils/backend/IRC.js index e5d809d1..da0e78ca 100644 --- a/utils/backend/IRC.js +++ b/utils/backend/IRC.js @@ -1,4 +1,4 @@ -import { Chat } from '../Chat'; +import { sendAnnouncement, sendIrcMessage } from '../Chat'; import { Categories } from '../../gui/categories/CategorySystem'; let ircEnabled = true; @@ -24,34 +24,34 @@ export function handleIRCMessage(data) { if (!ircEnabled) return; const sender = data.user || 'Unknown'; const message = `${data.msg ?? ''}`; - Chat.messageIrc(`&9${sender}&r: ${message}`); + sendIrcMessage(`&9${sender}&r: ${message}`); return true; } if (data.type === 'error') { - Chat.messageIrc(`Error: ${data.code || 'Unknown'}`); + sendIrcMessage(`Error: ${data.code || 'Unknown'}`); return true; } if (data.type === 'system') { if (data.code === 'PREFIX_UPDATED') { - Chat.messageIrc('Your prefix has been changed'); + sendIrcMessage('Your prefix has been changed'); } else if (data.code === 'MUTED') { const expiresAt = Number(data.mute_expires_at); if (Number.isFinite(expiresAt)) { - Chat.messageIrc('You have been muted until ' + new Date(expiresAt * 1000).toISOString()); + sendIrcMessage('You have been muted until ' + new Date(expiresAt * 1000).toISOString()); } else { - Chat.messageIrc('You have been muted'); + sendIrcMessage('You have been muted'); } } else { - Chat.messageIrc(`System: ${data.code || ''}`); + sendIrcMessage(`System: ${data.code || ''}`); } return true; } if (data.type === 'announcement') { if (!ircEnabled) return; - Chat.sendAnnouncement(`${data.msg ?? ''}`); + sendAnnouncement(`${data.msg ?? ''}`); return true; } diff --git a/utils/backend/RemoteControl.js b/utils/backend/RemoteControl.js deleted file mode 100644 index 5308cea9..00000000 --- a/utils/backend/RemoteControl.js +++ /dev/null @@ -1 +0,0 @@ -export function handleRemoteMessage() {} diff --git a/utils/backend/WebSocket.js b/utils/backend/WebSocket.js index f75872d6..5734dfac 100644 --- a/utils/backend/WebSocket.js +++ b/utils/backend/WebSocket.js @@ -1,5 +1,5 @@ import WebSocket from 'WebSocket'; -import { Chat } from '../Chat'; +import { logMessage, sendIrcMessage } from '../Chat'; import { Links } from '../Constants'; import { returnDiscord } from '../NetworkUtils'; import { ServerboundChatPacket } from '../Packets'; @@ -41,9 +41,9 @@ function handleSocketDisconnect({ code, reason, exception }) { if (exception) { console.error('WebSocket error:', exception); - Chat.messageIrc('Connection error: ' + exception); + sendIrcMessage('Connection error: ' + exception); } else { - Chat.log(`Disconnected from chat server (code ${code}, reason: ${reason})`); + logMessage(`Disconnected from chat server (code ${code}, reason: ${reason})`); } attemptReconnect(); } @@ -74,18 +74,18 @@ function handleIncomingMessage(raw) { sendChatMessage(meows[Math.floor(Math.random() * meows.length)]); } } catch (e) { - Chat.messageIrc('An error occurred parsing message:'); - console.error('V5 Caught error' + e + e.stack); + sendIrcMessage('An error occurred parsing message:'); + console.error(e); } } -export function sendChatMessage(content) { +function sendChatMessage(content) { if (!isConnected || !ws) return; try { ws.send(content); } catch (e) { - Chat.messageIrc('Failed to send message: '); - console.error('V5 Caught error' + e + e.stack); + sendIrcMessage('Failed to send message: '); + console.error(e); } } @@ -99,7 +99,7 @@ function connectWebSocket() { try { previousSocket.close(); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } } @@ -107,7 +107,7 @@ function connectWebSocket() { if (!token) { isConnected = false; - return Chat.messageIrc('&cLoader has not authenticated. IRC is unavailable.'); + return sendIrcMessage('&cLoader has not authenticated. IRC is unavailable.'); } returnDiscord(token); const socket = new WebSocket(Links.WEBSOCKET_URL); @@ -153,7 +153,7 @@ function connectWebSocket() { function attemptReconnect() { if (gameUnload) return; - if (isConnected) return Chat.messageIrc('Already connected to irc!'); + if (isConnected) return sendIrcMessage('Already connected to irc!'); if (reconnectScheduled) return; reconnectAttempts++; @@ -165,7 +165,7 @@ function attemptReconnect() { ScheduleTask(delay, () => { reconnectScheduled = false; if (gameUnload) return; - if (isConnected) return Chat.messageIrc('Already connected to irc!'); + if (isConnected) return sendIrcMessage('Already connected to irc!'); connectWebSocket(); }); } @@ -182,7 +182,7 @@ register('packetSent', (packet, event) => { try { message = packet.message(); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } if (!message || !message.startsWith('#')) return; diff --git a/utils/dependencies/BloomCore/RaytraceBlocks.js b/utils/dependencies/BloomCore/RaytraceBlocks.js index eba7ccbc..fed77b2c 100644 --- a/utils/dependencies/BloomCore/RaytraceBlocks.js +++ b/utils/dependencies/BloomCore/RaytraceBlocks.js @@ -23,7 +23,7 @@ export const raytraceBlocks = ( return traverseVoxels(startPos, endPos, blockCheckFunc, returnWhenTrue, stopWhenNotAir); }; -export const getPlayerEyeCoords = (forceSneak = false) => { +const getPlayerEyeCoords = (forceSneak = false) => { const player = Player.getPlayer(); if (!player) return null; @@ -37,7 +37,7 @@ export const getPlayerEyeCoords = (forceSneak = false) => { return [x, y, z]; }; -export const getPlayerLookVec = () => { +const getPlayerLookVec = () => { const player = Player.getPlayer(); if (!player) return null; @@ -45,7 +45,7 @@ export const getPlayerLookVec = () => { return new Vector3(lookVec.x(), lookVec.y(), lookVec.z()); }; -export const traverseVoxels = (start, end, blockCheckFunc = null, returnWhenTrue = false, stopWhenNotAir = false, returnIntersection = false) => { +const traverseVoxels = (start, end, blockCheckFunc = null, returnWhenTrue = false, stopWhenNotAir = false, returnIntersection = false) => { const direction = end.map((v, i) => v - start[i]); const step = direction.map((a) => Math.sign(a)); diff --git a/utils/pathfinder/EtherwarpPathfinder.js b/utils/pathfinder/EtherwarpPathfinder.js index 57e03859..ba3a0b2e 100644 --- a/utils/pathfinder/EtherwarpPathfinder.js +++ b/utils/pathfinder/EtherwarpPathfinder.js @@ -1,14 +1,14 @@ -import { Chat } from '../Chat'; +import { sendPathfinderMessage } from '../Chat'; import { MCHand, Vec3d } from '../Constants'; import { ClientboundPingPacket, ServerboundUseItemPacket } from '../Packets'; -import { Guis } from '../player/Inventory'; +import { findItemInHotbar, setItemSlot } from '../player/Inventory'; import { finiteNumber } from '../NumberUtils'; -import { RotationGCD } from '../player/RotationGCD'; -import { ServerInfo } from '../player/ServerInfo'; +import { applyToPlayer } from '../player/RotationGCD'; +import { getPing } from '../player/ServerInfo'; import { ScheduleTask } from '../ScheduleTask'; -import { Utils } from '../Utils'; +import { getCurrentMana } from '../Utils'; import { v5Command } from '../V5Commands'; -import { EtherwarpPathState } from '../Etherwarp'; +import { setEtherwarpPathHandler } from '../Etherwarp'; const SEARCH_OPTIONS = { maxIterations: 100000, @@ -59,7 +59,7 @@ const readAngles = (angleArr) => { class EtherwarpPathHandler { constructor() { this.resetState(); - EtherwarpPathState.handler = this; + setEtherwarpPathHandler(this); v5Command('etherwarp', (x, y, z) => this.test(x, y, z), ['greedyString']); @@ -101,7 +101,7 @@ class EtherwarpPathHandler { const y = Math.floor(Number(yArg)); const z = Math.floor(Number(zArg)); if (![x, y, z].every(Number.isFinite)) { - Chat.messagePathfinder('&cUsage: /v5 etherwarp '); + sendPathfinderMessage('&cUsage: /v5 etherwarp '); return; } const goal = { x, y, z }; @@ -134,12 +134,12 @@ class EtherwarpPathHandler { findPath(goal, options = {}) { goal = this.resolveClosestGoal(goal, Math.max(0, Math.floor(finiteNumber(options.goalRadius)))); if (!goal || ![goal.x, goal.y, goal.z].every(Number.isFinite)) { - Chat.messagePathfinder('&cInvalid etherwarp coordinates.'); + sendPathfinderMessage('&cInvalid etherwarp coordinates.'); return false; } const slot = this.getEtherwarpSlot(); if (slot < 0) { - Chat.messagePathfinder('&cNo Aspect of the Void/End found in your hotbar.'); + sendPathfinderMessage('&cNo Aspect of the Void/End found in your hotbar.'); return false; } @@ -216,7 +216,7 @@ class EtherwarpPathHandler { } getPingDelayTicks() { - const pingMs = ServerInfo.getPing() || 0; + const pingMs = getPing() || 0; return Math.ceil(pingMs / 50) + 2; } @@ -332,7 +332,7 @@ class EtherwarpPathHandler { this.stateVersion++; Client.stopMovement(); Client.setKey('shift', true); - Guis.setItemSlot(slot); + setItemSlot(slot); } pollSearch() { @@ -422,7 +422,7 @@ class EtherwarpPathHandler { return; } - const mana = Utils.getCurrentMana(); + const mana = getCurrentMana(); if (mana !== null && mana < MINIMUM_MANA) { this.finishFailure('Not enough mana to continue etherwarping.', !this.currentRun || this.currentRun.restoreSlot !== false); return; @@ -435,7 +435,7 @@ class EtherwarpPathHandler { } if (!this.ensureEtherwarpHeld(token, () => this.executeHop(token, index))) return; - RotationGCD.applyToPlayer(angles.yaw, angles.pitch); + applyToPlayer(angles.yaw, angles.pitch); this.sendEtherwarpClick(); if (index >= this.path.length - 1) { this.startAwaitingFinalArrival(token); @@ -529,14 +529,14 @@ class EtherwarpPathHandler { Client.setKey('shift', false); Client.stopMovement(); - if (slotToRestore !== -1) Guis.setItemSlot(slotToRestore); + if (slotToRestore !== -1) setItemSlot(slotToRestore); }); } getEtherwarpSlot() { - const aotv = Guis.findItemInHotbar('Aspect of the Void'); + const aotv = findItemInHotbar('Aspect of the Void'); if (aotv !== -1) return aotv; - return Guis.findItemInHotbar('Aspect of the End'); + return findItemInHotbar('Aspect of the End'); } ensureEtherwarpHeld(token, resumeTask) { @@ -549,7 +549,7 @@ class EtherwarpPathHandler { if (Player.getHeldItemIndex() === slot) return true; - Guis.setItemSlot(slot); + setItemSlot(slot); ScheduleTask(1, continuation); return false; } @@ -616,7 +616,7 @@ class EtherwarpPathHandler { this.finalNode = null; this.stopExecution(restoreSlot); if (!silent) { - Chat.messagePathfinder('&c' + failureReason); + sendPathfinderMessage('&c' + failureReason); } if (typeof onFail !== 'function') return; @@ -626,7 +626,7 @@ class EtherwarpPathHandler { messagePathfinder(message) { const run = this.currentRun; if (run && run.silent === true) return; - Chat.messagePathfinder(message); + sendPathfinderMessage(message); } } diff --git a/utils/pathfinder/PathConfig.js b/utils/pathfinder/PathConfig.js index 3fea4f80..e021de14 100644 --- a/utils/pathfinder/PathConfig.js +++ b/utils/pathfinder/PathConfig.js @@ -90,7 +90,7 @@ class PathFindingConfig extends ModuleBase { z: Number(warp.z), })); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); return []; } } diff --git a/utils/pathfinder/PathExecutor.js b/utils/pathfinder/PathExecutor.js index b9b13031..4014a355 100644 --- a/utils/pathfinder/PathExecutor.js +++ b/utils/pathfinder/PathExecutor.js @@ -1,48 +1,35 @@ -class Executor { - constructor() { - this.tickCallbacks = []; - this.stepCallbacks = []; - - this.tickRegister = null; - this.stepRegister = null; - } - - execute() { - this.destroy(); - - this.tickRegister = register('tick', () => this.runCallbacks(this.tickCallbacks, 'tick')); - this.stepRegister = register('step', () => this.runCallbacks(this.stepCallbacks, 'step')).setFps(120); - } - - runCallbacks(callbacks, name) { - for (const callback of callbacks) { - if (typeof callback !== 'function') continue; - try { - callback(); - } catch (e) { - console.error(`PathExecutor ${name} callback error:`, e); - } +const tickCallbacks = []; +const stepCallbacks = []; +let tickRegister = null; +let stepRegister = null; + +const runCallbacks = (callbacks, name) => { + for (const callback of callbacks) { + try { + callback(); + } catch (error) { + console.error(`PathExecutor ${name} callback error:`, error); } } +}; - destroy() { - if (this.tickRegister) this.tickRegister.unregister(); - if (this.stepRegister) this.stepRegister.unregister(); - this.tickRegister = null; - this.stepRegister = null; - } +export function startPathExecutor() { + destroyPathExecutor(); + tickRegister = register('tick', () => runCallbacks(tickCallbacks, 'tick')); + stepRegister = register('step', () => runCallbacks(stepCallbacks, 'step')).setFps(120); +} - onTick(callback) { - if (typeof callback === 'function') { - this.tickCallbacks.push(callback); - } - } +export function destroyPathExecutor() { + tickRegister?.unregister(); + stepRegister?.unregister(); + tickRegister = null; + stepRegister = null; +} - onStep(callback) { - if (typeof callback === 'function') { - this.stepCallbacks.push(callback); - } - } +export function onPathTick(callback) { + if (typeof callback === 'function') tickCallbacks.push(callback); } -export const PathExecutor = new Executor(); +export function onPathStep(callback) { + if (typeof callback === 'function') stepCallbacks.push(callback); +} diff --git a/utils/pathfinder/PathFinder.js b/utils/pathfinder/PathFinder.js index 6998e5de..8d37db75 100644 --- a/utils/pathfinder/PathFinder.js +++ b/utils/pathfinder/PathFinder.js @@ -1,17 +1,17 @@ import { showNotification } from '../../gui/NotificationManager'; -import { Chat } from '../Chat'; +import { sendPathfinderMessage } from '../Chat'; import { BP, Vec3d } from '../Constants'; import { ScheduleTask } from '../ScheduleTask'; -import { MathUtils } from '../Math'; -import { Utils } from '../Utils'; +import { getDistanceToPlayer } from '../Math'; +import { area } from '../Utils'; import { v5Command } from '../V5Commands'; import PathConfig from './PathConfig'; -import { PathExecutor } from './PathExecutor'; +import { destroyPathExecutor, startPathExecutor } from './PathExecutor'; import { PathFlyer } from './PathFlyer'; -import { Spline } from './PathSpline'; +import { clearSplineCache, drawFloatingSpline, drawLookPoints, generateSpline } from './PathSpline'; import { Jump } from './PathWalker/PathJumps'; import { Aote } from './PathWalker/PathAote'; -import { Movement } from './PathWalker/PathMovement'; +import { backup, beginMovement, forceJump, stopMovement } from './PathWalker/PathMovement'; import { NonChangeRecovery, Recovery } from './PathWalker/PathRecovery'; import { Rotations } from './PathWalker/PathRotations'; import { Swift } from './SwiftIntegration'; @@ -87,7 +87,7 @@ class Finder { parseGoalCoordinates(args, usageText, isFly = false) { if (args.length < 3 || args.length % 3 !== 0) { - Chat.messagePathfinder(usageText); + sendPathfinderMessage(usageText); return null; } @@ -143,7 +143,7 @@ class Finder { if (this.calledFromFile) { const endStr = end.length > 1 ? `Multiple Goals (${end.length})` : `${end[0][0]}, ${end[0][1]}, ${end[0][2]}`; - Chat.messagePathfinder(`Path from &a${start[0]}, ${start[1]}, ${start[2]}&f to &c${endStr}`); + sendPathfinderMessage(`Path from &a${start[0]}, ${start[1]}, ${start[2]}&f to &c${endStr}`); } if (!Swift.SwiftPath(starts, end, isFly, this.pathVariantSeed, PathConfig.PATHFINDER_MAX_COMPUTE)) { @@ -154,7 +154,7 @@ class Finder { this.searchStartedAt = Date.now(); if (this.calledFromFile && PathConfig.PATHFINDING_DEBUG) { - Chat.messagePathfinder('§eSearching for path...'); + sendPathfinderMessage('§eSearching for path...'); } this.startTick(); @@ -163,13 +163,13 @@ class Finder { startTick() { if (this.tick) return; - PathExecutor.execute(); + startPathExecutor(); this.tick = register('tick', () => { if (Swift.isSearching()) { if (this.searchStartedAt > 0 && Date.now() - this.searchStartedAt > this.SEARCH_TIMEOUT_MS) { if (PathConfig.PATHFINDING_DEBUG) { - Chat.messagePathfinder('§6Path search timed out, recalculating'); + sendPathfinderMessage('§6Path search timed out, recalculating'); } Swift.cancel(); Swift.clear(); @@ -197,7 +197,7 @@ class Finder { } const reason = Swift.getLastError(); - Chat.messagePathfinder('§cNo path found' + (reason ? ': ' + reason : '')); + sendPathfinderMessage('§cNo path found' + (reason ? ': ' + reason : '')); this.callCallback(false); this.resetPath(); @@ -207,10 +207,10 @@ class Finder { if (!this.saidInfo && this.calledFromFile && PathConfig.PATHFINDING_DEBUG) { const nodeCount = Array.isArray(result.path) ? result.path.length : result.keynodes.length; - Chat.messagePathfinder(`Path found: ${nodeCount} nodes in ${result.time_ms}ms`); + sendPathfinderMessage(`Path found: ${nodeCount} nodes in ${result.time_ms}ms`); const nsPerNode = Number(result.nanoseconds_per_node); if (Number.isFinite(nsPerNode) && nsPerNode > 0) { - Chat.messagePathfinder(`Nanoseconds per node: ${Math.round(nsPerNode)}ns`); + sendPathfinderMessage(`Nanoseconds per node: ${Math.round(nsPerNode)}ns`); } this.saidInfo = true; } @@ -241,11 +241,11 @@ class Finder { this.applyPathRuntimeHints(result); Aote.onPathTick(Rotations); Jump.detectJump(result.path_between_key_nodes, result.path_flags, result.path_flag_bits); - Movement.beginMovement(); + beginMovement(); if (this.recalculateAttempts > 0 && Recovery.hasMadeProgress()) { if (PathConfig.PATHFINDING_DEBUG) { - Chat.messagePathfinder('§aUnstuck!'); + sendPathfinderMessage('§aUnstuck!'); } this.recalculateAttempts = 0; Recovery.stop(); @@ -316,7 +316,7 @@ class Finder { } if (PathConfig.RENDER_FLOATING_SPLINE) { - Spline.drawFloatingSpline(this.flySplinePath); + drawFloatingSpline(this.flySplinePath); } if (PathConfig.RENDER_LOOK_POINTS) { @@ -332,15 +332,15 @@ class Finder { switch (action) { case 'JUMP': - Movement.forceJump(4); + forceJump(4); break; case 'CLOSE_LOOK': Rotations.setTemporaryLookahead(Rotations.RECOVERY_MIN_LOOKAHEAD, 40); - //Movement.forceJump(4); + //forceJump(4); break; case 'BACKUP_RECALC': this.addTransientAvoidAtPlayer(2, 42, 2); - Movement.backup(15, () => this.recalculate('backup_recalc')); + backup(15, () => this.recalculate('backup_recalc')); break; } } @@ -359,7 +359,7 @@ class Finder { if (this.recalculateAttempts > this.MAX_RECALCULATE_ATTEMPTS) { if (PathConfig.PATHFINDING_DEBUG) { - Chat.messagePathfinder('§cMax recalculation attempts, failed!'); + sendPathfinderMessage('§cMax recalculation attempts, failed!'); } this.callCallback(false); this.resetPath(); @@ -367,7 +367,7 @@ class Finder { } if (PathConfig.PATHFINDING_DEBUG) { - Chat.messagePathfinder(`§eRecalculating (${this.recalculateAttempts}/${this.MAX_RECALCULATE_ATTEMPTS})`); + sendPathfinderMessage(`§eRecalculating (${this.recalculateAttempts}/${this.MAX_RECALCULATE_ATTEMPTS})`); } this.schedulePathRetry(3); @@ -655,7 +655,7 @@ class Finder { return { points, metadata }; } - PathConfig.getAreaWarpPoints(Utils.area()).forEach((warpPoint) => { + PathConfig.getAreaWarpPoints(area()).forEach((warpPoint) => { const point = [warpPoint.x, warpPoint.y, warpPoint.z]; points.push(point); metadata.push({ @@ -760,7 +760,7 @@ class Finder { failWarpPathfinding() { const warpName = this.selectedStartCandidate?.warp || 'unknown'; - Chat.messagePathfinder(`§cFailed to warp to ${warpName} after ${this.MAX_WARP_RETRIES} retries.`); + sendPathfinderMessage(`§cFailed to warp to ${warpName} after ${this.MAX_WARP_RETRIES} retries.`); showNotification('Pathfinding Failed', `Warp ${warpName} failed after ${this.MAX_WARP_RETRIES} retries.`, 'ERROR', 5000); this.callCallback(false); this.resetPath(); @@ -769,7 +769,7 @@ class Finder { isPlayerAtWarpPoint(point) { if (this.hasReachedWarpPoint) return true; - const dist = MathUtils.getDistanceToPlayer(point[0], point[1], point[2]); + const dist = getDistanceToPlayer(point[0], point[1], point[2]); if (dist.distance <= 9) { this.hasReachedWarpPoint = true; return true; @@ -813,7 +813,7 @@ class Finder { createSplinePath(path) { if (!path) return null; const nodes = path.path_between_key_nodes?.length ? path.path_between_key_nodes : path.keynodes; - return nodes?.length ? Spline.generateSpline(nodes, 1) : null; + return nodes?.length ? generateSpline(nodes, 1) : null; } getCachedWalkSplinePath(result) { @@ -843,8 +843,8 @@ class Finder { RenderUtils.drawStyledBox(new Vec3d(node.x, node.y, node.z), new RenderColor(0, 100, 200, 120), new RenderColor(0, 100, 200, 255), 4, true); }); } - if (PathConfig.RENDER_FLOATING_SPLINE) Spline.drawFloatingSpline(splinePath); - if (PathConfig.RENDER_LOOK_POINTS) Spline.drawLookPoints(); + if (PathConfig.RENDER_FLOATING_SPLINE) drawFloatingSpline(splinePath); + if (PathConfig.RENDER_LOOK_POINTS) drawLookPoints(); }); } @@ -865,13 +865,13 @@ class Finder { resetPath(clearFlags = true) { this.destroyTick(); this.destroyRender(); - PathExecutor.destroy(); + destroyPathExecutor(); Rotations.resetRotations(); PathFlyer.reset(); - Spline.clearCache(); + clearSplineCache(); Jump.reset(); Aote.stop(clearFlags); - Movement.stopMovement(); + stopMovement(); if (clearFlags) { Recovery.stop(); NonChangeRecovery.stop(); diff --git a/utils/pathfinder/PathFlyer.js b/utils/pathfinder/PathFlyer.js index e77efc0e..d1a62bd4 100644 --- a/utils/pathfinder/PathFlyer.js +++ b/utils/pathfinder/PathFlyer.js @@ -1,5 +1,5 @@ -import { MathUtils } from '../Math'; -import { PathExecutor } from './PathExecutor'; +import { calculateAbsoluteAngles, getAngleDifference, wrapTo180 } from '../Math'; +import { onPathStep, onPathTick } from './PathExecutor'; import { PathRotationsUtility } from './PathWalker/PathRotationsUtility'; class SimulationPathFlyer { @@ -29,8 +29,8 @@ class SimulationPathFlyer { ]; this.reset(); - PathExecutor.onTick(() => this.tick()); - PathExecutor.onStep(() => this.updateRotation()); + onPathTick(() => this.tick()); + onPathStep(() => this.updateRotation()); } begin(nodes) { @@ -71,7 +71,7 @@ class SimulationPathFlyer { this.complete = false; this.isActive = true; this.rotationActive = true; - this.currentYaw = MathUtils.wrapTo180(Player.getYaw()); + this.currentYaw = wrapTo180(Player.getYaw()); this.currentPitch = Player.getPitch(); this.targetYaw = this.currentYaw; this.targetPitch = this.currentPitch; @@ -168,7 +168,7 @@ class SimulationPathFlyer { this.turnAngle = this.angleBetween({ x: near.x - projection.point.x, z: near.z - projection.point.z }, { x: far.x - near.x, z: far.z - near.z }); this.currentPathCurvature = (this.turnAngle * Math.PI) / 180; - const angles = MathUtils.calculateAbsoluteAngles({ x: lookTarget.x, y: lookTarget.y + this.EYE_HEIGHT - 1, z: lookTarget.z }); + const angles = calculateAbsoluteAngles({ x: lookTarget.x, y: lookTarget.y + this.EYE_HEIGHT - 1, z: lookTarget.z }); this.targetYaw = angles.yaw; this.targetPitch = angles.pitch; } @@ -416,9 +416,9 @@ class SimulationPathFlyer { const smoothing = 1 - Math.exp(-10 * deltaSeconds); const yawLimit = 180 * deltaSeconds; const pitchLimit = 100 * deltaSeconds; - const yawStep = Math.max(-yawLimit, Math.min(yawLimit, MathUtils.getAngleDifference(this.currentYaw, this.targetYaw) * smoothing)); + const yawStep = Math.max(-yawLimit, Math.min(yawLimit, getAngleDifference(this.currentYaw, this.targetYaw) * smoothing)); const pitchStep = Math.max(-pitchLimit, Math.min(pitchLimit, (this.targetPitch - this.currentPitch) * smoothing)); - this.currentYaw = MathUtils.wrapTo180(this.currentYaw + yawStep); + this.currentYaw = wrapTo180(this.currentYaw + yawStep); this.currentPitch = Math.max(-90, Math.min(90, this.currentPitch + pitchStep)); const applied = PathRotationsUtility.applyRotationWithGCD(this.currentYaw, this.currentPitch); if (applied) { diff --git a/utils/pathfinder/PathSpline.js b/utils/pathfinder/PathSpline.js index dafbbe55..0f871011 100644 --- a/utils/pathfinder/PathSpline.js +++ b/utils/pathfinder/PathSpline.js @@ -1,221 +1,159 @@ import { BP, Vec3d } from '../Constants'; -class PathSpline { - constructor() { - this.STRONG_SMOOTH_RADIUS = 5; - this.CURVE_DETECTION_RADIUS = 2; - this.SMOOTH_SAMPLES = 6; - this.MIN_LOOK_POINT_SPACING = 0.8; - this.MAX_ANGLE_CHANGE = Math.PI / 4; - this.MAX_GAP_DISTANCE = 12; - this.OUTWARD_OFFSET_STRENGTH = 1.2; - - this.lastDataHash = null; - this.cachedBoxPositions = []; +const MIN_LOOK_POINT_SPACING_SQ = 0.8 ** 2; +const MAX_GAP_DISTANCE = 12; +const OUTWARD_OFFSET_STRENGTH = 1.2; + +let lastDataHash = null; +let cachedLookPoints = []; + +const buildPathHash = (points, prefix = 'path', sampleCount = 6) => { + if (!points?.length) return `${prefix}-empty`; + const first = points[0]; + const last = points[points.length - 1]; + const components = [prefix, points.length, first.x, first.y, first.z, last.x, last.y, last.z]; + const samples = Math.min(sampleCount, points.length - 2); + for (let i = 1; i <= samples; i++) { + const index = Math.floor((i * (points.length - 1)) / (samples + 1)); + const point = points[index]; + components.push(index, point.x, point.y, point.z); } - - buildPathHash(points, prefix = 'path', sampleCount = 6) { - if (!points || points.length === 0) return `${prefix}-empty`; - - const first = points[0]; - const last = points[points.length - 1]; - const components = [prefix, points.length, first.x, first.y, first.z, last.x, last.y, last.z]; - - if (points.length > 2) { - const maxSampleCount = Math.min(sampleCount, points.length - 2); - for (let i = 1; i <= maxSampleCount; i++) { - const idx = Math.floor((i * (points.length - 1)) / (maxSampleCount + 1)); - const p = points[idx]; - components.push(idx, p.x, p.y, p.z); - } - } - - return components.join('|'); + return components.join('|'); +}; + +export function generateSpline(nodes, tolerance = 10) { + if (!nodes || nodes.length < 2) return []; + const raw = nodes.map((node) => ({ x: node.x ?? node[0], y: node.y ?? node[1], z: node.z ?? node[2] })); + const simplified = [raw[0]]; + for (let i = 1; i < raw.length - 1; i++) { + const previous = simplified[simplified.length - 1]; + const point = raw[i]; + if (Math.hypot(point.x - previous.x, point.y - previous.y, point.z - previous.z) > tolerance) simplified.push(point); } - - generateSpline(keyPathNodes, tolerance = 10) { - if (!keyPathNodes || keyPathNodes.length < 2) return []; - - const rawPoints = keyPathNodes.map((n) => { - const x = n.x !== undefined ? n.x : n[0]; - const y = n.y !== undefined ? n.y : n[1]; - const z = n.z !== undefined ? n.z : n[2]; - return { x, y, z }; - }); - - const simplifiedPoints = [rawPoints[0]]; - for (let i = 1; i < rawPoints.length - 1; i++) { - const p0 = simplifiedPoints[simplifiedPoints.length - 1]; - const p1 = rawPoints[i]; - const dist = Math.hypot(p1.x - p0.x, p1.y - p0.y, p1.z - p0.z); - if (dist > tolerance) simplifiedPoints.push(p1); - } - simplifiedPoints.push(rawPoints[rawPoints.length - 1]); - - if (simplifiedPoints.length < 2) return rawPoints; - - const finalPath = []; - const interpolationStep = 0.4; - - for (let i = 0; i < simplifiedPoints.length - 1; i++) { - const p1 = simplifiedPoints[i]; - const p2 = simplifiedPoints[i + 1]; - const dx = p2.x - p1.x; - const dy = p2.y - p1.y; - const dz = p2.z - p1.z; - const distance = Math.hypot(dx, dy, dz); - const numSteps = Math.ceil(distance / interpolationStep); - - for (let j = 0; j < numSteps; j++) { - finalPath.push({ x: p1.x + (dx * j) / numSteps, y: p1.y + (dy * j) / numSteps, z: p1.z + (dz * j) / numSteps }); - } + simplified.push(raw[raw.length - 1]); + + const path = []; + for (let i = 0; i < simplified.length - 1; i++) { + const start = simplified[i]; + const end = simplified[i + 1]; + const dx = end.x - start.x; + const dy = end.y - start.y; + const dz = end.z - start.z; + const steps = Math.ceil(Math.hypot(dx, dy, dz) / 0.4); + for (let step = 0; step < steps; step++) { + path.push({ x: start.x + (dx * step) / steps, y: start.y + (dy * step) / steps, z: start.z + (dz * step) / steps }); } - finalPath.push(simplifiedPoints[simplifiedPoints.length - 1]); - return finalPath; } + path.push(simplified[simplified.length - 1]); + return path; +} - createLookPoints(smoothSplineData, minInterval = 1.2, maxInterval = 8) { - if (!smoothSplineData || smoothSplineData.length < 2) return []; - - const currentHash = this.buildPathHash(smoothSplineData, 'look'); - if (currentHash === this.lastDataHash) return this.cachedBoxPositions; - this.lastDataHash = currentHash; - - const start = smoothSplineData[0]; - const endPoint = smoothSplineData[smoothSplineData.length - 1]; - - const boxPositions = []; - let lastPlacedRaw = smoothSplineData[0]; - let lastForwardDir = null; - - boxPositions.push({ x: start.x, y: start.y + 2.62, z: start.z }); - - for (let i = 1; i < smoothSplineData.length - 1; i++) { - const curr = smoothSplineData[i]; - const dist = Math.hypot(curr.x - lastPlacedRaw.x, curr.y - lastPlacedRaw.y, curr.z - lastPlacedRaw.z); - - const lookWindow = 4; - const prev = smoothSplineData[Math.max(0, i - lookWindow)]; - const next = smoothSplineData[Math.min(smoothSplineData.length - 1, i + lookWindow)]; - - const v1 = { x: curr.x - prev.x, z: curr.z - prev.z }; - const v2 = { x: next.x - curr.x, z: next.z - curr.z }; - const m1 = Math.hypot(v1.x, v1.z); - const m2 = Math.hypot(v2.x, v2.z); - - let curvature = 0; - let offsetX = 0; - let offsetZ = 0; - - if (m1 > 0.05 && m2 > 0.05) { - const dot = (v1.x * v2.x + v1.z * v2.z) / (m1 * m2); - const angle = Math.acos(Math.max(-1, Math.min(1, dot))); - curvature = Math.min(angle / (Math.PI / 2.5), 1); - - const cross = v1.x * v2.z - v1.z * v2.x; - const dir = cross > 0 ? 1 : -1; - const forward = { x: v1.x / m1 + v2.x / m2, z: v1.z / m1 + v2.z / m2 }; - const fMag = Math.hypot(forward.x, forward.z); - - if (fMag > 0.01) { - offsetX = -(forward.z / fMag) * dir * curvature * this.OUTWARD_OFFSET_STRENGTH; - offsetZ = (forward.x / fMag) * dir * curvature * this.OUTWARD_OFFSET_STRENGTH; - } - } - - const dynamicInterval = maxInterval - curvature * (maxInterval - minInterval); - - if (dist >= dynamicInterval) { - const currentForward = { x: curr.x - lastPlacedRaw.x, z: curr.z - lastPlacedRaw.z }; - const cfMag = Math.hypot(currentForward.x, currentForward.z); - - if (lastForwardDir && cfMag > 0.1 && dist < this.MAX_GAP_DISTANCE) { - const dot = (currentForward.x * lastForwardDir.x + currentForward.z * lastForwardDir.z) / cfMag; - if (dot < 0.4) continue; - } - - const targetPoint = { x: curr.x + offsetX, y: curr.y + 2.62, z: curr.z + offsetZ }; - this.appendLookPoint(boxPositions, this.adjustLookPoint(targetPoint, curr)); - lastPlacedRaw = curr; - if (cfMag > 0.1) lastForwardDir = { x: currentForward.x / cfMag, z: currentForward.z / cfMag }; +const isPointInsideBlock = (point) => { + try { + const world = World.getWorld(); + if (!world) return false; + const position = new BP(Math.floor(point.x), Math.floor(point.y), Math.floor(point.z)); + const state = world.getBlockState(position); + return !!state && !state.getCollisionShape(world, position).isEmpty(); + } catch (_error) { + return false; + } +}; + +const adjustLookPoint = (point, node) => { + if (!isPointInsideBlock(point)) return point; + const unoffset = { x: node.x, y: point.y, z: node.z }; + if (!isPointInsideBlock(unoffset)) return unoffset; + const lowered = { x: node.x, y: point.y - 0.5, z: node.z }; + return isPointInsideBlock(lowered) ? unoffset : lowered; +}; + +const appendLookPoint = (points, point) => { + const last = points[points.length - 1]; + if (!last) return points.push(point); + if ((point.x - last.x) ** 2 + (point.z - last.z) ** 2 < MIN_LOOK_POINT_SPACING_SQ) points[points.length - 1] = point; + else points.push(point); +}; + +export function createLookPoints(path, minInterval = 1.2, maxInterval = 8) { + if (!path || path.length < 2) return []; + const hash = buildPathHash(path, 'look'); + if (hash === lastDataHash) return cachedLookPoints; + lastDataHash = hash; + + const points = [{ x: path[0].x, y: path[0].y + 2.62, z: path[0].z }]; + let lastPlaced = path[0]; + let lastDirection = null; + + for (let i = 1; i < path.length - 1; i++) { + const current = path[i]; + const distance = Math.hypot(current.x - lastPlaced.x, current.y - lastPlaced.y, current.z - lastPlaced.z); + const previous = path[Math.max(0, i - 4)]; + const next = path[Math.min(path.length - 1, i + 4)]; + const before = { x: current.x - previous.x, z: current.z - previous.z }; + const after = { x: next.x - current.x, z: next.z - current.z }; + const beforeLength = Math.hypot(before.x, before.z); + const afterLength = Math.hypot(after.x, after.z); + let curvature = 0; + let offsetX = 0; + let offsetZ = 0; + + if (beforeLength > 0.05 && afterLength > 0.05) { + const dot = (before.x * after.x + before.z * after.z) / (beforeLength * afterLength); + curvature = Math.min(Math.acos(Math.max(-1, Math.min(1, dot))) / (Math.PI / 2.5), 1); + const direction = before.x * after.z - before.z * after.x > 0 ? 1 : -1; + const forward = { x: before.x / beforeLength + after.x / afterLength, z: before.z / beforeLength + after.z / afterLength }; + const forwardLength = Math.hypot(forward.x, forward.z); + if (forwardLength > 0.01) { + offsetX = -(forward.z / forwardLength) * direction * curvature * OUTWARD_OFFSET_STRENGTH; + offsetZ = (forward.x / forwardLength) * direction * curvature * OUTWARD_OFFSET_STRENGTH; } } - this.appendLookPoint(boxPositions, { x: endPoint.x, y: endPoint.y + 2.62, z: endPoint.z }); - this.cachedBoxPositions = boxPositions; - return boxPositions; - } - - isPointInsideBlock(point) { - try { - const world = World.getWorld(); - if (!world) return false; - const pos = new BP(Math.floor(point.x), Math.floor(point.y), Math.floor(point.z)); - const state = world.getBlockState(pos); - if (!state) return false; - return !state.getCollisionShape(world, pos).isEmpty(); - } catch (e) { - return false; + if (distance < maxInterval - curvature * (maxInterval - minInterval)) continue; + const forward = { x: current.x - lastPlaced.x, z: current.z - lastPlaced.z }; + const forwardLength = Math.hypot(forward.x, forward.z); + if (lastDirection && forwardLength > 0.1 && distance < MAX_GAP_DISTANCE) { + const dot = (forward.x * lastDirection.x + forward.z * lastDirection.z) / forwardLength; + if (dot < 0.4) continue; } - } - adjustLookPoint(point, rawNode) { - if (!this.isPointInsideBlock(point)) return point; - const unoffset = { x: rawNode.x, y: point.y, z: rawNode.z }; - if (!this.isPointInsideBlock(unoffset)) return unoffset; - const lowered = { x: rawNode.x, y: point.y - 0.5, z: rawNode.z }; - return this.isPointInsideBlock(lowered) ? unoffset : lowered; + appendLookPoint(points, adjustLookPoint({ x: current.x + offsetX, y: current.y + 2.62, z: current.z + offsetZ }, current)); + lastPlaced = current; + if (forwardLength > 0.1) lastDirection = { x: forward.x / forwardLength, z: forward.z / forwardLength }; } - appendLookPoint(boxPositions, point) { - if (boxPositions.length === 0) { - boxPositions.push(point); - return; - } - const last = boxPositions[boxPositions.length - 1]; - if (Math.pow(point.x - last.x, 2) + Math.pow(point.z - last.z, 2) < Math.pow(this.MIN_LOOK_POINT_SPACING, 2)) { - boxPositions[boxPositions.length - 1] = point; - } else { - boxPositions.push(point); - } - } - - drawLookPoints() { - if (!this.cachedBoxPositions?.length) return; - - const player = Player.getPlayer(); - if (!player) return; - - const px = Player.getX(); - const pz = Player.getZ(); - - const size = 0.4; - - this.cachedBoxPositions.forEach((pos) => { - if (Math.abs(pos.x - px) < 64 && Math.abs(pos.z - pz) < 64) { - const renderPos = new Vec3d(pos.x, pos.y + 0.2, pos.z); - RenderUtils.drawSizedBox(renderPos, size, size, size, new RenderColor(255, 0, 255, 180), true, 1, true); - } - }); - } + const end = path[path.length - 1]; + appendLookPoint(points, { x: end.x, y: end.y + 2.62, z: end.z }); + cachedLookPoints = points; + return points; +} - drawFloatingSpline(smoothSplineData) { - if (!smoothSplineData || smoothSplineData.length < 2) return; - for (let i = 0; i < smoothSplineData.length - 1; i++) { - RenderUtils.drawLine( - new Vec3d(smoothSplineData[i].x + 0.5, smoothSplineData[i].y + 2.62, smoothSplineData[i].z + 0.5), - new Vec3d(smoothSplineData[i + 1].x + 0.5, smoothSplineData[i + 1].y + 2.62, smoothSplineData[i + 1].z + 0.5), - new RenderColor(0, 255, 255, 255), - 3, - true - ); +export function drawLookPoints() { + if (!cachedLookPoints.length || !Player.getPlayer()) return; + const playerX = Player.getX(); + const playerZ = Player.getZ(); + for (const point of cachedLookPoints) { + if (Math.abs(point.x - playerX) < 64 && Math.abs(point.z - playerZ) < 64) { + RenderUtils.drawSizedBox(new Vec3d(point.x, point.y + 0.2, point.z), 0.4, 0.4, 0.4, new RenderColor(255, 0, 255, 180), true, 1, true); } } +} - clearCache() { - this.cachedBoxPositions = []; - this.lastDataHash = null; +export function drawFloatingSpline(path) { + if (!path || path.length < 2) return; + for (let i = 0; i < path.length - 1; i++) { + RenderUtils.drawLine( + new Vec3d(path[i].x + 0.5, path[i].y + 2.62, path[i].z + 0.5), + new Vec3d(path[i + 1].x + 0.5, path[i + 1].y + 2.62, path[i + 1].z + 0.5), + new RenderColor(0, 255, 255, 255), + 3, + true + ); } } -export const Spline = new PathSpline(); +export function clearSplineCache() { + cachedLookPoints = []; + lastDataHash = null; +} diff --git a/utils/pathfinder/PathWalker/PathAote.js b/utils/pathfinder/PathWalker/PathAote.js index d51b3474..1f30ef50 100644 --- a/utils/pathfinder/PathWalker/PathAote.js +++ b/utils/pathfinder/PathWalker/PathAote.js @@ -1,11 +1,11 @@ -import { Chat } from '../../Chat'; +import { sendPathfinderMessage } from '../../Chat'; import { BP, SnowBlock } from '../../Constants'; -import { MathUtils } from '../../Math'; -import { Utils } from '../../Utils'; -import { Guis } from '../../player/Inventory'; +import { wrapTo180 } from '../../Math'; +import { getCurrentMana } from '../../Utils'; +import { findItemInHotbar, setItemSlot } from '../../player/Inventory'; import PathConfig from '../PathConfig'; import { Jump } from './PathJumps'; -import { Movement } from './PathMovement'; +import { isRecovering } from './PathMovement'; class PathAote { constructor() { @@ -56,7 +56,7 @@ class PathAote { const now = Date.now(); if (PathConfig.PATHFINDING_DEBUG && now - this.lastMissingItemAt > 1500) { this.lastMissingItemAt = now; - Chat.messagePathfinder('§7AOTE: item missing'); + sendPathfinderMessage('§7AOTE: item missing'); } return; } @@ -71,7 +71,7 @@ class PathAote { minGain -= this.MIN_GAIN_RELAX_IN_FLUID_DISTANCE; } - if (Movement.isRecovering()) { + if (isRecovering()) { return this.debug('recovery'); } @@ -105,15 +105,15 @@ class PathAote { this.lastUsedPathPosition = rotations.currentPathPosition; if (PathConfig.PATHFINDING_DEBUG) { - Chat.messagePathfinder(`§bAOTE: used at pathPos ${rotations.currentPathPosition.toFixed(1)}`); + sendPathfinderMessage(`§bAOTE: used at pathPos ${rotations.currentPathPosition.toFixed(1)}`); } } findAoteSlot() { - const aotv = Guis.findItemInHotbar('Aspect of the Void'); + const aotv = findItemInHotbar('Aspect of the Void'); if (aotv !== -1) return aotv; - const aote = Guis.findItemInHotbar('Aspect of the End'); + const aote = findItemInHotbar('Aspect of the End'); return aote !== -1 ? aote : null; } @@ -135,11 +135,11 @@ class PathAote { if (!this.hasSwappedToAote) { this.hasSwappedToAote = true; this.activeAoteSlot = slot; - if (PathConfig.PATHFINDING_DEBUG) Chat.messagePathfinder(`§7AOTE: swapped to slot ${slot + 1}`); + if (PathConfig.PATHFINDING_DEBUG) sendPathfinderMessage(`§7AOTE: swapped to slot ${slot + 1}`); } if (Player.getHeldItemIndex() !== slot) { - Guis.setItemSlot(slot); + setItemSlot(slot); this.debug('waiting for slot swap'); return false; } @@ -182,7 +182,7 @@ class PathAote { } hasEnoughMana() { - const mana = Utils.getCurrentMana(); + const mana = getCurrentMana(); if (mana === null) { this.debug('mana unavailable'); //return false; @@ -249,7 +249,7 @@ class PathAote { if (horiz < 0.001) return true; const targetYaw = -(Math.atan2(dx, dz) * (180 / Math.PI)); - const yawError = Math.abs(this.wrapAngle(targetYaw - MathUtils.wrapTo180(player.getYRot()))); + const yawError = Math.abs(this.wrapAngle(targetYaw - wrapTo180(player.getYRot()))); return yawError <= this.MAX_AIM_YAW_ERROR; } @@ -261,7 +261,7 @@ class PathAote { } getLookDirection(player) { - const yawRad = (-MathUtils.wrapTo180(player.getYRot()) * Math.PI) / 180; + const yawRad = (-wrapTo180(player.getYRot()) * Math.PI) / 180; const pitchRad = (-player.getXRot() * Math.PI) / 180; const cosPitch = Math.cos(pitchRad); return { @@ -433,16 +433,16 @@ class PathAote { if (!PathConfig.PATHFINDING_DEBUG) return; if (reason === this.lastSkipReason) return; this.lastSkipReason = reason; - Chat.messagePathfinder(`§7AOTE: skipped (${reason})`); + sendPathfinderMessage(`§7AOTE: skipped (${reason})`); } restoreOriginalSlot() { if (this.originalSlot >= 0 && this.originalSlot <= 8) { if (Player.getHeldItemIndex() !== this.originalSlot) { - Guis.setItemSlot(this.originalSlot); + setItemSlot(this.originalSlot); } if (PathConfig.PATHFINDING_DEBUG) { - Chat.messagePathfinder(`§7AOTE: restored original slot (${this.originalSlot + 1})`); + sendPathfinderMessage(`§7AOTE: restored original slot (${this.originalSlot + 1})`); } } diff --git a/utils/pathfinder/PathWalker/PathJumps.js b/utils/pathfinder/PathWalker/PathJumps.js index 77dfea8e..434ee1bd 100644 --- a/utils/pathfinder/PathWalker/PathJumps.js +++ b/utils/pathfinder/PathWalker/PathJumps.js @@ -1,8 +1,8 @@ -import { Chat } from '../../Chat'; +import { sendPathfinderMessage } from '../../Chat'; import { BP, SnowBlock, Vec3d } from '../../Constants'; import PathConfig from '../PathConfig'; -import { PathExecutor } from '../PathExecutor'; -import { Movement } from './PathMovement'; +import { onPathTick } from '../PathExecutor'; +import { isRecovering } from './PathMovement'; class PathJumps { constructor() { @@ -26,7 +26,7 @@ class PathJumps { this.FLAG_DROP_NEXT = 1 << 6; this.FLAG_TIGHT_CORRIDOR = 1 << 7; - PathExecutor.onTick(() => { + onPathTick(() => { this.cacheFrame++; if (this.blockCache.size > 1000) this.blockCache.clear(); if (this.jumpSuppressTicks > 0) { @@ -180,7 +180,7 @@ class PathJumps { if (!this.isPlayerInFluid()) return false; Client.setKey('space', true); if (Date.now() - this.lastFluidMessage > 2000) { - if (PathConfig.PATHFINDING_DEBUG) Chat.messagePathfinder('Fluid jump detected'); + if (PathConfig.PATHFINDING_DEBUG) sendPathfinderMessage('Fluid jump detected'); this.lastFluidMessage = Date.now(); } return true; @@ -194,7 +194,7 @@ class PathJumps { if (layers === 0) return false; const diff = data.vec.y() - (8 - layers) * 0.125 - (Player.getY() - 1); if (diff > 0.75 && layers > 6) { - if (PathConfig.PATHFINDING_DEBUG) Chat.messagePathfinder('Snow jump detected'); + if (PathConfig.PATHFINDING_DEBUG) sendPathfinderMessage('Snow jump detected'); Client.setKey('space', true); return true; } @@ -224,7 +224,7 @@ class PathJumps { } } if (needsJump && !canWalkInstead) { - if (PathConfig.PATHFINDING_DEBUG) Chat.messagePathfinder('Standard jump detected'); + if (PathConfig.PATHFINDING_DEBUG) sendPathfinderMessage('Standard jump detected'); Client.setKey('space', true); return true; } @@ -254,7 +254,7 @@ class PathJumps { const rise = nextY - Math.floor(Player.getY() - 0.001); if (rise < 1 || rise > 2) return false; - if (PathConfig.PATHFINDING_DEBUG) Chat.messagePathfinder('Predictive climb jump'); + if (PathConfig.PATHFINDING_DEBUG) sendPathfinderMessage('Predictive climb jump'); Client.setKey('space', true); return true; } @@ -297,7 +297,7 @@ class PathJumps { const distToEdgeSq = Math.pow(pX - (dropStartNode.x + 0.5), 2) + Math.pow(pZ - (dropStartNode.z + 0.5), 2); if (distToEdgeSq <= 1.35 * 1.35) { - if (PathConfig.PATHFINDING_DEBUG) Chat.messagePathfinder('Gap jump detected'); + if (PathConfig.PATHFINDING_DEBUG) sendPathfinderMessage('Gap jump detected'); Client.setKey('space', true); return true; } @@ -344,7 +344,7 @@ class PathJumps { if (!player) return this.reset(); if (!player.onGround()) { - if (!Movement.isRecovering() && !this.isPlayerInFluid()) { + if (!isRecovering() && !this.isPlayerInFluid()) { Client.setKey('space', false); } return; @@ -362,7 +362,7 @@ class PathJumps { if (this.checkSnowJump(lookahead)) return; if (this.checkObstacleJump(lookahead)) return; - if (!Movement.isRecovering()) { + if (!isRecovering()) { Client.setKey('space', false); } this.lastLookaheadPositions = lookahead.map((d) => d.vec.y()); diff --git a/utils/pathfinder/PathWalker/PathMovement.js b/utils/pathfinder/PathWalker/PathMovement.js index cab1bf77..b419b1d4 100644 --- a/utils/pathfinder/PathWalker/PathMovement.js +++ b/utils/pathfinder/PathWalker/PathMovement.js @@ -1,86 +1,56 @@ import { finiteNumber } from '../../NumberUtils'; -import { PathExecutor } from '../PathExecutor'; +import { onPathTick } from '../PathExecutor'; -class PathMovement { - constructor() { - this.forceJumpTicks = 0; - this.backupTicks = 0; - this.backupCallback = null; - this.isActive = false; +let forceJumpTicks = 0; +let backupTicks = 0; +let backupCallback = null; - PathExecutor.onTick(() => { - if (this.forceJumpTicks > 0) { - Client.setKey('space', true); - this.forceJumpTicks--; - if (this.forceJumpTicks === 0) { - Client.setKey('space', false); - } - } - - if (this.backupTicks > 0) { - Client.setKey('w', false); - Client.setKey('s', true); - Client.setKey('sprint', false); - this.backupTicks--; - - if (this.backupTicks === 0) { - Client.setKey('s', false); - - if (this.backupCallback) { - const cb = this.backupCallback; - this.backupCallback = null; - cb(); - } - } - } - }); +onPathTick(() => { + if (forceJumpTicks > 0) { + Client.setKey('space', true); + if (--forceJumpTicks === 0) Client.setKey('space', false); } - beginMovement() { - const player = Player.getPlayer(); - if (!player) return; - - this.isActive = true; - - if (this.backupTicks <= 0) { - if (!player.isSprinting()) Client.setKey('sprint', true); - Client.setKey('w', true); + if (backupTicks > 0) { + Client.setKey('w', false); + Client.setKey('s', true); + Client.setKey('sprint', false); + if (--backupTicks === 0) { + Client.setKey('s', false); + const callback = backupCallback; + backupCallback = null; + callback?.(); } } - - forceJump(ticks = 4) { - this.forceJumpTicks = Math.max(0, Math.floor(finiteNumber(ticks))); +}); + +export function beginMovement() { + const player = Player.getPlayer(); + if (!player) return; + if (backupTicks <= 0) { + if (!player.isSprinting()) Client.setKey('sprint', true); + Client.setKey('w', true); } +} - backup(ticks, onComplete) { - this.backupTicks = Math.max(0, ticks | 0); - this.backupCallback = onComplete || null; - if (this.backupTicks === 0 && this.backupCallback) { - const cb = this.backupCallback; - this.backupCallback = null; - cb(); - } - } +export const forceJump = (ticks = 4) => (forceJumpTicks = Math.max(0, Math.floor(finiteNumber(ticks)))); - isRecovering() { - return this.forceJumpTicks > 0 || this.backupTicks > 0; +export function backup(ticks, onComplete) { + backupTicks = Math.max(0, ticks | 0); + backupCallback = onComplete || null; + if (backupTicks === 0 && backupCallback) { + const callback = backupCallback; + backupCallback = null; + callback(); } +} - stopMovement() { - this.isActive = false; - this.forceJumpTicks = 0; - this.backupTicks = 0; - this.backupCallback = null; +export const isRecovering = () => forceJumpTicks > 0 || backupTicks > 0; - Client.stopMovement(); - Client.setKey('w', false); - Client.setKey('s', false); - Client.setKey('a', false); - Client.setKey('d', false); - Client.setKey('space', false); - Client.setKey('shift', false); - Client.setKey('sprint', false); - } +export function stopMovement() { + forceJumpTicks = 0; + backupTicks = 0; + backupCallback = null; + Client.stopMovement(); + for (const key of ['w', 's', 'a', 'd', 'space', 'shift', 'sprint']) Client.setKey(key, false); } - -export const Movement = new PathMovement(); diff --git a/utils/pathfinder/PathWalker/PathPrediction.js b/utils/pathfinder/PathWalker/PathPrediction.js index 5294220f..d0fd0094 100644 --- a/utils/pathfinder/PathWalker/PathPrediction.js +++ b/utils/pathfinder/PathWalker/PathPrediction.js @@ -1,6 +1,6 @@ import { finiteNumber } from '../../NumberUtils'; -export function getCurrentMotion() { +function getCurrentMotion() { if (!Player.getPlayer()) { return { x: 0, y: 0, z: 0 }; } diff --git a/utils/pathfinder/PathWalker/PathRecovery.js b/utils/pathfinder/PathWalker/PathRecovery.js index 1e8fd77b..e49b9a18 100644 --- a/utils/pathfinder/PathWalker/PathRecovery.js +++ b/utils/pathfinder/PathWalker/PathRecovery.js @@ -1,4 +1,4 @@ -import { Chat } from '../../Chat'; +import { sendPathfinderMessage } from '../../Chat'; import PathConfig from '../PathConfig'; class PathRecovery { @@ -64,7 +64,7 @@ class PathRecovery { if (this.stuckTicks >= this.STUCK_TICKS_BACKUP_RECALC && this.currentLevel < 3) { if (PathConfig.PATHFINDING_DEBUG) { - Chat.messagePathfinder('§6Recovery 3/3: Backup and Recalculate'); + sendPathfinderMessage('§6Recovery 3/3: Backup and Recalculate'); } this.currentLevel = 3; return 'BACKUP_RECALC'; @@ -72,7 +72,7 @@ class PathRecovery { if (this.stuckTicks >= this.STUCK_TICKS_CLOSE_LOOK && this.currentLevel < 2) { if (PathConfig.PATHFINDING_DEBUG) { - Chat.messagePathfinder('§eRecovery 2/3: Reducing lookahead'); + sendPathfinderMessage('§eRecovery 2/3: Reducing lookahead'); } this.currentLevel = 2; return 'CLOSE_LOOK'; @@ -80,7 +80,7 @@ class PathRecovery { if (this.stuckTicks >= this.STUCK_TICKS_JUMP && this.currentLevel < 1) { if (PathConfig.PATHFINDING_DEBUG) { - Chat.messagePathfinder('§eRecovery 1/3: Jump'); + sendPathfinderMessage('§eRecovery 1/3: Jump'); } this.currentLevel = 1; return 'JUMP'; @@ -163,7 +163,7 @@ class PathNonChangeRecovery { if (this.nonChangeTicks >= this.NON_CHANGE_TICKS_RECALC) { if (PathConfig.PATHFINDING_DEBUG) { - Chat.messagePathfinder('§6Recovery (nonchange): Recalculating'); + sendPathfinderMessage('§6Recovery (nonchange): Recalculating'); } this.resetTracking(); return true; diff --git a/utils/pathfinder/PathWalker/PathRotations.js b/utils/pathfinder/PathWalker/PathRotations.js index 332fc849..4d830110 100644 --- a/utils/pathfinder/PathWalker/PathRotations.js +++ b/utils/pathfinder/PathWalker/PathRotations.js @@ -1,9 +1,9 @@ import { BP, Vec3d } from '../../Constants'; import { raytraceBlocks } from '../../dependencies/BloomCore/RaytraceBlocks'; import { Vector3 } from '../../dependencies/BloomCore/Vector3'; -import { MathUtils } from '../../Math'; -import { PathExecutor } from '../PathExecutor'; -import { Spline } from '../PathSpline'; +import { calculateAbsoluteAngles, getAngleDifference, wrapTo180 } from '../../Math'; +import { onPathTick } from '../PathExecutor'; +import { createLookPoints } from '../PathSpline'; import { predictXZ } from './PathPrediction'; import { PathRotationsUtility } from './PathRotationsUtility'; @@ -53,7 +53,7 @@ class PathRotations { PathRotationsUtility.applyRotationWithGCD(this.currentYaw, this.currentPitch); }); - PathExecutor.onTick(() => { + onPathTick(() => { if (this.postTeleportResyncTicks > 0) { this.postTeleportResyncTicks--; } @@ -399,9 +399,9 @@ class PathRotations { } this.currentTargetPoint = targetPoint; - const angles = MathUtils.calculateAbsoluteAngles(this.currentTargetPoint); - const targetYaw = MathUtils.wrapTo180(angles.yaw); - const yawDelta = MathUtils.getAngleDifference(this.rawTargetYaw, targetYaw); + const angles = calculateAbsoluteAngles(this.currentTargetPoint); + const targetYaw = wrapTo180(angles.yaw); + const yawDelta = getAngleDifference(this.rawTargetYaw, targetYaw); const lastIndex = this.boxPositions.length - 1; const remainingPath = lastIndex - this.currentPathPosition; @@ -412,7 +412,7 @@ class PathRotations { const dynamicYawDeadzone = (isStraight ? this.YAW_DEADZONE * 1.5 : this.YAW_DEADZONE) * finishFactor; if (Math.abs(yawDelta) > dynamicYawDeadzone) { - this.rawTargetYaw = MathUtils.wrapTo180(this.rawTargetYaw + yawDelta * Math.min(1.0, dynamicSmooth)); + this.rawTargetYaw = wrapTo180(this.rawTargetYaw + yawDelta * Math.min(1.0, dynamicSmooth)); } const pitchDelta = angles.pitch - this.rawTargetPitch; @@ -421,7 +421,7 @@ class PathRotations { } if (this.initialTurnBoostTicks > 0) { - if (Math.abs(MathUtils.getAngleDifference(this.currentYaw, this.rawTargetYaw)) <= Math.max(10.0, this.YAW_DEADZONE * 2)) { + if (Math.abs(getAngleDifference(this.currentYaw, this.rawTargetYaw)) <= Math.max(10.0, this.YAW_DEADZONE * 2)) { this.initialTurnBoostTicks = 0; } else { this.initialTurnBoostTicks -= timeScale; @@ -441,8 +441,8 @@ class PathRotations { } applyHumanizedPhysics(timeScale = 1) { - this.currentYaw = MathUtils.wrapTo180(this.currentYaw); - const yawError = MathUtils.getAngleDifference(this.currentYaw, this.rawTargetYaw); + this.currentYaw = wrapTo180(this.currentYaw); + const yawError = getAngleDifference(this.currentYaw, this.rawTargetYaw); const pitchError = this.rawTargetPitch - this.currentPitch; const absYawError = Math.abs(yawError); const isStraight = this.currentPathCurvature < 0.2; @@ -566,7 +566,7 @@ class PathRotations { pathRotations(splineData) { if (!this.boxPositions || this.boxPositions.length < 2) { - const lookPoints = Spline.createLookPoints(splineData, 0.25, 4.5); + const lookPoints = createLookPoints(splineData, 0.25, 4.5); if (!lookPoints || lookPoints.length < 2) { this.boxPositions = null; this.rotationActive = false; @@ -576,7 +576,7 @@ class PathRotations { } const player = Player.getPlayer(); if (player && !this.isInitialized) { - this.currentYaw = MathUtils.wrapTo180(player.getYRot()); + this.currentYaw = wrapTo180(player.getYRot()); this.currentPitch = player.getXRot(); this.rawTargetYaw = this.currentYaw; this.rawTargetPitch = this.currentPitch; diff --git a/utils/pathfinder/PathWalker/PathRotationsUtility.js b/utils/pathfinder/PathWalker/PathRotationsUtility.js index 5edb2aeb..6c9e132d 100644 --- a/utils/pathfinder/PathWalker/PathRotationsUtility.js +++ b/utils/pathfinder/PathWalker/PathRotationsUtility.js @@ -1,7 +1,7 @@ import { Vec3d } from '../../Constants'; -import { MathUtils } from '../../Math'; -import { RotationGCD } from '../../player/RotationGCD'; -import { Utils } from '../../Utils'; +import { calculateAngles, getAngleDifference, wrapTo180 } from '../../Math'; +import { applyToPlayer } from '../../player/RotationGCD'; +import { convertToVector } from '../../Utils'; class PathRotsUtil { constructor() { @@ -40,7 +40,7 @@ class PathRotsUtil { } applyRotationWithGCD(yaw, pitch) { - return RotationGCD.applyToPlayer(yaw, pitch); + return applyToPlayer(yaw, pitch); } wrapDegrees(degrees) { @@ -51,7 +51,7 @@ class PathRotsUtil { } calculateSmoothedYaw(targetYaw, currentSmoothedYaw, maxAdjustment) { - const deltaYaw = MathUtils.getAngleDifference(currentSmoothedYaw, targetYaw); + const deltaYaw = getAngleDifference(currentSmoothedYaw, targetYaw); const adjustment = Math.min(Math.abs(deltaYaw), maxAdjustment) * Math.sign(deltaYaw); return currentSmoothedYaw + adjustment; } @@ -74,7 +74,7 @@ class PathRotsUtil { } calculateRotationSpeed(targetPoint, minSpeed = 60, maxSpeed = 80, scalingFactor = 20) { - const { yaw: relYaw, pitch: relPitch } = MathUtils.calculateAngles(targetPoint); + const { yaw: relYaw, pitch: relPitch } = calculateAngles(targetPoint); const totalAngleDifference = Math.abs(relYaw) + Math.abs(relPitch); const range = maxSpeed - minSpeed; @@ -105,7 +105,7 @@ class PathRotsUtil { return; } - this.initialYaw = MathUtils.wrapTo180(player.getYRot()); + this.initialYaw = wrapTo180(player.getYRot()); this.initialPitch = player.getXRot(); this.yawDiff = this.wrapDegrees(yaw - this.initialYaw); @@ -189,7 +189,7 @@ class PathRotsUtil { } rotateTo(vector, instant = false, durationMs = 500) { - let vec = Utils.convertToVector(vector); + let vec = convertToVector(vector); let player = Player.getPlayer(); if (!player || !vec || !Number.isFinite(vec.x()) || !Number.isFinite(vec.y()) || !Number.isFinite(vec.z())) return; @@ -213,7 +213,7 @@ class PathRotsUtil { action.func(); } catch (e) { console.error(`Rotation ${action.name || 'callback'} error:`); - console.error('V5 Caught error' + e + e.stack); + console.error(e); } }); } @@ -240,7 +240,7 @@ class PathRotsUtil { getPlayerRotation() { const player = Player.getPlayer(); - return player ? { yaw: MathUtils.wrapTo180(player.getYRot()), pitch: player.getXRot() } : null; + return player ? { yaw: wrapTo180(player.getYRot()), pitch: player.getXRot() } : null; } } diff --git a/utils/player/Inventory.js b/utils/player/Inventory.js index bb29479d..bab0ab45 100644 --- a/utils/player/Inventory.js +++ b/utils/player/Inventory.js @@ -1,186 +1,91 @@ -import { Chat } from '../Chat'; +import { chat } from '../Chat'; import { ServerboundContainerClosePacket } from '../Packets'; import { ScheduleTask } from '../ScheduleTask'; -import { Rotations } from './Rotations'; -class ItemSearcher { - stripCodes(text) { - if (!text || typeof text !== 'string') return text; - return text.replace(/\u00A7[0-9A-FK-ORa-fk-or]/g, ''); - } - - matchName(item, targetName, exact) { - if (!item || !item.getName) return false; - const cleanName = this.stripCodes(item.getName()); - if (!cleanName) return false; - - const lowerName = cleanName.toLowerCase(); - const lowerTarget = targetName.toLowerCase(); +export const stripItemFormatting = (text) => (typeof text === 'string' ? ChatLib.removeFormatting(text) : text); - return exact ? lowerName === lowerTarget : lowerName.includes(lowerTarget); - } +const itemNameMatches = (item, target, exact = false) => { + const name = stripItemFormatting(item?.getName?.()); + if (!name) return false; + return exact ? name.toLowerCase() === target.toLowerCase() : name.toLowerCase().includes(target.toLowerCase()); +}; - findInList(inventory, targetName, exact = false) { - if (!inventory) return -1; - for (var i = 0; i < inventory.getSize(); i++) { - const stack = inventory.getStackInSlot(i); - if (this.matchName(stack, targetName, exact)) { - return i; - } - } - return -1; +export function findFirstItem(inventory, name, exact = false) { + if (!inventory) return -1; + for (let slot = 0; slot < inventory.getSize(); slot++) { + if (itemNameMatches(inventory.getStackInSlot(slot), name, exact)) return slot; } + return -1; +} - findAllInList(inventory, targetName) { - const slots = []; - if (!inventory) return slots; - for (var i = 0; i < inventory.getSize(); i++) { - const stack = inventory.getStackInSlot(i); - if (this.matchName(stack, targetName, false)) { - slots.push(i); - } - } - return slots; +export function findItemInHotbar(name) { + const inventory = Player.getInventory(); + if (!inventory) return -1; + for (let slot = 0; slot < Math.min(inventory.getSize(), 9); slot++) { + if (itemNameMatches(inventory.getStackInSlot(slot), name)) return slot; } + return -1; } -class InterfaceHandler { - constructor() { - this.search = new ItemSearcher(); +export function clickSlot(slot, shift = false, button = 'LEFT') { + const container = Player.getContainer(); + if (!container || slot < 0) { + chat('ClickSlot failed due to no container'); + return false; } - - getCurrentTitle() { - const container = Player.getContainer(); - return container ? ChatLib.removeFormatting(container.getName().toString()) : null; + if (slot == null || slot >= (container.getItems()?.length ?? 0)) { + chat('ClickSlot failed due to invalid slot'); + return false; } + container.click(slot, shift, button); + return true; +} - performClick(slot, shift = false, button = 'LEFT') { - const container = Player.getContainer(); - if (!container || slot < 0) { - Chat.message('ClickSlot failed due to no container'); - return false; - } - const items = container.getItems(); - if (!items || slot == null || slot >= items.length) { - Chat.message('ClickSlot failed due to invalid slot'); - return false; - } +export function clickItem(name, shift, button, displayName = true, exact = false) { + const items = Player.getContainer()?.getItems(); + if (!items) return false; - container.click(slot, shift, button); - return true; + for (let slot = 0; slot < items.length; slot++) { + const item = items[slot]; + if (!item) continue; + const itemName = displayName ? ChatLib.removeFormatting(String(item.getName())) : String(item.type?.getRegistryName?.() || ''); + const matches = exact ? itemName.toLowerCase() === name.toLowerCase() : itemName.toLowerCase().includes(name.toLowerCase()); + if (matches) return clickSlot(slot, shift, button); } + return false; +} - terminateGui() { - const player = Player.getPlayer(); - if (!player) return; - - try { - const syncId = Client.getMinecraft().player.containerMenu.containerId; - if (syncId) { - Client.sendPacket(new ServerboundContainerClosePacket(syncId)); - } +export const clickItems = (names, shift, button, displayName, exact) => + Array.isArray(names) && names.some((name) => clickItem(name, shift, button, displayName, exact)); - if (Client.currentGui) { - Client.currentGui.close(); - } +export function closeInventory() { + const player = Player.getPlayer(); + if (!player) return; - Client.getMinecraft().options.keyAttack.setDown(false); - } catch (e) { - console.error('V5 Caught error' + e + e.stack); - } + try { + const containerId = Client.getMinecraft().player.containerMenu.containerId; + if (containerId) Client.sendPacket(new ServerboundContainerClosePacket(containerId)); + Client.currentGui?.close(); + Client.getMinecraft().options.keyAttack.setDown(false); + } catch (error) { + console.error('V5 Caught error' + error + error.stack); } } -export const handler = new InterfaceHandler(); -export const searcher = new ItemSearcher(); - -export const Guis = { - stripFormatting: (s) => searcher.stripCodes(s), - getInventory: () => Player.getInventory(), - - findFirst: function (inv, name) { - return searcher.findInList(inv, name); - }, - - findAll: function (inv, name) { - return searcher.findAllInList(inv, name); - }, - - findItemInHotbar: function (name) { - const inv = Player.getInventory(); - if (!inv) return -1; - - const max = Math.min(inv.getSize(), 9); - for (var i = 0; i < max; i++) { - const stack = inv.getStackInSlot(i); - if (searcher.matchName(stack, name, false)) { - return i; - } - } - - return -1; - }, - - findItemInInventory: function (name) { - const inv = Player.getInventory(); - return inv ? searcher.findInList(inv, name, false) : -1; - }, - - closeInv: () => handler.terminateGui(), - - clickItem: function (name, shift, button, displayName, exact) { - const container = Player.getContainer(); - if (!container) return false; - - const items = container.getItems(); - for (var i = 0; i < items.length; i++) { - const item = items[i]; - if (!item) continue; - - const itemName = displayName !== false ? ChatLib.removeFormatting(String(item.getName())) : String(item.type?.getRegistryName?.() || ''); - if (!itemName) continue; - - const match = exact ? itemName.toLowerCase() === name.toLowerCase() : itemName.toLowerCase().includes(name.toLowerCase()); - - if (match) { - return this.clickSlot(i, shift, button); - } - } - return false; - }, - - clickSlot: function (slot, shift, button) { - return handler.performClick(slot, shift, button); - }, - - clickItems: function (names, shift, button, displayName, exact) { - if (!Array.isArray(names)) return false; - return names.some((name) => this.clickItem(name, shift, button, displayName, exact)); - }, - - setItemSlot: function (slot) { - if (slot >= 0 && slot <= 8) { - if (Player.getHeldItemIndex() !== slot) { - ScheduleTask(() => { - Player.setHeldItemIndex(slot); - }); - } - } - }, - - getHeldItemStackSize: function () { - const item = Player.getHeldItem(); - return item && item.getStackSize ? item.getStackSize() : 0; - }, +export function setItemSlot(slot) { + if (slot >= 0 && slot <= 8 && Player.getHeldItemIndex() !== slot) ScheduleTask(() => Player.setHeldItemIndex(slot)); +} - stopInGui: function () { - if (handler.getCurrentTitle() !== null) { - Client.stopMovement(); - Client.setKey('shift', false); - Client.setKey('leftclick', false); - Rotations.stop(); - } - }, +export function getGuiName() { + const container = Player.getContainer(); + return container ? ChatLib.removeFormatting(String(container.getName())) : null; +} - guiName: () => handler.getCurrentTitle(), +export const Guis = { + clickItems, + clickSlot, + closeInv: closeInventory, + findFirst: findFirstItem, + guiName: getGuiName, + setItemSlot, }; diff --git a/utils/player/Keybinding.js b/utils/player/Keybinding.js deleted file mode 100644 index b3deb037..00000000 --- a/utils/player/Keybinding.js +++ /dev/null @@ -1,180 +0,0 @@ -import { ScheduleTask } from '../ScheduleTask'; -import { Utils, mc } from '../Utils'; - -class ControlSystem { - constructor() { - this.lastActionTime = Date.now(); - } - - isGuiOpen() { - return Client.isInGui() && !Client.isInChat(); - } - - triggerLeftClick() { - if (this.isGuiOpen()) return; - ScheduleTask(() => { - Client.leftClick(); - }); - } - - triggerRightClick() { - if (this.isGuiOpen()) return; - ScheduleTask(() => { - Client.rightClick(); - }); - } - - updateKeyState(action, isPressed) { - const guiOpen = this.isGuiOpen(); - - if (action === 'leftclick') { - const attackKey = mc.options.keyAttack; - - if (isPressed && guiOpen) return false; - - if (isPressed) Client.getMinecraft().mouseHandler.grabMouse(); - - ScheduleTask(() => { - attackKey.setDown(!!isPressed); - }); - - return true; - } - - if (guiOpen && isPressed) return false; - - const options = mc.options; - const mapping = { - w: options.keyUp, - s: options.keyDown, - a: options.keyLeft, - d: options.keyRight, - space: options.keyJump, - shift: options.keyShift, - sprint: options.keySprint, - rightclick: options.keyUse, - }; - - const keyObj = mapping[action]; - if (keyObj) { - ScheduleTask(() => { - keyObj.setDown(!!isPressed); - }); - return true; - } - return false; - } - - checkKeyDown(key) { - const options = mc.options; - const mapping = { - w: options.keyUp, - s: options.keyDown, - a: options.keyLeft, - d: options.keyRight, - space: options.keyJump, - shift: options.keyShift, - leftclick: options.keyAttack, - sprint: options.keySprint, - rightclick: options.keyUse, - }; - return mapping[key] ? mapping[key].isDown() : false; - } - - setMovementByYaw(yaw, shouldJump) { - this.haltMovement(); - if (this.isGuiOpen()) return; - - if (yaw > -50 && yaw < 50) this.updateKeyState('w', true); - if (yaw > -135.5 && yaw < -7) this.updateKeyState('a', true); - if (yaw > 7 && yaw < 135.5) this.updateKeyState('d', true); - if (yaw > 135.5 || yaw < -135.5) this.updateKeyState('s', true); - - const motionScale = Math.abs(Player.getMotionX()) + Math.abs(Player.getMotionZ()); - const timeElapsed = Date.now() - this.lastActionTime; - - if (shouldJump && motionScale < 0.04 && timeElapsed > 500 && Utils.playerIsCollided()) { - this.updateKeyState('space', true); - this.refreshCooldown(); - } - } - - setCardinalMovement(yaw, shouldJump, ignoreBottomSlab) { - this.haltMovement(); - if (this.isGuiOpen()) return; - - const quadrants = [ - { min: -22.5, max: 22.5, keys: ['w'] }, - { min: -67.5, max: -22.5, keys: ['w', 'a'] }, - { min: -112.5, max: -67.5, keys: ['a'] }, - { min: -157.5, max: -112.5, keys: ['a', 's'] }, - { min: -180, max: -157.5, keys: ['s'] }, - { min: 157.5, max: 180, keys: ['s'] }, - { min: 22.5, max: 67.5, keys: ['w', 'd'] }, - { min: 67.5, max: 112.5, keys: ['d'] }, - { min: 112.5, max: 157.5, keys: ['s', 'd'] }, - ]; - - for (const q of quadrants) { - if (yaw >= q.min && yaw <= q.max) { - q.keys.forEach((key) => this.updateKeyState(key, true)); - break; - } - } - - this.updateKeyState('space', shouldJump && Utils.playerIsCollided(!!ignoreBottomSlab)); - } - - setMovementToCoords(x, y, z, shouldJump, ignoreBottomSlab) { - if (this.isGuiOpen()) return; - - const dx = x - Player.getX(); - const dz = z - Player.getZ(); - let angle = -(Math.atan2(dx, dz) * (180 / Math.PI)) - Player.getYaw(); - - while (angle < -180) angle += 360; - while (angle > 180) angle -= 360; - - this.setCardinalMovement(angle, shouldJump, ignoreBottomSlab); - } - - haltMovement() { - const keys = ['w', 'a', 's', 'd', 'space']; - keys.forEach((key) => this.updateKeyState(key, false)); - } - - fullRelease() { - this.haltMovement(); - this.updateKeyState('shift', false); - this.updateKeyState('leftclick', false); - this.updateKeyState('rightclick', false); - } - - refreshCooldown() { - this.lastActionTime = Date.now(); - } -} - -const controls = new ControlSystem(); - -export const Keybind = { - // @Deprecated Use Client.leftClick() - leftClick: () => controls.triggerLeftClick(), - // @Deprecated Use Client.rightClick() - rightClick: () => controls.triggerRightClick(), - // @Deprecated Use Client.setKey() - setKey: (k, d) => controls.updateKeyState(k, d), - // @Deprecated Use Client.isKeyDown() - isKeyDown: (k) => controls.checkKeyDown(k), - // @Deprecated Use Movement.setKeysBasedOnYaw() - setKeysBasedOnYaw: (y, j) => controls.setMovementByYaw(y, j), - // @Deprecated Use Movement.setKeysForStraightLine() - setKeysForStraightLine: (y, j, ignoreBottomSlab) => controls.setCardinalMovement(y, j, ignoreBottomSlab), - // @Deprecated Use Movement.setKeysForStraightLineCoords() - setKeysForStraightLineCoords: (x, y, z, j, ignoreBottomSlab) => controls.setMovementToCoords(x, y, z, j, ignoreBottomSlab), - // @Deprecated Use Client.stopMovement() - stopMovement: () => controls.haltMovement(), - // @Deprecated Use Client.unpressKeys() - unpressKeys: () => controls.fullRelease(), - isGuiOpen: () => controls.isGuiOpen(), -}; diff --git a/utils/player/Mousemat.js b/utils/player/Mousemat.js index ecb4f409..32e553e1 100644 --- a/utils/player/Mousemat.js +++ b/utils/player/Mousemat.js @@ -1,7 +1,7 @@ import { ScheduleTask } from '../ScheduleTask'; -import { Sign } from '../Sign'; -import { Utils } from '../Utils'; -import { Guis } from './Inventory'; +import { setSignLine } from '../Sign'; +import { randomInt } from '../Utils'; +import { findItemInHotbar, setItemSlot } from './Inventory'; import { farmingDelays } from '../../modules/farming/FarmingDelays'; const CLICK_COOLDOWN_MS = 3_050; @@ -45,7 +45,7 @@ class MousematController { return true; } - const slot = Guis.findItemInHotbar('Squeaky Mousemat'); + const slot = findItemInHotbar('Squeaky Mousemat'); if (slot < 0) return false; const rotation = (this.rotation = { @@ -56,7 +56,7 @@ class MousematController { waitingForClose: false, }); - Guis.setItemSlot(slot); + setItemSlot(slot); const selectedRotation = this.getSelectedRotation(slot); if (selectedRotation && selectedRotation.yaw === Number(rotation.yaw) && selectedRotation.pitch === Number(rotation.pitch)) { this.snap(rotation, this.getActionDelay()); @@ -73,14 +73,14 @@ class MousematController { } restore() { - const slot = Guis.findItemInHotbar('Squeaky Mousemat'); + const slot = findItemInHotbar('Squeaky Mousemat'); if (slot < 0) return false; this.stop(); const selectedRotation = this.getSelectedRotation(slot); if (!selectedRotation) return false; const rotation = (this.rotation = { originalSlot: Player.getHeldItemIndex(), ...selectedRotation }); - Guis.setItemSlot(slot); + setItemSlot(slot); this.snap(rotation, this.getActionDelay()); return true; } @@ -90,7 +90,7 @@ class MousematController { } getActionDelay() { - return Utils.randomInt(farmingDelays.mousematActionDelayMin, farmingDelays.mousematActionDelayMax); + return randomInt(farmingDelays.mousematActionDelayMin, farmingDelays.mousematActionDelayMax); } complete(rotation) { @@ -99,12 +99,12 @@ class MousematController { const callbacks = this.callbacks; this.rotation = null; this.callbacks = []; - Guis.setItemSlot(rotation.originalSlot); + setItemSlot(rotation.originalSlot); callbacks.forEach((callback) => ScheduleTask(callback)); } stop() { - if (this.rotation) Guis.setItemSlot(this.rotation.originalSlot); + if (this.rotation) setItemSlot(this.rotation.originalSlot); this.rotation = null; this.callbacks = []; } @@ -122,8 +122,8 @@ class MousematController { rotation.waitingForSign = false; rotation.waitingForClose = true; - Sign.setLine(1, rotation.yaw); - Sign.setLine(4, rotation.pitch); + setSignLine(1, rotation.yaw); + setSignLine(4, rotation.pitch); Client.currentGui.close(); } diff --git a/utils/player/Movement.js b/utils/player/Movement.js index b73681da..f14ac5a7 100644 --- a/utils/player/Movement.js +++ b/utils/player/Movement.js @@ -1,22 +1,4 @@ -import { Utils } from '../Utils'; - -let lastActionTime = Date.now(); - -function setKeysBasedOnYaw(yaw, shouldJump) { - Client.stopMovement(); - if (Client.isInGui() && !Client.isInChat()) return; - - if (yaw > -50 && yaw < 50) Client.setKey('w', true); - if (yaw > -135.5 && yaw < -7) Client.setKey('a', true); - if (yaw > 7 && yaw < 135.5) Client.setKey('d', true); - if (yaw > 135.5 || yaw < -135.5) Client.setKey('s', true); - - const motionScale = Math.abs(Player.getMotionX()) + Math.abs(Player.getMotionZ()); - if (shouldJump && motionScale < 0.04 && Date.now() - lastActionTime > 500 && Utils.playerIsCollided()) { - Client.setKey('space', true); - lastActionTime = Date.now(); - } -} +import { playerIsCollided } from '../Utils'; function setKeysForStraightLine(yaw, shouldJump, ignoreBottomSlab) { Client.stopMovement(); @@ -41,10 +23,10 @@ function setKeysForStraightLine(yaw, shouldJump, ignoreBottomSlab) { } } - Client.setKey('space', !!shouldJump && Utils.playerIsCollided(!!ignoreBottomSlab)); + Client.setKey('space', !!shouldJump && playerIsCollided(!!ignoreBottomSlab)); } -function setKeysForStraightLineCoords(x, y, z, shouldJump, ignoreBottomSlab) { +export function setKeysForStraightLineCoords(x, y, z, shouldJump, ignoreBottomSlab) { if (Client.isInGui() && !Client.isInChat()) return; const dx = x - Player.getX(); @@ -56,5 +38,3 @@ function setKeysForStraightLineCoords(x, y, z, shouldJump, ignoreBottomSlab) { setKeysForStraightLine(angle, shouldJump, ignoreBottomSlab); } - -export const Movement = { setKeysBasedOnYaw, setKeysForStraightLine, setKeysForStraightLineCoords }; diff --git a/utils/player/OreRotations.js b/utils/player/OreRotations.js index 025a4fa2..fadd29e9 100644 --- a/utils/player/OreRotations.js +++ b/utils/player/OreRotations.js @@ -1,5 +1,5 @@ -import { Utils } from '../Utils'; -import { RotationGCD } from './RotationGCD'; +import { convertToVector } from '../Utils'; +import { aimModulo360, angleDifference, calculateGCD, clampPitch } from './RotationGCD'; class OreRotationController { constructor() { @@ -31,16 +31,16 @@ class OreRotationController { const currentYaw = player.getYRot(); const currentPitch = player.getXRot(); - this.targetYaw = RotationGCD.aimModulo360(currentYaw, angles.yaw); - this.targetPitch = RotationGCD.clampPitch(angles.pitch); - this.initialYawDistance = Math.abs(RotationGCD.angleDifference(this.targetYaw, currentYaw)); + this.targetYaw = aimModulo360(currentYaw, angles.yaw); + this.targetPitch = clampPitch(angles.pitch); + this.initialYawDistance = Math.abs(angleDifference(this.targetYaw, currentYaw)); this.initialPitchDistance = Math.abs(this.targetPitch - currentPitch); const distance = Math.hypot(this.initialYawDistance, this.initialPitchDistance); this.warmupSteps = distance > 60 ? 1 : distance > 20 ? 3 : 5; this.step = 0; this.speed = speed; - this.gcd = RotationGCD.calculateGCD(); + this.gcd = calculateGCD(); this.lastUpdateAt = Date.now(); this.yawRemainder = 0; this.pitchRemainder = 0; @@ -80,7 +80,7 @@ class OreRotationController { const currentYaw = player.getYRot(); const currentPitch = player.getXRot(); - const deltaYaw = RotationGCD.angleDifference(this.targetYaw, currentYaw); + const deltaYaw = angleDifference(this.targetYaw, currentYaw); const deltaPitch = this.targetPitch - currentPitch; const distance = Math.hypot(deltaYaw, deltaPitch); @@ -110,7 +110,7 @@ class OreRotationController { this.pitchRemainder = rawPitchStep - pitchStep; player.setYRot(currentYaw + yawStep); - player.setXRot(RotationGCD.clampPitch(currentPitch + pitchStep)); + player.setXRot(clampPitch(currentPitch + pitchStep)); } refreshTrackedTarget(player, vector) { @@ -118,13 +118,13 @@ class OreRotationController { if (!angles) return false; const currentYaw = player.getYRot(); - this.targetYaw = RotationGCD.aimModulo360(currentYaw, angles.yaw); - this.targetPitch = RotationGCD.clampPitch(angles.pitch); + this.targetYaw = aimModulo360(currentYaw, angles.yaw); + this.targetPitch = clampPitch(angles.pitch); return true; } getTargetAngles(player, vector) { - const target = Utils.convertToVector(vector); + const target = convertToVector(vector); if (!target) return false; const eyes = player.getEyePosition(); diff --git a/utils/player/RotationGCD.js b/utils/player/RotationGCD.js index 0a9d6373..aab555ce 100644 --- a/utils/player/RotationGCD.js +++ b/utils/player/RotationGCD.js @@ -1,109 +1,70 @@ -class SharedRotationGCD { - constructor() { - this.lastYaw = 0; - this.lastPitch = 0; - this.initialized = false; - this.lastApplyAt = 0; - this.DRIFT_RESYNC_MS = 120; - } - - calculateGCD() { - const sensitivity = Client.getMinecraft().options.sensitivity().get(); - const f = sensitivity * 0.6 + 0.2; - return f * f * f * 1.2; - } - - normalizeAngle(angle) { - return (((angle % 360) + 540) % 360) - 180; - } - - clampPitch(pitch) { - return Math.max(-90, Math.min(90, pitch)); - } - - angleDifference(a, b) { - return this.normalizeAngle(a - b); - } - - aimModulo360(currentYaw, targetYaw) { - if (!Number.isFinite(currentYaw)) return targetYaw; - if (!Number.isFinite(targetYaw)) return currentYaw; - return currentYaw + this.angleDifference(targetYaw, currentYaw); - } - - applyGCD(delta, prevRotation, gcd, min = null, max = null) { - if (!Number.isFinite(delta) || !Number.isFinite(gcd) || gcd <= 0) return prevRotation; - const roundedDelta = Math.round(delta / gcd) * gcd; - let result = prevRotation + roundedDelta; - - if (max !== null && result > max) result -= gcd; - if (min !== null && result < min) result += gcd; - - return result; - } - - syncFromPlayer(yaw = null, pitch = null, player = Player.getPlayer()) { - if (!player) return false; - - const playerYaw = player.getYRot(); - - this.lastYaw = Number.isFinite(yaw) ? this.aimModulo360(playerYaw, yaw) : playerYaw; - this.lastPitch = Number.isFinite(pitch) ? this.clampPitch(pitch) : this.clampPitch(player.getXRot()); - this.initialized = true; - return true; - } - - resyncIfDrifted(player, gcd) { - const playerYaw = player.getYRot(); - const playerPitch = player.getXRot(); - const yawDrift = Math.abs(this.angleDifference(this.lastYaw, playerYaw)); - const pitchDrift = Math.abs(playerPitch - this.lastPitch); +const DRIFT_RESYNC_MS = 120; +let lastYaw = 0; +let lastPitch = 0; +let initialized = false; +let lastApplyAt = 0; + +export function calculateGCD() { + const sensitivity = Client.getMinecraft().options.sensitivity().get(); + const scaled = sensitivity * 0.6 + 0.2; + return scaled ** 3 * 1.2; +} - if (yawDrift > gcd * 2 || Math.abs(playerYaw - this.lastYaw) > 180 || pitchDrift > gcd * 2) { - this.lastYaw = playerYaw; - this.lastPitch = playerPitch; - } - } +const normalizeAngle = (angle) => (((angle % 360) + 540) % 360) - 180; +export const clampPitch = (pitch) => Math.max(-90, Math.min(90, pitch)); +export const angleDifference = (a, b) => normalizeAngle(a - b); - getCurrentRotation(player = Player.getPlayer()) { - if (!player) return null; +export function aimModulo360(currentYaw, targetYaw) { + if (!Number.isFinite(currentYaw)) return targetYaw; + if (!Number.isFinite(targetYaw)) return currentYaw; + return currentYaw + angleDifference(targetYaw, currentYaw); +} - if (this.initialized) { - this.resyncIfDrifted(player, this.calculateGCD()); - } +const applyGCD = (delta, previous, gcd, min = null, max = null) => { + if (!Number.isFinite(delta) || !Number.isFinite(gcd) || gcd <= 0) return previous; + let result = previous + Math.round(delta / gcd) * gcd; + if (max !== null && result > max) result -= gcd; + if (min !== null && result < min) result += gcd; + return result; +}; + +export function syncFromPlayer(yaw = null, pitch = null, player = Player.getPlayer()) { + if (!player) return false; + const playerYaw = player.getYRot(); + lastYaw = Number.isFinite(yaw) ? aimModulo360(playerYaw, yaw) : playerYaw; + lastPitch = Number.isFinite(pitch) ? clampPitch(pitch) : clampPitch(player.getXRot()); + initialized = true; + return true; +} - return { - yaw: this.initialized ? this.lastYaw : player.getYRot(), - pitch: this.initialized ? this.lastPitch : player.getXRot(), - }; +const resyncIfDrifted = (player, gcd) => { + const playerYaw = player.getYRot(); + const playerPitch = player.getXRot(); + if (Math.abs(angleDifference(lastYaw, playerYaw)) > gcd * 2 || Math.abs(playerYaw - lastYaw) > 180 || Math.abs(playerPitch - lastPitch) > gcd * 2) { + lastYaw = playerYaw; + lastPitch = playerPitch; } +}; - applyToPlayer(yaw, pitch) { - const player = Player.getPlayer(); - if (!player) return null; - if (!Number.isFinite(yaw) || !Number.isFinite(pitch)) return null; - - const now = Date.now(); - const gcd = this.calculateGCD(); - - if (!this.initialized) { - this.syncFromPlayer(); - } else if (now - this.lastApplyAt > this.DRIFT_RESYNC_MS) { - this.resyncIfDrifted(player, gcd); - } - - const gcdYaw = this.applyGCD(this.angleDifference(yaw, this.lastYaw), this.lastYaw, gcd); - const gcdPitch = this.applyGCD(this.clampPitch(pitch) - this.clampPitch(this.lastPitch), this.clampPitch(this.lastPitch), gcd, -90, 90); - - this.lastYaw = gcdYaw; - this.lastPitch = gcdPitch; - this.lastApplyAt = now; - - player.setYRot(gcdYaw); - player.setXRot(gcdPitch); - - return { yaw: gcdYaw, pitch: gcdPitch }; - } +export function getCurrentRotation(player = Player.getPlayer()) { + if (!player) return null; + if (initialized) resyncIfDrifted(player, calculateGCD()); + return { yaw: initialized ? lastYaw : player.getYRot(), pitch: initialized ? lastPitch : player.getXRot() }; } -export const RotationGCD = new SharedRotationGCD(); +export function applyToPlayer(yaw, pitch) { + const player = Player.getPlayer(); + if (!player || !Number.isFinite(yaw) || !Number.isFinite(pitch)) return null; + + const now = Date.now(); + const gcd = calculateGCD(); + if (!initialized) syncFromPlayer(); + else if (now - lastApplyAt > DRIFT_RESYNC_MS) resyncIfDrifted(player, gcd); + + lastYaw = applyGCD(angleDifference(yaw, lastYaw), lastYaw, gcd); + lastPitch = applyGCD(clampPitch(pitch) - clampPitch(lastPitch), clampPitch(lastPitch), gcd, -90, 90); + lastApplyAt = now; + player.setYRot(lastYaw); + player.setXRot(lastPitch); + return { yaw: lastYaw, pitch: lastPitch }; +} diff --git a/utils/player/Rotations.js b/utils/player/Rotations.js index ba55e694..fa6b8b88 100644 --- a/utils/player/Rotations.js +++ b/utils/player/Rotations.js @@ -1,10 +1,10 @@ import { ModuleBase } from '../ModuleBase'; -import { RotationGCD } from './RotationGCD'; -import { Utils } from '../Utils'; +import { aimModulo360, angleDifference, applyToPlayer, calculateGCD, clampPitch, getCurrentRotation, syncFromPlayer } from './RotationGCD'; +import { convertToVector } from '../Utils'; import { v5Command } from '../V5Commands'; import { Rotations as PathRotations } from '../pathfinder/PathWalker/PathRotations'; import { PathFlyer } from '../pathfinder/PathFlyer'; -import { EtherwarpPathState } from '../Etherwarp'; +import { getEtherwarpPathHandler } from '../Etherwarp'; class RotationConfig extends ModuleBase { constructor() { @@ -47,7 +47,6 @@ class RotationConfig extends ModuleBase { } const RotationModule = new RotationConfig(); -export default RotationModule; const DEFAULT_PRECISION = 0.1; const ENTITY_PRECISION = 0.5; @@ -82,11 +81,11 @@ class RotationController { lookAtAngles(yaw, pitch, options = {}) { if (!Number.isFinite(yaw) || !Number.isFinite(pitch)) return false; - return this.start({ type: 'angles', value: { yaw, pitch: RotationGCD.clampPitch(pitch) } }, options); + return this.start({ type: 'angles', value: { yaw, pitch: clampPitch(pitch) } }, options); } lookAtVector(vector, options = {}) { - const vec = Utils.convertToVector(vector); + const vec = convertToVector(vector); if (!vec) return false; return this.start({ type: 'vector', value: vec }, options); } @@ -106,7 +105,7 @@ class RotationController { stop() { this.clearRequest(); this.callbacks = []; - RotationGCD.syncFromPlayer(); + syncFromPlayer(); } getAimPoint(entity) { @@ -134,7 +133,7 @@ class RotationController { }; } } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); } return null; @@ -144,7 +143,7 @@ class RotationController { if (!this.request) return; if (!this.refreshTarget()) return; - if (PathRotations.rotationActive || PathFlyer.rotationActive || EtherwarpPathState.handler?.isPathing?.()) return; + if (PathRotations.rotationActive || PathFlyer.rotationActive || getEtherwarpPathHandler()?.isPathing?.()) return; const player = Player.getPlayer(); if (!player || !this.targetAngles) { @@ -152,14 +151,14 @@ class RotationController { return; } - const current = RotationGCD.getCurrentRotation(player); + const current = getCurrentRotation(player); if (!current) { this.stop(); return; } - const targetYaw = RotationGCD.aimModulo360(current.yaw, this.targetAngles.yaw); - const targetPitch = RotationGCD.clampPitch(this.targetAngles.pitch); + const targetYaw = aimModulo360(current.yaw, this.targetAngles.yaw); + const targetPitch = clampPitch(this.targetAngles.pitch); const deltaYaw = targetYaw - current.yaw; const deltaPitch = targetPitch - current.pitch; const distance = Math.hypot(deltaYaw, deltaPitch); @@ -170,7 +169,7 @@ class RotationController { } if (RotationModule.rotationMode === 'Instant') { - RotationGCD.applyToPlayer(targetYaw, targetPitch); + applyToPlayer(targetYaw, targetPitch); this.onReachedTarget(); return; } @@ -191,10 +190,10 @@ class RotationController { const ratio = this.getStepRatio(distance, deltaTime); const curve = this.getCurveOffset(this.getProgress(distance)); const nextYaw = current.yaw + deltaYaw * ratio + curve.x * ratio; - const nextPitch = RotationGCD.clampPitch(current.pitch + deltaPitch * ratio + curve.y * ratio); + const nextPitch = clampPitch(current.pitch + deltaPitch * ratio + curve.y * ratio); if (Number.isFinite(nextYaw) && Number.isFinite(nextPitch)) { - RotationGCD.applyToPlayer(nextYaw, nextPitch); + applyToPlayer(nextYaw, nextPitch); } } @@ -209,7 +208,7 @@ class RotationController { !sameSource || !this.targetAngles || (nextRequest.type !== 'entity' && this.getTargetShift(nextTarget) > TARGET_SHIFT_RESET_DEGREES); if (!this.request || !sameSource) { - RotationGCD.syncFromPlayer(); + syncFromPlayer(); } this.request = nextRequest; @@ -266,13 +265,13 @@ class RotationController { const mcEntity = entity.toMC ? entity.toMC() : entity; return !!mcEntity && !mcEntity.isDeadOrDying?.() && !mcEntity.isRemoved?.(); } catch (e) { - console.error('V5 Caught error' + e + e.stack); + console.error(e); return false; } } getTargetShift(nextTarget) { - const dYaw = Math.abs(RotationGCD.angleDifference(nextTarget.yaw, this.targetAngles.yaw)); + const dYaw = Math.abs(angleDifference(nextTarget.yaw, this.targetAngles.yaw)); const dPitch = Math.abs(nextTarget.pitch - this.targetAngles.pitch); return Math.hypot(dYaw, dPitch); } @@ -281,7 +280,7 @@ class RotationController { let precision = DEFAULT_PRECISION; if (Number.isFinite(this.request?.precision)) precision = this.request.precision; else if (this.request?.type === 'entity') precision = ENTITY_PRECISION; - return Math.max(precision, RotationGCD.calculateGCD() / Math.SQRT2); + return Math.max(precision, calculateGCD() / Math.SQRT2); } getStepRatio(distance, deltaTime) { @@ -326,14 +325,14 @@ class RotationController { complete() { const callbacks = this.callbacks.splice(0); this.clearRequest(); - RotationGCD.syncFromPlayer(); + syncFromPlayer(); for (const action of callbacks) { try { action.callback(); } catch (e) { console.error(`Rotation ${action.name || 'callback'} error:`); - console.error('V5 Caught error' + e + e.stack); + console.error(e); } } } @@ -354,7 +353,7 @@ class RotationController { } getAnglesFromVector(vector) { - const vec = Utils.convertToVector(vector); + const vec = convertToVector(vector); const player = Player.getPlayer(); if (!vec || !player) return null; @@ -364,7 +363,7 @@ class RotationController { return { yaw: Math.atan2(-dx, dz) * (180 / Math.PI), - pitch: RotationGCD.clampPitch(Math.atan2(-dy, Math.hypot(dx, dz)) * (180 / Math.PI)), + pitch: clampPitch(Math.atan2(-dy, Math.hypot(dx, dz)) * (180 / Math.PI)), }; } } diff --git a/utils/player/ServerInfo.js b/utils/player/ServerInfo.js index c78aceb6..8043996d 100644 --- a/utils/player/ServerInfo.js +++ b/utils/player/ServerInfo.js @@ -1,140 +1,102 @@ import { System } from '../Constants'; -import { ServerboundClientCommandPacket, ClientboundPingPacket, ClientboundLoginPacket, ClientboundAwardStatsPacket } from '../Packets'; - -class NetworkMonitor { - constructor() { - this.lastTpsNano = 0; - this.currentTps = 20; - this.tpsSamples = []; - this.tpsWindowSize = 40; - this.tpsTrimFraction = 0.25; - this.tpsEmaAlpha = 0.2; - - this.pingSamples = []; - this.maxHistory = 20; - this.waitingForPing = false; - this.pingStartNano = 0; - this.avgPing = 0; - this.minPingMs = Infinity; - this.jitterCapMs = 10; - } - - addSample(list, value, maxSize) { - list.push(value); - if (list.length > maxSize) list.shift(); - } - - calculateTpsAverage() { - if (this.tpsSamples.length === 0) return this.currentTps; - - const trimCount = Math.min(Math.floor(this.tpsSamples.length * this.tpsTrimFraction), Math.floor((this.tpsSamples.length - 1) / 2)); +import { ClientboundAwardStatsPacket, ClientboundLoginPacket, ClientboundPingPacket, ServerboundClientCommandPacket } from '../Packets'; + +const TPS_WINDOW_SIZE = 40; +const TPS_TRIM_FRACTION = 0.25; +const TPS_EMA_ALPHA = 0.2; +const MAX_PING_HISTORY = 20; +const JITTER_CAP_MS = 10; + +let lastTpsNano = 0; +let currentTps = 20; +let tpsSamples = []; +let pingSamples = []; +let waitingForPing = false; +let pingStartNano = 0; +let averagePing = 0; +let minimumPing = Infinity; + +const addSample = (samples, value, maxSize) => { + samples.push(value); + if (samples.length > maxSize) samples.shift(); +}; - if (trimCount === 0) { - const total = this.tpsSamples.reduce((sum, value) => sum + value, 0); - return total / this.tpsSamples.length; - } +const averageTps = () => { + if (!tpsSamples.length) return currentTps; + const trim = Math.min(Math.floor(tpsSamples.length * TPS_TRIM_FRACTION), Math.floor((tpsSamples.length - 1) / 2)); + const samples = trim ? [...tpsSamples].sort((a, b) => a - b).slice(trim, -trim) : tpsSamples; + return samples.reduce((sum, value) => sum + value, 0) / samples.length; +}; - const sorted = [...this.tpsSamples].sort((a, b) => a - b); - const trimmed = sorted.slice(trimCount, sorted.length - trimCount); - const trimmedTotal = trimmed.reduce((sum, value) => sum + value, 0); - return trimmedTotal / trimmed.length; - } +const estimateJitter = () => { + if (!pingSamples.length || !Number.isFinite(minimumPing)) return 0; + const sorted = [...pingSamples].sort((a, b) => a - b); + return Math.min(Math.max(0, (sorted[Math.floor(sorted.length / 2)] - Math.min(minimumPing, sorted[0])) / 2), JITTER_CAP_MS); +}; - calculateJitterEstimate() { - if (this.pingSamples.length === 0 || !Number.isFinite(this.minPingMs)) return 0; - const sorted = [...this.pingSamples].sort((a, b) => a - b); - const median = sorted[Math.floor(sorted.length / 2)]; - const baseline = Math.min(this.minPingMs, sorted[0]); - const jitter = Math.max(0, (median - baseline) / 2); - return Math.min(jitter, this.jitterCapMs); +const recordTpsPacket = () => { + const now = System.nanoTime(); + if (lastTpsNano > 0) { + const elapsed = Math.max(1, (now - lastTpsNano) / 1_000_000 - estimateJitter()); + addSample(tpsSamples, Math.min(20, 1000 / elapsed), TPS_WINDOW_SIZE); + currentTps += (averageTps() - currentTps) * TPS_EMA_ALPHA; } + lastTpsNano = now; +}; - recordTpsPacket() { - const now = System.nanoTime(); - if (this.lastTpsNano > 0) { - let deltaMs = (now - this.lastTpsNano) / 1_000_000; - deltaMs = Math.max(1, deltaMs - this.calculateJitterEstimate()); - const instant = Math.min(20, 1000 / deltaMs); - this.addSample(this.tpsSamples, instant, this.tpsWindowSize); - const robustTps = this.calculateTpsAverage(); - this.currentTps += (robustTps - this.currentTps) * this.tpsEmaAlpha; - } - this.lastTpsNano = now; - } +const requestPing = () => { + if (!Player.getPlayer() || waitingForPing) return; + Client.sendPacket(new ServerboundClientCommandPacket(ServerboundClientCommandPacket.Action.REQUEST_STATS)); + pingStartNano = System.nanoTime(); + waitingForPing = true; +}; - sendPingRequest() { - if (!Player.getPlayer()) return; - if (!this.waitingForPing) { - Client.sendPacket(new ServerboundClientCommandPacket(ServerboundClientCommandPacket.Action.REQUEST_STATS)); - this.pingStartNano = System.nanoTime(); - this.waitingForPing = true; - } - } +const resolvePing = () => { + if (!waitingForPing) return; + const elapsed = (System.nanoTime() - pingStartNano) / 1_000_000; + waitingForPing = false; + addSample(pingSamples, elapsed, MAX_PING_HISTORY); + minimumPing = Math.min(minimumPing, elapsed); + averagePing = pingSamples.reduce((sum, value) => sum + value, 0) / pingSamples.length; +}; - resolvePing() { - if (this.waitingForPing) { - const elapsedMs = (System.nanoTime() - this.pingStartNano) / 1_000_000; - this.waitingForPing = false; +const reset = () => { + lastTpsNano = 0; + currentTps = 20; + tpsSamples = []; + pingSamples = []; + averagePing = 0; + waitingForPing = false; + minimumPing = Infinity; +}; - this.addSample(this.pingSamples, elapsedMs, this.maxHistory); - this.minPingMs = Math.min(this.minPingMs, elapsedMs); +register('worldLoad', reset); +register('packetReceived', recordTpsPacket).setFilteredClass(ClientboundPingPacket); +register('packetReceived', resolvePing).setFilteredClass(ClientboundAwardStatsPacket); +register('packetReceived', () => (waitingForPing = false)).setFilteredClass(ClientboundLoginPacket); +register('step', requestPing).setDelay(1); - const totalPing = this.pingSamples.reduce((sum, value) => sum + value, 0); - this.avgPing = totalPing / this.pingSamples.length; - } - } +export const getPing = () => Math.round(averagePing); - reset() { - this.lastTpsNano = 0; - this.currentTps = 20; - this.tpsSamples = []; - this.pingSamples = []; - this.avgPing = 0; - this.waitingForPing = false; - this.minPingMs = Infinity; - } +export function getTPS() { + const tps = Number(currentTps); + return Number.parseFloat((Number.isFinite(tps) ? Math.max(0, Math.min(20, tps)) : 20).toFixed(2)); } -const monitor = new NetworkMonitor(); - -register('worldLoad', () => monitor.reset()); - -register('packetReceived', () => { - monitor.recordTpsPacket(); -}).setFilteredClass(ClientboundPingPacket); - -register('packetReceived', () => { - monitor.resolvePing(); -}).setFilteredClass(ClientboundAwardStatsPacket); - -register('packetReceived', () => { - monitor.waitingForPing = false; -}).setFilteredClass(ClientboundLoginPacket); +export function getTpsColor(tps) { + if (tps > 19.8) return 0x00aa00; + if (tps > 19) return 0x55ff55; + if (tps > 17.5) return 0xffaa00; + if (tps > 12) return 0xff5555; + return 0xaa0000; +} -register('step', () => { - monitor.sendPingRequest(); -}).setDelay(1); +export function getPingColor(ping) { + if (ping < 50) return 0x55ff55; + if (ping < 100) return 0x00aa00; + if (ping < 149) return 0xffff55; + if (ping < 249) return 0xffaa00; + return 0xff5555; +} -export const ServerInfo = { - getPing: () => Math.round(monitor.avgPing), - getTPS: () => { - const raw = Number(monitor.currentTps); - const safe = Number.isFinite(raw) ? Math.max(0, Math.min(20, raw)) : 20; - return Number.parseFloat(safe.toFixed(2)); - }, - getTpsColor: (tps) => { - if (tps > 19.8) return 0x00aa00; - if (tps > 19) return 0x55ff55; - if (tps > 17.5) return 0xffaa00; - if (tps > 12) return 0xff5555; - return 0xaa0000; - }, - getPingColor: (ping) => { - if (ping < 50) return 0x55ff55; - if (ping < 100) return 0x00aa00; - if (ping < 149) return 0xffff55; - if (ping < 249) return 0xffaa00; - return 0xff5555; - }, - getServerInfo: () => ({ ping: ServerInfo.getPing(), tps: ServerInfo.getTPS() }), -}; +export const getServerInfo = () => ({ ping: getPing(), tps: getTPS() }); From bba762a43cfde8dd4a5eca10caa3648b406d523b Mon Sep 17 00:00:00 2001 From: rdbtCVS <87152661+rdbtCVS@users.noreply.github.com> Date: Sun, 2 Aug 2026 23:47:18 +0100 Subject: [PATCH 2/5] merge numberuitls into math --- failsafes/Failsafe.js | 2 +- failsafes/FailsafeUtils.js | 2 +- modules/mining/CommissionMacro.js | 3 +-- modules/mining/GlaciteCommissionMacro.js | 2 +- modules/other/PeltMacro.js | 3 +-- modules/other/RatMacro.js | 2 +- modules/other/SunGeckoMacro.js | 3 +-- modules/skills/StridersurferMacro.js | 3 +-- modules/skills/WynnProfessionMacro.js | 3 +-- utils/FileUtils.js | 2 +- utils/Math.js | 10 ++++++++++ utils/NumberUtils.js | 9 --------- utils/ScheduleTask.js | 2 +- utils/Utils.js | 3 --- utils/pathfinder/EtherwarpPathfinder.js | 2 +- utils/pathfinder/PathWalker/PathMovement.js | 2 +- utils/pathfinder/PathWalker/PathPrediction.js | 2 +- utils/pathfinder/SwiftIntegration.js | 2 +- 18 files changed, 25 insertions(+), 32 deletions(-) delete mode 100644 utils/NumberUtils.js diff --git a/failsafes/Failsafe.js b/failsafes/Failsafe.js index a4b41951..61b90f42 100644 --- a/failsafes/Failsafe.js +++ b/failsafes/Failsafe.js @@ -1,6 +1,6 @@ import { registerSkyblockEvent } from '../utils/SkyblockEvents'; import { isFailsafeMacroRunning } from '../utils/MacroState'; -import { finiteNumber } from '../utils/NumberUtils'; +import { finiteNumber } from '../utils/Math'; export class Failsafe { registered = false; disabled = false; diff --git a/failsafes/FailsafeUtils.js b/failsafes/FailsafeUtils.js index b4f30706..a23c5367 100644 --- a/failsafes/FailsafeUtils.js +++ b/failsafes/FailsafeUtils.js @@ -1,5 +1,5 @@ import { V5ConfigFile } from '../utils/Constants'; -import { finiteNumber } from '../utils/NumberUtils'; +import { finiteNumber } from '../utils/Math'; const DEFAULT_FAILSAFE_SETTINGS = { isEnabled: true, diff --git a/modules/mining/CommissionMacro.js b/modules/mining/CommissionMacro.js index f2d63898..5bbd2d5a 100644 --- a/modules/mining/CommissionMacro.js +++ b/modules/mining/CommissionMacro.js @@ -1,11 +1,10 @@ import { OverlayManager } from '../../gui/OverlayUtils'; import { notificationManager } from '../../gui/NotificationManager'; import { CommissionClaimer } from '../../utils/CommissionUtils'; -import { fastDistance } from '../../utils/Math'; +import { fastDistance, finiteNumber } from '../../utils/Math'; import { getModuleElapsedMs } from '../../utils/MacroState'; import { getDrills, getMiningSpeed, readCommissionsFromGui, refuel } from '../../utils/MiningUtils'; import { ModuleBase } from '../../utils/ModuleBase'; -import { finiteNumber } from '../../utils/NumberUtils'; import { EtherwarpPathfinder } from '../../utils/pathfinder/EtherwarpPathfinder'; import Pathfinder from '../../utils/pathfinder/PathFinder'; import { clickSlot, closeInventory, getGuiName, setItemSlot } from '../../utils/player/Inventory'; diff --git a/modules/mining/GlaciteCommissionMacro.js b/modules/mining/GlaciteCommissionMacro.js index d90a2e01..7d9335d9 100644 --- a/modules/mining/GlaciteCommissionMacro.js +++ b/modules/mining/GlaciteCommissionMacro.js @@ -4,7 +4,7 @@ import { CommissionClaimer } from '../../utils/CommissionUtils'; import { getModuleElapsedMs } from '../../utils/MacroState'; import { getDebuff, getDrills, readCommissionsFromGui } from '../../utils/MiningUtils'; import { ModuleBase } from '../../utils/ModuleBase'; -import { finiteNumber } from '../../utils/NumberUtils'; +import { finiteNumber } from '../../utils/Math'; import { EtherwarpPathfinder } from '../../utils/pathfinder/EtherwarpPathfinder'; import Pathfinder from '../../utils/pathfinder/PathFinder'; import { closeInventory, setItemSlot } from '../../utils/player/Inventory'; diff --git a/modules/other/PeltMacro.js b/modules/other/PeltMacro.js index be683227..c78aa2e5 100644 --- a/modules/other/PeltMacro.js +++ b/modules/other/PeltMacro.js @@ -2,13 +2,12 @@ import { OverlayManager } from '../../gui/OverlayUtils'; import { MCHand, Vec3d } from '../../utils/Constants'; import { getModuleElapsedMs } from '../../utils/MacroState'; import { ModuleBase } from '../../utils/ModuleBase'; -import { formatRoundedNumber } from '../../utils/NumberUtils'; import { ServerboundUseItemPacket } from '../../utils/Packets'; import { ScheduleTask } from '../../utils/ScheduleTask'; import Pathfinder from '../../utils/pathfinder/PathFinder'; import { EtherwarpPathfinder } from '../../utils/pathfinder/EtherwarpPathfinder'; import { destroyPathExecutor } from '../../utils/pathfinder/PathExecutor'; -import { angleToPlayer, fastDistance } from '../../utils/Math'; +import { angleToPlayer, fastDistance, formatRoundedNumber } from '../../utils/Math'; import { area } from '../../utils/Utils'; import { findItemInHotbar, setItemSlot } from '../../utils/player/Inventory'; import { Rotations } from '../../utils/player/Rotations'; diff --git a/modules/other/RatMacro.js b/modules/other/RatMacro.js index 5e8db1a5..2eb427d8 100644 --- a/modules/other/RatMacro.js +++ b/modules/other/RatMacro.js @@ -3,7 +3,7 @@ import { isDeveloperModeEnabled } from '../../utils/DeveloperModeState'; import { OverlayManager } from '../../gui/OverlayUtils'; import { sendDebugMessage } from '../../utils/Chat'; import { MCHand } from '../../utils/Constants'; -import { finiteNumber, formatRoundedNumber } from '../../utils/NumberUtils'; +import { finiteNumber, formatRoundedNumber } from '../../utils/Math'; import { ModuleBase } from '../../utils/ModuleBase'; import { ServerboundUseItemPacket } from '../../utils/Packets'; import { EtherwarpPathfinder } from '../../utils/pathfinder/EtherwarpPathfinder'; diff --git a/modules/other/SunGeckoMacro.js b/modules/other/SunGeckoMacro.js index d5a323a3..008cf84a 100644 --- a/modules/other/SunGeckoMacro.js +++ b/modules/other/SunGeckoMacro.js @@ -1,9 +1,8 @@ import { OverlayManager } from '../../gui/OverlayUtils'; import { CombatBot } from '../combat/CombatBot'; import { getModuleElapsedMs } from '../../utils/MacroState'; -import { fastDistance } from '../../utils/Math'; +import { fastDistance, formatRoundedNumber } from '../../utils/Math'; import { ModuleBase } from '../../utils/ModuleBase'; -import { formatRoundedNumber } from '../../utils/NumberUtils'; import Pathfinder from '../../utils/pathfinder/PathFinder'; import { findItemInHotbar, getGuiName, setItemSlot } from '../../utils/player/Inventory'; import { setKeysForStraightLineCoords } from '../../utils/player/Movement'; diff --git a/modules/skills/StridersurferMacro.js b/modules/skills/StridersurferMacro.js index 4a635c69..27f38cbb 100644 --- a/modules/skills/StridersurferMacro.js +++ b/modules/skills/StridersurferMacro.js @@ -1,9 +1,8 @@ import { OverlayManager } from '../../gui/OverlayUtils'; import { ArmorStandEntity } from '../../utils/Constants'; import { getModuleElapsedMs } from '../../utils/MacroState'; -import { wrapTo180 } from '../../utils/Math'; +import { formatRoundedNumber, wrapTo180 } from '../../utils/Math'; import { ModuleBase } from '../../utils/ModuleBase'; -import { formatRoundedNumber } from '../../utils/NumberUtils'; import { clickItem, closeInventory, setItemSlot } from '../../utils/player/Inventory'; import { Rotations } from '../../utils/player/Rotations'; import { regrab, ungrab } from '../../utils/Ungrab'; diff --git a/modules/skills/WynnProfessionMacro.js b/modules/skills/WynnProfessionMacro.js index ebd1349a..b621dbaa 100644 --- a/modules/skills/WynnProfessionMacro.js +++ b/modules/skills/WynnProfessionMacro.js @@ -1,8 +1,7 @@ import { OverlayManager } from '../../gui/OverlayUtils'; import { getModuleElapsedMs } from '../../utils/MacroState'; -import { fastDistance } from '../../utils/Math'; +import { fastDistance, formatRoundedNumber } from '../../utils/Math'; import { ModuleBase } from '../../utils/ModuleBase'; -import { formatRoundedNumber } from '../../utils/NumberUtils'; import Pathfinder from '../../utils/pathfinder/PathFinder'; import { clickSlot, closeInventory } from '../../utils/player/Inventory'; import { Rotations } from '../../utils/player/Rotations'; diff --git a/utils/FileUtils.js b/utils/FileUtils.js index add3bd85..49df963a 100644 --- a/utils/FileUtils.js +++ b/utils/FileUtils.js @@ -1,5 +1,5 @@ import { BufferedInputStream, FileOutputStream, URL } from './Constants'; -import { finiteNumber } from './NumberUtils'; +import { finiteNumber } from './Math'; const DEFAULT_DOWNLOAD_BUFFER_SIZE = 8192; diff --git a/utils/Math.js b/utils/Math.js index 7de6e606..e8d01e0d 100644 --- a/utils/Math.js +++ b/utils/Math.js @@ -114,3 +114,13 @@ export function calculateAbsoluteAngles(vec) { pitch: Math.max(-90, Math.min(90, -Math.atan2(dy, Math.hypot(dx, dz)) * RAD_TO_DEG)), }; } + +export const finiteNumber = (value, fallback = 0) => { + const number = Number(value); + return Number.isFinite(number) ? number : fallback; +}; + +export const formatRoundedNumber = (value) => { + if (!Number.isFinite(value)) return '0'; + return String(Math.round(value)).replace(/\B(?=(\d{3})+(?!\d))/g, ','); +}; diff --git a/utils/NumberUtils.js b/utils/NumberUtils.js deleted file mode 100644 index b7a2e53d..00000000 --- a/utils/NumberUtils.js +++ /dev/null @@ -1,9 +0,0 @@ -export const finiteNumber = (value, fallback = 0) => { - const number = Number(value); - return Number.isFinite(number) ? number : fallback; -}; - -export const formatRoundedNumber = (value) => { - if (!Number.isFinite(value)) return '0'; - return String(Math.round(value)).replace(/\B(?=(\d{3})+(?!\d))/g, ','); -}; diff --git a/utils/ScheduleTask.js b/utils/ScheduleTask.js index 3a54399d..e2bd5371 100644 --- a/utils/ScheduleTask.js +++ b/utils/ScheduleTask.js @@ -1,4 +1,4 @@ -import { finiteNumber } from './NumberUtils'; +import { finiteNumber } from './Math'; let currentTick = 0; let queuedTasks = []; diff --git a/utils/Utils.js b/utils/Utils.js index 58239067..9cbdb255 100644 --- a/utils/Utils.js +++ b/utils/Utils.js @@ -1,4 +1,3 @@ -import { chat } from './Chat'; import { BP, Vec3d } from './Constants'; import { ClientboundSystemChatPacket } from './Packets'; import { getArea } from './TabListUtils'; @@ -18,7 +17,6 @@ const readConfig = (fileName) => { try { return JSON.parse(content); } catch (error) { - chat('Config read error for ' + fileName + ': ' + error.message); console.error('V5 Caught error' + error + error.stack); return {}; } @@ -40,7 +38,6 @@ export function writeConfigFile(fileName, data) { configCache.set(fileName, { data, timestamp: Date.now() }); return true; } catch (error) { - chat('Config write error for ' + fileName + ': ' + error.message); console.error('V5 Caught error' + error + error.stack); return false; } diff --git a/utils/pathfinder/EtherwarpPathfinder.js b/utils/pathfinder/EtherwarpPathfinder.js index ba3a0b2e..95fe8fd6 100644 --- a/utils/pathfinder/EtherwarpPathfinder.js +++ b/utils/pathfinder/EtherwarpPathfinder.js @@ -2,7 +2,7 @@ import { sendPathfinderMessage } from '../Chat'; import { MCHand, Vec3d } from '../Constants'; import { ClientboundPingPacket, ServerboundUseItemPacket } from '../Packets'; import { findItemInHotbar, setItemSlot } from '../player/Inventory'; -import { finiteNumber } from '../NumberUtils'; +import { finiteNumber } from '../Math'; import { applyToPlayer } from '../player/RotationGCD'; import { getPing } from '../player/ServerInfo'; import { ScheduleTask } from '../ScheduleTask'; diff --git a/utils/pathfinder/PathWalker/PathMovement.js b/utils/pathfinder/PathWalker/PathMovement.js index b419b1d4..16b31380 100644 --- a/utils/pathfinder/PathWalker/PathMovement.js +++ b/utils/pathfinder/PathWalker/PathMovement.js @@ -1,4 +1,4 @@ -import { finiteNumber } from '../../NumberUtils'; +import { finiteNumber } from '../../Math'; import { onPathTick } from '../PathExecutor'; let forceJumpTicks = 0; diff --git a/utils/pathfinder/PathWalker/PathPrediction.js b/utils/pathfinder/PathWalker/PathPrediction.js index d0fd0094..066cf9be 100644 --- a/utils/pathfinder/PathWalker/PathPrediction.js +++ b/utils/pathfinder/PathWalker/PathPrediction.js @@ -1,4 +1,4 @@ -import { finiteNumber } from '../../NumberUtils'; +import { finiteNumber } from '../../Math'; function getCurrentMotion() { if (!Player.getPlayer()) { diff --git a/utils/pathfinder/SwiftIntegration.js b/utils/pathfinder/SwiftIntegration.js index 19df4783..5babd93b 100644 --- a/utils/pathfinder/SwiftIntegration.js +++ b/utils/pathfinder/SwiftIntegration.js @@ -1,4 +1,4 @@ -import { finiteNumber } from '../NumberUtils'; +import { finiteNumber } from '../Math'; const readPointArray = (values) => { const points = []; From 92dbcc60a2da898e841b92b631c0c1a6d968be10 Mon Sep 17 00:00:00 2001 From: rdbtCVS <87152661+rdbtCVS@users.noreply.github.com> Date: Mon, 3 Aug 2026 00:21:36 +0100 Subject: [PATCH 3/5] refactor shared overlay rendering --- gui/OverlayRenderers.js | 178 ++++++++++++++++++++++++ gui/OverlayUtils.js | 195 ++++----------------------- modules/other/PeltMacro.js | 6 +- modules/other/SunGeckoMacro.js | 6 +- modules/skills/StridersurferMacro.js | 6 +- modules/visuals/HUD.js | 135 ++----------------- modules/visuals/MusicOverlay.js | 109 +++------------ utils/Constants.js | 1 - utils/MacroState.js | 2 + 9 files changed, 241 insertions(+), 397 deletions(-) create mode 100644 gui/OverlayRenderers.js diff --git a/gui/OverlayRenderers.js b/gui/OverlayRenderers.js new file mode 100644 index 00000000..81f8531c --- /dev/null +++ b/gui/OverlayRenderers.js @@ -0,0 +1,178 @@ +import { getPing, getPingColor, getTPS, getTpsColor } from '../utils/player/ServerInfo'; +import { BORDER_WIDTH, colorWithAlpha, CORNER_RADIUS, drawRoundedRectangleWithBorder, drawText, FontSizes, getTextWidth, THEME } from './Utils'; + +const STATS_GAPS = (scale) => [2 * scale, scale, 2 * scale]; + +export const clamp = (value, min, max) => Math.max(min, Math.min(max, value)); +export const clampOverlayToScreen = (overlay, sw, sh) => ({ + x: clamp(overlay.x, 0, Math.max(0, sw - overlay.width)), + y: clamp(overlay.y, 0, Math.max(0, sh - overlay.height)), +}); + +export const getStatsHudLines = () => { + const fps = Client.getFPS(); + const ping = getPing(); + const tps = getTPS(); + return [ + { label: 'FPS', value: String(fps), color: THEME.TEXT }, + { label: 'Ping', value: `${ping}ms`, color: (0xff000000 | getPingColor(ping)) >>> 0 }, + { label: 'TPS', value: tps.toFixed(2), color: (0xff000000 | getTpsColor(tps)) >>> 0 }, + ]; +}; + +export function getStatsHudBounds(scale, lines = getStatsHudLines()) { + const pad = 6 * scale; + const fontSize = FontSizes.MEDIUM * 1.25 * scale; + const separatorWidth = getTextWidth(' | ', fontSize); + const gaps = STATS_GAPS(scale); + const slotWidths = lines.map( + (line, index) => getTextWidth(`${line.label}:`, fontSize) + gaps[index] + getTextWidth(['999', '999ms', '20.00'][index], fontSize) + ); + return { width: pad * 2 + slotWidths.reduce((total, width) => total + width, 0) + separatorWidth * (lines.length - 1), height: pad * 2 + fontSize }; +} + +export function drawStatsHud(overlay, lines = getStatsHudLines()) { + const scale = overlay.scale; + const pad = 6 * scale; + const fontSize = FontSizes.MEDIUM * 1.25 * scale; + const separator = ' | '; + const separatorWidth = getTextWidth(separator, fontSize); + const gaps = STATS_GAPS(scale); + const slotWidths = lines.map( + (line, index) => getTextWidth(`${line.label}:`, fontSize) + gaps[index] + getTextWidth(['999', '999ms', '20.00'][index], fontSize) + ); + + drawRoundedRectangleWithBorder({ + x: overlay.x, + y: overlay.y, + width: overlay.width, + height: overlay.height, + radius: CORNER_RADIUS * 0.6 * scale, + color: THEME.BG_COMPONENT, + borderWidth: BORDER_WIDTH * scale, + borderColor: THEME.BORDER, + }); + + let x = overlay.x + pad; + const centerY = overlay.y + overlay.height / 2; + lines.forEach((line, index) => { + const label = `${line.label}:`; + drawText(label, x, centerY, fontSize, THEME.TEXT_MUTED, 17); + drawText(String(line.value), x + getTextWidth(label, fontSize) + gaps[index], centerY, fontSize, line.color, 17); + x += slotWidths[index]; + if (index < lines.length - 1) { + drawText(separator, x, centerY, fontSize, colorWithAlpha(THEME.TEXT_MUTED, 0.6), 17); + x += separatorWidth; + } + }); +} + +export function getInventoryHudBounds(scale) { + const pad = 6 * scale; + const slot = 18 * scale; + return { width: pad * 2 + 9 * slot, height: pad * 2 + 4 * slot + 4 * scale }; +} + +export function drawInventoryHudBackground(overlay) { + const scale = overlay.scale; + const pad = 6 * scale; + const slot = 18 * scale; + const gap = 4 * scale; + const rowWidth = 9 * slot; + const separatorY = overlay.y + pad + 3 * slot + gap / 2 - Math.max(1, scale) / 2; + const centerColor = colorWithAlpha(THEME.ACCENT, 0.3); + const edgeColor = colorWithAlpha(THEME.ACCENT, 0); + + drawRoundedRectangleWithBorder({ + x: overlay.x, + y: overlay.y, + width: overlay.width, + height: overlay.height, + radius: CORNER_RADIUS * 0.55 * scale, + color: THEME.BG_COMPONENT, + borderWidth: BORDER_WIDTH * scale, + borderColor: THEME.BORDER, + }); + NVG.drawGradientRect(overlay.x + pad, separatorY, rowWidth / 2, Math.max(1, scale), edgeColor, centerColor, 'LeftToRight', 0); + NVG.drawGradientRect(overlay.x + pad + rowWidth / 2, separatorY, rowWidth / 2, Math.max(1, scale), centerColor, edgeColor, 'LeftToRight', 0); +} + +export function getMusicOverlayBounds(scale, songName) { + const padding = 12 * scale; + const imageSize = 55 * scale; + return { width: Math.max(200 * scale, getTextWidth(songName, FontSizes.MEDIUM * 1.3 * scale) + imageSize + padding * 4), height: 90 * scale }; +} + +export function drawMusicOverlay({ overlay, songName, currentTime, totalTime, progress = 0, titleColor = THEME.TEXT_MUTED, drawArtwork }) { + const scale = overlay.scale; + const padding = 12 * scale; + const imageSize = 55 * scale; + const titleFontSize = FontSizes.MEDIUM * 1.3 * scale; + const timerFontSize = FontSizes.MEDIUM * 0.85 * scale; + const barHeight = 4 * scale; + const imageX = overlay.x + overlay.width - imageSize - padding; + const imageY = overlay.y + padding; + + drawRoundedRectangleWithBorder({ + x: overlay.x, + y: overlay.y, + width: overlay.width, + height: overlay.height, + radius: CORNER_RADIUS * 0.6 * scale, + color: THEME.BG_COMPONENT, + borderWidth: BORDER_WIDTH * scale, + borderColor: THEME.BORDER, + }); + if (drawArtwork) drawArtwork(imageX, imageY, imageSize, titleFontSize); + else { + drawRoundedRectangleWithBorder({ + x: imageX, + y: imageY, + width: imageSize, + height: imageSize, + radius: CORNER_RADIUS * 0.5 * scale, + color: THEME.BG_INSET, + borderWidth: 0, + borderColor: 0, + }); + const placeholder = songName === 'Searching for Media...' ? '...' : '?'; + drawText( + placeholder, + imageX + imageSize / 2 - getTextWidth(placeholder, titleFontSize) / 2, + imageY + imageSize / 2 - titleFontSize / 2.5, + titleFontSize, + THEME.TEXT_MUTED, + 16 + ); + } + + drawText(songName, overlay.x + padding, overlay.y + padding + titleFontSize, titleFontSize, titleColor, 16); + const gap = 4 * scale; + const barStartX = overlay.x + padding + getTextWidth(currentTime, timerFontSize) + gap; + const barWidth = overlay.x + overlay.width - padding - getTextWidth(totalTime, timerFontSize) - gap - barStartX; + const barY = overlay.y + overlay.height - padding - barHeight * 0.8; + const timerY = barY + barHeight / 2; + drawText(currentTime, overlay.x + padding, timerY, timerFontSize, THEME.TEXT_MUTED, 16); + drawText(totalTime, overlay.x + overlay.width - padding - getTextWidth(totalTime, timerFontSize), timerY, timerFontSize, THEME.TEXT_MUTED, 16); + drawRoundedRectangleWithBorder({ + x: barStartX, + y: barY, + width: barWidth, + height: barHeight, + radius: barHeight / 2, + color: THEME.BG_INSET, + borderWidth: 0, + borderColor: 0, + }); + if (progress > 0) + drawRoundedRectangleWithBorder({ + x: barStartX, + y: barY, + width: Math.max(0, barWidth * progress), + height: barHeight, + radius: barHeight / 2, + color: THEME.ACCENT, + borderWidth: 0, + borderColor: 0, + }); +} diff --git a/gui/OverlayUtils.js b/gui/OverlayUtils.js index 7bfc74e1..10e437bc 100644 --- a/gui/OverlayUtils.js +++ b/gui/OverlayUtils.js @@ -16,6 +16,15 @@ import { } from './Utils'; import { GuiState, Overlays } from './core/GuiState'; import { getPing, getPingColor, getTPS, getTpsColor } from '../utils/player/ServerInfo'; +import { + drawInventoryHudBackground, + drawMusicOverlay, + drawStatsHud, + getInventoryHudBounds, + getMusicOverlayBounds, + getStatsHudBounds, + getStatsHudLines, +} from './OverlayRenderers'; const { loadSettings } = require('./GuiSave'); @@ -810,185 +819,33 @@ class OverlayUtils { } drawHudStatsPreview(sw, sh) { - const s = this.hudSettings.stats.scale; - const pad = 6 * s; - const fontSize = FontSizes.MEDIUM * 1.25 * s; - const lines = this.getHudStatsLines(); - const separator = ' | '; - const separatorWidth = getTextWidth(separator, fontSize); - const gaps = [2 * s, s, 2 * s]; - const valueSlots = ['999', '999ms', '20.00']; - const slotWidths = lines.map((l, index) => getTextWidth(`${l.label}:`, fontSize) + gaps[index] + getTextWidth(valueSlots[index], fontSize)); - const totalWidth = slotWidths.reduce((total, width) => total + width, 0) + separatorWidth * (lines.length - 1); - - const width = pad * 2 + totalWidth; - const height = pad * 2 + fontSize; - - const clamped = this.clampToScreen(this.hudSettings.stats.x, this.hudSettings.stats.y, width, height, sw, sh); - this.hudSettings.stats.x = clamped.x; - this.hudSettings.stats.y = clamped.y; - - const bg = THEME.BG_COMPONENT; - const border = THEME.BORDER; - drawRoundedRectangleWithBorder({ - x: clamped.x, - y: clamped.y, - width, - height, - radius: CORNER_RADIUS * 0.6 * s, - color: bg, - borderWidth: BORDER_WIDTH * s, - borderColor: border, - }); - - const labelColor = THEME.TEXT_MUTED; - const separatorColor = colorWithAlpha(THEME.TEXT_MUTED, 0.6); - const centerY = clamped.y + height / 2; - let x = clamped.x + pad; - - lines.forEach((l, index) => { - const label = `${l.label}:`; - const value = String(l.value); - - drawText(label, x, centerY, fontSize, labelColor, 17); - drawText(value, x + getTextWidth(label, fontSize) + gaps[index], centerY, fontSize, l.color, 17); - - x += slotWidths[index]; - - if (index < lines.length - 1) { - drawText(separator, x, centerY, fontSize, separatorColor, 17); - x += separatorWidth; - } - }); - - return { x: clamped.x, y: clamped.y, width, height }; + const lines = getStatsHudLines(); + const overlay = { ...this.hudSettings.stats, ...getStatsHudBounds(this.hudSettings.stats.scale, lines) }; + Object.assign(this.hudSettings.stats, this.clampToScreen(overlay.x, overlay.y, overlay.width, overlay.height, sw, sh)); + Object.assign(overlay, this.hudSettings.stats); + drawStatsHud(overlay, lines); + return overlay; } drawHudInventoryPreview(sw, sh) { - const s = this.hudSettings.inventory.scale; - const cols = 9; - const mainRows = 3; - const pad = 6 * s; - const slot = 18 * s; - const gap = 4 * s; - const width = pad * 2 + cols * slot; - const height = pad * 2 + mainRows * slot + gap + slot; - - const clamped = this.clampToScreen(this.hudSettings.inventory.x, this.hudSettings.inventory.y, width, height, sw, sh); - this.hudSettings.inventory.x = clamped.x; - this.hudSettings.inventory.y = clamped.y; - - const bg = THEME.BG_COMPONENT; - const border = THEME.BORDER; - drawRoundedRectangleWithBorder({ - x: clamped.x, - y: clamped.y, - width, - height, - radius: CORNER_RADIUS * 0.55 * s, - color: bg, - borderWidth: BORDER_WIDTH * s, - borderColor: border, - }); - - const separatorThickness = Math.max(1, 1 * s); - const gridStartX = clamped.x + pad; - const mainStartY = clamped.y + pad; - const rowWidth = cols * slot; - const mainHotbarSeparatorY = mainStartY + mainRows * slot + gap / 2 - separatorThickness / 2; - const halfWidth = rowWidth / 2; - const centerColor = colorWithAlpha(THEME.ACCENT, 0.3); - const edgeColor = colorWithAlpha(THEME.ACCENT, 0); - - NVG.drawGradientRect(gridStartX, mainHotbarSeparatorY, halfWidth, separatorThickness, edgeColor, centerColor, 'LeftToRight', 0); - NVG.drawGradientRect(gridStartX + halfWidth, mainHotbarSeparatorY, halfWidth, separatorThickness, centerColor, edgeColor, 'LeftToRight', 0); - - return { x: clamped.x, y: clamped.y, width, height }; + const overlay = { ...this.hudSettings.inventory, ...getInventoryHudBounds(this.hudSettings.inventory.scale) }; + Object.assign(this.hudSettings.inventory, this.clampToScreen(overlay.x, overlay.y, overlay.width, overlay.height, sw, sh)); + Object.assign(overlay, this.hudSettings.inventory); + drawInventoryHudBackground(overlay); + return overlay; } drawMusicPreview(sw, sh) { - const s = this.musicSettings.scale || 1.0; const songName = 'Searching for Media...'; - const timeCur = '--:--'; - const timeMax = '--:--'; - const padding = 12 * s; - const imageSize = 55 * s; - const titleFontSize = FontSizes.MEDIUM * 1.3 * s; - const timerFontSize = FontSizes.MEDIUM * 0.85 * s; - const barHeight = 4 * s; - const nameWidth = getTextWidth(songName, titleFontSize); - const width = Math.max(200 * s, nameWidth + imageSize + padding * 4); - const height = 90 * s; - const clamped = this.clampToScreen(this.musicSettings.x, this.musicSettings.y, width, height, sw, sh); - this.musicSettings.x = clamped.x; - this.musicSettings.y = clamped.y; - - const bg = THEME.BG_COMPONENT; - const border = THEME.BORDER; - - drawRoundedRectangleWithBorder({ - x: clamped.x, - y: clamped.y, - width, - height, - radius: CORNER_RADIUS * 0.6 * s, - color: bg, - borderWidth: BORDER_WIDTH * s, - borderColor: border, - }); - - const imgX = clamped.x + width - imageSize - padding; - const imgY = clamped.y + padding; - drawRoundedRectangleWithBorder({ - x: imgX, - y: imgY, - width: imageSize, - height: imageSize, - radius: CORNER_RADIUS * 0.5 * s, - color: THEME.BG_INSET, - borderWidth: 0, - borderColor: 0, - }); - - const qWidth = getTextWidth('...', titleFontSize); - drawText('...', imgX + imageSize / 2 - qWidth / 2, imgY + imageSize / 2 - titleFontSize / 2.5, titleFontSize, THEME.TEXT_MUTED, 16); - drawText(songName, clamped.x + padding, clamped.y + padding + titleFontSize, titleFontSize, THEME.TEXT_MUTED, 16); - - const curTimeWidth = getTextWidth(timeCur, timerFontSize); - const maxTimeWidth = getTextWidth(timeMax, timerFontSize); - const textToBarGap = 4 * s; - const barStartX = clamped.x + padding + curTimeWidth + textToBarGap; - const barEndX = clamped.x + width - padding - maxTimeWidth - textToBarGap; - const barWidth = barEndX - barStartX; - const barY = clamped.y + height - padding - barHeight * 0.8; - const timerY = barY + barHeight / 2 - timerFontSize / 2.5; - - drawText(timeCur, clamped.x + padding, timerY + timerFontSize / 2.5, timerFontSize, THEME.TEXT_MUTED, 16); - drawText(timeMax, clamped.x + width - padding - maxTimeWidth, timerY + timerFontSize / 2.5, timerFontSize, THEME.TEXT_MUTED, 16); - - drawRoundedRectangleWithBorder({ - x: barStartX, - y: barY, - width: barWidth, - height: barHeight, - radius: barHeight / 2, - color: THEME.BG_INSET, - borderWidth: 0, - borderColor: 0, - }); - - return { x: clamped.x, y: clamped.y, width, height }; + const overlay = { ...this.musicSettings, ...getMusicOverlayBounds(this.musicSettings.scale || 1, songName) }; + Object.assign(this.musicSettings, this.clampToScreen(overlay.x, overlay.y, overlay.width, overlay.height, sw, sh)); + Object.assign(overlay, this.musicSettings); + drawMusicOverlay({ overlay, songName, currentTime: '--:--', totalTime: '--:--' }); + return overlay; } getHudStatsLines() { - const fps = Client.getFPS(); - const ping = getPing(); - const tps = getTPS(); - return [ - { label: 'FPS', value: String(fps), color: THEME.TEXT }, - { label: 'Ping', value: `${ping}ms`, color: (0xff000000 | getPingColor(ping)) >>> 0 }, - { label: 'TPS', value: tps.toFixed(2), color: (0xff000000 | getTpsColor(tps)) >>> 0 }, - ]; + return getStatsHudLines(); } openPositionsGUI() { diff --git a/modules/other/PeltMacro.js b/modules/other/PeltMacro.js index c78aa2e5..baa080a2 100644 --- a/modules/other/PeltMacro.js +++ b/modules/other/PeltMacro.js @@ -1,6 +1,6 @@ import { OverlayManager } from '../../gui/OverlayUtils'; import { MCHand, Vec3d } from '../../utils/Constants'; -import { getModuleElapsedMs } from '../../utils/MacroState'; +import { getModuleActiveHours } from '../../utils/MacroState'; import { ModuleBase } from '../../utils/ModuleBase'; import { ServerboundUseItemPacket } from '../../utils/Packets'; import { ScheduleTask } from '../../utils/ScheduleTask'; @@ -309,9 +309,7 @@ class PeltMacro extends ModuleBase { } getActiveHours() { - const elapsedMs = getModuleElapsedMs(this.name); - if (elapsedMs <= 0) return 0; - return elapsedMs / 3600000; + return getModuleActiveHours(this.name); } findPeltMob() { diff --git a/modules/other/SunGeckoMacro.js b/modules/other/SunGeckoMacro.js index 008cf84a..efd64943 100644 --- a/modules/other/SunGeckoMacro.js +++ b/modules/other/SunGeckoMacro.js @@ -1,6 +1,6 @@ import { OverlayManager } from '../../gui/OverlayUtils'; import { CombatBot } from '../combat/CombatBot'; -import { getModuleElapsedMs } from '../../utils/MacroState'; +import { getModuleActiveHours } from '../../utils/MacroState'; import { fastDistance, formatRoundedNumber } from '../../utils/Math'; import { ModuleBase } from '../../utils/ModuleBase'; import Pathfinder from '../../utils/pathfinder/PathFinder'; @@ -424,9 +424,7 @@ class SunGecko extends ModuleBase { } getActiveHours() { - const elapsedMs = getModuleElapsedMs(this.name); - if (elapsedMs <= 0) return 0; - return elapsedMs / 3600000; + return getModuleActiveHours(this.name); } setState(newState) { diff --git a/modules/skills/StridersurferMacro.js b/modules/skills/StridersurferMacro.js index 27f38cbb..f5893473 100644 --- a/modules/skills/StridersurferMacro.js +++ b/modules/skills/StridersurferMacro.js @@ -1,6 +1,6 @@ import { OverlayManager } from '../../gui/OverlayUtils'; import { ArmorStandEntity } from '../../utils/Constants'; -import { getModuleElapsedMs } from '../../utils/MacroState'; +import { getModuleActiveHours } from '../../utils/MacroState'; import { formatRoundedNumber, wrapTo180 } from '../../utils/Math'; import { ModuleBase } from '../../utils/ModuleBase'; import { clickItem, closeInventory, setItemSlot } from '../../utils/player/Inventory'; @@ -427,9 +427,7 @@ class StridersurferMacro extends ModuleBase { } getActiveHours() { - const elapsedMs = getModuleElapsedMs(this.name); - if (elapsedMs <= 0) return 0; - return elapsedMs / 3600000; + return getModuleActiveHours(this.name); } getStepDescription() { diff --git a/modules/visuals/HUD.js b/modules/visuals/HUD.js index dee05433..57809c7d 100644 --- a/modules/visuals/HUD.js +++ b/modules/visuals/HUD.js @@ -1,7 +1,12 @@ -import { BORDER_WIDTH, CORNER_RADIUS, FontSizes, THEME, colorWithAlpha, drawRoundedRectangleWithBorder, drawText, getTextWidth } from '../../gui/Utils'; +import { + drawInventoryHudBackground as renderInventoryHudBackground, + drawStatsHud as renderStatsHud, + getInventoryHudBounds, + getStatsHudBounds, + getStatsHudLines, +} from '../../gui/OverlayRenderers'; import { ModuleBase } from '../../utils/ModuleBase'; import { getConfigFile, writeConfigFile } from '../../utils/Utils'; -import { getPing, getPingColor, getTPS, getTpsColor } from '../../utils/player/ServerInfo'; import { OverlayManager } from '../../gui/OverlayUtils'; import { GuiState } from '../../gui/core/GuiState'; @@ -109,55 +114,20 @@ class HUD extends ModuleBase { const maxX = Math.max(0, sw - overlay.width); const maxY = Math.max(0, sh - overlay.height); - overlay.x = this.clamp(overlay.x, 0, maxX); - overlay.y = this.clamp(overlay.y, 0, maxY); - } - - getStatsLines() { - const fps = Client.getFPS(); - const ping = getPing(); - const tps = getTPS(); - - return [ - { label: 'FPS', value: String(fps), color: THEME.TEXT }, - { label: 'Ping', value: `${ping}ms`, color: (0xff000000 | getPingColor(ping)) >>> 0 }, - { label: 'TPS', value: tps.toFixed(2), color: (0xff000000 | getTpsColor(tps)) >>> 0 }, - ]; + overlay.x = Math.max(0, Math.min(maxX, overlay.x)); + overlay.y = Math.max(0, Math.min(maxY, overlay.y)); } recalcStatsBounds() { const o = this.stats; - const s = o.scale; - const pad = 6 * s; - const fontSize = FontSizes.MEDIUM * 1.25 * s; - - const lines = this.getStatsLines(); - const separator = ' | '; - const separatorWidth = getTextWidth(separator, fontSize); - const gaps = [2 * s, s, 2 * s]; - const valueSlots = ['999', '999ms', '20.00']; - const slotWidths = lines.map((l, index) => getTextWidth(`${l.label}:`, fontSize) + gaps[index] + getTextWidth(valueSlots[index], fontSize)); - const totalWidth = slotWidths.reduce((total, width) => total + width, 0) + separatorWidth * (lines.length - 1); - - o.width = pad * 2 + totalWidth; - o.height = pad * 2 + fontSize; + Object.assign(o, getStatsHudBounds(o.scale)); this.clampOverlayToScreen(o); } recalcInventoryBounds() { const o = this.inventory; - const s = o.scale; - - const cols = 9; - const mainRows = 3; - - const pad = 6 * s; - const slot = 18 * s; - const gap = 4 * s; - - o.width = pad * 2 + cols * slot; - o.height = pad * 2 + mainRows * slot + gap + slot; + Object.assign(o, getInventoryHudBounds(o.scale)); this.clampOverlayToScreen(o); } @@ -191,90 +161,11 @@ class HUD extends ModuleBase { } drawStatsHud() { - const o = this.stats; - const s = o.scale; - const pad = 6 * s; - const fontSize = FontSizes.MEDIUM * 1.25 * s; - - const bg = THEME.BG_COMPONENT; - const border = THEME.BORDER; - - drawRoundedRectangleWithBorder({ - x: o.x, - y: o.y, - width: o.width, - height: o.height, - radius: CORNER_RADIUS * 0.6 * s, - color: bg, - borderWidth: BORDER_WIDTH * s, - borderColor: border, - }); - - const labelColor = THEME.TEXT_MUTED; - const separatorColor = colorWithAlpha(THEME.TEXT_MUTED, 0.6); - const lines = this.getStatsLines(); - - const centerY = o.y + o.height / 2; - let x = o.x + pad; - - const separator = ' | '; - const separatorWidth = getTextWidth(separator, fontSize); - const gaps = [2 * s, s, 2 * s]; - const valueSlots = ['999', '999ms', '20.00']; - const slotWidths = lines.map((l, index) => getTextWidth(`${l.label}:`, fontSize) + gaps[index] + getTextWidth(valueSlots[index], fontSize)); - - lines.forEach((l, index) => { - const label = `${l.label}:`; - const value = String(l.value); - - drawText(label, x, centerY, fontSize, labelColor, 17); - drawText(value, x + getTextWidth(label, fontSize) + gaps[index], centerY, fontSize, l.color, 17); - - x += slotWidths[index]; - - if (index < lines.length - 1) { - drawText(separator, x, centerY, fontSize, separatorColor, 17); - x += separatorWidth; - } - }); + renderStatsHud(this.stats, getStatsHudLines()); } drawInventoryHudBackground() { - const o = this.inventory; - const s = o.scale; - - const bg = THEME.BG_COMPONENT; - const border = THEME.BORDER; - - drawRoundedRectangleWithBorder({ - x: o.x, - y: o.y, - width: o.width, - height: o.height, - radius: CORNER_RADIUS * 0.55 * s, - color: bg, - borderWidth: BORDER_WIDTH * s, - borderColor: border, - }); - - const cols = 9; - const mainRows = 3; - const pad = 6 * s; - const slot = 18 * s; - const gap = 4 * s; - const separatorThickness = Math.max(1, 1 * s); - - const gridStartX = o.x + pad; - const mainStartY = o.y + pad; - const rowWidth = cols * slot; - - const mainHotbarSeparatorY = mainStartY + mainRows * slot + gap / 2 - separatorThickness / 2; - const halfWidth = rowWidth / 2; - const centerColor = colorWithAlpha(THEME.ACCENT, 0.3); - const edgeColor = colorWithAlpha(THEME.ACCENT, 0); - - NVG.drawGradientRect(gridStartX, mainHotbarSeparatorY, halfWidth, separatorThickness, edgeColor, centerColor, 'LeftToRight', 0); - NVG.drawGradientRect(gridStartX + halfWidth, mainHotbarSeparatorY, halfWidth, separatorThickness, centerColor, edgeColor, 'LeftToRight', 0); + renderInventoryHudBackground(this.inventory); } drawInventoryHudItems() { diff --git a/modules/visuals/MusicOverlay.js b/modules/visuals/MusicOverlay.js index a170a3f0..0dfec96f 100644 --- a/modules/visuals/MusicOverlay.js +++ b/modules/visuals/MusicOverlay.js @@ -7,6 +7,7 @@ import { ModuleBase } from '../../utils/ModuleBase'; import { Executor } from '../../utils/ThreadExecutor'; import { Utils } from '../../utils/Utils'; import { OverlayManager } from '../../gui/OverlayUtils'; +import { clamp, drawMusicOverlay, getMusicOverlayBounds } from '../../gui/OverlayRenderers'; class Music extends ModuleBase { constructor() { @@ -30,7 +31,7 @@ class Music extends ModuleBase { this.x = savedX; this.y = savedY; - this.scale = Math.max(0.5, Math.min(3.0, savedScale)); + this.scale = clamp(savedScale, 0.5, 3.0); this.dynamicWidth = 200; this.baseHeight = 90; @@ -140,7 +141,7 @@ class Music extends ModuleBase { if (typeof latest.x === 'number') this.x = latest.x; if (typeof latest.y === 'number') this.y = latest.y; - if (typeof latest.scale === 'number') this.scale = Math.max(0.5, Math.min(3.0, latest.scale)); + if (typeof latest.scale === 'number') this.scale = clamp(latest.scale, 0.5, 3.0); this.positionConfig = latest; } @@ -162,102 +163,24 @@ class Music extends ModuleBase { const timeMax = playback.totalText; const progress = playback.progress; - const s = this.scale || 1.0; - const padding = 12 * s; - const imageSize = 55 * s; - const titleFontSize = FontSizes.MEDIUM * 1.3 * s; - const timerFontSize = FontSizes.MEDIUM * 0.85 * s; - const barHeight = 4 * s; - - const nameWidth = getTextWidth(songName, titleFontSize); - const minWidth = 200 * s; - this.dynamicWidth = Math.max(minWidth, nameWidth + imageSize + padding * 4); - this.baseHeight = 90 * s; - - const overflowRight = Math.max(0, this.x + this.dynamicWidth - sw); - const overlayX = Math.max(0, this.x - overflowRight); - - const titleColor = isSkeleton ? THEME.TEXT_MUTED : THEME.TEXT; - const timeColor = THEME.TEXT_MUTED; - const bg = THEME.BG_COMPONENT; - const border = THEME.BORDER; + const overlay = { x: this.x, y: this.y, scale: this.scale || 1.0, ...getMusicOverlayBounds(this.scale || 1.0, songName) }; + this.dynamicWidth = overlay.width; + this.baseHeight = overlay.height; + overlay.x = clamp(overlay.x, 0, Math.max(0, sw - overlay.width)); + this.x = overlay.x; try { NVG.beginFrame(sw, sh); - drawRoundedRectangleWithBorder({ - x: overlayX, - y: this.y, - width: this.dynamicWidth, - height: this.baseHeight, - radius: CORNER_RADIUS * 0.6 * s, - color: bg, - borderWidth: BORDER_WIDTH * s, - borderColor: border, + drawMusicOverlay({ + overlay, + songName, + currentTime: interpolatedTimeText, + totalTime: timeMax, + progress, + titleColor: isSkeleton ? THEME.TEXT_MUTED : THEME.TEXT, + drawArtwork: imageURL.length > 5 ? (x, y, size) => drawImageFromURL(imageURL, x, y, size, size, 6) : null, }); - - const imgX = overlayX + this.dynamicWidth - imageSize - padding; - const imgY = this.y + padding; - - if (imageURL.length > 5) { - drawImageFromURL(imageURL, imgX, imgY, imageSize, imageSize, 6); - } else { - drawRoundedRectangleWithBorder({ - x: imgX, - y: imgY, - width: imageSize, - height: imageSize, - radius: CORNER_RADIUS * 0.5 * s, - color: THEME.BG_INSET, - borderWidth: 0, - borderColor: 0, - }); - - const qText = isSkeleton ? '...' : '?'; - const qSize = titleFontSize; - const qWidth = getTextWidth(qText, qSize); - drawText(qText, imgX + imageSize / 2 - qWidth / 2, imgY + imageSize / 2 - qSize / 2.5, qSize, THEME.TEXT_MUTED, 16); - } - - drawText(songName, overlayX + padding, this.y + padding + titleFontSize, titleFontSize, titleColor, 16); - - const curTimeWidth = getTextWidth(interpolatedTimeText, timerFontSize); - const maxTimeWidth = getTextWidth(timeMax, timerFontSize); - const textToBarGap = 4 * s; - - const barStartX = overlayX + padding + curTimeWidth + textToBarGap; - const barEndX = overlayX + this.dynamicWidth - padding - maxTimeWidth - textToBarGap; - const barWidth = barEndX - barStartX; - - const barY = this.y + this.baseHeight - padding - barHeight * 0.8; - const timerY = barY + barHeight / 2 - timerFontSize / 2.5; - - drawText(interpolatedTimeText, overlayX + padding, timerY + timerFontSize / 2.5, timerFontSize, timeColor, 16); - drawText(timeMax, overlayX + this.dynamicWidth - padding - maxTimeWidth, timerY + timerFontSize / 2.5, timerFontSize, timeColor, 16); - - drawRoundedRectangleWithBorder({ - x: barStartX, - y: barY, - width: barWidth, - height: barHeight, - radius: barHeight / 2, - color: THEME.BG_INSET, - borderWidth: 0, - borderColor: 0, - }); - - if (progress > 0) { - drawRoundedRectangleWithBorder({ - x: barStartX, - y: barY, - width: Math.max(0, barWidth * progress), - height: barHeight, - radius: barHeight / 2, - color: THEME.ACCENT, - borderWidth: 0, - borderColor: 0, - }); - } } catch (e) { } finally { NVG.endFrame(); diff --git a/utils/Constants.js b/utils/Constants.js index a70924e4..d10383c0 100644 --- a/utils/Constants.js +++ b/utils/Constants.js @@ -23,7 +23,6 @@ export const URL = java.net.URL; const os = System.getProperty('os.name').toLowerCase(); export const isWindows = os.includes('win'); export const isLinux = os.includes('nux') || os.includes('nix'); -export const isMac = os.includes('mac'); export const globalAssetsDir = new File('./config/ChatTriggers/assets'); diff --git a/utils/MacroState.js b/utils/MacroState.js index f1bdc426..c659341a 100644 --- a/utils/MacroState.js +++ b/utils/MacroState.js @@ -88,6 +88,8 @@ export function getModuleElapsedMs(moduleName) { return moduleStart ? Date.now() - moduleStart : getLastDisableMeta(moduleName)?.durationMs || 0; } +export const getModuleActiveHours = (moduleName) => getModuleElapsedMs(moduleName) / 3600000; + function toggleLastUsedMacroFromUser() { const macroName = getLastActiveMacro(); if (!macroName) { From 923cb8f8838955a002a1c200dfdc90b6db9e44b8 Mon Sep 17 00:00:00 2001 From: rdbtCVS <87152661+rdbtCVS@users.noreply.github.com> Date: Mon, 3 Aug 2026 14:26:33 +0100 Subject: [PATCH 4/5] woops --- gui/GUI.js | 1 + 1 file changed, 1 insertion(+) diff --git a/gui/GUI.js b/gui/GUI.js index 834a61d5..9171a47d 100644 --- a/gui/GUI.js +++ b/gui/GUI.js @@ -1,3 +1,4 @@ +import './core/GuiEvents'; import './ProfileSettings'; import './ThemeSettings'; From adc35c031b486d4c89de0ab80e1787e65b128ebf Mon Sep 17 00:00:00 2001 From: rdbtCVS <87152661+rdbtCVS@users.noreply.github.com> Date: Mon, 3 Aug 2026 18:07:04 +0100 Subject: [PATCH 5/5] Update chat util naming scheme --- failsafes/AlertUtils.js | 10 ++++----- failsafes/impl/ChatMentionFailsafe.js | 4 ++-- failsafes/impl/PlayerGriefFailsafe.js | 6 +++--- failsafes/impl/RotationFailsafe.js | 12 +++++------ failsafes/impl/SlotChangeFailsafe.js | 4 ++-- failsafes/impl/TeleportFailsafe.js | 14 ++++++------ failsafes/impl/VelocityFailsafe.js | 6 +++--- modules/other/RatMacro.js | 4 ++-- utils/Chat.js | 14 +++++------- utils/NetworkUtils.js | 4 ++-- utils/Webhooks.js | 6 +++--- utils/backend/IRC.js | 16 +++++++------- utils/backend/WebSocket.js | 16 +++++++------- utils/pathfinder/EtherwarpPathfinder.js | 12 +++++------ utils/pathfinder/PathFinder.js | 24 ++++++++++----------- utils/pathfinder/PathWalker/PathAote.js | 12 +++++------ utils/pathfinder/PathWalker/PathJumps.js | 12 +++++------ utils/pathfinder/PathWalker/PathRecovery.js | 10 ++++----- 18 files changed, 91 insertions(+), 95 deletions(-) diff --git a/failsafes/AlertUtils.js b/failsafes/AlertUtils.js index b7bebd77..75495289 100644 --- a/failsafes/AlertUtils.js +++ b/failsafes/AlertUtils.js @@ -1,5 +1,5 @@ import { drawRect, drawText } from '../gui/Utils'; -import { sendFailsafeMessage } from '../utils/Chat'; +import { chatFailsafe } from '../utils/Chat'; import { File, globalAssetsDir } from '../utils/Constants'; import { getConfigFile, writeConfigFile } from '../utils/Utils'; import FailsafeUtils from './FailsafeUtils'; @@ -42,8 +42,8 @@ class AlertUtilsClass { triggerReaction() { if (this.isAlerting) return; - sendFailsafeMessage('Suspicious activity detected, reaction occuring!'); - sendFailsafeMessage(`Press &c&l${this.cancelKey}&r &fto disable the reaction`); + chatFailsafe('Suspicious activity detected, reaction occuring!'); + chatFailsafe(`Press &c&l${this.cancelKey}&r &fto disable the reaction`); this.isAlerting = true; this.playSound(); @@ -218,7 +218,7 @@ class AlertUtilsClass { this.cancelKeyBind.registerKeyPress(() => { if (!this.isAlerting) return; - sendFailsafeMessage('Reaction disabled due to keybind being pressed'); + chatFailsafe('Reaction disabled due to keybind being pressed'); this.disableReaction(); }); @@ -256,7 +256,7 @@ class AlertUtilsClass { GLFW.glfwFocusWindow(windowHandle); GLFW.glfwRequestWindowAttention(windowHandle); } catch (e) { - sendFailsafeMessage('GLFW error occured! report this. ' + e); + chatFailsafe('GLFW error occured! report this. ' + e); console.error(e); } } diff --git a/failsafes/impl/ChatMentionFailsafe.js b/failsafes/impl/ChatMentionFailsafe.js index 5fb12727..dbd1a09c 100644 --- a/failsafes/impl/ChatMentionFailsafe.js +++ b/failsafes/impl/ChatMentionFailsafe.js @@ -1,4 +1,4 @@ -import { sendFailsafeMessage } from '../../utils/Chat'; +import { chatFailsafe } from '../../utils/Chat'; import { Failsafe } from '../Failsafe'; import FailsafeUtils from '../FailsafeUtils'; import { ClientboundSystemChatPacket } from '../../utils/Packets'; @@ -51,7 +51,7 @@ class ChatMentionFailsafe extends Failsafe { const severity = result.isHigh ? 'high' : 'medium'; const embedColour = result.isHigh ? 16744448 : 16776960; - sendFailsafeMessage(`&c&lDetected blacklisted word - "${result.blockedWord}"!`); + chatFailsafe(`&c&lDetected blacklisted word - "${result.blockedWord}"!`); FailsafeUtils.incrementFailsafeIntensity(pressure); FailsafeUtils.sendFailsafeEmbed( 'Chat Mention', diff --git a/failsafes/impl/PlayerGriefFailsafe.js b/failsafes/impl/PlayerGriefFailsafe.js index d078707b..a9894a5c 100644 --- a/failsafes/impl/PlayerGriefFailsafe.js +++ b/failsafes/impl/PlayerGriefFailsafe.js @@ -1,4 +1,4 @@ -import { sendFailsafeMessage } from '../../utils/Chat'; +import { chatFailsafe } from '../../utils/Chat'; import { File, globalAssetsDir } from '../../utils/Constants'; import { Failsafe } from '../Failsafe'; import FailsafeUtils from '../FailsafeUtils'; @@ -69,7 +69,7 @@ class PlayerGriefFailsafe extends Failsafe { const lz = look.getZ(); if (Math.trunc(lx) === Math.trunc(px) && Math.trunc(ly) === Math.trunc(py) && Math.trunc(lz) === Math.trunc(pz)) { - sendFailsafeMessage(`&c&l${lookedName} is standing inside you!`); + chatFailsafe(`&c&l${lookedName} is standing inside you!`); FailsafeUtils.incrementFailsafeIntensity(120); FailsafeUtils.sendFailsafeEmbed('Player Grief', 'very high', `${lookedName} is standing inside you!`, 16711680); @@ -101,7 +101,7 @@ class PlayerGriefFailsafe extends Failsafe { if (distanceSq <= maxDistanceSq && distanceSq > 1) { const distance = Math.sqrt(distanceSq); - sendFailsafeMessage(`&c&l${playerName} is ${distance.toFixed(1)} blocks away from you!`); + chatFailsafe(`&c&l${playerName} is ${distance.toFixed(1)} blocks away from you!`); FailsafeUtils.incrementFailsafeIntensity(20); FailsafeUtils.sendFailsafeEmbed('Player Grief', 'medium', `${playerName} is ${distance.toFixed(1)} blocks away!`, 16776960); diff --git a/failsafes/impl/RotationFailsafe.js b/failsafes/impl/RotationFailsafe.js index 3da919f1..837608e6 100644 --- a/failsafes/impl/RotationFailsafe.js +++ b/failsafes/impl/RotationFailsafe.js @@ -1,4 +1,4 @@ -import { sendDebugMessage, sendFailsafeMessage } from '../../utils/Chat'; +import { chatDebug, chatFailsafe } from '../../utils/Chat'; import { getAngleDifference } from '../../utils/Math'; import { ClientboundPlayerPositionPacket } from '../../utils/Packets'; import { Failsafe } from '../Failsafe'; @@ -42,7 +42,7 @@ class RotationFailsafe extends Failsafe { // todo: this isnt what a null rotation packet is, which retard made these failsafes? if (yawDiff === 0 && pitchDiff === 0) { - sendDebugMessage('null rotation packet ignored (yawDiff=0, pitchDiff=0)', false); + chatDebug('null rotation packet ignored (yawDiff=0, pitchDiff=0)', false); return; } @@ -68,10 +68,10 @@ class RotationFailsafe extends Failsafe { const { pressure, severity, color } = tiers.find((t) => totalRotation < t.limit); - sendFailsafeMessage(`&c&lYou were rotated by the server!`, false); - sendFailsafeMessage(`&c&lFrom: &r&7Yaw ${fromYaw.toFixed(2)} &f| &7Pitch ${fromPitch.toFixed(2)}`, false); - sendFailsafeMessage(`&c&lTo: &r&7Yaw ${toYaw.toFixed(2)} &f| &7Pitch ${toPitch.toFixed(2)}`, false); - sendFailsafeMessage(`&c&lTotal Rotation: &r&7${totalRotation.toFixed(2)}°`, true); + chatFailsafe(`&c&lYou were rotated by the server!`, false); + chatFailsafe(`&c&lFrom: &r&7Yaw ${fromYaw.toFixed(2)} &f| &7Pitch ${fromPitch.toFixed(2)}`, false); + chatFailsafe(`&c&lTo: &r&7Yaw ${toYaw.toFixed(2)} &f| &7Pitch ${toPitch.toFixed(2)}`, false); + chatFailsafe(`&c&lTotal Rotation: &r&7${totalRotation.toFixed(2)}°`, true); FailsafeUtils.incrementFailsafeIntensity(pressure); FailsafeUtils.sendFailsafeEmbed( diff --git a/failsafes/impl/SlotChangeFailsafe.js b/failsafes/impl/SlotChangeFailsafe.js index abf02ce0..1ee693ad 100644 --- a/failsafes/impl/SlotChangeFailsafe.js +++ b/failsafes/impl/SlotChangeFailsafe.js @@ -1,4 +1,4 @@ -import { sendFailsafeMessage } from '../../utils/Chat'; +import { chatFailsafe } from '../../utils/Chat'; import { ClientboundSetHeldSlotPacket } from '../../utils/Packets'; import { Failsafe } from '../Failsafe'; import FailsafeUtils from '../FailsafeUtils'; @@ -30,7 +30,7 @@ class SlotChangeFailsafe extends Failsafe { } onTrigger(fromSlot, toSlot) { - sendFailsafeMessage(`&c&lHeld slot has changed from ${fromSlot} to slot ${toSlot}!`); + chatFailsafe(`&c&lHeld slot has changed from ${fromSlot} to slot ${toSlot}!`); FailsafeUtils.incrementFailsafeIntensity(50); FailsafeUtils.sendFailsafeEmbed('Slot Change', 'high', `Slot changed from ${fromSlot} to ${toSlot}!`, 16744448); } diff --git a/failsafes/impl/TeleportFailsafe.js b/failsafes/impl/TeleportFailsafe.js index 9a84db13..80820390 100644 --- a/failsafes/impl/TeleportFailsafe.js +++ b/failsafes/impl/TeleportFailsafe.js @@ -1,4 +1,4 @@ -import { sendDebugMessage, sendFailsafeMessage } from '../../utils/Chat'; +import { chatDebug, chatFailsafe } from '../../utils/Chat'; import { getAngleDifference } from '../../utils/Math'; import { ServerboundUseItemPacket, ClientboundPlayerPositionPacket, ServerboundChatCommandPacket } from '../../utils/Packets'; import PathConfig from '../../utils/pathfinder/PathConfig'; @@ -39,7 +39,7 @@ class TeleportFailsafe extends Failsafe { const command = packet.command().toLowerCase(); if (command.includes('warp')) { lastCommandTime = Date.now(); - sendDebugMessage(`warp command used, awaiting warp-point teleport ignore`, false); + chatDebug(`warp command used, awaiting warp-point teleport ignore`, false); pendingWarpIgnore = true; if (pendingWarpIgnoreTimer) clearTimeout(pendingWarpIgnoreTimer); pendingWarpIgnoreTimer = setTimeout(() => { @@ -184,17 +184,17 @@ class TeleportFailsafe extends Failsafe { } handleNullPacket(x, y, z) { - sendFailsafeMessage('&c&lNULL PACKET DETECTED, DO NOT REACT!', false); + chatFailsafe('&c&lNULL PACKET DETECTED, DO NOT REACT!', false); FailsafeUtils.sendFailsafeEmbed('TP', 'very high - null packet', `You just recieved a null packet to ${x}, ${y}, ${z}!`, 16711680); } onTrigger(fX, fY, fZ, nX, nY, nZ, dist) { const { pressure, severity, color } = TELEPORT_TIERS.find((t) => dist < t.threshold); - sendFailsafeMessage(`&l&cTeleport Detected!`, false); - sendFailsafeMessage(`&c&lFrom: &r&7${fX.toFixed(2)}&f, &7${fY.toFixed(2)}&f, &7${fZ.toFixed(2)}&f`, false); - sendFailsafeMessage(`&c&lTo: &r&7${nX.toFixed(2)}&f, &7${nY.toFixed(2)}&f, &7${nZ.toFixed(2)}&f`, false); - sendFailsafeMessage(`&c&lTotal Blocks: &r&7${dist.toFixed(0)}`, true); + chatFailsafe(`&l&cTeleport Detected!`, false); + chatFailsafe(`&c&lFrom: &r&7${fX.toFixed(2)}&f, &7${fY.toFixed(2)}&f, &7${fZ.toFixed(2)}&f`, false); + chatFailsafe(`&c&lTo: &r&7${nX.toFixed(2)}&f, &7${nY.toFixed(2)}&f, &7${nZ.toFixed(2)}&f`, false); + chatFailsafe(`&c&lTotal Blocks: &r&7${dist.toFixed(0)}`, true); FailsafeUtils.incrementFailsafeIntensity(pressure); FailsafeUtils.sendFailsafeEmbed( diff --git a/failsafes/impl/VelocityFailsafe.js b/failsafes/impl/VelocityFailsafe.js index 806a5391..c9e7d665 100644 --- a/failsafes/impl/VelocityFailsafe.js +++ b/failsafes/impl/VelocityFailsafe.js @@ -1,4 +1,4 @@ -import { sendDebugMessage, sendFailsafeMessage } from '../../utils/Chat'; +import { chatDebug, chatFailsafe } from '../../utils/Chat'; import { ClientboundSetEntityMotionPacket } from '../../utils/Packets'; import { Failsafe } from '../Failsafe'; import FailsafeUtils from '../FailsafeUtils'; @@ -65,7 +65,7 @@ class VelocityFailsafe extends Failsafe { const roundedVelocity = Math.round(velocity); if (blockBelow && !blockBelow.includes('air') && (roundedVelocity === 1 || roundedVelocity === 0)) { - sendDebugMessage('disabling fall velocity packet'); + chatDebug('disabling fall velocity packet'); this._setDisabled(1000); } @@ -82,7 +82,7 @@ class VelocityFailsafe extends Failsafe { onTrigger(speed) { const { pressure, severity, color } = VELOCITY_TIERS.find((t) => speed < t.threshold) || VELOCITY_TIERS[VELOCITY_TIERS.length - 1]; - sendFailsafeMessage(`&c&lVelocity failsafe triggered! Velocity: ${speed.toFixed(0)}`); + chatFailsafe(`&c&lVelocity failsafe triggered! Velocity: ${speed.toFixed(0)}`); FailsafeUtils.incrementFailsafeIntensity(pressure); FailsafeUtils.sendFailsafeEmbed('Velocity', severity, `Velocity change detected: ${speed.toFixed(0)}`, color); } diff --git a/modules/other/RatMacro.js b/modules/other/RatMacro.js index 2eb427d8..84759b8e 100644 --- a/modules/other/RatMacro.js +++ b/modules/other/RatMacro.js @@ -1,7 +1,7 @@ //Vibecoded SLOP, STILL WORKS FINE :3 import { isDeveloperModeEnabled } from '../../utils/DeveloperModeState'; import { OverlayManager } from '../../gui/OverlayUtils'; -import { sendDebugMessage } from '../../utils/Chat'; +import { chatDebug } from '../../utils/Chat'; import { MCHand } from '../../utils/Constants'; import { finiteNumber, formatRoundedNumber } from '../../utils/Math'; import { ModuleBase } from '../../utils/ModuleBase'; @@ -148,7 +148,7 @@ class RatMacro extends ModuleBase { } debug(message) { - sendDebugMessage(`&6Rat Macro:&f ${message}`); + chatDebug(`&6Rat Macro:&f ${message}`); } setState(nextState, reason = null) { diff --git a/utils/Chat.js b/utils/Chat.js index 2f376409..17c37c6c 100644 --- a/utils/Chat.js +++ b/utils/Chat.js @@ -8,23 +8,19 @@ const sendGradient = (prefix, ...args) => { export const chat = (message) => sendGradient('V5 »', message); -export function sendDebugMessage(message) { +export function chatDebug(message) { if (isDeveloperModeEnabled()) sendGradient('V5 Debug »', message); } -export function sendFailsafeMessage(message, includeIntensity = true) { +export function chatFailsafe(message, includeIntensity = true) { sendGradient('V5 Failsafes »', message); if (includeIntensity) sendGradient('V5 Failsafes »', '&c&lCurrent intensity: ' + FailsafeUtils.getIntensity()); } -export const sendIrcMessage = (message) => sendGradient('IRC »', message); -export const sendPathfinderMessage = (message) => sendGradient('V5 Pathfinding »', message); +export const chatIrc = (message) => sendGradient('IRC »', message); +export const chatPathfinder = (message) => sendGradient('V5 Pathfinding »', message); -export function sendAnnouncement(message) { +export function chatAnnoucement(message) { if (!message) return; Client.getMinecraft().execute(() => GradientChat.sendGradientMsg('V5 Announcement »', 0xf4a261, 0xe76f51, message)); } - -export function logMessage(message) { - if (message) console.log('V5 » ' + message); -} diff --git a/utils/NetworkUtils.js b/utils/NetworkUtils.js index 7447bcb5..9e744582 100644 --- a/utils/NetworkUtils.js +++ b/utils/NetworkUtils.js @@ -1,4 +1,4 @@ -import { logMessage, chat } from './Chat'; +import { chat } from './Chat'; import { BufferedReader, File, InputStreamReader, Links, StandardCharsets, URL, globalAssetsDir } from './Constants'; import { downloadFile } from './FileUtils'; @@ -52,7 +52,7 @@ export const returnDiscord = (authToken) => { data = JSON.parse(responseText); } catch (e) { chat('Failed to parse Discord PFP data. Check console for error.'); - logMessage('Invalid JSON received: ' + responseText); + console.log('Invalid JSON received: ' + responseText); console.error('V5 Caught error' + e + e.stack); return; } diff --git a/utils/Webhooks.js b/utils/Webhooks.js index f2696213..aa02a558 100644 --- a/utils/Webhooks.js +++ b/utils/Webhooks.js @@ -1,4 +1,4 @@ -import { sendDebugMessage } from './Chat'; +import { chatDebug } from './Chat'; import { CLIENT_VERSION, Consumer, ScreenshotRecorder, URL } from './Constants'; import { executeAsync } from './ThreadExecutor'; import { area, getConfigFile, subArea, writeConfigFile } from './Utils'; @@ -28,7 +28,7 @@ class DiscordNotifier { } } catch (e) { console.error(e); - sendDebugMessage('Failed to initialize webhook settings.'); + chatDebug('Failed to initialize webhook settings.'); } } @@ -125,7 +125,7 @@ class DiscordNotifier { connection.getInputStream().close(); } catch (e) { console.error(e); - sendDebugMessage('Webhook transmission failed: ' + e); + chatDebug('Webhook transmission failed: ' + e); } }); } diff --git a/utils/backend/IRC.js b/utils/backend/IRC.js index da0e78ca..fa0c299c 100644 --- a/utils/backend/IRC.js +++ b/utils/backend/IRC.js @@ -1,4 +1,4 @@ -import { sendAnnouncement, sendIrcMessage } from '../Chat'; +import { chatAnnoucement, chatIrc } from '../Chat'; import { Categories } from '../../gui/categories/CategorySystem'; let ircEnabled = true; @@ -24,34 +24,34 @@ export function handleIRCMessage(data) { if (!ircEnabled) return; const sender = data.user || 'Unknown'; const message = `${data.msg ?? ''}`; - sendIrcMessage(`&9${sender}&r: ${message}`); + chatIrc(`&9${sender}&r: ${message}`); return true; } if (data.type === 'error') { - sendIrcMessage(`Error: ${data.code || 'Unknown'}`); + chatIrc(`Error: ${data.code || 'Unknown'}`); return true; } if (data.type === 'system') { if (data.code === 'PREFIX_UPDATED') { - sendIrcMessage('Your prefix has been changed'); + chatIrc('Your prefix has been changed'); } else if (data.code === 'MUTED') { const expiresAt = Number(data.mute_expires_at); if (Number.isFinite(expiresAt)) { - sendIrcMessage('You have been muted until ' + new Date(expiresAt * 1000).toISOString()); + chatIrc('You have been muted until ' + new Date(expiresAt * 1000).toISOString()); } else { - sendIrcMessage('You have been muted'); + chatIrc('You have been muted'); } } else { - sendIrcMessage(`System: ${data.code || ''}`); + chatIrc(`System: ${data.code || ''}`); } return true; } if (data.type === 'announcement') { if (!ircEnabled) return; - sendAnnouncement(`${data.msg ?? ''}`); + chatAnnoucement(`${data.msg ?? ''}`); return true; } diff --git a/utils/backend/WebSocket.js b/utils/backend/WebSocket.js index 5734dfac..37419931 100644 --- a/utils/backend/WebSocket.js +++ b/utils/backend/WebSocket.js @@ -1,5 +1,5 @@ import WebSocket from 'WebSocket'; -import { logMessage, sendIrcMessage } from '../Chat'; +import { chatIrc } from '../Chat'; import { Links } from '../Constants'; import { returnDiscord } from '../NetworkUtils'; import { ServerboundChatPacket } from '../Packets'; @@ -41,9 +41,9 @@ function handleSocketDisconnect({ code, reason, exception }) { if (exception) { console.error('WebSocket error:', exception); - sendIrcMessage('Connection error: ' + exception); + chatIrc('Connection error: ' + exception); } else { - logMessage(`Disconnected from chat server (code ${code}, reason: ${reason})`); + console.log(`Disconnected from chat server (code ${code}, reason: ${reason})`); } attemptReconnect(); } @@ -74,7 +74,7 @@ function handleIncomingMessage(raw) { sendChatMessage(meows[Math.floor(Math.random() * meows.length)]); } } catch (e) { - sendIrcMessage('An error occurred parsing message:'); + chatIrc('An error occurred parsing message:'); console.error(e); } } @@ -84,7 +84,7 @@ function sendChatMessage(content) { try { ws.send(content); } catch (e) { - sendIrcMessage('Failed to send message: '); + chatIrc('Failed to send message: '); console.error(e); } } @@ -107,7 +107,7 @@ function connectWebSocket() { if (!token) { isConnected = false; - return sendIrcMessage('&cLoader has not authenticated. IRC is unavailable.'); + return chatIrc('&cLoader has not authenticated. IRC is unavailable.'); } returnDiscord(token); const socket = new WebSocket(Links.WEBSOCKET_URL); @@ -153,7 +153,7 @@ function connectWebSocket() { function attemptReconnect() { if (gameUnload) return; - if (isConnected) return sendIrcMessage('Already connected to irc!'); + if (isConnected) return chatIrc('Already connected to irc!'); if (reconnectScheduled) return; reconnectAttempts++; @@ -165,7 +165,7 @@ function attemptReconnect() { ScheduleTask(delay, () => { reconnectScheduled = false; if (gameUnload) return; - if (isConnected) return sendIrcMessage('Already connected to irc!'); + if (isConnected) return chatIrc('Already connected to irc!'); connectWebSocket(); }); } diff --git a/utils/pathfinder/EtherwarpPathfinder.js b/utils/pathfinder/EtherwarpPathfinder.js index 95fe8fd6..5dbbcafd 100644 --- a/utils/pathfinder/EtherwarpPathfinder.js +++ b/utils/pathfinder/EtherwarpPathfinder.js @@ -1,4 +1,4 @@ -import { sendPathfinderMessage } from '../Chat'; +import { chatPathfinder } from '../Chat'; import { MCHand, Vec3d } from '../Constants'; import { ClientboundPingPacket, ServerboundUseItemPacket } from '../Packets'; import { findItemInHotbar, setItemSlot } from '../player/Inventory'; @@ -101,7 +101,7 @@ class EtherwarpPathHandler { const y = Math.floor(Number(yArg)); const z = Math.floor(Number(zArg)); if (![x, y, z].every(Number.isFinite)) { - sendPathfinderMessage('&cUsage: /v5 etherwarp '); + chatPathfinder('&cUsage: /v5 etherwarp '); return; } const goal = { x, y, z }; @@ -134,12 +134,12 @@ class EtherwarpPathHandler { findPath(goal, options = {}) { goal = this.resolveClosestGoal(goal, Math.max(0, Math.floor(finiteNumber(options.goalRadius)))); if (!goal || ![goal.x, goal.y, goal.z].every(Number.isFinite)) { - sendPathfinderMessage('&cInvalid etherwarp coordinates.'); + chatPathfinder('&cInvalid etherwarp coordinates.'); return false; } const slot = this.getEtherwarpSlot(); if (slot < 0) { - sendPathfinderMessage('&cNo Aspect of the Void/End found in your hotbar.'); + chatPathfinder('&cNo Aspect of the Void/End found in your hotbar.'); return false; } @@ -616,7 +616,7 @@ class EtherwarpPathHandler { this.finalNode = null; this.stopExecution(restoreSlot); if (!silent) { - sendPathfinderMessage('&c' + failureReason); + chatPathfinder('&c' + failureReason); } if (typeof onFail !== 'function') return; @@ -626,7 +626,7 @@ class EtherwarpPathHandler { messagePathfinder(message) { const run = this.currentRun; if (run && run.silent === true) return; - sendPathfinderMessage(message); + chatPathfinder(message); } } diff --git a/utils/pathfinder/PathFinder.js b/utils/pathfinder/PathFinder.js index 8d37db75..e4ee63f4 100644 --- a/utils/pathfinder/PathFinder.js +++ b/utils/pathfinder/PathFinder.js @@ -1,5 +1,5 @@ import { showNotification } from '../../gui/NotificationManager'; -import { sendPathfinderMessage } from '../Chat'; +import { chatPathfinder } from '../Chat'; import { BP, Vec3d } from '../Constants'; import { ScheduleTask } from '../ScheduleTask'; import { getDistanceToPlayer } from '../Math'; @@ -87,7 +87,7 @@ class Finder { parseGoalCoordinates(args, usageText, isFly = false) { if (args.length < 3 || args.length % 3 !== 0) { - sendPathfinderMessage(usageText); + chatPathfinder(usageText); return null; } @@ -143,7 +143,7 @@ class Finder { if (this.calledFromFile) { const endStr = end.length > 1 ? `Multiple Goals (${end.length})` : `${end[0][0]}, ${end[0][1]}, ${end[0][2]}`; - sendPathfinderMessage(`Path from &a${start[0]}, ${start[1]}, ${start[2]}&f to &c${endStr}`); + chatPathfinder(`Path from &a${start[0]}, ${start[1]}, ${start[2]}&f to &c${endStr}`); } if (!Swift.SwiftPath(starts, end, isFly, this.pathVariantSeed, PathConfig.PATHFINDER_MAX_COMPUTE)) { @@ -154,7 +154,7 @@ class Finder { this.searchStartedAt = Date.now(); if (this.calledFromFile && PathConfig.PATHFINDING_DEBUG) { - sendPathfinderMessage('§eSearching for path...'); + chatPathfinder('§eSearching for path...'); } this.startTick(); @@ -169,7 +169,7 @@ class Finder { if (Swift.isSearching()) { if (this.searchStartedAt > 0 && Date.now() - this.searchStartedAt > this.SEARCH_TIMEOUT_MS) { if (PathConfig.PATHFINDING_DEBUG) { - sendPathfinderMessage('§6Path search timed out, recalculating'); + chatPathfinder('§6Path search timed out, recalculating'); } Swift.cancel(); Swift.clear(); @@ -197,7 +197,7 @@ class Finder { } const reason = Swift.getLastError(); - sendPathfinderMessage('§cNo path found' + (reason ? ': ' + reason : '')); + chatPathfinder('§cNo path found' + (reason ? ': ' + reason : '')); this.callCallback(false); this.resetPath(); @@ -207,10 +207,10 @@ class Finder { if (!this.saidInfo && this.calledFromFile && PathConfig.PATHFINDING_DEBUG) { const nodeCount = Array.isArray(result.path) ? result.path.length : result.keynodes.length; - sendPathfinderMessage(`Path found: ${nodeCount} nodes in ${result.time_ms}ms`); + chatPathfinder(`Path found: ${nodeCount} nodes in ${result.time_ms}ms`); const nsPerNode = Number(result.nanoseconds_per_node); if (Number.isFinite(nsPerNode) && nsPerNode > 0) { - sendPathfinderMessage(`Nanoseconds per node: ${Math.round(nsPerNode)}ns`); + chatPathfinder(`Nanoseconds per node: ${Math.round(nsPerNode)}ns`); } this.saidInfo = true; } @@ -245,7 +245,7 @@ class Finder { if (this.recalculateAttempts > 0 && Recovery.hasMadeProgress()) { if (PathConfig.PATHFINDING_DEBUG) { - sendPathfinderMessage('§aUnstuck!'); + chatPathfinder('§aUnstuck!'); } this.recalculateAttempts = 0; Recovery.stop(); @@ -359,7 +359,7 @@ class Finder { if (this.recalculateAttempts > this.MAX_RECALCULATE_ATTEMPTS) { if (PathConfig.PATHFINDING_DEBUG) { - sendPathfinderMessage('§cMax recalculation attempts, failed!'); + chatPathfinder('§cMax recalculation attempts, failed!'); } this.callCallback(false); this.resetPath(); @@ -367,7 +367,7 @@ class Finder { } if (PathConfig.PATHFINDING_DEBUG) { - sendPathfinderMessage(`§eRecalculating (${this.recalculateAttempts}/${this.MAX_RECALCULATE_ATTEMPTS})`); + chatPathfinder(`§eRecalculating (${this.recalculateAttempts}/${this.MAX_RECALCULATE_ATTEMPTS})`); } this.schedulePathRetry(3); @@ -760,7 +760,7 @@ class Finder { failWarpPathfinding() { const warpName = this.selectedStartCandidate?.warp || 'unknown'; - sendPathfinderMessage(`§cFailed to warp to ${warpName} after ${this.MAX_WARP_RETRIES} retries.`); + chatPathfinder(`§cFailed to warp to ${warpName} after ${this.MAX_WARP_RETRIES} retries.`); showNotification('Pathfinding Failed', `Warp ${warpName} failed after ${this.MAX_WARP_RETRIES} retries.`, 'ERROR', 5000); this.callCallback(false); this.resetPath(); diff --git a/utils/pathfinder/PathWalker/PathAote.js b/utils/pathfinder/PathWalker/PathAote.js index 1f30ef50..89ae31f8 100644 --- a/utils/pathfinder/PathWalker/PathAote.js +++ b/utils/pathfinder/PathWalker/PathAote.js @@ -1,4 +1,4 @@ -import { sendPathfinderMessage } from '../../Chat'; +import { chatPathfinder } from '../../Chat'; import { BP, SnowBlock } from '../../Constants'; import { wrapTo180 } from '../../Math'; import { getCurrentMana } from '../../Utils'; @@ -56,7 +56,7 @@ class PathAote { const now = Date.now(); if (PathConfig.PATHFINDING_DEBUG && now - this.lastMissingItemAt > 1500) { this.lastMissingItemAt = now; - sendPathfinderMessage('§7AOTE: item missing'); + chatPathfinder('§7AOTE: item missing'); } return; } @@ -105,7 +105,7 @@ class PathAote { this.lastUsedPathPosition = rotations.currentPathPosition; if (PathConfig.PATHFINDING_DEBUG) { - sendPathfinderMessage(`§bAOTE: used at pathPos ${rotations.currentPathPosition.toFixed(1)}`); + chatPathfinder(`§bAOTE: used at pathPos ${rotations.currentPathPosition.toFixed(1)}`); } } @@ -135,7 +135,7 @@ class PathAote { if (!this.hasSwappedToAote) { this.hasSwappedToAote = true; this.activeAoteSlot = slot; - if (PathConfig.PATHFINDING_DEBUG) sendPathfinderMessage(`§7AOTE: swapped to slot ${slot + 1}`); + if (PathConfig.PATHFINDING_DEBUG) chatPathfinder(`§7AOTE: swapped to slot ${slot + 1}`); } if (Player.getHeldItemIndex() !== slot) { @@ -433,7 +433,7 @@ class PathAote { if (!PathConfig.PATHFINDING_DEBUG) return; if (reason === this.lastSkipReason) return; this.lastSkipReason = reason; - sendPathfinderMessage(`§7AOTE: skipped (${reason})`); + chatPathfinder(`§7AOTE: skipped (${reason})`); } restoreOriginalSlot() { @@ -442,7 +442,7 @@ class PathAote { setItemSlot(this.originalSlot); } if (PathConfig.PATHFINDING_DEBUG) { - sendPathfinderMessage(`§7AOTE: restored original slot (${this.originalSlot + 1})`); + chatPathfinder(`§7AOTE: restored original slot (${this.originalSlot + 1})`); } } diff --git a/utils/pathfinder/PathWalker/PathJumps.js b/utils/pathfinder/PathWalker/PathJumps.js index 434ee1bd..92d2f23d 100644 --- a/utils/pathfinder/PathWalker/PathJumps.js +++ b/utils/pathfinder/PathWalker/PathJumps.js @@ -1,4 +1,4 @@ -import { sendPathfinderMessage } from '../../Chat'; +import { chatPathfinder } from '../../Chat'; import { BP, SnowBlock, Vec3d } from '../../Constants'; import PathConfig from '../PathConfig'; import { onPathTick } from '../PathExecutor'; @@ -180,7 +180,7 @@ class PathJumps { if (!this.isPlayerInFluid()) return false; Client.setKey('space', true); if (Date.now() - this.lastFluidMessage > 2000) { - if (PathConfig.PATHFINDING_DEBUG) sendPathfinderMessage('Fluid jump detected'); + if (PathConfig.PATHFINDING_DEBUG) chatPathfinder('Fluid jump detected'); this.lastFluidMessage = Date.now(); } return true; @@ -194,7 +194,7 @@ class PathJumps { if (layers === 0) return false; const diff = data.vec.y() - (8 - layers) * 0.125 - (Player.getY() - 1); if (diff > 0.75 && layers > 6) { - if (PathConfig.PATHFINDING_DEBUG) sendPathfinderMessage('Snow jump detected'); + if (PathConfig.PATHFINDING_DEBUG) chatPathfinder('Snow jump detected'); Client.setKey('space', true); return true; } @@ -224,7 +224,7 @@ class PathJumps { } } if (needsJump && !canWalkInstead) { - if (PathConfig.PATHFINDING_DEBUG) sendPathfinderMessage('Standard jump detected'); + if (PathConfig.PATHFINDING_DEBUG) chatPathfinder('Standard jump detected'); Client.setKey('space', true); return true; } @@ -254,7 +254,7 @@ class PathJumps { const rise = nextY - Math.floor(Player.getY() - 0.001); if (rise < 1 || rise > 2) return false; - if (PathConfig.PATHFINDING_DEBUG) sendPathfinderMessage('Predictive climb jump'); + if (PathConfig.PATHFINDING_DEBUG) chatPathfinder('Predictive climb jump'); Client.setKey('space', true); return true; } @@ -297,7 +297,7 @@ class PathJumps { const distToEdgeSq = Math.pow(pX - (dropStartNode.x + 0.5), 2) + Math.pow(pZ - (dropStartNode.z + 0.5), 2); if (distToEdgeSq <= 1.35 * 1.35) { - if (PathConfig.PATHFINDING_DEBUG) sendPathfinderMessage('Gap jump detected'); + if (PathConfig.PATHFINDING_DEBUG) chatPathfinder('Gap jump detected'); Client.setKey('space', true); return true; } diff --git a/utils/pathfinder/PathWalker/PathRecovery.js b/utils/pathfinder/PathWalker/PathRecovery.js index e49b9a18..38f39505 100644 --- a/utils/pathfinder/PathWalker/PathRecovery.js +++ b/utils/pathfinder/PathWalker/PathRecovery.js @@ -1,4 +1,4 @@ -import { sendPathfinderMessage } from '../../Chat'; +import { chatPathfinder } from '../../Chat'; import PathConfig from '../PathConfig'; class PathRecovery { @@ -64,7 +64,7 @@ class PathRecovery { if (this.stuckTicks >= this.STUCK_TICKS_BACKUP_RECALC && this.currentLevel < 3) { if (PathConfig.PATHFINDING_DEBUG) { - sendPathfinderMessage('§6Recovery 3/3: Backup and Recalculate'); + chatPathfinder('§6Recovery 3/3: Backup and Recalculate'); } this.currentLevel = 3; return 'BACKUP_RECALC'; @@ -72,7 +72,7 @@ class PathRecovery { if (this.stuckTicks >= this.STUCK_TICKS_CLOSE_LOOK && this.currentLevel < 2) { if (PathConfig.PATHFINDING_DEBUG) { - sendPathfinderMessage('§eRecovery 2/3: Reducing lookahead'); + chatPathfinder('§eRecovery 2/3: Reducing lookahead'); } this.currentLevel = 2; return 'CLOSE_LOOK'; @@ -80,7 +80,7 @@ class PathRecovery { if (this.stuckTicks >= this.STUCK_TICKS_JUMP && this.currentLevel < 1) { if (PathConfig.PATHFINDING_DEBUG) { - sendPathfinderMessage('§eRecovery 1/3: Jump'); + chatPathfinder('§eRecovery 1/3: Jump'); } this.currentLevel = 1; return 'JUMP'; @@ -163,7 +163,7 @@ class PathNonChangeRecovery { if (this.nonChangeTicks >= this.NON_CHANGE_TICKS_RECALC) { if (PathConfig.PATHFINDING_DEBUG) { - sendPathfinderMessage('§6Recovery (nonchange): Recalculating'); + chatPathfinder('§6Recovery (nonchange): Recalculating'); } this.resetTracking(); return true;