RubixYT1

DianondBot v7.13.3 textwall

Nov 23rd, 2025
73
1
Never
7
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 81.55 KB | None | 1 0
  1. (async function () {
  2. "use strict";
  3. if (typeof w === "undefined") {
  4. console.error("TextWall API (w) not found! Make sure you're on tw.2s4.me");
  5. return;
  6. }
  7. const Storage = {
  8. save: function (key, data) {
  9. try {
  10. localStorage.setItem(`diamondbot_${key}`, JSON.stringify(data));
  11. return true;
  12. } catch (e) {
  13. console.error("Failed to save to storage:", e);
  14. return false;
  15. }
  16. },
  17. load: function (key, defaultValue = null) {
  18. try {
  19. const data = localStorage.getItem(`diamondbot_${key}`);
  20. return data ? JSON.parse(data) : defaultValue;
  21. } catch (e) {
  22. console.error("Failed to load from storage:", e);
  23. return defaultValue;
  24. }
  25. },
  26. remove: function (key) {
  27. try {
  28. localStorage.removeItem(`diamondbot_${key}`);
  29. return true;
  30. } catch (e) {
  31. console.error("Failed to remove from storage:", e);
  32. return false;
  33. }
  34. },
  35. };
  36. const BOT_CONFIG = {
  37. version: "7.13.3",
  38. username: "diamondbot",
  39. color: 0,
  40. prefix: "\\",
  41. authorizedUsers: Storage.load("authorizedUsers", ["Diamond25", "KiwiTest"]),
  42. bannedUsers: Storage.load("bannedUsers", []),
  43. bannedIds: Storage.load("bannedIds", []),
  44. messageDelay: 150,
  45. position: { x: 0, y: 0 },
  46. heightSafetyEnabled: true,
  47. lastAuthorityMessage: "",
  48. authorityEchoEnabled: false,
  49. echoColorEnabled: false,
  50. };
  51. const state = {
  52. wall: "",
  53. subwall: "",
  54. perms: 0,
  55. isRegistered: false,
  56. isAdmin: false,
  57. readonly: false,
  58. hidecursors: false,
  59. disablechat: false,
  60. disablecolor: false,
  61. disablebraille: false,
  62. members: [],
  63. walllist: [],
  64. activeTimers: new Map(),
  65. activeCounts: new Map(),
  66. commandCooldowns: new Map(),
  67. messageQueue: [],
  68. isProcessingQueue: false,
  69. lastMessageTime: 0,
  70. cursors: new Map(),
  71. adminUsers: new Set(),
  72. processedMessages: new Set(),
  73. lastSayUser: null,
  74. userPositions: new Map(),
  75. userIds: new Map(),
  76. isShuttingDown: false,
  77. isTyping: false,
  78. countdownActive: false,
  79. clearingArea: false,
  80. };
  81. const COLORS = {
  82. "#000000": 0,
  83. "#ffffff": 1,
  84. "#ff0000": 2,
  85. "#00ff00": 3,
  86. "#0000ff": 4,
  87. "#ffff00": 5,
  88. "#ff00ff": 6,
  89. "#00ffff": 7,
  90. "#808080": 8,
  91. "#ff8800": 9,
  92. "#8800ff": 10,
  93. "#0088ff": 11,
  94. "#88ff00": 12,
  95. "#ff0088": 13,
  96. "#884400": 14,
  97. "#448800": 15,
  98. };
  99. const AUTHORITY_COMMANDS = [
  100. "to",
  101. "tp",
  102. "colorid",
  103. "addauth",
  104. "removeauth",
  105. "disablehs",
  106. "echoauth",
  107. "echocolor",
  108. "csay",
  109. "ban",
  110. "unban",
  111. "banid",
  112. "unbanid",
  113. "type",
  114. "cleararea",
  115. ];
  116. const INVISIBLE_CHAR = "\u200B";
  117. const CHANGELOG = [
  118. { version: "7.13.3", changes: "10ms cleararea cooldown, w.cursors detection" },
  119. { version: "7.13.2", changes: "\\cleararea command, unbanName console command" },
  120. { version: "7.13.1", changes: "\\tcountdown and \\userlist commands added" },
  121. { version: "7.13", changes: "Cursor Y coordinate flipped, \\chl command added" },
  122. { version: "7.12", changes: "\\echocolor command, HEX-only colors, authority color echo" },
  123. { version: "7.11", changes: "Color syntax support with <start #HEX>text<end>" },
  124. { version: "7.10", changes: "\\tp command using w.tp() function" },
  125. { version: "7.9", changes: "Help cooldown 0.7s, thelp step 1, page command update" },
  126. { version: "7.8", changes: "Bug fixes and performance improvements" },
  127. { version: "7.7", changes: "Enhanced security and ban system" },
  128. { version: "7.6", changes: "Timer system improvements" },
  129. { version: "7.5", changes: "Authority system enhancements" },
  130. { version: "7.4", changes: "Added height safety toggle" },
  131. { version: "7.3", changes: "Colored say command (csay)" },
  132. { version: "7.2", changes: "Ban system with ID support" },
  133. { version: "7.1", changes: "Echo authority messages feature" },
  134. { version: "7.0", changes: "Major rewrite with improved architecture" },
  135. ];
  136. const COMMAND_PAGES = {
  137. 1: [
  138. { cmd: "help", desc: "Show command pages", auth: false },
  139. { cmd: "thelp", desc: "Type help on wall", auth: false },
  140. { cmd: "fullcmd", desc: "Get full command list location", auth: false },
  141. { cmd: "info", desc: "Show bot information", auth: false },
  142. { cmd: "chl", desc: "Show changelog", auth: false },
  143. ],
  144. 2: [
  145. { cmd: "calculate", desc: "Calculate p1^p2", auth: false },
  146. { cmd: "calc2", desc: "Calculate p1^^p2 (tetration)", auth: false },
  147. { cmd: "rng", desc: "Random number between min and max", auth: false },
  148. { cmd: "timer", desc: "Set a timer (h m s)", auth: false },
  149. { cmd: "say", desc: "Make bot say something", auth: false },
  150. ],
  151. 3: [
  152. { cmd: "count", desc: "Count from 1 to n with cooldown", auth: false },
  153. { cmd: "tcountdown", desc: "Type countdown on wall from seconds", auth: false },
  154. { cmd: "status", desc: "Show bot status", auth: false },
  155. { cmd: "pos", desc: "Show cursor position (x,y coordinates)", auth: false },
  156. { cmd: "type", desc: "Type characters on wall (Authority)", auth: true },
  157. ],
  158. 4: [
  159. { cmd: "page", desc: "Show detailed page info", auth: false },
  160. { cmd: "members", desc: "List wall members", auth: false },
  161. { cmd: "walls", desc: "List available subwalls", auth: false },
  162. { cmd: "authlist", desc: "Show authorized users", auth: false },
  163. { cmd: "userlist", desc: "Show all online users in wall", auth: false },
  164. ],
  165. 5: [
  166. { cmd: "to", desc: "Teleport bot to X Y (Authority)", auth: true },
  167. { cmd: "tp", desc: "Teleport to X Y using w.tp (Authority)", auth: true },
  168. { cmd: "colorid", desc: "Change bot color (Authority)", auth: true },
  169. { cmd: "cleararea", desc: "Clear area with spaces (Authority)", auth: true },
  170. { cmd: "csay", desc: "Say colored text (Authority)", auth: true },
  171. ],
  172. 6: [
  173. { cmd: "addauth", desc: "Add user to authority list (Authority)", auth: true },
  174. { cmd: "removeauth", desc: "Remove user from authority (Authority)", auth: true },
  175. { cmd: "ban", desc: "Ban user from using bot (Authority)", auth: true },
  176. { cmd: "unban", desc: "Unban user/ID (Authority)", auth: true },
  177. { cmd: "banid", desc: "Ban user by ID (Authority)", auth: true },
  178. ],
  179. 7: [
  180. { cmd: "unbanid", desc: "Unban user by ID (Authority)", auth: true },
  181. { cmd: "banlist", desc: "Show banned users (Authority)", auth: true },
  182. { cmd: "disableHS", desc: "Toggle height safety (Authority)", auth: true },
  183. { cmd: "echoauth", desc: "Toggle authority echo (Authority)", auth: true },
  184. { cmd: "echocolor", desc: "Toggle color echo (Authority)", auth: true },
  185. ],
  186. };
  187. async function loadBreakEternity() {
  188. if (typeof window.Decimal !== "undefined") {
  189. console.log("[OK] Break Eternity already loaded");
  190. return true;
  191. }
  192. const sources = [
  193. "https://cdn.jsdelivr.net/npm/break_eternity.js@latest/break_eternity.min.js",
  194. "https://unpkg.com/break_eternity.js@latest/dist/break_eternity.min.js",
  195. "https://cdnjs.cloudflare.com/ajax/libs/break_eternity.js/1.3.0/break_eternity.min.js",
  196. ];
  197. for (let src of sources) {
  198. try {
  199. await loadScript(src);
  200. if (typeof window.Decimal !== "undefined") {
  201. console.log(`[OK] Break Eternity loaded from: ${src}`);
  202. return true;
  203. }
  204. } catch (e) {
  205. console.warn(`Failed to load from ${src}`);
  206. }
  207. }
  208. window.Decimal = createFallbackDecimal();
  209. console.log("[OK] Using fallback Decimal implementation");
  210. return true;
  211. }
  212. function loadScript(src) {
  213. return new Promise((resolve, reject) => {
  214. const script = document.createElement("script");
  215. script.src = src;
  216. script.onload = resolve;
  217. script.onerror = reject;
  218. document.head.appendChild(script);
  219. });
  220. }
  221. function createFallbackDecimal() {
  222. return class Decimal {
  223. constructor(value) {
  224. this.value =
  225. typeof value === "string" || typeof value === "number" ? parseFloat(value) || 0 : value?.value || 0;
  226. }
  227. static pow(base, exp) {
  228. const b = base instanceof Decimal ? base.value : parseFloat(base);
  229. const e = exp instanceof Decimal ? exp.value : parseFloat(exp);
  230. if (e === 0) return new Decimal(1);
  231. if (b === 0) return new Decimal(0);
  232. let result;
  233. if (Math.abs(e) > 308) {
  234. result = e > 0 ? Infinity : 0;
  235. } else {
  236. result = Math.pow(b, e);
  237. }
  238. return new Decimal(result);
  239. }
  240. static tetrate(base, height) {
  241. const b = base instanceof Decimal ? base.value : parseFloat(base);
  242. const h = parseInt(height);
  243. if (h === 0) return new Decimal(1);
  244. if (h === 1) return new Decimal(b);
  245. if (b === 0) return new Decimal(0);
  246. if (!BOT_CONFIG.heightSafetyEnabled) {
  247. let result = b;
  248. for (let i = 1; i < h; i++) {
  249. result = Math.pow(b, result);
  250. if (!isFinite(result)) break;
  251. }
  252. return new Decimal(result);
  253. }
  254. const maxHeight = 5;
  255. let result = b;
  256. for (let i = 1; i < h && i < maxHeight; i++) {
  257. result = Math.pow(b, result);
  258. if (!isFinite(result)) break;
  259. }
  260. return new Decimal(result);
  261. }
  262. toString() {
  263. if (!isFinite(this.value)) return this.value > 0 ? "Infinity" : "-Infinity";
  264. if (Math.abs(this.value) < 1e-6) return "0";
  265. if (Math.abs(this.value) < 1e6 && Math.abs(this.value) > 1e-3) {
  266. return this.value.toString();
  267. }
  268. return this.value.toExponential(2);
  269. }
  270. };
  271. }
  272. class TextWallBot {
  273. constructor(config) {
  274. this.config = config;
  275. this.state = state;
  276. this.eventHandlers = {};
  277. this.running = true;
  278. }
  279. async init() {
  280. console.log("===================================");
  281. console.log(` TextWall Bot v${this.config.version} Initializing `);
  282. console.log("===================================");
  283. await loadBreakEternity();
  284. this.setupEventListeners();
  285. this.setUsername(this.config.username);
  286. this.setColor(this.config.color);
  287. this.teleportCursor(0, 0);
  288. setTimeout(() => {
  289. this.sendMessage(
  290. `${this.config.username} v${this.config.version} online! Type ${this.config.prefix}help for commands`
  291. );
  292. }, 2000);
  293. console.log("[OK] Bot initialized successfully!");
  294. console.log(`[OK] Prefix: ${this.config.prefix}`);
  295. console.log(`[OK] Authorized users: ${this.config.authorizedUsers.join(", ")}`);
  296. console.log(`[OK] Banned users: ${this.config.bannedUsers.length}`);
  297. console.log(`[OK] Banned IDs: ${this.config.bannedIds.length}`);
  298. console.log("[OK] Type window.showCommands() to see all commands in console");
  299. console.log("[OK] Color syntax: <start #HEXCOLOR>text<end>");
  300. console.log("[OK] Y coordinates are flipped (negated)");
  301. console.log("===================================");
  302. }
  303. setupEventListeners() {
  304. this.eventHandlers = {
  305. join: (data) => this.onJoin(data),
  306. alert: (data) => this.onAlert(data),
  307. msg: (data) => this.onMessage(data),
  308. edit: (data) => this.onEdit(data),
  309. protect: (data) => this.onProtect(data),
  310. clear: (data) => this.onClear(data),
  311. cursor: (data) => this.onCursor(data),
  312. cursorleft: (id) => this.onCursorLeft(id),
  313. perms: (level) => this.onPerms(level),
  314. memberadded: (member) => this.onMemberAdded(member),
  315. memberlist: (members) => this.onMemberList(members),
  316. walllist: (walls) => this.onWallList(walls),
  317. readonly: (state) => this.onReadonly(state),
  318. hidecursors: (state) => this.onHideCursors(state),
  319. disablechat: (state) => this.onDisableChat(state),
  320. disablecolor: (state) => this.onDisableColor(state),
  321. disablebraille: (state) => this.onDisableBraille(state),
  322. nametaken: () => this.onNameTaken(),
  323. passfail: () => this.onPassFail(),
  324. tokenfail: () => this.onTokenFail(),
  325. regclosed: () => this.onRegClosed(),
  326. namechanged: (name) => this.onNameChanged(name),
  327. accountdeleted: () => this.onAccountDeleted(),
  328. pong: (ms) => this.onPong(ms),
  329. };
  330. for (let [event, handler] of Object.entries(this.eventHandlers)) {
  331. if (w && w.on) {
  332. w.on(event, handler);
  333. }
  334. }
  335. console.log(`[OK] Registered ${Object.keys(this.eventHandlers).length} event listeners`);
  336. }
  337. cleanup() {
  338. this.running = false;
  339. this.state.countdownActive = false;
  340. this.state.clearingArea = false;
  341. for (let [event, handler] of Object.entries(this.eventHandlers)) {
  342. if (w && w.off) {
  343. w.off(event, handler);
  344. }
  345. }
  346. this.state.activeTimers.forEach((timer) => {
  347. clearTimeout(timer.timeout);
  348. if (timer.intervalId) clearInterval(timer.intervalId);
  349. });
  350. this.state.activeCounts.forEach((count) => {
  351. if (count.intervalId) clearInterval(count.intervalId);
  352. });
  353. console.log("[OK] Bot cleaned up");
  354. }
  355. isAuthorized(username, isAdmin) {
  356. if (isAdmin) {
  357. this.state.adminUsers.add(username);
  358. return true;
  359. }
  360. return this.config.authorizedUsers.includes(username);
  361. }
  362. isBanned(username) {
  363. return this.config.bannedUsers.includes(username);
  364. }
  365. isIdBanned(userId) {
  366. return this.config.bannedIds.includes(userId);
  367. }
  368. getUserId(username) {
  369. for (let [id, cursor] of this.state.cursors.entries()) {
  370. if (cursor.name === username) {
  371. return id;
  372. }
  373. }
  374. return this.state.userIds.get(username) || null;
  375. }
  376. getCursorPosition(username) {
  377. if (this.state.userPositions.has(username)) {
  378. return this.state.userPositions.get(username);
  379. }
  380. for (let cursor of this.state.cursors.values()) {
  381. if (cursor.name === username) {
  382. return cursor.location;
  383. }
  384. }
  385. return null;
  386. }
  387. containsAuthorityCommand(message) {
  388. const msgLower = message.toLowerCase();
  389. for (let authCmd of AUTHORITY_COMMANDS) {
  390. if (msgLower.includes(`${this.config.prefix}${authCmd}`)) {
  391. return true;
  392. }
  393. }
  394. return false;
  395. }
  396. hasColorSyntax(message) {
  397. const colorPattern = /<start\s+#[0-9a-fA-F]{6}>([^<]*)<end>/i;
  398. return colorPattern.test(message);
  399. }
  400. parseColoredMessage(message) {
  401. const colorPattern = /<start\s+(#[0-9a-fA-F]{6})>([^<]*)<end>/gi;
  402. const segments = [];
  403. let lastIndex = 0;
  404. let match;
  405.  
  406. while ((match = colorPattern.exec(message)) !== null) {
  407. // Add text before colored segment
  408. if (match.index > lastIndex) {
  409. segments.push({
  410. text: message.substring(lastIndex, match.index),
  411. color: null
  412. });
  413. }
  414.  
  415. // Add colored segment
  416. const hexColor = match[1].toLowerCase();
  417. const text = match[2];
  418. const colorId = COLORS[hexColor];
  419.  
  420. segments.push({
  421. text: text,
  422. color: colorId !== undefined ? colorId : null
  423. });
  424.  
  425. lastIndex = match.index + match[0].length;
  426. }
  427.  
  428. // Add remaining text
  429. if (lastIndex < message.length) {
  430. segments.push({
  431. text: message.substring(lastIndex),
  432. color: null
  433. });
  434. }
  435.  
  436. // If no color segments found, return original message
  437. if (segments.length === 0) {
  438. return [{ text: message, color: null }];
  439. }
  440.  
  441. return segments;
  442. }
  443. onJoin(data) {
  444. this.state.wall = data.wall || "";
  445. this.state.subwall = data.subwall || "";
  446. console.log(`[JOINED] ${this.state.wall}/${this.state.subwall}`);
  447. }
  448. onAlert(data) {
  449. console.log(`[ALERT] ${data.message}`);
  450. }
  451. onMessage(data) {
  452. if (!data || !data.msg) return;
  453. if (data.nick === this.config.username) return;
  454. const message = data.msg.trim();
  455. const sender = data.nick || "Unknown";
  456. const isAdmin = data.isAdmin || false;
  457. const userId = data.id || null;
  458. if (userId && sender) {
  459. this.state.userIds.set(sender, userId);
  460. }
  461. const messageId = `${sender}-${message}-${Date.now()}`;
  462. if (this.state.processedMessages.has(messageId)) return;
  463. this.state.processedMessages.add(messageId);
  464. if (this.state.processedMessages.size > 100) {
  465. const messages = Array.from(this.state.processedMessages);
  466. messages.slice(0, messages.length - 100).forEach((msg) => {
  467. this.state.processedMessages.delete(msg);
  468. });
  469. }
  470. if (isAdmin) {
  471. this.state.adminUsers.add(sender);
  472. }
  473. const hasAuth = this.isAuthorized(sender, isAdmin);
  474. if (hasAuth) {
  475. console.log(`[AUTHORITY] ${sender} ~ ${message}`);
  476.  
  477. // Echo color handler
  478. if (this.config.echoColorEnabled &&
  479. !message.startsWith(this.config.prefix) &&
  480. !message.includes("[AUTHORITY COLOR]") &&
  481. this.hasColorSyntax(message)) {
  482.  
  483. this.sendMessage(`[AUTHORITY COLOR] ${sender} ~ ${message}`);
  484. }
  485. // Regular authority echo (without color syntax)
  486. else if (
  487. this.config.authorityEchoEnabled &&
  488. !message.startsWith(this.config.prefix) &&
  489. !message.includes("[AUTHORITY]") &&
  490. !this.hasColorSyntax(message) &&
  491. this.config.lastAuthorityMessage !== `${sender}:${message}`
  492. ) {
  493. this.config.lastAuthorityMessage = `${sender}:${message}`;
  494. this.sendMessage(`[AUTHORITY] ${sender} ~ ${message}`);
  495. }
  496. } else {
  497. console.log(`[MSG] ${sender}${data.isRegistered ? " (R)" : ""}: ${message}`);
  498. }
  499. if (message.startsWith(this.config.prefix)) {
  500. this.handleCommand(message, sender, data);
  501. }
  502. }
  503. onEdit(data) {
  504. if (data.edits && data.edits.length > 0) {
  505. console.log(`[EDIT] ${data.edits.length} edit(s) made`);
  506. }
  507. }
  508. onProtect(data) {
  509. console.log(`[PROTECT] Chunk ${data.cell} protection: ${data.protect ? "ON" : "OFF"}`);
  510. }
  511. onClear(data) {
  512. console.log(`[CLEAR] Area cleared: (${data.x1},${data.y1}) to (${data.x2},${data.y2})`);
  513. }
  514. onCursor(data) {
  515. if (!data.id) return;
  516.  
  517. // Flip Y coordinate (negate it)
  518. const flippedLocation = data.l ? [data.l[0], -data.l[1]] : [0, 0];
  519.  
  520. const cursorInfo = {
  521. name: data.n || "",
  522. location: flippedLocation,
  523. color: data.c || 0
  524. };
  525.  
  526. this.state.cursors.set(data.id, cursorInfo);
  527.  
  528. if (data.n) {
  529. this.state.userPositions.set(data.n, flippedLocation);
  530. this.state.userIds.set(data.n, data.id);
  531. }
  532.  
  533. // Flip Y for bot's own position
  534. if (data.n === this.config.username && data.l) {
  535. this.config.position.x = data.l[0];
  536. this.config.position.y = -data.l[1]; // Flipped Y
  537. }
  538. }
  539. onCursorLeft(id) {
  540. const cursor = this.state.cursors.get(id);
  541. if (cursor && cursor.name) {
  542. this.state.userPositions.delete(cursor.name);
  543. }
  544. this.state.cursors.delete(id);
  545. }
  546. onPerms(level) {
  547. this.state.perms = level;
  548. const permName = ["User", "Member", "Owner"][level] || "Unknown";
  549. console.log(`[PERMS] ${permName} (${level})`);
  550. }
  551. onMemberAdded(member) {
  552. console.log(`[MEMBER+] ${member}`);
  553. if (!this.state.members.includes(member)) {
  554. this.state.members.push(member);
  555. }
  556. }
  557. onMemberList(members) {
  558. this.state.members = members || [];
  559. console.log(`[MEMBERS] ${this.state.members.join(", ") || "None"}`);
  560. }
  561. onWallList(walls) {
  562. this.state.walllist = walls || [];
  563. console.log(`[WALLS] ${walls.length / 2} wall(s) available`);
  564. }
  565. onReadonly(state) {
  566. this.state.readonly = state;
  567. if (state) console.log("[STATE] Wall is now READONLY");
  568. }
  569. onHideCursors(state) {
  570. this.state.hidecursors = state;
  571. if (state) console.log("[STATE] Cursors are now HIDDEN");
  572. }
  573. onDisableChat(state) {
  574. this.state.disablechat = state;
  575. if (state) console.log("[STATE] Chat is DISABLED");
  576. }
  577. onDisableColor(state) {
  578. this.state.disablecolor = state;
  579. if (state) console.log("[STATE] Colors are DISABLED");
  580. }
  581. onDisableBraille(state) {
  582. this.state.disablebraille = state;
  583. if (state) console.log("[STATE] Braille is DISABLED");
  584. }
  585. onNameTaken() {
  586. console.log("[ERROR] Name is already taken!");
  587. }
  588. onPassFail() {
  589. console.log("[ERROR] Invalid password!");
  590. }
  591. onTokenFail() {
  592. console.log("[ERROR] Invalid token!");
  593. }
  594. onRegClosed() {
  595. console.log("[ERROR] Registration is closed!");
  596. }
  597. onNameChanged(name) {
  598. console.log(`[OK] Name changed to: ${name}`);
  599. this.config.username = name;
  600. }
  601. onAccountDeleted() {
  602. console.log("[ERROR] Account has been deleted!");
  603. }
  604. onPong(ms) {}
  605. handleCommand(message, sender, messageData) {
  606. const userId = messageData.id || this.getUserId(sender);
  607. if (userId && this.isIdBanned(userId)) {
  608. this.sendMessage("ERR: your id banned from using bot.");
  609. return;
  610. }
  611. if (this.isBanned(sender)) {
  612. this.sendMessage("You're banned.");
  613. return;
  614. }
  615. const commandLine = message.slice(this.config.prefix.length);
  616. const [command, ...args] = commandLine.split(/\s+/);
  617. const cmd = command.toLowerCase();
  618. this.state.lastSayUser = sender;
  619. const cooldownKey = `${cmd}-${sender}`;
  620. const lastUsed = this.state.commandCooldowns.get(cooldownKey) || 0;
  621. const now = Date.now();
  622. const hasAuth = this.isAuthorized(sender, messageData.isAdmin);
  623. if (now - lastUsed < 2000 && !hasAuth) {
  624. return;
  625. }
  626. this.state.commandCooldowns.set(cooldownKey, now);
  627. this.executeCommand(cmd, args, sender, messageData);
  628. }
  629. executeCommand(command, args, sender, messageData) {
  630. const hasAuth = this.isAuthorized(sender, messageData.isAdmin);
  631. const commands = {
  632. help: () => this.cmdHelp(args),
  633. thelp: () => this.cmdTypeHelp(args),
  634. fullcmd: () => this.cmdFullcmd(),
  635. info: () => this.cmdInfo(),
  636. chl: () => this.cmdChangelog(args),
  637. calculate: () => this.cmdCalculate(args),
  638. calc2: () => this.cmdTetration(args),
  639. rng: () => this.cmdRandom(args),
  640. timer: () => this.cmdTimer(args),
  641. say: () => this.cmdSay(args, sender, messageData.isAdmin),
  642. count: () => this.cmdCount(args),
  643. tcountdown: () => this.cmdTypeCountdown(args),
  644. status: () => this.cmdStatus(),
  645. pos: () => this.cmdPosition(args, sender),
  646. page: () => this.cmdPage(args),
  647. members: () => this.cmdMembers(),
  648. walls: () => this.cmdWalls(),
  649. authlist: () => this.cmdAuthList(),
  650. userlist: () => this.cmdUserList(),
  651. to: () =>
  652. hasAuth ? this.cmdTeleport(args) : this.sendMessage("Permission invalid - Authority required"),
  653. tp: () =>
  654. hasAuth ? this.cmdTp(args) : this.sendMessage("Permission invalid - Authority required"),
  655. type: () =>
  656. hasAuth ? this.cmdType(args) : this.sendMessage("Permission invalid - Authority required"),
  657. colorid: () => (hasAuth ? this.cmdColor(args) : this.sendMessage("Permission invalid")),
  658. cleararea: () =>
  659. hasAuth ? this.cmdClearArea(args) : this.sendMessage("Permission invalid - Authority required"),
  660. csay: () =>
  661. hasAuth ? this.cmdColoredSay(args) : this.sendMessage("Permission invalid - Authority required"),
  662. addauth: () =>
  663. hasAuth ? this.cmdAddAuth(args) : this.sendMessage("Permission invalid - Authority required"),
  664. removeauth: () =>
  665. hasAuth ? this.cmdRemoveAuth(args) : this.sendMessage("Permission invalid - Authority required"),
  666. ban: () => (hasAuth ? this.cmdBan(args) : this.sendMessage("Permission invalid - Authority required")),
  667. unban: () =>
  668. hasAuth ? this.cmdUnban(args) : this.sendMessage("Permission invalid - Authority required"),
  669. banid: () =>
  670. hasAuth ? this.cmdBanId(args) : this.sendMessage("Permission invalid - Authority required"),
  671. unbanid: () =>
  672. hasAuth ? this.cmdUnbanId(args) : this.sendMessage("Permission invalid - Authority required"),
  673. banlist: () =>
  674. hasAuth ? this.cmdBanList() : this.sendMessage("Permission invalid - Authority required"),
  675. disablehs: () =>
  676. hasAuth
  677. ? this.cmdDisableHeightSafety()
  678. : this.sendMessage("Permission invalid - Authority required"),
  679. echoauth: () =>
  680. hasAuth ? this.cmdToggleEcho() : this.sendMessage("Permission invalid - Authority required"),
  681. echocolor: () =>
  682. hasAuth ? this.cmdToggleEchoColor() : this.sendMessage("Permission invalid - Authority required"),
  683. };
  684. const cmdFunc = commands[command];
  685. if (cmdFunc) {
  686. cmdFunc();
  687. }
  688. }
  689. cmdHelp(args) {
  690. const pageInput = args[0];
  691. if (pageInput !== undefined && (isNaN(pageInput) || !Number.isInteger(Number(pageInput)))) {
  692. this.sendMessage("Invalid number.");
  693. return;
  694. }
  695. const page = parseInt(pageInput) || 1;
  696. const maxPage = Object.keys(COMMAND_PAGES).length;
  697. if (page < 1 || page > maxPage) {
  698. this.sendMessage(`Invalid number. Use ${this.config.prefix}help 1-${maxPage}`);
  699. return;
  700. }
  701. this.sendMessage(`Commands Page ${page}/${maxPage}:`);
  702. const commands = COMMAND_PAGES[page];
  703. commands.forEach((cmd, index) => {
  704. setTimeout(
  705. () => {
  706. this.sendMessage(
  707. `${INVISIBLE_CHAR}${this.config.prefix}${cmd.cmd}${cmd.auth ? " [A]" : ""} - ${cmd.desc}`
  708. );
  709. },
  710. (index + 1) * 700
  711. );
  712. });
  713. }
  714. cmdChangelog(args) {
  715. const pageInput = args[0];
  716. if (pageInput !== undefined && (isNaN(pageInput) || !Number.isInteger(Number(pageInput)))) {
  717. this.sendMessage("Invalid number.");
  718. return;
  719. }
  720. const itemsPerPage = 5;
  721. const totalPages = Math.ceil(CHANGELOG.length / itemsPerPage);
  722. const page = parseInt(pageInput) || 1;
  723.  
  724. if (page < 1 || page > totalPages) {
  725. this.sendMessage(`Invalid number. Use ${this.config.prefix}chl 1-${totalPages}`);
  726. return;
  727. }
  728.  
  729. const startIndex = (page - 1) * itemsPerPage;
  730. const endIndex = Math.min(startIndex + itemsPerPage, CHANGELOG.length);
  731. const pageEntries = CHANGELOG.slice(startIndex, endIndex);
  732.  
  733. this.sendMessage(`Changelog Page ${page}/${totalPages}:`);
  734.  
  735. pageEntries.forEach((entry, index) => {
  736. setTimeout(
  737. () => {
  738. this.sendMessage(`${INVISIBLE_CHAR}v${entry.version}: ${entry.changes}`);
  739. },
  740. (index + 1) * 700
  741. );
  742. });
  743. }
  744. cmdTypeCountdown(args) {
  745. if (this.state.countdownActive) {
  746. this.sendMessage("Countdown already active!");
  747. return;
  748. }
  749.  
  750. if (args.length < 1) {
  751. this.sendMessage(`Usage: ${this.config.prefix}tcountdown [seconds]`);
  752. return;
  753. }
  754.  
  755. const startSeconds = parseInt(args[0]);
  756. if (isNaN(startSeconds) || startSeconds <= 0) {
  757. this.sendMessage("Error: seconds must be a positive integer");
  758. return;
  759. }
  760.  
  761. if (startSeconds > 86400) { // 24 hours max
  762. this.sendMessage("Error: seconds cannot exceed 86400 (24 hours)");
  763. return;
  764. }
  765.  
  766. if (typeof w.tp !== 'function' || typeof w.typeChar !== 'function') {
  767. this.sendMessage("Error: w.tp or w.typeChar function not available");
  768. return;
  769. }
  770.  
  771. this.state.countdownActive = true;
  772. let currentSeconds = startSeconds;
  773. const startX = 0;
  774. const startY = -5;
  775. const endX = 25;
  776.  
  777. this.sendMessage(`Starting countdown from ${startSeconds}s at (${startX}, ${startY})...`);
  778.  
  779. const countdownInterval = setInterval(() => {
  780. if (!this.running || !this.state.countdownActive || currentSeconds < 0) {
  781. clearInterval(countdownInterval);
  782. this.state.countdownActive = false;
  783. if (currentSeconds < 0) {
  784. this.sendMessage("Countdown complete!");
  785. }
  786. return;
  787. }
  788.  
  789. try {
  790. // Teleport to start position
  791. w.tp(startX, startY);
  792.  
  793. // Format time
  794. const hours = Math.floor(currentSeconds / 3600);
  795. const minutes = Math.floor((currentSeconds % 3600) / 60);
  796. const seconds = currentSeconds % 60;
  797.  
  798. let timeStr = "";
  799. if (hours > 0) {
  800. timeStr += `${hours}h `;
  801. }
  802. if (minutes > 0) {
  803. timeStr += `${minutes}m `;
  804. }
  805. if (seconds > 0 || timeStr === "") {
  806. timeStr += `${seconds}s`;
  807. }
  808. timeStr = timeStr.trim();
  809.  
  810. // Type the countdown
  811. for (let char of timeStr) {
  812. w.typeChar(char, 1);
  813. }
  814.  
  815. // Calculate how many spaces needed to reach endX
  816. const charsTyped = timeStr.length;
  817. const spacesNeeded = endX - charsTyped;
  818.  
  819. // Type spaces until endX
  820. for (let i = 0; i < spacesNeeded; i++) {
  821. w.typeChar(' ', 1);
  822. }
  823.  
  824. console.log(`[TCOUNTDOWN] Typed "${timeStr}" at (${startX}, ${startY})`);
  825. } catch (e) {
  826. console.error(`[TCOUNTDOWN ERROR] Failed to type countdown:`, e);
  827. clearInterval(countdownInterval);
  828. this.state.countdownActive = false;
  829. return;
  830. }
  831.  
  832. currentSeconds--;
  833. }, 1000);
  834. }
  835. async cmdClearArea(args) {
  836. if (this.state.clearingArea) {
  837. this.sendMessage("Already clearing area! Please wait.");
  838. return;
  839. }
  840.  
  841. if (args.length !== 2 && args.length !== 4) {
  842. this.sendMessage(`Usage: ${this.config.prefix}cleararea x y OR x1 y1 x2 y2`);
  843. return;
  844. }
  845.  
  846. if (typeof w.tp !== 'function' || typeof w.typeChar !== 'function') {
  847. this.sendMessage("Error: w.tp or w.typeChar function not available");
  848. return;
  849. }
  850.  
  851. if (args.length === 2) {
  852. // Single point mode
  853. const x = parseInt(args[0]);
  854. const y = parseInt(args[1]);
  855.  
  856. if (isNaN(x) || isNaN(y)) {
  857. this.sendMessage("Invalid coordinates. Please provide integers.");
  858. return;
  859. }
  860.  
  861. // Negate Y
  862. const flippedY = -y;
  863.  
  864. try {
  865. this.state.clearingArea = true;
  866. w.tp(x, flippedY);
  867. w.typeChar(' ', 1);
  868. this.sendMessage(`Cleared position (${x}, ${y})`);
  869. console.log(`[CLEARAREA] Cleared single point at (${x}, ${flippedY})`);
  870. } catch (e) {
  871. this.sendMessage(`Error clearing area: ${e.message || "Unknown error"}`);
  872. console.error(`[CLEARAREA ERROR]`, e);
  873. } finally {
  874. this.state.clearingArea = false;
  875. }
  876. } else {
  877. // Rectangle mode
  878. const x1 = parseInt(args[0]);
  879. const y1 = parseInt(args[1]);
  880. const x2 = parseInt(args[2]);
  881. const y2 = parseInt(args[3]);
  882.  
  883. if (isNaN(x1) || isNaN(y1) || isNaN(x2) || isNaN(y2)) {
  884. this.sendMessage("Invalid coordinates. Please provide integers.");
  885. return;
  886. }
  887.  
  888. // Negate Y coordinates
  889. const flippedY1 = -y1;
  890. const flippedY2 = -y2;
  891.  
  892. // Calculate bounds
  893. const minX = Math.min(x1, x2);
  894. const maxX = Math.max(x1, x2);
  895. const minY = Math.min(flippedY1, flippedY2);
  896. const maxY = Math.max(flippedY1, flippedY2);
  897.  
  898. const width = maxX - minX + 1;
  899. const height = maxY - minY + 1;
  900. const totalChars = width * height;
  901.  
  902. if (totalChars > 10000) {
  903. this.sendMessage("Error: Area too large (max 10000 characters)");
  904. return;
  905. }
  906.  
  907. this.sendMessage(`Clearing area from (${x1}, ${y1}) to (${x2}, ${y2})...`);
  908. this.state.clearingArea = true;
  909.  
  910. try {
  911. for (let y = minY; y <= maxY; y++) {
  912. if (!this.running || !this.state.clearingArea) break;
  913. w.tp(minX, y);
  914. for (let x = minX; x <= maxX; x++) {
  915. if (!this.running || !this.state.clearingArea) break;
  916. w.typeChar(' ', 1);
  917. await new Promise(resolve => setTimeout(resolve, 10));
  918. }
  919. }
  920. this.sendMessage(`Cleared ${width}x${height} area (${totalChars} chars)`);
  921. console.log(`[CLEARAREA] Cleared rectangle from (${minX}, ${minY}) to (${maxX}, ${maxY})`);
  922. } catch (e) {
  923. this.sendMessage(`Error clearing area: ${e.message || "Unknown error"}`);
  924. console.error(`[CLEARAREA ERROR]`, e);
  925. } finally {
  926. this.state.clearingArea = false;
  927. }
  928. }
  929. }
  930. cmdUserList() {
  931. const onlineUsers = [];
  932.  
  933. // Use Array.from(w.cursors) for cursor detection
  934. try {
  935. if (typeof w !== 'undefined' && w.cursors) {
  936. const cursors = Array.from(w.cursors);
  937. for (let [id, cursor] of cursors) {
  938. if (cursor && cursor.name && !onlineUsers.includes(cursor.name)) {
  939. onlineUsers.push(cursor.name);
  940. }
  941. }
  942. } else {
  943. // Fallback to state.cursors
  944. for (let cursor of this.state.cursors.values()) {
  945. if (cursor.name && !onlineUsers.includes(cursor.name)) {
  946. onlineUsers.push(cursor.name);
  947. }
  948. }
  949. }
  950. } catch (e) {
  951. console.error(`[USERLIST ERROR]`, e);
  952. // Fallback to state.cursors
  953. for (let cursor of this.state.cursors.values()) {
  954. if (cursor.name && !onlineUsers.includes(cursor.name)) {
  955. onlineUsers.push(cursor.name);
  956. }
  957. }
  958. }
  959.  
  960. // Sort alphabetically
  961. onlineUsers.sort();
  962.  
  963. if (onlineUsers.length === 0) {
  964. this.sendMessage("Online Users: None");
  965. } else {
  966. this.sendMessage(`Online Users: ${onlineUsers.join(", ")}`);
  967. }
  968.  
  969. console.log(`[USERLIST] ${onlineUsers.length} users online: ${onlineUsers.join(", ")}`);
  970. }
  971. cmdTypeHelp(args) {
  972. if (this.state.isTyping) {
  973. this.sendMessage("Bot is already typing. Please wait.");
  974. return;
  975. }
  976. const pageInput = args[0];
  977. if (!pageInput || isNaN(pageInput) || !Number.isInteger(Number(pageInput))) {
  978. this.sendMessage(`Usage: ${this.config.prefix}thelp [page number]`);
  979. return;
  980. }
  981. const page = parseInt(pageInput);
  982. const maxPage = Object.keys(COMMAND_PAGES).length;
  983. if (page < 1 || page > maxPage) {
  984. this.sendMessage(`Invalid page. Use ${this.config.prefix}thelp 1-${maxPage}`);
  985. return;
  986. }
  987. if (typeof w.typeChar !== "function") {
  988. this.sendMessage("Error: typeChar function not available");
  989. return;
  990. }
  991. const commands = COMMAND_PAGES[page];
  992. const lines = [`Commands [PAGE: ${page}]`];
  993. commands.forEach((cmd) => {
  994. lines.push(`${this.config.prefix}${cmd.cmd}${cmd.auth ? " [A]" : ""} - ${cmd.desc}`);
  995. });
  996. this.state.isTyping = true;
  997. const startX = this.config.position.x;
  998. let currentY = this.config.position.y;
  999. let lineIndex = 0;
  1000. let charIndex = 0;
  1001. this.sendMessage(`Typing help page ${page} on wall...`);
  1002. const typeNextChar = () => {
  1003. if (!this.running || !this.state.isTyping) {
  1004. this.state.isTyping = false;
  1005. return;
  1006. }
  1007. if (lineIndex >= lines.length) {
  1008. this.state.isTyping = false;
  1009. console.log(`[THELP] Finished typing help page ${page}`);
  1010. return;
  1011. }
  1012. const currentLine = lines[lineIndex];
  1013. if (charIndex >= currentLine.length) {
  1014. this.teleportCursor(startX, currentY + 1);
  1015. currentY++;
  1016. lineIndex++;
  1017. charIndex = 0;
  1018. if (lineIndex < lines.length) {
  1019. setTimeout(typeNextChar, 100);
  1020. } else {
  1021. this.state.isTyping = false;
  1022. console.log(`[THELP] Finished typing help page ${page}`);
  1023. }
  1024. return;
  1025. }
  1026. try {
  1027. const char = currentLine[charIndex];
  1028. w.typeChar(char, 1);
  1029. charIndex++;
  1030. setTimeout(typeNextChar, 30);
  1031. } catch (e) {
  1032. console.error(`[THELP ERROR] Failed to type character:`, e);
  1033. this.state.isTyping = false;
  1034. }
  1035. };
  1036. this.teleportCursor(startX, currentY);
  1037. typeNextChar();
  1038. }
  1039. cmdFullcmd() {
  1040. this.sendMessage("if you wanna see all the commands, head to ~KiwiTest/diamondbot");
  1041. }
  1042. cmdInfo() {
  1043. this.sendMessage(`This bot was made by KiwiTest, version ${this.config.version}`);
  1044. }
  1045. cmdPage(args) {
  1046. const page = parseInt(args[0]) || 1;
  1047. const maxPage = Object.keys(COMMAND_PAGES).length;
  1048. if (page < 1 || page > maxPage) {
  1049. this.sendMessage(`Invalid page. Pages: 1-${maxPage}`);
  1050. return;
  1051. }
  1052. this.sendMessage(`Page ${page} Detailed Info:`);
  1053. const commands = COMMAND_PAGES[page];
  1054. commands.forEach((cmd, i) => {
  1055. setTimeout(
  1056. () => {
  1057. this.sendMessage(`${i + 1}. ${INVISIBLE_CHAR}${this.config.prefix}${cmd.cmd} - ${cmd.desc}`);
  1058. },
  1059. (i + 1) * 700
  1060. );
  1061. });
  1062. }
  1063. cmdSay(args, sender, isAdmin) {
  1064. if (args.length < 1) {
  1065. this.sendMessage(`Usage: ${this.config.prefix}say [message]`);
  1066. return;
  1067. }
  1068. const message = args.join(" ");
  1069. if (this.containsAuthorityCommand(message)) {
  1070. const hasAuth = this.isAuthorized(sender, isAdmin);
  1071. if (!hasAuth) {
  1072. this.sendMessage("ERR: trying to bypass authority!");
  1073. console.log(`[SECURITY] User ${sender} attempted to bypass authority with say command!`);
  1074. return;
  1075. }
  1076. }
  1077. this.sendMessage(message);
  1078. }
  1079. cmdType(args) {
  1080. if (args.length < 2) {
  1081. this.sendMessage(`Usage: ${this.config.prefix}type text step (step can be number or 'all')`);
  1082. return;
  1083. }
  1084. const text = args.slice(0, -1).join(" ");
  1085. const stepArg = args[args.length - 1].toLowerCase();
  1086. if (text.length === 0) {
  1087. this.sendMessage("Error: No text provided");
  1088. return;
  1089. }
  1090. if (typeof w.typeChar !== "function") {
  1091. this.sendMessage("Error: typeChar function not available");
  1092. return;
  1093. }
  1094. if (stepArg === "all") {
  1095. let delay = 0;
  1096. for (let i = 0; i < text.length; i++) {
  1097. const char = text[i];
  1098. setTimeout(() => {
  1099. try {
  1100. w.typeChar(char, i);
  1101. console.log(`[TYPE] Typed '${char}' at step ${i}`);
  1102. } catch (e) {
  1103. console.error(`[TYPE ERROR] Failed to type '${char}' at step ${i}:`, e);
  1104. }
  1105. }, delay);
  1106. delay += 50;
  1107. }
  1108. this.sendMessage(`Typing "${text}" across ${text.length} steps`);
  1109. return;
  1110. }
  1111. const step = parseInt(stepArg);
  1112. if (isNaN(step)) {
  1113. this.sendMessage("Error: Step must be a number or 'all'");
  1114. return;
  1115. }
  1116. if (step < 0) {
  1117. this.sendMessage("Error: Step must be non-negative");
  1118. return;
  1119. }
  1120. try {
  1121. for (let char of text) {
  1122. w.typeChar(char, step);
  1123. }
  1124. this.sendMessage(`Typed "${text}" at step ${step}`);
  1125. console.log(`[TYPE] Typed "${text}" at step ${step}`);
  1126. } catch (e) {
  1127. this.sendMessage(`Error typing text: ${e.message || "Unknown error"}`);
  1128. console.error(`[TYPE ERROR]`, e);
  1129. }
  1130. }
  1131. cmdCount(args) {
  1132. if (args.length < 2) {
  1133. this.sendMessage(`Usage: ${this.config.prefix}count n cooldown`);
  1134. return;
  1135. }
  1136. const n = parseInt(args[0]);
  1137. const cooldown = parseInt(args[1]);
  1138. if (isNaN(n) || !Number.isInteger(n) || n <= 0) {
  1139. this.sendMessage("Error: n must be a positive integer");
  1140. return;
  1141. }
  1142. if (isNaN(cooldown) || !Number.isInteger(cooldown) || cooldown < 100) {
  1143. this.sendMessage("Error: cooldown must be an integer >= 100 (milliseconds)");
  1144. return;
  1145. }
  1146. if (n > 100) {
  1147. this.sendMessage("Error: n cannot exceed 100");
  1148. return;
  1149. }
  1150. const countId = Date.now();
  1151. let current = 1;
  1152. this.sendMessage(`Starting count to ${n} with ${cooldown}ms delay...`);
  1153. const intervalId = setInterval(() => {
  1154. if (current > n || !this.running) {
  1155. clearInterval(intervalId);
  1156. this.state.activeCounts.delete(countId);
  1157. if (current > n) {
  1158. this.sendMessage(`Count complete!`);
  1159. }
  1160. return;
  1161. }
  1162. this.sendMessage(current.toString());
  1163. current++;
  1164. }, cooldown);
  1165. this.state.activeCounts.set(countId, { intervalId, max: n });
  1166. }
  1167. cmdColoredSay(args) {
  1168. if (args.length < 2) {
  1169. this.sendMessage(`Usage: ${this.config.prefix}csay [colorid] [text]`);
  1170. return;
  1171. }
  1172. const colorInput = args[0].toLowerCase();
  1173. let colorIndex;
  1174. if (!isNaN(colorInput)) {
  1175. colorIndex = parseInt(colorInput);
  1176. if (colorIndex < 0 || colorIndex > 15) {
  1177. this.sendMessage("Invalid colorid");
  1178. return;
  1179. }
  1180. } else if (colorInput.startsWith("#")) {
  1181. colorIndex = COLORS[colorInput];
  1182. if (colorIndex === undefined) {
  1183. this.sendMessage("Invalid colorid");
  1184. return;
  1185. }
  1186. } else {
  1187. this.sendMessage("Invalid colorid");
  1188. return;
  1189. }
  1190. const text = args.slice(1).join(" ");
  1191. if (!text || text.trim().length === 0) {
  1192. this.sendMessage("Invalid text characters");
  1193. return;
  1194. }
  1195. const originalColor = this.config.color;
  1196. this.setColor(colorIndex);
  1197. setTimeout(() => {
  1198. this.sendMessage(text);
  1199. setTimeout(() => {
  1200. this.setColor(originalColor);
  1201. }, 100);
  1202. }, 100);
  1203. }
  1204. cmdCalculate(args) {
  1205. if (args.length < 2) {
  1206. this.sendMessage(`Usage: ${this.config.prefix}calculate base exponent`);
  1207. return;
  1208. }
  1209. try {
  1210. const base = args[0];
  1211. const exp = args[1];
  1212. const result = window.Decimal.pow(new window.Decimal(base), new window.Decimal(exp));
  1213. this.sendMessage(`${base}^${exp} = ${result.toString()}`);
  1214. } catch (error) {
  1215. this.sendMessage("Error: Invalid input for calculation");
  1216. }
  1217. }
  1218. cmdTetration(args) {
  1219. if (args.length < 2) {
  1220. this.sendMessage(`Usage: ${this.config.prefix}calc2 base height`);
  1221. return;
  1222. }
  1223. try {
  1224. const base = args[0];
  1225. const height = parseInt(args[1]);
  1226. if (height < 0 || !Number.isInteger(height)) {
  1227. this.sendMessage("Height must be a non-negative integer");
  1228. return;
  1229. }
  1230. if (this.config.heightSafetyEnabled && height > 5) {
  1231. this.sendMessage(`Height too large! Maximum is 5 (Height Safety ON)`);
  1232. return;
  1233. }
  1234. const result = window.Decimal.tetrate(new window.Decimal(base), height);
  1235. this.sendMessage(`${base}^^${height} = ${result.toString()}`);
  1236. } catch (error) {
  1237. this.sendMessage("Error: Invalid input for tetration");
  1238. }
  1239. }
  1240. cmdRandom(args) {
  1241. if (args.length < 2) {
  1242. this.sendMessage(`Usage: ${this.config.prefix}rng min max`);
  1243. return;
  1244. }
  1245. const min = parseFloat(args[0]);
  1246. const max = parseFloat(args[1]);
  1247. if (isNaN(min) || isNaN(max)) {
  1248. this.sendMessage("Invalid input. Please provide valid numbers.");
  1249. return;
  1250. }
  1251. if (min > max) {
  1252. this.sendMessage("Min must be less than or equal to max.");
  1253. return;
  1254. }
  1255. const randomNum = Math.random() * (max - min) + min;
  1256. this.sendMessage(`Random number between ${min} and ${max}: ${randomNum.toFixed(2)}`);
  1257. }
  1258. cmdTimer(args) {
  1259. if (args.length < 3) {
  1260. this.sendMessage(`Usage: ${this.config.prefix}timer hours minutes seconds (use 0 to skip)`);
  1261. return;
  1262. }
  1263. const hours = Math.max(0, parseInt(args[0]) || 0);
  1264. const minutes = Math.max(0, parseInt(args[1]) || 0);
  1265. const seconds = Math.max(0, parseInt(args[2]) || 0);
  1266. if (hours === 0 && minutes === 0 && seconds === 0) {
  1267. this.sendMessage("Timer must have at least one non-zero value");
  1268. return;
  1269. }
  1270. if (hours > 24) {
  1271. this.sendMessage("Maximum timer is 24 hours");
  1272. return;
  1273. }
  1274. const totalMs = (hours * 3600 + minutes * 60 + seconds) * 1000;
  1275. let timeStr = [];
  1276. if (hours > 0) timeStr.push(`${hours}h`);
  1277. if (minutes > 0) timeStr.push(`${minutes}m`);
  1278. if (seconds > 0) timeStr.push(`${seconds}s`);
  1279. const timerId = Date.now();
  1280. this.sendMessage(`Timer set for ${timeStr.join(" ")} (ID: ${timerId})`);
  1281. const timerObj = setTimeout(() => {
  1282. this.sendMessage(`TIMER COMPLETE! ${timeStr.join(" ")} has elapsed (ID: ${timerId})`);
  1283. this.state.activeTimers.delete(timerId);
  1284. }, totalMs);
  1285. this.state.activeTimers.set(timerId, {
  1286. timeout: timerObj,
  1287. duration: timeStr.join(" "),
  1288. startTime: Date.now(),
  1289. endTime: Date.now() + totalMs,
  1290. });
  1291. if (totalMs > 60000) {
  1292. let updateCount = 0;
  1293. const maxUpdates = 3;
  1294. const updateInterval = Math.max(30000, totalMs / 4);
  1295. const intervalId = setInterval(() => {
  1296. const timer = this.state.activeTimers.get(timerId);
  1297. if (!timer || updateCount >= maxUpdates) {
  1298. clearInterval(intervalId);
  1299. return;
  1300. }
  1301. const remaining = timer.endTime - Date.now();
  1302. if (remaining > 1000) {
  1303. const h = Math.floor(remaining / 3600000);
  1304. const m = Math.floor((remaining % 3600000) / 60000);
  1305. const s = Math.floor((remaining % 60000) / 1000);
  1306. let remStr = [];
  1307. if (h > 0) remStr.push(`${h}h`);
  1308. if (m > 0) remStr.push(`${m}m`);
  1309. if (s > 0) remStr.push(`${s}s`);
  1310. this.sendMessage(`Timer ${timerId}: ${remStr.join(" ")} remaining`);
  1311. updateCount++;
  1312. }
  1313. }, updateInterval);
  1314. this.state.activeTimers.get(timerId).intervalId = intervalId;
  1315. }
  1316. }
  1317. cmdStatus() {
  1318. const status = [
  1319. `Wall: ${this.state.wall}/${this.state.subwall}`,
  1320. `Perms: ${["User", "Member", "Owner"][this.state.perms]}`,
  1321. `Pos: (${this.config.position.x}, ${this.config.position.y})`,
  1322. `Timers: ${this.state.activeTimers.size}`,
  1323. `Color: ${this.config.color}`,
  1324. `HS: ${this.config.heightSafetyEnabled ? "ON" : "OFF"}`,
  1325. `Echo: ${this.config.authorityEchoEnabled ? "ON" : "OFF"}`,
  1326. `EchoColor: ${this.config.echoColorEnabled ? "ON" : "OFF"}`,
  1327. `Auth: ${this.config.authorizedUsers.length}`,
  1328. `Banned: ${this.config.bannedUsers.length}/${this.config.bannedIds.length}`,
  1329. ];
  1330. this.sendMessage(status.join(" | "));
  1331. }
  1332. cmdPosition(args, sender) {
  1333. if (args.length === 0) {
  1334. const pos = this.getCursorPosition(sender);
  1335. if (pos) {
  1336. this.sendMessage(`Cursor position of ${sender}: (${pos[0]}, ${pos[1]})`);
  1337. } else {
  1338. this.sendMessage(`Cursor position of ${sender}: Not found in wall`);
  1339. }
  1340. return;
  1341. }
  1342. const targetUser = args[0];
  1343. const pos = this.getCursorPosition(targetUser);
  1344. if (pos) {
  1345. this.sendMessage(`Cursor position of ${targetUser}: (${pos[0]}, ${pos[1]})`);
  1346. } else {
  1347. this.sendMessage(`Cursor position of ${targetUser}: Not found in wall`);
  1348. }
  1349. }
  1350. cmdMembers() {
  1351. if (this.state.members.length === 0) {
  1352. this.sendMessage("No members in this wall");
  1353. } else {
  1354. this.sendMessage(`Members: ${this.state.members.join(", ")}`);
  1355. }
  1356. }
  1357. cmdWalls() {
  1358. if (this.state.walllist.length === 0) {
  1359. this.sendMessage("No subwalls available");
  1360. } else {
  1361. const walls = [];
  1362. for (let i = 0; i < this.state.walllist.length; i += 2) {
  1363. const wallName = this.state.walllist[i];
  1364. const isPrivate = this.state.walllist[i + 1];
  1365. walls.push(`${wallName}${isPrivate ? " (private)" : ""}`);
  1366. }
  1367. this.sendMessage(`Subwalls: ${walls.join(", ")}`);
  1368. }
  1369. }
  1370. cmdTeleport(args) {
  1371. if (args.length < 2) {
  1372. this.sendMessage(`Usage: ${this.config.prefix}to X Y`);
  1373. return;
  1374. }
  1375. const x = parseInt(args[0]);
  1376. const y = parseInt(args[1]);
  1377. if (isNaN(x) || isNaN(y)) {
  1378. this.sendMessage("Invalid coordinates. Please provide integers.");
  1379. return;
  1380. }
  1381. if (Math.abs(x) > 10000 || Math.abs(y) > 10000) {
  1382. this.sendMessage("Coordinates out of range (max +-10000)");
  1383. return;
  1384. }
  1385. this.teleportCursor(x, y);
  1386. this.sendMessage(`Teleported to (${x}, ${y})`);
  1387. }
  1388. cmdTp(args) {
  1389. if (args.length < 2) {
  1390. this.sendMessage(`Usage: ${this.config.prefix}tp X Y`);
  1391. return;
  1392. }
  1393. const x = parseInt(args[0]);
  1394. const y = parseInt(args[1]);
  1395. if (isNaN(x) || isNaN(y)) {
  1396. this.sendMessage("Invalid coordinates. Please provide integers.");
  1397. return;
  1398. }
  1399. if (Math.abs(x) > 10000 || Math.abs(y) > 10000) {
  1400. this.sendMessage("Coordinates out of range (max +-10000)");
  1401. return;
  1402. }
  1403.  
  1404. if (typeof w.tp !== 'function') {
  1405. this.sendMessage("Error: w.tp function not available");
  1406. return;
  1407. }
  1408.  
  1409. try {
  1410. w.tp(x, y);
  1411. this.config.position.x = x;
  1412. this.config.position.y = y;
  1413. this.sendMessage(`Teleported to (${x}, ${y}) using w.tp`);
  1414. console.log(`[TP] Teleported to (${x}, ${y}) using w.tp`);
  1415. } catch (e) {
  1416. this.sendMessage(`Error using w.tp: ${e.message || "Unknown error"}`);
  1417. console.error(`[TP ERROR]`, e);
  1418. }
  1419. }
  1420. cmdColor(args) {
  1421. if (args.length < 1) {
  1422. this.sendMessage(`Usage: ${this.config.prefix}colorid #hex or 0-15`);
  1423. return;
  1424. }
  1425. const input = args[0].toLowerCase();
  1426. let colorIndex;
  1427. if (!isNaN(input)) {
  1428. colorIndex = parseInt(input);
  1429. if (colorIndex < 0 || colorIndex > 15) {
  1430. this.sendMessage("Invalid colot");
  1431. return;
  1432. }
  1433. } else if (input.startsWith("#")) {
  1434. colorIndex = COLORS[input];
  1435. if (colorIndex === undefined) {
  1436. this.sendMessage("Invalid colot");
  1437. return;
  1438. }
  1439. } else {
  1440. this.sendMessage("Invalid colot");
  1441. return;
  1442. }
  1443. this.setColor(colorIndex);
  1444. this.sendMessage(`Color changed to ${colorIndex}`);
  1445. }
  1446. cmdBan(args) {
  1447. if (args.length < 1) {
  1448. this.sendMessage(`Usage: ${this.config.prefix}ban username`);
  1449. return;
  1450. }
  1451. const username = args[0];
  1452. if (this.config.authorizedUsers.includes(username)) {
  1453. this.sendMessage(`Cannot ban authority user ${username}`);
  1454. return;
  1455. }
  1456. if (this.config.bannedUsers.includes(username)) {
  1457. this.sendMessage(`${username} is already banned`);
  1458. return;
  1459. }
  1460. this.config.bannedUsers.push(username);
  1461. Storage.save("bannedUsers", this.config.bannedUsers);
  1462. this.sendMessage(`Banned ${username} from using bot`);
  1463. console.log(`[BAN] ${username} has been banned`);
  1464. }
  1465. cmdUnban(args) {
  1466. if (args.length < 1) {
  1467. this.sendMessage(`Usage: ${this.config.prefix}unban username or ID`);
  1468. return;
  1469. }
  1470. const input = args[0];
  1471. if (!isNaN(input)) {
  1472. const idToUnban = input;
  1473. const index = this.config.bannedIds.indexOf(idToUnban);
  1474. if (index === -1) {
  1475. this.sendMessage(`Error: ID ${idToUnban} is not banned`);
  1476. return;
  1477. }
  1478. this.config.bannedIds.splice(index, 1);
  1479. Storage.save("bannedIds", this.config.bannedIds);
  1480. this.sendMessage(`Unbanned ID ${idToUnban}`);
  1481. console.log(`[UNBAN] ID ${idToUnban} has been unbanned`);
  1482. } else {
  1483. const username = input;
  1484. const index = this.config.bannedUsers.indexOf(username);
  1485. if (index === -1) {
  1486. this.sendMessage(`Error: ${username} is not banned`);
  1487. return;
  1488. }
  1489. this.config.bannedUsers.splice(index, 1);
  1490. Storage.save("bannedUsers", this.config.bannedUsers);
  1491. this.sendMessage(`Unbanned ${username}`);
  1492. console.log(`[UNBAN] ${username} has been unbanned`);
  1493. }
  1494. }
  1495. cmdBanId(args) {
  1496. if (args.length < 1) {
  1497. this.sendMessage(`Usage: ${this.config.prefix}banid username`);
  1498. return;
  1499. }
  1500. const username = args[0];
  1501. const userId = this.getUserId(username);
  1502. if (!userId) {
  1503. this.sendMessage(`Cannot find user ID for ${username}. User must be in wall.`);
  1504. return;
  1505. }
  1506. if (this.config.authorizedUsers.includes(username)) {
  1507. this.sendMessage(`Cannot ban authority user ${username}`);
  1508. return;
  1509. }
  1510. if (this.config.bannedIds.includes(userId)) {
  1511. this.sendMessage(`User ID ${userId} is already banned`);
  1512. return;
  1513. }
  1514. this.config.bannedIds.push(userId);
  1515. Storage.save("bannedIds", this.config.bannedIds);
  1516. this.sendMessage(`Banned user ID for ${username} (ID: ${userId})`);
  1517. console.log(`[BANID] ${username} (ID: ${userId}) has been banned`);
  1518. }
  1519. cmdUnbanId(args) {
  1520. if (args.length < 1) {
  1521. this.sendMessage(`Usage: ${this.config.prefix}unbanid userid`);
  1522. return;
  1523. }
  1524. const userId = args[0];
  1525. const index = this.config.bannedIds.indexOf(userId);
  1526. if (index === -1) {
  1527. this.sendMessage(`ID ${userId} is not banned`);
  1528. return;
  1529. }
  1530. this.config.bannedIds.splice(index, 1);
  1531. Storage.save("bannedIds", this.config.bannedIds);
  1532. this.sendMessage(`Unbanned ID ${userId}`);
  1533. console.log(`[UNBANID] ID ${userId} has been unbanned`);
  1534. }
  1535. cmdBanList() {
  1536. const userBans = this.config.bannedUsers.length === 0 ? "None" : this.config.bannedUsers.join(", ");
  1537. const idBans = this.config.bannedIds.length === 0 ? "None" : `${this.config.bannedIds.length} IDs`;
  1538. this.sendMessage(`Banned users: ${userBans} | Banned IDs: ${idBans}`);
  1539. }
  1540. cmdAddAuth(args) {
  1541. if (args.length < 1) {
  1542. this.sendMessage(`Usage: ${this.config.prefix}addauth username`);
  1543. return;
  1544. }
  1545. const username = args[0];
  1546. if (this.config.authorizedUsers.includes(username)) {
  1547. this.sendMessage(`${username} already has authority`);
  1548. return;
  1549. }
  1550. const banIndex = this.config.bannedUsers.indexOf(username);
  1551. if (banIndex !== -1) {
  1552. this.config.bannedUsers.splice(banIndex, 1);
  1553. Storage.save("bannedUsers", this.config.bannedUsers);
  1554. }
  1555. this.config.authorizedUsers.push(username);
  1556. Storage.save("authorizedUsers", this.config.authorizedUsers);
  1557. this.sendMessage(`Added ${username} to authority list`);
  1558. console.log(`[AUTH+] Authority granted to: ${username}`);
  1559. }
  1560. cmdRemoveAuth(args) {
  1561. if (args.length < 1) {
  1562. this.sendMessage(`Usage: ${this.config.prefix}removeauth username`);
  1563. return;
  1564. }
  1565. const username = args[0];
  1566. if (username === "Diamond25" || username === "KiwiTest") {
  1567. this.sendMessage(`Cannot remove default authority from ${username}`);
  1568. return;
  1569. }
  1570. const index = this.config.authorizedUsers.indexOf(username);
  1571. if (index === -1) {
  1572. this.sendMessage(`${username} doesn't have authority`);
  1573. return;
  1574. }
  1575. this.config.authorizedUsers.splice(index, 1);
  1576. Storage.save("authorizedUsers", this.config.authorizedUsers);
  1577. this.sendMessage(`Removed ${username} from authority list`);
  1578. console.log(`[AUTH-] Authority revoked from: ${username}`);
  1579. }
  1580. cmdDisableHeightSafety() {
  1581. this.config.heightSafetyEnabled = !this.config.heightSafetyEnabled;
  1582. const status = this.config.heightSafetyEnabled ? "ENABLED" : "DISABLED";
  1583. const info = this.config.heightSafetyEnabled ? "(Max height: 5)" : "(No height limit)";
  1584. this.sendMessage(`Height safety is now ${status} ${info}`);
  1585. console.log(`Height safety: ${status}`);
  1586. }
  1587. cmdToggleEcho() {
  1588. if (!this.config.authorityEchoEnabled) {
  1589. this.config.authorityEchoEnabled = true;
  1590. this.sendMessage("Authority echo is now ENABLED (with recursion protection)");
  1591. } else {
  1592. this.config.authorityEchoEnabled = false;
  1593. this.sendMessage("Authority echo is now DISABLED");
  1594. }
  1595. console.log(`Authority echo: ${this.config.authorityEchoEnabled ? "ENABLED" : "DISABLED"}`);
  1596. }
  1597. cmdToggleEchoColor() {
  1598. if (!this.config.echoColorEnabled) {
  1599. this.config.echoColorEnabled = true;
  1600. this.sendMessage("Color echo is now ENABLED (echoes authority messages with color syntax)");
  1601. } else {
  1602. this.config.echoColorEnabled = false;
  1603. this.sendMessage("Color echo is now DISABLED");
  1604. }
  1605. console.log(`Color echo: ${this.config.echoColorEnabled ? "ENABLED" : "DISABLED"}`);
  1606. }
  1607. cmdAuthList() {
  1608. const authUsers = [...this.config.authorizedUsers];
  1609. const adminUsers = Array.from(this.state.adminUsers);
  1610. const allAuth = [...new Set([...authUsers, ...adminUsers])];
  1611. this.sendMessage(`Authorized users (${allAuth.length}): ${allAuth.join(", ")}`);
  1612. }
  1613. setUsername(username) {
  1614. if (typeof api !== "undefined" && api.nick) {
  1615. api.nick(username);
  1616. } else if (typeof setNick === "function") {
  1617. setNick(username);
  1618. } else if (typeof changeNick === "function") {
  1619. changeNick(username);
  1620. }
  1621. console.log(`[USERNAME] ${username}`);
  1622. }
  1623. setColor(colorIndex) {
  1624. if (typeof api !== "undefined" && api.color) {
  1625. api.color(colorIndex);
  1626. } else if (typeof setColor === "function") {
  1627. setColor(colorIndex);
  1628. }
  1629. this.config.color = colorIndex;
  1630. console.log(`[COLOR] Set to: ${colorIndex}`);
  1631. }
  1632. teleportCursor(x, y) {
  1633. if (typeof api !== "undefined" && api.cursor) {
  1634. api.cursor(x, y);
  1635. } else if (typeof moveCursor === "function") {
  1636. moveCursor(x, y);
  1637. } else if (typeof cursor === "object" && cursor.move) {
  1638. cursor.move(x, y);
  1639. }
  1640. this.config.position.x = x;
  1641. this.config.position.y = y;
  1642. }
  1643. sendMessage(message) {
  1644. if (this.state.disablechat && !this.state.isShuttingDown) {
  1645. console.log("Chat is disabled, cannot send message");
  1646. return;
  1647. }
  1648.  
  1649. // Parse colored segments
  1650. const segments = this.parseColoredMessage(message);
  1651.  
  1652. // If message has colored segments, handle them
  1653. if (segments.length > 1 || (segments.length === 1 && segments[0].color !== null)) {
  1654. const originalColor = this.config.color;
  1655. let delay = 0;
  1656.  
  1657. segments.forEach((segment, index) => {
  1658. setTimeout(() => {
  1659. if (segment.color !== null) {
  1660. this.setColor(segment.color);
  1661. } else if (index > 0) {
  1662. this.setColor(originalColor);
  1663. }
  1664.  
  1665. setTimeout(() => {
  1666. this.state.messageQueue.push(segment.text);
  1667. if (!this.state.isProcessingQueue) {
  1668. this.processMessageQueue();
  1669. }
  1670.  
  1671. // Restore original color after last segment
  1672. if (index === segments.length - 1) {
  1673. setTimeout(() => {
  1674. this.setColor(originalColor);
  1675. }, 100);
  1676. }
  1677. }, 50);
  1678. }, delay);
  1679.  
  1680. delay += 200;
  1681. });
  1682.  
  1683. return;
  1684. }
  1685.  
  1686. // Normal message without colors
  1687. this.state.messageQueue.push(message);
  1688. if (!this.state.isProcessingQueue) {
  1689. this.processMessageQueue();
  1690. }
  1691. }
  1692. async processMessageQueue() {
  1693. if (this.state.messageQueue.length === 0 || (!this.running && !this.state.isShuttingDown)) {
  1694. this.state.isProcessingQueue = false;
  1695. return;
  1696. }
  1697. this.state.isProcessingQueue = true;
  1698. const message = this.state.messageQueue.shift();
  1699. const now = Date.now();
  1700. const timeSinceLastMessage = now - this.state.lastMessageTime;
  1701. if (timeSinceLastMessage < this.config.messageDelay) {
  1702. await new Promise((resolve) => setTimeout(resolve, this.config.messageDelay - timeSinceLastMessage));
  1703. }
  1704. this.state.lastMessageTime = Date.now();
  1705. try {
  1706. if (w && w.chat && w.chat.send) {
  1707. w.chat.send(message);
  1708. console.log(`[SENT] ${message}`);
  1709. } else {
  1710. if (typeof sendChat === "function") {
  1711. sendChat(message);
  1712. } else if (typeof api !== "undefined" && api.chat) {
  1713. api.chat(message);
  1714. } else {
  1715. console.error("No chat send method available!");
  1716. }
  1717. }
  1718. } catch (error) {
  1719. console.error("Failed to send message:", error);
  1720. }
  1721. setTimeout(() => this.processMessageQueue(), this.config.messageDelay);
  1722. }
  1723. }
  1724. console.clear();
  1725. console.log(`Starting TextWall Bot v${BOT_CONFIG.version}...`);
  1726. const bot = new TextWallBot(BOT_CONFIG);
  1727. await bot.init();
  1728. window.diamondBot = bot;
  1729. window.sendMessage = function (message) {
  1730. if (!message) {
  1731. console.error("Error: No message provided. Usage: sendMessage('your message')");
  1732. return;
  1733. }
  1734. bot.sendMessage(`[SYSTEM]: ${message}`);
  1735. console.log(`[SYSTEM MESSAGE SENT]: ${message}`);
  1736. };
  1737. window.unbanName = function (username) {
  1738. if (!username) {
  1739. console.error("Error: No username provided. Usage: unbanName('username')");
  1740. return;
  1741. }
  1742.  
  1743. const index = bot.config.bannedUsers.indexOf(username);
  1744. if (index === -1) {
  1745. console.error(`Error: ${username} is not in the ban list`);
  1746. return;
  1747. }
  1748.  
  1749. bot.config.bannedUsers.splice(index, 1);
  1750. Storage.save("bannedUsers", bot.config.bannedUsers);
  1751. console.log(`[CONSOLE UNBAN] ${username} has been unbanned from the ban list`);
  1752. console.log(`Current banned users: ${bot.config.bannedUsers.length > 0 ? bot.config.bannedUsers.join(", ") : "None"}`);
  1753. };
  1754. window.stopBot = async function () {
  1755. console.log("Initiating shutdown sequence...");
  1756. bot.state.isShuttingDown = true;
  1757. bot.state.isTyping = false;
  1758. bot.state.countdownActive = false;
  1759. bot.state.clearingArea = false;
  1760. bot.sendMessage("Closing bot..");
  1761. await new Promise((resolve) => setTimeout(resolve, 500));
  1762. bot.running = false;
  1763. bot.state.activeTimers.forEach((timer) => {
  1764. clearTimeout(timer.timeout);
  1765. if (timer.intervalId) clearInterval(timer.intervalId);
  1766. });
  1767. bot.state.activeCounts.forEach((count) => {
  1768. if (count.intervalId) clearInterval(count.intervalId);
  1769. });
  1770. for (let [event, handler] of Object.entries(bot.eventHandlers)) {
  1771. if (w && w.off) {
  1772. w.off(event, handler);
  1773. }
  1774. }
  1775. bot.sendMessage("Bot successfully shutdown.");
  1776. await new Promise((resolve) => setTimeout(resolve, 500));
  1777. bot.state.isProcessingQueue = false;
  1778. bot.state.messageQueue = [];
  1779. console.log("[OK] Bot stopped completely");
  1780. };
  1781. window.restartBot = async function () {
  1782. console.log("Restarting bot...");
  1783. await window.stopBot();
  1784. await new Promise((resolve) => setTimeout(resolve, 1000));
  1785. const newBot = new TextWallBot(BOT_CONFIG);
  1786. await newBot.init();
  1787. window.diamondBot = newBot;
  1788. console.log("[OK] Bot restarted");
  1789. };
  1790. window.botStatus = function () {
  1791. console.table({
  1792. Username: bot.config.username,
  1793. Version: bot.config.version,
  1794. Prefix: bot.config.prefix,
  1795. Wall: `${bot.state.wall}/${bot.state.subwall}`,
  1796. Position: `(${bot.config.position.x}, ${bot.config.position.y})`,
  1797. Color: bot.config.color,
  1798. Permissions: ["User", "Member", "Owner"][bot.state.perms] || "Unknown",
  1799. "Active Timers": bot.state.activeTimers.size,
  1800. "Active Counts": bot.state.activeCounts.size,
  1801. "Countdown Active": bot.state.countdownActive ? "YES" : "NO",
  1802. "Clearing Area": bot.state.clearingArea ? "YES" : "NO",
  1803. "Authorized Users": bot.config.authorizedUsers.length,
  1804. "Banned Users": bot.config.bannedUsers.length,
  1805. "Banned IDs": bot.config.bannedIds.length,
  1806. "Height Safety": bot.config.heightSafetyEnabled ? "ON" : "OFF",
  1807. "Authority Echo": bot.config.authorityEchoEnabled ? "ON" : "OFF",
  1808. "Color Echo": bot.config.echoColorEnabled ? "ON" : "OFF",
  1809. "Is Typing": bot.state.isTyping ? "YES" : "NO",
  1810. "Queue Size": bot.state.messageQueue.length,
  1811. });
  1812. };
  1813. window.showCommands = function () {
  1814. console.log("\n====================================");
  1815. console.log(` ALL BOT COMMANDS (v${BOT_CONFIG.version}) `);
  1816. console.log("====================================\n");
  1817. for (let pageNum in COMMAND_PAGES) {
  1818. console.log(`\nPAGE ${pageNum}:`);
  1819. console.log("-".repeat(50));
  1820. const page = COMMAND_PAGES[pageNum];
  1821. page.forEach((cmd) => {
  1822. const authIcon = cmd.auth ? "[A]" : " ";
  1823. const cmdName = `\\${cmd.cmd}`.padEnd(15);
  1824. console.log(`${authIcon} ${cmdName} - ${cmd.desc}`);
  1825. });
  1826. }
  1827. console.log("\n" + "=".repeat(50));
  1828. console.log("[A] = Authority Required");
  1829. console.log("Default Authorities: Diamond25, KiwiTest");
  1830. console.log("Admins (ADMIN tag) have automatic authority");
  1831. console.log("\nCONSOLE COMMANDS:");
  1832. console.log(" unbanName('username') - Unban user from ban list");
  1833. console.log("=".repeat(50) + "\n");
  1834. };
  1835. window.showColors = function () {
  1836. console.log("\n====================================");
  1837. console.log(" COLOR SYNTAX GUIDE (v7.13.3) ");
  1838. console.log("====================================\n");
  1839. console.log("Use: <start #HEXCOLOR>text<end>");
  1840. console.log("Example: <start #ff0000>Hello<end> World\n");
  1841. console.log("Available colors (HEX only):");
  1842. console.log("-".repeat(50));
  1843. console.log(" 0 - #000000 (black)");
  1844. console.log(" 1 - #ffffff (white)");
  1845. console.log(" 2 - #ff0000 (red)");
  1846. console.log(" 3 - #00ff00 (green)");
  1847. console.log(" 4 - #0000ff (blue)");
  1848. console.log(" 5 - #ffff00 (yellow)");
  1849. console.log(" 6 - #ff00ff (magenta)");
  1850. console.log(" 7 - #00ffff (cyan)");
  1851. console.log(" 8 - #808080 (gray)");
  1852. console.log(" 9 - #ff8800 (orange)");
  1853. console.log(" 10 - #8800ff (purple)");
  1854. console.log(" 11 - #0088ff (light blue)");
  1855. console.log(" 12 - #88ff00 (lime)");
  1856. console.log(" 13 - #ff0088 (pink)");
  1857. console.log(" 14 - #884400 (brown)");
  1858. console.log(" 15 - #448800 (dark green)");
  1859. console.log("=".repeat(50) + "\n");
  1860. };
  1861. window.botHelp = function () {
  1862. console.log("====================================");
  1863. console.log(` TextWall Bot v${BOT_CONFIG.version} - Help `);
  1864. console.log("====================================");
  1865. console.log(" PREFIX: \\ ");
  1866. console.log(" ");
  1867. console.log(" NEW IN v7.13.3: ");
  1868. console.log(" - 10ms cleararea cooldown ");
  1869. console.log(" - w.cursors detection for users ");
  1870. console.log(" - Improved performance ");
  1871. console.log(" ");
  1872. console.log(" CONSOLE COMMANDS: ");
  1873. console.log(" window.showCommands() - List cmds ");
  1874. console.log(" window.showColors() - Color list");
  1875. console.log(" window.sendMessage(msg) - System ");
  1876. console.log(" window.unbanName(name) - Unban ");
  1877. console.log(" window.stopBot() - Stop bot ");
  1878. console.log(" window.restartBot() - Restart ");
  1879. console.log(" window.botStatus() - Status ");
  1880. console.log(" window.botHelp() - This help ");
  1881. console.log("====================================");
  1882. };
  1883. window.botHelp();
  1884. })();
Advertisement
Comments
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • User was banned
Add Comment
Please, Sign In to add comment