// ==UserScript==
// @name Drawaria Canvas Text Writer Safe Version
// @namespace http://tampermonkey.net/
// @version 1.0
// @description Write text on the Drawaria canvas using WebSockets
// @author YouTubeDrawaria
// @include https://drawaria.online/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=drawaria.online
// @license MIT
// @grant none
// ==/UserScript==
(function() {
'use strict';
// Adding Text Input and Button
function addTextInput() {
let container = document.createElement('div');
container.style.position = 'fixed';
container.style.top = '692.984px'; // Ajusta la posición vertical
container.style.left = '165.629px'; // Ajusta la posición horizontal
container.style.transform = 'translateX(-50%)';
container.style.zIndex = 1000;
container.style.background = 'linear-gradient(135deg, #003366, #0099cc)';
container.style.padding = '20px';
container.style.borderRadius = '10px';
container.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.2)';
container.style.display = 'flex';
container.style.flexDirection = 'column';
container.style.alignItems = 'center';
container.style.cursor = 'move';
let title = document.createElement('h3');
title.textContent = 'Canvas Text Writer';
title.style.margin = '0';
title.style.paddingBottom = '10px';
title.style.borderBottom = '1px solid #555';
title.style.width = '100%';
title.style.textAlign = 'center';
title.style.color = 'white';
container.appendChild(title);
let toggleButton = document.createElement('div');
toggleButton.innerHTML = '▲'; // Up arrow (cerrado por defecto)
toggleButton.style.cursor = 'pointer';
toggleButton.style.fontSize = '20px';
toggleButton.style.color = 'white';
toggleButton.style.marginBottom = '10px';
toggleButton.addEventListener('click', () => {
let content = container.querySelector('.content');
if (content.style.display === 'none') {
content.style.display = 'flex';
toggleButton.innerHTML = '▼'; // Down arrow
} else {
content.style.display = 'none';
toggleButton.innerHTML = '▲'; // Up arrow
}
});
container.appendChild(toggleButton);
let innerContainer = document.createElement('div');
innerContainer.className = 'content';
innerContainer.style.background = 'rgba(255, 255, 255, 0.2)';
innerContainer.style.padding = '20px';
innerContainer.style.borderRadius = '10px';
innerContainer.style.width = '100%';
innerContainer.style.display = 'none'; // Cerrado por defecto
innerContainer.style.flexDirection = 'column';
innerContainer.style.alignItems = 'center';
let wordList = document.createElement('div');
wordList.style.maxHeight = '150px';
wordList.style.overflowY = 'auto';
wordList.style.margin = '10px 0';
wordList.style.width = 'calc(100% - 20px)';
wordList.style.border = '1px solid #ccc';
wordList.style.borderRadius = '5px';
wordList.style.padding = '10px';
wordList.style.background = 'white';
let words = ['Hello', 'World', 'Draw', 'Canvas', 'Text', 'Write', 'Send', 'Clear', 'Join', 'Room'];
let selectedWord = null;
words.forEach(word => {
let checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.value = word;
checkbox.style.marginRight = '10px';
checkbox.addEventListener('change', () => {
if (checkbox.checked) {
selectedWord = word;
wordList.querySelectorAll('input[type="checkbox"]').forEach(cb => {
if (cb !== checkbox) {
cb.checked = false;
}
});
} else {
selectedWord = null;
}
});
let label = document.createElement('label');
label.appendChild(checkbox);
label.appendChild(document.createTextNode(word));
label.style.display = 'block';
label.style.marginBottom = '5px';
wordList.appendChild(label);
});
let fontSelect = document.createElement('select');
fontSelect.style.margin = '10px 0';
fontSelect.style.padding = '10px';
fontSelect.style.borderRadius = '5px';
fontSelect.style.border = '1px solid #ccc';
fontSelect.style.width = 'calc(100% - 20px)';
fontSelect.innerHTML = `
<option value="Arial">Arial</option>
<option value="Ravie">Ravie</option>
<option value="Courier">Courier</option>
<option value="Magneto">Magneto</option>
<option value="Papyrus">Papyrus</option>
<option value="Script MT Bold">Script MT Bold</option>
<option value="Algerian">Algerian</option>
<option value="Segoe Print">Segoe Print</option>
`;
let pixelSizeLabel = document.createElement('div');
pixelSizeLabel.textContent = 'Pixel Size: 30';
pixelSizeLabel.style.margin = '10px 0';
pixelSizeLabel.style.color = 'white';
let pixelSizeSlider = document.createElement('input');
pixelSizeSlider.type = 'range';
pixelSizeSlider.min = '10';
pixelSizeSlider.max = '30';
pixelSizeSlider.value = '30';
pixelSizeSlider.style.margin = '10px 0';
pixelSizeSlider.style.width = 'calc(100% - 20px)';
pixelSizeSlider.addEventListener('input', (event) => {
pixelSizeLabel.textContent = `Pixel Size: ${event.target.value}`;
});
let xPositionLabel = document.createElement('div');
xPositionLabel.textContent = 'Horizontal Position: 0';
xPositionLabel.style.margin = '10px 0';
xPositionLabel.style.color = 'white';
let xPositionSlider = document.createElement('input');
xPositionSlider.type = 'range';
xPositionSlider.min = '0';
xPositionSlider.max = '100';
xPositionSlider.value = '0';
xPositionSlider.style.margin = '10px 0';
xPositionSlider.style.width = 'calc(100% - 20px)';
xPositionSlider.addEventListener('input', (event) => {
xPositionLabel.textContent = `Horizontal Position: ${event.target.value}`;
});
let yPositionLabel = document.createElement('div');
yPositionLabel.textContent = 'Vertical Position: 0';
yPositionLabel.style.margin = '10px 0';
yPositionLabel.style.color = 'white';
let yPositionSlider = document.createElement('input');
yPositionSlider.type = 'range';
yPositionSlider.min = '0';
yPositionSlider.max = '100';
yPositionSlider.value = '0';
yPositionSlider.style.margin = '10px 0';
yPositionSlider.style.width = 'calc(100% - 20px)';
yPositionSlider.addEventListener('input', (event) => {
yPositionLabel.textContent = `Vertical Position: ${event.target.value}`;
});
let sendButton = document.createElement('button');
sendButton.textContent = 'Send Text';
sendButton.style.padding = '10px';
sendButton.style.borderRadius = '5px';
sendButton.style.border = 'none';
sendButton.style.background = 'linear-gradient(to bottom, white, #d3d3d3)';
sendButton.style.color = '#003366';
sendButton.style.cursor = 'pointer';
sendButton.style.width = 'calc(100% - 20px)';
sendButton.style.marginBottom = '10px';
sendButton.addEventListener('click', () => {
if (selectedWord) {
drawTextOnCanvas(selectedWord, fontSelect.value, parseInt(pixelSizeSlider.value), parseInt(xPositionSlider.value), parseInt(yPositionSlider.value));
}
});
let clearCanvasButton = document.createElement('button');
clearCanvasButton.textContent = 'Clear Canvas';
clearCanvasButton.style.padding = '10px';
clearCanvasButton.style.borderRadius = '5px';
clearCanvasButton.style.border = 'none';
clearCanvasButton.style.background = 'linear-gradient(to bottom, white, #d3d3d3)';
clearCanvasButton.style.color = '#003366';
clearCanvasButton.style.cursor = 'pointer';
clearCanvasButton.style.width = 'calc(100% - 20px)';
clearCanvasButton.style.marginBottom = '10px';
clearCanvasButton.addEventListener('click', () => {
let data = ["drawcmd", 0, [0.5, 0.5, 0.5, 0.5, !0, -2000, "#FFFFFF", -1, !1]];
window.sockets.forEach(socket => {
if (socket.readyState === WebSocket.OPEN) {
socket.send(`42${JSON.stringify(data)}`);
}
});
});
let joinButton = document.createElement('button');
joinButton.textContent = 'Join';
joinButton.style.padding = '10px';
joinButton.style.borderRadius = '5px';
joinButton.style.border = 'none';
joinButton.style.background = 'linear-gradient(to bottom, white, #d3d3d3)';
joinButton.style.color = '#003366';
joinButton.style.cursor = 'pointer';
joinButton.style.width = 'calc(100% - 20px)';
joinButton.style.marginBottom = '10px';
joinButton.addEventListener('mousedown', (e) => {
window['___BOT'].room.join(EL('#invurl').value);
});
let colorInput = document.createElement('input');
colorInput.type = 'color';
colorInput.value = '#000000';
colorInput.style.margin = '10px 0';
innerContainer.appendChild(wordList);
innerContainer.appendChild(fontSelect);
innerContainer.appendChild(pixelSizeLabel);
innerContainer.appendChild(pixelSizeSlider);
innerContainer.appendChild(xPositionLabel);
innerContainer.appendChild(xPositionSlider);
innerContainer.appendChild(yPositionLabel);
innerContainer.appendChild(yPositionSlider);
innerContainer.appendChild(sendButton);
innerContainer.appendChild(clearCanvasButton);
innerContainer.appendChild(joinButton);
innerContainer.appendChild(colorInput);
container.appendChild(innerContainer);
document.body.appendChild(container);
// Make the container draggable
let isDragging = false;
let offsetX, offsetY;
container.addEventListener('mousedown', (e) => {
if (e.target === container || e.target === title) {
isDragging = true;
offsetX = e.clientX - container.getBoundingClientRect().left;
offsetY = e.clientY - container.getBoundingClientRect().top;
container.style.cursor = 'grabbing';
}
});
document.addEventListener('mousemove', (e) => {
if (isDragging) {
container.style.left = `${e.clientX - offsetX}px`;
container.style.top = `${e.clientY - offsetY}px`;
}
});
document.addEventListener('mouseup', () => {
isDragging = false;
container.style.cursor = 'move';
});
}
// Drawing Text on Canvas
function drawTextOnCanvas(text, font, pixelSize, xPosition, yPosition) {
let x = xPosition / 100; // Convert to percentage
let y = yPosition / 100; // Convert to percentage
let thickness = 5;
let color = document.querySelector('input[type="color"]').value; // Get color from input
let canvas = document.createElement('canvas');
let ctx = canvas.getContext('2d');
canvas.width = 500;
canvas.height = 100;
ctx.font = `${pixelSize}px ${font}`;
ctx.fillStyle = color;
ctx.fillText(text, 10, 50);
let imageData = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
let commands = [];
for (let i = 0; i < imageData.length; i += 4) {
if (imageData[i + 3] > 0) { // Alpha channel is not zero
let px = (i / 4) % canvas.width;
let py = Math.floor((i / 4) / canvas.width);
let nx = x + (px / canvas.width);
let ny = y + (py / canvas.height);
commands.push([nx, ny, nx, ny, false, -thickness, color, 0, 0, {}]);
}
}
// Send commands in batches to avoid overloading the WebSocket
const batchSize = 50;
for (let i = 0; i < commands.length; i += batchSize) {
let batch = commands.slice(i, i + batchSize);
batch.forEach(cmd => {
sendDrawCommand(cmd[0], cmd[1], cmd[2], cmd[3], thickness, color);
});
// Add a small delay to avoid overloading the WebSocket
setTimeout(() => {}, 10);
}
}
// Sending Draw Command via WebSocket
function sendDrawCommand(x1, y1, x2, y2, thickness, color) {
let message = `42["drawcmd",0,[${x1},${y1},${x2},${y2},false,${0 - thickness},"${color}",0,0,{}]]`;
window.sockets.forEach(socket => {
if (socket.readyState === WebSocket.OPEN) {
socket.send(message);
}
});
}
// Overriding WebSocket send method to capture sockets
const originalSend = WebSocket.prototype.send;
WebSocket.prototype.send = function (...args) {
if (window.sockets.indexOf(this) === -1) {
window.sockets.push(this);
}
return originalSend.call(this, ...args);
};
// Initializing
window.sockets = [];
addTextInput();
// Adding the bot functionality
const EL = (sel) => document.querySelector(sel);
const Player = function (name = undefined) {
this.name = name;
this.sid1 = null;
this.uid = '';
this.wt = '';
this.conn = new Connection(this);
this.room = new Room(this.conn);
this.action = new Actions(this.conn);
};
Player.prototype.annonymize = function (name) {
this.name = name;
this.uid = undefined;
this.wt = undefined;
};
const Connection = function (player) {
this.player = player;
};
Connection.prototype.onopen = function (event) {
this.Heartbeat(25000);
};
Connection.prototype.onclose = function (event) {
};
Connection.prototype.onerror = function (event) {
};
Connection.prototype.onmessage = function (event) {
let message = String(event.data);
if (message.startsWith('42')) {
this.onbroadcast(message.slice(2));
} else if (message.startsWith('40')) {
this.onrequest();
} else if (message.startsWith('41')) {
this.player.room.join(this.player.room.id);
} else if (message.startsWith('430')) {
let configs = JSON.parse(message.slice(3))[0];
this.player.room.players = configs.players;
this.player.room.id = configs.roomid;
}
};
Connection.prototype.onbroadcast = function (payload) {
payload = JSON.parse(payload);
if (payload[0] == 'bc_uc_freedrawsession_changedroom') {
this.player.room.players = payload[3];
this.player.room.id = payload[4];
}
if (payload[0] == 'mc_roomplayerschange') {
this.player.room.players = payload[3];
}
};
Connection.prototype.onrequest = function () {};
Connection.prototype.open = function (url) {
this.socket = new WebSocket(url);
this.socket.onopen = this.onopen.bind(this);
this.socket.onclose = this.onclose.bind(this);
this.socket.onerror = this.onerror.bind(this);
this.socket.onmessage = this.onmessage.bind(this);
};
Connection.prototype.close = function (code, reason) {
this.socket.close(code, reason);
};
Connection.prototype.Heartbeat = function (interval) {
let timeout = setTimeout(() => {
if (this.socket.readyState == this.socket.OPEN) {
this.socket.send(2);
this.Heartbeat(interval);
}
}, interval);
};
Connection.prototype.serverconnect = function (server, room) {
if (this.socket == undefined || this.socket.readyState != this.socket.OPEN) {
this.open(server);
} else {
this.socket.send(41);
this.socket.send(40);
}
this.onrequest = () => {
this.socket.send(room);
};
};
const Room = function (conn) {
this.conn = conn;
this.id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';
this.players = [];
};
Room.prototype.join = function (invitelink) {
let gamemode = 2;
let server = '';
if (invitelink == null) {
this.id = null;
server = 'sv3.';
} else {
this.id = invitelink.startsWith('http') ? invitelink.split('/').pop() : invitelink;
if (invitelink.endsWith('.3')) {
server = 'sv3.';
gamemode = 2;
} else if (invitelink.endsWith('.2')) {
server = 'sv2.';
gamemode = 2;
} else {
server = '';
gamemode = 1;
}
}
let serverurl = `wss://${server}drawaria.online/socket.io/?sid1=undefined&hostname=drawaria.online&EIO=3&transport=websocket`;
let player = this.conn.player;
let connectstring = `420["startplay","${player.name}",${gamemode},"en",${nullify(this.id)},null,[null,"https://drawaria.online/",1000,1000,[${nullify(player.sid1)},${nullify(player.uid)},${nullify(player.wt)}],null]]`;
this.conn.serverconnect(serverurl, connectstring);
};
Room.prototype.next = function () {
if (this.conn.socket.readyState != this.conn.socket.OPEN) {
this.join(null);
} else {
this.conn.socket.send('42["pgswtichroom"]');
}
};
const Actions = function (conn) {
this.conn = conn;
};
Actions.prototype.DrawLine = function (bx = 50, by = 50, ex = 50, ey = 50, thickness = 50, color = '#FFFFFF', algo = 0) {
bx = bx / 100;
by = by / 100;
ex = ex / 100;
ey = ey / 100;
this.conn.socket.send(`42["drawcmd",0,[${bx},${by},${ex},${ey},true,${0 - thickness},"${color}",0,0,{"2":${algo},"3":0.5,"4":0.5}]]`);
this.conn.socket.send(`42["drawcmd",0,[${bx},${by},${ex},${ey},false,${0 - thickness},"${color}",0,0,{"2":${algo},"3":0.5,"4":0.5}]]`);
};
var nullify = (value = null) => {
return value == null ? null : String().concat('"', value, '"');
};
if (!document.getElementById('Engine-Cheatcontainer')) {
window['___BOT'] = new Player('Text Writer');
}
})();