blackhack

Cheat for brofist.io

Per 23-03-2026. Zie de nieuwste versie.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey, Greasemonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Userscripts.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een gebruikersscriptbeheerder nodig.

(Ik heb al een user script manager, laat me het downloaden!)

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

(Ik heb al een beheerder - laat me doorgaan met de installatie!)

// ==UserScript==
// @name           blackhack
// @version        1.15-beta0
// @description    Cheat for brofist.io
// @author         CiNoP
// @match          *://*.brofist.io/*
// @icon           https://www.google.com/s2/favicons?sz=64&domain=brofist.io
// @grant          none
// @license        GPL-3.0-only
// @namespace      brofist.io 1st-cheat (FOR ALL MODES)
// ==/UserScript==
/* jshint esversion: 11 */
/* jshint asi: true */




(() => {
	const _bind = Function.prototype.bind;
	const pathname = location.pathname.toLowerCase();
	const isTwoPlayer = pathname.includes("twoplayer");

	window.hack = {
		mode: null,
		modeController: null,
		gp: null,
		networkHandler: null,
		client: null,
		originalMakeMeGhost: null,
		originalSocketEmit: null,
	};

	new Promise((resolve) => {

		if (isTwoPlayer) {
			console.log("Подключение хука для Two Player Adventure...");

			Function.prototype.bind = function(context, ...args) {
				if (context && context.playerData && context.twoPlayerController) {
					window.hack.mode = context;
					window.hack.modeController = context.twoPlayerController;
					window.hack.gp = context.gp;
					window.hack.networkHandler = context.networkHandler;
					window.hack.client = context.client;

					Function.prototype.bind = _bind;
					console.log("2PA Hack Ready:", window.hack);
					resolve(window.hack);
				}
				return _bind.apply(this, [context, ...args]);
			};

		} else {
			console.log("Подключение хука для Sandbox/HideAndSeek...");

			let modeCaptured = false;
			let networkCaptured = false;

			const checkReady = () => {
				if (modeCaptured && networkCaptured) {
					window.hack.gp = window.gp;
					window.hack.client = window.client;
					console.log("Sandbox/Other Hack Ready:", window.hack);
					resolve(window.hack);
				}
			};

			Object.defineProperty(Object.prototype, 'pingCheckCount', {
				set(val) {
					delete Object.prototype.pingCheckCount;
					this.pingCheckCount = val;
					window.hack.networkHandler = this;
					networkCaptured = true;
					checkReady();
				},
				configurable: true
			});

			Object.defineProperty(Object.prototype, 'othersPlayerNetworkData', {
				set(val) {
					delete Object.prototype.othersPlayerNetworkData;
					this.othersPlayerNetworkData = val;
					window.hack.mode = this;
					window.hack.modeController = this;
					modeCaptured = true;
					checkReady();
				},
				configurable: true
			});
		}

	}).then(() => main(isTwoPlayer));

	function main(is2pa) {

		// --- Хук на сокет ---
		if (hack.networkHandler) {
			const existingSock = hack.networkHandler.gsSocket;
			if (existingSock && !existingSock.__patched) {
				existingSock.__patched = true;
				hack.originalSocketEmit = existingSock.emit;
				existingSock.emit = function(eventName, ...args) {
					if (eventName === "rGho" && hack.vars.imm) {
						console.log("[NETWORK] Заблокирована отправка rGho");
						return;
					}
					return hack.originalSocketEmit.apply(this, [eventName, ...args]);
				};
			}

			const origConnect = hack.networkHandler.connectToGs;
			if (origConnect) {
				hack.networkHandler.connectToGs = function(...args) {
					origConnect.apply(this, args);
					const sock = this.gsSocket;
					if (sock && !sock.__patched) {
						sock.__patched = true;
						hack.originalSocketEmit = sock.emit;
						sock.emit = function(eventName, ...args) {
							if (eventName === "rGho" && hack.vars.imm) {
								console.log("[NETWORK] Заблокирована отправка rGho");
								return;
							}
							return hack.originalSocketEmit.apply(this, [eventName, ...args]);
						};
					}
				};
			}
		}

		// ─── Состояния ──────────────────────────────────────────────
		hack.vars = {
			imm: false,
			noclip: false,
			mult: { enabled: false, value: 1 }
		};
		hack.keyBinds = {
			F2: false,
			F4: false,
			SHIFT: false,
			HOME: false,
			END: false
		};
		hack.prevKeys = {};

		const keyMap = {
			'F2': 'F2',
			'F4': 'F4',
			'Shift': 'SHIFT',
			'Home': 'HOME',
			'End': 'END'
		};

		document.addEventListener('keydown', (e) => {
			if (keyMap[e.key]) {
				e.preventDefault();
				hack.keyBinds[keyMap[e.key]] = true;
			}
		});
		document.addEventListener('keyup', (e) => {
			if (keyMap[e.key]) hack.keyBinds[keyMap[e.key]] = false;
		});
		window.addEventListener('blur', () => {
			for (const k in hack.keyBinds) hack.keyBinds[k] = false;
		});

		// ─── Доступ к игроку ────────────────────────────────────────
		const getLocalPlayer = () => {
			if (is2pa) return hack.modeController.localPlayer;
			return hack.modeController.player ? hack.modeController.player.gpData : null;
		};

		const getPlayerGpData = () => {
			if (is2pa) return hack.mode.player ? hack.mode.player.gpData : null;
			return getLocalPlayer();
		};

		// ─── Обработчики ────────────────────────────────────────────
		hack.funcs = {
			handlers: {
				immE: (obj, key) => {
					obj[key] = true;
					const gpData = getPlayerGpData();
					if (gpData) gpData.me = void 0;
					if (hack.mode.makeMeGhost && !hack.originalMakeMeGhost) {
						hack.originalMakeMeGhost = hack.mode.makeMeGhost;
					}
					if (hack.mode.makeMeGhost) {
						hack.mode.makeMeGhost = function() {
							console.log("[IMM] Попытка убить игрока заблокирована");
						};
					}
					console.log("Бессмертие ВКЛЮЧЕНО");
				},

				immD: (obj, key) => {
					obj[key] = false;
					const gpData = getPlayerGpData();
					if (gpData) gpData.me = true;
					if (hack.originalMakeMeGhost) {
						hack.mode.makeMeGhost = hack.originalMakeMeGhost;
					}
					console.log("Бессмертие ОТКЛЮЧЕНО");
				},

				noclipE: (obj, key, _mult) => {
					obj[key] = true;
					const gpData = getPlayerGpData();
					if (gpData && gpData.p) gpData.p.invMass = 0;
					const lp = getLocalPlayer();
					if (lp && lp.p) {
						lp.p.invMass = 0;
						lp.p.collisionResponse = false;
					}
					if (_mult.enabled) hack.vars.mult.value = 4;
					console.log("Noclip ВКЛЮЧЁН");
				},

				noclipD: (obj, key, _mult) => {
					obj[key] = false;
					const gpData = getPlayerGpData();
					if (gpData && gpData.p) gpData.p.invMass = 1;
					const lp = getLocalPlayer();
					if (lp && lp.p) {
						lp.p.invMass = 1;
						lp.p.mass = 1;
						lp.p.collisionResponse = true;
					}
					if (_mult.enabled) hack.vars.mult.value = 1;
					console.log("Noclip ОТКЛЮЧЁН");
				},

				multE: (obj, key, _noclip) => {
					if (_noclip) {
						obj[key] = true;
						hack.vars.mult.value = 4;
						console.log("Speedhack ВКЛЮЧЁН");
						return;
					}
					console.log("Включите noclip, чтобы изменить Speedhack");
				},

				multD: (obj, key, _noclip) => {
					if (_noclip) {
						obj[key] = false;
						hack.vars.mult.value = 1;
						console.log("Speedhack ОТКЛЮЧЁН");
						return;
					}
					console.log("Включите noclip, чтобы изменить Speedhack");
				},

				tpDoor: () => {
					const door = hack.gp.list.find(i => i.id && i.id.includes('door'));
					const lp = getLocalPlayer();
					if (door && lp) {
						lp.setX(door.getX());
						lp.setY(door.getY());
					}
				},

				tpSpawn: () => {
					const spawn = hack.gp.list.find(i => i.id && i.id.includes('spawn'));
					const lp = getLocalPlayer();
					if (spawn && lp) {
						lp.setX(spawn.getX());
						lp.setY(spawn.getY());
					}
				}
			}
		};

		// ─── Game Loop ──────────────────────────────────────────────
		function updateLoop() {
			const binds = hack.keyBinds;
			const prev = hack.prevKeys;
			const funcs = hack.funcs.handlers;
			const vars = hack.vars;
			const justPressed = (key) => binds[key] && !prev[key];

			if (is2pa) {
				if (justPressed('HOME')) funcs.tpSpawn();
				if (justPressed('END')) funcs.tpDoor();
				if (justPressed('F4')) {
					if (!vars.imm) funcs.immE(vars, 'imm');
					else funcs.immD(vars, 'imm');
				}
			}

			if (justPressed('F2')) {
				if (!vars.noclip) funcs.noclipE(vars, 'noclip', vars.mult);
				else funcs.noclipD(vars, 'noclip', vars.mult);
			}

			if (justPressed('SHIFT')) {
				if (!vars.mult.enabled) funcs.multE(vars.mult, 'enabled', vars.noclip);
				else funcs.multD(vars.mult, 'enabled', vars.noclip);
			}

			if (vars.noclip) {
				const gpData = getPlayerGpData();
				if (gpData && gpData.p && gpData.p.invMass !== 0) gpData.p.invMass = 0;
				const lp = getLocalPlayer();
				if (lp && lp.p) {
					if (lp.p.invMass !== 0) lp.p.invMass = 0;
					if (lp.p.collisionResponse !== false) lp.p.collisionResponse = false;
				}
			}

			if (is2pa && vars.imm) {
				const gpData = getPlayerGpData();
				if (gpData && gpData.me !== undefined) gpData.me = void 0;
			}

			for (const k in binds) prev[k] = binds[k];
			requestAnimationFrame(updateLoop);
		}
		requestAnimationFrame(updateLoop);

		// ─── Кастомная функция движения ─────────────────────────────
		const customMovement = function() {
			const ctrl = hack.modeController;
			const p = getLocalPlayer();
			const mult = hack.vars.mult.value;
			if (!p) return;

			if (hack.vars.noclip) {
				if (ctrl.moveRight) p.p.velocity[0] = 3 * mult;
				else if (ctrl.moveLeft) p.p.velocity[0] = -3 * mult;
				else p.p.velocity[0] = 0;

				if (ctrl.moveUp) p.p.velocity[1] = 3 * mult;
				else if (ctrl.moveDown) p.p.velocity[1] = -3 * mult;
				else p.p.velocity[1] = 0;
				return;
			}

			if (ctrl.moveRight) p.p.velocity[0] = 3;
			if (ctrl.moveLeft) p.p.velocity[0] = -3;
			if (!ctrl.moveUp) return;

			const ex = p.getX(),
				ty = p.getY(),
				n = ex - 15,
				r = 30 / 11;
			const phys = is2pa ? ctrl.physics : hack.gp;

			for (let i = 0; i < 12; i++) {
				const ox = n + i * r,
					oy1 = ty + 49,
					oy2 = oy1 + 50;
				p.ray.from = [phys.xAxis(ox, 0), phys.yAxis(oy1, 0)];
				p.ray.to = [phys.xAxis(ox, 0), phys.yAxis(oy2, 0)];
				p.ray.update();
				p.ray.result.reset();
				p.ray.hitPoint = [Infinity, Infinity];

				if (hack.gp.pWorld.raycast(p.ray.result, p.ray)) {
					const hitDist = p.ray.result.getHitDistance(p.ray);
					if (p.ray.result.shape.ref.getCollision() && hitDist < 0.05) {
						p.p.velocity[1] = 8;
						break;
					}
				}
			}
		};

		// ─── Замена movement (прямой поиск) ─────────────────────────
		let replaced = false;
		for (let i = 0; i < hack.client.loopFunctions.length; i++) {
			const funcStr = hack.client.loopFunctions[i].fun.toString();
			if (funcStr.includes("moveLeft") &&
				(funcStr.includes("raycast") || funcStr.includes("velocity[1]"))) {
				hack.client.loopFunctions[i].fun = customMovement;
				console.log("[MOVEMENT] Заменено в loopFunctions[" + i + "]");
				replaced = true;
				break;
			}
		}

		if (!replaced && is2pa && hack.client.loopFunctions.length > 7) {
			hack.client.loopFunctions[7].fun = customMovement;
			console.log("[MOVEMENT] 2PA-фолбэк loopFunctions[7]");
			replaced = true;
		}

		// Хук на addLoopFunction — ловим movement при смене карты
		const origAddLoop = hack.client.addLoopFunction;
		hack.client.addLoopFunction = function(fun, par, exeCount, timeOut) {
			if (fun) {
				const str = fun.toString();
				if (str.includes("moveLeft") &&
					(str.includes("raycast") || str.includes("velocity[1]"))) {
					console.log("[MOVEMENT] Перехвачено через addLoopFunction");
					return origAddLoop.call(this, customMovement, par, exeCount, timeOut);
				}
			}
			return origAddLoop.call(this, fun, par, exeCount, timeOut);
		};

		// ─── Промис: ждём sendMyStatus и ставим timeOut = 0 ────────
		new Promise((resolve) => {
			const check = () => {
				const lf = hack.client.loopFunctions;
				for (let i = 0; i < lf.length; i++) {
					if (lf[i] && (lf[i].timeOut === 200 || lf[i].timeOut === 150)) {
						lf[i].timeOut = 0;
						console.log("[SEND_STATUS] timeOut → 0 в loopFunctions[" + i + "]");
						resolve(i);
						return;
					}
				}
				requestAnimationFrame(check);
			};
			check();
		});

		console.log("Main Hook завершён. Game Loop (rAF) запущен.");
	}
})();