RubixYT1

DianondBot v7.0 textwall [OLD WARNING!]

Nov 28th, 2025
21
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 42.52 KB | None | 0 0
  1. // TextWall Bot - diamondbot v7.0
  2. // Fixed recursion and enhanced features
  3.  
  4. (async function() {
  5. 'use strict';
  6.  
  7. // Verify tw.2s4.me API is available
  8. if (typeof w === 'undefined') {
  9. console.error("TextWall API (w) not found! Make sure you're on tw.2s4.me");
  10. return;
  11. }
  12.  
  13. // Bot Configuration
  14. const BOT_CONFIG = {
  15. username: "diamondbot",
  16. color: 0, // Color index (0-15 for textwall)
  17. prefix: "\\", // Changed prefix to backslash
  18. authorizedUsers: ["Diamond25", "KiwiTest"], // List of authorized users
  19. messageDelay: 150, // Delay between messages in ms
  20. position: { x: 0, y: 0 },
  21. heightSafetyEnabled: true, // Height safety for tetration
  22. lastAuthorityMessage: "", // Track last authority message to prevent recursion
  23. authorityEchoEnabled: false // Toggle authority echo to prevent recursion
  24. };
  25.  
  26. // State management
  27. const state = {
  28. wall: "",
  29. subwall: "",
  30. perms: 0, // 0=user, 1=member, 2=owner
  31. isRegistered: false,
  32. isAdmin: false,
  33. readonly: false,
  34. hidecursors: false,
  35. disablechat: false,
  36. disablecolor: false,
  37. disablebraille: false,
  38. members: [],
  39. walllist: [],
  40. activeTimers: new Map(),
  41. commandCooldowns: new Map(),
  42. messageQueue: [],
  43. isProcessingQueue: false,
  44. lastMessageTime: 0,
  45. cursors: new Map(),
  46. adminUsers: new Set(), // Track users with ADMIN tag
  47. processedMessages: new Set() // Track processed messages to prevent recursion
  48. };
  49.  
  50. // Color mappings for textwall
  51. const COLORS = {
  52. "#000000": 0, "#ffffff": 1, "#ff0000": 2, "#00ff00": 3,
  53. "#0000ff": 4, "#ffff00": 5, "#ff00ff": 6, "#00ffff": 7,
  54. "#808080": 8, "#ff8800": 9, "#8800ff": 10, "#0088ff": 11,
  55. "#88ff00": 12, "#ff0088": 13, "#884400": 14, "#448800": 15
  56. };
  57.  
  58. // Command pages
  59. const COMMAND_PAGES = {
  60. 1: [
  61. { cmd: "help", desc: "Show command pages", auth: false },
  62. { cmd: "phelp", desc: "Print all commands", auth: false },
  63. { cmd: "calculate", desc: "Calculate p1^p2", auth: false },
  64. { cmd: "calc2", desc: "Calculate p1^^p2 (tetration)", auth: false },
  65. { cmd: "rng", desc: "Random number between min and max", auth: false }
  66. ],
  67. 2: [
  68. { cmd: "timer", desc: "Set a timer (h m s)", auth: false },
  69. { cmd: "say", desc: "Make bot say something", auth: false },
  70. { cmd: "status", desc: "Show bot status", auth: false },
  71. { cmd: "pos", desc: "Show current position", auth: false },
  72. { cmd: "page", desc: "Show detailed page info", auth: false }
  73. ],
  74. 3: [
  75. { cmd: "members", desc: "List wall members", auth: false },
  76. { cmd: "walls", desc: "List available subwalls", auth: false },
  77. { cmd: "authlist", desc: "Show authorized users", auth: false },
  78. { cmd: "to", desc: "Teleport bot to X Y (Authority)", auth: true },
  79. { cmd: "colorid", desc: "Change bot color (Authority)", auth: true }
  80. ],
  81. 4: [
  82. { cmd: "addauth", desc: "Add user to authority list (Authority)", auth: true },
  83. { cmd: "removeauth", desc: "Remove user from authority (Authority)", auth: true },
  84. { cmd: "disableHS", desc: "Toggle height safety (Authority)", auth: true },
  85. { cmd: "echoauth", desc: "Toggle authority echo (Authority)", auth: true }
  86. ]
  87. };
  88.  
  89. // Load break_eternity.js
  90. async function loadBreakEternity() {
  91. if (typeof window.Decimal !== 'undefined') {
  92. console.log("✓ Break Eternity already loaded");
  93. return true;
  94. }
  95.  
  96. const sources = [
  97. 'https://cdn.jsdelivr.net/npm/break_eternity.js@latest/break_eternity.min.js',
  98. 'https://unpkg.com/break_eternity.js@latest/dist/break_eternity.min.js',
  99. 'https://cdnjs.cloudflare.com/ajax/libs/break_eternity.js/1.3.0/break_eternity.min.js'
  100. ];
  101.  
  102. for (let src of sources) {
  103. try {
  104. await loadScript(src);
  105. if (typeof window.Decimal !== 'undefined') {
  106. console.log(`✓ Break Eternity loaded from: ${src}`);
  107. return true;
  108. }
  109. } catch (e) {
  110. console.warn(`Failed to load from ${src}`);
  111. }
  112. }
  113.  
  114. // Fallback implementation
  115. window.Decimal = createFallbackDecimal();
  116. console.log("✓ Using fallback Decimal implementation");
  117. return true;
  118. }
  119.  
  120. function loadScript(src) {
  121. return new Promise((resolve, reject) => {
  122. const script = document.createElement('script');
  123. script.src = src;
  124. script.onload = resolve;
  125. script.onerror = reject;
  126. document.head.appendChild(script);
  127. });
  128. }
  129.  
  130. function createFallbackDecimal() {
  131. return class Decimal {
  132. constructor(value) {
  133. this.value = typeof value === 'string' || typeof value === 'number'
  134. ? parseFloat(value) || 0
  135. : value?.value || 0;
  136. }
  137.  
  138. static pow(base, exp) {
  139. const b = base instanceof Decimal ? base.value : parseFloat(base);
  140. const e = exp instanceof Decimal ? exp.value : parseFloat(exp);
  141.  
  142. if (e === 0) return new Decimal(1);
  143. if (b === 0) return new Decimal(0);
  144.  
  145. let result;
  146. if (Math.abs(e) > 308) {
  147. result = e > 0 ? Infinity : 0;
  148. } else {
  149. result = Math.pow(b, e);
  150. }
  151. return new Decimal(result);
  152. }
  153.  
  154. static tetrate(base, height) {
  155. const b = base instanceof Decimal ? base.value : parseFloat(base);
  156. const h = parseInt(height);
  157.  
  158. if (h === 0) return new Decimal(1);
  159. if (h === 1) return new Decimal(b);
  160. if (b === 0) return new Decimal(0);
  161.  
  162. const maxHeight = BOT_CONFIG.heightSafetyEnabled ? 5 : 10;
  163. let result = b;
  164. for (let i = 1; i < h && i < maxHeight; i++) {
  165. result = Math.pow(b, result);
  166. if (!isFinite(result)) break;
  167. }
  168. return new Decimal(result);
  169. }
  170.  
  171. toString() {
  172. if (!isFinite(this.value)) return this.value > 0 ? "Infinity" : "-Infinity";
  173. if (Math.abs(this.value) < 1e-6) return "0";
  174. if (Math.abs(this.value) < 1e6 && Math.abs(this.value) > 1e-3) {
  175. return this.value.toString();
  176. }
  177. return this.value.toExponential(2);
  178. }
  179. };
  180. }
  181.  
  182. // Main Bot Class
  183. class TextWallBot {
  184. constructor(config) {
  185. this.config = config;
  186. this.state = state;
  187. this.eventHandlers = {};
  188. this.running = true;
  189. }
  190.  
  191. async init() {
  192. console.log("═══════════════════════════════════");
  193. console.log(" TextWall Bot v7.0 Initializing ");
  194. console.log("═══════════════════════════════════");
  195.  
  196. // Load dependencies
  197. await loadBreakEternity();
  198.  
  199. // Set up all event listeners
  200. this.setupEventListeners();
  201.  
  202. // Set username
  203. this.setUsername(this.config.username);
  204.  
  205. // Set initial color
  206. this.setColor(this.config.color);
  207.  
  208. // Initial position
  209. this.teleportCursor(0, 0);
  210.  
  211. // Announce bot is online after a short delay
  212. setTimeout(() => {
  213. this.sendMessage(`${this.config.username} v7.0 online! Type ${this.config.prefix}help for commands`);
  214. }, 2000);
  215.  
  216. console.log("✓ Bot initialized successfully!");
  217. console.log(`✓ Prefix: ${this.config.prefix}`);
  218. console.log(`✓ Authorized users: ${this.config.authorizedUsers.join(', ')}`);
  219. console.log("═══════════════════════════════════");
  220. }
  221.  
  222. setupEventListeners() {
  223. // Store handlers for cleanup
  224. this.eventHandlers = {
  225. // Connection events
  226. join: (data) => this.onJoin(data),
  227. alert: (data) => this.onAlert(data),
  228.  
  229. // Chat events
  230. msg: (data) => this.onMessage(data),
  231.  
  232. // Editor events
  233. edit: (data) => this.onEdit(data),
  234. protect: (data) => this.onProtect(data),
  235. clear: (data) => this.onClear(data),
  236.  
  237. // Cursor events
  238. cursor: (data) => this.onCursor(data),
  239. cursorleft: (id) => this.onCursorLeft(id),
  240.  
  241. // Permission events
  242. perms: (level) => this.onPerms(level),
  243. memberadded: (member) => this.onMemberAdded(member),
  244. memberlist: (members) => this.onMemberList(members),
  245. walllist: (walls) => this.onWallList(walls),
  246.  
  247. // State events
  248. readonly: (state) => this.onReadonly(state),
  249. hidecursors: (state) => this.onHideCursors(state),
  250. disablechat: (state) => this.onDisableChat(state),
  251. disablecolor: (state) => this.onDisableColor(state),
  252. disablebraille: (state) => this.onDisableBraille(state),
  253.  
  254. // Account events
  255. nametaken: () => this.onNameTaken(),
  256. passfail: () => this.onPassFail(),
  257. tokenfail: () => this.onTokenFail(),
  258. regclosed: () => this.onRegClosed(),
  259. namechanged: (name) => this.onNameChanged(name),
  260. accountdeleted: () => this.onAccountDeleted(),
  261.  
  262. // Heartbeat
  263. pong: (ms) => this.onPong(ms)
  264. };
  265.  
  266. // Register all event listeners
  267. for (let [event, handler] of Object.entries(this.eventHandlers)) {
  268. if (w && w.on) {
  269. w.on(event, handler);
  270. }
  271. }
  272.  
  273. console.log(`✓ Registered ${Object.keys(this.eventHandlers).length} event listeners`);
  274. }
  275.  
  276. cleanup() {
  277. this.running = false;
  278.  
  279. // Remove all event listeners
  280. for (let [event, handler] of Object.entries(this.eventHandlers)) {
  281. if (w && w.off) {
  282. w.off(event, handler);
  283. }
  284. }
  285.  
  286. // Clear timers
  287. this.state.activeTimers.forEach(timer => {
  288. clearTimeout(timer.timeout);
  289. if (timer.intervalId) clearInterval(timer.intervalId);
  290. });
  291.  
  292. console.log("✓ Bot cleaned up");
  293. }
  294.  
  295. // Check if user has authority
  296. isAuthorized(username, isAdmin) {
  297. // Admins always have authority
  298. if (isAdmin) {
  299. this.state.adminUsers.add(username);
  300. return true;
  301. }
  302.  
  303. // Check if user is in authorized list
  304. return this.config.authorizedUsers.includes(username);
  305. }
  306.  
  307. // Event Handlers
  308. onJoin(data) {
  309. this.state.wall = data.wall || "";
  310. this.state.subwall = data.subwall || "";
  311. console.log(`📍 Joined: ${this.state.wall}/${this.state.subwall}`);
  312. }
  313.  
  314. onAlert(data) {
  315. console.log(`⚠️ Server Alert: ${data.message}`);
  316. }
  317.  
  318. onMessage(data) {
  319. if (!data || !data.msg) return;
  320.  
  321. // Skip bot's own messages to prevent recursion
  322. if (data.nick === this.config.username) return;
  323.  
  324. const message = data.msg.trim();
  325. const sender = data.nick || "Unknown";
  326. const isAdmin = data.isAdmin || false;
  327.  
  328. // Create unique message ID to prevent duplicate processing
  329. const messageId = `${sender}-${message}-${Date.now()}`;
  330.  
  331. // Skip if already processed (prevents recursion)
  332. if (this.state.processedMessages.has(messageId)) return;
  333.  
  334. // Mark as processed
  335. this.state.processedMessages.add(messageId);
  336.  
  337. // Clean up old processed messages (keep only last 100)
  338. if (this.state.processedMessages.size > 100) {
  339. const messages = Array.from(this.state.processedMessages);
  340. messages.slice(0, messages.length - 100).forEach(msg => {
  341. this.state.processedMessages.delete(msg);
  342. });
  343. }
  344.  
  345. // Track admin users
  346. if (isAdmin) {
  347. this.state.adminUsers.add(sender);
  348. }
  349.  
  350. // Check authority
  351. const hasAuth = this.isAuthorized(sender, isAdmin);
  352.  
  353. // Log message with authority indicator if applicable
  354. if (hasAuth) {
  355. console.log(`🔑 [AUTHORITY] ${sender} ~ ${message}`);
  356.  
  357. // Only echo authority messages if enabled AND it's not a command AND not a duplicate
  358. if (this.config.authorityEchoEnabled &&
  359. !message.startsWith(this.config.prefix) &&
  360. this.config.lastAuthorityMessage !== `${sender}:${message}`) {
  361.  
  362. this.config.lastAuthorityMessage = `${sender}:${message}`;
  363. this.sendMessage(`[AUTHORITY] ${sender} ~ ${message}`);
  364. }
  365. } else {
  366. console.log(`💬 [${sender}${data.isRegistered ? ' ®' : ''}]: ${message}`);
  367. }
  368.  
  369. // Check for commands
  370. if (message.startsWith(this.config.prefix)) {
  371. this.handleCommand(message, sender, data);
  372. }
  373. }
  374.  
  375. onEdit(data) {
  376. if (data.edits && data.edits.length > 0) {
  377. console.log(`✏️ ${data.edits.length} edit(s) made`);
  378. }
  379. }
  380.  
  381. onProtect(data) {
  382. console.log(`🔒 Chunk ${data.cell} protection: ${data.protect ? 'ON' : 'OFF'}`);
  383. }
  384.  
  385. onClear(data) {
  386. console.log(`🧹 Area cleared: (${data.x1},${data.y1}) to (${data.x2},${data.y2})`);
  387. }
  388.  
  389. onCursor(data) {
  390. if (!data.id) return;
  391.  
  392. this.state.cursors.set(data.id, {
  393. name: data.n || "",
  394. location: data.l || [0, 0],
  395. color: data.c || 0
  396. });
  397.  
  398. if (data.n === this.config.username && data.l) {
  399. this.config.position.x = data.l[0];
  400. this.config.position.y = data.l[1];
  401. }
  402. }
  403.  
  404. onCursorLeft(id) {
  405. this.state.cursors.delete(id);
  406. }
  407.  
  408. onPerms(level) {
  409. this.state.perms = level;
  410. const permName = ['User', 'Member', 'Owner'][level] || 'Unknown';
  411. console.log(`🔑 Permission level: ${permName} (${level})`);
  412. }
  413.  
  414. onMemberAdded(member) {
  415. console.log(`➕ Member added: ${member}`);
  416. if (!this.state.members.includes(member)) {
  417. this.state.members.push(member);
  418. }
  419. }
  420.  
  421. onMemberList(members) {
  422. this.state.members = members || [];
  423. console.log(`👥 Members: ${this.state.members.join(', ') || 'None'}`);
  424. }
  425.  
  426. onWallList(walls) {
  427. this.state.walllist = walls || [];
  428. console.log(`📋 Available walls: ${walls.length / 2} wall(s)`);
  429. }
  430.  
  431. onReadonly(state) {
  432. this.state.readonly = state;
  433. if (state) console.log("📝 Wall is now READONLY");
  434. }
  435.  
  436. onHideCursors(state) {
  437. this.state.hidecursors = state;
  438. if (state) console.log("👤 Cursors are now HIDDEN");
  439. }
  440.  
  441. onDisableChat(state) {
  442. this.state.disablechat = state;
  443. if (state) console.log("🔇 Chat is DISABLED");
  444. }
  445.  
  446. onDisableColor(state) {
  447. this.state.disablecolor = state;
  448. if (state) console.log("🎨 Colors are DISABLED");
  449. }
  450.  
  451. onDisableBraille(state) {
  452. this.state.disablebraille = state;
  453. if (state) console.log("⠿ Braille is DISABLED");
  454. }
  455.  
  456. onNameTaken() {
  457. console.log("❌ Name is already taken!");
  458. }
  459.  
  460. onPassFail() {
  461. console.log("❌ Invalid password!");
  462. }
  463.  
  464. onTokenFail() {
  465. console.log("❌ Invalid token!");
  466. }
  467.  
  468. onRegClosed() {
  469. console.log("❌ Registration is closed!");
  470. }
  471.  
  472. onNameChanged(name) {
  473. console.log(`✅ Name changed to: ${name}`);
  474. this.config.username = name;
  475. }
  476.  
  477. onAccountDeleted() {
  478. console.log("❌ Account has been deleted!");
  479. }
  480.  
  481. onPong(ms) {
  482. // Heartbeat
  483. }
  484.  
  485. // Command handling
  486. handleCommand(message, sender, messageData) {
  487. const commandLine = message.slice(this.config.prefix.length);
  488. const [command, ...args] = commandLine.split(/\s+/);
  489. const cmd = command.toLowerCase();
  490.  
  491. // Check cooldown
  492. const cooldownKey = `${cmd}-${sender}`;
  493. const lastUsed = this.state.commandCooldowns.get(cooldownKey) || 0;
  494. const now = Date.now();
  495.  
  496. const hasAuth = this.isAuthorized(sender, messageData.isAdmin);
  497.  
  498. if (now - lastUsed < 2000 && !hasAuth) {
  499. return; // 2 second cooldown (except for authorized users)
  500. }
  501.  
  502. this.state.commandCooldowns.set(cooldownKey, now);
  503.  
  504. // Execute command
  505. this.executeCommand(cmd, args, sender, messageData);
  506. }
  507.  
  508. executeCommand(command, args, sender, messageData) {
  509. const hasAuth = this.isAuthorized(sender, messageData.isAdmin);
  510.  
  511. const commands = {
  512. // Basic commands
  513. 'help': () => this.cmdHelp(args),
  514. 'phelp': () => this.cmdPrintHelp(),
  515. 'calculate': () => this.cmdCalculate(args),
  516. 'calc2': () => this.cmdTetration(args),
  517. 'rng': () => this.cmdRandom(args),
  518.  
  519. // General commands
  520. 'timer': () => this.cmdTimer(args),
  521. 'say': () => this.cmdSay(args),
  522. 'status': () => this.cmdStatus(),
  523. 'pos': () => this.cmdPosition(),
  524. 'page': () => this.cmdPage(args),
  525.  
  526. // Info commands
  527. 'members': () => this.cmdMembers(),
  528. 'walls': () => this.cmdWalls(),
  529. 'authlist': () => this.cmdAuthList(),
  530.  
  531. // Authority commands
  532. 'to': () => hasAuth ? this.cmdTeleport(args) : this.sendMessage("Permission invalid - Authority required"),
  533. 'colorid': () => hasAuth ? this.cmdColor(args) : this.sendMessage("Permission invalid"),
  534. 'addauth': () => hasAuth ? this.cmdAddAuth(args) : this.sendMessage("Permission invalid - Authority required"),
  535. 'removeauth': () => hasAuth ? this.cmdRemoveAuth(args) : this.sendMessage("Permission invalid - Authority required"),
  536. 'disablehs': () => hasAuth ? this.cmdDisableHeightSafety() : this.sendMessage("Permission invalid - Authority required"),
  537. 'echoauth': () => hasAuth ? this.cmdToggleEcho() : this.sendMessage("Permission invalid - Authority required")
  538. };
  539.  
  540. const cmdFunc = commands[command];
  541. if (cmdFunc) {
  542. cmdFunc();
  543. }
  544. }
  545.  
  546. // Commands
  547. cmdHelp(args) {
  548. const page = parseInt(args[0]) || 1;
  549. const maxPage = Object.keys(COMMAND_PAGES).length;
  550.  
  551. if (page < 1 || page > maxPage) {
  552. this.sendMessage(`Invalid page. Use ${this.config.prefix}help 1-${maxPage}`);
  553. return;
  554. }
  555.  
  556. // Send page header
  557. this.sendMessage(`📖 Commands Page ${page}/${maxPage}:`);
  558.  
  559. // Send each command as separate message
  560. const commands = COMMAND_PAGES[page];
  561. commands.forEach((cmd, index) => {
  562. setTimeout(() => {
  563. this.sendMessage(`${this.config.prefix}${cmd.cmd}${cmd.auth ? ' 🔐' : ''} - ${cmd.desc}`);
  564. }, (index + 1) * 200);
  565. });
  566. }
  567.  
  568. cmdPrintHelp() {
  569. this.sendMessage("📚 All Commands:");
  570.  
  571. let delay = 200;
  572. for (let pageNum in COMMAND_PAGES) {
  573. const page = COMMAND_PAGES[pageNum];
  574.  
  575. setTimeout(() => {
  576. this.sendMessage(`── Page ${pageNum} ──`);
  577. }, delay);
  578. delay += 200;
  579.  
  580. page.forEach(cmd => {
  581. setTimeout(() => {
  582. this.sendMessage(`${this.config.prefix}${cmd.cmd}${cmd.auth ? ' 🔐' : ''} - ${cmd.desc}`);
  583. }, delay);
  584. delay += 200;
  585. });
  586. }
  587. }
  588.  
  589. cmdPage(args) {
  590. const page = parseInt(args[0]) || 1;
  591. const maxPage = Object.keys(COMMAND_PAGES).length;
  592.  
  593. if (page < 1 || page > maxPage) {
  594. this.sendMessage(`Invalid page. Pages: 1-${maxPage}`);
  595. return;
  596. }
  597.  
  598. this.sendMessage(`📄 Page ${page} Detailed Info:`);
  599.  
  600. const commands = COMMAND_PAGES[page];
  601. commands.forEach((cmd, i) => {
  602. setTimeout(() => {
  603. this.sendMessage(`${i+1}. ${this.config.prefix}${cmd.cmd} - ${cmd.desc}`);
  604. }, (i + 1) * 200);
  605. });
  606. }
  607.  
  608. cmdSay(args) {
  609. if (args.length < 1) {
  610. this.sendMessage(`Usage: ${this.config.prefix}say [message]`);
  611. return;
  612. }
  613.  
  614. const message = args.join(' ');
  615. this.sendMessage(message);
  616. }
  617.  
  618. cmdCalculate(args) {
  619. if (args.length < 2) {
  620. this.sendMessage(`Usage: ${this.config.prefix}calculate base exponent`);
  621. return;
  622. }
  623.  
  624. try {
  625. const base = args[0];
  626. const exp = args[1];
  627.  
  628. const result = window.Decimal.pow(new window.Decimal(base), new window.Decimal(exp));
  629. this.sendMessage(`${base}^${exp} = ${result.toString()}`);
  630. } catch (error) {
  631. this.sendMessage("Error: Invalid input for calculation");
  632. }
  633. }
  634.  
  635. cmdTetration(args) {
  636. if (args.length < 2) {
  637. this.sendMessage(`Usage: ${this.config.prefix}calc2 base height`);
  638. return;
  639. }
  640.  
  641. try {
  642. const base = args[0];
  643. const height = parseInt(args[1]);
  644.  
  645. if (height < 0 || !Number.isInteger(height)) {
  646. this.sendMessage("Height must be a non-negative integer");
  647. return;
  648. }
  649.  
  650. const maxHeight = this.config.heightSafetyEnabled ? 5 : 10;
  651. if (height > maxHeight) {
  652. this.sendMessage(`Height too large! Maximum is ${maxHeight}${this.config.heightSafetyEnabled ? ' (Height Safety ON)' : ' (Height Safety OFF)'}`);
  653. return;
  654. }
  655.  
  656. const result = window.Decimal.tetrate(new window.Decimal(base), height);
  657. this.sendMessage(`${base}^^${height} = ${result.toString()}`);
  658. } catch (error) {
  659. this.sendMessage("Error: Invalid input for tetration");
  660. }
  661. }
  662.  
  663. cmdRandom(args) {
  664. if (args.length < 2) {
  665. this.sendMessage(`Usage: ${this.config.prefix}rng min max`);
  666. return;
  667. }
  668.  
  669. const min = parseFloat(args[0]);
  670. const max = parseFloat(args[1]);
  671.  
  672. if (isNaN(min) || isNaN(max)) {
  673. this.sendMessage("Invalid input. Please provide valid numbers.");
  674. return;
  675. }
  676.  
  677. if (min > max) {
  678. this.sendMessage("Min must be less than or equal to max.");
  679. return;
  680. }
  681.  
  682. const randomNum = Math.random() * (max - min) + min;
  683. this.sendMessage(`Random number between ${min} and ${max}: ${randomNum.toFixed(2)}`);
  684. }
  685.  
  686. cmdTimer(args) {
  687. if (args.length < 3) {
  688. this.sendMessage(`Usage: ${this.config.prefix}timer hours minutes seconds (use 0 to skip)`);
  689. return;
  690. }
  691.  
  692. const hours = Math.max(0, parseInt(args[0]) || 0);
  693. const minutes = Math.max(0, parseInt(args[1]) || 0);
  694. const seconds = Math.max(0, parseInt(args[2]) || 0);
  695.  
  696. if (hours === 0 && minutes === 0 && seconds === 0) {
  697. this.sendMessage("Timer must have at least one non-zero value");
  698. return;
  699. }
  700.  
  701. if (hours > 24) {
  702. this.sendMessage("Maximum timer is 24 hours");
  703. return;
  704. }
  705.  
  706. const totalMs = (hours * 3600 + minutes * 60 + seconds) * 1000;
  707.  
  708. // Build display string (ignore 0 values)
  709. let timeStr = [];
  710. if (hours > 0) timeStr.push(`${hours}h`);
  711. if (minutes > 0) timeStr.push(`${minutes}m`);
  712. if (seconds > 0) timeStr.push(`${seconds}s`);
  713.  
  714. const timerId = Date.now();
  715.  
  716. this.sendMessage(`⏰ Timer set for ${timeStr.join(' ')} (ID: ${timerId})`);
  717.  
  718. // Create timer
  719. const timerObj = setTimeout(() => {
  720. this.sendMessage(`⏰ TIMER COMPLETE! ${timeStr.join(' ')} has elapsed (ID: ${timerId})`);
  721. this.state.activeTimers.delete(timerId);
  722. }, totalMs);
  723.  
  724. // Store timer
  725. this.state.activeTimers.set(timerId, {
  726. timeout: timerObj,
  727. duration: timeStr.join(' '),
  728. startTime: Date.now(),
  729. endTime: Date.now() + totalMs
  730. });
  731.  
  732. // Progress updates for long timers
  733. if (totalMs > 60000) {
  734. let updateCount = 0;
  735. const maxUpdates = 3;
  736. const updateInterval = Math.max(30000, totalMs / 4);
  737.  
  738. const intervalId = setInterval(() => {
  739. const timer = this.state.activeTimers.get(timerId);
  740. if (!timer || updateCount >= maxUpdates) {
  741. clearInterval(intervalId);
  742. return;
  743. }
  744.  
  745. const remaining = timer.endTime - Date.now();
  746. if (remaining > 1000) {
  747. const h = Math.floor(remaining / 3600000);
  748. const m = Math.floor((remaining % 3600000) / 60000);
  749. const s = Math.floor((remaining % 60000) / 1000);
  750.  
  751. let remStr = [];
  752. if (h > 0) remStr.push(`${h}h`);
  753. if (m > 0) remStr.push(`${m}m`);
  754. if (s > 0) remStr.push(`${s}s`);
  755.  
  756. this.sendMessage(`⏰ Timer ${timerId}: ${remStr.join(' ')} remaining`);
  757. updateCount++;
  758. }
  759. }, updateInterval);
  760.  
  761. this.state.activeTimers.get(timerId).intervalId = intervalId;
  762. }
  763. }
  764.  
  765. cmdStatus() {
  766. const status = [
  767. `Wall: ${this.state.wall}/${this.state.subwall}`,
  768. `Perms: ${['User', 'Member', 'Owner'][this.state.perms]}`,
  769. `Pos: (${this.config.position.x}, ${this.config.position.y})`,
  770. `Timers: ${this.state.activeTimers.size}`,
  771. `Color: ${this.config.color}`,
  772. `HS: ${this.config.heightSafetyEnabled ? 'ON' : 'OFF'}`,
  773. `Echo: ${this.config.authorityEchoEnabled ? 'ON' : 'OFF'}`,
  774. `Auth: ${this.config.authorizedUsers.length}`
  775. ];
  776. this.sendMessage(`📊 ${status.join(' | ')}`);
  777. }
  778.  
  779. cmdPosition() {
  780. this.sendMessage(`📍 Current position: (${this.config.position.x}, ${this.config.position.y})`);
  781. }
  782.  
  783. cmdMembers() {
  784. if (this.state.members.length === 0) {
  785. this.sendMessage("No members in this wall");
  786. } else {
  787. this.sendMessage(`Members: ${this.state.members.join(', ')}`);
  788. }
  789. }
  790.  
  791. cmdWalls() {
  792. if (this.state.walllist.length === 0) {
  793. this.sendMessage("No subwalls available");
  794. } else {
  795. const walls = [];
  796. for (let i = 0; i < this.state.walllist.length; i += 2) {
  797. const wallName = this.state.walllist[i];
  798. const isPrivate = this.state.walllist[i + 1];
  799. walls.push(`${wallName}${isPrivate ? ' (private)' : ''}`);
  800. }
  801. this.sendMessage(`Subwalls: ${walls.join(', ')}`);
  802. }
  803. }
  804.  
  805. cmdTeleport(args) {
  806. if (args.length < 2) {
  807. this.sendMessage(`Usage: ${this.config.prefix}to X Y`);
  808. return;
  809. }
  810.  
  811. const x = parseInt(args[0]);
  812. const y = parseInt(args[1]);
  813.  
  814. if (isNaN(x) || isNaN(y)) {
  815. this.sendMessage("Invalid coordinates. Please provide integers.");
  816. return;
  817. }
  818.  
  819. if (Math.abs(x) > 10000 || Math.abs(y) > 10000) {
  820. this.sendMessage("Coordinates out of range (max ±10000)");
  821. return;
  822. }
  823.  
  824. this.teleportCursor(x, y);
  825. this.sendMessage(`📍 Teleported to (${x}, ${y})`);
  826. }
  827.  
  828. cmdColor(args) {
  829. if (args.length < 1) {
  830. this.sendMessage(`Usage: ${this.config.prefix}colorid #hex or 0-15`);
  831. return;
  832. }
  833.  
  834. const input = args[0].toLowerCase();
  835. let colorIndex;
  836.  
  837. if (!isNaN(input)) {
  838. colorIndex = parseInt(input);
  839. if (colorIndex < 0 || colorIndex > 15) {
  840. this.sendMessage("Invalid colot");
  841. return;
  842. }
  843. } else if (input.startsWith('#')) {
  844. colorIndex = COLORS[input];
  845. if (colorIndex === undefined) {
  846. this.sendMessage("Invalid colot");
  847. return;
  848. }
  849. } else {
  850. this.sendMessage("Invalid colot");
  851. return;
  852. }
  853.  
  854. this.setColor(colorIndex);
  855. this.sendMessage(`🎨 Color changed to ${colorIndex}`);
  856. }
  857.  
  858. cmdAddAuth(args) {
  859. if (args.length < 1) {
  860. this.sendMessage(`Usage: ${this.config.prefix}addauth username`);
  861. return;
  862. }
  863.  
  864. const username = args[0];
  865.  
  866. if (this.config.authorizedUsers.includes(username)) {
  867. this.sendMessage(`${username} already has authority`);
  868. return;
  869. }
  870.  
  871. this.config.authorizedUsers.push(username);
  872. this.sendMessage(`✅ Added ${username} to authority list`);
  873. console.log(`🔑 Authority granted to: ${username}`);
  874. }
  875.  
  876. cmdRemoveAuth(args) {
  877. if (args.length < 1) {
  878. this.sendMessage(`Usage: ${this.config.prefix}removeauth username`);
  879. return;
  880. }
  881.  
  882. const username = args[0];
  883.  
  884. if (username === "Diamond25" || username === "KiwiTest") {
  885. this.sendMessage(`Cannot remove default authority from ${username}`);
  886. return;
  887. }
  888.  
  889. const index = this.config.authorizedUsers.indexOf(username);
  890. if (index === -1) {
  891. this.sendMessage(`${username} doesn't have authority`);
  892. return;
  893. }
  894.  
  895. this.config.authorizedUsers.splice(index, 1);
  896. this.sendMessage(`❌ Removed ${username} from authority list`);
  897. console.log(`🔑 Authority revoked from: ${username}`);
  898. }
  899.  
  900. cmdDisableHeightSafety() {
  901. this.config.heightSafetyEnabled = !this.config.heightSafetyEnabled;
  902. const status = this.config.heightSafetyEnabled ? "ENABLED" : "DISABLED";
  903. this.sendMessage(`⚠️ Height safety is now ${status} (Max tetration height: ${this.config.heightSafetyEnabled ? '5' : '10'})`);
  904. console.log(`Height safety: ${status}`);
  905. }
  906.  
  907. cmdToggleEcho() {
  908. this.config.authorityEchoEnabled = !this.config.authorityEchoEnabled;
  909. const status = this.config.authorityEchoEnabled ? "ENABLED" : "DISABLED";
  910. this.sendMessage(`📢 Authority echo is now ${status}`);
  911. console.log(`Authority echo: ${status}`);
  912. }
  913.  
  914. cmdAuthList() {
  915. const authUsers = [...this.config.authorizedUsers];
  916. const adminUsers = Array.from(this.state.adminUsers);
  917.  
  918. const allAuth = [...new Set([...authUsers, ...adminUsers])];
  919.  
  920. this.sendMessage(`🔑 Authorized users (${allAuth.length}): ${allAuth.join(', ')}`);
  921. }
  922.  
  923. // Core functions
  924. setUsername(username) {
  925. if (typeof api !== 'undefined' && api.nick) {
  926. api.nick(username);
  927. } else if (typeof setNick === 'function') {
  928. setNick(username);
  929. } else if (typeof changeNick === 'function') {
  930. changeNick(username);
  931. }
  932.  
  933. console.log(`👤 Username: ${username}`);
  934. }
  935.  
  936. setColor(colorIndex) {
  937. if (typeof api !== 'undefined' && api.color) {
  938. api.color(colorIndex);
  939. } else if (typeof setColor === 'function') {
  940. setColor(colorIndex);
  941. }
  942.  
  943. this.config.color = colorIndex;
  944. console.log(`🎨 Color set to: ${colorIndex}`);
  945. }
  946.  
  947. teleportCursor(x, y) {
  948. if (typeof api !== 'undefined' && api.cursor) {
  949. api.cursor(x, y);
  950. } else if (typeof moveCursor === 'function') {
  951. moveCursor(x, y);
  952. } else if (typeof cursor === 'object' && cursor.move) {
  953. cursor.move(x, y);
  954. }
  955.  
  956. this.config.position.x = x;
  957. this.config.position.y = y;
  958. }
  959.  
  960. sendMessage(message) {
  961. if (this.state.disablechat) {
  962. console.log("Chat is disabled, cannot send message");
  963. return;
  964. }
  965.  
  966. this.state.messageQueue.push(message);
  967.  
  968. if (!this.state.isProcessingQueue) {
  969. this.processMessageQueue();
  970. }
  971. }
  972.  
  973. async processMessageQueue() {
  974. if (this.state.messageQueue.length === 0 || !this.running) {
  975. this.state.isProcessingQueue = false;
  976. return;
  977. }
  978.  
  979. this.state.isProcessingQueue = true;
  980. const message = this.state.messageQueue.shift();
  981.  
  982. // Rate limiting
  983. const now = Date.now();
  984. const timeSinceLastMessage = now - this.state.lastMessageTime;
  985. if (timeSinceLastMessage < this.config.messageDelay) {
  986. await new Promise(resolve =>
  987. setTimeout(resolve, this.config.messageDelay - timeSinceLastMessage)
  988. );
  989. }
  990.  
  991. this.state.lastMessageTime = Date.now();
  992.  
  993. // Send using w.chat.send
  994. try {
  995. if (w && w.chat && w.chat.send) {
  996. w.chat.send(message);
  997. console.log(`📤 Sent: ${message}`);
  998. } else {
  999. if (typeof sendChat === 'function') {
  1000. sendChat(message);
  1001. } else if (typeof api !== 'undefined' && api.chat) {
  1002. api.chat(message);
  1003. } else {
  1004. console.error("No chat send method available!");
  1005. }
  1006. }
  1007. } catch (error) {
  1008. console.error("Failed to send message:", error);
  1009. }
  1010.  
  1011. // Continue processing queue
  1012. setTimeout(() => this.processMessageQueue(), this.config.messageDelay);
  1013. }
  1014. }
  1015.  
  1016. // Initialize the bot
  1017. console.clear();
  1018. console.log("Starting TextWall Bot v7.0...");
  1019.  
  1020. const bot = new TextWallBot(BOT_CONFIG);
  1021. await bot.init();
  1022.  
  1023. // Make bot globally accessible
  1024. window.diamondBot = bot;
  1025.  
  1026. // Utility commands
  1027. window.stopBot = function() {
  1028. console.log("Stopping bot...");
  1029. bot.cleanup();
  1030. bot.sendMessage("Bot shutting down...");
  1031. console.log("✅ Bot stopped");
  1032. };
  1033.  
  1034. window.restartBot = async function() {
  1035. console.log("Restarting bot...");
  1036. window.stopBot();
  1037. await new Promise(resolve => setTimeout(resolve, 1000));
  1038. const newBot = new TextWallBot(BOT_CONFIG);
  1039. await newBot.init();
  1040. window.diamondBot = newBot;
  1041. console.log("✅ Bot restarted");
  1042. };
  1043.  
  1044. window.botStatus = function() {
  1045. console.table({
  1046. 'Username': bot.config.username,
  1047. 'Prefix': bot.config.prefix,
  1048. 'Wall': `${bot.state.wall}/${bot.state.subwall}`,
  1049. 'Position': `(${bot.config.position.x}, ${bot.config.position.y})`,
  1050. 'Color': bot.config.color,
  1051. 'Permissions': ['User', 'Member', 'Owner'][bot.state.perms] || 'Unknown',
  1052. 'Active Timers': bot.state.activeTimers.size,
  1053. 'Authorized Users': bot.config.authorizedUsers.length,
  1054. 'Height Safety': bot.config.heightSafetyEnabled ? 'ON' : 'OFF',
  1055. 'Authority Echo': bot.config.authorityEchoEnabled ? 'OFF (Default)' : 'ON',
  1056. 'Queue Size': bot.state.messageQueue.length
  1057. });
  1058. };
  1059.  
  1060. window.botHelp = function() {
  1061. console.log("╔══════════════════════════════════════════╗");
  1062. console.log("║ TextWall Bot v7.0 - Help ║");
  1063. console.log("╠══════════════════════════════════════════╣");
  1064. console.log("║ PREFIX: \\ ║");
  1065. console.log("║ ║");
  1066. console.log("║ MAIN COMMANDS: ║");
  1067. console.log("║ \\help [1-4] - Show command page ║");
  1068. console.log("║ \\phelp - Print ALL commands ║");
  1069. console.log("║ \\say text - Make bot say something ║");
  1070. console.log("║ ║");
  1071. console.log("║ FIXES: ║");
  1072. console.log("║ • Fixed recursion bug ║");
  1073. console.log("║ • Authority echo OFF by default ║");
  1074. console.log("║ • Use \\echoauth to toggle ║");
  1075. console.log("║ ║");
  1076. console.log("║ CONSOLE: ║");
  1077. console.log("║ window.stopBot() - Stop bot ║");
  1078. console.log("║ window.restartBot() - Restart bot ║");
  1079. console.log("║ window.botStatus() - Show status ║");
  1080. console.log("║ window.botHelp() - This help ║");
  1081. console.log("╚══════════════════════════════════════════╝");
  1082. };
  1083.  
  1084. // Show help on start
  1085. window.botHelp();
  1086.  
  1087. })();
Advertisement
Add Comment
Please, Sign In to add comment