您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Pixel Battle Overlay
// ==UserScript== // @name Pixel Overlay // @namespace http://tampermonkey.net/ // @version 2.4 // @description Pixel Battle Overlay // @author .hilkach. // @match https://pixelbattles.ru/* // @match https://api.pixelbattles.ru/* // @license MIT // @grant none // ==/UserScript== (function() { 'use strict'; // === Всплывающее окно "Сделано Хилкачом" === const infoBox = document.createElement("div"); infoBox.innerHTML = ` <div id="hilkachInfo" style=" position: fixed; top: 20px; left: 50%; transform: translateX(-50%); background: rgba(0,0,0,0.85); color: white; padding: 16px 20px; border-radius: 12px; box-shadow: 0 0 12px rgba(0,0,0,0.6); z-index: 30000; font-family: 'Segoe UI', sans-serif; text-align: center; width: 320px; animation: fadeIn 0.6s ease; "> <div style="font-weight: bold; font-size: 18px; margin-bottom: 6px;">Сделано Хилкачом</div> <div style="font-size: 14px; margin-bottom: 8px; line-height: 1.5;"> Discord: <span style="color:#5cc87f;">.hilkach.</span><br> YouTube: <a href="https://www.youtube.com/@hilkashosho" target="_blank" style="color:#4d90e3; text-decoration:none;">youtube.com/@hilkashosho</a><br> Twitch: <a href="https://www.twitch.tv/mreklick" target="_blank" style="color:#a754ba; text-decoration:none;">twitch.tv/mreklick</a> </div> <button id="closeInfoBtn" style=" background: #ec5427; color: white; border: none; padding: 6px 10px; border-radius: 6px; cursor: pointer; font-size: 13px; ">Закрыть</button> </div> <style> @keyframes fadeIn { from { opacity: 0; transform: translate(-50%, -20px); } to { opacity: 1; transform: translate(-50%, 0); } } </style> `; document.body.appendChild(infoBox); document.getElementById("closeInfoBtn").addEventListener("click", () => { infoBox.remove(); }); // === Основной скрипт Pixel Overlay === const CANVAS_WIDTH = 1024; const CANVAS_HEIGHT = 768; const canvas = document.querySelector("#root > div > div.bZsByG_root > div.bZsByG_workbench > div.bZsByG_draggable > canvas"); const container = document.querySelector("#root > div > div.bZsByG_root > div.bZsByG_workbench > div.bZsByG_draggable"); if (!canvas || !container) return console.warn("Канвас не найден"); const overlayCanvas = document.createElement("canvas"); overlayCanvas.width = CANVAS_WIDTH; overlayCanvas.height = CANVAS_HEIGHT; overlayCanvas.style.position = "absolute"; overlayCanvas.style.left = canvas.offsetLeft + "px"; overlayCanvas.style.top = canvas.offsetTop + "px"; overlayCanvas.style.pointerEvents = "none"; overlayCanvas.style.zIndex = 9999; overlayCanvas.style.imageRendering = "pixelated"; container.style.position = "relative"; container.appendChild(overlayCanvas); const octx = overlayCanvas.getContext("2d"); octx.imageSmoothingEnabled = false; let pixelSize = 1; let img = new Image(); let offsetX = 0; let offsetY = 0; let opacity = 1.0; const PALETTE = [ "#ae233d", "#ec5427", "#f4ab3c", "#f9d759", "#48a06d", "#5cc87f", "#9ae96c", "#317270", "#469ca8", "#2d519e", "#4d90e3", "#7ee6f2", "#4440ba", "#6662f6", "#772b99", "#a754ba", "#eb4e81", "#f19eab", "#684a34", "#956a34", "#000000", "#898d90", "#d5d7d9", "#ffffff" ].map(hex => { const bigint = parseInt(hex.slice(1), 16); return [ (bigint >> 16) & 255, (bigint >> 8) & 255, bigint & 255 ]; }); function nearestPaletteColor(r, g, b) { let minDist = Infinity; let nearest = [0,0,0]; for (const [pr, pg, pb] of PALETTE) { const dist = (r - pr) ** 2 + (g - pg) ** 2 + (b - pb) ** 2; if (dist < minDist) { minDist = dist; nearest = [pr, pg, pb]; } } return nearest; } const menu = document.createElement("div"); menu.style.position = "fixed"; menu.style.top = "10px"; menu.style.right = "10px"; menu.style.background = "rgba(0,0,0,0.85)"; menu.style.color = "#fff"; menu.style.padding = "0"; menu.style.zIndex = 20000; menu.style.fontFamily = "sans-serif"; menu.style.borderRadius = "8px"; menu.style.width = "190px"; menu.style.fontSize = "14px"; menu.style.userSelect = "none"; menu.style.boxShadow = "0 0 8px rgba(0,0,0,0.5)"; menu.innerHTML = ` <div id="menuHeader" style=" background: #222; padding: 6px 10px; cursor: move; border-top-left-radius: 8px; border-top-right-radius: 8px; font-weight: bold; text-align: center; ">Pixel Overlay</div> <div style="padding: 10px;"> <label>Пиксельный размер: <span id="pixelSizeVal">1</span></label><br> <input type="range" min="1" max="20" value="1" id="pixelRange" style="width:100%;"><br><br> <div style=" display: flex; justify-content: space-between; align-items: center; gap: 6px; margin-top: 4px; margin-bottom: 10px; "> <label>X: <input type="number" id="xCoord" value="0" style="width:60px;"></label> <label>Y: <input type="number" id="yCoord" value="0" style="width:60px;"></label> </div> <label>Прозрачность: <span id="opacityVal">100%</span></label><br> <input type="range" min="0" max="100" value="100" id="opacityRange" style="width:100%;"><br><br> <input type="file" id="imgFile" style="width:100%;"> </div> `; document.body.appendChild(menu); document.getElementById("pixelRange").addEventListener("input", (e) => { pixelSize = parseInt(e.target.value); document.getElementById("pixelSizeVal").innerText = pixelSize; drawPixelImage(); }); document.getElementById("xCoord").addEventListener("change", (e) => { offsetX = parseInt(e.target.value); drawPixelImage(); }); document.getElementById("yCoord").addEventListener("change", (e) => { offsetY = parseInt(e.target.value); drawPixelImage(); }); document.getElementById("opacityRange").addEventListener("input", (e) => { opacity = e.target.value / 100; document.getElementById("opacityVal").innerText = `${e.target.value}%`; drawPixelImage(); }); document.getElementById("imgFile").addEventListener("change", (e) => { const file = e.target.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = function(ev) { img.src = ev.target.result; }; reader.readAsDataURL(file); }); img.onload = drawPixelImage; function drawPixelImage() { if (!img.complete) return; octx.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT); const tempCanvas = document.createElement("canvas"); tempCanvas.width = img.width; tempCanvas.height = img.height; const tctx = tempCanvas.getContext("2d"); tctx.imageSmoothingEnabled = false; tctx.drawImage(img, 0, 0); const data = tctx.getImageData(0, 0, img.width, img.height).data; for (let y = 0; y < img.height; y++) { for (let x = 0; x < img.width; x++) { const i = (y * img.width + x) * 4; const r = data[i]; const g = data[i + 1]; const b = data[i + 2]; const a = data[i + 3] * opacity; if (a === 0) continue; const [nr, ng, nb] = nearestPaletteColor(r, g, b); octx.fillStyle = `rgba(${nr},${ng},${nb},${a / 255})`; octx.fillRect(offsetX + x * pixelSize, offsetY + y * pixelSize, pixelSize, pixelSize); } } document.getElementById("xCoord").value = Math.round(offsetX); document.getElementById("yCoord").value = Math.round(offsetY); } // Перемещение оверлея let isDraggingOverlay = false, startX, startY; overlayCanvas.addEventListener("mousedown", (e) => { isDraggingOverlay = true; startX = e.clientX; startY = e.clientY; }); window.addEventListener("mousemove", (e) => { if (!isDraggingOverlay) return; const dx = e.clientX - startX; const dy = e.clientY - startY; startX = e.clientX; startY = e.clientY; offsetX += dx; offsetY += dy; drawPixelImage(); }); window.addEventListener("mouseup", () => isDraggingOverlay = false); // Перемещение меню const menuHeader = document.getElementById("menuHeader"); let isDraggingMenu = false, menuStartX, menuStartY, menuOffsetX, menuOffsetY; menuHeader.addEventListener("mousedown", (e) => { isDraggingMenu = true; menuStartX = e.clientX; menuStartY = e.clientY; const rect = menu.getBoundingClientRect(); menuOffsetX = menuStartX - rect.left; menuOffsetY = menuStartY - rect.top; e.preventDefault(); }); window.addEventListener("mousemove", (e) => { if (!isDraggingMenu) return; menu.style.left = (e.clientX - menuOffsetX) + "px"; menu.style.top = (e.clientY - menuOffsetY) + "px"; menu.style.right = "auto"; }); window.addEventListener("mouseup", () => isDraggingMenu = false); })();