您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Spinner, Aimbot, AutoFarm
// ==UserScript== // @license MIT // @name SkidWare ModMenu - diep.io // @namespace bo$$ // @version v1.1.0 // @description Spinner, Aimbot, AutoFarm // @author Dreamy @C:Mi300(Aimbot+Fov) // @match https://diep.io/* // @match https://staging.diep.io/* // @match https://diep-io.rivet.game/* // @icon https://gamesense.pub/favicon.ico // @grant none // @run-at document-start // ==/UserScript== // mi300's discord - https://discord.gg/S4CA5w9p8p // my discord - https://discord.gg/NBN3jgQDGe const FOV_UPDATE_INTERVAL = 16.6; const FOV_LERP = 0.1; let setFov = 0.5; let foxv = 0.5; let keyStates = new Map(); const onWheelEvent = event => {setFov += -Math.sign(event.deltaY) * 0.02 * Math.log10(setFov / 0.55 + 1)} const onKeyDown = event => {keyStates.set(event.keyCode, 1)} const onKeyUp = event => {keyStates.set(event.keyCode, 0)} function updateFov(){ if(typeof window.extern === 'undefined')return; if(!window.extern.doesHaveTank())return; if(keyStates.get(187)) setFov += 0.01 * Math.log10(setFov / 0.55 + 1); if(keyStates.get(189)) setFov -= 0.01 * Math.log10(setFov / 0.55 + 1); foxv += (setFov - foxv) * FOV_LERP; window.extern.setScreensizeZoom(1, foxv); } function init(){ document.addEventListener("wheel", onWheelEvent); document.addEventListener("keydown", onKeyDown); document.addEventListener("keyup", onKeyUp); setInterval(updateFov, FOV_UPDATE_INTERVAL); } init(); let a; class _a { constructor() { this.p = {}; this.v = false; document.addEventListener("DOMContentLoaded", this.tu.bind(this)); } tu() { if (this.v) return; this.v = true; const originalGetElementById = HTMLDocument.prototype.getElementById; HTMLDocument.prototype.getElementById = function (id) { const elem = originalGetElementById.call(document, id); if (id === "canvas") return wrapCanvas(elem); return elem; }; const originalCreateElement = HTMLDocument.prototype.createElement; HTMLDocument.prototype.createElement = function (tag) { const elem = originalCreateElement.call(document, tag); if (tag === "canvas") return wrapCanvas(elem); return elem; }; function wrapCanvas(origCanvas) { class HTMLCanvasElementProxy {} let proxyCanvas = new HTMLCanvasElementProxy(); proxyCanvas.width = origCanvas.width; proxyCanvas.height = origCanvas.height; proxyCanvas.transferControlToOffscreen = origCanvas.transferControlToOffscreen.bind(origCanvas); proxyCanvas.toDataURL = origCanvas.toDataURL.bind(origCanvas); proxyCanvas.toBlob = origCanvas.toBlob.bind(origCanvas); proxyCanvas.captureStream = origCanvas.captureStream.bind(origCanvas); proxyCanvas.getContext = function (...args) { let ctx = origCanvas.getContext(...args); if (args[0] !== "2d") return ctx; return new Proxy(ctx, { get: function (target, prop) { const original = target[prop]; if (typeof original !== "function") return original; if (Object.keys(a.p).includes(prop)) { return function (...pArgs) { let skip = false; a.p[prop].forEach((hook) => { const result = hook(ctx, ...pArgs); if (!result) { skip = true; } else { [ctx, pArgs] = result; } }); if (skip) return; return original.apply(target, pArgs); }; } return original.bind(target); }, set: function (target, prop, value) { target[prop] = value; return true; }, }); }; return proxyCanvas; } createUnifiedMenu(); } _(methodName, hookFn) { if (Object.keys(a.p).includes(methodName)) { a.p[methodName].push(hookFn); } else { a.p[methodName] = [hookFn]; } } } a = new _a(); let spinSpeed = 0.80; let isSpinning = false; let spinAngle = 0; let isShooting = false; let isFiring = false; let isAimbotActive = false; let playerTank = "Tank"; let playerLevel = 1; let playerX = 0; let playerY = 0; let arrowPos = [0, 0]; let minimapPos = [0, 0]; let minimapSize = [0, 0]; let fov = 0.5; let text = []; let tankShapes = []; let lastPlayers = []; let players = []; let lastArc = [Infinity, Infinity]; let mousePressed = false; let mouseLocked = false; let mouseX = 0; let mouseY = 0; let isAutoFarm = false; let neutralSquares = []; let neutralPentagons = []; let neutralTriangles = []; let farmPriority = "pentagon"; let isDebug = false; let hasJoined = false; const averageEnemyDodgeTime = 1750; const destroyerAccuracy = true; const playerVelocityPredictionSampleSize = 50; const arenaSize = 26000; const gameStyle = { ren_grid_base_alpha: 0.05, square: "#ffe869", triangle: "#fc7677", pentagon: "#768dfc", teamBlue: "#00b2e1", teamRed: "#f14e54", teamPurple: "#bf7ff5", teamGreen: "#00e16e", }; let teamColor = ""; const bulletSpeedOffsets = { Skimmer: 0.5, Factory: 0.56, Annihilator: 0.7, Streamliner: 1.1, "Auto Gunner": 1.1, Gunner: 1.1, Predator: 1.4, Mothership: 0.48, Manager: 0.8, Hybrid: 0.7, Ranger: 1.5, Stalker: 1.5, Assassin: 1.5, Sniper: 1.5, Hunter: 1.4, Necromancer: 0.72, "Arena Closer": 2, Overlord: 0.8, Overseer: 0.8, Destroyer: 0.7, }; const predatorStackTime = [ [50, 500, 1400, 2800], [50, 500, 1300, 2700], [50, 400, 1200, 2450], [50, 300, 1100, 2200], [50, 300, 1000, 2100], [50, 300, 900, 1800], [50, 300, 800, 1700], [50, 300, 750, 1500], ]; const hunterStackTime = [ [50, 1200], [50, 1100], [50, 1000], [50, 950], [50, 800], [50, 725], [50, 700], [50, 625], ]; const buildStatLevels = [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 30, 33, 36, 39, 42, 45, ]; const statNumbers = { 1: "healthRegen", 2: "maxHealth", 3: "bodyDamage", 4: "bulletSpeed", 5: "bulletPenetration", 6: "bulletDamage", 7: "reload", 8: "movementSpeed", }; function getUpgrades() { let upgrades = 0; for (let i = 0; i < buildStatLevels.length; ++i) { upgrades++; if (playerLevel < buildStatLevels[i]) break; } return upgrades; } function canUpgrade() { const rawStats = window.extern.get_convar("game_stats_build"); return getUpgrades() - 1 > rawStats.length; } function truncateStats() { const rawStats = window.extern.get_convar("game_stats_build"); return rawStats.slice(0, getUpgrades()); } function getStats() { const rawStats = window.extern.get_convar("game_stats_build"); let stats = { healthRegen: 0, maxHealth: 0, bodyDamage: 0, bulletSpeed: 0, bulletPenetration: 0, bulletDamage: 0, reload: 0, movementSpeed: 0, }; for (let i = 0; i < rawStats.length; ++i) { ++stats[statNumbers[rawStats[i]]]; } return stats; } let forcingU = false; function forceU() { if (canUpgrade()) { forcingU = true; window.extern.onKeyDown(21, 1); } else if (forcingU) { forcingU = false; window.extern.onKeyUp(21, 1); } } function getTankBulletSpeedOffset(tank) { return bulletSpeedOffsets[tank] || 1; } function calculateMainBulletSpeed() { const speedstat = getStats().bulletSpeed; return ( (20 + speedstat * 3 * getTankBulletSpeedOffset(playerTank)) * 0.03 ); } function getDistance(x1, y1, x2, y2) { const distX = x1 - x2; const distY = y1 - y2; return Math.hypot(distX, distY); } function calculateTime(player) { const distance = getDistance(playerX, playerY, player.wx, player.wy); const bulletSpeed = calculateMainBulletSpeed(); const playerVel = getDistVel(player); const relativeBulletToTargetVel = bulletSpeed - playerVel; return distance / relativeBulletToTargetVel; } function predictPlayer(player, time) { const [velX, velY] = typeof player.velocity === "undefined" ? [0, 0] : [(player.velocity[0] || 0), (player.velocity[1] || 0)]; return [player.wx + time * velX, player.wy + time * velY]; } function getDistVel(player) { let dd = 0; let dataPoints = 0; for (let i = 1; i < player.positionTable.length; ++i) { if (!player.positionTable[i] || !player.positionTable[i - 1]) continue; const d = getDistance( playerX, playerY, player.positionTable[i].x, player.positionTable[i].y ) - getDistance( playerX, playerY, player.positionTable[i - 1].x, player.positionTable[i - 1].y ); const dt = player.positionTable[i].timestamp - player.positionTable[i - 1].timestamp; dd += d / dt; dataPoints++; } return dataPoints > 0 ? dd / dataPoints : 0; } function getPlayerWeight(player) { const distanceWeight = (1 / getDistance(playerX, playerY, player.wx, player.wy)) * 1000; const scoreWeight = Math.min(23536, Math.max(0, player.score || 0)) / 100000; return distanceWeight + scoreWeight; } function setPlayerPos() { const dx = arrowPos[0] - minimapPos[0]; const dy = arrowPos[1] - minimapPos[1]; playerX = (dx / minimapSize[0]) * arenaSize; playerY = (dy / minimapSize[1]) * arenaSize; } function getRenderedWorldPosition(x, y) { const mainCanvas = document.getElementById("canvas"); const midX = x - mainCanvas.width / 2; const midY = y - mainCanvas.height / 2; const scaledX = midX / (fov / 2.8); const scaledY = midY / (fov / 2.8); return [playerX + scaledX, playerY + scaledY]; } function worldToCanvasPosition(x, y) { const mainCanvas = document.getElementById("canvas"); const deltaX = x - playerX; const deltaY = y - playerY; return [ mainCanvas.width / 2 + deltaX * (fov / 2.8), mainCanvas.height / 2 + deltaY * (fov / 2.8), ]; } function worldToMousePosition(x, y) { const deltaX = x - playerX; const deltaY = y - playerY; return [ window.innerWidth / 2 + deltaX * (fov / 2.8), window.innerHeight / 2 + deltaY * (fov / 2.8), ]; } function parseDiepScore(s) { let scoreMultiplier = 1; if (s[s.length - 1] === "k") scoreMultiplier = 1000; else if (s[s.length - 1] === "m") scoreMultiplier = 1000000; else if (!s.includes(".")) { if (isNaN(s)) return null; const toInt = parseInt(s, 10); return isNaN(toInt) ? null : toInt; } else return null; const toFloat = parseFloat(s.slice(0, -1)); if (isNaN(toFloat)) return null; return toFloat * scoreMultiplier; } function getClosestText(arr, x, y) { return arr.reduce(function (acc, cur) { if (!acc) return cur; const distAcc = getDistance(x, y, acc.mx, acc.my); const distCur = getDistance(x, y, cur.mx, cur.my); return distAcc > distCur ? cur : acc; }, null); } function getPlayers() { lastPlayers = players; players = []; for (let aIndex = 0; aIndex < tankShapes.length; ++aIndex) { if (tankShapes[aIndex].radius / fov < 19) continue; const scoreTextPos = [ tankShapes[aIndex].x, tankShapes[aIndex].y - tankShapes[aIndex].radius * 1.3, ]; const nameTextPos = [ tankShapes[aIndex].x, tankShapes[aIndex].y - tankShapes[aIndex].radius * 2, ]; const closestScoreText = getClosestText(text, ...scoreTextPos); const closestNameText = getClosestText(text, ...nameTextPos); const distToScore = closestScoreText ? getDistance( ...scoreTextPos, closestScoreText.mx, closestScoreText.my ) : Infinity; const distToName = closestNameText ? getDistance(...nameTextPos, closestNameText.mx, closestNameText.my) : Infinity; let score = ""; let name = ""; if (distToScore < 25) { score = parseDiepScore(closestScoreText ? closestScoreText.text : "-1"); } if (distToName < 25) { name = closestNameText ? closestNameText.text : ""; } if (score !== "") { const [wx, wy] = getRenderedWorldPosition( tankShapes[aIndex].x, tankShapes[aIndex].y ); players.push({ wx, wy, x: tankShapes[aIndex].x, y: tankShapes[aIndex].y, radius: tankShapes[aIndex].radius, name, score, velocity: undefined, teammate: tankShapes[aIndex].fillStyle === gameStyle[teamColor], }); } } } function matchPlayers() { for (let i = 0; i < players.length; ++i) { const [x, y] = [players[i].wx, players[i].wy]; const lastPlayer = lastPlayers.reduce((acc, cur) => { if (!acc) return cur; const distAcc = getDistance(x, y, acc.wx, acc.wy); const distCur = getDistance(x, y, cur.wx, cur.wy); return distAcc > distCur ? cur : acc; }, null); if ( lastPlayer && getDistance( players[i].wx, players[i].wy, lastPlayer.wx, lastPlayer.wy ) < 25 ) { players[i].teammate = lastPlayer.teammate || players[i].teammate; players[i].positionTable = lastPlayer.positionTable.concat(); players[i].positionTable.push({ x: players[i].wx, y: players[i].wy, timestamp: performance.now(), }); players[i].positionTable.shift(); players[i].velocity = getVelocity(players[i]); } else { players[i].positionTable = Array.from( new Array(playerVelocityPredictionSampleSize), () => null ); } } } function getVelocity(player) { let tx = 0, ty = 0; let dataPoints = 0; for (let i = 1; i < player.positionTable.length; ++i) { if (!player.positionTable[i] || !player.positionTable[i - 1]) continue; const dx = player.positionTable[i].x - player.positionTable[i - 1].x; const dy = player.positionTable[i].y - player.positionTable[i - 1].y; const dt = player.positionTable[i].timestamp - player.positionTable[i - 1].timestamp; tx += dx / dt; ty += dy / dt; dataPoints++; } return dataPoints > 0 ? [tx / dataPoints, ty / dataPoints] : [0, 0]; } function renderOverlay(player, tx, ty, px, py) { if (!isDebug) return; const ctx = document.getElementById("canvas").getContext("2d"); const [stx, sty] = worldToCanvasPosition(tx, ty); const [spx, spy] = worldToCanvasPosition(px, py); ctx.beginPath(); ctx.arc(stx, sty, 25, Math.PI * 2, 0, 1); ctx.globalAlpha = 0.35; ctx.fillStyle = "#ff5294"; ctx.fill(); ctx.beginPath(); ctx.arc(spx, spy, 25, Math.PI * 2, 0, 1); ctx.fillStyle = "#52e8ff"; ctx.fill(); ctx.globalAlpha = 1; ctx.beginPath(); ctx.moveTo(stx, sty); ctx.lineTo(spx, spy); ctx.strokeStyle = "#000000"; ctx.lineWidth = 1; ctx.stroke(); } function aim() { const target = players .filter(plr => !plr.teammate) .reduce((acc, cur) => { if (!acc) return cur; return getPlayerWeight(cur) > getPlayerWeight(acc) ? cur : acc; }, null); const enemyMightDodge = destroyerAccuracy && !!target && ["Destroyer", "Hybrid", "Annihilator"].includes(playerTank) && calculateTime(target) >= averageEnemyDodgeTime; if (!target || enemyMightDodge || !isAimbotActive || mousePressed) { if (mouseLocked) { mouseLocked = false; window.extern.onTouchMove(-1, mouseX, mouseY, true); setTimeout(() => { window.extern.onKeyUp(36); }, 80); } return; } if (!mouseLocked) { mouseLocked = true; setTimeout(() => { isFiring = true; window.extern.onKeyDown(36); }, 80); } const [sPX, sPY] = worldToMousePosition(target.wx, target.wy); if (sPX != null && sPY != null) { if (typeof window.extern.onTouchMove === "function") { window.extern.onTouchMove(-1, sPX, sPY, true); } else if (typeof window.extern.onMouseMove === "function") { window.extern.onMouseMove(sPX, sPY); } else { window.extern.onTouchMove(-1, sPX, sPY, true); } setTimeout(() => { isFiring = true; window.extern.onKeyDown(36); setTimeout(() => { window.extern.onKeyUp(36); }, 50); }, 10); } renderOverlay(target, target.wx, target.wy, target.wx, target.wy); } function stack() { if (!(window && window.extern)) return; const reload = getStats().reload; window.extern.onKeyUp(36); // release fire if (playerTank === "Hunter") { shoot(hunterStackTime[reload][0]); setTimeout(() => { window.extern.onKeyDown(5); window.extern.onKeyUp(5); }, hunterStackTime[reload][1]); } else if (playerTank === "Predator") { shoot(predatorStackTime[reload][0]); setTimeout(() => { shoot(predatorStackTime[reload][1]); }, predatorStackTime[reload][2]); setTimeout(() => { window.extern.onKeyDown(5); window.extern.onKeyUp(5); }, predatorStackTime[reload][3]); } } function shoot(t) { isFiring = true; window.extern.onKeyDown(36); setTimeout(() => { window.extern.onKeyUp(36); }, t); } document.addEventListener("mousedown", function (ev) { mousePressed = true; if (ev.button === 0) { if (mouseLocked) { isFiring = true; window.extern.onKeyDown(36); setTimeout(() => { window.extern.onKeyDown(36); }, 10); } } }); document.addEventListener("mouseup", function (ev) { mousePressed = false; if (ev.button === 0) { window.extern.onKeyUp(36); } }); document.addEventListener("touchstart", function (ev) { isShooting = true; }); document.addEventListener("touchend", function (ev) { isShooting = false; }); document.addEventListener( "mousemove", function (ev) { if (isSpinning) { ev.stopImmediatePropagation(); ev.preventDefault(); } }, true ); document.addEventListener( "touchmove", function (ev) { if (isSpinning) { ev.stopImmediatePropagation(); ev.preventDefault(); } }, true ); // yes const KeyToToggleAimbot = "KeyU"; const KeyToStack = "KeyI"; const KeyToToggleMenu = "KeyM"; document.addEventListener("keydown", function (ev) { if (ev.code === KeyToToggleAimbot) { isAimbotActive ^= 1; if (window.__common__ && window.__common__.active_gamemode === "sandbox") { window.extern && window.extern.inGameNotification( "Aimbot Doesn't Work in Sandbox", 0xF533FF ); isAimbotActive = 0; } else { window.extern && window.extern.inGameNotification( isAimbotActive ? "Aimbot: ON" : "Aimbot: OFF", 0xF533FF ); } const aimbotCheckbox = document.getElementById("aimbot-checkbox"); if (aimbotCheckbox) aimbotCheckbox.checked = Boolean(isAimbotActive); } else if (ev.code === KeyToStack) { if (["Hunter", "Predator"].includes(playerTank)) { stack(); window.extern && window.extern.inGameNotification("Stacking Bullets...", 0xF533FF); } } else if (ev.code === KeyToToggleMenu) { if (!menuContainer) return; const isHidden = menuContainer.style.display === "none"; menuContainer.style.display = isHidden ? "block" : "none"; } }); // why am I even doing this? let ctxTransform; a._("setTransform", (context, ...args) => { ctxTransform = args; return [context, args]; }); a._("drawImage", (context, ...args) => { if (args[0].renderMethod) { const x = ctxTransform[4] + args[1]; const y = ctxTransform[5] + args[2]; if (args[0].renderMethod.method === "text") { text.push({ x, y, cw: args[0].width, ch: args[0].height, mx: x + args[0].width / 4, my: y + args[0].height / 4, text: args[0].renderMethod.text, }); } } return [context, args]; }); a._("strokeText", (context, ...args) => { if (context.canvas.id !== "canvas") { context.canvas.renderMethod = { method: "text", text: args[0], args, fillStyle: context.fillStyle, }; if (args[0].startsWith("Lvl ")) { if (args[0][5] === " ") { playerLevel = Number(args[0].slice(4, 5)); playerTank = args[0].slice(6); } else { playerLevel = Number(args[0].slice(4, 6)); playerTank = args[0].slice(7); } } } return [context, args]; }); a._("arc", (context, ...args) => { if ( context.canvas.id === "canvas" && ctxTransform[4] === lastArc[0] && ctxTransform[5] === lastArc[1] ) { tankShapes.push({ x: ctxTransform[4], y: ctxTransform[5], radius: Math.hypot(ctxTransform[1], ctxTransform[0]), fillStyle: context.fillStyle, }); lastArc = [Infinity, Infinity]; } else { lastArc = [ctxTransform[4], ctxTransform[5]]; } return [context, args]; }); // maybe my sister looks hot a._("stroke", (context, ...args) => { if ( ["#cccccc", "#cdcdcd"].includes(context.fillStyle) && context.strokeStyle === "#000000" ) { fov = context.globalAlpha / gameStyle.ren_grid_base_alpha; } return [context, args]; }); a._("strokeRect", (context, ...args) => { const t = context.getTransform(); minimapPos = [t.e, t.f]; minimapSize = [t.a, t.d]; return [context, args]; }); // yes i will kill myself one day let position = 0; let vertex = []; a._("beginPath", (context, ...args) => { position = 0; vertex = []; return [context, args]; }); a._("moveTo", (context, ...args) => { position = 1; vertex.push(args); return [context, args]; }); a._("lineTo", (context, ...args) => { position++; vertex.push(args); return [context, args]; }); a._("fill", (context, ...args) => { if ( context.fillStyle === "#000000" && context.globalAlpha > 0.949 && position === 3 ) { arrowPos = getAverage(vertex); setPlayerPos(); } else if ( position === 4 && context.fillStyle && context.fillStyle.toLowerCase().includes("ffe869") ) { const [rawX, rawY] = getAverage(vertex); const centerX = ctxTransform[4] + rawX; const centerY = ctxTransform[5] + rawY; neutralSquares.push([centerX, centerY]); } else if ( position === 5 && context.fillStyle && context.fillStyle.toLowerCase().includes("768dfc") ) { const [rawX, rawY] = getAverage(vertex); const centerX = ctxTransform[4] + rawX; const centerY = ctxTransform[5] + rawY; neutralPentagons.push([centerX, centerY]); } else if ( position === 3 && context.fillStyle && context.fillStyle.toLowerCase().includes("fc7677") ) { const [rawX, rawY] = getAverage(vertex); const centerX = ctxTransform[4] + rawX; const centerY = ctxTransform[5] + rawY; neutralTriangles.push([centerX, centerY]); } return [context, args]; }); function getAverage(points) { let tx = 0, ty = 0; points.forEach((point) => { tx += point[0]; ty += point[1]; }); return [tx / points.length, ty / points.length]; } // i hate niggers btw function onFrame() { window.requestAnimationFrame(onFrame); getPlayers(); matchPlayers(); if (isDebug) { const ctx = document.getElementById("canvas").getContext("2d"); ctx.save(); ctx.strokeStyle = "#FF0000"; ctx.lineWidth = 1; const centerX = ctx.canvas.width / 2; const centerY = ctx.canvas.height / 2; players.forEach((plr) => { if (!plr.teammate) { ctx.beginPath(); ctx.moveTo(centerX, centerY); ctx.lineTo(plr.x, plr.y); ctx.stroke(); } }); ctx.restore(); } forceU(); aim(); text = []; tankShapes = []; getTeam(); if (isAutoFarm && window.extern && window.extern.doesHaveTank()) { if (isDebug) { const ctx = document.getElementById("canvas").getContext("2d"); ctx.save(); const centerX = ctx.canvas.width / 2; const centerY = ctx.canvas.height / 2; ctx.strokeStyle = "#9600D6"; ctx.lineWidth = 1; neutralPentagons.forEach(([cx, cy]) => { ctx.beginPath(); ctx.moveTo(centerX, centerY); ctx.lineTo(cx, cy); ctx.stroke(); }); ctx.strokeStyle = "#00FF00"; ctx.lineWidth = 1; neutralSquares.forEach(([cx, cy]) => { ctx.beginPath(); ctx.moveTo(centerX, centerY); ctx.lineTo(cx, cy); ctx.stroke(); }); ctx.strokeStyle = "#FF9900"; ctx.lineWidth = 1; neutralTriangles.forEach(([cx, cy]) => { ctx.beginPath(); ctx.moveTo(centerX, centerY); ctx.lineTo(cx, cy); ctx.stroke(); }); ctx.restore(); } let targetWorld = null; if (farmPriority === "pentagon" && neutralPentagons.length > 0) { targetWorld = nearestShapeWorld(neutralPentagons); } else if (farmPriority === "square" && neutralSquares.length > 0) { targetWorld = nearestShapeWorld(neutralSquares); } else if (farmPriority === "triangle" && neutralTriangles.length > 0) { targetWorld = nearestShapeWorld(neutralTriangles); } if (!targetWorld) { if (farmPriority !== "pentagon" && neutralPentagons.length > 0) { targetWorld = nearestShapeWorld(neutralPentagons); } else if (farmPriority !== "square" && neutralSquares.length > 0) { targetWorld = nearestShapeWorld(neutralSquares); } else if (farmPriority !== "triangle" && neutralTriangles.length > 0) { targetWorld = nearestShapeWorld(neutralTriangles); } } if (targetWorld) { const [sPX, sPY] = worldToMousePosition(targetWorld[0], targetWorld[1]); if (sPX != null && sPY != null) { isFiring = true; window.extern.onTouchMove(-1, sPX, sPY, true); window.extern.onKeyDown(36); setTimeout(() => { window.extern.onKeyUp(36); }, 50); } } } neutralSquares = []; neutralPentagons = []; neutralTriangles = []; if ( isSpinning && !isShooting && !isFiring && window.extern && window.extern.doesHaveTank() ) { spinAngle += spinSpeed; const cx = window.innerWidth / 2; const cy = window.innerHeight / 2; const radius = 120; const targetX = cx + radius * Math.cos(spinAngle); const targetY = cy + radius * Math.sin(spinAngle); if (typeof window.extern.onTouchMove === "function") { window.extern.onTouchMove(-1, targetX, targetY, true); } else if (typeof window.extern.onMouseMove === "function") { window.extern.onMouseMove(targetX, targetY); } } if (window.extern && window.extern.doesHaveTank() && !hasJoined) { hasJoined = true; window.extern.inGameNotification("Welcome to SkidWare. Press M for menu.", 0x6670ff); } } function nearestShapeWorld(arr) { let nearest = null; let nearestDist = Infinity; for (const [cx, cy] of arr) { const [wx, wy] = getRenderedWorldPosition(cx, cy); const dist = getDistance(playerX, playerY, wx, wy); if (dist < nearestDist) { nearestDist = dist; nearest = [wx, wy]; } } return nearest; } function onGameStart() { if (typeof extern === "undefined") return; clearInterval(checkGameStart); window.requestAnimationFrame(onFrame); window.extern.onKeyDown = new Proxy(window.extern.onKeyDown, { apply: function (method, context, args) { if (args[0] === 36) { isFiring = true; } if (args[0] === 21 && !args[1]) return; return Reflect.apply(method, context, args); }, }); window.extern.onKeyUp = new Proxy(window.extern.onKeyUp, { apply: function (method, context, args) { if (args[0] === 36) { isFiring = false; } if (args[0] === 21 && !args[1]) return; return Reflect.apply(method, context, args); }, }); const mouseHandler = { apply: function (method, context, args) { if (!args[3]) { [mouseX, mouseY] = [args[1], args[2]]; if (mouseLocked) return; } return Reflect.apply(method, context, args); }, }; window.extern.onTouchStart = new Proxy(window.extern.onTouchStart, mouseHandler); window.extern.onTouchMove = new Proxy(window.extern.onTouchMove, mouseHandler); window.extern.onTouchEnd = new Proxy(window.extern.onTouchEnd, mouseHandler); window.extern.set_convar = new Proxy(window.extern.set_convar, { apply: function (method, context, args) { gameStyle[args[0]] = args[1]; return Reflect.apply(method, context, args); }, }); window.extern.execute = new Proxy(window.extern.execute, { apply: function (method, context, args) { if (args[0].startsWith("net_replace_color 3 ")) { gameStyle.teamBlue = args[0][20] === "0" ? "#" + args[0].slice(22) : args[0].slice(20); } if (args[0].startsWith("net_replace_color 4 ")) { gameStyle.teamRed = args[0][20] === "0" ? "#" + args[0].slice(22) : args[0].slice(20); } if (args[0].startsWith("net_replace_color 5 ")) { gameStyle.teamPurple = args[0][20] === "0" ? "#" + args[0].slice(22) : args[0].slice(20); } if (args[0].startsWith("net_replace_color 6 ")) { gameStyle.teamGreen = args[0][20] === "0" ? "#" + args[0].slice(22) : args[0].slice(20); } if (args[0].startsWith("net_replace_color 8 ")) { gameStyle.square = args[0][20] === "0" ? "#" + args[0].slice(22) : args[0].slice(20); } if (args[0].startsWith("net_replace_color 9 ")) { gameStyle.triangle = args[0][20] === "0" ? "#" + args[0].slice(22) : args[0].slice(20); } if (args[0].startsWith("net_replace_color 10 ")) { gameStyle.pentagon = args[0][21] === "0" ? "#" + args[0].slice(23) : args[0].slice(21); } return Reflect.apply(method, context, args); }, }); } const checkGameStart = setInterval(onGameStart, 400); function getTeam() { const partyLinkButton = document.getElementById("copy-party-link"); if (!partyLinkButton) return; switch (partyLinkButton.className) { case "active blue": teamColor = "teamBlue"; break; case "active purple": teamColor = "teamPurple"; break; case "active green": teamColor = "teamGreen"; break; case "active red": teamColor = "teamRed"; break; } } let menuContainer = null; let isBlackBg = false; let blackBgDiv = null; // menu full chatgpt function createUnifiedMenu() { const styleEl = document.createElement("style"); styleEl.textContent = ` /* ===================== skeet.cc-Style Menu (30% Bigger & Draggable) ===================== */ @font-face { font-family: 'SkeetFont'; src: local('Segoe UI'), local('Arial'), sans-serif; /* Fallback: system sans-serif if Segoe UI not present */ } /* ── Main Menu Container ───────────────────────────────────────────────────── */ .skeet-menu { position: fixed; /* Initial position at 50px, 50px; will be overridden during dragging */ top: 50px; left: 50px; width: 494px; /* 380px * 1.3 */ background-color: #1b1b1b; border: 1px solid #2f2f2f; border-radius: 6px; box-shadow: 0 0 12px rgba(0, 0, 0, 0.7); font-family: 'SkeetFont', sans-serif; color: #e0e0e0; font-size: 17px; /* 13px * 1.3 */ user-select: none; display: none; /* hidden by default; toggled with “M” */ pointer-events: auto; z-index: 9999; } /* ── Drag Handle (26px high) ─────────────────────────────────────────────────── */ .skeet-drag-handle { height: 26px; /* 20px * 1.3 */ background-color: #2f2f2f; border-bottom: 1px solid #2f2f2f; cursor: move; text-align: center; line-height: 26px; /* same as height, to center text vertically */ font-size: 17px; /* 13px * 1.3 */ font-weight: 500; color: #e0e0e0; user-select: none; } /* ── Sidebar (104px-wide Text Tabs) ────────────────────────────────────────── */ .skeet-sidebar { float: left; width: 104px; /* 80px * 1.3 */ background-color: #171717; border-right: 1px solid #2f2f2f; display: flex; flex-direction: column; align-items: center; padding-top: 16px; /* 12px * 1.3 */ } .skeet-sidebar button { width: 83px; /* 64px * 1.3 ≈ 83 */ height: 42px; /* 32px * 1.3 ≈ 42 */ margin: 8px 0; /* 6px * 1.3 ≈ 8 */ background-color: transparent; border: none; outline: none; cursor: pointer; transition: background-color 0.15s ease, color 0.15s ease; color: #888888; font-size: 17px; /* 13px * 1.3 ≈ 17 */ font-weight: 500; } .skeet-sidebar button:hover, .skeet-sidebar button.active { background-color: #2f2f2f; color: #00b4ff; border-radius: 4px; } /* ── Content Area (Remaining ≈390px) ────────────────────────────────────────── */ .skeet-content { margin-left: 104px; /* leave room for sidebar */ padding: 21px; /* 16px * 1.3 ≈ 21 */ box-sizing: border-box; } /* Hide all sections by default; only the “.active” one displays */ .skeet-section { display: none; } .skeet-section.active { display: block; } .skeet-content .section-title { font-size: 21px; /* 16px * 1.3 ≈ 21 */ font-weight: 600; color: #ffffff; margin-bottom: 13px; /* 10px * 1.3 ≈ 13 */ } /* ── Section Header ───────────────────────────────────────────────────────── */ .skeet-section .header { font-size: 18px; /* 14px * 1.3 ≈ 18 */ font-weight: 500; margin-bottom: 10px; /* 8px * 1.3 ≈ 10 */ color: #e0e0e0; } /* ── Toggle Labels (Checkbox + Text) ───────────────────────────────────────── */ .skeet-toggle-label { display: flex; align-items: center; margin-bottom: 10px; /* 8px * 1.3 ≈ 10 */ cursor: pointer; } .skeet-toggle-label input[type="checkbox"] { width: 18px; /* 14px * 1.3 ≈ 18 */ height: 18px; /* 14px * 1.3 ≈ 18 */ margin-right: 10px; /* 8px * 1.3 ≈ 10 */ accent-color: #00b4ff; cursor: pointer; outline: none; } .skeet-toggle-label span { font-size: 17px; /* 13px * 1.3 ≈ 17 */ color: #e0e0e0; } /* ── Slider (Range Input) ─────────────────────────────────────────────────── */ .skeet-slider-container { display: flex; align-items: center; margin-bottom: 15px; /* 12px * 1.3 ≈ 15 */ } .skeet-slider-container span { margin-right: 10px; /* 8px * 1.3 ≈ 10 */ font-size: 16px; /* 12px * 1.3 ≈ 16 */ color: #cccccc; min-width: 91px; /* 70px * 1.3 ≈ 91 */ } .skeet-slider { flex: 1; -webkit-appearance: none; width: 100%; height: 5px; /* 4px * 1.3 ≈ 5 */ background: #2f2f2f; border-radius: 3px; cursor: pointer; outline: none; } .skeet-slider::-webkit-slider-thumb { -webkit-appearance: none; width: 16px; /* 12px * 1.3 ≈ 16 */ height: 16px; /* 12px * 1.3 ≈ 16 */ border-radius: 50%; background: #00b4ff; border: 1px solid #1b1b1b; cursor: pointer; margin-top: -5px; /* center thumb (≈ half the thumb height) */ } .skeet-slider::-moz-range-thumb { width: 16px; height: 16px; border-radius: 50%; background: #00b4ff; border: 1px solid #1b1b1b; cursor: pointer; } /* ── Buttons (Load/Save/Stack etc.) ───────────────────────────────────────── */ .skeet-button { display: inline-block; background-color: #2f2f2f; color: #e0e0e0; font-size: 15px; /* 12px * 1.3 ≈ 15 */ padding: 8px 16px; /* 6px*1.3≈8 & 12px*1.3≈16 */ margin-top: 8px; /* 6px * 1.3 ≈ 8 */ border: 1px solid #3f3f3f; border-radius: 4px; cursor: pointer; transition: background-color 0.15s ease, border-color 0.15s ease; } .skeet-button:hover { background-color: #3f3f3f; border-color: #5f5f5f; } .skeet-button:active { background-color: #5f5f5f; border-color: #7f7f7f; } /* ── Radio Buttons for Farming Priority ───────────────────────────────────── */ .skeet-radio-group { margin-bottom: 10px; /* some spacing */ } .skeet-radio-label { display: flex; align-items: center; margin-right: 20px; cursor: pointer; font-size: 17px; /* 13px * 1.3 */ color: #e0e0e0; } .skeet-radio-label input[type="radio"] { margin-right: 8px; accent-color: #00b4ff; cursor: pointer; outline: none; } /* ── Focus Ring for Keyboard Navigation ──────────────────────────────────── */ .skeet-menu input:focus-visible, .skeet-menu button:focus-visible { outline: 2px solid #00b4ff; outline-offset: 1px; } `; document.head.appendChild(styleEl); menuContainer = document.createElement("div"); menuContainer.classList.add("skeet-menu"); const dragHandle = document.createElement("div"); dragHandle.classList.add("skeet-drag-handle"); dragHandle.innerText = "Skid Ware"; menuContainer.appendChild(dragHandle); const sidebar = document.createElement("div"); sidebar.classList.add("skeet-sidebar"); const tabs = [ { id: "tab-spin", label: "Spin" }, { id: "tab-aim", label: "Aim" }, { id: "tab-farm", label: "Farm" }, { id: "tab-visuals", label: "Visuals" }, ]; tabs.forEach((t, idx) => { const btn = document.createElement("button"); btn.id = t.id + "-btn"; btn.innerText = t.label; btn.title = t.label; if (idx === 0) btn.classList.add("active"); btn.addEventListener("click", () => switchTab(t.id)); sidebar.appendChild(btn); }); menuContainer.appendChild(sidebar); const content = document.createElement("div"); content.classList.add("skeet-content"); const spinSection = document.createElement("div"); spinSection.id = "tab-spin"; spinSection.classList.add("skeet-section", "active"); const spinTitle = document.createElement("div"); spinTitle.classList.add("section-title"); spinTitle.innerText = "Spinner Settings:"; spinSection.appendChild(spinTitle); const spinHeader = document.createElement("div"); spinHeader.classList.add("header"); spinHeader.innerText = "• Enable / Disable Spinner:"; spinSection.appendChild(spinHeader); const spinToggleLabel = document.createElement("label"); spinToggleLabel.classList.add("skeet-toggle-label"); const spinCheckbox = document.createElement("input"); spinCheckbox.type = "checkbox"; spinCheckbox.id = "spinner-checkbox"; spinCheckbox.checked = isSpinning; const spinLabelText = document.createElement("span"); spinLabelText.innerText = "Enable Spinner"; spinToggleLabel.appendChild(spinCheckbox); spinToggleLabel.appendChild(spinLabelText); spinSection.appendChild(spinToggleLabel); spinCheckbox.addEventListener("change", function () { isSpinning = this.checked; if (window.extern) { window.extern.inGameNotification( isSpinning ? "Spinner: ON" : "Spinner: OFF", 0xF533FF ); } }); const spinSpeedHeader = document.createElement("div"); spinSpeedHeader.classList.add("header"); spinSpeedHeader.innerText = "• Spin Speed:"; spinSection.appendChild(spinSpeedHeader); const spinSpeedContainer = document.createElement("div"); spinSpeedContainer.classList.add("skeet-slider-container"); const speedLabelText = document.createElement("span"); speedLabelText.innerText = `Speed: ${spinSpeed.toFixed(2)}`; const spinSlider = document.createElement("input"); spinSlider.type = "range"; spinSlider.min = "0"; spinSlider.max = "2"; spinSlider.step = "0.01"; spinSlider.value = spinSpeed.toString(); spinSlider.classList.add("skeet-slider"); spinSlider.addEventListener("input", (ev) => { spinSpeed = parseFloat(ev.target.value); speedLabelText.innerText = `Speed: ${spinSpeed.toFixed(2)}`; }); ["mousedown", "mousemove", "mouseup", "touchstart", "touchmove", "touchend"].forEach((evt) => { spinSlider.addEventListener(evt, (e) => e.stopPropagation(), { capture: true, passive: false }); }); spinSpeedContainer.appendChild(speedLabelText); spinSpeedContainer.appendChild(spinSlider); spinSection.appendChild(spinSpeedContainer); content.appendChild(spinSection); const aimSection = document.createElement("div"); aimSection.id = "tab-aim"; aimSection.classList.add("skeet-section"); const aimTitle = document.createElement("div"); aimTitle.classList.add("section-title"); aimTitle.innerText = "Aimbot Settings:"; aimSection.appendChild(aimTitle); const aimHeader = document.createElement("div"); aimHeader.classList.add("header"); aimHeader.innerText = "• Enable / Disable Aimbot:"; aimSection.appendChild(aimHeader); const aimToggleLabel = document.createElement("label"); aimToggleLabel.classList.add("skeet-toggle-label"); const aimCheckbox = document.createElement("input"); aimCheckbox.type = "checkbox"; aimCheckbox.id = "aimbot-checkbox"; aimCheckbox.checked = isAimbotActive; const aimLabelText = document.createElement("span"); aimLabelText.innerText = "Enable Aimbot"; aimToggleLabel.appendChild(aimCheckbox); aimToggleLabel.appendChild(aimLabelText); aimSection.appendChild(aimToggleLabel); aimCheckbox.addEventListener("change", function () { isAimbotActive = this.checked; if (window.extern) { window.extern.inGameNotification( isAimbotActive ? "Aimbot: ON" : "Aimbot: OFF", 0xF533FF ); } }); const stackHeader = document.createElement("div"); stackHeader.classList.add("header"); stackHeader.innerText = "• Manual Stack (Hunter/Predator):"; aimSection.appendChild(stackHeader); const stackButton = document.createElement("button"); stackButton.innerText = "Stack Bullets"; stackButton.classList.add("skeet-button"); stackButton.addEventListener("click", () => { if (["Hunter", "Predator"].includes(playerTank)) { stack(); window.extern && window.extern.inGameNotification("Stacking Bullets...", 0xF533FF); } else { window.extern && window.extern.inGameNotification("Not Hunter/Predator", 0xF533FF); } }); aimSection.appendChild(stackButton); content.appendChild(aimSection); const farmSection = document.createElement("div"); farmSection.id = "tab-farm"; farmSection.classList.add("skeet-section"); const farmTitle = document.createElement("div"); farmTitle.classList.add("section-title"); farmTitle.innerText = "AutoFarm:"; farmSection.appendChild(farmTitle); const farmHeader = document.createElement("div"); farmHeader.classList.add("header"); farmHeader.innerText = "• Enable / Disable AutoFarm:"; farmSection.appendChild(farmHeader); const farmToggleLabel = document.createElement("label"); farmToggleLabel.classList.add("skeet-toggle-label"); const farmCheckbox = document.createElement("input"); farmCheckbox.type = "checkbox"; farmCheckbox.id = "autofarm-checkbox"; farmCheckbox.checked = isAutoFarm; const farmLabelText = document.createElement("span"); farmLabelText.innerText = "Enable AutoFarm"; farmToggleLabel.appendChild(farmCheckbox); farmToggleLabel.appendChild(farmLabelText); farmSection.appendChild(farmToggleLabel); farmCheckbox.addEventListener("change", function () { isAutoFarm = this.checked; if (window.extern) { window.extern.inGameNotification( isAutoFarm ? "AutoFarm: ON" : "AutoFarm: OFF", 0xF533FF ); } }); const priorityContainer = document.createElement("div"); priorityContainer.classList.add("skeet-radio-group"); const priorityLabel = document.createElement("div"); priorityLabel.classList.add("header"); priorityLabel.innerText = "• Farming Priority:"; farmSection.appendChild(priorityLabel); const pentRadioLabel = document.createElement("label"); pentRadioLabel.classList.add("skeet-radio-label"); const pentRadio = document.createElement("input"); pentRadio.type = "radio"; pentRadio.name = "farm-priority"; pentRadio.id = "farm-priority-pentagon"; pentRadio.value = "pentagon"; pentRadio.checked = (farmPriority === "pentagon"); const pentLabelText = document.createElement("span"); pentLabelText.innerText = "Prioritize Pentagons"; pentRadioLabel.appendChild(pentRadio); pentRadioLabel.appendChild(pentLabelText); priorityContainer.appendChild(pentRadioLabel); pentRadio.addEventListener("change", function () { if (this.checked) { farmPriority = "pentagon"; if (window.extern) { window.extern.inGameNotification("FarmPriority: Pentagons", 0xF533FF); } } }); const sqRadioLabel = document.createElement("label"); sqRadioLabel.classList.add("skeet-radio-label"); const sqRadio = document.createElement("input"); sqRadio.type = "radio"; sqRadio.name = "farm-priority"; sqRadio.id = "farm-priority-square"; sqRadio.value = "square"; sqRadio.checked = (farmPriority === "square"); const sqLabelText = document.createElement("span"); sqLabelText.innerText = "Prioritize Squares"; sqRadioLabel.appendChild(sqRadio); sqRadioLabel.appendChild(sqLabelText); priorityContainer.appendChild(sqRadioLabel); sqRadio.addEventListener("change", function () { if (this.checked) { farmPriority = "square"; if (window.extern) { window.extern.inGameNotification("FarmPriority: Squares", 0xF533FF); } } }); const triRadioLabel = document.createElement("label"); triRadioLabel.classList.add("skeet-radio-label"); const triRadio = document.createElement("input"); triRadio.type = "radio"; triRadio.name = "farm-priority"; triRadio.id = "farm-priority-triangle"; triRadio.value = "triangle"; triRadio.checked = (farmPriority === "triangle"); const triLabelText = document.createElement("span"); triLabelText.innerText = "Prioritize Triangles"; triRadioLabel.appendChild(triRadio); triRadioLabel.appendChild(triLabelText); priorityContainer.appendChild(triRadioLabel); triRadio.addEventListener("change", function () { if (this.checked) { farmPriority = "triangle"; if (window.extern) { window.extern.inGameNotification("FarmPriority: Triangles", 0xF533FF); } } }); farmSection.appendChild(priorityContainer); content.appendChild(farmSection); const visualsSection = document.createElement("div"); visualsSection.id = "tab-visuals"; visualsSection.classList.add("skeet-section"); const visualsTitle = document.createElement("div"); visualsTitle.classList.add("section-title"); visualsTitle.innerText = "Debug / Visuals:"; visualsSection.appendChild(visualsTitle); const visualsHeader = document.createElement("div"); visualsHeader.classList.add("header"); visualsHeader.innerText = "• Enable / Disable Debug Lines:"; visualsSection.appendChild(visualsHeader); const visualsToggleLabel = document.createElement("label"); visualsToggleLabel.classList.add("skeet-toggle-label"); const visualsCheckbox = document.createElement("input"); visualsCheckbox.type = "checkbox"; visualsCheckbox.id = "debug-checkbox"; visualsCheckbox.checked = isDebug; const visualsLabelText = document.createElement("span"); visualsLabelText.innerText = "Enable Debug Lines"; visualsToggleLabel.appendChild(visualsCheckbox); visualsToggleLabel.appendChild(visualsLabelText); visualsSection.appendChild(visualsToggleLabel); visualsCheckbox.addEventListener("change", function () { isDebug = this.checked; if (window.extern) { window.extern.inGameNotification( isDebug ? "Debug Lines: ON" : "Debug Lines: OFF", 0xF533FF ); } }); const blackBgToggleLabel = document.createElement("label"); blackBgToggleLabel.classList.add("skeet-toggle-label"); const blackBgCheckbox = document.createElement("input"); blackBgCheckbox.type = "checkbox"; blackBgCheckbox.id = "blackbg-checkbox"; blackBgCheckbox.checked = isBlackBg; const blackBgLabelText = document.createElement("span"); blackBgLabelText.innerText = "Black Background (buggy on aim)"; blackBgToggleLabel.appendChild(blackBgCheckbox); blackBgToggleLabel.appendChild(blackBgLabelText); visualsSection.appendChild(blackBgToggleLabel); blackBgCheckbox.addEventListener("change", function () { isBlackBg = this.checked; if (window.input && typeof window.input.set_convar === "function") { window.input.set_convar("ren_background_color", isBlackBg ? "#000000" : "#CDCDCD"); } if (window.extern) { window.extern.inGameNotification( isBlackBg ? "Black background: ON" : "Black background: OFF", 0xF533FF ); } }); content.appendChild(visualsSection); menuContainer.appendChild(content); document.body.appendChild(menuContainer); function switchTab(activeId) { tabs.forEach((t) => { const btn = document.getElementById(t.id + "-btn"); if (t.id === activeId) btn.classList.add("active"); else btn.classList.remove("active"); }); tabs.forEach((t) => { const section = document.getElementById(t.id); if (t.id === activeId) section.classList.add("active"); else section.classList.remove("active"); }); } let isDragging = false; let dragOffsetX = 0; let dragOffsetY = 0; dragHandle.addEventListener("mousedown", function (e) { isDragging = true; const rect = menuContainer.getBoundingClientRect(); dragOffsetX = e.clientX - rect.left; dragOffsetY = e.clientY - rect.top; document.addEventListener("mousemove", onMouseMove); document.addEventListener("mouseup", onMouseUp); e.preventDefault(); }); function onMouseMove(e) { if (!isDragging) return; const newLeft = e.clientX - dragOffsetX; const newTop = e.clientY - dragOffsetY; menuContainer.style.left = newLeft + "px"; menuContainer.style.top = newTop + "px"; } function onMouseUp() { isDragging = false; document.removeEventListener("mousemove", onMouseMove); document.removeEventListener("mouseup", onMouseUp); } } // https://discord.gg/NBN3jgQDGe
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址