A client packed with features! ZoomHack, AimBow, AutoHeal, ESP, Tracers, Scout, WalkUnlock, KillMessage, Gold Bot, HUD
// ==UserScript==
// @name TakeMineClient
// @namespace Violentmonkey Scripts
// @icon https://takemine.io/favicon-32x32.png
// @version 1.0
// @match *://takemine.io/*
// @grant unsafeWindow
// @grant GM_addStyle
// @grant GM_info
// @author Drik
// @description A client packed with features! ZoomHack, AimBow, AutoHeal, ESP, Tracers, Scout, WalkUnlock, KillMessage, Gold Bot, HUD
// @run-at document-start
// @license MIT
// ==/UserScript==
(function() {
'use strict';
const _$gi = (typeof GM_info !== 'undefined') ? GM_info : null;
const _$raw = _$gi && _$gi.script ? (_$gi.script.updateURL || '') : null;
if (_$raw === null) {
alert('Install the original TakeMineClient from GreasyFork');
throw new Error('TMC');
}
const CFG_KEY = 'TakeMineClient';
let menuKey = 'F4';
const _defaults = {
zoom: {
enabled: false
},
autoheal: {
enabled: false
},
skinunlock: {
enabled: false
},
esp: {
enabled: false
},
tracers: {
enabled: false
},
scout: {
enabled: false
},
walkunlock: {
enabled: false
},
killmessage: {
enabled: false
},
aimbow: {
enabled: false
},
Gold_Bot: {
enabled: false
},
hud: {
enabled: false
},
};
function loadState() {
try {
const sv = JSON.parse(localStorage.getItem(CFG_KEY) || '{}');
const st = {};
for (const k in _defaults) st[k] = {
enabled: sv[k] !== undefined ? !!sv[k] : _defaults[k].enabled
};
if (sv._mk) menuKey = sv._mk;
return st;
} catch {
return JSON.parse(JSON.stringify(_defaults));
}
}
function saveState() {
const o = {};
for (const k in state) o[k] = state[k].enabled;
o._mk = menuKey;
localStorage.setItem(CFG_KEY, JSON.stringify(o));
}
const state = loadState();
if (state.skinunlock.enabled) {
['elf', 'orc', 'undead'].forEach(h => {
unsafeWindow.localStorage[h] = true;
});
}
let gameWS = null;
let ahEnabled = state.autoheal.enabled;
let ahHealing = false;
let ahProto = false;
let ahPrevTool = 1;
let ahFrames = 0;
const ZOOM_BASE = 1.06;
let zoomFactor = ZOOM_BASE;
const wuKeys = {
attack: false,
up: false,
right: false,
down: false,
left: false
};
let wuLast = null;
let scoutGhost = null,
scoutGhostId = null,
scoutRespawnT = null;
const scoutMarks = [];
const MAP_SIZE = 8160;
const dgBots = [];
let dgRunning = false;
let kmKills = 0;
const kmQueue = [];
const BOW_ID = 4;
const ARROW_SPD = 0.55;
let hudPing = 0,
hudFps = 0,
hudLast = performance.now(),
hudF = 0;
if (typeof _$raw === 'string' && _$raw.length === 0) {
alert('Install the original TakeMineClient from GreasyFork');
throw new Error('TMC');
}
const _nativeSend = unsafeWindow.WebSocket.prototype.send;
unsafeWindow.WebSocket.prototype.send = function(data) {
if (typeof data === 'string' && data.startsWith('42[1,') && !gameWS) gameWS = this;
return _nativeSend.call(this, data);
};
function rawSend(s) {
if (gameWS && gameWS.readyState === 1) _nativeSend.call(gameWS, s);
}
const _omDesc = Object.getOwnPropertyDescriptor(unsafeWindow.WebSocket.prototype, 'onmessage');
Object.defineProperty(unsafeWindow.WebSocket.prototype, 'onmessage', {
get() {
return this._tmc_om || null;
},
set(fn) {
this._tmc_om = fn;
_omDesc.set.call(this, function(ev) {
if (state.killmessage.enabled && typeof ev.data === 'string' && ev.data.startsWith('42')) {
try {
const p = JSON.parse(ev.data.slice(2));
const id = p[0],
pl = p[1],
c = unsafeWindow.CLIENT;
if (id === 11) {
const c = unsafeWindow.CLIENT;
const name = c?.playerNames?.[pl] || ('Player#' + pl);
kmQueue.push(name);
}
if (id === 6 && Array.isArray(pl)) {
for (let i = 0; i < pl.length; i += 2) {
if (pl[i] === 0 && pl[i + 1] > kmKills) {
kmKills = pl[i + 1];
const name = kmQueue.shift() || null;
if (name) {
const c = unsafeWindow.CLIENT;
c?.socket?.emit(10, name + ' killed by ' + c?.player?.name);
}
}
}
}
if (id === 9) {
kmKills = 0;
kmQueue.length = 0;
}
} catch {}
}
if (fn) fn.call(this, ev);
});
},
configurable: true
});
Object.defineProperty(unsafeWindow, 'Vue', {
configurable: true,
set(V) {
Object.defineProperty(unsafeWindow, 'Vue', {
value: V,
writable: true,
configurable: true
});
const _O = V;
function PV(opts) {
const i = new _O(opts);
if (opts && opts.el === '#ui') unsafeWindow.UI = i;
return i;
}
PV.prototype = _O.prototype;
['config', 'use', 'component', 'set', 'delete', 'nextTick', 'extend', 'mixin', 'compile', 'observable', 'version'].forEach(k => {
if (_O[k] !== undefined) PV[k] = typeof _O[k] === 'function' ? (...a) => _O[k].apply(_O, a) : _O[k];
});
Object.defineProperty(unsafeWindow, 'Vue', {
value: PV,
writable: true,
configurable: true
});
}
});
const _origBind = unsafeWindow.Function.prototype.bind;
unsafeWindow.Function.prototype.bind = function(thisArg, ...args) {
if (
!unsafeWindow.CLIENT &&
thisArg !== null && thisArg !== undefined &&
typeof thisArg === 'object' &&
thisArg.camera !== undefined &&
thisArg.mainCanvas !== undefined &&
thisArg.mainCtx !== undefined &&
thisArg.screenWidth !== undefined
) {
unsafeWindow.CLIENT = thisArg;
unsafeWindow.Function.prototype.bind = _origBind;
_initFeatures(thisArg);
}
return _origBind.apply(this, [thisArg, ...args]);
};
function _initFeatures(c) {
_initAutoHeal(c);
_initRender(c);
_initWalkUnlock(c);
if (c.socket?.io) c.socket.io.on('pong', ms => {
hudPing = ms;
});
}
function _initAutoHeal(c) {
let _p = null;
Object.defineProperty(c, 'player', {
get() {
return _p;
},
set(val) {
_p = val;
if (val && !ahProto) {
ahProto = true;
_hookSetHP(Object.getPrototypeOf(val));
}
},
configurable: true
});
}
function _hookSetHP(proto) {
const _orig = proto.setHP;
proto.setHP = function(hp) {
const res = _orig.call(this, hp);
const c = unsafeWindow.CLIENT;
if (!c || !c.player || this !== c.player) return res;
if (ahEnabled && !ahHealing && hp > 0 && hp < this.maxHP * 0.6 && c.player.food >= 10) {
ahPrevTool = c.player.tool ? c.player.tool.id : 1;
ahHealing = true;
ahFrames = 0;
_doHeal();
}
return res;
};
}
function _doHeal() {
rawSend('42[3,2]');
requestAnimationFrame(() => {
rawSend('42[2,16]');
requestAnimationFrame(() => {
rawSend('42[2,0]');
ahFrames = 0;
});
});
}
function _initRender(c) {
const _orig = c.render.bind(c);
c.render = function() {
_orig();
const ctx = c.mainCtx,
cam = c.camera,
me = c.player,
pl = c.players;
if (!me || !pl) return;
if (state.esp.enabled) {
ctx.save();
ctx.globalAlpha = 1;
ctx.shadowColor = 'transparent';
ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;
for (const id in pl) {
if (!pl.hasOwnProperty(id)) continue;
const p = pl[id];
if (!p || !p.isVisible || p.id === me.id) continue;
const cx = cam.calculateCameraX(p.x),
cy = cam.calculateCameraY(p.y);
const r = p.radius,
rs = p.skin ? p.skin.radiusShift : 0;
ctx.beginPath();
ctx.arc(cx, cy, r + rs, 0, 6.2832);
ctx.strokeStyle = 'rgba(255,200,0,1)';
ctx.lineWidth = 1;
ctx.stroke();
ctx.beginPath();
ctx.arc(cx, cy, r, 0, 6.2832);
ctx.strokeStyle = 'rgba(255,50,50,0.9)';
ctx.lineWidth = 1.5;
ctx.stroke();
}
ctx.beginPath();
ctx.restore();
}
if (state.tracers.enabled) {
const mx = cam.calculateCameraX(me.x),
my = cam.calculateCameraY(me.y);
const sorted = [];
for (const id in pl) {
if (!pl.hasOwnProperty(id)) continue;
const p = pl[id];
if (!p || p.id === me.id) continue;
const dx = p.x - me.x,
dy = p.y - me.y;
sorted.push({
p,
d: dx * dx + dy * dy
});
}
sorted.sort((a, b) => a.d - b.d);
ctx.save();
sorted.forEach(({
p,
d
}, i) => {
const px = cam.calculateCameraX(p.x),
py = cam.calculateCameraY(p.y);
const ratio = Math.min(d / (3000 * 3000), 1);
const rv = Math.round(255 * ratio),
gv = Math.round(255 * (1 - ratio));
ctx.beginPath();
ctx.moveTo(mx, my);
ctx.lineTo(px, py);
ctx.strokeStyle = `rgba(${rv},${gv},0,0.75)`;
ctx.lineWidth = i === 0 ? 2.5 / cam.scale : 1.5 / cam.scale;
ctx.stroke();
ctx.fillStyle = `rgba(${rv},${gv},0,0.9)`;
ctx.beginPath();
ctx.arc(px, py, 4 / cam.scale, 0, Math.PI * 2);
ctx.fill();
});
ctx.restore();
}
};
}
function _initWalkUnlock(c) {
const s = c.socket;
const _oe = s.emit.bind(s);
s.emit = function(op, val) {
if (op === 2 && state.walkunlock.enabled) {
const oc = _wuCode();
if (val === 0 && oc !== 0) {
wuLast = oc;
return _oe(2, oc);
}
if (val === oc) {
wuLast = val;
return _oe.apply(this, arguments);
}
}
return _oe.apply(this, arguments);
};
}
function _wuCode() {
return parseInt('' + +wuKeys.attack + +wuKeys.up + +wuKeys.right + +wuKeys.down + +wuKeys.left, 2);
}
function _wuSend() {
const c = unsafeWindow.CLIENT;
if (!c || !c.socket || !state.walkunlock.enabled) return;
const code = _wuCode();
if (code === wuLast) return;
wuLast = code;
c.socket.emit(2, code);
}
unsafeWindow.addEventListener('keydown', e => {
let ch = true;
switch (e.keyCode) {
case 32:
wuKeys.attack = true;
break;
case 69:
wuKeys.attack = !wuKeys.attack;
break;
case 38:
case 87:
wuKeys.up = true;
break;
case 39:
case 68:
wuKeys.right = true;
break;
case 40:
case 83:
wuKeys.down = true;
break;
case 37:
case 65:
wuKeys.left = true;
break;
default:
ch = false;
}
if (ch) _wuSend();
}, true);
unsafeWindow.addEventListener('keyup', e => {
let ch = true;
switch (e.keyCode) {
case 32:
wuKeys.attack = false;
break;
case 38:
case 87:
wuKeys.up = false;
break;
case 39:
case 68:
wuKeys.right = false;
break;
case 40:
case 83:
wuKeys.down = false;
break;
case 37:
case 65:
wuKeys.left = false;
break;
default:
ch = false;
}
if (ch) _wuSend();
}, true);
unsafeWindow.addEventListener('blur', () => {
wuKeys.attack = wuKeys.up = wuKeys.right = wuKeys.down = wuKeys.left = false;
wuLast = null;
});
function _applyZoom() {
const c = unsafeWindow.CLIENT;
if (!c) return;
const w = c.screenWidth,
h = c.screenHeight;
const base = Math.round(100 * Math.max(w / 1440, h / 900)) / 100;
const ns = parseFloat((base * zoomFactor).toFixed(4));
const pr = unsafeWindow.PIXEL_RATIO;
c.camera.scale = ns;
c.camera.width = parseInt(w / ns);
c.camera.height = parseInt(h / ns);
c.camera.widthHalf = c.camera.width / 2;
c.camera.heightHalf = c.camera.height / 2;
c.camera.isChanged = true;
c.mainCtx.setTransform(pr, 0, 0, pr, 0, 0);
c.mainCtx.scale(ns, ns);
c.backgroundCtx.setTransform(pr, 0, 0, pr, 0, 0);
c.backgroundCtx.scale(ns, ns);
}
unsafeWindow.addEventListener('wheel', e => {
if (!state.zoom.enabled || !e.ctrlKey) return;
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
zoomFactor = parseFloat((e.deltaY < 0 ?
Math.min(3.0, zoomFactor + 0.1) :
Math.max(0.1, zoomFactor - 0.1)).toFixed(2));
_applyZoom();
}, {
passive: false,
capture: true
});
const _origRAF = unsafeWindow.requestAnimationFrame;
unsafeWindow.requestAnimationFrame = function(cb) {
return _origRAF(function(ts) {
const c = unsafeWindow.CLIENT;
if (ahHealing && c && c.player) {
if (c.player.hp >= c.player.maxHP || c.player.food < 10) {
ahHealing = false;
ahFrames = 0;
rawSend('42[3,' + ahPrevTool + ']');
} else {
ahFrames++;
if (ahFrames >= 3) _doHeal();
}
}
if (state.aimbow.enabled && c && c.player && c.socket) {
if (c.player.tool && c.player.tool.id === BOW_ID) {
const t = _findNearest(c);
if (t) {
const {
x,
y
} = _predictPos(t, c.player);
const ang = _bowAngle(c.player, x, y);
if (ang !== c.prevAngle) {
c.socket.emit(1, ang);
c.angle = ang;
c.prevAngle = ang;
}
}
}
}
cb(ts);
});
};
function _findNearest(c) {
const me = c.player;
let cl = null,
md = Infinity;
for (const id in c.players) {
if (!c.players.hasOwnProperty(id)) continue;
const p = c.players[id];
if (!p || p.id === me.id) continue;
const d = (p.x - me.x) ** 2 + (p.y - me.y) ** 2;
if (d < md) {
md = d;
cl = p;
}
}
return cl;
}
function _predictPos(t, me) {
const buf = t.positionBuffer;
let px = t.x,
py = t.y;
if (buf && buf.length >= 2) {
const b0 = buf[buf.length - 2],
b1 = buf[buf.length - 1],
dt = b1.t - b0.t;
if (dt > 0) {
const vx = (b1.x - b0.x) / dt,
vy = (b1.y - b0.y) / dt;
const d = Math.sqrt((t.x - me.x) ** 2 + (t.y - me.y) ** 2);
px = t.x + vx * (d / ARROW_SPD);
py = t.y + vy * (d / ARROW_SPD);
}
}
return {
x: px,
y: py
};
}
function _bowAngle(me, tx, ty) {
const cam = unsafeWindow.CLIENT.camera;
return Math.round(100 * (Math.atan2(cam.calculateCameraY(ty) - cam.calculateCameraY(me.y), cam.calculateCameraX(tx) - cam.calculateCameraX(me.x)) + Math.PI / 2));
}
function scoutStart() {
if (!unsafeWindow.CLIENT || !unsafeWindow.UI) return;
const sv = document.getElementById('serverList')?.value;
if (!sv) return;
scoutGhost = unsafeWindow.io.connect(sv, {
forceNew: true
});
scoutGhost.on('connect', () => _scoutSpawn());
scoutGhost.on(3, d => {
scoutGhostId = d[0];
clearTimeout(scoutRespawnT);
scoutRespawnT = setTimeout(_scoutSpawn, 700);
});
scoutGhost.on(4, d => {
const UI = unsafeWindow.UI,
C = unsafeWindow.CLIENT;
if (!UI?.minimap) return;
const mn = C?.player?.name;
for (let t = 0; t < d.length; t += 11) {
const r = d.slice(t, t + 11);
if (r[0] === scoutGhostId) continue;
if (mn && C?.playerNames?.[r[0]] === mn) continue;
const key = 'scout_' + r[0];
UI.minimap.setMarker(key, MAP_SIZE, MAP_SIZE, r[2], r[3], '#ffff00');
if (!scoutMarks.includes(key)) scoutMarks.push(key);
}
});
scoutGhost.on(9, () => {
clearTimeout(scoutRespawnT);
_scoutSpawn();
});
}
function scoutStop() {
clearTimeout(scoutRespawnT);
if (scoutGhost) {
scoutGhost.disconnect();
scoutGhost = null;
scoutGhostId = null;
}
}
function _scoutSpawn() {
if (scoutGhost) scoutGhost.emit(0, 'Drik_Scout', 1);
}
function scoutClear() {
const UI = unsafeWindow.UI;
if (!UI) return;
scoutMarks.forEach(k => UI.minimap.removeMarker(k));
scoutMarks.length = 0;
}
function dgStart() {
dgRunning = true;
for (let i = 0; i < 15; i++) _dgCreateBot(i);
}
function dgStop() {
dgRunning = false;
const UI = unsafeWindow.UI;
dgBots.forEach(b => {
if (b.moveInterval) clearInterval(b.moveInterval);
if (b.socket) b.socket.disconnect();
if (UI?.minimap && b.id) UI.minimap.removeMarker('gp_' + b.id);
});
dgBots.length = 0;
}
function _dgCreateBot(idx) {
const sv = document.getElementById('serverList')?.value;
if (!sv) return;
const bot = {
socket: null,
id: null,
x: 0,
y: 0,
moveInterval: null
};
dgBots[idx] = bot;
bot.socket = unsafeWindow.io.connect(sv, {
forceNew: true
});
bot.socket.on('connect', () => bot.socket.emit(0, 'Drik_Gold', 1));
bot.socket.on(3, d => {
bot.id = d[0];
_dgMove(bot);
});
bot.socket.on(4, d => {
for (let t = 0; t < d.length; t += 11) {
const r = d.slice(t, t + 11);
if (r[0] === bot.id) {
bot.x = r[2];
bot.y = r[3];
_dgMark(bot);
}
}
});
bot.socket.on(9, () => {
clearInterval(bot.moveInterval);
if (dgRunning) setTimeout(() => bot.socket.emit(0, 'Drik_Gold', 1), 500);
});
}
function _dgMove(bot) {
clearInterval(bot.moveInterval);
bot.moveInterval = setInterval(() => {
const c = unsafeWindow.CLIENT;
if (!c?.player) return;
const dx = c.player.x - bot.x,
dy = c.player.y - bot.y;
const d = Math.sqrt(dx * dx + dy * dy);
if (d < 80) {
bot.socket.emit(2, 0);
return;
}
const kc = parseInt('0' + (dy < -40 ? '1' : '0') + (dx > 40 ? '1' : '0') + (dy > 40 ? '1' : '0') + (dx < -40 ? '1' : '0'), 2);
bot.socket.emit(1, Math.round(100 * (Math.atan2(dy, dx) + Math.PI / 2)));
bot.socket.emit(2, kc);
}, 50);
}
function _dgMark(bot) {
const UI = unsafeWindow.UI;
if (UI?.minimap) UI.minimap.setMarker('gp_' + bot.id, MAP_SIZE, MAP_SIZE, bot.x, bot.y, '#ffd700');
}
(function _hudLoop(now) {
hudF++;
const dt = now - hudLast;
if (dt >= 1000) {
hudFps = Math.round(hudF * 1000 / dt);
hudF = 0;
hudLast = now;
}
if (state.hud.enabled) {
const el = document.getElementById('pfhud');
if (el) {
const c = unsafeWindow.CLIENT;
const pl = c?.playerNames ? Object.keys(c.playerNames).length : '-';
el.innerHTML = 'FPS: ' + (hudFps || '-') + '<br>PING: ' + (hudPing ? hudPing + 'ms' : '-') + '<br>PLAYER: ' + pl;
}
}
_origRAF(_hudLoop);
})(performance.now());
(function() {
let _u;
try {
_u = decodeURIComponent(_$raw).toLowerCase();
} catch {
_u = (_$raw || '').toLowerCase();
}
const _valid =
_u.length > 0 &&
_u.startsWith('https://update.greatest.deepsurf.us/scripts/') &&
_u.endsWith('.meta.js') &&
/takemineclient(\[\d+(\.\d+)?\])?/.test(_u);
if (!_valid) {
alert('Invalid source. Download TakeMineClient from official page');
throw new Error('TMC');
}
})();
function onToggle(key, on) {
switch (key) {
case 'skinunlock':
if (on)['elf', 'orc', 'undead'].forEach(h => {
unsafeWindow.localStorage[h] = true;
});
break;
case 'autoheal':
ahEnabled = on;
if (!on && ahHealing) {
ahHealing = false;
ahFrames = 0;
rawSend('42[3,' + ahPrevTool + ']');
}
break;
case 'Gold_Bot':
on ? dgStart() : dgStop();
break;
case 'hud': {
const el = document.getElementById('pfhud');
if (el) el.style.display = on ? '' : 'none';
break;
}
}
saveState();
}
GM_addStyle(`
@import url("https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;700&family=Rajdhani:wght@400;500;600;700&display=swap");
#tm-menu * {
box-sizing: border-box;
margin: 0;
padding: 0;
}
#tm-menu {
position: fixed;
top: 14px;
right: 14px;
z-index: 999999;
width: 320px;
background: #161b27;
border: 1px solid #252d3d;
border-radius: 12px;
box-shadow: 0 8px 40px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.04);
font-family: "Rajdhani", sans-serif;
overflow: hidden;
user-select: none;
}
#tm-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 14px 18px;
background: #1a2030;
border-bottom: 1px solid #252d3d;
cursor: move;
}
#tm-title {
font-size: 16px;
font-weight: 700;
letter-spacing: 3px;
text-transform: uppercase;
color: #e2e8f0;
font-family: "Space Mono", monospace;
}
#tm-title span {
color: #4ade80;
}
#tm-tabs {
display: flex;
border-bottom: 1px solid #252d3d;
background: #161b27;
}
.tm-tab {
flex: 1;
padding: 11px 0;
border: none;
background: transparent;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
font-family: "Rajdhani", sans-serif;
font-size: 11px;
font-weight: 600;
letter-spacing: 1.5px;
text-transform: uppercase;
color: #4a5568;
transition: color 0.2s;
border-bottom: 2px solid transparent;
position: relative;
top: 1px;
}
.tm-tab svg {
width: 13px;
height: 13px;
flex-shrink: 0;
}
.tm-tab.active {
color: #4ade80;
border-bottom: 2px solid #4ade80;
}
.tm-tab:hover:not(.active) {
color: #94a3b8;
}
#tm-body {
padding: 6px 0;
max-height: 400px;
overflow-y: auto;
}
#tm-body::-webkit-scrollbar {
width: 3px;
}
#tm-body::-webkit-scrollbar-track {
background: transparent;
}
#tm-body::-webkit-scrollbar-thumb {
background: #252d3d;
border-radius: 3px;
}
.tm-panel {
display: none;
}
.tm-panel.active {
display: block;
}
.tm-row {
display: flex;
align-items: flex-start;
justify-content: space-between;
padding: 11px 18px;
gap: 14px;
transition: background 0.15s;
}
.tm-row:hover {
background: rgba(255, 255, 255, 0.025);
}
.tm-row-info {
flex: 1;
min-width: 0;
}
.tm-row-name {
font-size: 14px;
font-weight: 700;
color: #e2e8f0;
letter-spacing: 0.4px;
line-height: 1.2;
}
.tm-row-desc {
font-size: 11px;
color: #4a5568;
margin-top: 3px;
line-height: 1.45;
font-weight: 400;
font-family: "Space Mono", monospace;
}
.tm-toggle {
flex-shrink: 0;
width: 40px;
height: 22px;
background: #252d3d;
border-radius: 11px;
position: relative;
cursor: pointer;
transition: background 0.25s;
margin-top: 2px;
}
.tm-toggle.on {
background: #16a34a;
}
.tm-toggle::after {
content: "";
position: absolute;
top: 3px;
left: 3px;
width: 16px;
height: 16px;
border-radius: 50%;
background: #fff;
transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
}
.tm-toggle.on::after {
transform: translateX(18px);
}
.tm-divider {
height: 1px;
background: #1e2636;
margin: 0 18px;
}
#tm-footer {
padding: 9px 18px;
border-top: 1px solid #252d3d;
display: flex;
align-items: center;
justify-content: flex-end;
gap: 8px;
}
#tm-footer-label {
font-size: 9px;
letter-spacing: 1.5px;
color: #2d3748;
text-transform: uppercase;
font-family: "Space Mono", monospace;
}
#tm-menu-key-btn {
background: #1a2030;
border: 1px solid #2d3748;
border-radius: 4px;
padding: 2px 8px;
font-size: 10px;
color: #94a3b8;
cursor: pointer;
font-family: "Space Mono", monospace;
transition: border-color 0.2s, color 0.2s;
}
#tm-menu-key-btn:hover {
border-color: #4ade80;
color: #4ade80;
}
#tm-menu-key-btn.listening {
border-color: #f59e0b;
color: #f59e0b;
animation: tm-pulse 0.8s ease infinite;
}
@keyframes tm-pulse {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0.3;
}
}
.tm-scout-btns {
display: flex;
gap: 8px;
padding: 6px 18px 14px;
}
.tm-scout-btn {
flex: 1;
padding: 5px 0;
border-radius: 5px;
border: 1px solid #252d3d;
background: #1a2030;
color: #94a3b8;
font-family: "Space Mono", monospace;
font-size: 9px;
letter-spacing: 1px;
text-transform: uppercase;
cursor: pointer;
transition: border-color 0.2s, color 0.2s;
}
.tm-scout-btn:hover {
border-color: #4ade80;
color: #4ade80;
}
#tm-scout-stop:hover {
border-color: #ef4444;
color: #ef4444;
}
#tm-scout-clear:hover {
border-color: #f59e0b;
color: #f59e0b;
}
.tm-changelog {
padding: 10px 18px 14px;
}
.tm-cl-entry {
display: flex;
gap: 12px;
align-items: flex-start;
padding: 8px 0;
border-bottom: 1px solid #1e2636;
}
.tm-cl-entry:last-child {
border-bottom: none;
}
.tm-cl-version {
flex-shrink: 0;
font-family: "Space Mono", monospace;
font-size: 10px;
color: #4ade80;
background: rgba(74, 222, 128, 0.08);
border: 1px solid rgba(74, 222, 128, 0.2);
border-radius: 4px;
padding: 2px 7px;
margin-top: 1px;
}
.tm-cl-text {
font-size: 12px;
color: #64748b;
font-family: "Space Mono", monospace;
line-height: 1.5;
}
#pfhud {
position: fixed;
top: 12px;
left: 12px;
z-index: 99998;
background: rgba(0, 0, 0, 0.5);
color: #fff;
font-family: monospace;
font-size: 12px;
padding: 4px 9px;
border-radius: 5px;
pointer-events: none;
line-height: 1.6;
border-left: 2px solid #4af;
}
`);
document.addEventListener('DOMContentLoaded', () => {
const pfhud = document.createElement('div');
pfhud.id = 'pfhud';
pfhud.innerHTML = 'FPS: -<br>PING: -<br>PLAYER: -';
pfhud.style.display = state.hud.enabled ? '' : 'none';
document.body.appendChild(pfhud);
const menu = document.createElement('div');
menu.id = 'tm-menu';
menu.innerHTML = `
<div id="tm-header">
<div id="tm-title">TakeMine<span>Client</span></div>
</div>
<div id="tm-tabs">
<button class="tm-tab active" data-tab="combat">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
<line x1="19" y1="5" x2="5" y2="19"/><polyline points="16 5 19 5 19 8"/><polyline points="5 8 5 5 8 5"/>
</svg>Combat
</button>
<button class="tm-tab" data-tab="visual">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="3"/><path d="M2 12s4-7 10-7 10 7 10 7-4 7-10 7-10-7-10-7z"/>
</svg>Visual
</button>
<button class="tm-tab" data-tab="misc">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round">
<circle cx="5" cy="12" r="1.2"/><circle cx="12" cy="12" r="1.2"/><circle cx="19" cy="12" r="1.2"/>
</svg>Misc
</button>
<button class="tm-tab" data-tab="changelog">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
<polyline points="14 2 14 8 20 8"/>
<line x1="16" y1="13" x2="8" y2="13"/>
<line x1="16" y1="17" x2="8" y2="17"/>
<line x1="10" y1="9" x2="8" y2="9"/>
</svg>Log
</button>
</div>
<div id="tm-body">
<div class="tm-panel active" data-panel="combat">
${_row('autoheal', 'Auto Heal', 'Auto heal when HP < 60% and food available')}
<div class="tm-divider"></div>
${_row('aimbow', 'Aim Bow', 'Aim with a bow toward the nearest enemy')}
<div class="tm-divider"></div>
${_row('Gold_Bot', 'Gold Bot', 'Bots coming toward you, kill them for gold')}
<div class="tm-divider"></div>
${_row('killmessage', 'Kill Message', 'Send a chat message when you kill a player')}
</div>
<div class="tm-panel" data-panel="visual">
${_row('zoom', 'Zoom', 'Default zoom hack (CTRL + mouse wheel)')}
<div class="tm-divider"></div>
${_row('esp', 'ESP', 'Draws the players precise hitbox')}
<div class="tm-divider"></div>
${_row('tracers', 'Tracers', 'Draws a line from you to each enemy')}
<div class="tm-divider"></div>
${_row('hud', 'HUD', 'Shows FPS, ping and player counter')}
</div>
<div class="tm-panel" data-panel="misc">
${_row('skinunlock', 'Skin Unlock', 'Unlocks Orc, Elf, Undead without sharing')}
<div class="tm-divider"></div>
${_row('walkunlock', 'Walk Unlock', 'Move even with chat or menus open')}
<div class="tm-divider"></div>
${_row('scout', 'Scout', 'Second account that marks players on minimap')}
<div class="tm-scout-btns">
<button class="tm-scout-btn" id="tm-scout-start">Start</button>
<button class="tm-scout-btn" id="tm-scout-stop">Stop</button>
<button class="tm-scout-btn" id="tm-scout-clear">Clear</button>
</div>
</div>
<div class="tm-panel" data-panel="changelog">
<div class="tm-changelog">
<div class="tm-cl-entry">
<div class="tm-cl-version">v1.0</div>
<div class="tm-cl-text">Client released. First public build. Zoom, ESP, Tracers, AutoHeal, AimBow, Scout, WalkUnlock, KillMessage, Gold Bot, HUD.</div>
</div>
</div>
</div>
</div>
<div id="tm-footer">
<div id="tm-footer-label">Menu key:</div>
<button id="tm-menu-key-btn">${menuKey}</button>
</div>
`;
document.body.appendChild(menu);
menu.querySelectorAll('.tm-tab').forEach(tab => {
tab.addEventListener('click', () => {
menu.querySelectorAll('.tm-tab').forEach(t => t.classList.remove('active'));
menu.querySelectorAll('.tm-panel').forEach(p => p.classList.remove('active'));
tab.classList.add('active');
menu.querySelector('[data-panel="' + tab.dataset.tab + '"]')?.classList.add('active');
document.getElementById('tm-footer').style.display = tab.dataset.tab === 'changelog' ? 'none' : '';
});
});
menu.querySelectorAll('.tm-toggle').forEach(t => {
t.addEventListener('click', () => {
const k = t.dataset.key;
state[k].enabled = !state[k].enabled;
t.classList.toggle('on', state[k].enabled);
onToggle(k, state[k].enabled);
});
});
document.getElementById('tm-scout-start').addEventListener('click', scoutStart);
document.getElementById('tm-scout-stop').addEventListener('click', scoutStop);
document.getElementById('tm-scout-clear').addEventListener('click', scoutClear);
const mkBtn = document.getElementById('tm-menu-key-btn');
const BLOCKED = new Set(['KeyW', 'KeyA', 'KeyS', 'KeyD', 'Escape', 'Space', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight']);
mkBtn.addEventListener('click', () => {
mkBtn.classList.add('listening');
mkBtn.textContent = '...';
const h = e => {
e.preventDefault();
if (BLOCKED.has(e.code)) {
mkBtn.textContent = 'blocked!';
setTimeout(() => {
mkBtn.textContent = menuKey;
mkBtn.classList.remove('listening');
window.removeEventListener('keydown', h, true);
}, 800);
return;
}
menuKey = e.key;
mkBtn.textContent = menuKey;
mkBtn.classList.remove('listening');
window.removeEventListener('keydown', h, true);
saveState();
};
window.addEventListener('keydown', h, {
capture: true
});
});
window.addEventListener('keydown', e => {
if (e.key === menuKey && !_isInput()) {
e.preventDefault();
menu.style.display = menu.style.display === 'none' ? '' : 'none';
}
}, true);
_makeDraggable(menu, document.getElementById('tm-header'));
Object.keys(state).forEach(k => {
const t = menu.querySelector('[data-key="' + k + '"]');
if (t && state[k]?.enabled) t.classList.add('on');
});
});
function _row(key, name, desc) {
return `<div class="tm-row"><div class="tm-row-info"><div class="tm-row-name">${name}</div><div class="tm-row-desc">${desc}</div></div><div class="tm-toggle${state[key]?.enabled ? ' on' : ''}" data-key="${key}"></div></div>`;
}
function _isInput() {
const el = document.activeElement;
if (!el) return false;
const tag = el.tagName.toLowerCase();
if (tag === 'input' || tag === 'textarea' || el.isContentEditable) return true;
try {
const ui = unsafeWindow.UI;
if (ui && (ui.chatVisible || ui.teamVisible)) return true;
} catch {}
return false;
}
function _makeDraggable(el, handle) {
let ox = 0,
oy = 0;
handle.addEventListener('mousedown', e => {
e.preventDefault();
ox = e.clientX - el.offsetLeft;
oy = e.clientY - el.offsetTop;
const mv = e => {
el.style.left = (e.clientX - ox) + 'px';
el.style.top = (e.clientY - oy) + 'px';
el.style.right = 'auto';
};
document.addEventListener('mousemove', mv);
document.addEventListener('mouseup', () => document.removeEventListener('mousemove', mv), {
once: true
});
});
}
})();