Krunker.io assistant
// ==UserScript== // @name Xianware // @namespace http://tampermonkey.net/ // @version 8.2.1 // @description Krunker.io assistant // @author simplexian // @match *://krunker.io/* // @exclude *://krunker.io/social* // @exclude *://krunker.io/editor* // @exclude *://krunker.io/viewer* // @icon https://iili.io/qNroOue.png // @grant none // @run-at document-start // @license MIT // @require https://unpkg.com/[email protected]/build/three.min.js // ==/UserScript== (function () { "use strict"; let THREE, MathUtils; try { THREE = window.THREE; MathUtils = THREE.MathUtils; delete window.THREE; } catch (e) { console.error("[Xianware] Error initializing THREE.js:", e); } class ConfigManager { constructor() { this.defaultSettings = { aimbotEnabled: true, aimbotOnRightMouse: false, smoothAim: true, horizontalFreeAim: true, verticalFreeAim: true, aimOffset: 0.75, aimHorizontal: true, aimVertical: true, wallCheck: true, aimSpeedXMin: 0.15, aimSpeedXMax: 0.3, aimSpeedYMin: 0.15, aimSpeedYMax: 0.3, aimPrediction: false, predictionFactor: 1.0, fovCheck: true, fovRadius: 150, fovCircleColor: "#ffffff", drawFov: true, targetIndicator: true, indicatorShape: "Arrow", indicatorColor: "#ff0000", indicatorSize: 15, indicatorOpacity: 1.0, indicatorImageUrl: "", espEnabled: true, espRainbow: false, espColor: "#fbc02d", espSnaplines: false, snaplineColor: "#ffffff", snaplineOrigin: "Bottom", espDistance: false, espDistanceColor: "#ffffff", chamsEnabled: false, chamsRainbow: false, chamsColor: "#ff0000", menuTheme: "Dark", menuScale: 1.0, menuColor: "#fbc02d", showNotifications: true, showHud: true, hudScale: 1.0, hudPosition: "Top Left", customCssText: "", }; this.defaultKeybinds = { menuToggle: "Insert", aimbotEnabled: "KeyB", drawFov: "KeyG", espEnabled: "KeyV", espSnaplines: "", chamsEnabled: "", wallCheck: "", reloadScript: "KeyZ", showNotifications: "", showHud: "", }; this.settings = JSON.parse(JSON.stringify(this.defaultSettings)); this.keybinds = JSON.parse(JSON.stringify(this.defaultKeybinds)); this.profiles = { Default: { settings: JSON.parse(JSON.stringify(this.defaultSettings)), keybinds: JSON.parse(JSON.stringify(this.defaultKeybinds)), hotkey: "", }, }; this.activeProfile = "Default"; this.autoLoadProfile = "Default"; this.reverseKeyMap = {}; this.profileKeyMap = {}; this.load(); } updateKeyMaps() { this.reverseKeyMap = {}; for (const [feat, key] of Object.entries(this.keybinds)) { if (key) this.reverseKeyMap[key] = feat; } this.profileKeyMap = {}; for (const [pName, pData] of Object.entries(this.profiles)) { if (pData.hotkey) this.profileKeyMap[pData.hotkey] = pName; } } save() { try { localStorage.setItem( "xian_profiles_v82", JSON.stringify(this.profiles), ); localStorage.setItem("xian_autoload_profile_v82", this.autoLoadProfile); this.updateKeyMaps(); } catch (e) {} } load() { try { let savedProfiles = JSON.parse(localStorage.getItem("xian_profiles_v82")) || JSON.parse(localStorage.getItem("xian_profiles_v81")) || JSON.parse(localStorage.getItem("xian_profiles_v8")) || JSON.parse(localStorage.getItem("xian_profiles_v75")); if (savedProfiles) { this.profiles = savedProfiles; } this.autoLoadProfile = localStorage.getItem("xian_autoload_profile_v82") || localStorage.getItem("xian_autoload_profile_v81") || localStorage.getItem("xian_autoload_profile_v8") || localStorage.getItem("xian_autoload_profile_v75") || "Default"; this.activeProfile = this.autoLoadProfile; if (!this.profiles[this.activeProfile]) { this.activeProfile = "Default"; this.autoLoadProfile = "Default"; } this.migrateProfiles(); this.applyProfile(this.activeProfile); } catch (e) {} } migrateProfiles() { for (const pName of Object.keys(this.profiles)) { const prof = this.profiles[pName]; if (prof.hotkey === undefined) prof.hotkey = ""; if (!prof.settings) prof.settings = {}; if (!prof.keybinds) prof.keybinds = {}; for (const key of Object.keys(this.defaultSettings)) { if (prof.settings[key] === undefined) prof.settings[key] = this.defaultSettings[key]; } for (const key of Object.keys(this.defaultKeybinds)) { if (prof.keybinds[key] === undefined) prof.keybinds[key] = this.defaultKeybinds[key]; } } } applyProfile(name) { if (!this.profiles[name]) return; this.activeProfile = name; const prof = this.profiles[name]; Object.keys(this.defaultSettings).forEach((k) => { this.settings[k] = prof.settings.hasOwnProperty(k) ? prof.settings[k] : this.defaultSettings[k]; }); Object.keys(this.defaultKeybinds).forEach((k) => { this.keybinds[k] = prof.keybinds.hasOwnProperty(k) ? prof.keybinds[k] : this.defaultKeybinds[k]; }); this.updateKeyMaps(); } resetToDefault() { Object.keys(this.defaultSettings).forEach((k) => { this.settings[k] = this.defaultSettings[k]; }); Object.keys(this.defaultKeybinds).forEach((k) => { this.keybinds[k] = this.defaultKeybinds[k]; }); } } class UIManager { constructor(app) { this.app = app; this.config = app.config; this.canvas = null; this.ctx = null; this.gui = null; this.welcomeGui = null; this.hudEl = null; this.notificationEl = null; this.toastQueue = []; this.toastActive = false; this.toastTimer = null; this.bindingFeature = null; this.saveDebounce = null; this.menuStructure = this.buildMenuStructure(); } init() { this.createCanvas(); this.injectCSS(); this.createDOM(); this.attachEventListeners(); this.refreshUI(); window.addEventListener("resize", () => { this.canvas.width = window.innerWidth; this.canvas.height = window.innerHeight; }); } createCanvas() { this.canvas = document.createElement("canvas"); this.canvas.style.position = "fixed"; this.canvas.style.top = "0"; this.canvas.style.left = "0"; this.canvas.style.width = "100%"; this.canvas.style.height = "100%"; this.canvas.style.pointerEvents = "none"; this.canvas.style.zIndex = "999"; document.documentElement.appendChild(this.canvas); this.ctx = this.canvas.getContext("2d", { alpha: true }); this.canvas.width = window.innerWidth; this.canvas.height = window.innerHeight; } cleanKeyName(code) { return !code || code === "" ? "NONE" : code.replace("Key", "").replace("Digit", ""); } showToast(text, stateText = "", duration = 1500) { if (!this.config.settings.showNotifications) return; this.toastQueue.push({ text, stateText, duration }); if (!this.toastActive) this.processToastQueue(); } processToastQueue() { if (this.toastQueue.length === 0) { this.toastActive = false; return; } this.toastActive = true; const { text, stateText, duration } = this.toastQueue.shift(); this.notificationEl.innerHTML = `${text} <span>${stateText}</span>`; this.notificationEl.classList.add("show"); clearTimeout(this.toastTimer); this.toastTimer = setTimeout(() => { this.notificationEl.classList.remove("show"); setTimeout(() => this.processToastQueue(), 300); }, duration); } queueSave() { clearTimeout(this.saveDebounce); this.saveDebounce = setTimeout(() => { this.config.profiles[this.config.activeProfile].settings = JSON.parse( JSON.stringify(this.config.settings), ); this.config.profiles[this.config.activeProfile].keybinds = JSON.parse( JSON.stringify(this.config.keybinds), ); this.config.save(); }, 2000); } applyTheme() { document.documentElement.setAttribute( "data-theme", this.config.settings.menuTheme.toLowerCase(), ); document.documentElement.style.setProperty( "--accent-color", this.config.settings.menuColor, ); } refreshUI() { this.applyTheme(); this.updateHud(); if (this.gui) this.gui.style.transform = `scale(${this.config.settings.menuScale})`; if (this.welcomeGui) this.welcomeGui.style.transform = `scale(${this.config.settings.menuScale})`; this.menuStructure.forEach((cat) => cat.groups.forEach((group) => group.items.forEach((item) => { const chk = document.getElementById(`chk-${item.id}`); const sld = document.getElementById(`sld-${item.id}`); const col = document.getElementById(`col-${item.id}`); const sel = document.getElementById(`sel-${item.id}`); const txt = document.getElementById(`txt-${item.id}`); const bind = document.getElementById( `bind-${item.bind || item.id}`, ); if (chk) chk.checked = this.config.settings[item.id]; if (sld) { sld.value = this.config.settings[item.id]; const valEl = document.getElementById(`val-${item.id}`); if (valEl) valEl.innerText = this.config.settings[item.id]; } if (col) col.value = this.config.settings[item.id]; if (sel && item.id !== "profileSelect") sel.value = this.config.settings[item.id]; if (txt && item.id !== "profileName" && item.id !== "configData") txt.value = this.config.settings[item.id] || ""; if ( item.type === "bind" && this.config.keybinds[item.bind || item.id] !== undefined ) { if (bind) bind.innerText = this.cleanKeyName( this.config.keybinds[item.bind || item.id] || "", ); } else if ( item.type === "customBind" && item.id === "profileHotkey" ) { if (bind) bind.innerText = this.cleanKeyName( this.config.profiles[this.config.activeProfile]?.hotkey || "", ); } }), ), ); this.updateProfileDropdown(); this.app.engine.updateMaterials(); } updateProfileDropdown() { const sel = document.getElementById("sel-profileSelect"); if (!sel) return; sel.innerHTML = Object.keys(this.config.profiles) .map((p) => { const isActive = p === this.config.activeProfile ? " [ACTIVE]" : ""; const isAuto = p === this.config.autoLoadProfile ? " [AUTO]" : ""; const hk = this.config.profiles[p].hotkey ? ` [${this.cleanKeyName(this.config.profiles[p].hotkey)}]` : ""; return `<option value="${p}">${p}${isActive}${isAuto}${hk}</option>`; }) .join(""); sel.value = this.config.activeProfile; } updateHud() { if (!this.hudEl) return; const s = this.config.settings; if (!s.showHud) { this.hudEl.style.display = "none"; return; } this.hudEl.style.display = "flex"; this.hudEl.style.transform = `scale(${s.hudScale})`; this.hudEl.style.top = "auto"; this.hudEl.style.bottom = "auto"; this.hudEl.style.left = "auto"; this.hudEl.style.right = "auto"; this.hudEl.style.alignItems = "flex-start"; switch (s.hudPosition) { case "Top Left": this.hudEl.style.top = "15px"; this.hudEl.style.left = "15px"; this.hudEl.style.transformOrigin = "top left"; break; case "Top Right": this.hudEl.style.top = "15px"; this.hudEl.style.right = "15px"; this.hudEl.style.alignItems = "flex-end"; this.hudEl.style.transformOrigin = "top right"; break; case "Bottom Left": this.hudEl.style.bottom = "15px"; this.hudEl.style.left = "15px"; this.hudEl.style.transformOrigin = "bottom left"; break; case "Bottom Right": this.hudEl.style.bottom = "15px"; this.hudEl.style.right = "15px"; this.hudEl.style.alignItems = "flex-end"; this.hudEl.style.transformOrigin = "bottom right"; break; } const activeFeatures = [ { name: "XianWare", active: true, color: s.menuColor, isTitle: true }, { name: "Profile", state: `[${this.config.activeProfile}]` }, ]; if (s.aimbotEnabled) activeFeatures.push({ name: "Aimbot", state: s.aimbotOnRightMouse ? "[ADS]" : "[ON]", }); if (s.aimPrediction) activeFeatures.push({ name: "Prediction", state: "[ON]" }); let freeAimState = s.horizontalFreeAim && s.verticalFreeAim ? "[H+V]" : s.horizontalFreeAim ? "[HORIZ]" : s.verticalFreeAim ? "[VERT]" : ""; if (freeAimState) activeFeatures.push({ name: "Free-Aim", state: freeAimState }); if (s.espEnabled) activeFeatures.push({ name: "ESP", state: s.espRainbow ? "[RAINBOW]" : "[ON]", }); if (s.espSnaplines) activeFeatures.push({ name: "Snaplines", state: "[ON]" }); if (s.espDistance) activeFeatures.push({ name: "Distance", state: "[ON]" }); if (s.chamsEnabled) activeFeatures.push({ name: "Chams", state: s.chamsRainbow ? "[RAINBOW]" : "[ON]", }); if (s.drawFov) activeFeatures.push({ name: "Draw FOV", state: "[ON]" }); if (s.targetIndicator) activeFeatures.push({ name: "Target Ind.", state: "[ON]" }); if (s.wallCheck) activeFeatures.push({ name: "Wall Check", state: "[ON]" }); this.hudEl.innerHTML = activeFeatures .map((f) => { if (f.isTitle) return `<div class="hud-item title" style="color:${f.color}; font-size: 20px;">${f.name} <span style="font-size:12px;color:#fff;">V8.2.1</span></div>`; return `<div class="hud-item">${f.name} <span>${f.state}</span></div>`; }) .join(""); } injectCustomCss() { const existing = document.getElementById("xian-custom-css"); if (existing) existing.remove(); if ( !this.config.settings.customCssText || this.config.settings.customCssText.trim() === "" ) return; const styleBlock = document.createElement("style"); styleBlock.id = "xian-custom-css"; styleBlock.innerHTML = this.config.settings.customCssText; document.documentElement.appendChild(styleBlock); this.showToast("Custom CSS", "APPLIED"); } confirmAction(message) { return new Promise((resolve) => { const overlay = document.createElement("div"); overlay.style.cssText = "position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.6);z-index:10000001;display:flex;justify-content:center;align-items:center;font-family:'Rajdhani',sans-serif;"; overlay.innerHTML = `<div style="background:var(--bg-main);border:2px solid var(--border-light);border-radius:8px;padding:24px 32px;text-align:center;color:var(--text-main);min-width:300px;box-shadow:0 10px 40px rgba(0,0,0,0.8);"><div style="font-size:16px;font-weight:700;margin-bottom:20px;text-transform:uppercase;">${message}</div><div style="display:flex;gap:12px;justify-content:center;"><button class="xian-btn" id="xian-confirm-yes" style="width:auto;padding:8px 24px;border-color:#ff4444;color:#ff4444;">YES</button><button class="xian-btn" id="xian-confirm-no" style="width:auto;padding:8px 24px;">CANCEL</button></div></div>`; document.documentElement.appendChild(overlay); document.getElementById("xian-confirm-yes").onclick = () => { overlay.remove(); resolve(true); }; document.getElementById("xian-confirm-no").onclick = () => { overlay.remove(); resolve(false); }; }); } btnSaveProfile() { this.config.profiles[this.config.activeProfile].settings = JSON.parse( JSON.stringify(this.config.settings), ); this.config.profiles[this.config.activeProfile].keybinds = JSON.parse( JSON.stringify(this.config.keybinds), ); this.config.save(); this.updateProfileDropdown(); this.showToast("Profile Saved", this.config.activeProfile.toUpperCase()); } btnLoadProfile() { const sel = document.getElementById("sel-profileSelect"); if (sel && this.config.profiles[sel.value]) { this.config.applyProfile(sel.value); this.refreshUI(); this.injectCustomCss(); this.showToast("Profile Loaded", sel.value.toUpperCase()); } } btnCreateProfile() { const name = document.getElementById("txt-profileName").value.trim(); if (!name) return this.showToast("Error", "NAME EMPTY"); if (this.config.profiles[name]) return this.showToast("Error", "EXISTS"); this.config.activeProfile = name; this.config.profiles[name] = { settings: JSON.parse(JSON.stringify(this.config.settings)), keybinds: JSON.parse(JSON.stringify(this.config.keybinds)), hotkey: "", }; this.config.save(); document.getElementById("txt-profileName").value = ""; this.updateProfileDropdown(); this.showToast("Profile Created", name.toUpperCase()); } async btnDeleteProfile() { const sel = document.getElementById("sel-profileSelect"); if (sel.value === "Default") return this.showToast("Error", "CANNOT DELETE DEFAULT"); const confirmed = await this.confirmAction( `Delete profile "${sel.value}"?`, ); if (!confirmed) return; delete this.config.profiles[sel.value]; if (this.config.activeProfile === sel.value) this.config.applyProfile("Default"); if (this.config.autoLoadProfile === sel.value) this.config.autoLoadProfile = "Default"; this.config.save(); this.updateProfileDropdown(); this.refreshUI(); this.showToast("Profile Deleted", sel.value.toUpperCase()); } btnSetAutoLoad() { const sel = document.getElementById("sel-profileSelect"); this.config.autoLoadProfile = sel.value; this.config.save(); this.updateProfileDropdown(); this.showToast("Auto-Load Set", sel.value.toUpperCase()); } btnExportConfig() { const jsonStr = JSON.stringify( { settings: this.config.settings, keybinds: this.config.keybinds }, null, 2, ); const txt = document.getElementById("txt-configData"); if (txt) { txt.value = jsonStr; txt.select(); } if (navigator.clipboard) navigator.clipboard .writeText(jsonStr) .catch(() => document.execCommand("copy")); else document.execCommand("copy"); this.showToast("Config Exported", "COPIED TO CLIPBOARD"); } btnImportConfig() { const txt = document.getElementById("txt-configData"); try { const parsed = JSON.parse(txt.value.trim()); if (parsed.settings) Object.assign(this.config.settings, parsed.settings); if (parsed.keybinds) Object.assign(this.config.keybinds, parsed.keybinds); this.refreshUI(); this.showToast("Config Imported", "UNSAVED"); } catch (e) { this.showToast("Import Error", "INVALID JSON"); } } async btnResetSettings() { const confirmed = await this.confirmAction( "Reset all settings to default?", ); if (!confirmed) return; this.config.resetToDefault(); this.refreshUI(); this.showToast("Current Profile Reset", "DEFAULT"); } injectCSS() { const style = document.createElement("style"); style.innerHTML = ` @import url('https://fonts.googleapis.com/css2?family=Rajdhani:wght@500;700&display=swap'); :root { --accent-color: ${this.config.settings.menuColor}; } :root[data-theme="dark"] { --bg-main: rgba(20, 20, 20, 0.95); --text-main: #ffffff; --bg-header: rgba(10, 10, 10, 0.8); --text-muted: #dddddd; --bg-tab-hover: rgba(255, 255, 255, 0.08); --bg-group: rgba(0, 0, 0, 0.25); --border-light: rgba(255, 255, 255, 0.08); --bg-row: rgba(255, 255, 255, 0.03); --bg-row-hover: rgba(255, 255, 255, 0.07); --bg-input: #2a2a2a; --bg-input-dark: #1f1f1f; --border-input: #555; --text-input: #ffffff; --bg-tooltip: #1a1a1a; --bg-slider-track: #555; } :root[data-theme="light"] { --bg-main: rgba(240, 240, 240, 0.95); --text-main: #111111; --bg-header: rgba(220, 220, 220, 0.9); --text-muted: #333333; --bg-tab-hover: rgba(0, 0, 0, 0.05); --bg-group: rgba(255, 255, 255, 0.6); --border-light: rgba(0, 0, 0, 0.1); --bg-row: rgba(255, 255, 255, 0.4); --bg-row-hover: rgba(255, 255, 255, 0.8); --bg-input: #e8e8e8; --bg-input-dark: #dddddd; --border-input: #aaaaaa; --text-input: #111111; --bg-tooltip: #f5f5f5; --bg-slider-track: #bbbbbb; } #xian-ui { position: fixed; width: 440px; background: var(--bg-main); border-radius: 8px; box-shadow: 0 10px 40px rgba(0,0,0,0.8); color: var(--text-main); font-family: 'Rajdhani', sans-serif; z-index: 1000000; user-select: none; transform-origin: top left; transform: scale(${this.config.settings.menuScale}); border: 2px solid var(--border-light); } #xian-welcome { position: fixed; top: 20px; right: 20px; width: 320px; background: var(--bg-main); border-radius: 8px; box-shadow: 0 10px 40px rgba(0,0,0,0.8); color: var(--text-main); font-family: 'Rajdhani', sans-serif; z-index: 1000001; border: 2px solid var(--border-light); transform-origin: top right; transform: scale(${this.config.settings.menuScale}); } #xian-welcome a { color: var(--accent-color); text-decoration: underline; font-weight: bold; transition: 0.2s; } #xian-welcome a:hover { filter: brightness(1.2); } .xian-header { display: flex; flex-direction: column; background: var(--bg-header); border-radius: 8px 8px 0 0; cursor: grab; border-bottom: 2px solid var(--border-light); } .xian-header:active { cursor: grabbing; } .xian-header-top { display: flex; justify-content: space-between; align-items: flex-start; width: 100%; } .xian-brand-container { display: flex; align-items: center; gap: 10px; padding: 12px 15px 4px 15px; pointer-events: none; } .xian-brand-logo { width: 24px; height: 24px; border-radius: 4px; filter: drop-shadow(0 0 2px rgba(0,0,0,0.5)); } .xian-brand-text { font-size: 20px; font-weight: 700; color: var(--text-main); text-transform: uppercase; letter-spacing: 1px; } .xian-brand-text span { color: var(--accent-color); } .xian-tabs { display: flex; width: 100%; overflow: hidden; } .xian-tab { padding: 10px 10px; font-size: 14px; font-weight: 700; color: var(--text-muted); cursor: pointer; transition: 0.2s; border-bottom: 3px solid transparent; text-transform: uppercase; text-align: center; flex: 1; white-space: nowrap; } .xian-tab.active { color: var(--text-main); background: var(--bg-row); border-bottom: 3px solid var(--accent-color); } .xian-tab:hover:not(.active) { background: var(--bg-tab-hover); color: var(--text-main); } .xian-close { padding: 12px 16px; font-weight: 700; cursor: pointer; color: #ff4444; font-size: 15px; transition: 0.2s; border-radius: 0 8px 0 0; } .xian-close:hover { color: #ff6666; background: rgba(255,0,0,0.1); } .xian-content { padding: 15px; max-height: 500px; overflow-y: auto; } .xian-content::-webkit-scrollbar { width: 6px; } .xian-content::-webkit-scrollbar-thumb { background: var(--bg-input); border-radius: 3px; } .xian-tab-pane { display: none; } .xian-tab-pane.active { display: block; animation: fadeIn 0.2s; } @keyframes fadeIn { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: translateY(0); } } .xian-group { margin-bottom: 12px; background: var(--bg-group); border-radius: 6px; border: 1px solid var(--border-light); } .xian-group-header { padding: 8px 14px; background: transparent; font-size: 14px; font-weight: 700; color: var(--accent-color); text-transform: uppercase; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid var(--border-light); } .xian-group-content { padding: 8px 10px; } .xian-row { display: flex; justify-content: space-between; align-items: center; padding: 8px 10px; margin-bottom: 4px; background: var(--bg-row); border-radius: 4px; transition: background 0.2s; } .xian-row:hover { background: var(--bg-row-hover); } .xian-label { font-size: 15px; color: var(--text-main); font-weight: 600; text-transform: uppercase; display: flex; align-items: center; } .xian-info { display: inline-flex; justify-content: center; align-items: center; width: 16px; height: 16px; background: var(--border-light); border-radius: 50%; font-size: 11px; font-weight: bold; margin-left: 8px; cursor: help; color: var(--text-muted); position: relative; transition: 0.2s; } .xian-info:hover { background: var(--accent-color); color: #000; } .xian-info::after { content: attr(data-tooltip); position: absolute; bottom: 130%; left: 50%; transform: translateX(-50%); background: var(--bg-tooltip); color: var(--text-main); padding: 8px 12px; border-radius: 4px; font-size: 13px; white-space: normal; width: max-content; max-width: 220px; text-align: center; line-height: 1.3; opacity: 0; visibility: hidden; pointer-events: none; transition: 0.2s; border: 1px solid var(--border-input); box-shadow: 0 4px 10px rgba(0,0,0,0.5); z-index: 1000; font-weight: 600; font-family: sans-serif; text-transform: none; } .xian-info:hover::after { opacity: 1; visibility: visible; } .xian-controls { display: flex; align-items: center; gap: 12px; } .xian-switch { position: relative; display: inline-block; width: 40px; height: 22px; } .xian-switch input { opacity: 0; width: 0; height: 0; } .xian-slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: var(--bg-input-dark); transition: .3s; border-radius: 4px; } .xian-slider:before { position: absolute; content: ""; height: 14px; width: 14px; left: 4px; bottom: 4px; background-color: var(--text-muted); transition: .3s; border-radius: 2px; } input:checked + .xian-slider { background-color: var(--border-light); } input:checked + .xian-slider:before { transform: translateX(18px); background-color: var(--accent-color); box-shadow: 0 0 8px var(--accent-color); } .xian-bind { background: var(--bg-input); border: 1px solid var(--border-input); color: var(--text-main); padding: 4px 10px; border-radius: 4px; font-size: 13px; cursor: pointer; min-width: 60px; text-align: center; font-weight: 700; } .xian-bind:hover { border-color: var(--accent-color); color: var(--accent-color); } .xian-bind.active { border-color: var(--accent-color); color: var(--accent-color); animation: pulse 1s infinite; } .xian-btn { background: var(--bg-input); border: 1px solid var(--border-input); color: var(--text-main); padding: 6px 15px; border-radius: 4px; font-family: inherit; font-size: 14px; font-weight: 700; cursor: pointer; transition: 0.2s; width: 100%; text-transform: uppercase; } .xian-btn:hover { border-color: var(--accent-color); color: var(--accent-color); background: var(--bg-row-hover); } .xian-select { background: var(--bg-input); color: var(--text-input); border: 1px solid var(--border-input); padding: 4px 8px; border-radius: 4px; font-family: inherit; font-size: 14px; font-weight: 600; outline: none; cursor: pointer; } .xian-textarea, .xian-text { background: var(--bg-input-dark); border: 1px solid var(--border-input); color: var(--text-input); padding: 8px 12px; border-radius: 4px; font-family: monospace; font-size: 12px; outline: none; margin-top: 8px; box-sizing: border-box; width: 100%; } .xian-textarea { height: 120px; resize: vertical; white-space: pre-wrap; overflow-wrap: break-word; overflow-y: auto; } .xian-textarea:focus, .xian-text:focus, .xian-select:focus { border-color: var(--accent-color); } .xian-search { background: var(--bg-input-dark); border: 1px solid var(--border-input); color: var(--text-input); padding: 8px 12px; border-radius: 4px; font-family: 'Rajdhani', sans-serif; font-size: 14px; font-weight: 600; outline: none; box-sizing: border-box; width: 100%; margin-bottom: 10px; } .xian-search:focus { border-color: var(--accent-color); } .xian-search::placeholder { color: var(--text-muted); opacity: 0.6; } .range-container { width: 100%; padding: 5px 0; } input[type=range] { -webkit-appearance: none; width: 100%; background: transparent; } input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; height: 16px; width: 16px; border-radius: 4px; background: var(--accent-color); cursor: pointer; margin-top: -6px; } input[type=range]::-webkit-slider-runnable-track { width: 100%; height: 4px; cursor: pointer; background: var(--bg-slider-track); border-radius: 2px; } input[type="color"] { -webkit-appearance: none; border: none; width: 26px; height: 26px; background: none; cursor: pointer; } input[type="color"]::-webkit-color-swatch { border: 2px solid var(--border-input); border-radius: 4px; } .xian-footer { padding: 10px 15px; background: var(--bg-header); border-top: 2px solid var(--border-light); border-radius: 0 0 8px 8px; font-size: 13px; font-weight: 700; color: var(--text-muted); text-align: center; text-transform: uppercase; cursor: default; } .xian-footer span { color: var(--accent-color); } .xian-notification { position: fixed; top: 15px; left: 50%; transform: translateX(-50%) translateY(-20px) scale(0.9); background: var(--bg-main); color: var(--text-main); padding: 10px 24px; border-radius: 6px; font-size: 14px; font-weight: 700; pointer-events: none; opacity: 0; z-index: 1000000; display: flex; align-items: center; box-shadow: 0 5px 20px rgba(0,0,0,0.5); border: 1px solid var(--border-light); transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); text-transform: uppercase; } .xian-notification.show { transform: translateX(-50%) translateY(0) scale(1); opacity: 1; } .xian-notification span { color: var(--accent-color); margin-left: 8px; } #xian-hud { position: fixed; pointer-events: none; z-index: 999999; display: flex; flex-direction: column; gap: 4px; font-family: 'Rajdhani', sans-serif; text-transform: uppercase; font-weight: 700; text-shadow: 1px 1px 2px #000, -1px -1px 2px #000, 1px -1px 2px #000, -1px 1px 2px #000; } .hud-item { color: #fff; font-size: 16px; } .hud-item.title { margin-bottom: 5px; } .hud-item span { color: var(--accent-color); } @keyframes pulse { 0% { opacity: 1; } 50% { opacity: 0.5; } 100% { opacity: 1; } } `; document.documentElement.appendChild(style); } createDOM() { this.gui = document.createElement("div"); this.gui.id = "xian-ui"; this.gui.style.left = `${window.innerWidth / 2 - 220}px`; this.gui.style.top = `${window.innerHeight / 2 - 200}px`; let tabsHtml = "", panesHtml = ""; this.menuStructure.forEach((cat, index) => { const isActive = index === 0 ? "active" : ""; const safeId = cat.title.replace(/\s+/g, ""); tabsHtml += `<div class="xian-tab ${isActive}" data-target="${safeId}">${cat.title}</div>`; panesHtml += `<div class="xian-tab-pane ${isActive}" id="pane-${safeId}">`; cat.groups.forEach((group) => { panesHtml += `<div class="xian-group" data-group-name="${group.name}"><div class="xian-group-header">${group.name}</div><div class="xian-group-content">`; group.items.forEach((item) => { let labelHtml = item.tooltip ? `<span class="xian-label">${item.name}<span class="xian-info" data-tooltip="${item.tooltip}">?</span></span>` : `<span class="xian-label">${item.name}</span>`; let controlsHtml = ""; if (item.type === "slider") { panesHtml += `<div class="xian-row" data-item-id="${item.id}" data-search-name="${item.name.toLowerCase()}" data-search-tip="${(item.tooltip || "").toLowerCase()}" style="flex-direction: column; align-items: flex-start;"><div style="display:flex; justify-content:space-between; width:100%; margin-bottom:5px;">${labelHtml}<span class="xian-label" id="val-${item.id}" style="color:var(--accent-color);">${this.config.settings[item.id]}</span></div><div class="range-container"><input type="range" id="sld-${item.id}" min="${item.min}" max="${item.max}" step="${item.step}" value="${this.config.settings[item.id]}"></div></div>`; } else if (item.type === "textarea" || item.type === "text") { const tag = item.type === "textarea" ? "textarea" : "input"; const typeAttr = item.type === "text" ? 'type="text"' : ""; panesHtml += `<div class="xian-row" data-item-id="${item.id}" data-search-name="${item.name.toLowerCase()}" data-search-tip="${(item.tooltip || "").toLowerCase()}" style="flex-direction: column; align-items: flex-start;">${labelHtml}<${tag} ${typeAttr} id="txt-${item.id}" class="xian-${item.type}" placeholder="${item.placeholder || ""}">${item.type === "textarea" ? this.config.settings[item.id] || "" : ""}</${tag}></div>`; } else if (item.type === "button") { const bindHtml = item.bind ? `<div class="xian-bind" id="bind-${item.bind}" data-key="${item.bind}">${this.cleanKeyName(this.config.keybinds[item.bind])}</div>` : ""; panesHtml += `<div class="xian-row" data-item-id="${item.id}" data-search-name="${item.name.toLowerCase()}" data-search-tip="${(item.tooltip || "").toLowerCase()}">${labelHtml}<div class="xian-controls">${bindHtml}<button class="xian-btn" id="btn-${item.id}" style="width: auto; padding: 4px 12px; margin-left: ${item.bind ? "5px" : "0"};">EXECUTE</button></div></div>`; } else { if (item.type === "checkbox") { const bindHtml = item.bind ? `<div class="xian-bind" id="bind-${item.bind}" data-key="${item.bind}">${this.cleanKeyName(this.config.keybinds[item.bind])}</div>` : ""; controlsHtml = `${bindHtml}<label class="xian-switch"><input type="checkbox" id="chk-${item.id}" ${this.config.settings[item.id] ? "checked" : ""}><span class="xian-slider"></span></label>`; } else if (item.type === "color") { controlsHtml = `<input type="color" id="col-${item.id}" value="${this.config.settings[item.id]}">`; } else if (item.type === "select") { controlsHtml = `<select class="xian-select" id="sel-${item.id}">${item.options.map((opt) => `<option value="${opt}" ${this.config.settings[item.id] === opt ? "selected" : ""}>${opt}</option>`).join("")}</select>`; } else if (item.type === "bind" || item.type === "customBind") { controlsHtml = `<div class="xian-bind" id="bind-${item.bind || item.id}" data-key="${item.bind || item.id}">${this.cleanKeyName(item.id === "profileHotkey" ? this.config.profiles[this.config.activeProfile]?.hotkey : this.config.keybinds[item.bind])}</div>`; } panesHtml += `<div class="xian-row" data-item-id="${item.id}" data-search-name="${item.name.toLowerCase()}" data-search-tip="${(item.tooltip || "").toLowerCase()}">${labelHtml}<div class="xian-controls">${controlsHtml}</div></div>`; } }); panesHtml += `</div></div>`; }); panesHtml += `</div>`; }); this.gui.innerHTML = `<div class="xian-header"><div class="xian-header-top"><div class="xian-brand-container"><img src="https://iili.io/qNroOue.png" class="xian-brand-logo" alt="logo"><div class="xian-brand-text">Xian<span>ware</span></div></div><div class="xian-close">✖</div></div><div class="xian-tabs">${tabsHtml}</div></div><div class="xian-content"><input type="text" id="xian-search" class="xian-search" placeholder="Search settings...">${panesHtml}</div><div class="xian-footer">Xianware V8.2.1 • Made with love by <span>simplexian</span></div>`; document.documentElement.appendChild(this.gui); this.gui.addEventListener("mousedown", (e) => e.stopPropagation()); this.gui.addEventListener("wheel", (e) => e.stopPropagation()); this.welcomeGui = document.createElement("div"); this.welcomeGui.id = "xian-welcome"; this.welcomeGui.innerHTML = `<div class="xian-header" style="justify-content: space-between; padding: 10px 14px; cursor: default; flex-direction: row; align-items: center;"><span style="font-weight: 700; color: var(--accent-color); text-transform: uppercase;">Xianware Announcement</span><div id="xian-welcome-close" class="xian-close" style="padding: 5px 10px; border-radius: 4px; font-size: 14px;">✖</div></div><div style="padding: 16px; font-size: 15px; line-height: 1.5; color: var(--text-main); font-weight: 600;">Join the official discord server at <a href="https://discord.gg/Jg6V3e6euj" target="_blank">https://discord.gg/Jg6V3e6euj</a> for the latest version / early access of the new update!<div id="xian-welcome-timer" style="margin-top: 14px; font-size: 13px; color: var(--text-muted); text-align: right; font-weight: 700; text-transform: uppercase;">Auto-closing in 30s...</div></div>`; document.documentElement.appendChild(this.welcomeGui); this.hudEl = document.createElement("div"); this.hudEl.id = "xian-hud"; document.documentElement.appendChild(this.hudEl); this.notificationEl = document.createElement("div"); this.notificationEl.className = "xian-notification"; document.documentElement.appendChild(this.notificationEl); } attachEventListeners() { const head = this.gui.querySelector(".xian-header"); let initLeft, initTop, startX, startY; const onDragMove = (e) => { let newLeft = initLeft + (e.clientX - startX); let newTop = initTop + (e.clientY - startY); const scale = this.config.settings.menuScale; const h = 40 * scale; newLeft = Math.max(-360, Math.min(window.innerWidth - 80, newLeft)); newTop = Math.max(0, Math.min(window.innerHeight - h, newTop)); this.gui.style.left = `${newLeft}px`; this.gui.style.top = `${newTop}px`; }; const onDragUp = () => { window.removeEventListener("mousemove", onDragMove); window.removeEventListener("mouseup", onDragUp); head.style.cursor = "grab"; }; head.addEventListener("mousedown", (e) => { if ( e.target.classList.contains("xian-tab") || e.target.classList.contains("xian-close") ) return; startX = e.clientX; startY = e.clientY; initLeft = this.gui.offsetLeft; initTop = this.gui.offsetTop; head.style.cursor = "grabbing"; window.addEventListener("mousemove", onDragMove); window.addEventListener("mouseup", onDragUp); }); this.gui.querySelector(".xian-close").onclick = () => (this.gui.style.display = "none"); const tabs = this.gui.querySelectorAll(".xian-tab"), panes = this.gui.querySelectorAll(".xian-tab-pane"); tabs.forEach((tab) => tab.addEventListener("click", () => { tabs.forEach((t) => t.classList.remove("active")); panes.forEach((p) => p.classList.remove("active")); tab.classList.add("active"); document .getElementById(`pane-${tab.dataset.target}`) .classList.add("active"); }), ); let wTimeLeft = 30; const wTimerText = document.getElementById("xian-welcome-timer"); const wInterval = setInterval(() => { wTimeLeft--; if (wTimerText) wTimerText.innerText = `Auto-closing in ${wTimeLeft}s...`; if (wTimeLeft <= 0) { clearInterval(wInterval); if (this.welcomeGui) this.welcomeGui.remove(); } }, 1000); document.getElementById("xian-welcome-close").onclick = () => { clearInterval(wInterval); this.welcomeGui.remove(); }; const searchInput = document.getElementById("xian-search"); if (searchInput) { searchInput.addEventListener("input", (e) => { const query = e.target.value.toLowerCase().trim(); const allRows = this.gui.querySelectorAll(".xian-row[data-item-id]"); const allGroups = this.gui.querySelectorAll(".xian-group"); allRows.forEach((row) => { const name = row.getAttribute("data-search-name") || ""; const tip = row.getAttribute("data-search-tip") || ""; const matches = !query || name.includes(query) || tip.includes(query); row.style.display = matches ? "" : "none"; }); allGroups.forEach((group) => { const visibleRows = group.querySelectorAll( '.xian-row[data-item-id]:not([style*="display: none"])', ); group.style.display = !query || visibleRows.length > 0 ? "" : "none"; }); if (query) { panes.forEach((p) => p.classList.add("active")); tabs.forEach((t) => t.classList.add("active")); } else { panes.forEach((p) => p.classList.remove("active")); tabs.forEach((t) => t.classList.remove("active")); tabs[0].classList.add("active"); panes[0].classList.add("active"); } }); } this.menuStructure.forEach((cat) => cat.groups.forEach((group) => group.items.forEach((item) => { const el = document.getElementById(`chk-${item.id}`) || document.getElementById(`sld-${item.id}`) || document.getElementById(`col-${item.id}`) || document.getElementById(`sel-${item.id}`) || document.getElementById(`txt-${item.id}`); if (el) { el.addEventListener( item.type === "slider" || item.type === "color" || item.type === "textarea" || item.type === "text" ? "input" : "change", (e) => { if ( item.id === "configData" || item.id === "profileSelect" || item.id === "profileName" ) return; this.config.settings[item.id] = item.type === "checkbox" ? e.target.checked : item.type === "slider" ? parseFloat(e.target.value) : e.target.value; if (item.type === "slider") { const valEl = document.getElementById(`val-${item.id}`); if (valEl) valEl.innerText = this.config.settings[item.id]; } if (item.id === "menuScale") { this.gui.style.transform = `scale(${this.config.settings.menuScale})`; if (this.welcomeGui) this.welcomeGui.style.transform = `scale(${this.config.settings.menuScale})`; } if (item.id === "menuTheme" || item.id === "menuColor") this.applyTheme(); if (item.type !== "textarea" && item.type !== "text") this.updateHud(); this.app.engine.updateMaterials(); this.queueSave(); }, ); } const btnMap = { loadCss: () => this.injectCustomCss(), reloadScript: () => this.app.engine.reset(), resetSettings: () => this.btnResetSettings(), loadProfile: () => this.btnLoadProfile(), saveProfile: () => this.btnSaveProfile(), deleteProfile: () => this.btnDeleteProfile(), setAutoLoad: () => this.btnSetAutoLoad(), createProfile: () => this.btnCreateProfile(), exportConfig: () => this.btnExportConfig(), importConfig: () => this.btnImportConfig(), }; if (item.type === "button" && btnMap[item.id]) { const btnEl = document.getElementById(`btn-${item.id}`); if (btnEl) btnEl.onclick = btnMap[item.id]; } if ( item.bind || item.type === "bind" || item.type === "customBind" ) { const bindBtn = document.getElementById( `bind-${item.bind || item.id}`, ); if (bindBtn) bindBtn.addEventListener("click", () => { if (this.bindingFeature) return; this.bindingFeature = item.bind || item.id; bindBtn.classList.add("active"); bindBtn.innerText = "..."; this.showToast("Press key to bind", item.name); }); } }), ), ); } buildMenuStructure() { return [ { title: "Combat", groups: [ { name: "Aimbot", items: [ { id: "aimbotEnabled", name: "Enable Aimbot", type: "checkbox", bind: "aimbotEnabled", tooltip: "Automatically aims at enemies.", }, { id: "aimbotOnRightMouse", name: "Aim on ADS", type: "checkbox", tooltip: "Only aims when holding the right mouse button.", }, { id: "aimOffset", name: "Aim Height", type: "slider", min: 0.0, max: 1.0, step: 0.05, tooltip: "Where to aim. 0 = Feet, 0.5 = Chest, 0.75 = Head, 1.0 = Top of Head.", }, { id: "wallCheck", name: "Visible Only", type: "checkbox", bind: "wallCheck", tooltip: "Won't aim at enemies hidden behind walls.", }, { id: "aimPrediction", name: "Aim Prediction", type: "checkbox", tooltip: "Leads targets based on their movement velocity.", }, { id: "predictionFactor", name: "Prediction Strength", type: "slider", min: 0.1, max: 3.0, step: 0.1, tooltip: "How far ahead to predict movement.", }, ], }, { name: "Aim Smoothing", items: [ { id: "smoothAim", name: "Smooth Aiming", type: "checkbox", tooltip: "Makes aiming look more natural and human-like.", }, { id: "aimHorizontal", name: "Horizontal Lock", type: "checkbox", tooltip: "Allows the aimbot to move left and right.", }, { id: "aimSpeedXMin", name: "Min X Speed", type: "slider", min: 0.01, max: 1.0, step: 0.01, tooltip: "Minimum horizontal aiming speed.", }, { id: "aimSpeedXMax", name: "Max X Speed", type: "slider", min: 0.01, max: 1.0, step: 0.01, tooltip: "Maximum horizontal aiming speed.", }, { id: "aimVertical", name: "Vertical Lock", type: "checkbox", tooltip: "Allows the aimbot to move up and down.", }, { id: "aimSpeedYMin", name: "Min Y Speed", type: "slider", min: 0.01, max: 1.0, step: 0.01, tooltip: "Minimum vertical aiming speed.", }, { id: "aimSpeedYMax", name: "Max Y Speed", type: "slider", min: 0.01, max: 1.0, step: 0.01, tooltip: "Maximum vertical aiming speed.", }, ], }, { name: "Free-Aim Tracking", items: [ { id: "horizontalFreeAim", name: "Horiz. Free-Aim", type: "checkbox", tooltip: "Allows manual horizontal movement while locked on.", }, { id: "verticalFreeAim", name: "Vert. Free-Aim", type: "checkbox", tooltip: "Allows manual vertical movement without breaking lock.", }, ], }, { name: "FOV Rules", items: [ { id: "drawFov", name: "Show FOV Circle", type: "checkbox", bind: "drawFov", tooltip: "Draws a circle to show the aimbot range.", }, { id: "fovRadius", name: "FOV Size", type: "slider", min: 50, max: 500, step: 10, tooltip: "How large the aimbot detection area is.", }, { id: "fovCircleColor", name: "FOV Color", type: "color", tooltip: "Color of the FOV circle.", }, { id: "fovCheck", name: "Require FOV", type: "checkbox", tooltip: "Only aims at enemies inside the FOV circle.", }, ], }, ], }, { title: "Visuals", groups: [ { name: "Player ESP", items: [ { id: "espEnabled", name: "Enable ESP", type: "checkbox", bind: "espEnabled", tooltip: "Draws a box around enemies so you can see them.", }, { id: "espRainbow", name: "Rainbow ESP", type: "checkbox", tooltip: "Makes the ESP box constantly change colors.", }, { id: "espColor", name: "ESP Color", type: "color", tooltip: "Choose a specific color for the ESP box.", }, { id: "espSnaplines", name: "Snaplines", type: "checkbox", bind: "espSnaplines", tooltip: "Draws lines from your screen to each enemy.", }, { id: "snaplineColor", name: "Line Color", type: "color", tooltip: "Color of the snaplines.", }, { id: "snaplineOrigin", name: "Line Origin", type: "select", options: ["Bottom", "Center", "Crosshair"], tooltip: "Where the snapline starts on your screen.", }, { id: "espDistance", name: "Show Distance", type: "checkbox", tooltip: "Displays the distance to each enemy in meters.", }, { id: "espDistanceColor", name: "Distance Color", type: "color", tooltip: "Color of the distance text.", }, ], }, { name: "Player Chams", items: [ { id: "chamsEnabled", name: "Enable Chams", type: "checkbox", bind: "chamsEnabled", tooltip: "Colors the enemy models so they are visible through walls.", }, { id: "chamsRainbow", name: "Rainbow Chams", type: "checkbox", tooltip: "Makes the enemy models constantly change colors.", }, { id: "chamsColor", name: "Chams Color", type: "color", tooltip: "Choose a specific color for the enemy models.", }, ], }, { name: "Target Indicator", items: [ { id: "targetIndicator", name: "Show Marker", type: "checkbox", tooltip: "Draws a marker above the enemy currently targeted.", }, { id: "indicatorShape", name: "Marker Shape", type: "select", options: ["Arrow", "Triangle", "Dot", "Image"], tooltip: "The design of the target marker.", }, { id: "indicatorColor", name: "Marker Color", type: "color", tooltip: "The color of the target marker.", }, { id: "indicatorSize", name: "Marker Size", type: "slider", min: 5, max: 100, step: 1, tooltip: "How big the target marker should be.", }, { id: "indicatorOpacity", name: "Marker Opacity", type: "slider", min: 0.1, max: 1.0, step: 0.05, tooltip: "How transparent the target marker is (1 = solid, 0.1 = faint).", }, { id: "indicatorImageUrl", name: "Custom Image URL", type: "text", placeholder: "https://example.com/image.png", tooltip: "Paste a direct link to an image (png/jpg) to use as the marker.", }, ], }, ], }, { title: "System", groups: [ { name: "Interface", items: [ { id: "menuToggle", name: "Menu Key", type: "bind", bind: "menuToggle", tooltip: "The keyboard key to open or close this menu.", }, { id: "menuTheme", name: "UI Theme", type: "select", options: ["Dark", "Light"], tooltip: "Switches the menu between Dark and Light mode.", }, { id: "menuColor", name: "Menu Accent", type: "color", tooltip: "The main color used for buttons and active tabs.", }, { id: "menuScale", name: "Menu Size", type: "slider", min: 0.5, max: 1.5, step: 0.1, tooltip: "Adjusts how big the menu appears on your screen.", }, { id: "showHud", name: "Enable HUD", type: "checkbox", bind: "showHud", tooltip: "Shows a small info box on screen with active features.", }, { id: "hudScale", name: "HUD Size", type: "slider", min: 0.5, max: 2.0, step: 0.1, tooltip: "Adjusts how big the HUD info box is.", }, { id: "hudPosition", name: "HUD Location", type: "select", options: [ "Top Left", "Top Right", "Bottom Left", "Bottom Right", ], tooltip: "Where the HUD is placed on your screen.", }, { id: "showNotifications", name: "Notifications", type: "checkbox", bind: "showNotifications", tooltip: "Shows small popup alerts when you toggle features.", }, ], }, { name: "Customization & Fixes", items: [ { id: "customCssText", name: "Custom CSS", type: "textarea", placeholder: "/* Paste CSS code here */\n.headerBar { display: none; }", tooltip: "Write your own CSS code to change how the game looks.", }, { id: "loadCss", name: "Apply CSS", type: "button", tooltip: "Activates your custom CSS code immediately.", }, { id: "reloadScript", name: "Reload Cheat", type: "button", bind: "reloadScript", tooltip: "Refreshes the cheat if it glitches or stops working.", }, { id: "resetSettings", name: "Factory Reset", type: "button", tooltip: "Restores all settings in the current profile back to default.", }, ], }, ], }, { title: "Config", groups: [ { name: "Profiles", items: [ { id: "profileSelect", name: "Select Profile", type: "select", options: ["Default"], tooltip: "Choose a saved profile from the list.", }, { id: "loadProfile", name: "Load Profile", type: "button", tooltip: "Loads the settings of the selected profile.", }, { id: "saveProfile", name: "Save Profile", type: "button", tooltip: "Saves your current settings to the active profile.", }, { id: "deleteProfile", name: "Delete Profile", type: "button", tooltip: "Permanently removes the selected profile.", }, { id: "setAutoLoad", name: "Set Startup Profile", type: "button", tooltip: "Makes the selected profile load automatically when you join a game.", }, { id: "profileHotkey", name: "Profile Hotkey", type: "customBind", bind: "profileHotkey", tooltip: "Assign a key to instantly switch to the active profile.", }, { id: "profileName", name: "New Profile Name", type: "text", placeholder: "Enter new name...", tooltip: "Type a name for your new settings profile.", }, { id: "createProfile", name: "Create Profile", type: "button", tooltip: "Creates a new profile with the name you typed above.", }, ], }, { name: "Data Management", items: [ { id: "configData", name: "Config Data", type: "textarea", placeholder: "Paste config JSON here to import...", tooltip: "The raw text data of your settings. Use this to share or backup.", }, { id: "exportConfig", name: "Copy to Clipboard", type: "button", tooltip: "Copies your settings text so you can save it elsewhere.", }, { id: "importConfig", name: "Load from Text", type: "button", tooltip: "Applies settings from the text you pasted above.", }, ], }, ], }, ]; } } class InputManager { constructor(app) { this.app = app; this.rightMouseDown = false; } init() { window.addEventListener("pointerdown", (e) => { if (e.button === 2) this.rightMouseDown = true; }); window.addEventListener("pointerup", (e) => { if (e.button === 2) this.rightMouseDown = false; }); window.addEventListener("keydown", (e) => { const ui = this.app.ui; const config = this.app.config; if (ui.bindingFeature) { e.preventDefault(); e.stopPropagation(); if (ui.bindingFeature === "profileHotkey") { const code = e.code === "Escape" ? "" : e.code; if (code !== "") for (let p in config.profiles) if (config.profiles[p].hotkey === code) config.profiles[p].hotkey = ""; config.profiles[config.activeProfile].hotkey = code; config.save(); const btn = document.getElementById("bind-profileHotkey"); if (btn) { btn.innerText = ui.cleanKeyName(code); btn.classList.remove("active"); } ui.showToast("Profile Hotkey bound to", ui.cleanKeyName(code)); } else { if (e.code === "Escape") { config.keybinds[ui.bindingFeature] = ""; const btn = document.getElementById(`bind-${ui.bindingFeature}`); if (btn) { btn.innerText = "NONE"; btn.classList.remove("active"); } ui.showToast("Unbound feature", ""); } else { config.keybinds[ui.bindingFeature] = e.code; const btn = document.getElementById(`bind-${ui.bindingFeature}`); if (btn) { btn.innerText = ui.cleanKeyName(e.code); btn.classList.remove("active"); } ui.showToast("Bound to", ui.cleanKeyName(e.code)); } } config.updateKeyMaps(); ui.bindingFeature = null; return; } if ( document.activeElement && (document.activeElement.tagName === "INPUT" || document.activeElement.tagName === "TEXTAREA") ) return; if (config.profileKeyMap[e.code]) { const targetProfile = config.profileKeyMap[e.code]; if (config.activeProfile !== targetProfile) { config.applyProfile(targetProfile); ui.refreshUI(); ui.showToast("Profile Loaded", targetProfile.toUpperCase()); } return; } const feature = config.reverseKeyMap[e.code]; if (feature) { if (feature === "menuToggle") { if (ui.gui) ui.gui.style.display = ui.gui.style.display === "none" ? "block" : "none"; } else if (feature === "reloadScript") { this.app.engine.reset(); } else if (typeof config.settings[feature] === "boolean") { config.settings[feature] = !config.settings[feature]; ui.updateHud(); const chk = document.getElementById(`chk-${feature}`); if (chk) chk.checked = config.settings[feature]; let displayName = feature; ui.menuStructure.forEach((cat) => cat.groups.forEach((g) => { const item = g.items.find((i) => i.id === feature); if (item) displayName = item.name; }), ); ui.showToast(displayName, config.settings[feature] ? "ON" : "OFF"); ui.queueSave(); } } }); } } class Engine { constructor(app) { this.app = app; this.scene = null; this.gameCamera = null; this.cachedPlayers = []; this.mapMeshes = []; this.myPlayerCache = null; this.lastMapScrape = 0; this.lastNonPlayerCount = -1; this.lockedTarget = null; this.lastFrameTime = performance.now(); this.canvasNeedsClear = false; this.hue = 0; this.cachedIndicatorImage = new Image(); this.currentImageUrl = ""; this.aimCandidates = []; this.nonPlayerObjects = []; this._pool = null; this.geometry = null; this.espMaterial = null; this.chamsMaterial = null; this.line = null; this.linePositions = null; this.originalPush = Array.prototype.push; } init() { if (!THREE) return; this._pool = { tempVec: new THREE.Vector3(), tempObj: new THREE.Object3D(), originVec: new THREE.Vector3(), destVec: new THREE.Vector3(), dirVec: new THREE.Vector3(), camPos: new THREE.Vector3(), centerVec: new THREE.Vector3(), topVec: new THREE.Vector3(), botVec: new THREE.Vector3(), targetVec: new THREE.Vector3(), raycaster: new THREE.Raycaster(), tempBox: new THREE.Box3(), localPos: new THREE.Vector3(), worldPos: new THREE.Vector3(), fallbackOffset: new THREE.Vector3(0, 5.5, 0), fallbackSize: new THREE.Vector3(3.5, 11, 3.5), }; this._pool.tempObj.rotation.order = "YXZ"; this.geometry = new THREE.EdgesGeometry(new THREE.BoxGeometry(1, 1, 1)); this.espMaterial = new THREE.RawShaderMaterial({ uniforms: { uColor: { value: new THREE.Color(this.app.config.settings.espColor) }, }, vertexShader: "precision mediump float; attribute vec3 position; uniform mat4 projectionMatrix; uniform mat4 modelViewMatrix; void main() { gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); }", fragmentShader: "precision mediump float; uniform vec3 uColor; void main() { gl_FragColor = vec4(uColor, 1.0); }", }); this.espMaterial.depthTest = false; this.espMaterial.depthWrite = false; this.espMaterial.transparent = true; this.line = new THREE.LineSegments( new THREE.BufferGeometry(), this.espMaterial, ); this.line.frustumCulled = false; this.linePositions = new THREE.BufferAttribute( new Float32Array(100 * 2 * 3), 3, ); this.line.geometry.setAttribute("position", this.linePositions); this.chamsMaterial = new THREE.MeshBasicMaterial({ color: new THREE.Color(this.app.config.settings.chamsColor), depthTest: false, depthWrite: false, transparent: true, opacity: 0.8, }); this.hookArrayPush(); this.renderLoop(); } updateMaterials() { if (this.espMaterial) this.espMaterial.uniforms.uColor.value.set( this.app.config.settings.espColor, ); if (this.chamsMaterial) this.chamsMaterial.color.set(this.app.config.settings.chamsColor); } hookArrayPush() { const self = this; const origPush = this.originalPush; if (Array.prototype.push === origPush) { Object.defineProperty(Array.prototype, "push", { configurable: true, enumerable: false, writable: true, value: function () { for (let i = 0; i < arguments.length; i++) { const obj = arguments[i]; if ( !self.scene && obj && typeof obj === "object" && obj.parent && obj.parent.type === "Scene" && obj.parent.name === "Main" ) { self.scene = obj.parent; Object.defineProperty(Array.prototype, "push", { configurable: true, enumerable: false, writable: true, value: origPush, }); } } return origPush.apply(this, arguments); }, }); } } reset() { this.scene = null; this.gameCamera = null; this.cachedPlayers.length = 0; this.mapMeshes.length = 0; this.myPlayerCache = null; this.lastMapScrape = 0; this.lastNonPlayerCount = -1; this.lockedTarget = null; this.hookArrayPush(); this.app.ui.showToast("Cheat Reloaded", "SCANNING"); } getPlayerHead(player) { try { const c0 = player?.children?.[0]; const c00 = c0?.children?.[0]; return c00 || null; } catch (e) { return null; } } renderLoop = () => { x.requestAnimationFrame.call(x.window, this.renderLoop); if (!THREE || !this.app.ui.ctx || !this._pool) return; const s = this.app.config.settings; const ctx = this.app.ui.ctx; const canvas = this.app.ui.canvas; let currentTime = performance.now(); let delta = currentTime - this.lastFrameTime; if (delta > 100) delta = 16; this.lastFrameTime = currentTime; this.updateRainbow(s); this.updateIndicatorImage(s); let needs2D = s.drawFov || s.targetIndicator || s.espSnaplines || s.espDistance; if (needs2D || this.canvasNeedsClear) { ctx.clearRect(0, 0, canvas.width, canvas.height); this.canvasNeedsClear = needs2D; } if (s.drawFov) { ctx.beginPath(); ctx.arc( canvas.width / 2, canvas.height / 2, s.fovRadius, 0, 2 * Math.PI, ); ctx.strokeStyle = s.espRainbow ? `hsl(${this.hue}, 100%, 50%)` : s.fovCircleColor; ctx.lineWidth = 1.5; ctx.stroke(); } if (!this.scene || !this.scene.children) return; this.scanScene(currentTime); if (!this.myPlayerCache || !this.gameCamera) return; const centerX = canvas.width / 2; const centerY = canvas.height / 2; const fovRadiusSq = s.fovRadius * s.fovRadius; const myHead = this.getPlayerHead(this.myPlayerCache); if (myHead) myHead.updateMatrixWorld(true); if (s.espEnabled) this._pool.tempObj.matrix.copy(this.myPlayerCache.matrix).invert(); this.aimCandidates.length = 0; let counter = 0; for (let i = 0; i < this.cachedPlayers.length; i++) { const player = this.cachedPlayers[i]; if (!player.box) { const box = new THREE.LineSegments(this.geometry, this.espMaterial); box.frustumCulled = false; player.add(box); player.box = box; } if ( player.position.x === this.myPlayerCache.position.x && player.position.z === this.myPlayerCache.position.z ) { player.box.visible = false; if (this.line.parent !== player) player.add(this.line); continue; } player.visible = s.espEnabled || player.visible || s.chamsEnabled; player.box.visible = s.espEnabled; if (!player._xBox) player._xBox = new THREE.Box3(); if (!player._xSize) player._xSize = new THREE.Vector3(); if (!player._xCenter) player._xCenter = new THREE.Vector3(); if (!player._xRawSize) player._xRawSize = new THREE.Vector3(); if (!player._xRawCenter) player._xRawCenter = new THREE.Vector3(); if (!player._xLastPos) player._xLastPos = new THREE.Vector3().copy(player.position); if (!player._xVelocity) player._xVelocity = new THREE.Vector3(); player._xVelocity.copy(player.position).sub(player._xLastPos); player._xLastPos.copy(player.position); player._xBox.makeEmpty(); let hasMesh = false; const applyChams = s.chamsEnabled; player.traverse((obj) => { if (!obj.isMesh || obj === player.box) return; if (!obj.visible) return; if (obj.geometry) { if (obj.geometry.boundingBox === null) obj.geometry.computeBoundingBox(); this._pool.tempBox.copy(obj.geometry.boundingBox); this._pool.tempBox.applyMatrix4(obj.matrixWorld); player._xBox.union(this._pool.tempBox); hasMesh = true; } if (applyChams) { if (!obj.userData.originalMaterial) obj.userData.originalMaterial = obj.material; obj.material = this.chamsMaterial; } else if ( obj.userData.originalMaterial && obj.material === this.chamsMaterial ) { obj.material = obj.userData.originalMaterial; } }); if (!hasMesh) { this._pool.tempVec .copy(player.position) .add(this._pool.fallbackOffset); player._xBox.setFromCenterAndSize( this._pool.tempVec, this._pool.fallbackSize, ); } player._xBox.getSize(player._xRawSize); player._xBox.getCenter(player._xRawCenter); let tightBodyWidth = 3.5; player._xSize.set(tightBodyWidth, player._xRawSize.y, tightBodyWidth); player._xCenter.set( player.position.x, player._xRawCenter.y, player.position.z, ); if (s.espEnabled) { player.box.scale.copy(player._xSize); this._pool.localPos.copy(player._xCenter); player.worldToLocal(this._pool.localPos); player.box.position.copy(this._pool.localPos); this.linePositions.setXYZ(counter++, 0, 10, -5); this._pool.tempVec .copy(player._xCenter) .applyMatrix4(this._pool.tempObj.matrix); this.linePositions.setXYZ( counter++, this._pool.tempVec.x, this._pool.tempVec.y, this._pool.tempVec.z, ); } if (s.espSnaplines && this.gameCamera) { const head = this.getPlayerHead(player); if (head) { head.getWorldPosition(this._pool.worldPos); this._pool.worldPos.project(this.gameCamera); if (this._pool.worldPos.z < 1) { const sx = (this._pool.worldPos.x + 1) * centerX; const sy = (-this._pool.worldPos.y + 1) * centerY; let originX = centerX, originY; switch (s.snaplineOrigin) { case "Bottom": originY = canvas.height; break; case "Center": originY = centerY; break; case "Crosshair": originY = centerY; break; default: originY = canvas.height; } ctx.beginPath(); ctx.moveTo(originX, originY); ctx.lineTo(sx, sy); ctx.strokeStyle = s.espRainbow ? `hsl(${this.hue}, 100%, 50%)` : s.snaplineColor; ctx.lineWidth = 1; ctx.stroke(); } } } if (s.espDistance && this.gameCamera) { this._pool.worldPos.copy(player._xCenter); this._pool.worldPos.y = player._xBox.min.y; this._pool.worldPos.project(this.gameCamera); if (this._pool.worldPos.z < 1) { const sx = (this._pool.worldPos.x + 1) * centerX; const sy = (-this._pool.worldPos.y + 1) * centerY; const dist = Math.sqrt( player.position.distanceToSquared(this.myPlayerCache.position), ).toFixed(0); ctx.font = "bold 13px Rajdhani"; ctx.textAlign = "center"; ctx.fillStyle = "#000"; ctx.fillText(`${dist}m`, sx + 1, sy + 16); ctx.fillStyle = s.espDistanceColor; ctx.fillText(`${dist}m`, sx, sy + 15); } } if (s.aimbotEnabled) { let inFov = true; let distToCenterSq = 0; if (s.fovCheck) { const head = this.getPlayerHead(player); if (head) { head.getWorldPosition(this._pool.tempVec); this._pool.tempVec.project(this.gameCamera); const dx = (this._pool.tempVec.x + 1) * centerX - centerX; const dy = (-this._pool.tempVec.y + 1) * centerY - centerY; distToCenterSq = dx * dx + dy * dy; if (this._pool.tempVec.z > 1 || distToCenterSq > fovRadiusSq) inFov = false; } else { inFov = false; } } if (inFov) { this.aimCandidates.push({ player: player, dist3D: player.position.distanceToSquared( this.myPlayerCache.position, ), distFOV: distToCenterSq, }); } } } if (s.espEnabled) { this.linePositions.needsUpdate = true; this.line.geometry.setDrawRange(0, counter); this.line.visible = false; } const shouldAimbot = s.aimbotEnabled && (!s.aimbotOnRightMouse || this.app.input.rightMouseDown); let targetPlayer = null; if (shouldAimbot && this.aimCandidates.length > 0) { if (s.fovCheck) this.aimCandidates.sort((a, b) => a.distFOV - b.distFOV); else this.aimCandidates.sort((a, b) => a.dist3D - b.dist3D); const checkWall = (candidate) => { if (!s.wallCheck || this.mapMeshes.length === 0) return true; if ( candidate.lastWallCheckTime && currentTime - candidate.lastWallCheckTime < 100 ) return candidate.isWallVisible; const myHead = this.getPlayerHead(this.myPlayerCache); const enemyHead = this.getPlayerHead(candidate); if (!myHead || !enemyHead) return false; myHead.getWorldPosition(this._pool.originVec); enemyHead.getWorldPosition(this._pool.destVec); const distToEnemy = this._pool.originVec.distanceTo( this._pool.destVec, ); this._pool.dirVec .copy(this._pool.destVec) .sub(this._pool.originVec) .normalize(); this._pool.raycaster.set(this._pool.originVec, this._pool.dirVec); this._pool.raycaster.far = distToEnemy; const intersects = this._pool.raycaster.intersectObjects( this.mapMeshes, false, ); let isVisible = true; for (let j = 0; j < intersects.length; j++) { const hit = intersects[j].object; if (hit.visible && (!hit.material || hit.material.opacity > 0.5)) { isVisible = false; break; } } candidate.lastWallCheckTime = currentTime; candidate.isWallVisible = isVisible; return isVisible; }; let lockedCandidate = this.lockedTarget ? this.aimCandidates.find((c) => c.player === this.lockedTarget) : null; if (lockedCandidate && checkWall(lockedCandidate.player)) { targetPlayer = this.lockedTarget; } else { for (let i = 0; i < this.aimCandidates.length; i++) { if (checkWall(this.aimCandidates[i].player)) { targetPlayer = this.aimCandidates[i].player; break; } } this.lockedTarget = targetPlayer; } } else { this.lockedTarget = null; } if (targetPlayer && s.targetIndicator && this.gameCamera) { this._pool.tempVec.set( targetPlayer._xCenter.x, targetPlayer._xBox.max.y + 1.5, targetPlayer._xCenter.z, ); this._pool.tempVec.project(this.gameCamera); if (this._pool.tempVec.z < 1) { const screenX = (this._pool.tempVec.x + 1) * centerX; const screenY = (-this._pool.tempVec.y + 1) * centerY; ctx.globalAlpha = s.indicatorOpacity; const isz = s.indicatorSize; if (s.indicatorShape === "Image") { if ( this.cachedIndicatorImage.complete && this.cachedIndicatorImage.naturalWidth > 0 ) { ctx.drawImage( this.cachedIndicatorImage, screenX - isz, screenY - isz * 2, isz * 2, isz * 2, ); } } else { ctx.beginPath(); if (s.indicatorShape === "Dot") { ctx.arc(screenX, screenY - isz * 0.6, isz * 0.5, 0, Math.PI * 2); } else if (s.indicatorShape === "Triangle") { ctx.moveTo(screenX, screenY); ctx.lineTo(screenX - isz * 0.6, screenY - isz * 1.2); ctx.lineTo(screenX + isz * 0.6, screenY - isz * 1.2); } else { ctx.moveTo(screenX, screenY); ctx.lineTo(screenX - isz * 0.5, screenY - isz * 0.6); ctx.lineTo(screenX - isz * 0.2, screenY - isz * 0.6); ctx.lineTo(screenX - isz * 0.2, screenY - isz * 1.2); ctx.lineTo(screenX + isz * 0.2, screenY - isz * 1.2); ctx.lineTo(screenX + isz * 0.2, screenY - isz * 0.6); ctx.lineTo(screenX + isz * 0.5, screenY - isz * 0.6); } ctx.closePath(); ctx.fillStyle = s.indicatorColor; ctx.fill(); ctx.strokeStyle = "rgba(0,0,0,0.8)"; ctx.lineWidth = 1.5; ctx.stroke(); } ctx.globalAlpha = 1.0; } } if (!targetPlayer) return; this.executeAimbot(s, targetPlayer); }; updateRainbow(s) { if (s.espRainbow || s.chamsRainbow) this.hue = (this.hue + 1) % 360; if (s.espEnabled && s.espRainbow) this.espMaterial.uniforms.uColor.value.setHSL(this.hue / 360, 1, 0.5); if (s.chamsEnabled && this.chamsMaterial) { if (s.chamsRainbow) this.chamsMaterial.color.setHSL(this.hue / 360, 1, 0.5); else this.chamsMaterial.color.set(s.chamsColor); } } updateIndicatorImage(s) { if ( s.indicatorShape === "Image" && s.indicatorImageUrl !== this.currentImageUrl ) { this.currentImageUrl = s.indicatorImageUrl; if (this.currentImageUrl) this.cachedIndicatorImage.src = this.currentImageUrl; } } scanScene(currentTime) { this.cachedPlayers.length = 0; this.myPlayerCache = null; this.nonPlayerObjects.length = 0; for (let i = 0; i < this.scene.children.length; i++) { const child = this.scene.children[i]; let isPlayer = false; if (child.type === "Object3D") { try { const c0 = child.children[0]; if (c0 && c0.children && c0.children[0]) { if (c0.children[0].type === "PerspectiveCamera") { this.myPlayerCache = child; this.gameCamera = c0.children[0]; isPlayer = true; } else { this.cachedPlayers.push(child); isPlayer = true; } } } catch (err) {} } if (!isPlayer) this.nonPlayerObjects.push(child); } if (this.nonPlayerObjects.length !== this.lastNonPlayerCount) { if ( currentTime - this.lastMapScrape > 1000 || this.lastNonPlayerCount === -1 ) { this.mapMeshes.length = 0; for (let i = 0; i < this.nonPlayerObjects.length; i++) { const child = this.nonPlayerObjects[i]; if (child.material) child.material.wireframe = false; child.traverse((node) => { if (node.isMesh && node.visible) { if ( node.material && (node.material.transparent || node.material.opacity < 0.9 || node.material.depthWrite === false) ) return; if (node.geometry) { if (node.geometry.boundingSphere === null) node.geometry.computeBoundingSphere(); if (node.geometry.boundingBox === null) node.geometry.computeBoundingBox(); } this.mapMeshes.push(node); } }); } this.lastNonPlayerCount = this.nonPlayerObjects.length; this.lastMapScrape = currentTime; } } } executeAimbot(s, targetPlayer) { this.gameCamera.getWorldPosition(this._pool.camPos); let headTopY = targetPlayer._xBox.max.y; let feetY = targetPlayer._xBox.min.y; let dynamicHeight = targetPlayer._xSize.y; const getPitchYaw = (vec) => { this._pool.tempObj.position.copy(this._pool.camPos); this._pool.tempObj.lookAt(vec); let p = Math.max( -Math.PI / 2, Math.min(Math.PI / 2, -this._pool.tempObj.rotation.x), ); let y = this._pool.tempObj.rotation.y + Math.PI; return { pitch: p, yaw: y }; }; this._pool.centerVec.set( targetPlayer._xCenter.x, targetPlayer.position.y, targetPlayer._xCenter.z, ); if (s.aimPrediction && targetPlayer._xVelocity) { const dist = this._pool.camPos.distanceTo(targetPlayer.position); const travelTime = dist / 600; const leadFactor = travelTime * s.predictionFactor * 60; this._pool.centerVec.x += targetPlayer._xVelocity.x * leadFactor; this._pool.centerVec.z += targetPlayer._xVelocity.z * leadFactor; } let targetYaw = getPitchYaw(this._pool.centerVec).yaw; let angleDiff = targetYaw - this.myPlayerCache.rotation.y; while (angleDiff > Math.PI) angleDiff -= Math.PI * 2; while (angleDiff < -Math.PI) angleDiff += Math.PI * 2; if (s.aimHorizontal && s.horizontalFreeAim) { let distToTarget = this._pool.camPos.distanceTo(targetPlayer.position); let deadzoneAngle = Math.atan2(targetPlayer._xSize.x / 2, distToTarget); if (Math.abs(angleDiff) <= deadzoneAngle) angleDiff = 0; else angleDiff = angleDiff > 0 ? angleDiff - deadzoneAngle : angleDiff + deadzoneAngle; } let currentPitch = this.myPlayerCache.children[0].rotation.x; let pitchDiff = 0; if (s.aimVertical) { let predOffsetX = 0, predOffsetZ = 0; if (s.aimPrediction && targetPlayer._xVelocity) { const dist = this._pool.camPos.distanceTo(targetPlayer.position); const travelTime = dist / 600; const leadFactor = travelTime * s.predictionFactor * 60; predOffsetX = targetPlayer._xVelocity.x * leadFactor; predOffsetZ = targetPlayer._xVelocity.z * leadFactor; } if (s.verticalFreeAim) { this._pool.topVec.set( targetPlayer._xCenter.x + predOffsetX, headTopY, targetPlayer._xCenter.z + predOffsetZ, ); this._pool.botVec.set( targetPlayer._xCenter.x + predOffsetX, feetY, targetPlayer._xCenter.z + predOffsetZ, ); let topPitch = getPitchYaw(this._pool.topVec).pitch; let botPitch = getPitchYaw(this._pool.botVec).pitch; let maxPitch = Math.max(topPitch, botPitch); let minPitch = Math.min(topPitch, botPitch); if (currentPitch < minPitch) pitchDiff = minPitch - currentPitch; else if (currentPitch > maxPitch) pitchDiff = maxPitch - currentPitch; else pitchDiff = 0; } else { let targetY = feetY + dynamicHeight * s.aimOffset; this._pool.targetVec.set( targetPlayer._xCenter.x + predOffsetX, targetY, targetPlayer._xCenter.z + predOffsetZ, ); let targetPitch = getPitchYaw(this._pool.targetVec).pitch; pitchDiff = targetPitch - currentPitch; } } let targetPitchOffset = currentPitch + pitchDiff; targetPitchOffset = Math.max( -Math.PI / 2, Math.min(Math.PI / 2, targetPitchOffset), ); if (s.smoothAim) { const minX = Math.min(s.aimSpeedXMin, s.aimSpeedXMax); const maxX = Math.max(s.aimSpeedXMin, s.aimSpeedXMax); const minY = Math.min(s.aimSpeedYMin, s.aimSpeedYMax); const maxY = Math.max(s.aimSpeedYMin, s.aimSpeedYMax); const speedX = (minX + Math.random() * (maxX - minX)) * 0.4; const speedY = (minY + Math.random() * (maxY - minY)) * 0.4; if (s.aimVertical && pitchDiff !== 0) { this.myPlayerCache.children[0].rotation.x = MathUtils.lerp( this.myPlayerCache.children[0].rotation.x, targetPitchOffset, speedY, ); } if (s.aimHorizontal && angleDiff !== 0) { this.myPlayerCache.rotation.y += angleDiff * speedX; } } else { if (s.aimVertical && pitchDiff !== 0) this.myPlayerCache.children[0].rotation.x = targetPitchOffset; if (s.aimHorizontal && angleDiff !== 0) this.myPlayerCache.rotation.y += angleDiff; } } } class Xianware { constructor() { this.config = new ConfigManager(); this.ui = new UIManager(this); this.input = new InputManager(this); this.engine = new Engine(this); this.isInitialized = false; } init() { if (this.isInitialized) return; this.isInitialized = true; this.ui.init(); this.input.init(); this.engine.init(); if (this.config.settings.customCssText) this.ui.injectCustomCss(); console.log("[Xianware] V8.2.1 Initialized Successfully."); } } const x = { window: window, document: document, requestAnimationFrame: window.requestAnimationFrame, }; const app = new Xianware(); if ( document.readyState === "complete" || document.readyState === "interactive" ) { app.init(); } else { window.addEventListener("DOMContentLoaded", () => app.init()); window.addEventListener("load", () => app.init()); } })();