Enhanced Bloxd.io client with modern UI
// ==UserScript==
// @name BounceClient
// @namespace http://tampermonkey.net/
// @version 1.0
// @description Enhanced Bloxd.io client with modern UI
// @author ninja + CyphrNX + marcus (Modified for BounceClient)
// @match *://*.bloxd.io/*
// @grant none
// ==/UserScript==
(function () {
'use strict';
if (document.getElementById('bounceclient-root')) return;
// --- Module definitions ---
const Modules = {
Blatant: { "Killaura": false, "Scaffold": false },
Visual: { "ESP": false, "Coords": false },
Legit: { "FPS Counter": false, "CPS Counter": false, "Keystrokes": false }
};
// Keybinds configuration
const Keybinds = {
"Killaura": null,
"Scaffold": null,
"ESP": null,
"Coords": null
};
// Module configuration
const Config = {
Killaura: {
delay: 50,
range: 4.5,
jitter: 0
},
Scaffold: {
delay: 50,
tower: false
},
ESP: {
chestUpdateInterval: 3000,
playerUpdateInterval: 100,
wireframeColor: [0, 0.7, 1] // Cyan RGB
},
Coords: {
updateInterval: 100
}
};
// Load config from localStorage
const savedConfig = localStorage.getItem('bounceclient-config');
if (savedConfig) {
try {
Object.assign(Config, JSON.parse(savedConfig));
} catch(e) {
console.error("Failed to load config:", e);
}
}
// Save config to localStorage
function saveConfig() {
localStorage.setItem('bounceclient-config', JSON.stringify(Config));
}
let currentCategory = "Blatant";
let gameState = {};
let injectionStatus = { injected: false, failed: false }; // Track injection status
let injectionRetryInterval = null;
let objectUtils = {
keys(e) {
var t = [], n = 0;
for (var o in e) null != e && (t[n] = o, n++);
return t;
},
values(e) {
for (var t = this.keys(e), n = [], o = 0, i = 0; o < t.length;) {
var a = e[t[o]];
n[i] = a, i++, o++;
}
return n;
}
};
// === GUI Setup ===
const root = document.createElement("div");
root.id = "bounceclient-root";
document.body.appendChild(root);
const style = document.createElement("style");
style.textContent = `
:root {
--primary: #00d4ff;
--primary-dark: #0099cc;
--secondary: #7c4dff;
--bg: rgba(15, 15, 30, 0.95);
--card-bg: rgba(25, 25, 45, 0.8);
--border: rgba(100, 100, 255, 0.3);
--text: #ffffff;
--text-secondary: rgba(255, 255, 255, 0.7);
}
#bounceclient-root * {
font-family: 'Segoe UI', system-ui, sans-serif;
box-sizing: border-box;
transition: all 0.2s ease;
}
#bounceclient-gui {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 500px;
max-width: 90vw;
background: var(--bg);
color: var(--text);
border-radius: 16px;
border: 1px solid var(--border);
backdrop-filter: blur(10px);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
display: none;
flex-direction: column;
z-index: 999999;
overflow: hidden;
}
#bounceclient-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 20px;
background: linear-gradient(135deg, var(--primary), var(--secondary));
border-bottom: 1px solid var(--border);
}
.title {
font-weight: 800;
font-size: 24px;
text-shadow: 0 0 10px rgba(0, 212, 255, 0.5);
letter-spacing: 1px;
}
.title sup {
font-size: 14px;
color: var(--text);
opacity: 0.8;
}
#category-buttons {
display: flex;
gap: 8px;
margin: 16px;
margin-bottom: 0;
}
.cat-btn {
flex: 1;
padding: 10px;
border-radius: 10px;
border: 1px solid var(--border);
background: var(--card-bg);
color: var(--text-secondary);
cursor: pointer;
text-align: center;
font-weight: 600;
transition: all 0.2s;
}
.cat-btn:hover {
background: rgba(255, 255, 255, 0.1);
transform: translateY(-2px);
}
.cat-btn.on {
background: linear-gradient(135deg, var(--primary), var(--secondary));
color: white;
border-color: transparent;
box-shadow: 0 4px 12px rgba(0, 212, 255, 0.3);
}
#bounceclient-content {
display: flex;
padding: 16px;
gap: 16px;
}
#bounceclient-mods {
flex: 1;
display: flex;
flex-direction: column;
gap: 12px;
}
.module {
display: flex;
align-items: center;
justify-content: space-between;
padding: 14px 16px;
border-radius: 12px;
background: var(--card-bg);
border: 1px solid var(--border);
cursor: pointer;
transition: all 0.2s;
}
.module:hover {
background: rgba(255, 255, 255, 0.08);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}
.module-name {
font-weight: 600;
font-size: 16px;
}
.toggle {
width: 48px;
height: 24px;
border-radius: 24px;
background: rgba(255, 255, 255, 0.15);
position: relative;
cursor: pointer;
}
.knob {
position: absolute;
top: 3px;
left: 3px;
width: 18px;
height: 18px;
background: white;
border-radius: 50%;
transition: all 0.2s;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
.toggle.on {
background: linear-gradient(90deg, var(--primary), var(--secondary));
}
.toggle.on .knob {
left: 27px;
}
#themes {
width: 160px;
display: flex;
flex-direction: column;
gap: 12px;
}
#themeLabel {
font-weight: 700;
color: var(--primary);
margin-bottom: 4px;
text-shadow: 0 0 8px rgba(0, 212, 255, 0.5);
}
.theme {
padding: 12px;
border-radius: 10px;
border: 1px solid var(--border);
background: var(--card-bg);
cursor: pointer;
transition: all 0.2s;
}
.theme:hover {
background: rgba(255, 255, 255, 0.1);
transform: translateY(-2px);
}
.keybind-btn {
width: 36px;
height: 24px;
font-size: 10px;
padding: 0;
margin-left: 10px;
cursor: pointer;
border: 1px solid var(--border);
background: var(--card-bg);
color: var(--text-secondary);
border-radius: 6px;
transition: all 0.2s;
}
.keybind-btn:hover {
background: rgba(255, 255, 255, 0.1);
}
.module-info {
display: flex;
align-items: center;
flex: 1;
}
.keybind-label {
font-size: 11px;
opacity: 0.6;
margin-left: 8px;
}
#inject-status {
width: 14px;
height: 14px;
border-radius: 50%;
margin-left: 12px;
transition: background 0.3s;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.3);
}
#inject-status.red {
background: #ff3b49;
box-shadow: 0 0 8px rgba(255, 59, 73, 0.5);
}
#inject-status.green {
background: #34dd55;
box-shadow: 0 0 8px rgba(52, 221, 85, 0.5);
}
#inject-status.yellow {
background: #ffa500;
box-shadow: 0 0 8px rgba(255, 165, 0, 0.5);
}
#inject-btn, #settings-btn {
padding: 10px 16px;
background: linear-gradient(135deg, var(--primary), var(--secondary));
border: none;
border-radius: 10px;
color: white;
cursor: pointer;
font-weight: 700;
font-size: 13px;
margin-top: 8px;
transition: all 0.2s;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
#inject-btn:hover, #settings-btn:hover {
transform: translateY(-2px);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.3);
}
#settings-panel {
display: none;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 500px;
max-width: 90vw;
background: var(--bg);
color: var(--text);
border: 1px solid var(--border);
border-radius: 16px;
backdrop-filter: blur(10px);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
z-index: 1000000;
padding: 24px;
max-height: 80vh;
overflow-y: auto;
}
#settings-panel.show {
display: block;
}
.settings-section {
margin-bottom: 24px;
}
.settings-section h3 {
color: var(--primary);
margin-bottom: 16px;
font-size: 18px;
text-shadow: 0 0 8px rgba(0, 212, 255, 0.3);
}
.setting-item {
margin-bottom: 16px;
display: flex;
align-items: center;
justify-content: space-between;
}
.setting-label {
flex: 1;
font-size: 14px;
}
.setting-input {
width: 100px;
padding: 8px 12px;
background: var(--card-bg);
border: 1px solid var(--border);
border-radius: 8px;
color: var(--text);
font-size: 14px;
transition: all 0.2s;
}
.setting-input:focus {
outline: none;
border-color: var(--primary);
box-shadow: 0 0 8px rgba(0, 212, 255, 0.3);
}
.setting-toggle {
width: 48px;
height: 24px;
border-radius: 24px;
background: rgba(255, 255, 255, 0.15);
position: relative;
cursor: pointer;
}
.setting-toggle.knob {
position: absolute;
top: 3px;
left: 3px;
width: 18px;
height: 18px;
background: white;
border-radius: 50%;
transition: all 0.2s;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
.setting-toggle.on {
background: linear-gradient(90deg, var(--primary), var(--secondary));
}
.setting-toggle.on .knob {
left: 27px;
}
#settings-close {
position: absolute;
top: 16px;
right: 16px;
background: none;
border: none;
color: var(--text-secondary);
font-size: 24px;
cursor: pointer;
padding: 4px 8px;
border-radius: 6px;
transition: all 0.2s;
}
#settings-close:hover {
background: rgba(255, 255, 255, 0.1);
color: var(--text);
}
#watermark {
position: fixed;
top: 15px;
right: 15px;
font-weight: 900;
font-size: 28px;
background: linear-gradient(135deg, var(--primary), var(--secondary));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
text-shadow: 0 0 15px rgba(0, 212, 255, 0.5);
z-index: 9999999;
pointer-events: none;
letter-spacing: 1px;
}
#arraylist {
position: fixed;
right: 15px;
top: 60px;
display: flex;
flex-direction: column;
gap: 8px;
z-index: 9999999;
text-align: right;
}
.arrItem {
background: rgba(20, 20, 40, 0.8);
padding: 8px 14px;
border-radius: 10px;
font-weight: 600;
color: white;
border: 1px solid var(--border);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
backdrop-filter: blur(5px);
}
.arrItem::before {
content: '';
position: absolute;
right: 0;
top: 0;
height: 100%;
width: 4px;
background: linear-gradient(to bottom, var(--primary), var(--secondary));
border-radius: 4px 0 0 4px;
}
`;
document.head.appendChild(style);
root.innerHTML = `
<div id="bounceclient-gui">
<div id="bounceclient-header">
<div style="display:flex;align-items:center;">
<div class="title">Bounce<sup>Client</sup></div>
<div id="inject-status" class="red"></div>
</div>
<div style="font-size:13px;opacity:.8;">RightShift to toggle</div>
</div>
<div id="category-buttons"></div>
<div id="bounceclient-content">
<div id="bounceclient-mods"></div>
<div id="themes">
<div id="themeLabel">Theme</div>
<div class="theme" data-theme="ocean">Ocean Blue</div>
<div class="theme" data-theme="purple">Deep Purple</div>
<div class="theme" data-theme="matrix">Matrix Green</div>
<div class="theme" data-theme="sunset">Sunset Red</div>
<button id="inject-btn">Inject/Re-inject</button>
<button id="settings-btn">Settings</button>
</div>
</div>
</div>
<div id="settings-panel">
<button id="settings-close">×</button>
<h2 style="color:var(--primary);margin-bottom:24px;">Settings</h2>
<div id="settings-content"></div>
</div>
<div id="watermark">BounceClient</div>
<div id="arraylist"></div>
`;
const gui = root.querySelector("#bounceclient-gui");
const modsDiv = root.querySelector("#bounceclient-mods");
const arraylist = root.querySelector("#arraylist");
const watermark = root.querySelector("#watermark");
const categoryButtonsDiv = root.querySelector("#category-buttons");
const injectStatus = root.querySelector("#inject-status");
const injectBtn = root.querySelector("#inject-btn");
const settingsPanel = root.querySelector("#settings-panel");
const settingsContent = root.querySelector("#settings-content");
const settingsBtn = root.querySelector("#settings-btn");
const settingsClose = root.querySelector("#settings-close");
// === Category buttons ===
["Blatant","Visual","Legit"].forEach(cat=>{
const btn=document.createElement("div");
btn.className="cat-btn";
btn.textContent=cat;
btn.onclick=()=>{currentCategory=cat; refreshModules(); updateCategoryButtons();}
categoryButtonsDiv.appendChild(btn);
});
function updateCategoryButtons(){
categoryButtonsDiv.querySelectorAll(".cat-btn").forEach(b=>{
if(b.textContent===currentCategory) b.classList.add("on"); else b.classList.remove("on");
});
}
// === Module refresh ===
function refreshModules(){
modsDiv.innerHTML="";
const mods=Modules[currentCategory];
Object.keys(mods).forEach(name=>{
const div=document.createElement("div");
div.className="module";
const moduleInfo = document.createElement("div");
moduleInfo.className = "module-info";
moduleInfo.innerHTML = `<span class="module-name">${name}</span>`;
const hasKeybind = Keybinds.hasOwnProperty(name);
if(hasKeybind){
const keybindBtn = document.createElement("button");
keybindBtn.className = "keybind-btn";
keybindBtn.textContent = Keybinds[name] || "NONE";
keybindBtn.onclick = (e) => {
e.stopPropagation();
listeningKeybind = name;
keybindBtn.textContent = "...";
keybindBtn.style.background = "var(--primary)";
};
moduleInfo.appendChild(keybindBtn);
}
const toggle = document.createElement("div");
toggle.className = "toggle";
toggle.dataset.mod = name;
toggle.innerHTML = "<div class='knob'></div>";
div.appendChild(moduleInfo);
div.appendChild(toggle);
div.onclick = () => {
mods[name] = !mods[name];
updateToggles(); updateArray(); toggleModule(name, mods[name]);
};
modsDiv.appendChild(div);
});
updateToggles();
}
let listeningKeybind = null;
window.addEventListener("keydown", e => {
if(listeningKeybind && listeningKeybind in Keybinds){
Keybinds[listeningKeybind] = e.code;
listeningKeybind = null;
refreshModules();
}
});
function updateToggles(){
root.querySelectorAll(".toggle").forEach(t=>{
const m=t.dataset.mod;
const mods=Modules[currentCategory];
if(mods[m]) t.classList.add("on"); else t.classList.remove("on");
});
}
function updateArray(){
arraylist.innerHTML="";
Object.values(Modules).forEach(group=>{
Object.keys(group).forEach(m=>{
if(group[m]){
const el=document.createElement("div");
el.className="arrItem";
el.textContent=m;
el.style.position = "relative";
el.style.paddingRight = "20px";
arraylist.appendChild(el);
}
});
});
}
// === Themes ===
const themes = {
ocean: {
primary: "#00d4ff",
primaryDark: "#0099cc",
secondary: "#7c4dff",
border: "rgba(100, 100, 255, 0.3)"
},
purple: {
primary: "#9d4edd",
primaryDark: "#7b2cbf",
secondary: "#c77dff",
border: "rgba(157, 78, 221, 0.3)"
},
matrix: {
primary: "#00ff41",
primaryDark: "#00cc33",
secondary: "#00ff7f",
border: "rgba(0, 255, 65, 0.3)"
},
sunset: {
primary: "#ff5e5b",
primaryDark: "#ff3d3a",
secondary: "#ff9a8b",
border: "rgba(255, 94, 91, 0.3)"
}
};
root.querySelectorAll(".theme").forEach(t=>{
t.onclick=()=>{
const th=themes[t.dataset.theme];
document.documentElement.style.setProperty("--primary",th.primary);
document.documentElement.style.setProperty("--primary-dark",th.primaryDark);
document.documentElement.style.setProperty("--secondary",th.secondary);
document.documentElement.style.setProperty("--border",th.border);
};
});
// === GUI Toggle ===
let visible=false;
function toggleGUI(){visible=!visible; gui.style.display=visible?"flex":"none";}
window.addEventListener("keydown",e=>{
if(e.code==="ShiftRight" && !listeningKeybind) toggleGUI();
});
// === Vector utilities ===
const vectorUtils = {
normalizeVector(e) {
let t = e[0] * e[0] + e[1] * e[1] + e[2] * e[2];
if (t > 0) {
let n = 1 / Math.sqrt(t);
return [e[0] * n, e[1] * n, e[2] * n];
}
return e;
},
distanceBetweenSqrt(e, t) {
let n = t[0] - e[0], o = t[1] - e[1], i = t[2] - e[2];
return Math.sqrt(n * n + o * o + i * i);
}
};
// === NOA API wrappers ===
const noaAPI = {
noa: {
getPosition(e) {
return gameState.entities?.getState(e, "position")?.position;
},
get getMoveState() {
return objectUtils.values(gameState.noa?.entities)?.[36];
},
get getHeldItem() {
return objectUtils.values(gameState.noa?.entities).find((e => 1 == e?.length && e?.toString()?.length < 13 && e?.toString().includes(").")));
},
safeGetHeldItem(e) {
let t;
try {
t = this.getHeldItem(e);
} catch {}
return t;
},
get playerList() {
try {
return objectUtils.values(gameState.bloxd?.getPlayerIds()).filter((e => 1 !== e && this.safeGetHeldItem(e))).map((e => parseInt(e)));
} catch(e) {
return [];
}
},
get doAttack() {
let e = this.safeGetHeldItem(1);
return (e?.doAttack || e?.breakingItem?.doAttack)?.bind(e);
}
}
};
// === Killaura ===
let killauraInterval = null;
function tryKill() {
let myPos = noaAPI.noa.getPosition(1);
noaAPI.noa.playerList.forEach((target => {
let targetPos = noaAPI.noa.getPosition(target);
if (targetPos && vectorUtils.distanceBetweenSqrt(myPos, targetPos) <= Config.Killaura.range) {
let direction = vectorUtils.normalizeVector([
targetPos[0] - myPos[0],
targetPos[1] - myPos[1],
targetPos[2] - myPos[2]
]);
// Apply random jitter if enabled
if (Config.Killaura.jitter > 0) {
const jitterAmount = Config.Killaura.jitter / 100;
direction[0] += (Math.random() - 0.5) * jitterAmount;
direction[1] += (Math.random() - 0.5) * jitterAmount;
direction[2] += (Math.random() - 0.5) * jitterAmount;
direction = vectorUtils.normalizeVector(direction);
}
noaAPI.noa.doAttack(direction, target.toString(), "BodyMesh");
noaAPI.noa.getHeldItem(1)?.trySwingBlock?.();
noaAPI.noa.getMoveState(1)?.setArmsAreSwinging?.();
}
}));
}
function toggleKillaura(on) {
if (on) {
if (killauraInterval) clearInterval(killauraInterval);
let last = 0;
killauraInterval = setInterval(() => {
const now = Date.now();
if (now - last >= Config.Killaura.delay) {
last = now;
tryKill();
}
}, 16); // ~60fps
} else {
if (killauraInterval) {
clearInterval(killauraInterval);
killauraInterval = null;
}
}
}
function toggleModule(name,state){
if(name==="Killaura") toggleKillaura(state);
if(name==="Scaffold") toggleScaffold(state);
if(name==="ESP") toggleESP(state);
if(name==="Coords") toggleCoords(state);
if(name==="FPS Counter") fpsHUD.style.display=state?"block":"none";
if(name==="CPS Counter") cpsHUD.style.display=state?"block":"none";
if(name==="Keystrokes") keystrokesHUD.style.display=state?"grid":"none";
}
// === Update injection status indicator ===
function updateInjectStatus() {
if (injectionStatus.injected) {
injectStatus.className = "green";
} else if (injectionStatus.failed) {
injectStatus.className = "yellow";
} else {
injectStatus.className = "red";
}
}
// === Try to get noa object ===
function tryGetNoa() {
try {
// Always check if noa still exists and is valid
if (gameState.noa && gameState.noa.entities && typeof gameState.noa.entities.getState === 'function') {
return true; // Already have valid noa
}
let e = Object.getOwnPropertyDescriptors(window);
let i = Object.keys(e).find(key => e[key]?.set?.toString().includes("++"));
if (!i || !window[i]) {
return false;
}
(window[i] = window[i]).push([
[Math.floor(9e4 * Math.random()) + 1e4], {},
function (t) {
gameState.findModule = e => t(Object.keys(t.m)[Object.values(t.m).findIndex((t => t.toString().includes(e)))]);
gameState.Props = Object.values(gameState.findModule("nonBlocksClient:")).find((e => "object" == typeof e));
gameState.noa = Object.values(gameState.Props).find((e => e?.entities));
}
]);
return gameState.noa && gameState.noa.entities;
} catch(err) {
return false;
}
}
// === Game Injection ===
function injectGame() {
try {
// Try to get noa object
if (!tryGetNoa()) {
console.error("[BounceClient] Injection failed: Could not find webpack array or noa object.");
injectionStatus.injected = false;
injectionStatus.failed = true;
updateInjectStatus();
return false;
}
// Always reinitialize game state references
const a = objectUtils.values(gameState.noa.entities)[2];
const r = Object.entries(gameState.noa.entities);
gameState.impKey = r.find((([e, t]) => t === a))?.[0];
gameState.registry = objectUtils.values(gameState.noa)[17];
gameState.rendering = objectUtils.values(gameState.noa)[12];
gameState.entities = gameState.noa.entities;
gameState.world = objectUtils.values(gameState.noa)[11];
gameState.camera = gameState.noa.camera;
gameState.bloxd = gameState.noa.bloxd;
gameState.physics = gameState.noa.physics;
gameState.entityList = objectUtils.values(gameState.noa)[30];
let f = objectUtils.values(gameState.rendering)[7].meshes[0];
let m = objectUtils.values(gameState.rendering)[7];
gameState.Lion = {
scene: m,
Mesh: f.constructor,
StandardMaterial: f.material.constructor,
Color3: f.material.diffuseColor.constructor
};
injectionStatus.injected = true;
injectionStatus.failed = false;
updateInjectStatus();
console.log("%c[BounceClient] Game injected successfully!","color:var(--primary);font-weight:700;");
return true;
} catch(err) {
console.error("[BounceClient] Injection error:", err);
injectionStatus.injected = false;
injectionStatus.failed = true;
updateInjectStatus();
return false;
}
}
// === Auto-retry injection ===
function startInjectionRetry() {
if (injectionRetryInterval) return;
injectionRetryInterval = setInterval(() => {
if (!injectionStatus.injected) {
const gotNoa = tryGetNoa();
if (gotNoa && !gameState.impKey) {
// Have noa but not initialized, try to initialize
injectGame();
} else if (!gotNoa && injectionStatus.injected) {
// Lost noa object
injectionStatus.injected = false;
injectionStatus.failed = true;
updateInjectStatus();
}
}
}, 1000);
}
// === Inject button handler ===
injectBtn.onclick = () => {
injectGame();
};
// === Settings panel ===
function renderSettings() {
settingsContent.innerHTML = `
<div class="settings-section">
<h3>Killaura</h3>
<div class="setting-item">
<span class="setting-label">Delay (ms)</span>
<input type="number" class="setting-input" value="${Config.Killaura.delay}"
onchange="window.BounceClient.Config.Killaura.delay = parseInt(this.value); window.BounceClient.saveConfig(); toggleKillaura(window.BounceClient.Modules.Blatant.Killaura);">
</div>
<div class="setting-item">
<span class="setting-label">Range</span>
<input type="number" class="setting-input" step="0.1" value="${Config.Killaura.range}"
onchange="window.BounceClient.Config.Killaura.range = parseFloat(this.value); window.BounceClient.saveConfig();">
</div>
<div class="setting-item">
<span class="setting-label">Jitter (%)</span>
<input type="number" class="setting-input" value="${Config.Killaura.jitter}"
onchange="window.BounceClient.Config.Killaura.jitter = parseInt(this.value); window.BounceClient.saveConfig();">
</div>
</div>
<div class="settings-section">
<h3>Scaffold</h3>
<div class="setting-item">
<span class="setting-label">Delay (ms)</span>
<input type="number" class="setting-input" value="${Config.Scaffold.delay}"
onchange="window.BounceClient.Config.Scaffold.delay = parseInt(this.value); window.BounceClient.saveConfig(); toggleScaffold(window.BounceClient.Modules.Blatant.Scaffold);">
</div>
</div>
<div class="settings-section">
<h3>ESP</h3>
<div class="setting-item">
<span class="setting-label">Chest Update (ms)</span>
<input type="number" class="setting-input" value="${Config.ESP.chestUpdateInterval}"
onchange="window.BounceClient.Config.ESP.chestUpdateInterval = parseInt(this.value); window.BounceClient.saveConfig(); toggleESP(window.BounceClient.Modules.Visual.ESP);">
</div>
<div class="setting-item">
<span class="setting-label">Player Update (ms)</span>
<input type="number" class="setting-input" value="${Config.ESP.playerUpdateInterval}"
onchange="window.BounceClient.Config.ESP.playerUpdateInterval = parseInt(this.value); window.BounceClient.saveConfig(); togglePlayerESP(playerESPEnabled);">
</div>
</div>
<div class="settings-section">
<h3>Coords</h3>
<div class="setting-item">
<span class="setting-label">Update Interval (ms)</span>
<input type="number" class="setting-input" value="${Config.Coords.updateInterval}"
onchange="window.BounceClient.Config.Coords.updateInterval = parseInt(this.value); window.BounceClient.saveConfig(); toggleCoords(window.BounceClient.Modules.Visual.Coords);">
</div>
</div>
`;
}
settingsBtn.onclick = () => {
renderSettings();
settingsPanel.classList.add("show");
};
settingsClose.onclick = () => {
settingsPanel.classList.remove("show");
};
// === ESP ===
let espInterval = null;
let espMeshes = {};
let espChunks = new Set();
let chunkDataKey = null;
function getChunkKey(chunk) {
const [x, y, z] = chunk.pos || [0, 0, 0];
const chunkX = Math.floor(x / 32);
const chunkY = Math.floor(y / 32);
const chunkZ = Math.floor(z / 32);
return `${chunkX}|${chunkY}|${chunkZ}|overworld`;
}
function decodeChunkIndex(index, stride) {
const x = Math.floor(index / stride[0]);
const remainder = index % stride[0];
const y = Math.floor(remainder / stride[1]);
const z = remainder % stride[1];
return [x, y, z];
}
function findChunkDataKey(chunk) {
for (const key of Object.keys(chunk)) {
const value = chunk[key];
if (value && typeof value === "object" &&
Array.isArray(value.stride) && value.stride.length === 3 &&
(Array.isArray(value.data) || ArrayBuffer.isView(value.data))) {
return key;
}
}
return null;
}
function renderChestESP(chunk, blockIds) {
const chunkData = chunk[chunkDataKey];
if (!chunkData) return;
const { data, stride } = chunkData;
const chunkPos = chunk.pos || [0, 0, 0];
if (!data || !stride) return;
const chunkKey = getChunkKey(chunk);
for (let i = 0; i < data.length; i++) {
const blockId = data[i];
if (!blockIds.includes(blockId)) continue;
const [localX, localY, localZ] = decodeChunkIndex(i, stride);
const worldX = chunkPos[0] + localX + 0.5;
const worldY = chunkPos[1] + localY + 0.5;
const worldZ = chunkPos[2] + localZ + 0.5;
const mesh = gameState.Lion.Mesh.CreateBox("espbox", 1, gameState.Lion.scene);
mesh.position.set(worldX, worldY, worldZ);
mesh.renderingGroupId = 1;
mesh.material = new gameState.Lion.StandardMaterial("mat", gameState.Lion.scene);
mesh.material.wireframe = true;
mesh.material.emissiveColor = new gameState.Lion.Color3(
Config.ESP.wireframeColor[0],
Config.ESP.wireframeColor[1],
Config.ESP.wireframeColor[2]
);
if (!espMeshes[chunkKey]) espMeshes[chunkKey] = [];
espMeshes[chunkKey].push(mesh);
}
}
function updateESP() {
if (!gameState?.world || !gameState?.world?.[gameState.impKey]?.hash) return;
const worldChunks = gameState.world[gameState.impKey].hash;
for (const chunkId in worldChunks) {
const chunk = worldChunks[chunkId];
if (!chunkDataKey) chunkDataKey = findChunkDataKey(chunk);
if (!chunkDataKey || !chunk[chunkDataKey]?.data || !chunk.pos) continue;
const chunkKey = getChunkKey(chunk);
if (espChunks.has(chunkKey)) continue;
espChunks.add(chunkKey);
renderChestESP(chunk, [204, 205, 206, 207]);
}
}
function clearESP() {
for (const chunkKey in espMeshes) {
for (const mesh of espMeshes[chunkKey]) {
mesh.dispose();
}
}
espChunks.clear();
espMeshes = {};
}
// === Player ESP ===
let playerESPInterval = null;
let playerESPEnabled = false;
function updatePlayerESP() {
if (!gameState.rendering || !playerESPEnabled) {
return;
}
try {
const thinMeshes = objectUtils.values(gameState.rendering)[19]?.thinMeshes;
if (!Array.isArray(thinMeshes)) {
return;
}
const renderingGroupId = 2;
for (const item of thinMeshes) {
if (item?.meshVariations?.__DEFAULT__?.mesh && typeof item?.meshVariations?.__DEFAULT__?.mesh.renderingGroupId === "number") {
item.meshVariations.__DEFAULT__.mesh.renderingGroupId = renderingGroupId;
}
}
} catch(e) {
console.error("Player ESP error:", e);
}
}
function togglePlayerESP(on) {
playerESPEnabled = on;
if (on) {
if (!playerESPInterval) {
playerESPInterval = setInterval(updatePlayerESP, Config.ESP.playerUpdateInterval);
}
updatePlayerESP();
} else {
if (playerESPInterval) {
clearInterval(playerESPInterval);
playerESPInterval = null;
}
// Reset to normal rendering
if (gameState.rendering) {
try {
const thinMeshes = objectUtils.values(gameState.rendering)[19]?.thinMeshes;
if (Array.isArray(thinMeshes)) {
for (const item of thinMeshes) {
if (item.meshVariations?.__DEFAULT__?.mesh && typeof item?.meshVariations?.__DEFAULT__?.mesh.renderingGroupId === "number") {
item.meshVariations.__DEFAULT__.mesh.renderingGroupId = 0;
}
}
}
} catch(e) {
console.error("Player ESP reset error:", e);
}
}
}
}
function toggleESP(on) {
if (on) {
if (!espInterval) {
espInterval = setInterval(updateESP, Config.ESP.chestUpdateInterval);
}
updateESP();
togglePlayerESP(true);
} else {
if (espInterval) {
clearInterval(espInterval);
espInterval = null;
}
clearESP();
togglePlayerESP(false);
}
}
// === Coords ===
let coordsInterval = null;
function updateCoords() {
if (!gameState?.bloxd?.entityNames) return;
try {
for (const entityId in gameState.bloxd.entityNames) {
if (entityId === "1") continue;
const entityData = gameState.bloxd.entityNames[entityId];
const positionData = gameState.entities.getState(entityId, "position");
if (!positionData || !positionData.position) continue;
const position = positionData.position;
const x = Math.round(position[0]);
const y = Math.round(position[1]);
const z = Math.round(position[2]);
const baseName = entityData.entityName.replace(/\s*\(\-?\d+,\s*\-?\d+,\s*\-?\d+\)$/, "");
entityData.entityName = `${baseName} (${x}, ${y}, ${z})`;
}
} catch (error) {
console.error("Error updating coords:", error);
stopCoords();
}
}
function startCoords() {
if (!coordsInterval) {
updateCoords();
coordsInterval = setInterval(updateCoords, Config.Coords.updateInterval);
}
}
function stopCoords() {
if (coordsInterval) {
clearInterval(coordsInterval);
coordsInterval = null;
}
}
function toggleCoords(on) {
if (on) startCoords();
else stopCoords();
}
// === Scaffold ===
let scaffoldInterval = null;
function placeBlock(position) {
try {
const blockItem = objectUtils.values(gameState.noa.entities[gameState.impKey])[22].list[0]._blockItem;
const firstKey = Object.keys(blockItem)[0];
const firstValue = Object.values(blockItem)[0];
const posKey = Object.keys(firstValue)[25];
const posValue = firstValue[posKey];
blockItem.placeBlock.call(createPlacementProxy(position, blockItem, firstKey, firstValue, posKey, posValue));
} catch(e) {
console.error("Scaffold placement error:", e);
}
}
function createPlacementProxy(targetPos, blockItem, firstKey, firstValue, posKey, posValue) {
return new Proxy({}, {
get: (target, prop) => {
if (prop === firstKey) {
return new Proxy(firstValue, {
get(t, p) {
if (p === posKey) {
let cloned = structuredClone(posValue) || {};
cloned.position = targetPos;
return cloned;
}
return firstValue[p];
}
});
} else if (prop === "checkTargetedBlockCanBePlacedOver") {
return () => true;
} else if (typeof blockItem[prop] === "function") {
return blockItem[prop].bind(blockItem);
}
return blockItem[prop];
}
});
}
function canPlaceBlock(x, y, z, heldItem) {
try {
return heldItem.checkTargetedBlockCanBePlacedOver([x, y, z]) ||
0 === objectUtils.values(gameState.world)[47].call(gameState.world, x, y, z);
} catch(e) {
return false;
}
}
function scaffoldTick() {
try {
const playerPos = gameState.entities.getState(1, "position").position;
if (!playerPos) return;
const heldItemData = gameState.noa.entities?.[gameState.impKey];
const currentHeldItem = Object.values(Object.values(heldItemData)?.[22]?.list?.[0])?.[1];
if (!currentHeldItem || !currentHeldItem.heldItemState || currentHeldItem.heldItemState.heldType !== "CubeBlock") return;
const px = playerPos[0];
const py = Math.floor(playerPos[1]);
const pz = playerPos[2];
const fx = Math.floor(px);
const fz = Math.floor(pz);
if (canPlaceBlock(fx, py - 1, fz, currentHeldItem)) {
placeBlock([fx, py - 1, fz]);
return;
}
const offsetX = px - fx;
const offsetZ = pz - fz;
const positions = [];
if (offsetX < 0.3) positions.push([-1, 0]);
if (offsetX > 0.7) positions.push([1, 0]);
if (offsetZ < 0.3) positions.push([0, -1]);
if (offsetZ > 0.7) positions.push([0, 1]);
for (const [dx, dz] of positions) {
const targetX = fx + dx;
const targetZ = fz + dz;
if (canPlaceBlock(targetX, py - 1, targetZ, currentHeldItem)) {
placeBlock([targetX, py - 1, targetZ]);
return;
}
}
} catch(e) {
console.error("Scaffold tick error:", e);
}
}
function toggleScaffold(on) {
if (on) {
if (!scaffoldInterval) {
scaffoldInterval = setInterval(scaffoldTick, Config.Scaffold.delay);
}
} else {
if (scaffoldInterval) {
clearInterval(scaffoldInterval);
scaffoldInterval = null;
}
}
}
// === Keybind listeners for module toggles ===
window.addEventListener("keydown", e => {
// Don't trigger module keybinds if GUI is open or setting a keybind
if (visible || listeningKeybind) return;
for (const [module, keybind] of Object.entries(Keybinds)) {
if (keybind && e.code === keybind) {
if (module in Modules.Blatant) {
Modules.Blatant[module] = !Modules.Blatant[module];
toggleModule(module, Modules.Blatant[module]);
} else if (module in Modules.Visual) {
Modules.Visual[module] = !Modules.Visual[module];
toggleModule(module, Modules.Visual[module]);
}
updateArray();
}
}
});
// === Legit HUD ---
const hudStyle = "font-family:'Segoe UI',sans-serif;font-weight:700;color:white;text-align:center;"+
"background:rgba(20, 20, 40, 0.8);padding:10px 14px;border-radius:10px;"+
"border:1px solid var(--border);box-shadow:0 4px 12px rgba(0, 0, 0, 0.2);backdrop-filter:blur(5px);";
const fpsHUD=document.createElement("div");
fpsHUD.style.cssText=`position:fixed;bottom:15px;left:15px;z-index:9999999;${hudStyle}`;
fpsHUD.textContent="FPS: 0"; fpsHUD.style.display="none"; document.body.appendChild(fpsHUD);
const cpsHUD=document.createElement("div");
cpsHUD.style.cssText=`position:fixed;bottom:70px;left:15px;z-index:9999999;${hudStyle}`;
cpsHUD.textContent="CPS: 0"; cpsHUD.style.display="none"; document.body.appendChild(cpsHUD);
const keystrokesHUD = document.createElement("div");
keystrokesHUD.style.cssText = `
position: fixed;
bottom: 20px;
right: 20px;
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 8px;
z-index: 9999999;
`;
const keys = {};
function createKey(char, gridArea) {
const k = document.createElement("div");
k.textContent = char;
k.style.cssText = `
min-width: 40px;
height: 40px;
background: rgba(20, 20, 40, 0.8);
color: white;
display: flex;
align-items: center;
justify-content: center;
border-radius: 10px;
font-weight: 700;
border: 1px solid var(--border);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
transition: all 0.1s;
${gridArea ? `grid-area: ${gridArea};` : ''}
`;
keys[char] = k;
return k;
}
// Add keys in a WASD layout
keystrokesHUD.appendChild(createKey("", "top")); // Empty top-left
keystrokesHUD.appendChild(createKey("W", "top"));
keystrokesHUD.appendChild(createKey("", "top")); // Empty top-right
keystrokesHUD.appendChild(createKey("A", "middle"));
keystrokesHUD.appendChild(createKey("S", "middle"));
keystrokesHUD.appendChild(createKey("D", "middle"));
keystrokesHUD.style.display = "none"; // hide by default
document.body.appendChild(keystrokesHUD);
// FPS / CPS logic
let lastFrame=performance.now(),frameCount=0,fps=0;
function updateFPS(){
const now=performance.now();
frameCount++;
if(now-lastFrame>=1000){ fps=frameCount; frameCount=0; lastFrame=now; fpsHUD.textContent="FPS: "+fps; }
requestAnimationFrame(updateFPS);
}
requestAnimationFrame(updateFPS);
let clicks=0,cps=0;
document.addEventListener("mousedown",()=>clicks++);
setInterval(()=>{
cps=clicks; clicks=0; cpsHUD.textContent="CPS: "+cps;
},1000);
// Key press highlight for keystrokes
document.addEventListener("keydown",e=>{
const k=e.key.toUpperCase();
if(keys[k]) {
keys[k].style.background="linear-gradient(135deg, var(--primary), var(--secondary))";
keys[k].style.transform="scale(0.95)";
}
});
document.addEventListener("keyup",e=>{
const k=e.key.toUpperCase();
if(keys[k]) {
keys[k].style.background="rgba(20, 20, 40, 0.8)";
keys[k].style.transform="scale(1)";
}
});
// --- Initialize ---
updateCategoryButtons(); refreshModules();
updateInjectStatus(); // Set initial status
// Start auto-retry injection
startInjectionRetry();
// Inject game state on load
setTimeout(() => {
if (injectGame()) {
console.log("%c[BounceClient] All systems ready!","color:var(--primary);font-weight:700;");
}
}, 2000);
window.BounceClient={Modules, Keybinds, Config, gameState, injectGame, saveConfig};
console.log("%cBounceClient GUI loaded - Press RightShift","color:var(--primary);font-weight:700;");
})();