Greasy Fork 支持简体中文。

Frozen Bot V1

Frozen bot script for gartic

  1. // ==UserScript==
  2. // @name Frozen Bot V1
  3. // @namespace tampermonkey.net
  4. // @version 1.0
  5. // @description Frozen bot script for gartic
  6. // @match *://*/*?__cpo=aHR0cHM6Ly9nYXJ0aWMuaW8
  7. // @match *://gartic.io/?bot*
  8. // @grant GM_setValue
  9. // @grant GM_getValue
  10. // @grant GM_addValueChangeListener
  11. // @grant GM_addStyle
  12. // @grant none
  13. // ==/UserScript==
  14.  
  15. (function() {
  16. 'use strict';
  17.  
  18. const config = {
  19. Rooms: [],
  20. userAgents: ["Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36", "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36"],
  21. proxies: ["https://www.blockaway.net/"],
  22. playerName: "",
  23. roomCode: "",
  24. delayBetweenEntries: 1000,
  25. reexecutionDelay: 1900,
  26. randomAvatar: false,
  27. selectedAvatar: 0,
  28. settings: {
  29. nickName: "",
  30. roomCode: "",
  31. avatarId: 0
  32. }
  33. };
  34.  
  35. let wsList = [];
  36. let isRunning = false;
  37. let messageInterval;
  38. let mainInterval;
  39. let afkIntervals = [];
  40. let isAfkPaused = false;
  41. let roomusers = [];
  42. let kickedUsers = new Set();
  43. let userListUpdateInterval;
  44.  
  45. const drawCommands = [
  46. '[6,"11"]',
  47. '[5,"x000000"]',
  48. '[3,0,0,767,448]',
  49. '[5,"x26C9FF"]',
  50. '[2,245,64,249,67,257,75,260,81,262,89,264,96,263,105,260,114,255,121,249,127,242,132,242,132]',
  51. '[2,231,69,237,67,247,67,259,66,270,67,274,67]',
  52. '[2,311,89,311,90,309,98,308,107,307,112,306,120]',
  53. '[2,312,71,320,68,328,67,332,67]',
  54. '[2,337,119,337,119,341,114,348,106,353,99,361,88,368,80,372,74,373,73,374,72,374,73,372,77,371,85,369,97,368,107,369,115]',
  55. '[2,369,115,371,120,374,120,380,116,387,109,396,101,408,87,422,75,443,55,452,49]',
  56. '[2,217,192,217,192,218,194,221,200,224,205,226,211,227,217,229,224,230,229,231,234,231,237,232,240,232,242,233,244,233,244,233,244]',
  57. '[2,233,244,235,241,241,233,248,222,257,210,267,197,275,187,279,182,280,180,280,181,280,181]',
  58. '[2,282,190,282,190,282,192,284,198,285,206,285,214,287,221,287,228,288,236,288,242,289,246,290,249,290,250,291,250,293,248,296,241]',
  59. '[2,355,203,355,203,349,211,344,220,344,229,344,236,347,241,352,242,360,240,369,236,378,230,385,223,390,215,391,210,392,204,389,198]',
  60. '[2,296,241,304,230,312,217,321,205,328,195,332,188,334,185,337,182]',
  61. '[2,418,196,418,196,417,198,414,208,413,218,414,228,421,234,429,237,440,236,450,231,458,224,465,216,468,207,470,198,465,194,458,192]',
  62. '[2,458,192,449,192,441,194,438,196,438,196]',
  63. '[2,389,198,384,194,378,192,373,191,367,194,360,198]'
  64. ];
  65.  
  66. window.toggleBot = toggleBot;
  67. window.sendMessage = sendMessage;
  68. window.exitFromRooms = exitFromRooms;
  69. window.autoDraw = autoDraw;
  70. window.toggleRandomAvatar = toggleRandomAvatar;
  71. window.updateAvatarPreview = updateAvatarPreview;
  72. window.applySettings = applySettings;
  73. window.sendReport = sendReport;
  74.  
  75.  
  76. function loadSettings() {
  77. const savedSettings = localStorage.getItem('frozenBotSettings');
  78. if(savedSettings) {
  79. config.settings = JSON.parse(savedSettings);
  80. document.querySelector('.bot-nick').value = config.settings.nickName;
  81. document.querySelector('.room-input').value = config.settings.roomCode;
  82. document.querySelector('.avatar-input').value = config.settings.avatarId;
  83. updateAvatarPreview(config.settings.avatarId);
  84. updateRoomCode();
  85. }
  86. }
  87.  
  88. function updateUserList() {
  89. const userListElement = document.querySelector('.user-list');
  90. const botNick = document.querySelector('.bot-nick').value.trim();
  91. userListElement.innerHTML = '';
  92. const addedUsers = new Set();
  93.  
  94. wsList.forEach(ws => {
  95. if (ws.readyState === WebSocket.OPEN) {
  96. ws.send('42[32]');
  97. }
  98. });
  99.  
  100. roomusers.forEach(user => {
  101. if (user.nick &&
  102. user.nick !== "Jinwoo" &&
  103. !addedUsers.has(user.id) &&
  104. !user.nick.replace(/\s+/g, '').includes(botNick.replace(/\s+/g, ''))) {
  105. const button = document.createElement('button');
  106. button.className = 'user-button';
  107. button.textContent = user.nick;
  108. button.onclick = () => kickUser(user.id, user.nick);
  109. userListElement.appendChild(button);
  110. addedUsers.add(user.id);
  111. }
  112. });
  113. }
  114.  
  115. function kickUser(userId, userNick) {
  116. if (!kickedUsers.has(userId)) {
  117. wsList.forEach(ws => {
  118. if (ws.readyState === WebSocket.OPEN) {
  119. ws.send(`42[11,${ws.id},"siktirgit ${userNick}"]`);
  120. setTimeout(() => {
  121. ws.send(`42[45,${ws.id},["${userId}",true]]`);
  122. ws.send(`42[45,${ws.id},["${userId}",false]]`);
  123. }, 100);
  124. }
  125. });
  126. kickedUsers.add(userId);
  127. updateUserList();
  128. }
  129. }
  130.  
  131. function applySettings() {
  132. config.settings.nickName = document.querySelector('.bot-nick').value;
  133. config.settings.roomCode = document.querySelector('.room-input').value;
  134. config.settings.avatarId = parseInt(document.querySelector('.avatar-input').value) || 0;
  135. localStorage.setItem('frozenBotSettings', JSON.stringify(config.settings));
  136. updateRoomCode();
  137. }
  138.  
  139. function generateInvisibleChar() {
  140. const invisibleChars = ['\u200B', '\u200C', '\u200D', '\u2061', '\u2062', '\u2063', '\u2064', '\u2066', '\u17b4', '\u17b5', '\u2068', '\u2069'];
  141. return invisibleChars[Math.floor(Math.random() * invisibleChars.length)];
  142. }
  143.  
  144. function addInvisibleCharsToMessage(message) {
  145. let result = '';
  146. for (let i = 0; i < message.length; i++) {
  147. result += message[i] + generateInvisibleChar();
  148. }
  149. return result;
  150. }
  151.  
  152. function getRandomName() {
  153. let name = document.querySelector('.bot-nick').value.trim();
  154. let result = '';
  155. for (let i = 0; i < name.length; i++) {
  156. result += name[i] + generateInvisibleChar();
  157. }
  158. result += generateInvisibleChar();
  159. return result.trim();
  160. }
  161.  
  162. function setRandomPlayerName() {
  163. config.playerName = getRandomName();
  164. }
  165.  
  166. function updateRoomCode() {
  167. const roomInput = document.querySelector('.room-input');
  168. const roomCode = roomInput.value.trim();
  169. if(roomCode) {
  170. config.Rooms = [roomCode];
  171. config.settings.roomCode = roomCode;
  172. }
  173. }
  174.  
  175. function autoDraw() {
  176. isAfkPaused = true;
  177. setTimeout(() => { isAfkPaused = false; }, 7000);
  178. wsList.forEach(ws => {
  179. if(ws.readyState === WebSocket.OPEN) {
  180. ws.send(`42[34,${ws.id}]`);
  181. let index = 0;
  182. const drawInterval = setInterval(() => {
  183. if(index < drawCommands.length) {
  184. ws.send(`42[10,${ws.id},${drawCommands[index]}]`);
  185. index++;
  186. } else {
  187. clearInterval(drawInterval);
  188. }
  189. }, 50);
  190. }
  191. });
  192. }
  193.  
  194. function exitFromRooms() {
  195. wsList.forEach(ws => {
  196. if (ws.readyState === WebSocket.OPEN) {
  197. ws.send(`42[11,${ws.id},"bb"]`);
  198. setTimeout(() => {
  199. ws.send(`42[24,${ws.id}]`);
  200. }, 100);
  201. }
  202. });
  203. wsList = [];
  204. roomusers = [];
  205. updateUserList();
  206. kickedUsers.clear();
  207. document.querySelector('.bot-counter').textContent = 'Bots: 0';
  208. }
  209.  
  210. function sendReport() {
  211. wsList.forEach(ws => {
  212. if (ws.readyState === WebSocket.OPEN) {
  213. ws.send(`42[35,${ws.id}]`);
  214. }
  215. });
  216. }
  217.  
  218. async function enterRoom(roomCode) {
  219. setRandomPlayerName();
  220. try {
  221. const logoutResponse = await fetch("/logout");
  222. if (!logoutResponse.ok) throw new Error('Logout failed');
  223.  
  224. const roomResponse = await fetch("https://gartic.io/server?check=1&v3=1&room=" + roomCode);
  225. if (!roomResponse.ok) throw new Error('Room check failed');
  226.  
  227. const roomText = await roomResponse.text();
  228. const server = roomText.split("//")[1].split(".")[0];
  229. const ccode = roomText.split("c=")[1];
  230.  
  231. const ws = new WebSocket('wss://' + server + '.gartic.io/socket.io/?c=' + ccode + '&EIO=3&transport=websocket');
  232. wsList.push(ws);
  233.  
  234. ws.onopen = () => {
  235. let botData = {
  236. v: 20000,
  237. nick: getRandomName(),
  238. avatar: config.randomAvatar ? Math.floor(Math.random() * 36) : config.selectedAvatar,
  239. platform: 0,
  240. sala: roomCode.slice(-4)
  241. };
  242. ws.send(`42[3,${JSON.stringify(botData)}]`);
  243. };
  244.  
  245. ws.onmessage = (msg) => {
  246. if (msg.data.indexOf('42["5"') !== -1) {
  247. let objlist = JSON.parse('["5"' + msg.data.split('42["5"')[1]);
  248. ws.id = objlist[2];
  249. roomusers = objlist[5];
  250. updateUserList();
  251. updateBotCounter();
  252. startAntiAfk(ws.id);
  253. setTimeout(() => {
  254. ws.send(`42[11,${ws.id},"sa"]`);
  255. }, 10);
  256. }
  257. if (msg.data.indexOf('42["23"') !== -1) {
  258. let user = JSON.parse("{" + msg.data.split("{")[1].split("}")[0] + "}");
  259. if (!roomusers.some(existingUser => existingUser.id === user.id)) {
  260. roomusers.push(user);
  261. updateUserList();
  262. }
  263. }
  264. if (msg.data.indexOf('42["24"') !== -1) {
  265. let userId = msg.data.split(",")[1].split('"')[1];
  266. roomusers = roomusers.filter(u => u.id !== userId);
  267. updateUserList();
  268. }
  269. if (msg.data.indexOf('42["33"') !== -1) {
  270. try {
  271. let userList = JSON.parse(msg.data.split('42["33",')[1]);
  272. roomusers = userList;
  273. updateUserList();
  274. } catch(e) {
  275. console.error(e);
  276. }
  277. }
  278. };
  279. } catch (error) {
  280. console.error(error);
  281. }
  282. }
  283.  
  284. function startAntiAfk(botId) {
  285. const interval = setInterval(() => {
  286. if (!isAfkPaused) {
  287. wsList.forEach(ws => {
  288. if (ws.readyState === WebSocket.OPEN && ws.id === botId) {
  289. ws.send(`42[25,${botId}]`);
  290. }
  291. });
  292. }
  293. }, 5000);
  294. afkIntervals.push(interval);
  295. }
  296.  
  297. function updateBotCounter() {
  298. let botCounter = document.querySelector('.bot-counter');
  299. let currentBots = parseInt(botCounter.textContent.split(': ')[1]);
  300. botCounter.textContent = `Bots: ${currentBots + 1}`;
  301. }
  302.  
  303. function toggleRandomAvatar() {
  304. const switch_elem = document.querySelector('.avatar-switch input');
  305. const avatar_input = document.querySelector('.avatar-input');
  306. config.randomAvatar = switch_elem.checked;
  307. avatar_input.disabled = config.randomAvatar;
  308. if(config.randomAvatar) {
  309. avatar_input.value = '';
  310. updateAvatarPreview('');
  311. }
  312. }
  313.  
  314. function updateAvatarPreview(value) {
  315. const preview = document.querySelector('.avatar-preview');
  316. const numValue = parseInt(value);
  317. if(numValue >= 0 && numValue <= 36) {
  318. preview.src = `https://gartic.io/static/images/avatar/svg/${numValue}.svg`;
  319. preview.style.display = 'inline';
  320. config.selectedAvatar = numValue;
  321. config.settings.avatarId = numValue;
  322. } else {
  323. preview.style.display = 'none';
  324. }
  325. }
  326.  
  327. function sendMessage() {
  328. const messageInput = document.querySelector('.message-input');
  329. const message = messageInput.value;
  330. if (message && wsList.length > 0) {
  331. const firstBot = wsList[0];
  332. if (firstBot && firstBot.readyState === WebSocket.OPEN) {
  333. firstBot.send(`42[11,${firstBot.id},"${addInvisibleCharsToMessage(message)}"]`);
  334. }
  335. }
  336. }
  337.  
  338. function toggleBot() {
  339. const toggleButton = document.querySelector('.toggle-button');
  340. isRunning = !isRunning;
  341. toggleButton.textContent = isRunning ? 'Stop Bots' : 'Start Bots';
  342. toggleButton.style.backgroundColor = isRunning ? '#ff4444' : '#4CAF50';
  343.  
  344. if (isRunning) {
  345. enterAllRooms();
  346. mainInterval = setInterval(enterAllRooms, config.reexecutionDelay);
  347. } else {
  348. clearInterval(mainInterval);
  349. }
  350. }
  351.  
  352. async function enterAllRooms() {
  353. if (!isRunning) return;
  354. for (const roomCode of config.Rooms) {
  355. await enterRoom(roomCode);
  356. await new Promise(resolve => setTimeout(resolve, config.delayBetweenEntries));
  357. }
  358. }
  359.  
  360. function createGUI() {
  361. const css = `
  362. .frozen-bot {
  363. position: fixed;
  364. top: 0;
  365. left: 0;
  366. width: 100%;
  367. height: 100%;
  368. background: linear-gradient(135deg, #0c1d3b 0%, #1a3b7c 100%);
  369. padding: 20px;
  370. color: #fff;
  371. font-family: 'Arial', sans-serif;
  372. z-index: 9999;
  373. overflow-y: auto;
  374. }
  375.  
  376. .bot-container {
  377. max-width: 1200px;
  378. margin: 0 auto;
  379. display: grid;
  380. grid-template-columns: repeat(2, 1fr);
  381. gap: 20px;
  382. padding: 20px;
  383. }
  384.  
  385. .control-panel, .user-panel {
  386. background: rgba(255, 255, 255, 0.1);
  387. padding: 20px;
  388. border-radius: 15px;
  389. backdrop-filter: blur(10px);
  390. }
  391.  
  392. .frozen-bot input {
  393. width: 100%;
  394. padding: 12px;
  395. margin: 8px 0;
  396. border: none;
  397. border-radius: 8px;
  398. background: rgba(255, 255, 255, 0.15);
  399. color: #fff;
  400. font-size: 16px;
  401. }
  402.  
  403. .frozen-bot button {
  404. width: 100%;
  405. padding: 12px;
  406. margin: 8px 0;
  407. border: none;
  408. border-radius: 8px;
  409. cursor: pointer;
  410. font-weight: bold;
  411. font-size: 16px;
  412. transition: all 0.3s ease;
  413. }
  414.  
  415. .user-list {
  416. display: grid;
  417. grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  418. gap: 10px;
  419. max-height: 600px;
  420. overflow-y: auto;
  421. padding: 15px;
  422. background: rgba(255, 255, 255, 0.05);
  423. border-radius: 10px;
  424. }
  425.  
  426. .user-button {
  427. background: linear-gradient(135deg, #1a3b7c 0%, #0c1d3b 100%);
  428. color: #89CFF0;
  429. padding: 10px;
  430. border-radius: 8px;
  431. font-size: 14px;
  432. text-align: center;
  433. margin: 0;
  434. }
  435.  
  436. h2 {
  437. color: #89CFF0;
  438. text-align: center;
  439. margin-bottom: 15px;
  440. text-shadow: 0 0 10px rgba(137, 207, 240, 0.5);
  441. }
  442.  
  443. .toggle-button { background: #4CAF50; color: white; }
  444. .send-button { background: #2196F3; color: white; }
  445. .exit-button { background: #f44336; color: white; }
  446. .report-button { background: #E91E63; color: white; }
  447. .draw-button { background: #9C27B0; color: white; }
  448. .apply-button { background: #FF9800; color: white; }
  449.  
  450. .bot-counter {
  451. text-align: center;
  452. margin: 10px 0;
  453. font-size: 1.2em;
  454. color: #89CFF0;
  455. }
  456.  
  457. .avatar-container {
  458. display: flex;
  459. align-items: center;
  460. margin: 10px 0;
  461. gap: 10px;
  462. }
  463.  
  464. .avatar-input { width: 60px !important; }
  465.  
  466. .avatar-switch {
  467. position: relative;
  468. display: inline-block;
  469. width: 60px;
  470. height: 34px;
  471. }
  472.  
  473. .avatar-preview {
  474. width: 30px;
  475. height: 30px;
  476. display: none;
  477. }
  478.  
  479. .avatar-switch input {
  480. opacity: 0;
  481. width: 0;
  482. height: 0;
  483. }
  484.  
  485. .slider {
  486. position: absolute;
  487. cursor: pointer;
  488. top: 0;
  489. left: 0;
  490. right: 0;
  491. bottom: 0;
  492. background-color: #ccc;
  493. transition: .4s;
  494. border-radius: 34px;
  495. }
  496.  
  497. .slider:before {
  498. position: absolute;
  499. content: "";
  500. height: 26px;
  501. width: 26px;
  502. left: 4px;
  503. bottom: 4px;
  504. background-color: white;
  505. transition: .4s;
  506. border-radius: 50%;
  507. }
  508.  
  509. input:checked + .slider { background-color: #2196F3; }
  510. input:checked + .slider:before { transform: translateX(26px); }
  511. `;
  512.  
  513. const html = `
  514. <div class="frozen-bot">
  515. <div class="bot-container">
  516. <div class="control-panel">
  517. <h2>❄️ Frozen Bot Control Panel ❄️</h2>
  518. <div class="bot-counter">Bots: 0</div>
  519. <input type="text" class="room-input" placeholder="Enter Room Code..." oninput="updateRoomCode()">
  520. <input type="text" class="message-input" placeholder="Enter message...">
  521. <button class="send-button" onclick="window.sendMessage()">Send Message</button>
  522. <input type="text" class="bot-nick" placeholder="Bot Nick...">
  523. <div class="avatar-container">
  524. <input type="number" class="avatar-input" placeholder="Avatar" min="0" max="36" oninput="window.updateAvatarPreview(this.value)">
  525. <label class="avatar-switch">
  526. <input type="checkbox" onchange="window.toggleRandomAvatar()">
  527. <span class="slider"></span>
  528. </label>
  529. <span style="color: #89CFF0;">Random Avatar</span>
  530. <img class="avatar-preview">
  531. </div>
  532. <button class="apply-button" onclick="window.applySettings()">Apply Settings</button>
  533. <button class="toggle-button" onclick="window.toggleBot()">Start Bots</button>
  534. <button class="exit-button" onclick="window.exitFromRooms()">Exit Room</button>
  535. <button class="report-button" onclick="window.sendReport()">Report</button>
  536. <button class="draw-button" onclick="window.autoDraw()">AUTO DRAW</button>
  537. </div>
  538. <div class="user-panel">
  539. <h2>👥 User List</h2>
  540. <div class="user-list"></div>
  541. </div>
  542. </div>
  543. </div>
  544. `;
  545.  
  546. const style = document.createElement('style');
  547. style.textContent = css;
  548. document.head.appendChild(style);
  549.  
  550. const div = document.createElement('div');
  551. div.innerHTML = html;
  552. document.body.appendChild(div);
  553. }
  554.  
  555. function init() {
  556. createGUI();
  557. loadSettings();
  558. userListUpdateInterval = setInterval(updateUserList, 100);
  559. }
  560.  
  561. init();
  562. })();