TV Block ESP

Please dont report

Terá de instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

Terá de instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Terá de instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Terá de instalar uma extensão como Tampermonkey para instalar este script.

Terá de instalar uma extensão de gestão de scripts de utilizador para instalar este script.

(Já tenho um gestor de scripts de utilizador, deixe-me instalá-lo!)

Terá de instalar uma extensão como Stylus para instalar este estilo.

Terá de instalar uma extensão como Stylus para instalar este estilo.

Terá de instalar uma extensão como Stylus para instalar este estilo.

Terá de instalar uma extensão de gestão de estilos de utilizador para instalar este estilo.

Terá de instalar uma extensão de gestão de estilos de utilizador para instalar este estilo.

Terá de instalar uma extensão de gestão de estilos de utilizador para instalar este estilo.

(Já tenho um gestor de estilos de utilizador, deixe-me instalá-lo!)

// ==UserScript==
// @name         TV Block ESP
// @namespace    *://minefun.io/*
// @version      2.5.0
// @author       TVhackgaming
// @description  Please dont report
// @match        *://minefun.io/*
// @grant        none
// @license      MIT
// ==/UserScript==

/* eslint-disable */
(function () {
    'use strict';

    var ALL_IDS = [ 1067, 572, 580, 840, 503, 1063, 571, 581, 616, 830];

    var ACTIVE_IDS    = ALL_IDS.slice();
    var SEARCH_RADIUS = 5;
    var MAX_RADIUS    = 16;
    var FOV_Y         = 70;
    var BATCH_SIZE    = 5;
    var STEPS_FRAME   = 80;

    var targetBlocks = [];
    var allBlocks    = [];
    var espOn        = true;
    var camera       = null;
    var scanState    = null;
    var lastURL      = location.href;
    var checkTick    = 0;
    var ui, listEl, statusEl;

    // ID colors
    var ID_COLORS = {
        1067:   '#f70a41',  // Infernal Shard
        572:    '#575403',   // gold block
        580:    '#03574e',   // diamond block
        840: '#64B5F6',   // furnace
        503: '#fefcff',   // Private block
        1063: '#230a40',   // Screaming Obsidian
        571: '#ffff05',   // gold
        581: '#80DEEA',   // diamond
        616: '#050505',   // coal
        830: '#e8e8e8'    // iron
    };
    function colorFor(id){ return ID_COLORS[id] || '#ffffff'; }

    var cvs = document.createElement('canvas');
    cvs.style.cssText = 'position:fixed;top:0;left:0;width:100vw;height:100vh;pointer-events:none;z-index:2147483646';
    document.body.appendChild(cvs);
    var ctx = cvs.getContext('2d');
    function resize(){ cvs.width=innerWidth; cvs.height=innerHeight; }
    resize(); window.addEventListener('resize', resize);

    function getO() {
        try {
            var r   = app._vnode.component.appContext.provides;
            var sym = Object.getOwnPropertySymbols(r).find(function(s){ return r[s] && r[s]._s; });
            if (!sym) return null;
            var o = r[sym]._s.get('gameState');
            if (!o || !o.gameWorld || !o.gameWorld.chunkManager || !o.gameWorld.player) return null;
            return o;
        } catch(e) { return null; }
    }

    function findCamera(o) {
        if (camera) { try{ if(camera.matrixWorldInverse) return camera; }catch(e){} camera=null; }
        try {
            var sys=o.gameWorld.systemsManager.activeSystems;
            for(var i=0;i<sys.length;i++){
                var s=sys[i]; if(!s) continue;
                var ks=Object.getOwnPropertyNames(s);
                for(var j=0;j<ks.length;j++){
                    try{
                        var v=s[ks[j]]; if(!v||typeof v!=='object') continue;
                        if(v.isPerspectiveCamera||v.isCamera){camera=v;return v;}
                        var ks2=Object.getOwnPropertyNames(v);
                        for(var n=0;n<ks2.length;n++){try{var v2=v[ks2[n]];if(v2&&(v2.isPerspectiveCamera||v2.isCamera)){camera=v2;return v2;}}catch(e){}}
                    }catch(e){}
                }
            }
        }catch(e){}
        return null;
    }

    function worldToScreen(pp, rot, bx, by, bz) {
        if (camera&&camera.projectionMatrix&&camera.matrixWorldInverse) {
            try {
                var mv=camera.matrixWorldInverse.elements, p=camera.projectionMatrix.elements;
                var vx=mv[0]*bx+mv[4]*by+mv[8]*bz+mv[12], vy=mv[1]*bx+mv[5]*by+mv[9]*bz+mv[13];
                var vz=mv[2]*bx+mv[6]*by+mv[10]*bz+mv[14], vw=mv[3]*bx+mv[7]*by+mv[11]*bz+mv[15];
                var cx=p[0]*vx+p[4]*vy+p[8]*vz+p[12]*vw, cy=p[1]*vx+p[5]*vy+p[9]*vz+p[13]*vw;
                var cz=p[2]*vx+p[6]*vy+p[10]*vz+p[14]*vw, cw=p[3]*vx+p[7]*vy+p[11]*vz+p[15]*vw;
                if(cw<=0||cz/cw>1) return null;
                return{x:((cx/cw)*0.5+0.5)*cvs.width, y:(-(cy/cw)*0.5+0.5)*cvs.height};
            }catch(e){camera=null;}
        }
        var dx=bx-pp[0],dy=by-pp[1]-1.6,dz=bz-pp[2];
        var bYaw=Math.atan2(dx,dz)+Math.PI;
        var pYaw=((rot.y%(2*Math.PI))+2*Math.PI)%(2*Math.PI);
        var yd=bYaw-pYaw;
        while(yd>Math.PI)yd-=2*Math.PI;
        while(yd<-Math.PI)yd+=2*Math.PI;
        if(Math.abs(yd)>Math.PI*0.65) return null;
        var h=Math.sqrt(dx*dx+dz*dz),pd=Math.atan2(dy,h)-rot.x;
        var W=cvs.width,H=cvs.height,fvY=FOV_Y*Math.PI/180,fvX=2*Math.atan(Math.tan(fvY/2)*W/H);
        return{x:W/2+(yd/(fvX/2))*(W/2), y:H/2-(pd/(fvY/2))*(H/2)};
    }

    function clampR(r){r=parseInt(r)||5;if(r<1)r=1;if(r>MAX_RADIUS)r=MAX_RADIUS;return r;}

    // huh
    function makeIdSet(){ var s={}; for(var i=0;i<ACTIVE_IDS.length;i++) s[ACTIVE_IDS[i]]=true; return s; }

    function startScan(o) {
        if (scanState) return;
        var R=clampR(SEARCH_RADIUS);
        var pos=Array.from(o.gameWorld.player.position);
        var sx=pos[0]>>4, sy=pos[1]>>4, sz=pos[2]>>4;
        scanState={
            cm:o.gameWorld.chunkManager,
            idSet: makeIdSet(),
            found:[], a:-R,l:-R,m:-R,R:R,
            cx:sx,cy:sy,cz:sz,
            pp:pos, total:Math.pow(2*R+1,3), done:0
        };
    }

    function forceScan(){
        scanState=null; targetBlocks=[]; allBlocks=[];
        var o=getO(); if(o) startScan(o);
    }

    function tickScan(){
        if(!scanState) return;
        var st=scanState, R=st.R, steps=0;
        while(steps<STEPS_FRAME){
            var cx=st.cx+st.a, cy=st.cy+st.l, cz=st.cz+st.m;
            try{
                var arr=st.cm.getChunkArray(cx,cy,cz);
                if(arr){
                    for(var g=0;g<arr.length;g++){
                        var bid=arr[g];
                        if(!st.idSet[bid]) continue;
                        var bx=(cx<<4)+(g&15), by=(cy<<4)+((g>>4)&15), bz=(cz<<4)+(g>>8);
                        try{if(st.cm.getBlock(bx,by,bz)===bid)st.found.push({bx:bx,by:by,bz:bz,id:bid});}catch(e){}
                    }
                }
            }catch(e){}
            st.done++; st.m++;
            if(st.m>R){st.m=-R;st.l++;}
            if(st.l>R){st.l=-R;st.a++;}
            if(st.a>R){
                allBlocks=st.found;
                var pp=st.pp; scanState=null;

                targetBlocks=allBlocks
                    .map(function(b){return{b:b,d:Math.hypot(b.bx-pp[0],b.by-pp[1],b.bz-pp[2])};})
                    .sort(function(a,z){return a.d-z.d;})
                    .slice(0,BATCH_SIZE).map(function(x){return x.b;});
                return;
            }
            steps++;
        }
        if(statusEl){var pct=Math.round(st.done/st.total*100);statusEl.textContent='Escaneando... '+pct+'%';}
    }

    function blockExists(o,b){
        try{return o.gameWorld.chunkManager.getBlock(b.bx,b.by,b.bz)===b.id;}catch(e){return false;}
    }

    function renderLoop(){
        ctx.clearRect(0,0,cvs.width,cvs.height);
        tickScan();
        var o=getO();
        if(o){
            if(!camera)findCamera(o);
            if(camera){try{camera.updateMatrixWorld(true);}catch(e){camera=null;}}

            checkTick++;
            if(checkTick>=45){
                checkTick=0;
                if(!scanState){
                    var alive=targetBlocks.filter(function(b){return blockExists(o,b);});
                    if(alive.length<targetBlocks.length) startScan(o);
                }
            }

            if(espOn&&targetBlocks.length){
                var pp=Array.from(o.gameWorld.player.position);
                var rot=o.gameWorld.player.rotation;
                for(var i=0;i<targetBlocks.length;i++){
                    var b=targetBlocks[i];
                    var sc=worldToScreen(pp,rot,b.bx+0.5,b.by+0.5,b.bz+0.5);
                    if(!sc||sc.x<-80||sc.x>cvs.width+80||sc.y<-80||sc.y>cvs.height+80)continue;
                    var d=Math.hypot(b.bx-pp[0],b.by-pp[1],b.bz-pp[2]);
                    var sz=Math.max(8,Math.min(52,400/d)), hw=sz/2;
                    var col=colorFor(b.id);
                    ctx.save();ctx.shadowColor=col;ctx.shadowBlur=18;ctx.strokeStyle=col;ctx.lineWidth=2.5;
                    ctx.strokeRect(sc.x-hw,sc.y-hw,sz,sz);
                    ctx.fillStyle=col.slice(0,7)+'22';ctx.fillRect(sc.x-hw,sc.y-hw,sz,sz);
                    ctx.restore();
                    ctx.save();ctx.font='bold 10px monospace';ctx.textAlign='center';
                    ctx.strokeStyle='rgba(0,0,0,0.9)';ctx.lineWidth=3;
                    ctx.strokeText(b.id+' '+d.toFixed(0)+'m',sc.x,sc.y-hw-3);
                    ctx.fillStyle='#fff';ctx.fillText(b.id+' '+d.toFixed(0)+'m',sc.x,sc.y-hw-3);
                    ctx.restore();
                }
            }

            if(!scanState){
                var pp2=Array.from(o.gameWorld.player.position);
                var camL=camera?'cam exacta':'angular FOV:'+FOV_Y;
                if(statusEl)statusEl.textContent=targetBlocks.length+'/5 activos | '+allBlocks.length+' total | '+camL;
                if(listEl){
                    listEl.textContent=targetBlocks.length===0?'none nearby':
                        targetBlocks.map(function(b){
                            return{b:b,d:Math.hypot(b.bx-pp2[0],b.by-pp2[1],b.bz-pp2[2])};
                        }).sort(function(a,z){return a.d-z.d;})
                        .map(function(x){
                            return '['+x.b.id+'] '+x.b.bx+','+x.b.by+','+x.b.bz+'  '+x.d.toFixed(1)+'m';
                        }).join('\n');
                }
            }
        }else{
            if(targetBlocks.length>0){targetBlocks=[];allBlocks=[];camera=null;scanState=null;
                if(listEl)listEl.textContent='';if(statusEl)statusEl.textContent='Esperando partida...';}
        }
        if(location.href!==lastURL){lastURL=location.href;targetBlocks=[];allBlocks=[];camera=null;scanState=null;
            if(statusEl)statusEl.textContent='Cargando nueva partida...';}
        requestAnimationFrame(renderLoop);
    }

    function createUI(){
        ui=document.createElement('div');
        // RED AND BLACK
        ui.style.cssText='position:fixed;top:80px;left:80px;width:280px;background:#0d0d0d;color:#e0e0e0;font:11px system-ui,sans-serif;border:1.5px solid #ff1e1e;border-radius:6px;box-shadow:0 0 15px rgba(255,30,30,0.3);z-index:2147483647;user-select:none;display:flex;flex-direction:column;';

        var cbHtml='';
        for(var i=0;i<ALL_IDS.length;i++){
            var id=ALL_IDS[i], col=colorFor(id);
            cbHtml+='<label style="display:inline-flex;align-items:center;gap:2px;margin:2px;cursor:pointer;font-size:10px">'
                +'<input type="checkbox" class="bfcb" data-id="'+id+'" checked '
                +'style="accent-color:'+col+'"> '
                +'<span style="color:'+col+'">'+id+'</span></label>';
        }

        ui.innerHTML='<div class="bfh" style="padding:6px 8px;cursor:move;display:flex;justify-content:space-between;align-items:center;border-bottom:1px solid #ff1e1e;font-weight:700;background:#140505;color:#ff4d4d"><span>Block Finder</span><button id="bfesp" style="background:#b71c1c;border:1px solid #ff5252;color:#fff;border-radius:3px;padding:2px 7px;cursor:pointer;font-size:10px">ESP ON</button></div>'
            +'<div style="padding:4px 8px;border-bottom:1px solid #260a0a">'+cbHtml+'</div>'
            +'<div style="padding:4px 8px;border-bottom:1px solid #260a0a;display:flex;gap:4px;align-items:center">'
            +'<label style="font-size:10px;color:#ccc">R(chunks):<input id="bfr" type="number" min="1" max="'+MAX_RADIUS+'" value="'+SEARCH_RADIUS+'" style="width:30px;background:#1a1a1a;border:1px solid #ff1e1e;color:#fff;border-radius:3px;padding:2px 3px;text-align:center"></label>'
            +'<label style="font-size:10px;color:#ccc">FOV:<input id="bffov" type="number" value="'+FOV_Y+'" style="width:34px;background:#1a1a1a;border:1px solid #ff1e1e;color:#fff;border-radius:3px;padding:2px 3px;text-align:center"></label>'
            +'<button id="bfscan" style="background:#81c784;border:none;color:#000;font-weight:bold;border-radius:3px;padding:2px 6px;cursor:pointer;font-size:10px">Scan</button>'
            +'</div>'
            +'<div id="bfst" style="padding:2px 8px;font-size:10px;color:#ff6666;border-bottom:1px solid #260a0a">Esperando partida...</div>'
            +'<div id="bflist" style="max-height:180px;overflow:auto;padding:4px 8px 8px;font-family:monospace;white-space:pre;font-size:11px;color:#ffb3b3"></div>'
            // THANH NẮM KÉO PHÍA DƯỚI (DRAG BAR BOTTOM)
            +'<div class="bfb-drag" style="padding:6px;cursor:move;background:#140505;border-top:1px solid #ff1e1e;display:flex;justify-content:center;align-items:center;border-radius:0 0 4px 4px;">'
            +'<div style="width:40px;height:4px;background:#ff4d4d;border-radius:2px;box-shadow:0 0 5px rgba(255,77,77,0.5);"></div>'
            +'</div>';

        document.body.appendChild(ui);
        listEl=ui.querySelector('#bflist');statusEl=ui.querySelector('#bfst');

        function readActive(){
            ACTIVE_IDS=[];
            var cbs=ui.querySelectorAll('.bfcb');
            for(var i=0;i<cbs.length;i++) if(cbs[i].checked) ACTIVE_IDS.push(parseInt(cbs[i].dataset.id));
        }

        ui.querySelectorAll('.bfcb').forEach(function(cb){
            cb.addEventListener('change',function(){ readActive(); forceScan(); });
        });

        ui.querySelector('#bfscan').onclick=function(){
            SEARCH_RADIUS=clampR(ui.querySelector('#bfr').value);
            ui.querySelector('#bfr').value=SEARCH_RADIUS;
            FOV_Y=parseInt(ui.querySelector('#bffov').value)||70;
            readActive(); forceScan();
        };
        ui.querySelector('#bfr').addEventListener('change',function(){SEARCH_RADIUS=clampR(this.value);this.value=SEARCH_RADIUS;});
        ui.querySelector('#bffov').addEventListener('change',function(){FOV_Y=parseInt(this.value)||70;});
        ui.querySelector('#bfesp').onclick=function(){
            espOn=!espOn;
            this.textContent=espOn?'ESP ON':'ESP OFF';
            this.style.background=espOn?'#b71c1c':'#333';
            this.style.borderColor=espOn?'#ff5252':'#555';
        };

        // 6TOUCH & MOUSE7
        var drag=false, ox=0, oy=0;

        function startDrag(clientX, clientY) {
            drag = true;
            ox = clientX - ui.offsetLeft;
            oy = clientY - ui.offsetTop;
        }

        function doDrag(clientX, clientY) {
            if (drag) {
                ui.style.left = (clientX - ox) + 'px';
                ui.style.top = (clientY - oy) + 'px';
            }
        }

        function stopDrag() {
            drag = false;
        }

        var dragElements = [ui.querySelector('.bfh'), ui.querySelector('.bfb-drag')];
        dragElements.forEach(function(el) {
            // Chuột (Mouse)
            el.addEventListener('mousedown', function(e){ startDrag(e.clientX, e.clientY); });

            // Màn hình cảm ứng Mobile (Touch)
            el.addEventListener('touchstart', function(e){
                if (e.touches.length === 1) {
                    startDrag(e.touches[0].clientX, e.touches[0].clientY);
                }
            }, { passive: true });
        });

        document.addEventListener('mousemove', function(e){ doDrag(e.clientX, e.clientY); });
        document.addEventListener('mouseup', stopDrag);

        document.addEventListener('touchmove', function(e){
            if (drag && e.touches.length === 1) {
                doDrag(e.touches[0].clientX, e.touches[0].clientY);
            }
        }, { passive: true });
        document.addEventListener('touchend', stopDrag);
    }

    function tryInit(){
        var o=getO();if(!o){setTimeout(tryInit,1000);return;}
        createUI();findCamera(o);startScan(o);renderLoop();
    }
    setTimeout(tryInit,2000);
})();