Pixelplace.io tuvalinde WebSocket üzerinden hızlı piksel yerleştirme ve görsel aktarımı sağlayan gelişmiş otomasyon botu.
// ==UserScript==
// @name Wipo
// @namespace http://tampermonkey.net/
// @version 2.0.3
// @description Pixelplace.io tuvalinde WebSocket üzerinden hızlı piksel yerleştirme ve görsel aktarımı sağlayan gelişmiş otomasyon botu.
// @author Kiwe
// @match https://pixelplace.io/*
// @icon https://pixelplace.io/favicon.ico
// @require https://pixelplace.io/js/jquery.min.js?v2=1
// @grant GM_xmlhttpRequest
// @grant GM_addStyle
// @grant GM_setValue
// @grant GM_getValue
// @connect pixelplace.io
// @run-at document-end
// ==/UserScript==
(function() {
'use strict';
console.log('[Wipo] v2.0.3 by Kiwe — Pixelplace.io bot loaded.');
// ----- 64 RENK PALET -----
var PALETTE = [
[0, 0, 0], [29, 43, 83], [126, 37, 83], [0, 135, 81],
[171, 82, 54], [95, 87, 79], [194, 195, 199], [255, 241, 231],
[255, 0, 77], [255, 163, 0], [255, 236, 39], [0, 228, 54],
[41, 173, 255], [131, 118, 255], [255, 119, 168], [255, 204, 170],
[34, 34, 34], [76, 82, 106], [216, 76, 120], [67, 179, 113],
[208, 120, 86], [138, 131, 123], [223, 223, 223], [255, 248, 240],
[255, 80, 120], [255, 190, 40], [255, 236, 39], [0, 228, 54],
[80, 200, 255], [170, 160, 255], [255, 160, 190], [255, 220, 200],
[50, 50, 50], [100, 100, 100], [150, 150, 150], [200, 200, 200],
[255, 100, 100], [100, 255, 100], [100, 100, 255], [255, 255, 100],
[255, 100, 255], [100, 255, 255], [200, 150, 100], [150, 200, 100],
[100, 150, 200], [200, 100, 150], [150, 100, 200], [100, 200, 150],
[200, 200, 150], [150, 200, 200], [200, 150, 200], [150, 150, 200],
[255, 200, 150], [150, 255, 200], [200, 150, 255], [150, 200, 255],
[255, 150, 200], [200, 255, 150], [150, 255, 200], [255, 200, 100],
[100, 200, 255], [200, 100, 255], [255, 100, 200], [200, 255, 100]
];
// ----- ORTAK PIXEL TYPE -----
function determinePixelType(x, y, color, type) {
type = type || 'default';
var types = {
default: '[' + x + ',' + y + ',' + color + ',1]',
protect: '[' + x + ',' + y + ',' + color + ',1,1]',
seaprotect: '[' + x + ',' + y + ',-100,1,1]',
unprotect: '[' + x + ',' + y + ',' + color + ',1,2]',
replace: '[' + x + ',' + y + ',' + color + ',1,3]'
};
if (!(type in types)) type = 'default';
return types[type];
}
// ----- DITHERING (SINIR KONTROLLU) -----
var DITHER = {
none: function() {},
floyd: function(errR, errG, errB, x, y, w, h, data) {
var eR = errR / 16, eG = errG / 16, eB = errB / 16;
var i = (y * w + x) * 4;
if (x + 1 < w && i + 4 < data.length) {
data[i+4] += eR * 7; data[i+5] += eG * 7; data[i+6] += eB * 7;
}
if (y + 1 < h) {
var j = ((y + 1) * w + x) * 4;
if (j < data.length) {
if (x > 0 && j - 4 >= 0) {
data[j-4] += eR * 3; data[j-3] += eG * 3; data[j-2] += eB * 3;
}
data[j] += eR * 5; data[j+1] += eG * 5; data[j+2] += eB * 5;
if (x + 1 < w && j + 4 < data.length) {
data[j+4] += eR; data[j+5] += eG; data[j+6] += eB;
}
}
}
},
falsefloyd: function(errR, errG, errB, x, y, w, h, data) {
var eR = errR / 16, eG = errG / 16, eB = errB / 16;
if (y + 1 < h) {
var j = ((y + 1) * w + x) * 4;
if (j < data.length) {
data[j] += eR * 8; data[j+1] += eG * 8; data[j+2] += eB * 8;
if (x + 1 < w && j + 4 < data.length) {
data[j+4] += eR * 8; data[j+5] += eG * 8; data[j+6] += eB * 8;
}
}
}
},
stucki: function(errR, errG, errB, x, y, w, h, data) {
var eR = errR / 42, eG = errG / 42, eB = errB / 42;
var i = (y * w + x) * 4;
if (x + 1 < w && i + 4 < data.length) {
data[i+4] += eR * 8; data[i+5] += eG * 8; data[i+6] += eB * 8;
}
if (x + 2 < w && i + 8 < data.length) {
data[i+8] += eR * 4; data[i+9] += eG * 4; data[i+10] += eB * 4;
}
if (y + 1 < h) {
var j = ((y + 1) * w + x) * 4;
if (j < data.length) {
if (x > 1 && j - 8 >= 0) {
data[j-8] += eR * 2; data[j-7] += eG * 2; data[j-6] += eB * 2;
}
if (x > 0 && j - 4 >= 0) {
data[j-4] += eR * 4; data[j-3] += eG * 4; data[j-2] += eB * 4;
}
data[j] += eR * 8; data[j+1] += eG * 8; data[j+2] += eB * 8;
if (x + 1 < w && j + 4 < data.length) {
data[j+4] += eR * 4; data[j+5] += eG * 4; data[j+6] += eB * 4;
}
if (x + 2 < w && j + 8 < data.length) {
data[j+8] += eR * 2; data[j+9] += eG * 2; data[j+10] += eB * 2;
}
}
}
if (y + 2 < h) {
var k = ((y + 2) * w + x) * 4;
if (k < data.length) {
if (x > 1 && k - 8 >= 0) {
data[k-8] += eR; data[k-7] += eG; data[k-6] += eB;
}
if (x > 0 && k - 4 >= 0) {
data[k-4] += eR * 2; data[k-3] += eG * 2; data[k-2] += eB * 2;
}
data[k] += eR * 4; data[k+1] += eG * 4; data[k+2] += eB * 4;
if (x + 1 < w && k + 4 < data.length) {
data[k+4] += eR * 2; data[k+5] += eG * 2; data[k+6] += eB * 2;
}
if (x + 2 < w && k + 8 < data.length) {
data[k+8] += eR; data[k+9] += eG; data[k+10] += eB;
}
}
}
},
atkinson: function(errR, errG, errB, x, y, w, h, data) {
var eR = errR / 8, eG = errG / 8, eB = errB / 8;
var i = (y * w + x) * 4;
if (x + 1 < w && i + 4 < data.length) {
data[i+4] += eR; data[i+5] += eG; data[i+6] += eB;
}
if (x + 2 < w && i + 8 < data.length) {
data[i+8] += eR; data[i+9] += eG; data[i+10] += eB;
}
if (y + 1 < h) {
var j = ((y + 1) * w + x) * 4;
if (j < data.length) {
if (x > 0 && j - 4 >= 0) {
data[j-4] += eR; data[j-3] += eG; data[j-2] += eB;
}
data[j] += eR; data[j+1] += eG; data[j+2] += eB;
if (x + 1 < w && j + 4 < data.length) {
data[j+4] += eR; data[j+5] += eG; data[j+6] += eB;
}
}
}
if (y + 2 < h) {
var k = ((y + 2) * w + x) * 4;
if (k < data.length) {
data[k] += eR; data[k+1] += eG; data[k+2] += eB;
}
}
},
jarvis: function(errR, errG, errB, x, y, w, h, data) {
var eR = errR / 48, eG = errG / 48, eB = errB / 48;
var i = (y * w + x) * 4;
if (x + 1 < w && i + 4 < data.length) {
data[i+4] += eR * 7; data[i+5] += eG * 7; data[i+6] += eB * 7;
}
if (x + 2 < w && i + 8 < data.length) {
data[i+8] += eR * 5; data[i+9] += eG * 5; data[i+10] += eB * 5;
}
if (y + 1 < h) {
var j = ((y + 1) * w + x) * 4;
if (j < data.length) {
if (x > 2 && j - 12 >= 0) {
data[j-12] += eR * 3; data[j-11] += eG * 3; data[j-10] += eB * 3;
}
if (x > 1 && j - 8 >= 0) {
data[j-8] += eR * 5; data[j-7] += eG * 5; data[j-6] += eB * 5;
}
if (x > 0 && j - 4 >= 0) {
data[j-4] += eR * 7; data[j-3] += eG * 7; data[j-2] += eB * 7;
}
data[j] += eR * 5; data[j+1] += eG * 5; data[j+2] += eB * 5;
if (x + 1 < w && j + 4 < data.length) {
data[j+4] += eR * 3; data[j+5] += eG * 3; data[j+6] += eB * 3;
}
if (x + 2 < w && j + 8 < data.length) {
data[j+8] += eR; data[j+9] += eG; data[j+10] += eB;
}
}
}
if (y + 2 < h) {
var k = ((y + 2) * w + x) * 4;
if (k < data.length) {
if (x > 2 && k - 12 >= 0) {
data[k-12] += eR; data[k-11] += eG; data[k-10] += eB;
}
if (x > 1 && k - 8 >= 0) {
data[k-8] += eR * 3; data[k-7] += eG * 3; data[k-6] += eB * 3;
}
if (x > 0 && k - 4 >= 0) {
data[k-4] += eR * 5; data[k-3] += eG * 5; data[k-2] += eB * 5;
}
data[k] += eR * 3; data[k+1] += eG * 3; data[k+2] += eB * 3;
if (x + 1 < w && k + 4 < data.length) {
data[k+4] += eR; data[k+5] += eG; data[k+6] += eB;
}
}
}
},
burkes: function(errR, errG, errB, x, y, w, h, data) {
var eR = errR / 32, eG = errG / 32, eB = errB / 32;
var i = (y * w + x) * 4;
if (x + 1 < w && i + 4 < data.length) {
data[i+4] += eR * 8; data[i+5] += eG * 8; data[i+6] += eB * 8;
}
if (x + 2 < w && i + 8 < data.length) {
data[i+8] += eR * 4; data[i+9] += eG * 4; data[i+10] += eB * 4;
}
if (y + 1 < h) {
var j = ((y + 1) * w + x) * 4;
if (j < data.length) {
if (x > 1 && j - 8 >= 0) {
data[j-8] += eR * 2; data[j-7] += eG * 2; data[j-6] += eB * 2;
}
if (x > 0 && j - 4 >= 0) {
data[j-4] += eR * 4; data[j-3] += eG * 4; data[j-2] += eB * 4;
}
data[j] += eR * 8; data[j+1] += eG * 8; data[j+2] += eB * 8;
if (x + 1 < w && j + 4 < data.length) {
data[j+4] += eR * 4; data[j+5] += eG * 4; data[j+6] += eB * 4;
}
if (x + 2 < w && j + 8 < data.length) {
data[j+8] += eR * 2; data[j+9] += eG * 2; data[j+10] += eB * 2;
}
}
}
},
sierra: function(errR, errG, errB, x, y, w, h, data) {
var eR = errR / 32, eG = errG / 32, eB = errB / 32;
var i = (y * w + x) * 4;
if (x + 1 < w && i + 4 < data.length) {
data[i+4] += eR * 5; data[i+5] += eG * 5; data[i+6] += eB * 5;
}
if (x + 2 < w && i + 8 < data.length) {
data[i+8] += eR * 3; data[i+9] += eG * 3; data[i+10] += eB * 3;
}
if (y + 1 < h) {
var j = ((y + 1) * w + x) * 4;
if (j < data.length) {
if (x > 1 && j - 8 >= 0) {
data[j-8] += eR * 2; data[j-7] += eG * 2; data[j-6] += eB * 2;
}
if (x > 0 && j - 4 >= 0) {
data[j-4] += eR * 4; data[j-3] += eG * 4; data[j-2] += eB * 4;
}
data[j] += eR * 5; data[j+1] += eG * 5; data[j+2] += eB * 5;
if (x + 1 < w && j + 4 < data.length) {
data[j+4] += eR * 4; data[j+5] += eG * 4; data[j+6] += eB * 4;
}
if (x + 2 < w && j + 8 < data.length) {
data[j+8] += eR * 2; data[j+9] += eG * 2; data[j+10] += eB * 2;
}
}
}
if (y + 2 < h) {
var k = ((y + 2) * w + x) * 4;
if (k < data.length) {
if (x > 0 && k - 4 >= 0) {
data[k-4] += eR * 2; data[k-3] += eG * 2; data[k-2] += eB * 2;
}
data[k] += eR * 3; data[k+1] += eG * 3; data[k+2] += eB * 3;
if (x + 1 < w && k + 4 < data.length) {
data[k+4] += eR * 2; data[k+5] += eG * 2; data[k+6] += eB * 2;
}
}
}
}
};
// ----- SORTING -----
var SORT_FUNCTIONS = {
none: function(arr) { return arr; },
rand: function(arr) {
var shuffled = arr.slice();
for (var i = shuffled.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = shuffled[i];
shuffled[i] = shuffled[j];
shuffled[j] = temp;
}
return shuffled;
},
colors: function(arr) { var a = arr.slice(); a.sort(function(a, b) { return a.color - b.color; }); return a; },
vertical: function(arr) { var a = arr.slice(); a.sort(function(a, b) { return a.x - b.x; }); return a; },
horizontal: function(arr) { var a = arr.slice(); a.sort(function(a, b) { return a.y - b.y; }); return a; },
topleft: function(arr) { var a = arr.slice(); a.sort(function(a, b) { return (a.x + a.y) - (b.x + b.y); }); return a; },
grid: function(arr) {
var rows = {};
arr.forEach(function(p) {
if (!rows[p.y]) rows[p.y] = [];
rows[p.y].push(p);
});
var result = [];
var sortedRows = Object.keys(rows).sort(function(a, b) { return parseInt(a) - parseInt(b); });
sortedRows.forEach(function(y, idx) {
var row = rows[y];
if (idx % 2 === 0) row.sort(function(a, b) { return a.x - b.x; });
else row.sort(function(a, b) { return b.x - a.x; });
result = result.concat(row);
});
return result;
},
circle: function(arr) {
var a = arr.slice();
var cx = a.reduce(function(s, p) { return s + p.x; }, 0) / a.length;
var cy = a.reduce(function(s, p) { return s + p.y; }, 0) / a.length;
a.sort(function(a, b) {
return Math.hypot(a.x - cx, a.y - cy) - Math.hypot(b.x - cx, b.y - cy);
});
return a;
}
};
// ----- YARDIMCILAR -----
function nearestPaletteColor(r, g, b) {
var minDist = Infinity, best = 0;
for (var i = 0; i < PALETTE.length; i++) {
var pr = PALETTE[i][0], pg = PALETTE[i][1], pb = PALETTE[i][2];
var dr = r - pr, dg = g - pg, db = b - pb;
var dist = dr*dr + dg*dg + db*db;
if (dist < minDist) { minDist = dist; best = i; }
}
return best;
}
function getCanvasCoords(clientX, clientY) {
var canvas = document.querySelector('canvas');
if (!canvas) return { x: 0, y: 0 };
var rect = canvas.getBoundingClientRect();
var scaleX = canvas.width / rect.width;
var scaleY = canvas.height / rect.height;
var x = Math.round((clientX - rect.left) * scaleX);
var y = Math.round((clientY - rect.top) * scaleY);
x = Math.max(0, Math.min(canvas.width - 1, x));
y = Math.max(0, Math.min(canvas.height - 1, y));
return { x: x, y: y };
}
// ----- WEBSOCKET -----
window.wipo = {
pixelspeed: 17,
queue: [],
inprogress: false,
protect: false,
tickspeed: 1000,
order: 'circle',
dither: null,
agressive_protection: false,
pixel_type: 'default',
ws: null,
wsReady: false,
wsReconnectTimer: null
};
var wsHookActive = false;
function hookWebSocket() {
if (wsHookActive) return;
wsHookActive = true;
var unmodifiedWS = window.WebSocket;
window.WebSocket = function(url, protocols) {
var socket = new unmodifiedWS(url, protocols);
if (url && url.includes('pixelplace.io')) {
console.log('[Wipo] WebSocket intercepted.');
socket.addEventListener('open', function() {
console.log('[Wipo] WebSocket opened.');
window.wipo.ws = socket;
window.wipo.wsReady = true;
if (window.wipo.wsReconnectTimer) {
clearTimeout(window.wipo.wsReconnectTimer);
window.wipo.wsReconnectTimer = null;
}
});
socket.addEventListener('close', function() {
console.log('[Wipo] WebSocket closed.');
window.wipo.wsReady = false;
if (!window.wipo.wsReconnectTimer) {
window.wipo.wsReconnectTimer = setTimeout(function() {
console.log('[Wipo] Attempting to reconnect WebSocket...');
hookWebSocket();
}, 3000);
}
});
socket.addEventListener('error', function() {
console.log('[Wipo] WebSocket error.');
window.wipo.wsReady = false;
});
}
return socket;
};
window.WebSocket.prototype = unmodifiedWS.prototype;
}
hookWebSocket();
// ----- BOT SINIFI -----
function WipoBot() {
var self = this;
self.lastPlace = 0;
self.queue = [];
self.isRunning = false;
self.isProcessing = false;
self.placedCount = 0;
self.totalPixels = 0;
self.pixelSpeed = 17;
self.protectMode = false;
self.aggressiveProtect = false;
self.protectedPixels = new Map();
self.canvasCache = null;
self.ppsCounter = 0;
self.ppsInterval = null;
self.startTime = 0;
self.priorityAreas = [];
self.ditherType = 'none';
self.sortType = 'circle';
self.pixelType = 'default';
self.currentImageData = null;
self.startX = 0;
self.startY = 0;
self.diffCheck = false;
self.protectTimer = null;
self.isProcessingImage = false;
self.canvasWidth = 0;
self.canvasHeight = 0;
self.totalSent = 0;
self.totalFailed = 0;
self.isPaused = false;
}
var bot = null;
WipoBot.prototype.processImage = async function(imageData, startX, startY, ditherType, enableDiff) {
var self = this;
var data = imageData.data, width = imageData.width, height = imageData.height;
var result = [];
var w = width, h = height;
var workData = new Uint8ClampedArray(data);
var ditherFn = DITHER[ditherType] || DITHER.none;
var BATCH_SIZE = 5000;
var canvas = document.querySelector('canvas');
if (canvas) {
self.canvasWidth = canvas.width;
self.canvasHeight = canvas.height;
}
self.isProcessingImage = true;
for (var y = 0; y < h; y++) {
for (var x = 0; x < w; x++) {
var idx = (y * w + x) * 4;
if (idx + 3 >= workData.length) continue;
var r = workData[idx];
var g = workData[idx + 1];
var b = workData[idx + 2];
var a = workData[idx + 3];
if (a < 128) continue;
var colorIdx = nearestPaletteColor(r, g, b);
var pr = PALETTE[colorIdx][0], pg = PALETTE[colorIdx][1], pb = PALETTE[colorIdx][2];
var errR = r - pr;
var errG = g - pg;
var errB = b - pb;
if (ditherType !== 'none') {
ditherFn(errR, errG, errB, x, y, w, h, workData);
}
var px = startX + x;
var py = startY + y;
if (px < 0 || py < 0 || px >= self.canvasWidth || py >= self.canvasHeight) {
continue;
}
if (enableDiff && !self.checkPixelDiff(px, py, colorIdx)) continue;
result.push({ x: px, y: py, color: colorIdx });
if (result.length % BATCH_SIZE === 0) {
await new Promise(function(r) { setTimeout(r, 0); });
}
}
}
self.isProcessingImage = false;
console.log('[Wipo] ' + result.length + ' pixels processed.');
return result;
};
WipoBot.prototype.checkPixelDiff = function(x, y, color) {
var self = this;
try {
if (!self.canvasCache) {
var canvas = document.querySelector('canvas');
if (!canvas) return true;
var ctx = canvas.getContext('2d');
self.canvasCache = ctx.getImageData(0, 0, canvas.width, canvas.height);
}
var idx = (y * self.canvasCache.width + x) * 4;
if (idx + 3 >= self.canvasCache.data.length) return true;
var pr = PALETTE[color][0], pg = PALETTE[color][1], pb = PALETTE[color][2];
var dr = self.canvasCache.data[idx] - pr;
var dg = self.canvasCache.data[idx + 1] - pg;
var db = self.canvasCache.data[idx + 2] - pb;
return (dr*dr + dg*dg + db*db) > 10;
} catch(e) { return true; }
};
WipoBot.prototype.updateCache = function() {
var self = this;
try {
var canvas = document.querySelector('canvas');
if (!canvas) return;
var ctx = canvas.getContext('2d');
self.canvasCache = ctx.getImageData(0, 0, canvas.width, canvas.height);
} catch(e) {}
};
// ----- SEND PIXEL (DUZELTILDI - DOGRUDAN wipo.ws KULLANIR) -----
WipoBot.prototype.sendPixel = async function(x, y, color, type) {
var self = this;
type = type || 'default';
var wipo = window.wipo;
// DOGRUDAN wipo.ws KONTROL
if (!wipo.wsReady || !wipo.ws || wipo.ws.readyState !== WebSocket.OPEN) {
console.log('[Wipo] WebSocket connection lost.');
self.totalFailed++;
return false;
}
var canvas = document.querySelector('canvas');
if (canvas) {
if (x < 0 || y < 0 || x >= canvas.width || y >= canvas.height) {
console.log('[Wipo] Invalid coordinates: (' + x + ', ' + y + ')');
self.totalFailed++;
return false;
}
}
var now = performance.now();
var elapsed = now - self.lastPlace;
var waitTime = self.pixelSpeed - elapsed;
if (waitTime > 0) {
await new Promise(function(r) { setTimeout(r, waitTime); });
}
try {
var pixelParam = determinePixelType(x, y, color, type);
wipo.ws.send('42["p",' + pixelParam + ']');
self.lastPlace = performance.now();
self.ppsCounter++;
self.totalSent++;
if (self.totalSent % 10 === 0) {
self.updateCache();
}
return true;
} catch(e) {
console.error('[Wipo] Send error:', e);
self.totalFailed++;
return false;
}
};
// ----- START (DUZELTILDI) -----
WipoBot.prototype.start = async function() {
var self = this;
var wipo = window.wipo;
if (wipo.inprogress) {
console.log('[Wipo] Already running.');
return;
}
// DOGRUDAN wipo.ws KONTROL
if (!wipo.wsReady || !wipo.ws || wipo.ws.readyState !== WebSocket.OPEN) {
console.log('[Wipo] WebSocket not ready, waiting...');
setTimeout(function() { self.start(); }, 1000);
return;
}
if (!self.currentImageData && self.queue.length === 0) {
alert('Please load an image or create a square.');
return;
}
if (self.currentImageData) {
self.updateStatus('Processing image...');
var processed = await self.processImage(
self.currentImageData,
self.startX,
self.startY,
self.ditherType,
self.diffCheck
);
var sorted = SORT_FUNCTIONS[self.sortType] ? SORT_FUNCTIONS[self.sortType](processed) : processed;
self.queue = self.applyPriorityAreas(sorted);
}
if (self.queue.length === 0) {
alert('No pixels to draw.');
return;
}
self.totalPixels = self.queue.length;
self.placedCount = 0;
self.totalSent = 0;
self.totalFailed = 0;
wipo.inprogress = true;
self.startTime = Date.now();
self.ppsCounter = 0;
self.updateStatus('Drawing started (' + self.queue.length + ' pixels)');
console.log('[Wipo] Drawing started, total: ' + self.queue.length + ' pixels');
if (self.ppsInterval) clearInterval(self.ppsInterval);
self.ppsInterval = setInterval(function() {
var elapsed = (Date.now() - self.startTime) / 1000;
var pps = elapsed > 0 ? Math.round(self.ppsCounter / elapsed) : 0;
var percent = self.totalPixels > 0 ? Math.round((self.placedCount / self.totalPixels) * 100) : 0;
self.updateStats('PPS: ' + pps + ' | ' + self.placedCount + '/' + self.totalPixels + ' (' + percent + '%) | Failed: ' + self.totalFailed);
}, 1000);
self.processQueue();
};
WipoBot.prototype.processQueue = async function() {
var self = this;
var wipo = window.wipo;
while (wipo.inprogress && self.queue.length > 0) {
if (!wipo.inprogress || self.isPaused) {
await new Promise(function(r) { setTimeout(r, 100); });
continue;
}
// WS kontrol
if (!wipo.wsReady || !wipo.ws || wipo.ws.readyState !== WebSocket.OPEN) {
console.log('[Wipo] WebSocket lost, pausing...');
self.isPaused = true;
await new Promise(function(r) { setTimeout(r, 2000); });
self.isPaused = false;
continue;
}
var pixel = self.queue[0];
if (!self.canvasCache) {
self.updateCache();
}
if (self.canvasCache) {
var idx = (pixel.y * self.canvasCache.width + pixel.x) * 4;
if (idx + 3 < self.canvasCache.data.length) {
var pr = PALETTE[pixel.color][0], pg = PALETTE[pixel.color][1], pb = PALETTE[pixel.color][2];
var dr = self.canvasCache.data[idx] - pr;
var dg = self.canvasCache.data[idx + 1] - pg;
var db = self.canvasCache.data[idx + 2] - pb;
if (dr*dr + dg*dg + db*db < 10 && self.pixelType === 'default') {
self.queue.shift();
self.placedCount++;
continue;
}
}
}
var success = await self.sendPixel(pixel.x, pixel.y, pixel.color, self.pixelType);
if (success) {
self.queue.shift();
self.placedCount++;
if (self.protectMode || self.pixelType === 'protect') {
self.protectedPixels.set(pixel.x + ',' + pixel.y, pixel.color);
}
} else {
var retry = 0;
var retrySuccess = false;
while (retry < 3 && !retrySuccess) {
await new Promise(function(r) { setTimeout(r, 50); });
retrySuccess = await self.sendPixel(pixel.x, pixel.y, pixel.color, self.pixelType);
retry++;
}
if (retrySuccess) {
self.queue.shift();
self.placedCount++;
} else {
self.queue.shift();
console.log('[Wipo] Pixel (' + pixel.x + ',' + pixel.y + ') skipped.');
}
}
var remaining = self.queue.length;
var percent = self.totalPixels > 0 ? Math.round((self.placedCount / self.totalPixels) * 100) : 0;
self.updateStatus('Progress: ' + self.placedCount + '/' + self.totalPixels + ' (' + percent + '%) | ' + remaining + ' remaining');
await new Promise(function(r) { setTimeout(r, 1); });
}
if (self.queue.length === 0 && wipo.inprogress) {
wipo.inprogress = false;
self.updateStatus('Completed! (' + self.placedCount + ' pixels, ' + self.totalFailed + ' failed)');
if (self.ppsInterval) clearInterval(self.ppsInterval);
console.log('[Wipo] Drawing completed. Total: ' + self.totalSent + ', Failed: ' + self.totalFailed);
}
};
WipoBot.prototype.stop = function() {
var self = this;
var wipo = window.wipo;
wipo.inprogress = false;
self.isPaused = false;
self.queue = [];
if (self.ppsInterval) clearInterval(self.ppsInterval);
self.updateStatus('Stopped.');
console.log('[Wipo] Drawing stopped.');
};
WipoBot.prototype.createSquare = function(x1, y1, x2, y2, colorId) {
var self = this;
var q = [];
var minX = Math.min(x1, x2), maxX = Math.max(x1, x2);
var minY = Math.min(y1, y2), maxY = Math.max(y1, y2);
var canvas = document.querySelector('canvas');
var maxW = canvas ? canvas.width : Infinity;
var maxH = canvas ? canvas.height : Infinity;
for (var y = minY; y <= maxY; y++) {
for (var x = minX; x <= maxX; x++) {
if (x >= 0 && y >= 0 && x < maxW && y < maxH) {
q.push({ x: x, y: y, color: colorId });
}
}
}
self.queue = q;
self.updateStatus('Square: ' + q.length + ' pixels (' + x1 + ',' + y1 + ') - (' + x2 + ',' + y2 + ')');
var wipo = window.wipo;
if (wipo.inprogress) {
self.processQueue();
}
};
WipoBot.prototype.applyPriorityAreas = function(queue) {
var self = this;
if (self.priorityAreas.length === 0) return queue;
var priority = [];
var normal = [];
for (var i = 0; i < queue.length; i++) {
var pixel = queue[i];
var isPriority = false;
for (var j = 0; j < self.priorityAreas.length; j++) {
var area = self.priorityAreas[j];
if (pixel.x >= area.x1 && pixel.x <= area.x2 &&
pixel.y >= area.y1 && pixel.y <= area.y2) {
isPriority = true;
break;
}
}
if (isPriority) priority.push(pixel);
else normal.push(pixel);
}
return priority.concat(normal);
};
WipoBot.prototype.startProtect = function() {
var self = this;
if (self.protectTimer) clearInterval(self.protectTimer);
self.protectTimer = setInterval(function() {
if (!self.protectMode || !window.wipo.inprogress) return;
self.updateCache();
if (self.aggressiveProtect) {
var toRepair = [];
var iter = self.protectedPixels.entries();
var entry = iter.next();
while (!entry.done) {
var key = entry.value[0];
var color = entry.value[1];
var coords = key.split(',').map(Number);
var x = coords[0], y = coords[1];
if (!self.checkPixelDiff(x, y, color)) {
toRepair.push({ x: x, y: y, color: color });
}
entry = iter.next();
}
if (toRepair.length > 0) {
self.queue = toRepair.concat(self.queue);
self.updateStatus('Protection: ' + toRepair.length + ' pixels added to queue.');
}
}
}, 3000);
};
WipoBot.prototype.updateStatus = function(text) {
var el = document.getElementById('statusText');
if (el) el.innerText = text;
};
WipoBot.prototype.updateStats = function(text) {
var el = document.getElementById('statsText');
if (el) el.innerText = text;
};
bot = new WipoBot();
// ----- GORSEL YUKLEME -----
function loadImage(file) {
if (!file) return;
var reader = new FileReader();
reader.onload = function(e) {
var img = new Image();
img.onload = function() {
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var width = img.width, height = img.height;
var maxDim = 500;
if (width > maxDim || height > maxDim) {
var ratio = Math.min(maxDim / width, maxDim / height);
width = Math.floor(width * ratio);
height = Math.floor(height * ratio);
}
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
bot.currentImageData = ctx.getImageData(0, 0, width, height);
updateOverlay();
bot.updateStatus('Image loaded: ' + width + 'x' + height);
};
img.src = e.target.result;
};
reader.readAsDataURL(file);
}
// ----- OVERLAY -----
var overlayImg = null;
function createOverlay() {
var old = document.getElementById('wipo-overlay');
if (old) old.remove();
var div = document.createElement('div');
div.id = 'wipo-overlay';
div.style.cssText = 'position:absolute;pointer-events:none;top:0;left:0;width:100%;height:100%;z-index:500;display:none;overflow:hidden';
overlayImg = document.createElement('img');
overlayImg.style.cssText = 'position:absolute;opacity:0.35;pointer-events:none;image-rendering:pixelated';
div.appendChild(overlayImg);
var container = document.querySelector('#painting-move');
if (container) {
container.style.position = 'relative';
container.appendChild(div);
} else {
document.body.appendChild(div);
}
}
function updateOverlay() {
if (!overlayImg) createOverlay();
if (!overlayImg || !bot.currentImageData) {
if (overlayImg) overlayImg.parentElement.style.display = 'none';
return;
}
var sx = parseInt(document.getElementById('startX') ? document.getElementById('startX').value : 0) || 0;
var sy = parseInt(document.getElementById('startY') ? document.getElementById('startY').value : 0) || 0;
bot.startX = sx;
bot.startY = sy;
var canvas = document.createElement('canvas');
canvas.width = bot.currentImageData.width;
canvas.height = bot.currentImageData.height;
canvas.getContext('2d').putImageData(bot.currentImageData, 0, 0);
overlayImg.src = canvas.toDataURL();
overlayImg.style.left = sx + 'px';
overlayImg.style.top = sy + 'px';
overlayImg.style.width = bot.currentImageData.width + 'px';
overlayImg.style.height = bot.currentImageData.height + 'px';
overlayImg.parentElement.style.display = 'block';
document.getElementById('overlayToggle').innerHTML = 'Gizle';
}
function toggleOverlay() {
if (!overlayImg) createOverlay();
var visible = overlayImg.parentElement.style.display !== 'none';
overlayImg.parentElement.style.display = visible ? 'none' : 'block';
document.getElementById('overlayToggle').innerHTML = visible ? 'Goster' : 'Gizle';
if (!visible) updateOverlay();
}
// ----- MOUSE KOORDINAT -----
window._wipoMouseX = 0;
window._wipoMouseY = 0;
// ----- MENU VE GUI -----
function createUI() {
GM_addStyle(`
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
:root { --gui-main-color: #7300ff; }
#wipo-menu-btn {
position:fixed;left:10px;top:50%;transform:translateY(-50%);
background:#1a1f2e;border:2px solid #7300ff;border-radius:8px;
padding:12px 6px;color:#eaeef5;z-index:10001;cursor:pointer;
font-family:'Inter',sans-serif;font-size:14px;font-weight:700;
writing-mode:vertical-lr;letter-spacing:2px;
box-shadow:0 4px 20px rgba(0,0,0,0.8);
transition:all 0.3s ease;user-select:none;
background:linear-gradient(180deg,#1a1f2e,#0d111c);
}
#wipo-menu-btn:hover { transform:translateY(-50%) scale(1.05); background:#2a2f3e; }
#wipo-panel {
position:fixed;left:60px;top:50%;transform:translateY(-50%);
background:#141a28;border:1px solid #2f3a55;border-radius:20px;
padding:0;color:#eaeef5;font-family:'Inter',sans-serif;
width:460px;max-height:85vh;overflow:hidden;
backdrop-filter:blur(12px);box-shadow:0 16px 40px rgba(0,0,0,0.8);
z-index:9999;font-size:13px;transition:0.3s ease;
display:flex;flex-direction:column;
}
#wipo-panel.hidden { display:none; }
.wipo-header {
padding:12px 20px 8px 20px;border-bottom:1px solid #1f2840;
display:flex;justify-content:space-between;align-items:center;
cursor:move;flex-shrink:0;background:#0d111c;
border-radius:20px 20px 0 0;
}
.wipo-header .title { font-weight:700;font-size:18px;color:var(--gui-main-color);font-family:Verdana,Tahoma,sans-serif; }
.wipo-header .version { font-weight:300;color:#5d6a84;font-size:11px;font-family:Verdana,Tahoma,sans-serif; }
.wipo-tabs {
display:flex;padding:0 16px;gap:4px;border-bottom:1px solid #1a1f2e;
flex-shrink:0;background:#0d111c;
}
.wipo-tab-btn {
padding:8px 16px;font-size:12px;font-weight:500;color:#5d6a84;
cursor:pointer;border:none;background:transparent;
border-radius:8px 8px 0 0;transition:0.2s;font-family:'Inter',sans-serif;
}
.wipo-tab-btn:hover { color:#c8d0e5;background:#1a1f2e; }
.wipo-tab-btn.active { color:var(--gui-main-color);background:#141a28; }
.wipo-body { padding:16px 20px;overflow-y:auto;flex:1;background:#141a28; }
.wipo-body::-webkit-scrollbar { width:4px; }
.wipo-body::-webkit-scrollbar-thumb { background:#3a4a6a;border-radius:10px; }
.wipo-tab-content { display:none;flex-direction:column;gap:10px; }
.wipo-tab-content.active { display:flex; }
.wipo-row { display:flex;gap:8px;flex-wrap:wrap;align-items:center; }
.wipo-row label { font-size:11px;color:#a5b1cc;min-width:40px;font-weight:500;font-family:'Inter',sans-serif; }
.wipo-row input,.wipo-row select {
background:#0b101c;border:1px solid #2a3450;border-radius:30px;
padding:6px 12px;color:white;font-size:12px;flex:1;min-width:40px;
font-family:'Inter',sans-serif;
}
.wipo-row input:focus,.wipo-row select:focus { outline:none;border-color:var(--gui-main-color);box-shadow:0 0 0 2px rgba(115,0,255,0.2); }
.wipo-row input[type="file"] { padding:4px 8px;background:#111a2a;flex:2;cursor:pointer; }
.wipo-row input[type="file"]::file-selector-button {
background:#2d3a55;border:none;border-radius:30px;padding:4px 16px;
color:white;font-weight:500;cursor:pointer;font-family:'Inter',sans-serif;
transition:0.2s;
}
.wipo-row input[type="file"]::file-selector-button:hover { background:#3f5280; }
.wipo-row input[type="checkbox"] { flex:0;min-width:auto;width:16px;height:16px;accent-color:var(--gui-main-color); }
.wipo-row button {
background:#2d3d62;border:none;border-radius:30px;padding:6px 16px;
color:white;font-weight:600;cursor:pointer;transition:0.15s;
flex:1;font-size:12px;font-family:'Inter',sans-serif;
}
.wipo-row button:hover { background:#3f5280;transform:scale(0.97); }
.wipo-row button:active { transform:scale(0.95); }
.wipo-row button.danger { background:#6d2e3a; }
.wipo-row button.danger:hover { background:#8f3b4a; }
.wipo-row button.success { background:#1f6d4a; }
.wipo-row button.success:hover { background:#2a8a5e; }
.wipo-row button.warning { background:#8a6d2a; }
.wipo-row button.warning:hover { background:#aa8830; }
.wipo-row button.purple { background:#4a2d7a; }
.wipo-row button.purple:hover { background:#5d3a9a; }
.wipo-row .small-btn { flex:0.4;padding:4px 10px;font-size:10px; }
.status {
background:#0b111e;padding:6px 14px;border-radius:30px;
font-size:11px;border:1px solid #232d44;color:#c8d0e5;
overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
font-family:'Inter',sans-serif;
}
.footer {
font-size:9px;color:#455470;text-align:right;padding:8px 20px;
border-top:1px solid #1a1f2e;flex-shrink:0;font-family:'Inter',sans-serif;
background:#0d111c;border-radius:0 0 20px 20px;
}
#inspectorText { font-size:10px;color:#88aacc; }
.wipo-section-title {
font-size:11px;font-weight:600;color:#5d6a84;
text-transform:uppercase;letter-spacing:0.5px;
margin:8px 0 4px 0;border-bottom:1px solid #1a1f2e;padding-bottom:4px;
}
#wipo-overlay { pointer-events:none; }
.wipo-row .flex-2 { flex:2; }
.wipo-row .flex-3 { flex:3; }
`);
// Menu Button
var menuBtn = document.createElement('div');
menuBtn.id = 'wipo-menu-btn';
menuBtn.textContent = 'WIPO';
menuBtn.title = 'Wipo Bot Show/Hide';
document.body.appendChild(menuBtn);
// Panel
var panel = document.createElement('div');
panel.id = 'wipo-panel';
panel.innerHTML = `
<div class="wipo-header" id="wipo-drag">
<span class="title">WIPO</span>
<span class="version">v2.0.3</span>
</div>
<div class="wipo-tabs">
<button class="wipo-tab-btn active" data-tab="botting">Botting</button>
<button class="wipo-tab-btn" data-tab="settings">Settings</button>
</div>
<div class="wipo-body">
<div class="wipo-tab-content active" id="tab-botting">
<div class="wipo-row">
<label>Start X</label>
<input type="number" id="startX" value="0" step="1" />
<label>Y</label>
<input type="number" id="startY" value="0" step="1" />
<button id="overlayToggle" class="small-btn purple">Show</button>
</div>
<div class="wipo-row">
<label>Speed</label>
<input type="number" id="speedInput" value="17" step="1" min="14" max="21" style="flex:0.5;" />
<span style="font-size:10px;color:#5d6a84;">14-21</span>
<label><input type="checkbox" id="diffCheck" /> Diff</label>
</div>
<div class="wipo-row">
<label>Image</label>
<input type="file" id="imageUpload" accept="image/*" />
</div>
<div class="wipo-row">
<label>Dither</label>
<select id="ditherSelect">
<option value="none">None</option>
<option value="floyd">Floyd-Steinberg</option>
<option value="falsefloyd">False Floyd</option>
<option value="stucki">Stucki</option>
<option value="atkinson">Atkinson</option>
<option value="jarvis">Jarvis</option>
<option value="burkes">Burkes</option>
<option value="sierra">Sierra</option>
</select>
</div>
<div class="wipo-row">
<label>Sort</label>
<select id="sortSelect">
<option value="none">None</option>
<option value="grid">Grid</option>
<option value="topleft">Top Left</option>
<option value="rand">Random</option>
<option value="colors">Colors</option>
<option value="vertical">Vertical</option>
<option value="horizontal">Horizontal</option>
<option value="circle">Circle</option>
</select>
</div>
<div class="wipo-row">
<label>Color ID</label>
<input type="number" id="squareColor" value="0" min="0" max="63" style="flex:0.5;" />
<button id="squareBtn" class="success small-btn">Square</button>
<button id="priorityBtn" class="warning small-btn">Priority</button>
</div>
<div class="wipo-row">
<label>Pixel Type</label>
<select id="pixelType" style="flex:0.8;">
<option value="default">Default</option>
<option value="protect">Protect</option>
<option value="unprotect">Unprotect</option>
<option value="replace">Replace</option>
</select>
</div>
<div class="wipo-row">
<button id="startBtn" class="success">Start</button>
<button id="stopBtn" class="danger">Stop</button>
<button id="protectBtn">Protect</button>
<button id="inspectorBtn">Inspect</button>
</div>
<div class="status" id="statusText">Ready</div>
<div class="status" id="statsText">PPS: 0 | 0/0 (0%)</div>
<div class="status" id="inspectorText">Hover over pixel</div>
</div>
<div class="wipo-tab-content" id="tab-settings">
<div class="wipo-section-title">Appearance</div>
<div class="wipo-row">
<label>Color</label>
<input type="color" id="themeColor" value="#7300ff" style="flex:0;width:50px;height:30px;padding:2px;" />
<button id="applyColorBtn" class="small-btn">Apply</button>
</div>
<div class="wipo-section-title">Data</div>
<div class="wipo-row">
<button id="clearProgressBtn" class="danger small-btn">Clear Progress</button>
</div>
<div class="footer" style="border:none;padding:8px 0 0 0;text-align:center;">
Hotkeys: B (coord) | X (square) | Alt+W (stop)
</div>
</div>
</div>
<div class="footer">Wipo v2.0.3 · Made By Kiwe</div>
`;
document.body.appendChild(panel);
// Drag
var dragHandle = document.getElementById('wipo-drag');
var isDragging = false, offsetX, offsetY;
dragHandle.addEventListener('mousedown', function(e) {
isDragging = true;
var rect = panel.getBoundingClientRect();
offsetX = e.clientX - rect.left;
offsetY = e.clientY - rect.top;
panel.style.transition = 'none';
});
document.addEventListener('mousemove', function(e) {
if (!isDragging) return;
panel.style.left = (e.clientX - offsetX) + 'px';
panel.style.top = (e.clientY - offsetY) + 'px';
panel.style.transform = 'none';
});
document.addEventListener('mouseup', function() {
isDragging = false;
panel.style.transition = '0.3s ease';
});
// Menu toggle
menuBtn.addEventListener('click', function() {
panel.classList.toggle('hidden');
menuBtn.style.borderColor = panel.classList.contains('hidden') ? '#ff4444' : '#7300ff';
});
// Tab switching
document.querySelectorAll('.wipo-tab-btn').forEach(function(btn) {
btn.addEventListener('click', function() {
document.querySelectorAll('.wipo-tab-content').forEach(function(el) { el.classList.remove('active'); });
document.querySelectorAll('.wipo-tab-btn').forEach(function(b) { b.classList.remove('active'); });
document.getElementById('tab-' + this.dataset.tab).classList.add('active');
this.classList.add('active');
});
});
// Overlay
createOverlay();
document.getElementById('overlayToggle').addEventListener('click', toggleOverlay);
// Input changes
document.getElementById('startX').addEventListener('change', updateOverlay);
document.getElementById('startY').addEventListener('change', updateOverlay);
// Speed
document.getElementById('speedInput').addEventListener('input', function() {
window.wipo.pixelspeed = Math.min(21, Math.max(14, parseInt(this.value) || 17));
bot.pixelSpeed = window.wipo.pixelspeed;
});
// Settings to bot
document.getElementById('ditherSelect').addEventListener('change', function() {
bot.ditherType = this.value;
});
document.getElementById('sortSelect').addEventListener('change', function() {
bot.sortType = this.value;
});
document.getElementById('pixelType').addEventListener('change', function() {
bot.pixelType = this.value;
window.wipo.pixel_type = this.value;
});
document.getElementById('diffCheck').addEventListener('change', function() {
bot.diffCheck = this.checked;
});
// Start
document.getElementById('startBtn').addEventListener('click', function() {
bot.startX = parseInt(document.getElementById('startX').value) || 0;
bot.startY = parseInt(document.getElementById('startY').value) || 0;
bot.pixelSpeed = window.wipo.pixelspeed;
bot.ditherType = document.getElementById('ditherSelect').value;
bot.sortType = document.getElementById('sortSelect').value;
bot.pixelType = document.getElementById('pixelType').value;
bot.diffCheck = document.getElementById('diffCheck').checked;
bot.start();
});
// Stop
document.getElementById('stopBtn').addEventListener('click', function() {
bot.stop();
});
// Image upload
document.getElementById('imageUpload').addEventListener('change', function(e) {
if (e.target.files[0]) loadImage(e.target.files[0]);
});
// Square
document.getElementById('squareBtn').addEventListener('click', function() {
var x1 = parseInt(document.getElementById('startX').value) || 0;
var y1 = parseInt(document.getElementById('startY').value) || 0;
var colorId = parseInt(document.getElementById('squareColor').value) || 0;
var mx = window._wipoMouseX || 0;
var my = window._wipoMouseY || 0;
var coords = getCanvasCoords(mx, my);
bot.createSquare(x1, y1, coords.x, coords.y, colorId);
});
// Priority
document.getElementById('priorityBtn').addEventListener('click', function() {
var x1 = parseInt(prompt('Priority area X1:')) || 0;
var y1 = parseInt(prompt('Priority area Y1:')) || 0;
var x2 = parseInt(prompt('Priority area X2:')) || 100;
var y2 = parseInt(prompt('Priority area Y2:')) || 100;
if (isNaN(x1) || isNaN(y1) || isNaN(x2) || isNaN(y2)) {
alert('Invalid coordinates. Please enter numbers.');
return;
}
bot.priorityAreas.push({ x1: x1, y1: y1, x2: x2, y2: y2 });
bot.updateStatus('Priority area added: (' + x1 + ',' + y1 + ') - (' + x2 + ',' + y2 + ')');
});
// Protect
document.getElementById('protectBtn').addEventListener('click', function() {
bot.protectMode = !bot.protectMode;
window.wipo.protect = bot.protectMode;
if (bot.protectMode) {
bot.aggressiveProtect = confirm('Enable aggressive protection?');
window.wipo.agressive_protection = bot.aggressiveProtect;
bot.startProtect();
bot.updateStatus('Protection active');
} else {
if (bot.protectTimer) clearInterval(bot.protectTimer);
bot.updateStatus('Protection inactive');
}
});
// Inspect
var inspectorActive = false;
document.getElementById('inspectorBtn').addEventListener('click', function() {
inspectorActive = !inspectorActive;
document.getElementById('inspectorText').innerText = inspectorActive ?
'Inspection active (hover over pixel)' : 'Inspection inactive';
});
document.addEventListener('mousemove', function(e) {
window._wipoMouseX = e.clientX;
window._wipoMouseY = e.clientY;
if (!inspectorActive) return;
var coords = getCanvasCoords(e.clientX, e.clientY);
var canvas = document.querySelector('canvas');
if (!canvas || coords.x < 0 || coords.y < 0 || coords.x >= canvas.width || coords.y >= canvas.height) return;
try {
var ctx = canvas.getContext('2d');
var pixel = ctx.getImageData(coords.x, coords.y, 1, 1);
document.getElementById('inspectorText').innerText =
'Pixel (' + coords.x + ',' + coords.y + ') RGB(' + pixel.data[0] + ',' + pixel.data[1] + ',' + pixel.data[2] + ')';
} catch(e) {}
});
// Color
document.getElementById('applyColorBtn').addEventListener('click', function() {
var color = document.getElementById('themeColor').value;
document.querySelector(':root').style.setProperty('--gui-main-color', color);
document.getElementById('wipo-menu-btn').style.borderColor = color;
});
// Clear
document.getElementById('clearProgressBtn').addEventListener('click', function() {
if (confirm('Clear progress data?')) {
GM_setValue('wipo_progress', '');
bot.updateStatus('Progress cleared.');
}
});
// Hotkeys
document.addEventListener('keydown', function(e) {
if (e.key === 'b' || e.key === 'B') {
var mx = window._wipoMouseX || 0;
var my = window._wipoMouseY || 0;
var coords = getCanvasCoords(mx, my);
document.getElementById('startX').value = coords.x;
document.getElementById('startY').value = coords.y;
updateOverlay();
bot.updateStatus('Coordinates: ' + coords.x + ', ' + coords.y);
}
if (e.key === 'x' || e.key === 'X') {
var x1 = parseInt(document.getElementById('startX').value) || 0;
var y1 = parseInt(document.getElementById('startY').value) || 0;
var mx = window._wipoMouseX || 0;
var my = window._wipoMouseY || 0;
var coords = getCanvasCoords(mx, my);
var colorId = parseInt(document.getElementById('squareColor').value) || 0;
bot.createSquare(x1, y1, coords.x, coords.y, colorId);
}
if (e.key === 'w' && e.altKey) {
bot.stop();
bot.updateStatus('All processes stopped.');
e.preventDefault();
}
});
// WebSocket kontrol
setTimeout(function() {
if (window.wipo.ws && window.wipo.ws.readyState === WebSocket.OPEN) {
window.wipo.wsReady = true;
console.log('[Wipo] WebSocket ready.');
} else {
console.log('[Wipo] WebSocket not ready, waiting...');
}
}, 2000);
console.log('[Wipo] GUI created.');
}
// ----- BASLAT -----
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() {
if (window.location.hostname === 'pixelplace.io') createUI();
});
} else {
if (window.location.hostname === 'pixelplace.io') setTimeout(createUI, 100);
}
})();