SkidWare ModMenu - diep.io

Spinner, Aimbot, AutoFarm

  1. // ==UserScript==
  2. // @license MIT
  3. // @name SkidWare ModMenu - diep.io
  4. // @namespace bo$$
  5. // @version v1.1.0
  6. // @description Spinner, Aimbot, AutoFarm
  7. // @author Dreamy @C:Mi300(Aimbot+Fov)
  8. // @match https://diep.io/*
  9. // @match https://staging.diep.io/*
  10. // @match https://diep-io.rivet.game/*
  11. // @icon https://gamesense.pub/favicon.ico
  12. // @grant none
  13. // @run-at document-start
  14. // ==/UserScript==
  15.  
  16. // mi300's discord - https://discord.gg/S4CA5w9p8p
  17. // my discord - https://discord.gg/NBN3jgQDGe
  18. const FOV_UPDATE_INTERVAL = 16.6;
  19. const FOV_LERP = 0.1;
  20. let setFov = 0.5;
  21. let foxv = 0.5;
  22. let keyStates = new Map();
  23.  
  24. const onWheelEvent = event => {setFov += -Math.sign(event.deltaY) * 0.02 * Math.log10(setFov / 0.55 + 1)}
  25. const onKeyDown = event => {keyStates.set(event.keyCode, 1)}
  26. const onKeyUp = event => {keyStates.set(event.keyCode, 0)}
  27.  
  28. function updateFov(){
  29. if(typeof window.extern === 'undefined')return;
  30. if(!window.extern.doesHaveTank())return;
  31. if(keyStates.get(187)) setFov += 0.01 * Math.log10(setFov / 0.55 + 1);
  32. if(keyStates.get(189)) setFov -= 0.01 * Math.log10(setFov / 0.55 + 1);
  33.  
  34. foxv += (setFov - foxv) * FOV_LERP;
  35. window.extern.setScreensizeZoom(1, foxv);
  36. }
  37. function init(){
  38. document.addEventListener("wheel", onWheelEvent);
  39. document.addEventListener("keydown", onKeyDown);
  40. document.addEventListener("keyup", onKeyUp);
  41. setInterval(updateFov, FOV_UPDATE_INTERVAL);
  42. }
  43. init();
  44.  
  45. let a;
  46. class _a {
  47. constructor() {
  48. this.p = {};
  49. this.v = false;
  50. document.addEventListener("DOMContentLoaded", this.tu.bind(this));
  51. }
  52.  
  53. tu() {
  54. if (this.v) return;
  55. this.v = true;
  56. const originalGetElementById = HTMLDocument.prototype.getElementById;
  57. HTMLDocument.prototype.getElementById = function (id) {
  58. const elem = originalGetElementById.call(document, id);
  59. if (id === "canvas") return wrapCanvas(elem);
  60. return elem;
  61. };
  62.  
  63. const originalCreateElement = HTMLDocument.prototype.createElement;
  64. HTMLDocument.prototype.createElement = function (tag) {
  65. const elem = originalCreateElement.call(document, tag);
  66. if (tag === "canvas") return wrapCanvas(elem);
  67. return elem;
  68. };
  69.  
  70. function wrapCanvas(origCanvas) {
  71. class HTMLCanvasElementProxy {}
  72. let proxyCanvas = new HTMLCanvasElementProxy();
  73. proxyCanvas.width = origCanvas.width;
  74. proxyCanvas.height = origCanvas.height;
  75. proxyCanvas.transferControlToOffscreen = origCanvas.transferControlToOffscreen.bind(origCanvas);
  76. proxyCanvas.toDataURL = origCanvas.toDataURL.bind(origCanvas);
  77. proxyCanvas.toBlob = origCanvas.toBlob.bind(origCanvas);
  78. proxyCanvas.captureStream = origCanvas.captureStream.bind(origCanvas);
  79.  
  80. proxyCanvas.getContext = function (...args) {
  81. let ctx = origCanvas.getContext(...args);
  82. if (args[0] !== "2d") return ctx;
  83. return new Proxy(ctx, {
  84. get: function (target, prop) {
  85. const original = target[prop];
  86. if (typeof original !== "function") return original;
  87. if (Object.keys(a.p).includes(prop)) {
  88. return function (...pArgs) {
  89. let skip = false;
  90. a.p[prop].forEach((hook) => {
  91. const result = hook(ctx, ...pArgs);
  92. if (!result) {
  93. skip = true;
  94. } else {
  95. [ctx, pArgs] = result;
  96. }
  97. });
  98. if (skip) return;
  99. return original.apply(target, pArgs);
  100. };
  101. }
  102. return original.bind(target);
  103. },
  104. set: function (target, prop, value) {
  105. target[prop] = value;
  106. return true;
  107. },
  108. });
  109. };
  110. return proxyCanvas;
  111. }
  112.  
  113. createUnifiedMenu();
  114. }
  115.  
  116. _(methodName, hookFn) {
  117. if (Object.keys(a.p).includes(methodName)) {
  118. a.p[methodName].push(hookFn);
  119. } else {
  120. a.p[methodName] = [hookFn];
  121. }
  122. }
  123. }
  124. a = new _a();
  125.  
  126. let spinSpeed = 0.80;
  127. let isSpinning = false;
  128. let spinAngle = 0;
  129. let isShooting = false;
  130. let isFiring = false;
  131. let isAimbotActive = false;
  132. let playerTank = "Tank";
  133. let playerLevel = 1;
  134. let playerX = 0;
  135. let playerY = 0;
  136. let arrowPos = [0, 0];
  137. let minimapPos = [0, 0];
  138. let minimapSize = [0, 0];
  139. let fov = 0.5;
  140. let text = [];
  141. let tankShapes = [];
  142. let lastPlayers = [];
  143. let players = [];
  144. let lastArc = [Infinity, Infinity];
  145. let mousePressed = false;
  146. let mouseLocked = false;
  147. let mouseX = 0;
  148. let mouseY = 0;
  149. let isAutoFarm = false;
  150. let neutralSquares = [];
  151. let neutralPentagons = [];
  152. let neutralTriangles = [];
  153. let farmPriority = "pentagon";
  154. let isDebug = false;
  155. let hasJoined = false;
  156. const averageEnemyDodgeTime = 1750;
  157. const destroyerAccuracy = true;
  158. const playerVelocityPredictionSampleSize = 50;
  159. const arenaSize = 26000;
  160. const gameStyle = {
  161. ren_grid_base_alpha: 0.05,
  162. square: "#ffe869",
  163. triangle: "#fc7677",
  164. pentagon: "#768dfc",
  165. teamBlue: "#00b2e1",
  166. teamRed: "#f14e54",
  167. teamPurple: "#bf7ff5",
  168. teamGreen: "#00e16e",
  169. };
  170. let teamColor = "";
  171. const bulletSpeedOffsets = {
  172. Skimmer: 0.5,
  173. Factory: 0.56,
  174. Annihilator: 0.7,
  175. Streamliner: 1.1,
  176. "Auto Gunner": 1.1,
  177. Gunner: 1.1,
  178. Predator: 1.4,
  179. Mothership: 0.48,
  180. Manager: 0.8,
  181. Hybrid: 0.7,
  182. Ranger: 1.5,
  183. Stalker: 1.5,
  184. Assassin: 1.5,
  185. Sniper: 1.5,
  186. Hunter: 1.4,
  187. Necromancer: 0.72,
  188. "Arena Closer": 2,
  189. Overlord: 0.8,
  190. Overseer: 0.8,
  191. Destroyer: 0.7,
  192. };
  193. const predatorStackTime = [
  194. [50, 500, 1400, 2800],
  195. [50, 500, 1300, 2700],
  196. [50, 400, 1200, 2450],
  197. [50, 300, 1100, 2200],
  198. [50, 300, 1000, 2100],
  199. [50, 300, 900, 1800],
  200. [50, 300, 800, 1700],
  201. [50, 300, 750, 1500],
  202. ];
  203. const hunterStackTime = [
  204. [50, 1200],
  205. [50, 1100],
  206. [50, 1000],
  207. [50, 950],
  208. [50, 800],
  209. [50, 725],
  210. [50, 700],
  211. [50, 625],
  212. ];
  213. const buildStatLevels = [
  214. 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
  215. 23, 24, 25, 26, 27, 28, 30, 33, 36, 39, 42, 45,
  216. ];
  217. const statNumbers = {
  218. 1: "healthRegen",
  219. 2: "maxHealth",
  220. 3: "bodyDamage",
  221. 4: "bulletSpeed",
  222. 5: "bulletPenetration",
  223. 6: "bulletDamage",
  224. 7: "reload",
  225. 8: "movementSpeed",
  226. };
  227.  
  228. function getUpgrades() {
  229. let upgrades = 0;
  230. for (let i = 0; i < buildStatLevels.length; ++i) {
  231. upgrades++;
  232. if (playerLevel < buildStatLevels[i]) break;
  233. }
  234. return upgrades;
  235. }
  236. function canUpgrade() {
  237. const rawStats = window.extern.get_convar("game_stats_build");
  238. return getUpgrades() - 1 > rawStats.length;
  239. }
  240. function truncateStats() {
  241. const rawStats = window.extern.get_convar("game_stats_build");
  242. return rawStats.slice(0, getUpgrades());
  243. }
  244. function getStats() {
  245. const rawStats = window.extern.get_convar("game_stats_build");
  246. let stats = {
  247. healthRegen: 0,
  248. maxHealth: 0,
  249. bodyDamage: 0,
  250. bulletSpeed: 0,
  251. bulletPenetration: 0,
  252. bulletDamage: 0,
  253. reload: 0,
  254. movementSpeed: 0,
  255. };
  256. for (let i = 0; i < rawStats.length; ++i) {
  257. ++stats[statNumbers[rawStats[i]]];
  258. }
  259. return stats;
  260. }
  261.  
  262. let forcingU = false;
  263. function forceU() {
  264. if (canUpgrade()) {
  265. forcingU = true;
  266. window.extern.onKeyDown(21, 1);
  267. } else if (forcingU) {
  268. forcingU = false;
  269. window.extern.onKeyUp(21, 1);
  270. }
  271. }
  272. function getTankBulletSpeedOffset(tank) {
  273. return bulletSpeedOffsets[tank] || 1;
  274. }
  275. function calculateMainBulletSpeed() {
  276. const speedstat = getStats().bulletSpeed;
  277. return (
  278. (20 + speedstat * 3 * getTankBulletSpeedOffset(playerTank)) * 0.03
  279. );
  280. }
  281. function getDistance(x1, y1, x2, y2) {
  282. const distX = x1 - x2;
  283. const distY = y1 - y2;
  284. return Math.hypot(distX, distY);
  285. }
  286.  
  287. function calculateTime(player) {
  288. const distance = getDistance(playerX, playerY, player.wx, player.wy);
  289. const bulletSpeed = calculateMainBulletSpeed();
  290. const playerVel = getDistVel(player);
  291. const relativeBulletToTargetVel = bulletSpeed - playerVel;
  292. return distance / relativeBulletToTargetVel;
  293. }
  294.  
  295. function predictPlayer(player, time) {
  296. const [velX, velY] =
  297. typeof player.velocity === "undefined"
  298. ? [0, 0]
  299. : [(player.velocity[0] || 0), (player.velocity[1] || 0)];
  300. return [player.wx + time * velX, player.wy + time * velY];
  301. }
  302.  
  303. function getDistVel(player) {
  304. let dd = 0;
  305. let dataPoints = 0;
  306. for (let i = 1; i < player.positionTable.length; ++i) {
  307. if (!player.positionTable[i] || !player.positionTable[i - 1]) continue;
  308. const d =
  309. getDistance(
  310. playerX,
  311. playerY,
  312. player.positionTable[i].x,
  313. player.positionTable[i].y
  314. ) -
  315. getDistance(
  316. playerX,
  317. playerY,
  318. player.positionTable[i - 1].x,
  319. player.positionTable[i - 1].y
  320. );
  321. const dt =
  322. player.positionTable[i].timestamp - player.positionTable[i - 1].timestamp;
  323. dd += d / dt;
  324. dataPoints++;
  325. }
  326. return dataPoints > 0 ? dd / dataPoints : 0;
  327. }
  328.  
  329. function getPlayerWeight(player) {
  330. const distanceWeight =
  331. (1 / getDistance(playerX, playerY, player.wx, player.wy)) * 1000;
  332. const scoreWeight = Math.min(23536, Math.max(0, player.score || 0)) / 100000;
  333. return distanceWeight + scoreWeight;
  334. }
  335.  
  336. function setPlayerPos() {
  337. const dx = arrowPos[0] - minimapPos[0];
  338. const dy = arrowPos[1] - minimapPos[1];
  339. playerX = (dx / minimapSize[0]) * arenaSize;
  340. playerY = (dy / minimapSize[1]) * arenaSize;
  341. }
  342.  
  343. function getRenderedWorldPosition(x, y) {
  344. const mainCanvas = document.getElementById("canvas");
  345. const midX = x - mainCanvas.width / 2;
  346. const midY = y - mainCanvas.height / 2;
  347. const scaledX = midX / (fov / 2.8);
  348. const scaledY = midY / (fov / 2.8);
  349. return [playerX + scaledX, playerY + scaledY];
  350. }
  351.  
  352. function worldToCanvasPosition(x, y) {
  353. const mainCanvas = document.getElementById("canvas");
  354. const deltaX = x - playerX;
  355. const deltaY = y - playerY;
  356. return [
  357. mainCanvas.width / 2 + deltaX * (fov / 2.8),
  358. mainCanvas.height / 2 + deltaY * (fov / 2.8),
  359. ];
  360. }
  361.  
  362. function worldToMousePosition(x, y) {
  363. const deltaX = x - playerX;
  364. const deltaY = y - playerY;
  365. return [
  366. window.innerWidth / 2 + deltaX * (fov / 2.8),
  367. window.innerHeight / 2 + deltaY * (fov / 2.8),
  368. ];
  369. }
  370.  
  371. function parseDiepScore(s) {
  372. let scoreMultiplier = 1;
  373. if (s[s.length - 1] === "k") scoreMultiplier = 1000;
  374. else if (s[s.length - 1] === "m") scoreMultiplier = 1000000;
  375. else if (!s.includes(".")) {
  376. if (isNaN(s)) return null;
  377. const toInt = parseInt(s, 10);
  378. return isNaN(toInt) ? null : toInt;
  379. } else return null;
  380. const toFloat = parseFloat(s.slice(0, -1));
  381. if (isNaN(toFloat)) return null;
  382. return toFloat * scoreMultiplier;
  383. }
  384.  
  385. function getClosestText(arr, x, y) {
  386. return arr.reduce(function (acc, cur) {
  387. if (!acc) return cur;
  388. const distAcc = getDistance(x, y, acc.mx, acc.my);
  389. const distCur = getDistance(x, y, cur.mx, cur.my);
  390. return distAcc > distCur ? cur : acc;
  391. }, null);
  392. }
  393.  
  394. function getPlayers() {
  395. lastPlayers = players;
  396. players = [];
  397. for (let aIndex = 0; aIndex < tankShapes.length; ++aIndex) {
  398. if (tankShapes[aIndex].radius / fov < 19) continue;
  399. const scoreTextPos = [
  400. tankShapes[aIndex].x,
  401. tankShapes[aIndex].y - tankShapes[aIndex].radius * 1.3,
  402. ];
  403. const nameTextPos = [
  404. tankShapes[aIndex].x,
  405. tankShapes[aIndex].y - tankShapes[aIndex].radius * 2,
  406. ];
  407. const closestScoreText = getClosestText(text, ...scoreTextPos);
  408. const closestNameText = getClosestText(text, ...nameTextPos);
  409. const distToScore = closestScoreText
  410. ? getDistance(
  411. ...scoreTextPos,
  412. closestScoreText.mx,
  413. closestScoreText.my
  414. )
  415. : Infinity;
  416. const distToName = closestNameText
  417. ? getDistance(...nameTextPos, closestNameText.mx, closestNameText.my)
  418. : Infinity;
  419.  
  420. let score = "";
  421. let name = "";
  422. if (distToScore < 25) {
  423. score = parseDiepScore(closestScoreText ? closestScoreText.text : "-1");
  424. }
  425. if (distToName < 25) {
  426. name = closestNameText ? closestNameText.text : "";
  427. }
  428. if (score !== "") {
  429. const [wx, wy] = getRenderedWorldPosition(
  430. tankShapes[aIndex].x,
  431. tankShapes[aIndex].y
  432. );
  433. players.push({
  434. wx,
  435. wy,
  436. x: tankShapes[aIndex].x,
  437. y: tankShapes[aIndex].y,
  438. radius: tankShapes[aIndex].radius,
  439. name,
  440. score,
  441. velocity: undefined,
  442. teammate: tankShapes[aIndex].fillStyle === gameStyle[teamColor],
  443. });
  444. }
  445. }
  446. }
  447.  
  448. function matchPlayers() {
  449. for (let i = 0; i < players.length; ++i) {
  450. const [x, y] = [players[i].wx, players[i].wy];
  451. const lastPlayer = lastPlayers.reduce((acc, cur) => {
  452. if (!acc) return cur;
  453. const distAcc = getDistance(x, y, acc.wx, acc.wy);
  454. const distCur = getDistance(x, y, cur.wx, cur.wy);
  455. return distAcc > distCur ? cur : acc;
  456. }, null);
  457. if (
  458. lastPlayer &&
  459. getDistance(
  460. players[i].wx,
  461. players[i].wy,
  462. lastPlayer.wx,
  463. lastPlayer.wy
  464. ) < 25
  465. ) {
  466. players[i].teammate = lastPlayer.teammate || players[i].teammate;
  467. players[i].positionTable = lastPlayer.positionTable.concat();
  468. players[i].positionTable.push({
  469. x: players[i].wx,
  470. y: players[i].wy,
  471. timestamp: performance.now(),
  472. });
  473. players[i].positionTable.shift();
  474. players[i].velocity = getVelocity(players[i]);
  475. } else {
  476. players[i].positionTable = Array.from(
  477. new Array(playerVelocityPredictionSampleSize),
  478. () => null
  479. );
  480. }
  481. }
  482. }
  483.  
  484. function getVelocity(player) {
  485. let tx = 0,
  486. ty = 0;
  487. let dataPoints = 0;
  488. for (let i = 1; i < player.positionTable.length; ++i) {
  489. if (!player.positionTable[i] || !player.positionTable[i - 1]) continue;
  490. const dx = player.positionTable[i].x - player.positionTable[i - 1].x;
  491. const dy = player.positionTable[i].y - player.positionTable[i - 1].y;
  492. const dt =
  493. player.positionTable[i].timestamp - player.positionTable[i - 1].timestamp;
  494. tx += dx / dt;
  495. ty += dy / dt;
  496. dataPoints++;
  497. }
  498. return dataPoints > 0 ? [tx / dataPoints, ty / dataPoints] : [0, 0];
  499. }
  500.  
  501. function renderOverlay(player, tx, ty, px, py) {
  502. if (!isDebug) return;
  503. const ctx = document.getElementById("canvas").getContext("2d");
  504. const [stx, sty] = worldToCanvasPosition(tx, ty);
  505. const [spx, spy] = worldToCanvasPosition(px, py);
  506. ctx.beginPath();
  507. ctx.arc(stx, sty, 25, Math.PI * 2, 0, 1);
  508. ctx.globalAlpha = 0.35;
  509. ctx.fillStyle = "#ff5294";
  510. ctx.fill();
  511. ctx.beginPath();
  512. ctx.arc(spx, spy, 25, Math.PI * 2, 0, 1);
  513. ctx.fillStyle = "#52e8ff";
  514. ctx.fill();
  515. ctx.globalAlpha = 1;
  516. ctx.beginPath();
  517. ctx.moveTo(stx, sty);
  518. ctx.lineTo(spx, spy);
  519. ctx.strokeStyle = "#000000";
  520. ctx.lineWidth = 1;
  521. ctx.stroke();
  522. }
  523.  
  524. function aim() {
  525. const target = players
  526. .filter(plr => !plr.teammate)
  527. .reduce((acc, cur) => {
  528. if (!acc) return cur;
  529. return getPlayerWeight(cur) > getPlayerWeight(acc) ? cur : acc;
  530. }, null);
  531. const enemyMightDodge =
  532. destroyerAccuracy &&
  533. !!target &&
  534. ["Destroyer", "Hybrid", "Annihilator"].includes(playerTank) &&
  535. calculateTime(target) >= averageEnemyDodgeTime;
  536.  
  537. if (!target || enemyMightDodge || !isAimbotActive || mousePressed) {
  538. if (mouseLocked) {
  539. mouseLocked = false;
  540. window.extern.onTouchMove(-1, mouseX, mouseY, true);
  541. setTimeout(() => {
  542. window.extern.onKeyUp(36);
  543. }, 80);
  544. }
  545. return;
  546. }
  547. if (!mouseLocked) {
  548. mouseLocked = true;
  549. setTimeout(() => {
  550. isFiring = true;
  551. window.extern.onKeyDown(36);
  552. }, 80);
  553. }
  554.  
  555. const [sPX, sPY] = worldToMousePosition(target.wx, target.wy);
  556.  
  557. if (sPX != null && sPY != null) {
  558. if (typeof window.extern.onTouchMove === "function") {
  559. window.extern.onTouchMove(-1, sPX, sPY, true);
  560. } else if (typeof window.extern.onMouseMove === "function") {
  561. window.extern.onMouseMove(sPX, sPY);
  562. } else {
  563. window.extern.onTouchMove(-1, sPX, sPY, true);
  564. }
  565.  
  566. setTimeout(() => {
  567. isFiring = true;
  568. window.extern.onKeyDown(36);
  569. setTimeout(() => {
  570. window.extern.onKeyUp(36);
  571. }, 50);
  572. }, 10);
  573. }
  574. renderOverlay(target, target.wx, target.wy, target.wx, target.wy);
  575. }
  576.  
  577. function stack() {
  578. if (!(window && window.extern)) return;
  579. const reload = getStats().reload;
  580. window.extern.onKeyUp(36); // release fire
  581.  
  582. if (playerTank === "Hunter") {
  583. shoot(hunterStackTime[reload][0]);
  584. setTimeout(() => {
  585. window.extern.onKeyDown(5);
  586. window.extern.onKeyUp(5);
  587. }, hunterStackTime[reload][1]);
  588. } else if (playerTank === "Predator") {
  589. shoot(predatorStackTime[reload][0]);
  590. setTimeout(() => {
  591. shoot(predatorStackTime[reload][1]);
  592. }, predatorStackTime[reload][2]);
  593. setTimeout(() => {
  594. window.extern.onKeyDown(5);
  595. window.extern.onKeyUp(5);
  596. }, predatorStackTime[reload][3]);
  597. }
  598. }
  599. function shoot(t) {
  600. isFiring = true;
  601. window.extern.onKeyDown(36);
  602. setTimeout(() => {
  603. window.extern.onKeyUp(36);
  604. }, t);
  605. }
  606.  
  607. document.addEventListener("mousedown", function (ev) {
  608. mousePressed = true;
  609. if (ev.button === 0) {
  610. if (mouseLocked) {
  611. isFiring = true;
  612. window.extern.onKeyDown(36);
  613. setTimeout(() => {
  614. window.extern.onKeyDown(36);
  615. }, 10);
  616. }
  617. }
  618. });
  619. document.addEventListener("mouseup", function (ev) {
  620. mousePressed = false;
  621. if (ev.button === 0) {
  622. window.extern.onKeyUp(36);
  623. }
  624. });
  625. document.addEventListener("touchstart", function (ev) {
  626. isShooting = true;
  627. });
  628. document.addEventListener("touchend", function (ev) {
  629. isShooting = false;
  630. });
  631. document.addEventListener(
  632. "mousemove",
  633. function (ev) {
  634. if (isSpinning) {
  635. ev.stopImmediatePropagation();
  636. ev.preventDefault();
  637. }
  638. },
  639. true
  640. );
  641. document.addEventListener(
  642. "touchmove",
  643. function (ev) {
  644. if (isSpinning) {
  645. ev.stopImmediatePropagation();
  646. ev.preventDefault();
  647. }
  648. },
  649. true
  650. );
  651. // yes
  652. const KeyToToggleAimbot = "KeyU";
  653. const KeyToStack = "KeyI";
  654. const KeyToToggleMenu = "KeyM";
  655.  
  656. document.addEventListener("keydown", function (ev) {
  657. if (ev.code === KeyToToggleAimbot) {
  658. isAimbotActive ^= 1;
  659. if (window.__common__ && window.__common__.active_gamemode === "sandbox") {
  660. window.extern &&
  661. window.extern.inGameNotification(
  662. "Aimbot Doesn't Work in Sandbox",
  663. 0xF533FF
  664. );
  665. isAimbotActive = 0;
  666. } else {
  667. window.extern &&
  668. window.extern.inGameNotification(
  669. isAimbotActive ? "Aimbot: ON" : "Aimbot: OFF",
  670. 0xF533FF
  671. );
  672. }
  673. const aimbotCheckbox = document.getElementById("aimbot-checkbox");
  674. if (aimbotCheckbox) aimbotCheckbox.checked = Boolean(isAimbotActive);
  675. }
  676. else if (ev.code === KeyToStack) {
  677. if (["Hunter", "Predator"].includes(playerTank)) {
  678. stack();
  679. window.extern &&
  680. window.extern.inGameNotification("Stacking Bullets...", 0xF533FF);
  681. }
  682. }
  683. else if (ev.code === KeyToToggleMenu) {
  684. if (!menuContainer) return;
  685. const isHidden = menuContainer.style.display === "none";
  686. menuContainer.style.display = isHidden ? "block" : "none";
  687. }
  688. });
  689. // why am I even doing this?
  690. let ctxTransform;
  691. a._("setTransform", (context, ...args) => {
  692. ctxTransform = args;
  693. return [context, args];
  694. });
  695.  
  696. a._("drawImage", (context, ...args) => {
  697. if (args[0].renderMethod) {
  698. const x = ctxTransform[4] + args[1];
  699. const y = ctxTransform[5] + args[2];
  700. if (args[0].renderMethod.method === "text") {
  701. text.push({
  702. x,
  703. y,
  704. cw: args[0].width,
  705. ch: args[0].height,
  706. mx: x + args[0].width / 4,
  707. my: y + args[0].height / 4,
  708. text: args[0].renderMethod.text,
  709. });
  710. }
  711. }
  712. return [context, args];
  713. });
  714.  
  715. a._("strokeText", (context, ...args) => {
  716. if (context.canvas.id !== "canvas") {
  717. context.canvas.renderMethod = {
  718. method: "text",
  719. text: args[0],
  720. args,
  721. fillStyle: context.fillStyle,
  722. };
  723. if (args[0].startsWith("Lvl ")) {
  724. if (args[0][5] === " ") {
  725. playerLevel = Number(args[0].slice(4, 5));
  726. playerTank = args[0].slice(6);
  727. } else {
  728. playerLevel = Number(args[0].slice(4, 6));
  729. playerTank = args[0].slice(7);
  730. }
  731. }
  732. }
  733. return [context, args];
  734. });
  735. a._("arc", (context, ...args) => {
  736. if (
  737. context.canvas.id === "canvas" &&
  738. ctxTransform[4] === lastArc[0] &&
  739. ctxTransform[5] === lastArc[1]
  740. ) {
  741. tankShapes.push({
  742. x: ctxTransform[4],
  743. y: ctxTransform[5],
  744. radius: Math.hypot(ctxTransform[1], ctxTransform[0]),
  745. fillStyle: context.fillStyle,
  746. });
  747. lastArc = [Infinity, Infinity];
  748. } else {
  749. lastArc = [ctxTransform[4], ctxTransform[5]];
  750. }
  751. return [context, args];
  752. });
  753. // maybe my sister looks hot
  754. a._("stroke", (context, ...args) => {
  755. if (
  756. ["#cccccc", "#cdcdcd"].includes(context.fillStyle) &&
  757. context.strokeStyle === "#000000"
  758. ) {
  759. fov = context.globalAlpha / gameStyle.ren_grid_base_alpha;
  760. }
  761. return [context, args];
  762. });
  763.  
  764. a._("strokeRect", (context, ...args) => {
  765. const t = context.getTransform();
  766. minimapPos = [t.e, t.f];
  767. minimapSize = [t.a, t.d];
  768. return [context, args];
  769. });
  770.  
  771. // yes i will kill myself one day
  772. let position = 0;
  773. let vertex = [];
  774.  
  775. a._("beginPath", (context, ...args) => {
  776. position = 0;
  777. vertex = [];
  778. return [context, args];
  779. });
  780. a._("moveTo", (context, ...args) => {
  781. position = 1;
  782. vertex.push(args);
  783. return [context, args];
  784. });
  785. a._("lineTo", (context, ...args) => {
  786. position++;
  787. vertex.push(args);
  788. return [context, args];
  789. });
  790. a._("fill", (context, ...args) => {
  791. if (
  792. context.fillStyle === "#000000" &&
  793. context.globalAlpha > 0.949 &&
  794. position === 3
  795. ) {
  796. arrowPos = getAverage(vertex);
  797. setPlayerPos();
  798. }
  799. else if (
  800. position === 4 &&
  801. context.fillStyle &&
  802. context.fillStyle.toLowerCase().includes("ffe869")
  803. ) {
  804. const [rawX, rawY] = getAverage(vertex);
  805. const centerX = ctxTransform[4] + rawX;
  806. const centerY = ctxTransform[5] + rawY;
  807. neutralSquares.push([centerX, centerY]);
  808. }
  809. else if (
  810. position === 5 &&
  811. context.fillStyle &&
  812. context.fillStyle.toLowerCase().includes("768dfc")
  813. ) {
  814. const [rawX, rawY] = getAverage(vertex);
  815. const centerX = ctxTransform[4] + rawX;
  816. const centerY = ctxTransform[5] + rawY;
  817. neutralPentagons.push([centerX, centerY]);
  818. }
  819.  
  820. else if (
  821. position === 3 &&
  822. context.fillStyle &&
  823. context.fillStyle.toLowerCase().includes("fc7677")
  824. ) {
  825. const [rawX, rawY] = getAverage(vertex);
  826. const centerX = ctxTransform[4] + rawX;
  827. const centerY = ctxTransform[5] + rawY;
  828. neutralTriangles.push([centerX, centerY]);
  829. }
  830.  
  831. return [context, args];
  832. });
  833.  
  834. function getAverage(points) {
  835. let tx = 0,
  836. ty = 0;
  837. points.forEach((point) => {
  838. tx += point[0];
  839. ty += point[1];
  840. });
  841. return [tx / points.length, ty / points.length];
  842. }
  843.  
  844. // i hate niggers btw
  845. function onFrame() {
  846. window.requestAnimationFrame(onFrame);
  847.  
  848. getPlayers();
  849. matchPlayers();
  850.  
  851. if (isDebug) {
  852. const ctx = document.getElementById("canvas").getContext("2d");
  853. ctx.save();
  854. ctx.strokeStyle = "#FF0000";
  855. ctx.lineWidth = 1;
  856. const centerX = ctx.canvas.width / 2;
  857. const centerY = ctx.canvas.height / 2;
  858. players.forEach((plr) => {
  859. if (!plr.teammate) {
  860. ctx.beginPath();
  861. ctx.moveTo(centerX, centerY);
  862. ctx.lineTo(plr.x, plr.y);
  863. ctx.stroke();
  864. }
  865. });
  866. ctx.restore();
  867. }
  868.  
  869. forceU();
  870. aim();
  871. text = [];
  872. tankShapes = [];
  873. getTeam();
  874.  
  875. if (isAutoFarm && window.extern && window.extern.doesHaveTank()) {
  876. if (isDebug) {
  877. const ctx = document.getElementById("canvas").getContext("2d");
  878. ctx.save();
  879. const centerX = ctx.canvas.width / 2;
  880. const centerY = ctx.canvas.height / 2;
  881.  
  882. ctx.strokeStyle = "#9600D6";
  883. ctx.lineWidth = 1;
  884. neutralPentagons.forEach(([cx, cy]) => {
  885. ctx.beginPath();
  886. ctx.moveTo(centerX, centerY);
  887. ctx.lineTo(cx, cy);
  888. ctx.stroke();
  889. });
  890.  
  891. ctx.strokeStyle = "#00FF00";
  892. ctx.lineWidth = 1;
  893. neutralSquares.forEach(([cx, cy]) => {
  894. ctx.beginPath();
  895. ctx.moveTo(centerX, centerY);
  896. ctx.lineTo(cx, cy);
  897. ctx.stroke();
  898. });
  899. ctx.strokeStyle = "#FF9900";
  900. ctx.lineWidth = 1;
  901. neutralTriangles.forEach(([cx, cy]) => {
  902. ctx.beginPath();
  903. ctx.moveTo(centerX, centerY);
  904. ctx.lineTo(cx, cy);
  905. ctx.stroke();
  906. });
  907.  
  908. ctx.restore();
  909. }
  910.  
  911. let targetWorld = null;
  912.  
  913. if (farmPriority === "pentagon" && neutralPentagons.length > 0) {
  914. targetWorld = nearestShapeWorld(neutralPentagons);
  915. } else if (farmPriority === "square" && neutralSquares.length > 0) {
  916. targetWorld = nearestShapeWorld(neutralSquares);
  917. } else if (farmPriority === "triangle" && neutralTriangles.length > 0) {
  918. targetWorld = nearestShapeWorld(neutralTriangles);
  919. }
  920. if (!targetWorld) {
  921. if (farmPriority !== "pentagon" && neutralPentagons.length > 0) {
  922. targetWorld = nearestShapeWorld(neutralPentagons);
  923. } else if (farmPriority !== "square" && neutralSquares.length > 0) {
  924. targetWorld = nearestShapeWorld(neutralSquares);
  925. } else if (farmPriority !== "triangle" && neutralTriangles.length > 0) {
  926. targetWorld = nearestShapeWorld(neutralTriangles);
  927. }
  928. }
  929. if (targetWorld) {
  930. const [sPX, sPY] = worldToMousePosition(targetWorld[0], targetWorld[1]);
  931. if (sPX != null && sPY != null) {
  932. isFiring = true;
  933. window.extern.onTouchMove(-1, sPX, sPY, true);
  934. window.extern.onKeyDown(36);
  935. setTimeout(() => {
  936. window.extern.onKeyUp(36);
  937. }, 50);
  938. }
  939. }
  940. }
  941. neutralSquares = [];
  942. neutralPentagons = [];
  943. neutralTriangles = [];
  944. if (
  945. isSpinning &&
  946. !isShooting &&
  947. !isFiring &&
  948. window.extern &&
  949. window.extern.doesHaveTank()
  950. ) {
  951. spinAngle += spinSpeed;
  952. const cx = window.innerWidth / 2;
  953. const cy = window.innerHeight / 2;
  954. const radius = 120;
  955. const targetX = cx + radius * Math.cos(spinAngle);
  956. const targetY = cy + radius * Math.sin(spinAngle);
  957. if (typeof window.extern.onTouchMove === "function") {
  958. window.extern.onTouchMove(-1, targetX, targetY, true);
  959. } else if (typeof window.extern.onMouseMove === "function") {
  960. window.extern.onMouseMove(targetX, targetY);
  961. }
  962. }
  963.  
  964. if (window.extern && window.extern.doesHaveTank() && !hasJoined) {
  965. hasJoined = true;
  966. window.extern.inGameNotification("Welcome to SkidWare. Press M for menu.", 0x6670ff);
  967. }
  968. }
  969.  
  970. function nearestShapeWorld(arr) {
  971. let nearest = null;
  972. let nearestDist = Infinity;
  973. for (const [cx, cy] of arr) {
  974. const [wx, wy] = getRenderedWorldPosition(cx, cy);
  975. const dist = getDistance(playerX, playerY, wx, wy);
  976. if (dist < nearestDist) {
  977. nearestDist = dist;
  978. nearest = [wx, wy];
  979. }
  980. }
  981. return nearest;
  982. }
  983.  
  984.  
  985. function onGameStart() {
  986. if (typeof extern === "undefined") return;
  987. clearInterval(checkGameStart);
  988. window.requestAnimationFrame(onFrame);
  989.  
  990. window.extern.onKeyDown = new Proxy(window.extern.onKeyDown, {
  991. apply: function (method, context, args) {
  992. if (args[0] === 36) {
  993. isFiring = true;
  994. }
  995. if (args[0] === 21 && !args[1]) return;
  996. return Reflect.apply(method, context, args);
  997. },
  998. });
  999. window.extern.onKeyUp = new Proxy(window.extern.onKeyUp, {
  1000. apply: function (method, context, args) {
  1001. if (args[0] === 36) {
  1002. isFiring = false;
  1003. }
  1004. if (args[0] === 21 && !args[1]) return;
  1005. return Reflect.apply(method, context, args);
  1006. },
  1007. });
  1008.  
  1009. const mouseHandler = {
  1010. apply: function (method, context, args) {
  1011. if (!args[3]) {
  1012. [mouseX, mouseY] = [args[1], args[2]];
  1013. if (mouseLocked) return;
  1014. }
  1015. return Reflect.apply(method, context, args);
  1016. },
  1017. };
  1018. window.extern.onTouchStart = new Proxy(window.extern.onTouchStart, mouseHandler);
  1019. window.extern.onTouchMove = new Proxy(window.extern.onTouchMove, mouseHandler);
  1020. window.extern.onTouchEnd = new Proxy(window.extern.onTouchEnd, mouseHandler);
  1021.  
  1022. window.extern.set_convar = new Proxy(window.extern.set_convar, {
  1023. apply: function (method, context, args) {
  1024. gameStyle[args[0]] = args[1];
  1025. return Reflect.apply(method, context, args);
  1026. },
  1027. });
  1028.  
  1029. window.extern.execute = new Proxy(window.extern.execute, {
  1030. apply: function (method, context, args) {
  1031. if (args[0].startsWith("net_replace_color 3 ")) {
  1032. gameStyle.teamBlue =
  1033. args[0][20] === "0" ? "#" + args[0].slice(22) : args[0].slice(20);
  1034. }
  1035. if (args[0].startsWith("net_replace_color 4 ")) {
  1036. gameStyle.teamRed =
  1037. args[0][20] === "0" ? "#" + args[0].slice(22) : args[0].slice(20);
  1038. }
  1039. if (args[0].startsWith("net_replace_color 5 ")) {
  1040. gameStyle.teamPurple =
  1041. args[0][20] === "0" ? "#" + args[0].slice(22) : args[0].slice(20);
  1042. }
  1043. if (args[0].startsWith("net_replace_color 6 ")) {
  1044. gameStyle.teamGreen =
  1045. args[0][20] === "0" ? "#" + args[0].slice(22) : args[0].slice(20);
  1046. }
  1047. if (args[0].startsWith("net_replace_color 8 ")) {
  1048. gameStyle.square =
  1049. args[0][20] === "0" ? "#" + args[0].slice(22) : args[0].slice(20);
  1050. }
  1051. if (args[0].startsWith("net_replace_color 9 ")) {
  1052. gameStyle.triangle =
  1053. args[0][20] === "0" ? "#" + args[0].slice(22) : args[0].slice(20);
  1054. }
  1055. if (args[0].startsWith("net_replace_color 10 ")) {
  1056. gameStyle.pentagon =
  1057. args[0][21] === "0" ? "#" + args[0].slice(23) : args[0].slice(21);
  1058. }
  1059. return Reflect.apply(method, context, args);
  1060. },
  1061. });
  1062. }
  1063.  
  1064. const checkGameStart = setInterval(onGameStart, 400);
  1065.  
  1066. function getTeam() {
  1067. const partyLinkButton = document.getElementById("copy-party-link");
  1068. if (!partyLinkButton) return;
  1069. switch (partyLinkButton.className) {
  1070. case "active blue":
  1071. teamColor = "teamBlue";
  1072. break;
  1073. case "active purple":
  1074. teamColor = "teamPurple";
  1075. break;
  1076. case "active green":
  1077. teamColor = "teamGreen";
  1078. break;
  1079. case "active red":
  1080. teamColor = "teamRed";
  1081. break;
  1082. }
  1083. }
  1084.  
  1085. let menuContainer = null;
  1086. let isBlackBg = false;
  1087. let blackBgDiv = null;
  1088.  
  1089. // menu full chatgpt
  1090. function createUnifiedMenu() {
  1091. const styleEl = document.createElement("style");
  1092. styleEl.textContent = `
  1093. /* ===================== skeet.cc-Style Menu (30% Bigger & Draggable) ===================== */
  1094.  
  1095. @font-face {
  1096. font-family: 'SkeetFont';
  1097. src: local('Segoe UI'), local('Arial'), sans-serif;
  1098. /* Fallback: system sans-serif if Segoe UI not present */
  1099. }
  1100.  
  1101. /* ── Main Menu Container ───────────────────────────────────────────────────── */
  1102. .skeet-menu {
  1103. position: fixed;
  1104. /* Initial position at 50px, 50px; will be overridden during dragging */
  1105. top: 50px;
  1106. left: 50px;
  1107. width: 494px; /* 380px * 1.3 */
  1108. background-color: #1b1b1b;
  1109. border: 1px solid #2f2f2f;
  1110. border-radius: 6px;
  1111. box-shadow: 0 0 12px rgba(0, 0, 0, 0.7);
  1112. font-family: 'SkeetFont', sans-serif;
  1113. color: #e0e0e0;
  1114. font-size: 17px; /* 13px * 1.3 */
  1115. user-select: none;
  1116. display: none; /* hidden by default; toggled with “M” */
  1117. pointer-events: auto;
  1118. z-index: 9999;
  1119. }
  1120.  
  1121. /* ── Drag Handle (26px high) ─────────────────────────────────────────────────── */
  1122. .skeet-drag-handle {
  1123. height: 26px; /* 20px * 1.3 */
  1124. background-color: #2f2f2f;
  1125. border-bottom: 1px solid #2f2f2f;
  1126. cursor: move;
  1127. text-align: center;
  1128. line-height: 26px; /* same as height, to center text vertically */
  1129. font-size: 17px; /* 13px * 1.3 */
  1130. font-weight: 500;
  1131. color: #e0e0e0;
  1132. user-select: none;
  1133. }
  1134.  
  1135. /* ── Sidebar (104px-wide Text Tabs) ────────────────────────────────────────── */
  1136. .skeet-sidebar {
  1137. float: left;
  1138. width: 104px; /* 80px * 1.3 */
  1139. background-color: #171717;
  1140. border-right: 1px solid #2f2f2f;
  1141. display: flex;
  1142. flex-direction: column;
  1143. align-items: center;
  1144. padding-top: 16px; /* 12px * 1.3 */
  1145. }
  1146.  
  1147. .skeet-sidebar button {
  1148. width: 83px; /* 64px * 1.3 ≈ 83 */
  1149. height: 42px; /* 32px * 1.3 ≈ 42 */
  1150. margin: 8px 0; /* 6px * 1.3 ≈ 8 */
  1151. background-color: transparent;
  1152. border: none;
  1153. outline: none;
  1154. cursor: pointer;
  1155. transition: background-color 0.15s ease, color 0.15s ease;
  1156. color: #888888;
  1157. font-size: 17px; /* 13px * 1.3 ≈ 17 */
  1158. font-weight: 500;
  1159. }
  1160.  
  1161. .skeet-sidebar button:hover,
  1162. .skeet-sidebar button.active {
  1163. background-color: #2f2f2f;
  1164. color: #00b4ff;
  1165. border-radius: 4px;
  1166. }
  1167.  
  1168. /* ── Content Area (Remaining ≈390px) ────────────────────────────────────────── */
  1169. .skeet-content {
  1170. margin-left: 104px; /* leave room for sidebar */
  1171. padding: 21px; /* 16px * 1.3 ≈ 21 */
  1172. box-sizing: border-box;
  1173. }
  1174.  
  1175. /* Hide all sections by default; only the “.active” one displays */
  1176. .skeet-section {
  1177. display: none;
  1178. }
  1179. .skeet-section.active {
  1180. display: block;
  1181. }
  1182.  
  1183. .skeet-content .section-title {
  1184. font-size: 21px; /* 16px * 1.3 ≈ 21 */
  1185. font-weight: 600;
  1186. color: #ffffff;
  1187. margin-bottom: 13px; /* 10px * 1.3 ≈ 13 */
  1188. }
  1189.  
  1190. /* ── Section Header ───────────────────────────────────────────────────────── */
  1191. .skeet-section .header {
  1192. font-size: 18px; /* 14px * 1.3 ≈ 18 */
  1193. font-weight: 500;
  1194. margin-bottom: 10px; /* 8px * 1.3 ≈ 10 */
  1195. color: #e0e0e0;
  1196. }
  1197.  
  1198. /* ── Toggle Labels (Checkbox + Text) ───────────────────────────────────────── */
  1199. .skeet-toggle-label {
  1200. display: flex;
  1201. align-items: center;
  1202. margin-bottom: 10px; /* 8px * 1.3 ≈ 10 */
  1203. cursor: pointer;
  1204. }
  1205. .skeet-toggle-label input[type="checkbox"] {
  1206. width: 18px; /* 14px * 1.3 ≈ 18 */
  1207. height: 18px; /* 14px * 1.3 ≈ 18 */
  1208. margin-right: 10px; /* 8px * 1.3 ≈ 10 */
  1209. accent-color: #00b4ff;
  1210. cursor: pointer;
  1211. outline: none;
  1212. }
  1213. .skeet-toggle-label span {
  1214. font-size: 17px; /* 13px * 1.3 ≈ 17 */
  1215. color: #e0e0e0;
  1216. }
  1217.  
  1218. /* ── Slider (Range Input) ─────────────────────────────────────────────────── */
  1219. .skeet-slider-container {
  1220. display: flex;
  1221. align-items: center;
  1222. margin-bottom: 15px; /* 12px * 1.3 ≈ 15 */
  1223. }
  1224. .skeet-slider-container span {
  1225. margin-right: 10px; /* 8px * 1.3 ≈ 10 */
  1226. font-size: 16px; /* 12px * 1.3 ≈ 16 */
  1227. color: #cccccc;
  1228. min-width: 91px; /* 70px * 1.3 ≈ 91 */
  1229. }
  1230. .skeet-slider {
  1231. flex: 1;
  1232. -webkit-appearance: none;
  1233. width: 100%;
  1234. height: 5px; /* 4px * 1.3 ≈ 5 */
  1235. background: #2f2f2f;
  1236. border-radius: 3px;
  1237. cursor: pointer;
  1238. outline: none;
  1239. }
  1240. .skeet-slider::-webkit-slider-thumb {
  1241. -webkit-appearance: none;
  1242. width: 16px; /* 12px * 1.3 ≈ 16 */
  1243. height: 16px; /* 12px * 1.3 ≈ 16 */
  1244. border-radius: 50%;
  1245. background: #00b4ff;
  1246. border: 1px solid #1b1b1b;
  1247. cursor: pointer;
  1248. margin-top: -5px; /* center thumb (≈ half the thumb height) */
  1249. }
  1250. .skeet-slider::-moz-range-thumb {
  1251. width: 16px;
  1252. height: 16px;
  1253. border-radius: 50%;
  1254. background: #00b4ff;
  1255. border: 1px solid #1b1b1b;
  1256. cursor: pointer;
  1257. }
  1258.  
  1259. /* ── Buttons (Load/Save/Stack etc.) ───────────────────────────────────────── */
  1260. .skeet-button {
  1261. display: inline-block;
  1262. background-color: #2f2f2f;
  1263. color: #e0e0e0;
  1264. font-size: 15px; /* 12px * 1.3 ≈ 15 */
  1265. padding: 8px 16px; /* 6px*1.3≈8 & 12px*1.3≈16 */
  1266. margin-top: 8px; /* 6px * 1.3 ≈ 8 */
  1267. border: 1px solid #3f3f3f;
  1268. border-radius: 4px;
  1269. cursor: pointer;
  1270. transition: background-color 0.15s ease, border-color 0.15s ease;
  1271. }
  1272. .skeet-button:hover {
  1273. background-color: #3f3f3f;
  1274. border-color: #5f5f5f;
  1275. }
  1276. .skeet-button:active {
  1277. background-color: #5f5f5f;
  1278. border-color: #7f7f7f;
  1279. }
  1280.  
  1281. /* ── Radio Buttons for Farming Priority ───────────────────────────────────── */
  1282. .skeet-radio-group {
  1283. margin-bottom: 10px; /* some spacing */
  1284. }
  1285. .skeet-radio-label {
  1286. display: flex;
  1287. align-items: center;
  1288. margin-right: 20px;
  1289. cursor: pointer;
  1290. font-size: 17px; /* 13px * 1.3 */
  1291. color: #e0e0e0;
  1292. }
  1293. .skeet-radio-label input[type="radio"] {
  1294. margin-right: 8px;
  1295. accent-color: #00b4ff;
  1296. cursor: pointer;
  1297. outline: none;
  1298. }
  1299.  
  1300. /* ── Focus Ring for Keyboard Navigation ──────────────────────────────────── */
  1301. .skeet-menu input:focus-visible,
  1302. .skeet-menu button:focus-visible {
  1303. outline: 2px solid #00b4ff;
  1304. outline-offset: 1px;
  1305. }
  1306. `;
  1307. document.head.appendChild(styleEl);
  1308.  
  1309. menuContainer = document.createElement("div");
  1310. menuContainer.classList.add("skeet-menu");
  1311.  
  1312. const dragHandle = document.createElement("div");
  1313. dragHandle.classList.add("skeet-drag-handle");
  1314. dragHandle.innerText = "Skid Ware";
  1315. menuContainer.appendChild(dragHandle);
  1316. const sidebar = document.createElement("div");
  1317. sidebar.classList.add("skeet-sidebar");
  1318.  
  1319. const tabs = [
  1320. { id: "tab-spin", label: "Spin" },
  1321. { id: "tab-aim", label: "Aim" },
  1322. { id: "tab-farm", label: "Farm" },
  1323. { id: "tab-visuals", label: "Visuals" },
  1324. ];
  1325.  
  1326. tabs.forEach((t, idx) => {
  1327. const btn = document.createElement("button");
  1328. btn.id = t.id + "-btn";
  1329. btn.innerText = t.label;
  1330. btn.title = t.label;
  1331. if (idx === 0) btn.classList.add("active");
  1332. btn.addEventListener("click", () => switchTab(t.id));
  1333. sidebar.appendChild(btn);
  1334. });
  1335. menuContainer.appendChild(sidebar);
  1336.  
  1337. const content = document.createElement("div");
  1338. content.classList.add("skeet-content");
  1339. const spinSection = document.createElement("div");
  1340. spinSection.id = "tab-spin";
  1341. spinSection.classList.add("skeet-section", "active");
  1342.  
  1343. const spinTitle = document.createElement("div");
  1344. spinTitle.classList.add("section-title");
  1345. spinTitle.innerText = "Spinner Settings:";
  1346. spinSection.appendChild(spinTitle);
  1347.  
  1348. const spinHeader = document.createElement("div");
  1349. spinHeader.classList.add("header");
  1350. spinHeader.innerText = "• Enable / Disable Spinner:";
  1351. spinSection.appendChild(spinHeader);
  1352.  
  1353. const spinToggleLabel = document.createElement("label");
  1354. spinToggleLabel.classList.add("skeet-toggle-label");
  1355. const spinCheckbox = document.createElement("input");
  1356. spinCheckbox.type = "checkbox";
  1357. spinCheckbox.id = "spinner-checkbox";
  1358. spinCheckbox.checked = isSpinning;
  1359. const spinLabelText = document.createElement("span");
  1360. spinLabelText.innerText = "Enable Spinner";
  1361. spinToggleLabel.appendChild(spinCheckbox);
  1362. spinToggleLabel.appendChild(spinLabelText);
  1363. spinSection.appendChild(spinToggleLabel);
  1364.  
  1365. spinCheckbox.addEventListener("change", function () {
  1366. isSpinning = this.checked;
  1367. if (window.extern) {
  1368. window.extern.inGameNotification(
  1369. isSpinning ? "Spinner: ON" : "Spinner: OFF",
  1370. 0xF533FF
  1371. );
  1372. }
  1373. });
  1374.  
  1375. const spinSpeedHeader = document.createElement("div");
  1376. spinSpeedHeader.classList.add("header");
  1377. spinSpeedHeader.innerText = "• Spin Speed:";
  1378. spinSection.appendChild(spinSpeedHeader);
  1379.  
  1380. const spinSpeedContainer = document.createElement("div");
  1381. spinSpeedContainer.classList.add("skeet-slider-container");
  1382. const speedLabelText = document.createElement("span");
  1383. speedLabelText.innerText = `Speed: ${spinSpeed.toFixed(2)}`;
  1384. const spinSlider = document.createElement("input");
  1385. spinSlider.type = "range";
  1386. spinSlider.min = "0";
  1387. spinSlider.max = "2";
  1388. spinSlider.step = "0.01";
  1389. spinSlider.value = spinSpeed.toString();
  1390. spinSlider.classList.add("skeet-slider");
  1391.  
  1392. spinSlider.addEventListener("input", (ev) => {
  1393. spinSpeed = parseFloat(ev.target.value);
  1394. speedLabelText.innerText = `Speed: ${spinSpeed.toFixed(2)}`;
  1395. });
  1396. ["mousedown", "mousemove", "mouseup", "touchstart", "touchmove", "touchend"].forEach((evt) => {
  1397. spinSlider.addEventListener(evt, (e) => e.stopPropagation(), { capture: true, passive: false });
  1398. });
  1399.  
  1400. spinSpeedContainer.appendChild(speedLabelText);
  1401. spinSpeedContainer.appendChild(spinSlider);
  1402. spinSection.appendChild(spinSpeedContainer);
  1403.  
  1404. content.appendChild(spinSection);
  1405.  
  1406. const aimSection = document.createElement("div");
  1407. aimSection.id = "tab-aim";
  1408. aimSection.classList.add("skeet-section");
  1409.  
  1410. const aimTitle = document.createElement("div");
  1411. aimTitle.classList.add("section-title");
  1412. aimTitle.innerText = "Aimbot Settings:";
  1413. aimSection.appendChild(aimTitle);
  1414.  
  1415. const aimHeader = document.createElement("div");
  1416. aimHeader.classList.add("header");
  1417. aimHeader.innerText = "• Enable / Disable Aimbot:";
  1418. aimSection.appendChild(aimHeader);
  1419.  
  1420. const aimToggleLabel = document.createElement("label");
  1421. aimToggleLabel.classList.add("skeet-toggle-label");
  1422. const aimCheckbox = document.createElement("input");
  1423. aimCheckbox.type = "checkbox";
  1424. aimCheckbox.id = "aimbot-checkbox";
  1425. aimCheckbox.checked = isAimbotActive;
  1426. const aimLabelText = document.createElement("span");
  1427. aimLabelText.innerText = "Enable Aimbot";
  1428. aimToggleLabel.appendChild(aimCheckbox);
  1429. aimToggleLabel.appendChild(aimLabelText);
  1430. aimSection.appendChild(aimToggleLabel);
  1431.  
  1432. aimCheckbox.addEventListener("change", function () {
  1433. isAimbotActive = this.checked;
  1434. if (window.extern) {
  1435. window.extern.inGameNotification(
  1436. isAimbotActive ? "Aimbot: ON" : "Aimbot: OFF",
  1437. 0xF533FF
  1438. );
  1439. }
  1440. });
  1441.  
  1442. const stackHeader = document.createElement("div");
  1443. stackHeader.classList.add("header");
  1444. stackHeader.innerText = "• Manual Stack (Hunter/Predator):";
  1445. aimSection.appendChild(stackHeader);
  1446.  
  1447. const stackButton = document.createElement("button");
  1448. stackButton.innerText = "Stack Bullets";
  1449. stackButton.classList.add("skeet-button");
  1450. stackButton.addEventListener("click", () => {
  1451. if (["Hunter", "Predator"].includes(playerTank)) {
  1452. stack();
  1453. window.extern &&
  1454. window.extern.inGameNotification("Stacking Bullets...", 0xF533FF);
  1455. } else {
  1456. window.extern &&
  1457. window.extern.inGameNotification("Not Hunter/Predator", 0xF533FF);
  1458. }
  1459. });
  1460. aimSection.appendChild(stackButton);
  1461.  
  1462. content.appendChild(aimSection);
  1463.  
  1464. const farmSection = document.createElement("div");
  1465. farmSection.id = "tab-farm";
  1466. farmSection.classList.add("skeet-section");
  1467.  
  1468. const farmTitle = document.createElement("div");
  1469. farmTitle.classList.add("section-title");
  1470. farmTitle.innerText = "AutoFarm:";
  1471. farmSection.appendChild(farmTitle);
  1472.  
  1473. const farmHeader = document.createElement("div");
  1474. farmHeader.classList.add("header");
  1475. farmHeader.innerText = "• Enable / Disable AutoFarm:";
  1476. farmSection.appendChild(farmHeader);
  1477.  
  1478. const farmToggleLabel = document.createElement("label");
  1479. farmToggleLabel.classList.add("skeet-toggle-label");
  1480. const farmCheckbox = document.createElement("input");
  1481. farmCheckbox.type = "checkbox";
  1482. farmCheckbox.id = "autofarm-checkbox";
  1483. farmCheckbox.checked = isAutoFarm;
  1484. const farmLabelText = document.createElement("span");
  1485. farmLabelText.innerText = "Enable AutoFarm";
  1486. farmToggleLabel.appendChild(farmCheckbox);
  1487. farmToggleLabel.appendChild(farmLabelText);
  1488. farmSection.appendChild(farmToggleLabel);
  1489.  
  1490. farmCheckbox.addEventListener("change", function () {
  1491. isAutoFarm = this.checked;
  1492. if (window.extern) {
  1493. window.extern.inGameNotification(
  1494. isAutoFarm ? "AutoFarm: ON" : "AutoFarm: OFF",
  1495. 0xF533FF
  1496. );
  1497. }
  1498. });
  1499.  
  1500. const priorityContainer = document.createElement("div");
  1501. priorityContainer.classList.add("skeet-radio-group");
  1502. const priorityLabel = document.createElement("div");
  1503. priorityLabel.classList.add("header");
  1504. priorityLabel.innerText = "• Farming Priority:";
  1505. farmSection.appendChild(priorityLabel);
  1506.  
  1507. const pentRadioLabel = document.createElement("label");
  1508. pentRadioLabel.classList.add("skeet-radio-label");
  1509. const pentRadio = document.createElement("input");
  1510. pentRadio.type = "radio";
  1511. pentRadio.name = "farm-priority";
  1512. pentRadio.id = "farm-priority-pentagon";
  1513. pentRadio.value = "pentagon";
  1514. pentRadio.checked = (farmPriority === "pentagon");
  1515. const pentLabelText = document.createElement("span");
  1516. pentLabelText.innerText = "Prioritize Pentagons";
  1517. pentRadioLabel.appendChild(pentRadio);
  1518. pentRadioLabel.appendChild(pentLabelText);
  1519. priorityContainer.appendChild(pentRadioLabel);
  1520.  
  1521. pentRadio.addEventListener("change", function () {
  1522. if (this.checked) {
  1523. farmPriority = "pentagon";
  1524. if (window.extern) {
  1525. window.extern.inGameNotification("FarmPriority: Pentagons", 0xF533FF);
  1526. }
  1527. }
  1528. });
  1529. const sqRadioLabel = document.createElement("label");
  1530. sqRadioLabel.classList.add("skeet-radio-label");
  1531. const sqRadio = document.createElement("input");
  1532. sqRadio.type = "radio";
  1533. sqRadio.name = "farm-priority";
  1534. sqRadio.id = "farm-priority-square";
  1535. sqRadio.value = "square";
  1536. sqRadio.checked = (farmPriority === "square");
  1537. const sqLabelText = document.createElement("span");
  1538. sqLabelText.innerText = "Prioritize Squares";
  1539. sqRadioLabel.appendChild(sqRadio);
  1540. sqRadioLabel.appendChild(sqLabelText);
  1541. priorityContainer.appendChild(sqRadioLabel);
  1542.  
  1543. sqRadio.addEventListener("change", function () {
  1544. if (this.checked) {
  1545. farmPriority = "square";
  1546. if (window.extern) {
  1547. window.extern.inGameNotification("FarmPriority: Squares", 0xF533FF);
  1548. }
  1549. }
  1550.  
  1551. });
  1552. const triRadioLabel = document.createElement("label");
  1553. triRadioLabel.classList.add("skeet-radio-label");
  1554. const triRadio = document.createElement("input");
  1555. triRadio.type = "radio";
  1556. triRadio.name = "farm-priority";
  1557. triRadio.id = "farm-priority-triangle";
  1558. triRadio.value = "triangle";
  1559. triRadio.checked = (farmPriority === "triangle");
  1560. const triLabelText = document.createElement("span");
  1561. triLabelText.innerText = "Prioritize Triangles";
  1562. triRadioLabel.appendChild(triRadio);
  1563. triRadioLabel.appendChild(triLabelText);
  1564. priorityContainer.appendChild(triRadioLabel);
  1565.  
  1566. triRadio.addEventListener("change", function () {
  1567. if (this.checked) {
  1568. farmPriority = "triangle";
  1569. if (window.extern) {
  1570. window.extern.inGameNotification("FarmPriority: Triangles", 0xF533FF);
  1571. }
  1572. }
  1573. });
  1574.  
  1575. farmSection.appendChild(priorityContainer);
  1576. content.appendChild(farmSection);
  1577. const visualsSection = document.createElement("div");
  1578. visualsSection.id = "tab-visuals";
  1579. visualsSection.classList.add("skeet-section");
  1580.  
  1581. const visualsTitle = document.createElement("div");
  1582. visualsTitle.classList.add("section-title");
  1583. visualsTitle.innerText = "Debug / Visuals:";
  1584. visualsSection.appendChild(visualsTitle);
  1585.  
  1586. const visualsHeader = document.createElement("div");
  1587. visualsHeader.classList.add("header");
  1588. visualsHeader.innerText = "• Enable / Disable Debug Lines:";
  1589. visualsSection.appendChild(visualsHeader);
  1590.  
  1591. const visualsToggleLabel = document.createElement("label");
  1592. visualsToggleLabel.classList.add("skeet-toggle-label");
  1593. const visualsCheckbox = document.createElement("input");
  1594. visualsCheckbox.type = "checkbox";
  1595. visualsCheckbox.id = "debug-checkbox";
  1596. visualsCheckbox.checked = isDebug;
  1597. const visualsLabelText = document.createElement("span");
  1598. visualsLabelText.innerText = "Enable Debug Lines";
  1599. visualsToggleLabel.appendChild(visualsCheckbox);
  1600. visualsToggleLabel.appendChild(visualsLabelText);
  1601. visualsSection.appendChild(visualsToggleLabel);
  1602.  
  1603. visualsCheckbox.addEventListener("change", function () {
  1604. isDebug = this.checked;
  1605. if (window.extern) {
  1606. window.extern.inGameNotification(
  1607. isDebug ? "Debug Lines: ON" : "Debug Lines: OFF",
  1608. 0xF533FF
  1609. );
  1610. }
  1611. });
  1612. const blackBgToggleLabel = document.createElement("label");
  1613. blackBgToggleLabel.classList.add("skeet-toggle-label");
  1614. const blackBgCheckbox = document.createElement("input");
  1615. blackBgCheckbox.type = "checkbox";
  1616. blackBgCheckbox.id = "blackbg-checkbox";
  1617. blackBgCheckbox.checked = isBlackBg;
  1618. const blackBgLabelText = document.createElement("span");
  1619. blackBgLabelText.innerText = "Black Background (buggy on aim)";
  1620. blackBgToggleLabel.appendChild(blackBgCheckbox);
  1621. blackBgToggleLabel.appendChild(blackBgLabelText);
  1622. visualsSection.appendChild(blackBgToggleLabel);
  1623.  
  1624. blackBgCheckbox.addEventListener("change", function () {
  1625. isBlackBg = this.checked;
  1626. if (window.input && typeof window.input.set_convar === "function") {
  1627. window.input.set_convar("ren_background_color",
  1628. isBlackBg ? "#000000" : "#CDCDCD");
  1629. }
  1630. if (window.extern) {
  1631. window.extern.inGameNotification(
  1632. isBlackBg ? "Black background: ON" : "Black background: OFF",
  1633. 0xF533FF
  1634. );
  1635. }
  1636. });
  1637. content.appendChild(visualsSection);
  1638. menuContainer.appendChild(content);
  1639. document.body.appendChild(menuContainer);
  1640. function switchTab(activeId) {
  1641. tabs.forEach((t) => {
  1642. const btn = document.getElementById(t.id + "-btn");
  1643. if (t.id === activeId) btn.classList.add("active");
  1644. else btn.classList.remove("active");
  1645. });
  1646. tabs.forEach((t) => {
  1647. const section = document.getElementById(t.id);
  1648. if (t.id === activeId) section.classList.add("active");
  1649. else section.classList.remove("active");
  1650. });
  1651. }
  1652. let isDragging = false;
  1653. let dragOffsetX = 0;
  1654. let dragOffsetY = 0;
  1655.  
  1656. dragHandle.addEventListener("mousedown", function (e) {
  1657. isDragging = true;
  1658. const rect = menuContainer.getBoundingClientRect();
  1659. dragOffsetX = e.clientX - rect.left;
  1660. dragOffsetY = e.clientY - rect.top;
  1661. document.addEventListener("mousemove", onMouseMove);
  1662. document.addEventListener("mouseup", onMouseUp);
  1663. e.preventDefault();
  1664. });
  1665.  
  1666. function onMouseMove(e) {
  1667. if (!isDragging) return;
  1668. const newLeft = e.clientX - dragOffsetX;
  1669. const newTop = e.clientY - dragOffsetY;
  1670. menuContainer.style.left = newLeft + "px";
  1671. menuContainer.style.top = newTop + "px";
  1672. }
  1673.  
  1674. function onMouseUp() {
  1675. isDragging = false;
  1676. document.removeEventListener("mousemove", onMouseMove);
  1677. document.removeEventListener("mouseup", onMouseUp);
  1678. }
  1679. }
  1680.  
  1681. // https://discord.gg/NBN3jgQDGe

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址