Загрузка данных
"use strict";
/// Виталя шота сделал
var nickMaskBrowser = null;
var isMaskVisible = false;
var logBrowser = null;
var logBrowserHTML = `<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
html, body {
margin: 0; padding: 0;
background: transparent !important;
overflow: hidden;
font-family: 'Segoe UI', Verdana, sans-serif;
user-select: none;
}
@keyframes snowfall {
0% { transform: translateY(-10px) translateX(0); opacity: 0.8; }
100% { transform: translateY(200px) translateX(15px); opacity: 0; }
}
.snowflake {
position: absolute; background: white; border-radius: 50%;
top: -10px; z-index: 1; pointer-events: none;
animation: snowfall linear infinite;
box-shadow: 0 0 5px rgba(255,255,255,0.8);
}
#log-menu {
position: absolute; left: 15px; top: 330px; width: 220px;
background: linear-gradient(160deg, rgba(107,0,179,0.75), rgba(0,0,0,0.8));
border-radius: 12px; color: #fff; z-index: 9998; cursor: move;
box-shadow: 0 8px 20px rgba(0,0,0,0.3);
border: 1px solid rgba(255,255,255,0.2); overflow: hidden;
}
h1 {
font-size: 14px; margin: 0; padding: 10px; text-align: center;
font-weight: 700; text-transform: uppercase; letter-spacing: 1px;
color: #fff; background: rgba(0,0,0,0.15);
border-bottom: 1px solid rgba(255,255,255,0.1);
}
#status-container { padding: 10px 15px; position: relative; z-index: 2; }
.info-row {
display: flex; justify-content: space-between; align-items: center;
margin-bottom: 6px; font-size: 12px;
}
.info-row:last-child { margin-bottom: 0; }
.label {
color: rgba(255,255,255,0.9); font-weight: 600;
font-size: 11px; text-shadow: 0 1px 2px rgba(0,0,0,0.5);
}
.value-box {
background: rgba(255,255,255,0.15); padding: 2px 8px;
border-radius: 6px; font-weight: 700; font-size: 11px;
color: #fff; text-align: right; min-width: 60px; max-width: 120px;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
transition: background 0.3s; box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}
</style>
</head>
<body>
<div id="log-menu">
<div class="snowflake" style="left:10%;width:4px;height:4px;animation-duration:4s;animation-delay:0s;"></div>
<div class="snowflake" style="left:30%;width:3px;height:3px;animation-duration:5s;animation-delay:1s;"></div>
<div class="snowflake" style="left:50%;width:5px;height:5px;animation-duration:3.5s;animation-delay:2s;"></div>
<div class="snowflake" style="left:70%;width:3px;height:3px;animation-duration:4.5s;animation-delay:0.5s;"></div>
<div class="snowflake" style="left:90%;width:4px;height:4px;animation-duration:3s;animation-delay:1.5s;"></div>
<h1>BOT by PROMERHIC</h1>
<div id="status-container">
<div class="info-row">
<span class="label">СТАТУС БОТА:</span>
<span id="status-value" class="value-box">ОСТАНОВЛЕН (F8)</span>
</div>
<div class="info-row">
<span class="label">ПОЗИЦИЯ:</span>
<span id="route-value" class="value-box">Н/Д</span>
</div>
<div class="info-row">
<span class="label">ТАЙМЕР АНТИ-ЗАСТРЕВАНИЯ:</span>
<span id="timer-value" class="value-box">Н/Д</span>
</div>
<div class="info-row">
<span class="label">АДМИНЫ РЯДОМ</span>
<span id="admin-value" class="value-box">0</span>
</div>
<div class="info-row">
<span class="label">КЛИКЕР:</span>
<span id="clicker-value" class="value-box">ОТКЛЮЧЕН</span>
</div>
</div>
</div>
<script>
const logMenu = document.getElementById('log-menu');
let isDragging = false, offsetX, offsetY;
logMenu.onmousedown = function(e) {
isDragging = true;
offsetX = e.clientX - logMenu.getBoundingClientRect().left;
offsetY = e.clientY - logMenu.getBoundingClientRect().top;
e.preventDefault();
};
document.onmousemove = function(e) {
if (isDragging) {
logMenu.style.left = (e.clientX - offsetX) + 'px';
logMenu.style.top = (e.clientY - offsetY) + 'px';
}
};
document.onmouseup = function() { isDragging = false; };
</script>
</body>
</html>`;
if (logBrowser) { logBrowser.destroy(); logBrowser = null; }
logBrowser = mp.browsers.new("data:text/html," + encodeURIComponent(logBrowserHTML));
// ---- HUD helpers ----
function updateStatus(status, route) {
if (!logBrowser) return;
logBrowser.execute(`document.getElementById('status-value').innerText = ${JSON.stringify(status)};`);
logBrowser.execute(`document.getElementById('route-value').innerText = ${JSON.stringify(route)};`);
var bg = "rgba(255,255,255,0.15)";
if (status.startsWith("Фармит...") || status.startsWith("Активирован..")) bg = "rgba(100,255,100,0.35)";
else if (status.includes("АФК..")) bg = "rgba(255,50,50,0.6)";
logBrowser.execute(`document.getElementById('status-value').style.background = '${bg}';`);
}
function updateTimer(val) {
if (!logBrowser) return;
logBrowser.execute(`document.getElementById('timer-value').innerText = ${JSON.stringify(val)};`);
var bg = val === "Телепортирую..." ? "rgba(255,200,50,0.6)" : "rgba(255,255,255,0.15)";
logBrowser.execute(`document.getElementById('timer-value').style.background = '${bg}';`);
}
function updateAdminCount(count) {
if (!logBrowser) return;
logBrowser.execute(`document.getElementById('admin-value').innerText = '${count}';`);
logBrowser.execute(`document.getElementById('admin-value').style.background = 'rgba(255,255,255,0.15)';`);
}
function updateClickerStatus(status) {
if (!logBrowser) return;
var bg = status === "ВКЛЮЧЕН" ? "rgba(100,255,100,0.35)" : "rgba(255,255,255,0.15)";
logBrowser.execute(`
var el = document.getElementById('clicker-value');
if (el) { el.innerText = '${status}'; el.style.background = '${bg}'; }
`);
}
// ============================================================
// Safety zone
// ============================================================
var SAFETY_ZONE_HEIGHT = 4.0;
var SAFETY_ZONE_COLOR = [255, 0, 0, 180];
var SAFETY_ZONE_COORDS = [
new mp.Vector3(-451.88, -2677.97, 5.01),
new mp.Vector3(-494.98, -2721.12, 5.01),
new mp.Vector3(-452.69, -2762.40, 5.01),
new mp.Vector3(-448.32, -2758.15, 5.01),
new mp.Vector3(-390.93, -2757.68, 5.01),
new mp.Vector3(-376.61, -2742.29, 5.01),
new mp.Vector3(-368.58, -2728.36, 5.01),
];
var SAFETY_ZONE_POLYGON = SAFETY_ZONE_COORDS.map(p => ({ x: p.x, y: p.y }));
function isPlayerInSafetyZone(point, polygon) {
var inside = false;
for (var i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
var xi = polygon[i].x, yi = polygon[i].y;
var xj = polygon[j].x, yj = polygon[j].y;
var intersect = ((yi > point.y) !== (yj > point.y))
&& (point.x < (xj - xi) * (point.y - yi) / (yj - yi) + xi);
if (intersect) inside = !inside;
}
return inside;
}
function drawSafetyZone() {
var len = SAFETY_ZONE_COORDS.length;
for (var i = 0; i < len; i++) {
var p1b = SAFETY_ZONE_COORDS[i];
var p2b = SAFETY_ZONE_COORDS[(i + 1) % len];
var p1t = new mp.Vector3(p1b.x, p1b.y, p1b.z + SAFETY_ZONE_HEIGHT);
var p2t = new mp.Vector3(p2b.x, p2b.y, p2b.z + SAFETY_ZONE_HEIGHT);
var c = SAFETY_ZONE_COLOR;
mp.game.graphics.drawLine(p1b.x, p1b.y, p1b.z, p2b.x, p2b.y, p2b.z, ...c);
mp.game.graphics.drawLine(p1t.x, p1t.y, p1t.z, p2t.x, p2t.y, p2t.z, ...c);
mp.game.graphics.drawLine(p1b.x, p1b.y, p1b.z, p1t.x, p1t.y, p1t.z, ...c);
mp.game.graphics.drawLine(p1b.x, p1b.y, p1b.z, p2t.x, p2t.y, p2t.z, ...c);
mp.game.graphics.drawLine(p2b.x, p2b.y, p2b.z, p1t.x, p1t.y, p1t.z, ...c);
}
}
// ============================================================
// Routes
// ============================================================
var ROUTE_CARRY_1 = [
[new mp.Vector3(-438.91,-2733.70,6)],[new mp.Vector3(-440.44,-2733.29,6)],
[new mp.Vector3(-441.66,-2732.68,6)],[new mp.Vector3(-442.62,-2731.79,6)],
[new mp.Vector3(-451.99,-2722.89,6)],[new mp.Vector3(-453.12,-2722.03,6)],
[new mp.Vector3(-454.13,-2721.39,6)],[new mp.Vector3(-455.85,-2720.27,6)],
[new mp.Vector3(-458.47,-2718.62,6)],[new mp.Vector3(-461.15,-2719.19,6)],
[new mp.Vector3(-462.59,-2718.26,6)],[new mp.Vector3(-463.39,-2716.36,6)],
[new mp.Vector3(-464.65,-2715.30,6)],[new mp.Vector3(-465.85,-2714.71,6)],
[new mp.Vector3(-466.43,-2715.41,6)],[new mp.Vector3(-466.03,-2716.70,6)],
[new mp.Vector3(-460.90,-2722.01,6)],[new mp.Vector3(-466.67,-2714.87,6)],
[new mp.Vector3(-464.83,-2715.07,6)],[new mp.Vector3(-462.25,-2714.48,6)],
[new mp.Vector3(-463.38,-2717.35,6)],[new mp.Vector3(-461.58,-2719.22,6)],
[new mp.Vector3(-459.80,-2719.14,6)],[new mp.Vector3(-459.23,-2717.72,6)],
[new mp.Vector3(-440.34,-2735.44,6)],[new mp.Vector3(-440.33,-2735.44,6)],
];
var ROUTE_CARRY_2 = [
[new mp.Vector3(-441.51,-2732.93,6)],[new mp.Vector3(-450.88,-2723.85,6)],
[new mp.Vector3(-453.53,-2721.41,6)],[new mp.Vector3(-456.53,-2719.36,6)],
[new mp.Vector3(-458.47,-2718.62,6)],[new mp.Vector3(-461.15,-2719.19,6)],
[new mp.Vector3(-462.59,-2718.26,6)],[new mp.Vector3(-463.39,-2716.36,6)],
[new mp.Vector3(-464.65,-2715.30,6)],[new mp.Vector3(-465.85,-2714.71,6)],
[new mp.Vector3(-466.43,-2715.41,6)],[new mp.Vector3(-466.03,-2716.70,6)],
[new mp.Vector3(-460.90,-2722.01,6)],[new mp.Vector3(-466.67,-2714.87,6)],
[new mp.Vector3(-464.83,-2715.07,6)],[new mp.Vector3(-462.25,-2714.48,6)],
[new mp.Vector3(-463.38,-2717.35,6)],[new mp.Vector3(-461.58,-2719.22,6)],
[new mp.Vector3(-459.80,-2719.14,6)],[new mp.Vector3(-459.23,-2717.72,6)],
[new mp.Vector3(-440.34,-2735.44,6)],[new mp.Vector3(-440.33,-2735.44,6)],
];
var ROUTE_CARRY_3 = [
[new mp.Vector3(-438.53,-2730.49,6)],[new mp.Vector3(-438.89,-2729.58,6)],
[new mp.Vector3(-439.70,-2728.34,6)],[new mp.Vector3(-445.42,-2723.11,6)],
[new mp.Vector3(-446.62,-2722.23,6)],[new mp.Vector3(-448.10,-2721.45,6)],
[new mp.Vector3(-450.13,-2720.79,6)],[new mp.Vector3(-458.47,-2718.62,6)],
[new mp.Vector3(-461.15,-2719.19,6)],[new mp.Vector3(-462.59,-2718.26,6)],
[new mp.Vector3(-463.39,-2716.36,6)],[new mp.Vector3(-464.65,-2715.30,6)],
[new mp.Vector3(-465.85,-2714.71,6)],[new mp.Vector3(-466.43,-2715.41,6)],
[new mp.Vector3(-466.03,-2716.70,6)],[new mp.Vector3(-460.90,-2722.01,6)],
[new mp.Vector3(-466.67,-2714.87,6)],[new mp.Vector3(-464.83,-2715.07,6)],
[new mp.Vector3(-462.25,-2714.48,6)],[new mp.Vector3(-463.38,-2717.35,6)],
[new mp.Vector3(-461.58,-2719.22,6)],[new mp.Vector3(-459.80,-2719.14,6)],
[new mp.Vector3(-459.23,-2717.72,6)],[new mp.Vector3(-440.34,-2735.44,6)],
[new mp.Vector3(-440.33,-2735.44,6)],
];
var ROUTE_CARRY_4 = [
[new mp.Vector3(-436.03,-2732.87,6)],[new mp.Vector3(-436.69,-2731.33,6)],
[new mp.Vector3(-437.45,-2729.32,6)],[new mp.Vector3(-438.34,-2727.31,6)],
[new mp.Vector3(-440.11,-2725.16,6)],[new mp.Vector3(-444.86,-2721.01,6)],
[new mp.Vector3(-448.86,-2719.13,6)],[new mp.Vector3(-452.04,-2718.73,6)],
[new mp.Vector3(-458.47,-2718.62,6)],[new mp.Vector3(-461.15,-2719.19,6)],
[new mp.Vector3(-462.59,-2718.26,6)],[new mp.Vector3(-463.39,-2716.36,6)],
[new mp.Vector3(-464.65,-2715.30,6)],[new mp.Vector3(-465.85,-2714.71,6)],
[new mp.Vector3(-466.43,-2715.41,6)],[new mp.Vector3(-466.03,-2716.70,6)],
[new mp.Vector3(-460.90,-2722.01,6)],[new mp.Vector3(-466.67,-2714.87,6)],
[new mp.Vector3(-464.83,-2715.07,6)],[new mp.Vector3(-462.25,-2714.48,6)],
[new mp.Vector3(-463.38,-2717.35,6)],[new mp.Vector3(-461.58,-2719.22,6)],
[new mp.Vector3(-459.80,-2719.14,6)],[new mp.Vector3(-459.23,-2717.72,6)],
[new mp.Vector3(-440.34,-2735.44,6)],[new mp.Vector3(-440.33,-2735.44,6)],
];
var ALL_CARRY_ROUTES_TEMPLATES = [
{ name: "Доставка #1", route: ROUTE_CARRY_1 },
{ name: "Доставка #2", route: ROUTE_CARRY_2 },
{ name: "Доставка #3", route: ROUTE_CARRY_3 },
{ name: "Доставка #4", route: ROUTE_CARRY_4 },
];
var ROUTE_EMPTY_TEMPLATE = {
name: "Беру ящик..",
route: [
[new mp.Vector3(-458.64,-2727.29,6)],[new mp.Vector3(-457.58,-2729.58,6)],
[new mp.Vector3(-455.32,-2732.09,6)],[new mp.Vector3(-451.80,-2735.55,6)],
[new mp.Vector3(-450.33,-2736.48,6)],[new mp.Vector3(-448.08,-2737.56,6)],
[new mp.Vector3(-445.60,-2738.64,6)],[new mp.Vector3(-443.24,-2739.44,6)],
[new mp.Vector3(-439.61,-2740.32,6)],[new mp.Vector3(-437.18,-2740.92,6)],
[new mp.Vector3(-435.74,-2740.88,6)],[new mp.Vector3(-432.77,-2740.68,6)],
[new mp.Vector3(-430.55,-2741.53,6)],[new mp.Vector3(-429.67,-2739.96,6)],
[new mp.Vector3(-428.10,-2740.10,6)],[new mp.Vector3(-426.61,-2741.02,6)],
[new mp.Vector3(-424.23,-2741.72,6)],[new mp.Vector3(-426.01,-2739.83,6)],
[new mp.Vector3(-428.19,-2739.98,6)],[new mp.Vector3(-429.40,-2740.48,6)],
[new mp.Vector3(-430.08,-2742.11,6)],[new mp.Vector3(-431.22,-2741.90,6)],
[new mp.Vector3(-432.11,-2740.45,6)],[new mp.Vector3(-435.86,-2740.50,6)],
[new mp.Vector3(-436.62,-2741.33,6)],[new mp.Vector3(-447.82,-2741.47,6)],
],
};
// ============================================================
// Bot state
// ============================================================
var autorunActive = false;
var currentRouteData = null;
var routeStep = 0;
var lastCarryingState = null;
var isAdminDetected = false;
var adminPauseTriggered = false;
var stuckTimerTimestamp = 0;
var STUCK_TIMEOUT = 7500;
var lastMenuUpdateTime = 0;
var MENU_UPDATE_INTERVAL = 200;
// ============================================================
// Autoclicker
// ============================================================
var portClicker = {
active: false,
checkInterval: null,
browser: null,
gameWasVisible: false,
hasPressed: false,
clickDelayMin: 500,
clickDelayMax: 503,
getRandomDelay: function() {
return Math.floor(Math.random() * (this.clickDelayMax - this.clickDelayMin + 1)) + this.clickDelayMin;
},
findBrowser: function() {
var browsers = mp.browsers.toArray();
for (var i = 0; i < browsers.length; i++) {
var url = browsers[i].url || '';
if (url.includes('__menu.html') || url.includes('Menu')) return browsers[i];
}
return null;
},
checkAndPress: function() {
this.browser = this.findBrowser();
if (!this.browser) { this.gameWasVisible = false; this.hasPressed = false; return; }
var checkCode = `(function(){
var gc = document.getElementById('portGameContent');
mp.trigger('clicker:gameStatus', !!(gc && gc.style.display !== 'none'));
})();`;
try { this.browser.execute(checkCode); } catch(e) {}
},
pressE: function() {
if (!this.browser) return;
var pressCode = `(function(){
['keydown','keypress','keyup'].forEach(function(type){
var e = new KeyboardEvent(type,{key:'E',code:'KeyE',bubbles:true,cancelable:true,view:window});
document.body.dispatchEvent(e);
document.dispatchEvent(e);
});
})();`;
try { this.browser.execute(pressCode); } catch(e) {}
},
onGameStatus: function(isVisible) {
if (isVisible && !this.gameWasVisible && !this.hasPressed) {
this.gameWasVisible = true;
var self = this;
setTimeout(function() {
if (self.active) { self.pressE(); self.hasPressed = true; }
}, this.getRandomDelay());
}
if (!isVisible) { this.gameWasVisible = false; this.hasPressed = false; }
},
start: function() {
if (this.active) return;
this.active = true;
this.gameWasVisible = false;
this.hasPressed = false;
var self = this;
this.checkInterval = setInterval(function() { if (self.active) self.checkAndPress(); }, 200);
updateClickerStatus("ВКЛ.");
},
stop: function() {
this.active = false;
if (this.checkInterval) { clearInterval(this.checkInterval); this.checkInterval = null; }
this.gameWasVisible = false;
this.hasPressed = false;
updateClickerStatus("ВЫКЛ.");
},
};
// ============================================================
// Bot logic
// ============================================================
function playerIsCarryingBox() {
return mp.players.local.isPlayingAnim("anim@heists@box_carry@", "idle", 3);
}
function stopAutorun() {
var player = mp.players.local;
if (player && player.handle) {
mp.game.invoke('0xE1EF3C1216AFF2CD', player.handle);
player.setMoveRateOverride(1.0);
try { mp.game.task.setPedDesiredMoveBlendRatio(player.handle, 1.0); } catch(e) {}
}
autorunActive = false;
stuckTimerTimestamp = 0;
portClicker.stop();
updateStatus("Остановлен.. (F7)", "Н/Д");
updateTimer("Н/Д");
}
function chooseRoute(findNearest) {
var carrying = playerIsCarryingBox();
lastCarryingState = carrying;
var template, name;
if (carrying) {
var idx = Math.floor(Math.random() * ALL_CARRY_ROUTES_TEMPLATES.length);
template = ALL_CARRY_ROUTES_TEMPLATES[idx].route;
name = ALL_CARRY_ROUTES_TEMPLATES[idx].name;
} else {
template = ROUTE_EMPTY_TEMPLATE.route;
name = ROUTE_EMPTY_TEMPLATE.name;
}
currentRouteData = { name: name, route: template };
if (findNearest) {
var playerPos = mp.players.local.position;
var minDist = Infinity, closestIdx = 0;
for (var i = 0; i < template.length; i++) {
var pt = template[i][0];
var d = mp.game.gameplay.getDistanceBetweenCoords(
playerPos.x, playerPos.y, playerPos.z, pt.x, pt.y, pt.z, true
);
if (d < minDist) { minDist = d; closestIdx = i; }
}
routeStep = closestIdx;
} else {
routeStep = 0;
}
stuckTimerTimestamp = Date.now();
updateStatus("Фармит... " + (routeStep + 1) + "/" + template.length, name);
updateTimer("7.5 сек.");
}
function moveTo(target) {
var player = mp.players.local;
if (!player || !player.handle) return;
player.setMoveRateOverride(1.4);
try { mp.game.task.setPedDesiredMoveBlendRatio(player.handle, 1.35); } catch(e) {}
var pos = player.position;
var heading = Math.atan2(target.y - pos.y, target.x - pos.x) * 180 / Math.PI;
mp.game.task.taskGoStraightToCoord(player.handle, target.x, target.y, target.z, 4.0, 60000, heading, 0);
}
// ============================================================
// Key handlers
// ============================================================
var startHandler = function() {
if (autorunActive) return;
var playerPos = mp.players.local.position;
if (!isPlayerInSafetyZone({ x: playerPos.x, y: playerPos.y }, SAFETY_ZONE_POLYGON)) {
mp.gui.chat.push("!{FF0000}[ПОРТ-БОТ]: !{FFFFFF}Тебе русским языком сказали! НЕ МОГУ РАБОТАТЬ ВНЕ КРАСНОЙ ЗОНЫ ИШАК!!");
return;
}
autorunActive = true;
portClicker.start();
updateStatus("Активирован", "Ищу...");
chooseRoute(true);
stuckTimerTimestamp = Date.now();
updateTimer("7.5 сек.");
};
var stopHandler = function() {
if (!autorunActive) return;
stopAutorun();
};
var f9TeleportHandler = function() {
var player = mp.players.local;
if (player && player.handle) player.position = new mp.Vector3(-457.70, -2750.95, 8.00);
};
// ============================================================
// Render
// ============================================================
var renderHandler = function() {
var player = mp.players.local;
if (!player || !player.handle) return;
var playerPos = player.position;
var now = Date.now();
// Admin scan + draw lines
var adminCount = 0;
mp.players.forEachInStreamRange(function(p) {
if (p === player || !p.doesExist() || p.handle === 0) return;
if (p.__displayIsAdmin) {
adminCount++;
var ap = p.position;
mp.game.graphics.drawLine(playerPos.x, playerPos.y, playerPos.z, ap.x, ap.y, ap.z, 255, 0, 0, 255);
var dist = mp.game.system.vdist(playerPos.x, playerPos.y, playerPos.z, ap.x, ap.y, ap.z);
mp.game.graphics.drawText(
"ADMIN\n~r~" + dist.toFixed(1) + " m.",
[ap.x, ap.y, ap.z + 1.2],
{ font: 0, color: [255,0,0,255], scale: [0.3,0.3], outline: true, centre: true }
);
}
});
isAdminDetected = adminCount > 0;
if (now - lastMenuUpdateTime > MENU_UPDATE_INTERVAL) {
updateAdminCount(adminCount);
}
if (!autorunActive) return;
if (player.isDead() || player.vehicle) { stopAutorun(); return; }
if (!isPlayerInSafetyZone({ x: playerPos.x, y: playerPos.y }, SAFETY_ZONE_POLYGON)) {
mp.gui.chat.push("!{FF0000}[ПОРТ-БОТ]: !{FFFFFF}Ты вышел из красной зоны! Ишак!");
stopAutorun();
return;
}
if (isAdminDetected) {
if (!adminPauseTriggered) {
mp.game.invoke('0xE1EF3C1216AFF2CD', player.handle);
player.setMoveRateOverride(1.0);
try { mp.game.task.setPedDesiredMoveBlendRatio(player.handle, 1.0); } catch(e) {}
adminPauseTriggered = true;
}
stuckTimerTimestamp = Date.now();
if (now - lastMenuUpdateTime > MENU_UPDATE_INTERVAL) {
updateStatus("Админ рядом! Стою АФК..", "Остановился..");
updateTimer("Жду...");
lastMenuUpdateTime = now;
}
return;
} else {
adminPauseTriggered = false;
}
if (now - lastMenuUpdateTime > MENU_UPDATE_INTERVAL) {
lastMenuUpdateTime = now;
if (stuckTimerTimestamp !== 0) {
var timeLeft = Math.max(0, (STUCK_TIMEOUT - (now - stuckTimerTimestamp)) / 1000);
updateTimer(timeLeft.toFixed(1) + " сек.");
}
}
var carrying = playerIsCarryingBox();
if (carrying !== lastCarryingState) chooseRoute(false);
if (!currentRouteData || !currentRouteData.route.length) return;
var route = currentRouteData.route;
if (routeStep >= route.length) { routeStep = 0; stuckTimerTimestamp = Date.now(); }
var possibleTargets = route[routeStep];
var target = possibleTargets[Math.floor(Math.random() * possibleTargets.length)];
var dist = mp.game.gameplay.getDistanceBetweenCoords(
playerPos.x, playerPos.y, playerPos.z, target.x, target.y, target.z, true
);
var elapsed = Date.now() - stuckTimerTimestamp;
if (dist < 1.5) {
routeStep = (routeStep + 1) % route.length;
stuckTimerTimestamp = Date.now();
updateTimer("7.5 сек.");
updateStatus("Фармит... " + (routeStep + 1) + "/" + route.length, currentRouteData.name);
} else if (elapsed > STUCK_TIMEOUT) {
mp.gui.chat.push("[ПОРТ-БОТ]: Ты застрялъ, телепортирую тя.");
updateTimer("Телепортирую...");
player.position = new mp.Vector3(target.x, target.y, target.z);
routeStep = (routeStep + 1) % route.length;
stuckTimerTimestamp = Date.now();
updateStatus("Фармит... " + (routeStep + 1) + "/" + route.length, currentRouteData.name);
}
moveTo(target);
};
// ============================================================
// Unload
// ============================================================
var fullUnloadScript = function() {
if (autorunActive) stopAutorun();
portClicker.stop();
mp.keys.unbind(0x76, false, startHandler);
mp.keys.unbind(0x77, false, stopHandler);
mp.keys.unbind(0x78, false, f9TeleportHandler);
mp.keys.unbind(0x7B, false, fullUnloadScript);
mp.events.remove('render', renderHandler);
mp.events.remove('render', drawSafetyZone);
mp.events.remove('clicker:gameStatus', clickerGameStatusHandler);
if (nickMaskBrowser) { nickMaskBrowser.destroy(); nickMaskBrowser = null; isMaskVisible = false; }
if (logBrowser) { logBrowser.destroy(); logBrowser = null; }
currentRouteData = null;
lastCarryingState = null;
stuckTimerTimestamp = 0;
lastMenuUpdateTime = 0;
};
// ============================================================
// Events + binds
// ============================================================
var clickerGameStatusHandler = function(isVisible) {
portClicker.onGameStatus(isVisible);
};
mp.events.add('clicker:gameStatus', clickerGameStatusHandler);
mp.events.add('render', renderHandler);
mp.events.add('render', drawSafetyZone);
mp.keys.bind(0x76, false, startHandler); // F7
mp.keys.bind(0x77, false, stopHandler); // F8
mp.keys.bind(0x78, false, f9TeleportHandler); // F9
mp.keys.bind(0x7B, false, fullUnloadScript); // F12
// ============================================================
// Init messages
// ============================================================
mp.gui.chat.push("!{FFFFFF}.");
mp.gui.chat.push("!{00FF00}[ПОРТ-БОТ v1 + КЛИКЕР]: !{FFFFFF}Я заинжектился!");
mp.gui.chat.push("!{FFFF00}ВНИМАНИЕ!: !{FFFFFF}Я работаю только в !{FF0000}красной зоне!{FFFFFF}.");
mp.gui.chat.push("!{FFFFFF}.");