Загрузка данных
(function () {
let teleportCoords = null;
let guiOpen = false;
let browser = null;
let bindSaveKey = null;
let bindTeleportKey = null;
let bindAttachKey = null;
let bindThrowKey = null;
let bindTPToPlayerKey = null;
let bindAAALoopKey = null;
let espCarsEnabled = false;
let menuPos = { x: 0.3, y: 0.3 };
let currentTab = 'teleport';
let attachedVehicles = [];
let attachedTarget = null;
let tpTarget = null;
let savedAttachId = '';
let savedTpId = '';
let savedLoopTargetId = '';
let spamActive = false;
let loopTargetId = null;
// Изменено с HOME (0x24) на F8 (0x77)
const MENU_KEY = 0x77; // F8
mp.keys.bind(MENU_KEY, true, () => {
guiOpen ? closeMenu() : openMenu();
});
const ui = `
<!DOCTYPE html><html><head><meta charset="utf-8">
<style>
*{box-sizing:border-box}
html,body{margin:0;width:100%;height:100%;background:transparent;overflow:hidden;font-family:Consolas}
*{user-select:none;-webkit-user-select:none;-ms-user-select:none;-moz-user-select:none;}
body{ -webkit-touch-callout:none; -webkit-user-drag:none; }
#win{
position:absolute;
width:520px;
height:350px;
background:#0b0b0b;
color:#fff;
border-radius:8px;
border:1px solid #2a2a2a;
display:flex;
opacity:0;
transform:scale(0.8);
transition: opacity 250ms ease, transform 250ms ease;
}
#win.open{
opacity:1;
transform:scale(1);
}
#sidebar{width:120px;background:#0f0f0f;border-right:1px solid #2a2a2a}
.side-tab{padding:12px;text-align:center;cursor:pointer;opacity:.6;border-bottom:1px solid #2a2a2a}
.side-tab.active{background:#1e3a8a;opacity:1}
#content{flex:1;padding:10px}
#head{display:flex;align-items:center;cursor:move;user-select:none;margin-bottom:10px}
#head svg{margin-right:6px}
.row{display:flex;align-items:center;margin-bottom:10px}
.label{flex:1}
input{background:#111;color:#fff;border:1px solid #333;padding:4px 10px;width:170px;text-align:center;cursor:pointer}
.section{display:none}
.section.active{display:block}
.toggle-on{background:#1e3a8a}
.note{
font-size:11px;
opacity:0.6;
margin-top:6px;
}
</style>
</head>
<body>
<div id="win">
<div id="sidebar">
<div class="side-tab active" onclick="setTab('teleport')">Телепорт</div>
<div class="side-tab" onclick="setTab('attach')">Приклеить</div>
<div class="side-tab" onclick="setTab('extra')">Телепорт на игрока</div>
<div class="side-tab" onclick="setTab('slapper')">Слаппер</div>
</div>
<div id="content">
<div id="head">
<svg width="22" height="22" viewBox="0 0 45 48" fill="white">
<path d="M4.6875 35.5L0 43H45L40.3125 35.5H22.5H4.6875Z"/>
<path d="M14 14L5 5V24L13 32H25L14 21V14Z"/>
<path d="M31 14L40 5V24L32 32L30 32L25 27L31 21V14Z"/>
<path d="M18 19.5L22.5 24L27 19.5V12.5L22.5 8L18 12.5V19.5Z"/>
</svg>
<b>menu vehicle</b>
</div>
<div id="teleport" class="section active">
<div class="row">
<div class="label">ESP</div>
<input id="espCars" readonly onselectstart="return false" onmousedown="return false" value="Выключено" onclick="toggleESP()">
</div>
<div class="row">
<div class="label">Сохранить координаты</div>
<input id="bindSave" readonly onselectstart="return false" onmousedown="return false" onclick="listenKey('save')">
</div>
<div class="row">
<div class="label">Телепорт машин</div>
<input id="bindTeleport" readonly onselectstart="return false" onmousedown="return false" onclick="listenKey('teleport')">
</div>
<div class="row">
<div class="label">Подбрасывание машин</div>
<input id="bindThrow" readonly onselectstart="return false" onmousedown="return false" onclick="listenKey('throw')">
</div>
<div class="row">
<div class="label">Удалить все бинды</div>
<input id="resetBinds" readonly onselectstart="return false" onmousedown="return false" value="СБРОСИТЬ" onclick="resetBinds()">
</div>
</div>
<div id="attach" class="section">
<div class="row">
<div class="label">ID игрока</div>
<input id="targetId" value="" placeholder="Введите ID" oninput="setTarget(this.value)">
</div>
<div class="row">
<div class="label">Бинд приклеить</div>
<input id="bindAttach" readonly onselectstart="return false" onmousedown="return false" onclick="listenKey('attach')">
</div>
<div class="note">Машина приклеивается к игроку</div>
</div>
<div id="extra" class="section">
<div class="row">
<div class="label">ID игрока</div>
<input id="tpId" value="" placeholder="Введите ID" oninput="setTpTarget(this.value)">
</div>
<div class="row">
<div class="label">Бинд телепорта к игроку</div>
<input id="bindTPToPlayer" readonly onselectstart="return false" onmousedown="return false" onclick="listenKey('tpto')">
</div>
<div class="note">Машина телепортируется на игрока</div>
</div>
<div id="slapper" class="section">
<div class="row">
<div class="label">ID игрока</div>
<input id="loopTargetId" value="" placeholder="Введите ID" oninput="setLoopTarget(this.value)">
</div>
<div class="row">
<div class="label">Бинд вкл/выкл</div>
<input id="bindAAALoop" readonly onselectstart="return false" onmousedown="return false" onclick="listenKey('aaaloop')">
</div>
</div>
</div>
</div>
<script>
const w = win;
const h = head;
let drag=false, ox=0, oy=0;
let listening=null;
function setTab(t){
document.querySelectorAll('.side-tab').forEach(e=>e.classList.remove('active'));
document.querySelectorAll('.section').forEach(e=>e.classList.remove('active'));
document.querySelector('[onclick="setTab(\\''+t+'\\')"]').classList.add('active');
document.getElementById(t).classList.add('active');
mp.trigger('menu:setTab', t);
}
window.setBind=(t,n)=>{
if(t==='save') bindSave.value=n;
if(t==='teleport') bindTeleport.value=n;
if(t==='attach') bindAttach.value=n;
if(t==='throw') bindThrow.value=n;
if(t==='tpto') bindTPToPlayer.value=n;
if(t==='aaaloop') bindAAALoop.value=n;
};
window.setESP=(state)=>{
espCars.value = state ? 'Включено' : 'Выключено';
espCars.className = state ? 'toggle-on' : '';
};
window.toggleESP=()=>{
mp.trigger('menu:toggleESP');
};
window.setPos=(x,y)=>{
w.style.left=(innerWidth*x)+'px';
w.style.top=(innerHeight*y)+'px';
};
window.listenKey=t=>{
listening=t;
if(t==='save') bindSave.value='НАЖМИ КЛАВИШУ';
if(t==='teleport') bindTeleport.value='НАЖМИ КЛАВИШУ';
if(t==='attach') bindAttach.value='НАЖМИ КЛАВИШУ';
if(t==='throw') bindThrow.value='НАЖМИ КЛАВИШУ';
if(t==='tpto') bindTPToPlayer.value='НАЖМИ КЛАВИШУ';
if(t==='aaaloop') bindAAALoop.value='НАЖМИ КЛАВИШУ';
};
window.resetBinds=()=>{
mp.trigger('menu:resetBinds');
};
window.setTarget=(id)=>{
mp.trigger('attach:setTarget', id);
};
window.setTpTarget=(id)=>{
mp.trigger('tpto:setTarget', id);
};
window.setLoopTarget=(id)=>{
mp.trigger('slapper:setLoopTarget', id);
};
document.onkeydown=e=>{
if(!listening) return;
if(e.key === 'F8' || e.key === 'Escape'){ listening=null; return; }
let name=e.key.toUpperCase();
if(name===' ')name='SPACE';
if(name==='CONTROL')name='CTRL';
if(name==='SHIFT')name='SHIFT';
if(name==='ALT')name='ALT';
mp.trigger('menu:setBind',listening,e.keyCode,name);
listening=null;
};
h.onmousedown=e=>{
drag=true;
ox=e.clientX-w.offsetLeft;
oy=e.clientY-w.offsetTop;
};
document.onmouseup=()=>drag=false;
document.onmousemove=e=>{
if(drag){
w.style.left=e.clientX-ox+'px';
w.style.top=e.clientY-oy+'px';
mp.trigger('menu:savePos',w.offsetLeft/innerWidth,w.offsetTop/innerHeight);
}
};
document.addEventListener('contextmenu', event => event.preventDefault());
</script>
</body></html>
`;
function openMenu(){
if(browser) return;
browser = mp.browsers.new("data:text/html,"+encodeURIComponent(ui));
guiOpen = true;
mp.gui.cursor.show(true,true);
setTimeout(()=>{
browser.execute(`setBind('save','${getKeyName(bindSaveKey)}')`);
browser.execute(`setBind('teleport','${getKeyName(bindTeleportKey)}')`);
browser.execute(`setBind('attach','${getKeyName(bindAttachKey)}')`);
browser.execute(`setBind('throw','${getKeyName(bindThrowKey)}')`);
browser.execute(`setBind('tpto','${getKeyName(bindTPToPlayerKey)}')`);
browser.execute(`setBind('aaaloop','${getKeyName(bindAAALoopKey)}')`);
browser.execute(`setESP(${espCarsEnabled})`);
browser.execute(`setPos(${menuPos.x},${menuPos.y})`);
browser.execute(`document.getElementById('win').classList.add('open');`);
browser.execute(`setTab('${currentTab}');`);
browser.execute(`
if (document.getElementById('targetId')) document.getElementById('targetId').value = '${savedAttachId}';
if (document.getElementById('tpId')) document.getElementById('tpId').value = '${savedTpId}';
if (document.getElementById('loopTargetId')) document.getElementById('loopTargetId').value = '${savedLoopTargetId}';
`);
},50);
}
function closeMenu(){
if(!browser) return;
browser.execute(`document.getElementById('win').classList.remove('open');`);
setTimeout(()=>{
browser.destroy();
browser=null;
guiOpen=false;
mp.gui.cursor.show(false,false);
}, 250);
}
function rebind(){
if(bindSaveKey) mp.keys.unbind(bindSaveKey,true);
if(bindTeleportKey) mp.keys.unbind(bindTeleportKey,true);
if(bindAttachKey) mp.keys.unbind(bindAttachKey,true);
if(bindThrowKey) mp.keys.unbind(bindThrowKey,true);
if(bindTPToPlayerKey) mp.keys.unbind(bindTPToPlayerKey,true);
if(bindAAALoopKey) mp.keys.unbind(bindAAALoopKey,true);
if(bindSaveKey) mp.keys.bind(bindSaveKey,true,() => { if(!guiOpen) saveCoords(); });
if(bindTeleportKey) mp.keys.bind(bindTeleportKey,true,() => { if(!guiOpen) teleportCars(); });
if(bindAttachKey) mp.keys.bind(bindAttachKey,true,() => { if(!guiOpen) attachCars(); });
if(bindThrowKey) mp.keys.bind(bindThrowKey,true,() => { if(!guiOpen) throwCars(); });
if(bindTPToPlayerKey) mp.keys.bind(bindTPToPlayerKey,true,() => { if(!guiOpen) teleportCarsToPlayer(); });
if(bindAAALoopKey) mp.keys.bind(bindAAALoopKey,true,() => { if(!guiOpen) toggleSpam(); });
}
rebind();
function saveCoords(){
teleportCoords = mp.players.local.position;
mp.gui.chat.push("Координаты сохранены");
}
function teleportCars(){
if(!teleportCoords)
return mp.gui.chat.push("Сначала сохраните координаты");
let count = 0;
const p = mp.players.local.position;
mp.vehicles.forEachInStreamRange(v=>{
if(!v.controller || v.controller.remoteId !== mp.players.local.remoteId) return;
if(mp.dist(p.x,p.y,p.z,v.position.x,v.position.y,v.position.z) <= 380){
v.setCoordsNoOffset(
teleportCoords.x,
teleportCoords.y,
teleportCoords.z,
false,false,false
);
count++;
}
});
mp.gui.chat.push(`Машины телепортированы (${count})`);
}
function attachCars(){
if (!attachedTarget || !mp.players.exists(attachedTarget)) {
mp.gui.chat.push("Сначала выбери цель через ввод ID.");
return;
}
const player = mp.players.local;
const headBone = attachedTarget.getBoneIndex(12844);
mp.vehicles.forEachInStreamRange(vehicle => {
if (!vehicle || !mp.vehicles.exists(vehicle)) return;
if (vehicle.controller && vehicle.controller.remoteId === player.remoteId) {
if (attachedVehicles.includes(vehicle)) return;
vehicle.attachTo(
attachedTarget.handle,
headBone,
0, 0, 0.5,
0, 0, 0,
false, false, false, false,
2, true
);
attachedVehicles.push(vehicle);
}
});
mp.gui.chat.push(`Приклеено: ${attachedVehicles.length}`);
}
function throwCars(){
const player = mp.players.local;
const playerPos = player.position;
const radius = 380.0;
let count = 0;
mp.vehicles.forEachInStreamRange(veh => {
if (!veh.controller || veh.controller.remoteId !== player.remoteId) return;
const dist = mp.game.gameplay.getDistanceBetweenCoords(
playerPos.x, playerPos.y, playerPos.z,
veh.position.x, veh.position.y, veh.position.z,
true
);
if (dist <= radius) {
veh.setVelocity(0, 0, 70);
count++;
}
});
mp.gui.chat.push(`Подброшено машин: ${count}`);
}
function teleportCarsToPlayer(){
if (!tpTarget || !mp.players.exists(tpTarget)) {
mp.gui.chat.push("Игрок не найден (ID не в стриме или не существует).");
return;
}
const player = mp.players.local;
const playerPos = player.position;
const radius = 380.0;
let count = 0;
const targetPos = tpTarget.position;
mp.vehicles.forEachInStreamRange(veh => {
if (!veh.controller || veh.controller.remoteId !== player.remoteId) return;
const dist = mp.game.gameplay.getDistanceBetweenCoords(
playerPos.x, playerPos.y, playerPos.z,
veh.position.x, veh.position.y, veh.position.z,
true
);
if (dist <= radius) {
veh.setCoordsNoOffset(targetPos.x, targetPos.y, targetPos.z + 1, false, false, false);
count++;
}
});
mp.gui.chat.push(`Телепортировано машин: ${count}`);
}
function toggleSpam(){
spamActive = !spamActive;
mp.gui.chat.push(spamActive ? "Слаппер включен" : "Слаппер выключен");
}
const drawCarsESP = () => {
const p = mp.players.local.position;
mp.vehicles.forEachInStreamRange(v=>{
if(!v.controller || v.controller.remoteId !== mp.players.local.remoteId) return;
if(mp.dist(p.x,p.y,p.z,v.position.x,v.position.y,v.position.z) < 380){
mp.game.graphics.drawText(
"TP",
[v.position.x, v.position.y, v.position.z],
{ font:4, color:[255,255,255,255], scale:[0.35,0.35], outline:true }
);
}
});
};
mp.events.add("render", () => {
if(espCarsEnabled) drawCarsESP();
if (!spamActive) return;
const targetPlayer = mp.players.atRemoteId(loopTargetId);
if (!targetPlayer) return;
let controlledVehicle = null;
mp.vehicles.forEach(vehicle => {
if (vehicle.controller &&
vehicle.controller.remoteId === mp.players.local.remoteId) {
controlledVehicle = vehicle;
}
});
if (!controlledVehicle) return;
const pos = targetPlayer.position;
controlledVehicle.setCoordsNoOffset(
pos.x,
pos.y,
pos.z - 3,
false,
false,
false
);
controlledVehicle.setVelocity(0, 0, 70);
});
mp.events.add('menu:setBind',(type,keyCode,keyName)=>{
if(type==='save') bindSaveKey = keyCode;
if(type==='teleport') bindTeleportKey = keyCode;
if(type==='attach') bindAttachKey = keyCode;
if(type==='throw') bindThrowKey = keyCode;
if(type==='tpto') bindTPToPlayerKey = keyCode;
if(type==='aaaloop') bindAAALoopKey = keyCode;
rebind();
browser?.execute(`setBind('${type}','${keyName}')`);
});
mp.events.add('menu:toggleESP',()=>{
espCarsEnabled = !espCarsEnabled;
browser?.execute(`setESP(${espCarsEnabled})`);
mp.gui.chat.push(espCarsEnabled ? 'Включено' : 'Выключено');
});
mp.events.add('menu:setTab',(tab)=>{
currentTab = tab;
});
mp.events.add('menu:savePos',(x,y)=>{ menuPos={x,y}; });
mp.events.add('menu:resetBinds',()=>{
if(bindSaveKey) mp.keys.unbind(bindSaveKey,true);
if(bindTeleportKey) mp.keys.unbind(bindTeleportKey,true);
if(bindAttachKey) mp.keys.unbind(bindAttachKey,true);
if(bindThrowKey) mp.keys.unbind(bindThrowKey,true);
if(bindTPToPlayerKey) mp.keys.unbind(bindTPToPlayerKey,true);
if(bindAAALoopKey) mp.keys.unbind(bindAAALoopKey,true);
bindSaveKey = null;
bindTeleportKey = null;
bindAttachKey = null;
bindThrowKey = null;
bindTPToPlayerKey = null;
bindAAALoopKey = null;
browser?.execute(`setBind('save','---')`);
browser?.execute(`setBind('teleport','---')`);
browser?.execute(`setBind('attach','---')`);
browser?.execute(`setBind('throw','---')`);
browser?.execute(`setBind('tpto','---')`);
browser?.execute(`setBind('aaaloop','---')`);
mp.gui.chat.push("Все пользовательские бинды удалены");
});
mp.events.add('attach:setTarget', (id) => {
savedAttachId = id;
const targetId = parseInt(id);
if (isNaN(targetId)) return;
const target = mp.players.atRemoteId(targetId);
if (!target || !mp.players.exists(target)) return;
attachedTarget = target;
});
mp.events.add('tpto:setTarget', (id) => {
savedTpId = id;
const targetId = parseInt(id);
if (isNaN(targetId)) return;
const target = mp.players.toArray().find(p => p.remoteId === targetId);
if (!target || !mp.players.exists(target)) return;
tpTarget = target;
});
mp.events.add('slapper:setLoopTarget', (id) => {
savedLoopTargetId = id;
const targetId = parseInt(id);
if (isNaN(targetId)) return;
loopTargetId = targetId;
});
function getKeyName(code){
if(!code) return '---';
if(code>=48 && code<=57) return String.fromCharCode(code);
if(code>=65 && code<=90) return String.fromCharCode(code);
const f={0x70:'F1',0x71:'F2',0x72:'F3',0x73:'F4',0x74:'F5',
0x75:'F6',0x76:'F7',0x77:'F8',0x78:'F9',0x79:'F10',
0x7A:'F11',0x7B:'F12'};
return f[code]||'KEY';
}
})();