Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (async function () {
- "use strict";
- if (typeof w === "undefined") {
- console.error("TextWall API (w) not found! Make sure you're on tw.2s4.me");
- return;
- }
- const Storage = {
- save: function (key, data) {
- try {
- localStorage.setItem(`diamondbot_${key}`, JSON.stringify(data));
- return true;
- } catch (e) {
- console.error("Failed to save to storage:", e);
- return false;
- }
- },
- load: function (key, defaultValue = null) {
- try {
- const data = localStorage.getItem(`diamondbot_${key}`);
- return data ? JSON.parse(data) : defaultValue;
- } catch (e) {
- console.error("Failed to load from storage:", e);
- return defaultValue;
- }
- },
- remove: function (key) {
- try {
- localStorage.removeItem(`diamondbot_${key}`);
- return true;
- } catch (e) {
- console.error("Failed to remove from storage:", e);
- return false;
- }
- },
- };
- const BOT_CONFIG = {
- version: "7.13.3",
- username: "diamondbot",
- color: 0,
- prefix: "\\",
- authorizedUsers: Storage.load("authorizedUsers", ["Diamond25", "KiwiTest"]),
- bannedUsers: Storage.load("bannedUsers", []),
- bannedIds: Storage.load("bannedIds", []),
- messageDelay: 150,
- position: { x: 0, y: 0 },
- heightSafetyEnabled: true,
- lastAuthorityMessage: "",
- authorityEchoEnabled: false,
- echoColorEnabled: false,
- };
- const state = {
- wall: "",
- subwall: "",
- perms: 0,
- isRegistered: false,
- isAdmin: false,
- readonly: false,
- hidecursors: false,
- disablechat: false,
- disablecolor: false,
- disablebraille: false,
- members: [],
- walllist: [],
- activeTimers: new Map(),
- activeCounts: new Map(),
- commandCooldowns: new Map(),
- messageQueue: [],
- isProcessingQueue: false,
- lastMessageTime: 0,
- cursors: new Map(),
- adminUsers: new Set(),
- processedMessages: new Set(),
- lastSayUser: null,
- userPositions: new Map(),
- userIds: new Map(),
- isShuttingDown: false,
- isTyping: false,
- countdownActive: false,
- clearingArea: false,
- };
- const COLORS = {
- "#000000": 0,
- "#ffffff": 1,
- "#ff0000": 2,
- "#00ff00": 3,
- "#0000ff": 4,
- "#ffff00": 5,
- "#ff00ff": 6,
- "#00ffff": 7,
- "#808080": 8,
- "#ff8800": 9,
- "#8800ff": 10,
- "#0088ff": 11,
- "#88ff00": 12,
- "#ff0088": 13,
- "#884400": 14,
- "#448800": 15,
- };
- const AUTHORITY_COMMANDS = [
- "to",
- "tp",
- "colorid",
- "addauth",
- "removeauth",
- "disablehs",
- "echoauth",
- "echocolor",
- "csay",
- "ban",
- "unban",
- "banid",
- "unbanid",
- "type",
- "cleararea",
- ];
- const INVISIBLE_CHAR = "\u200B";
- const CHANGELOG = [
- { version: "7.13.3", changes: "10ms cleararea cooldown, w.cursors detection" },
- { version: "7.13.2", changes: "\\cleararea command, unbanName console command" },
- { version: "7.13.1", changes: "\\tcountdown and \\userlist commands added" },
- { version: "7.13", changes: "Cursor Y coordinate flipped, \\chl command added" },
- { version: "7.12", changes: "\\echocolor command, HEX-only colors, authority color echo" },
- { version: "7.11", changes: "Color syntax support with <start #HEX>text<end>" },
- { version: "7.10", changes: "\\tp command using w.tp() function" },
- { version: "7.9", changes: "Help cooldown 0.7s, thelp step 1, page command update" },
- { version: "7.8", changes: "Bug fixes and performance improvements" },
- { version: "7.7", changes: "Enhanced security and ban system" },
- { version: "7.6", changes: "Timer system improvements" },
- { version: "7.5", changes: "Authority system enhancements" },
- { version: "7.4", changes: "Added height safety toggle" },
- { version: "7.3", changes: "Colored say command (csay)" },
- { version: "7.2", changes: "Ban system with ID support" },
- { version: "7.1", changes: "Echo authority messages feature" },
- { version: "7.0", changes: "Major rewrite with improved architecture" },
- ];
- const COMMAND_PAGES = {
- 1: [
- { cmd: "help", desc: "Show command pages", auth: false },
- { cmd: "thelp", desc: "Type help on wall", auth: false },
- { cmd: "fullcmd", desc: "Get full command list location", auth: false },
- { cmd: "info", desc: "Show bot information", auth: false },
- { cmd: "chl", desc: "Show changelog", auth: false },
- ],
- 2: [
- { cmd: "calculate", desc: "Calculate p1^p2", auth: false },
- { cmd: "calc2", desc: "Calculate p1^^p2 (tetration)", auth: false },
- { cmd: "rng", desc: "Random number between min and max", auth: false },
- { cmd: "timer", desc: "Set a timer (h m s)", auth: false },
- { cmd: "say", desc: "Make bot say something", auth: false },
- ],
- 3: [
- { cmd: "count", desc: "Count from 1 to n with cooldown", auth: false },
- { cmd: "tcountdown", desc: "Type countdown on wall from seconds", auth: false },
- { cmd: "status", desc: "Show bot status", auth: false },
- { cmd: "pos", desc: "Show cursor position (x,y coordinates)", auth: false },
- { cmd: "type", desc: "Type characters on wall (Authority)", auth: true },
- ],
- 4: [
- { cmd: "page", desc: "Show detailed page info", auth: false },
- { cmd: "members", desc: "List wall members", auth: false },
- { cmd: "walls", desc: "List available subwalls", auth: false },
- { cmd: "authlist", desc: "Show authorized users", auth: false },
- { cmd: "userlist", desc: "Show all online users in wall", auth: false },
- ],
- 5: [
- { cmd: "to", desc: "Teleport bot to X Y (Authority)", auth: true },
- { cmd: "tp", desc: "Teleport to X Y using w.tp (Authority)", auth: true },
- { cmd: "colorid", desc: "Change bot color (Authority)", auth: true },
- { cmd: "cleararea", desc: "Clear area with spaces (Authority)", auth: true },
- { cmd: "csay", desc: "Say colored text (Authority)", auth: true },
- ],
- 6: [
- { cmd: "addauth", desc: "Add user to authority list (Authority)", auth: true },
- { cmd: "removeauth", desc: "Remove user from authority (Authority)", auth: true },
- { cmd: "ban", desc: "Ban user from using bot (Authority)", auth: true },
- { cmd: "unban", desc: "Unban user/ID (Authority)", auth: true },
- { cmd: "banid", desc: "Ban user by ID (Authority)", auth: true },
- ],
- 7: [
- { cmd: "unbanid", desc: "Unban user by ID (Authority)", auth: true },
- { cmd: "banlist", desc: "Show banned users (Authority)", auth: true },
- { cmd: "disableHS", desc: "Toggle height safety (Authority)", auth: true },
- { cmd: "echoauth", desc: "Toggle authority echo (Authority)", auth: true },
- { cmd: "echocolor", desc: "Toggle color echo (Authority)", auth: true },
- ],
- };
- async function loadBreakEternity() {
- if (typeof window.Decimal !== "undefined") {
- console.log("[OK] Break Eternity already loaded");
- return true;
- }
- const sources = [
- "https://cdn.jsdelivr.net/npm/break_eternity.js@latest/break_eternity.min.js",
- "https://unpkg.com/break_eternity.js@latest/dist/break_eternity.min.js",
- "https://cdnjs.cloudflare.com/ajax/libs/break_eternity.js/1.3.0/break_eternity.min.js",
- ];
- for (let src of sources) {
- try {
- await loadScript(src);
- if (typeof window.Decimal !== "undefined") {
- console.log(`[OK] Break Eternity loaded from: ${src}`);
- return true;
- }
- } catch (e) {
- console.warn(`Failed to load from ${src}`);
- }
- }
- window.Decimal = createFallbackDecimal();
- console.log("[OK] Using fallback Decimal implementation");
- return true;
- }
- function loadScript(src) {
- return new Promise((resolve, reject) => {
- const script = document.createElement("script");
- script.src = src;
- script.onload = resolve;
- script.onerror = reject;
- document.head.appendChild(script);
- });
- }
- function createFallbackDecimal() {
- return class Decimal {
- constructor(value) {
- this.value =
- typeof value === "string" || typeof value === "number" ? parseFloat(value) || 0 : value?.value || 0;
- }
- static pow(base, exp) {
- const b = base instanceof Decimal ? base.value : parseFloat(base);
- const e = exp instanceof Decimal ? exp.value : parseFloat(exp);
- if (e === 0) return new Decimal(1);
- if (b === 0) return new Decimal(0);
- let result;
- if (Math.abs(e) > 308) {
- result = e > 0 ? Infinity : 0;
- } else {
- result = Math.pow(b, e);
- }
- return new Decimal(result);
- }
- static tetrate(base, height) {
- const b = base instanceof Decimal ? base.value : parseFloat(base);
- const h = parseInt(height);
- if (h === 0) return new Decimal(1);
- if (h === 1) return new Decimal(b);
- if (b === 0) return new Decimal(0);
- if (!BOT_CONFIG.heightSafetyEnabled) {
- let result = b;
- for (let i = 1; i < h; i++) {
- result = Math.pow(b, result);
- if (!isFinite(result)) break;
- }
- return new Decimal(result);
- }
- const maxHeight = 5;
- let result = b;
- for (let i = 1; i < h && i < maxHeight; i++) {
- result = Math.pow(b, result);
- if (!isFinite(result)) break;
- }
- return new Decimal(result);
- }
- toString() {
- if (!isFinite(this.value)) return this.value > 0 ? "Infinity" : "-Infinity";
- if (Math.abs(this.value) < 1e-6) return "0";
- if (Math.abs(this.value) < 1e6 && Math.abs(this.value) > 1e-3) {
- return this.value.toString();
- }
- return this.value.toExponential(2);
- }
- };
- }
- class TextWallBot {
- constructor(config) {
- this.config = config;
- this.state = state;
- this.eventHandlers = {};
- this.running = true;
- }
- async init() {
- console.log("===================================");
- console.log(` TextWall Bot v${this.config.version} Initializing `);
- console.log("===================================");
- await loadBreakEternity();
- this.setupEventListeners();
- this.setUsername(this.config.username);
- this.setColor(this.config.color);
- this.teleportCursor(0, 0);
- setTimeout(() => {
- this.sendMessage(
- `${this.config.username} v${this.config.version} online! Type ${this.config.prefix}help for commands`
- );
- }, 2000);
- console.log("[OK] Bot initialized successfully!");
- console.log(`[OK] Prefix: ${this.config.prefix}`);
- console.log(`[OK] Authorized users: ${this.config.authorizedUsers.join(", ")}`);
- console.log(`[OK] Banned users: ${this.config.bannedUsers.length}`);
- console.log(`[OK] Banned IDs: ${this.config.bannedIds.length}`);
- console.log("[OK] Type window.showCommands() to see all commands in console");
- console.log("[OK] Color syntax: <start #HEXCOLOR>text<end>");
- console.log("[OK] Y coordinates are flipped (negated)");
- console.log("===================================");
- }
- setupEventListeners() {
- this.eventHandlers = {
- join: (data) => this.onJoin(data),
- alert: (data) => this.onAlert(data),
- msg: (data) => this.onMessage(data),
- edit: (data) => this.onEdit(data),
- protect: (data) => this.onProtect(data),
- clear: (data) => this.onClear(data),
- cursor: (data) => this.onCursor(data),
- cursorleft: (id) => this.onCursorLeft(id),
- perms: (level) => this.onPerms(level),
- memberadded: (member) => this.onMemberAdded(member),
- memberlist: (members) => this.onMemberList(members),
- walllist: (walls) => this.onWallList(walls),
- readonly: (state) => this.onReadonly(state),
- hidecursors: (state) => this.onHideCursors(state),
- disablechat: (state) => this.onDisableChat(state),
- disablecolor: (state) => this.onDisableColor(state),
- disablebraille: (state) => this.onDisableBraille(state),
- nametaken: () => this.onNameTaken(),
- passfail: () => this.onPassFail(),
- tokenfail: () => this.onTokenFail(),
- regclosed: () => this.onRegClosed(),
- namechanged: (name) => this.onNameChanged(name),
- accountdeleted: () => this.onAccountDeleted(),
- pong: (ms) => this.onPong(ms),
- };
- for (let [event, handler] of Object.entries(this.eventHandlers)) {
- if (w && w.on) {
- w.on(event, handler);
- }
- }
- console.log(`[OK] Registered ${Object.keys(this.eventHandlers).length} event listeners`);
- }
- cleanup() {
- this.running = false;
- this.state.countdownActive = false;
- this.state.clearingArea = false;
- for (let [event, handler] of Object.entries(this.eventHandlers)) {
- if (w && w.off) {
- w.off(event, handler);
- }
- }
- this.state.activeTimers.forEach((timer) => {
- clearTimeout(timer.timeout);
- if (timer.intervalId) clearInterval(timer.intervalId);
- });
- this.state.activeCounts.forEach((count) => {
- if (count.intervalId) clearInterval(count.intervalId);
- });
- console.log("[OK] Bot cleaned up");
- }
- isAuthorized(username, isAdmin) {
- if (isAdmin) {
- this.state.adminUsers.add(username);
- return true;
- }
- return this.config.authorizedUsers.includes(username);
- }
- isBanned(username) {
- return this.config.bannedUsers.includes(username);
- }
- isIdBanned(userId) {
- return this.config.bannedIds.includes(userId);
- }
- getUserId(username) {
- for (let [id, cursor] of this.state.cursors.entries()) {
- if (cursor.name === username) {
- return id;
- }
- }
- return this.state.userIds.get(username) || null;
- }
- getCursorPosition(username) {
- if (this.state.userPositions.has(username)) {
- return this.state.userPositions.get(username);
- }
- for (let cursor of this.state.cursors.values()) {
- if (cursor.name === username) {
- return cursor.location;
- }
- }
- return null;
- }
- containsAuthorityCommand(message) {
- const msgLower = message.toLowerCase();
- for (let authCmd of AUTHORITY_COMMANDS) {
- if (msgLower.includes(`${this.config.prefix}${authCmd}`)) {
- return true;
- }
- }
- return false;
- }
- hasColorSyntax(message) {
- const colorPattern = /<start\s+#[0-9a-fA-F]{6}>([^<]*)<end>/i;
- return colorPattern.test(message);
- }
- parseColoredMessage(message) {
- const colorPattern = /<start\s+(#[0-9a-fA-F]{6})>([^<]*)<end>/gi;
- const segments = [];
- let lastIndex = 0;
- let match;
- while ((match = colorPattern.exec(message)) !== null) {
- // Add text before colored segment
- if (match.index > lastIndex) {
- segments.push({
- text: message.substring(lastIndex, match.index),
- color: null
- });
- }
- // Add colored segment
- const hexColor = match[1].toLowerCase();
- const text = match[2];
- const colorId = COLORS[hexColor];
- segments.push({
- text: text,
- color: colorId !== undefined ? colorId : null
- });
- lastIndex = match.index + match[0].length;
- }
- // Add remaining text
- if (lastIndex < message.length) {
- segments.push({
- text: message.substring(lastIndex),
- color: null
- });
- }
- // If no color segments found, return original message
- if (segments.length === 0) {
- return [{ text: message, color: null }];
- }
- return segments;
- }
- onJoin(data) {
- this.state.wall = data.wall || "";
- this.state.subwall = data.subwall || "";
- console.log(`[JOINED] ${this.state.wall}/${this.state.subwall}`);
- }
- onAlert(data) {
- console.log(`[ALERT] ${data.message}`);
- }
- onMessage(data) {
- if (!data || !data.msg) return;
- if (data.nick === this.config.username) return;
- const message = data.msg.trim();
- const sender = data.nick || "Unknown";
- const isAdmin = data.isAdmin || false;
- const userId = data.id || null;
- if (userId && sender) {
- this.state.userIds.set(sender, userId);
- }
- const messageId = `${sender}-${message}-${Date.now()}`;
- if (this.state.processedMessages.has(messageId)) return;
- this.state.processedMessages.add(messageId);
- if (this.state.processedMessages.size > 100) {
- const messages = Array.from(this.state.processedMessages);
- messages.slice(0, messages.length - 100).forEach((msg) => {
- this.state.processedMessages.delete(msg);
- });
- }
- if (isAdmin) {
- this.state.adminUsers.add(sender);
- }
- const hasAuth = this.isAuthorized(sender, isAdmin);
- if (hasAuth) {
- console.log(`[AUTHORITY] ${sender} ~ ${message}`);
- // Echo color handler
- if (this.config.echoColorEnabled &&
- !message.startsWith(this.config.prefix) &&
- !message.includes("[AUTHORITY COLOR]") &&
- this.hasColorSyntax(message)) {
- this.sendMessage(`[AUTHORITY COLOR] ${sender} ~ ${message}`);
- }
- // Regular authority echo (without color syntax)
- else if (
- this.config.authorityEchoEnabled &&
- !message.startsWith(this.config.prefix) &&
- !message.includes("[AUTHORITY]") &&
- !this.hasColorSyntax(message) &&
- this.config.lastAuthorityMessage !== `${sender}:${message}`
- ) {
- this.config.lastAuthorityMessage = `${sender}:${message}`;
- this.sendMessage(`[AUTHORITY] ${sender} ~ ${message}`);
- }
- } else {
- console.log(`[MSG] ${sender}${data.isRegistered ? " (R)" : ""}: ${message}`);
- }
- if (message.startsWith(this.config.prefix)) {
- this.handleCommand(message, sender, data);
- }
- }
- onEdit(data) {
- if (data.edits && data.edits.length > 0) {
- console.log(`[EDIT] ${data.edits.length} edit(s) made`);
- }
- }
- onProtect(data) {
- console.log(`[PROTECT] Chunk ${data.cell} protection: ${data.protect ? "ON" : "OFF"}`);
- }
- onClear(data) {
- console.log(`[CLEAR] Area cleared: (${data.x1},${data.y1}) to (${data.x2},${data.y2})`);
- }
- onCursor(data) {
- if (!data.id) return;
- // Flip Y coordinate (negate it)
- const flippedLocation = data.l ? [data.l[0], -data.l[1]] : [0, 0];
- const cursorInfo = {
- name: data.n || "",
- location: flippedLocation,
- color: data.c || 0
- };
- this.state.cursors.set(data.id, cursorInfo);
- if (data.n) {
- this.state.userPositions.set(data.n, flippedLocation);
- this.state.userIds.set(data.n, data.id);
- }
- // Flip Y for bot's own position
- if (data.n === this.config.username && data.l) {
- this.config.position.x = data.l[0];
- this.config.position.y = -data.l[1]; // Flipped Y
- }
- }
- onCursorLeft(id) {
- const cursor = this.state.cursors.get(id);
- if (cursor && cursor.name) {
- this.state.userPositions.delete(cursor.name);
- }
- this.state.cursors.delete(id);
- }
- onPerms(level) {
- this.state.perms = level;
- const permName = ["User", "Member", "Owner"][level] || "Unknown";
- console.log(`[PERMS] ${permName} (${level})`);
- }
- onMemberAdded(member) {
- console.log(`[MEMBER+] ${member}`);
- if (!this.state.members.includes(member)) {
- this.state.members.push(member);
- }
- }
- onMemberList(members) {
- this.state.members = members || [];
- console.log(`[MEMBERS] ${this.state.members.join(", ") || "None"}`);
- }
- onWallList(walls) {
- this.state.walllist = walls || [];
- console.log(`[WALLS] ${walls.length / 2} wall(s) available`);
- }
- onReadonly(state) {
- this.state.readonly = state;
- if (state) console.log("[STATE] Wall is now READONLY");
- }
- onHideCursors(state) {
- this.state.hidecursors = state;
- if (state) console.log("[STATE] Cursors are now HIDDEN");
- }
- onDisableChat(state) {
- this.state.disablechat = state;
- if (state) console.log("[STATE] Chat is DISABLED");
- }
- onDisableColor(state) {
- this.state.disablecolor = state;
- if (state) console.log("[STATE] Colors are DISABLED");
- }
- onDisableBraille(state) {
- this.state.disablebraille = state;
- if (state) console.log("[STATE] Braille is DISABLED");
- }
- onNameTaken() {
- console.log("[ERROR] Name is already taken!");
- }
- onPassFail() {
- console.log("[ERROR] Invalid password!");
- }
- onTokenFail() {
- console.log("[ERROR] Invalid token!");
- }
- onRegClosed() {
- console.log("[ERROR] Registration is closed!");
- }
- onNameChanged(name) {
- console.log(`[OK] Name changed to: ${name}`);
- this.config.username = name;
- }
- onAccountDeleted() {
- console.log("[ERROR] Account has been deleted!");
- }
- onPong(ms) {}
- handleCommand(message, sender, messageData) {
- const userId = messageData.id || this.getUserId(sender);
- if (userId && this.isIdBanned(userId)) {
- this.sendMessage("ERR: your id banned from using bot.");
- return;
- }
- if (this.isBanned(sender)) {
- this.sendMessage("You're banned.");
- return;
- }
- const commandLine = message.slice(this.config.prefix.length);
- const [command, ...args] = commandLine.split(/\s+/);
- const cmd = command.toLowerCase();
- this.state.lastSayUser = sender;
- const cooldownKey = `${cmd}-${sender}`;
- const lastUsed = this.state.commandCooldowns.get(cooldownKey) || 0;
- const now = Date.now();
- const hasAuth = this.isAuthorized(sender, messageData.isAdmin);
- if (now - lastUsed < 2000 && !hasAuth) {
- return;
- }
- this.state.commandCooldowns.set(cooldownKey, now);
- this.executeCommand(cmd, args, sender, messageData);
- }
- executeCommand(command, args, sender, messageData) {
- const hasAuth = this.isAuthorized(sender, messageData.isAdmin);
- const commands = {
- help: () => this.cmdHelp(args),
- thelp: () => this.cmdTypeHelp(args),
- fullcmd: () => this.cmdFullcmd(),
- info: () => this.cmdInfo(),
- chl: () => this.cmdChangelog(args),
- calculate: () => this.cmdCalculate(args),
- calc2: () => this.cmdTetration(args),
- rng: () => this.cmdRandom(args),
- timer: () => this.cmdTimer(args),
- say: () => this.cmdSay(args, sender, messageData.isAdmin),
- count: () => this.cmdCount(args),
- tcountdown: () => this.cmdTypeCountdown(args),
- status: () => this.cmdStatus(),
- pos: () => this.cmdPosition(args, sender),
- page: () => this.cmdPage(args),
- members: () => this.cmdMembers(),
- walls: () => this.cmdWalls(),
- authlist: () => this.cmdAuthList(),
- userlist: () => this.cmdUserList(),
- to: () =>
- hasAuth ? this.cmdTeleport(args) : this.sendMessage("Permission invalid - Authority required"),
- tp: () =>
- hasAuth ? this.cmdTp(args) : this.sendMessage("Permission invalid - Authority required"),
- type: () =>
- hasAuth ? this.cmdType(args) : this.sendMessage("Permission invalid - Authority required"),
- colorid: () => (hasAuth ? this.cmdColor(args) : this.sendMessage("Permission invalid")),
- cleararea: () =>
- hasAuth ? this.cmdClearArea(args) : this.sendMessage("Permission invalid - Authority required"),
- csay: () =>
- hasAuth ? this.cmdColoredSay(args) : this.sendMessage("Permission invalid - Authority required"),
- addauth: () =>
- hasAuth ? this.cmdAddAuth(args) : this.sendMessage("Permission invalid - Authority required"),
- removeauth: () =>
- hasAuth ? this.cmdRemoveAuth(args) : this.sendMessage("Permission invalid - Authority required"),
- ban: () => (hasAuth ? this.cmdBan(args) : this.sendMessage("Permission invalid - Authority required")),
- unban: () =>
- hasAuth ? this.cmdUnban(args) : this.sendMessage("Permission invalid - Authority required"),
- banid: () =>
- hasAuth ? this.cmdBanId(args) : this.sendMessage("Permission invalid - Authority required"),
- unbanid: () =>
- hasAuth ? this.cmdUnbanId(args) : this.sendMessage("Permission invalid - Authority required"),
- banlist: () =>
- hasAuth ? this.cmdBanList() : this.sendMessage("Permission invalid - Authority required"),
- disablehs: () =>
- hasAuth
- ? this.cmdDisableHeightSafety()
- : this.sendMessage("Permission invalid - Authority required"),
- echoauth: () =>
- hasAuth ? this.cmdToggleEcho() : this.sendMessage("Permission invalid - Authority required"),
- echocolor: () =>
- hasAuth ? this.cmdToggleEchoColor() : this.sendMessage("Permission invalid - Authority required"),
- };
- const cmdFunc = commands[command];
- if (cmdFunc) {
- cmdFunc();
- }
- }
- cmdHelp(args) {
- const pageInput = args[0];
- if (pageInput !== undefined && (isNaN(pageInput) || !Number.isInteger(Number(pageInput)))) {
- this.sendMessage("Invalid number.");
- return;
- }
- const page = parseInt(pageInput) || 1;
- const maxPage = Object.keys(COMMAND_PAGES).length;
- if (page < 1 || page > maxPage) {
- this.sendMessage(`Invalid number. Use ${this.config.prefix}help 1-${maxPage}`);
- return;
- }
- this.sendMessage(`Commands Page ${page}/${maxPage}:`);
- const commands = COMMAND_PAGES[page];
- commands.forEach((cmd, index) => {
- setTimeout(
- () => {
- this.sendMessage(
- `${INVISIBLE_CHAR}${this.config.prefix}${cmd.cmd}${cmd.auth ? " [A]" : ""} - ${cmd.desc}`
- );
- },
- (index + 1) * 700
- );
- });
- }
- cmdChangelog(args) {
- const pageInput = args[0];
- if (pageInput !== undefined && (isNaN(pageInput) || !Number.isInteger(Number(pageInput)))) {
- this.sendMessage("Invalid number.");
- return;
- }
- const itemsPerPage = 5;
- const totalPages = Math.ceil(CHANGELOG.length / itemsPerPage);
- const page = parseInt(pageInput) || 1;
- if (page < 1 || page > totalPages) {
- this.sendMessage(`Invalid number. Use ${this.config.prefix}chl 1-${totalPages}`);
- return;
- }
- const startIndex = (page - 1) * itemsPerPage;
- const endIndex = Math.min(startIndex + itemsPerPage, CHANGELOG.length);
- const pageEntries = CHANGELOG.slice(startIndex, endIndex);
- this.sendMessage(`Changelog Page ${page}/${totalPages}:`);
- pageEntries.forEach((entry, index) => {
- setTimeout(
- () => {
- this.sendMessage(`${INVISIBLE_CHAR}v${entry.version}: ${entry.changes}`);
- },
- (index + 1) * 700
- );
- });
- }
- cmdTypeCountdown(args) {
- if (this.state.countdownActive) {
- this.sendMessage("Countdown already active!");
- return;
- }
- if (args.length < 1) {
- this.sendMessage(`Usage: ${this.config.prefix}tcountdown [seconds]`);
- return;
- }
- const startSeconds = parseInt(args[0]);
- if (isNaN(startSeconds) || startSeconds <= 0) {
- this.sendMessage("Error: seconds must be a positive integer");
- return;
- }
- if (startSeconds > 86400) { // 24 hours max
- this.sendMessage("Error: seconds cannot exceed 86400 (24 hours)");
- return;
- }
- if (typeof w.tp !== 'function' || typeof w.typeChar !== 'function') {
- this.sendMessage("Error: w.tp or w.typeChar function not available");
- return;
- }
- this.state.countdownActive = true;
- let currentSeconds = startSeconds;
- const startX = 0;
- const startY = -5;
- const endX = 25;
- this.sendMessage(`Starting countdown from ${startSeconds}s at (${startX}, ${startY})...`);
- const countdownInterval = setInterval(() => {
- if (!this.running || !this.state.countdownActive || currentSeconds < 0) {
- clearInterval(countdownInterval);
- this.state.countdownActive = false;
- if (currentSeconds < 0) {
- this.sendMessage("Countdown complete!");
- }
- return;
- }
- try {
- // Teleport to start position
- w.tp(startX, startY);
- // Format time
- const hours = Math.floor(currentSeconds / 3600);
- const minutes = Math.floor((currentSeconds % 3600) / 60);
- const seconds = currentSeconds % 60;
- let timeStr = "";
- if (hours > 0) {
- timeStr += `${hours}h `;
- }
- if (minutes > 0) {
- timeStr += `${minutes}m `;
- }
- if (seconds > 0 || timeStr === "") {
- timeStr += `${seconds}s`;
- }
- timeStr = timeStr.trim();
- // Type the countdown
- for (let char of timeStr) {
- w.typeChar(char, 1);
- }
- // Calculate how many spaces needed to reach endX
- const charsTyped = timeStr.length;
- const spacesNeeded = endX - charsTyped;
- // Type spaces until endX
- for (let i = 0; i < spacesNeeded; i++) {
- w.typeChar(' ', 1);
- }
- console.log(`[TCOUNTDOWN] Typed "${timeStr}" at (${startX}, ${startY})`);
- } catch (e) {
- console.error(`[TCOUNTDOWN ERROR] Failed to type countdown:`, e);
- clearInterval(countdownInterval);
- this.state.countdownActive = false;
- return;
- }
- currentSeconds--;
- }, 1000);
- }
- async cmdClearArea(args) {
- if (this.state.clearingArea) {
- this.sendMessage("Already clearing area! Please wait.");
- return;
- }
- if (args.length !== 2 && args.length !== 4) {
- this.sendMessage(`Usage: ${this.config.prefix}cleararea x y OR x1 y1 x2 y2`);
- return;
- }
- if (typeof w.tp !== 'function' || typeof w.typeChar !== 'function') {
- this.sendMessage("Error: w.tp or w.typeChar function not available");
- return;
- }
- if (args.length === 2) {
- // Single point mode
- const x = parseInt(args[0]);
- const y = parseInt(args[1]);
- if (isNaN(x) || isNaN(y)) {
- this.sendMessage("Invalid coordinates. Please provide integers.");
- return;
- }
- // Negate Y
- const flippedY = -y;
- try {
- this.state.clearingArea = true;
- w.tp(x, flippedY);
- w.typeChar(' ', 1);
- this.sendMessage(`Cleared position (${x}, ${y})`);
- console.log(`[CLEARAREA] Cleared single point at (${x}, ${flippedY})`);
- } catch (e) {
- this.sendMessage(`Error clearing area: ${e.message || "Unknown error"}`);
- console.error(`[CLEARAREA ERROR]`, e);
- } finally {
- this.state.clearingArea = false;
- }
- } else {
- // Rectangle mode
- const x1 = parseInt(args[0]);
- const y1 = parseInt(args[1]);
- const x2 = parseInt(args[2]);
- const y2 = parseInt(args[3]);
- if (isNaN(x1) || isNaN(y1) || isNaN(x2) || isNaN(y2)) {
- this.sendMessage("Invalid coordinates. Please provide integers.");
- return;
- }
- // Negate Y coordinates
- const flippedY1 = -y1;
- const flippedY2 = -y2;
- // Calculate bounds
- const minX = Math.min(x1, x2);
- const maxX = Math.max(x1, x2);
- const minY = Math.min(flippedY1, flippedY2);
- const maxY = Math.max(flippedY1, flippedY2);
- const width = maxX - minX + 1;
- const height = maxY - minY + 1;
- const totalChars = width * height;
- if (totalChars > 10000) {
- this.sendMessage("Error: Area too large (max 10000 characters)");
- return;
- }
- this.sendMessage(`Clearing area from (${x1}, ${y1}) to (${x2}, ${y2})...`);
- this.state.clearingArea = true;
- try {
- for (let y = minY; y <= maxY; y++) {
- if (!this.running || !this.state.clearingArea) break;
- w.tp(minX, y);
- for (let x = minX; x <= maxX; x++) {
- if (!this.running || !this.state.clearingArea) break;
- w.typeChar(' ', 1);
- await new Promise(resolve => setTimeout(resolve, 10));
- }
- }
- this.sendMessage(`Cleared ${width}x${height} area (${totalChars} chars)`);
- console.log(`[CLEARAREA] Cleared rectangle from (${minX}, ${minY}) to (${maxX}, ${maxY})`);
- } catch (e) {
- this.sendMessage(`Error clearing area: ${e.message || "Unknown error"}`);
- console.error(`[CLEARAREA ERROR]`, e);
- } finally {
- this.state.clearingArea = false;
- }
- }
- }
- cmdUserList() {
- const onlineUsers = [];
- // Use Array.from(w.cursors) for cursor detection
- try {
- if (typeof w !== 'undefined' && w.cursors) {
- const cursors = Array.from(w.cursors);
- for (let [id, cursor] of cursors) {
- if (cursor && cursor.name && !onlineUsers.includes(cursor.name)) {
- onlineUsers.push(cursor.name);
- }
- }
- } else {
- // Fallback to state.cursors
- for (let cursor of this.state.cursors.values()) {
- if (cursor.name && !onlineUsers.includes(cursor.name)) {
- onlineUsers.push(cursor.name);
- }
- }
- }
- } catch (e) {
- console.error(`[USERLIST ERROR]`, e);
- // Fallback to state.cursors
- for (let cursor of this.state.cursors.values()) {
- if (cursor.name && !onlineUsers.includes(cursor.name)) {
- onlineUsers.push(cursor.name);
- }
- }
- }
- // Sort alphabetically
- onlineUsers.sort();
- if (onlineUsers.length === 0) {
- this.sendMessage("Online Users: None");
- } else {
- this.sendMessage(`Online Users: ${onlineUsers.join(", ")}`);
- }
- console.log(`[USERLIST] ${onlineUsers.length} users online: ${onlineUsers.join(", ")}`);
- }
- cmdTypeHelp(args) {
- if (this.state.isTyping) {
- this.sendMessage("Bot is already typing. Please wait.");
- return;
- }
- const pageInput = args[0];
- if (!pageInput || isNaN(pageInput) || !Number.isInteger(Number(pageInput))) {
- this.sendMessage(`Usage: ${this.config.prefix}thelp [page number]`);
- return;
- }
- const page = parseInt(pageInput);
- const maxPage = Object.keys(COMMAND_PAGES).length;
- if (page < 1 || page > maxPage) {
- this.sendMessage(`Invalid page. Use ${this.config.prefix}thelp 1-${maxPage}`);
- return;
- }
- if (typeof w.typeChar !== "function") {
- this.sendMessage("Error: typeChar function not available");
- return;
- }
- const commands = COMMAND_PAGES[page];
- const lines = [`Commands [PAGE: ${page}]`];
- commands.forEach((cmd) => {
- lines.push(`${this.config.prefix}${cmd.cmd}${cmd.auth ? " [A]" : ""} - ${cmd.desc}`);
- });
- this.state.isTyping = true;
- const startX = this.config.position.x;
- let currentY = this.config.position.y;
- let lineIndex = 0;
- let charIndex = 0;
- this.sendMessage(`Typing help page ${page} on wall...`);
- const typeNextChar = () => {
- if (!this.running || !this.state.isTyping) {
- this.state.isTyping = false;
- return;
- }
- if (lineIndex >= lines.length) {
- this.state.isTyping = false;
- console.log(`[THELP] Finished typing help page ${page}`);
- return;
- }
- const currentLine = lines[lineIndex];
- if (charIndex >= currentLine.length) {
- this.teleportCursor(startX, currentY + 1);
- currentY++;
- lineIndex++;
- charIndex = 0;
- if (lineIndex < lines.length) {
- setTimeout(typeNextChar, 100);
- } else {
- this.state.isTyping = false;
- console.log(`[THELP] Finished typing help page ${page}`);
- }
- return;
- }
- try {
- const char = currentLine[charIndex];
- w.typeChar(char, 1);
- charIndex++;
- setTimeout(typeNextChar, 30);
- } catch (e) {
- console.error(`[THELP ERROR] Failed to type character:`, e);
- this.state.isTyping = false;
- }
- };
- this.teleportCursor(startX, currentY);
- typeNextChar();
- }
- cmdFullcmd() {
- this.sendMessage("if you wanna see all the commands, head to ~KiwiTest/diamondbot");
- }
- cmdInfo() {
- this.sendMessage(`This bot was made by KiwiTest, version ${this.config.version}`);
- }
- cmdPage(args) {
- const page = parseInt(args[0]) || 1;
- const maxPage = Object.keys(COMMAND_PAGES).length;
- if (page < 1 || page > maxPage) {
- this.sendMessage(`Invalid page. Pages: 1-${maxPage}`);
- return;
- }
- this.sendMessage(`Page ${page} Detailed Info:`);
- const commands = COMMAND_PAGES[page];
- commands.forEach((cmd, i) => {
- setTimeout(
- () => {
- this.sendMessage(`${i + 1}. ${INVISIBLE_CHAR}${this.config.prefix}${cmd.cmd} - ${cmd.desc}`);
- },
- (i + 1) * 700
- );
- });
- }
- cmdSay(args, sender, isAdmin) {
- if (args.length < 1) {
- this.sendMessage(`Usage: ${this.config.prefix}say [message]`);
- return;
- }
- const message = args.join(" ");
- if (this.containsAuthorityCommand(message)) {
- const hasAuth = this.isAuthorized(sender, isAdmin);
- if (!hasAuth) {
- this.sendMessage("ERR: trying to bypass authority!");
- console.log(`[SECURITY] User ${sender} attempted to bypass authority with say command!`);
- return;
- }
- }
- this.sendMessage(message);
- }
- cmdType(args) {
- if (args.length < 2) {
- this.sendMessage(`Usage: ${this.config.prefix}type text step (step can be number or 'all')`);
- return;
- }
- const text = args.slice(0, -1).join(" ");
- const stepArg = args[args.length - 1].toLowerCase();
- if (text.length === 0) {
- this.sendMessage("Error: No text provided");
- return;
- }
- if (typeof w.typeChar !== "function") {
- this.sendMessage("Error: typeChar function not available");
- return;
- }
- if (stepArg === "all") {
- let delay = 0;
- for (let i = 0; i < text.length; i++) {
- const char = text[i];
- setTimeout(() => {
- try {
- w.typeChar(char, i);
- console.log(`[TYPE] Typed '${char}' at step ${i}`);
- } catch (e) {
- console.error(`[TYPE ERROR] Failed to type '${char}' at step ${i}:`, e);
- }
- }, delay);
- delay += 50;
- }
- this.sendMessage(`Typing "${text}" across ${text.length} steps`);
- return;
- }
- const step = parseInt(stepArg);
- if (isNaN(step)) {
- this.sendMessage("Error: Step must be a number or 'all'");
- return;
- }
- if (step < 0) {
- this.sendMessage("Error: Step must be non-negative");
- return;
- }
- try {
- for (let char of text) {
- w.typeChar(char, step);
- }
- this.sendMessage(`Typed "${text}" at step ${step}`);
- console.log(`[TYPE] Typed "${text}" at step ${step}`);
- } catch (e) {
- this.sendMessage(`Error typing text: ${e.message || "Unknown error"}`);
- console.error(`[TYPE ERROR]`, e);
- }
- }
- cmdCount(args) {
- if (args.length < 2) {
- this.sendMessage(`Usage: ${this.config.prefix}count n cooldown`);
- return;
- }
- const n = parseInt(args[0]);
- const cooldown = parseInt(args[1]);
- if (isNaN(n) || !Number.isInteger(n) || n <= 0) {
- this.sendMessage("Error: n must be a positive integer");
- return;
- }
- if (isNaN(cooldown) || !Number.isInteger(cooldown) || cooldown < 100) {
- this.sendMessage("Error: cooldown must be an integer >= 100 (milliseconds)");
- return;
- }
- if (n > 100) {
- this.sendMessage("Error: n cannot exceed 100");
- return;
- }
- const countId = Date.now();
- let current = 1;
- this.sendMessage(`Starting count to ${n} with ${cooldown}ms delay...`);
- const intervalId = setInterval(() => {
- if (current > n || !this.running) {
- clearInterval(intervalId);
- this.state.activeCounts.delete(countId);
- if (current > n) {
- this.sendMessage(`Count complete!`);
- }
- return;
- }
- this.sendMessage(current.toString());
- current++;
- }, cooldown);
- this.state.activeCounts.set(countId, { intervalId, max: n });
- }
- cmdColoredSay(args) {
- if (args.length < 2) {
- this.sendMessage(`Usage: ${this.config.prefix}csay [colorid] [text]`);
- return;
- }
- const colorInput = args[0].toLowerCase();
- let colorIndex;
- if (!isNaN(colorInput)) {
- colorIndex = parseInt(colorInput);
- if (colorIndex < 0 || colorIndex > 15) {
- this.sendMessage("Invalid colorid");
- return;
- }
- } else if (colorInput.startsWith("#")) {
- colorIndex = COLORS[colorInput];
- if (colorIndex === undefined) {
- this.sendMessage("Invalid colorid");
- return;
- }
- } else {
- this.sendMessage("Invalid colorid");
- return;
- }
- const text = args.slice(1).join(" ");
- if (!text || text.trim().length === 0) {
- this.sendMessage("Invalid text characters");
- return;
- }
- const originalColor = this.config.color;
- this.setColor(colorIndex);
- setTimeout(() => {
- this.sendMessage(text);
- setTimeout(() => {
- this.setColor(originalColor);
- }, 100);
- }, 100);
- }
- cmdCalculate(args) {
- if (args.length < 2) {
- this.sendMessage(`Usage: ${this.config.prefix}calculate base exponent`);
- return;
- }
- try {
- const base = args[0];
- const exp = args[1];
- const result = window.Decimal.pow(new window.Decimal(base), new window.Decimal(exp));
- this.sendMessage(`${base}^${exp} = ${result.toString()}`);
- } catch (error) {
- this.sendMessage("Error: Invalid input for calculation");
- }
- }
- cmdTetration(args) {
- if (args.length < 2) {
- this.sendMessage(`Usage: ${this.config.prefix}calc2 base height`);
- return;
- }
- try {
- const base = args[0];
- const height = parseInt(args[1]);
- if (height < 0 || !Number.isInteger(height)) {
- this.sendMessage("Height must be a non-negative integer");
- return;
- }
- if (this.config.heightSafetyEnabled && height > 5) {
- this.sendMessage(`Height too large! Maximum is 5 (Height Safety ON)`);
- return;
- }
- const result = window.Decimal.tetrate(new window.Decimal(base), height);
- this.sendMessage(`${base}^^${height} = ${result.toString()}`);
- } catch (error) {
- this.sendMessage("Error: Invalid input for tetration");
- }
- }
- cmdRandom(args) {
- if (args.length < 2) {
- this.sendMessage(`Usage: ${this.config.prefix}rng min max`);
- return;
- }
- const min = parseFloat(args[0]);
- const max = parseFloat(args[1]);
- if (isNaN(min) || isNaN(max)) {
- this.sendMessage("Invalid input. Please provide valid numbers.");
- return;
- }
- if (min > max) {
- this.sendMessage("Min must be less than or equal to max.");
- return;
- }
- const randomNum = Math.random() * (max - min) + min;
- this.sendMessage(`Random number between ${min} and ${max}: ${randomNum.toFixed(2)}`);
- }
- cmdTimer(args) {
- if (args.length < 3) {
- this.sendMessage(`Usage: ${this.config.prefix}timer hours minutes seconds (use 0 to skip)`);
- return;
- }
- const hours = Math.max(0, parseInt(args[0]) || 0);
- const minutes = Math.max(0, parseInt(args[1]) || 0);
- const seconds = Math.max(0, parseInt(args[2]) || 0);
- if (hours === 0 && minutes === 0 && seconds === 0) {
- this.sendMessage("Timer must have at least one non-zero value");
- return;
- }
- if (hours > 24) {
- this.sendMessage("Maximum timer is 24 hours");
- return;
- }
- const totalMs = (hours * 3600 + minutes * 60 + seconds) * 1000;
- let timeStr = [];
- if (hours > 0) timeStr.push(`${hours}h`);
- if (minutes > 0) timeStr.push(`${minutes}m`);
- if (seconds > 0) timeStr.push(`${seconds}s`);
- const timerId = Date.now();
- this.sendMessage(`Timer set for ${timeStr.join(" ")} (ID: ${timerId})`);
- const timerObj = setTimeout(() => {
- this.sendMessage(`TIMER COMPLETE! ${timeStr.join(" ")} has elapsed (ID: ${timerId})`);
- this.state.activeTimers.delete(timerId);
- }, totalMs);
- this.state.activeTimers.set(timerId, {
- timeout: timerObj,
- duration: timeStr.join(" "),
- startTime: Date.now(),
- endTime: Date.now() + totalMs,
- });
- if (totalMs > 60000) {
- let updateCount = 0;
- const maxUpdates = 3;
- const updateInterval = Math.max(30000, totalMs / 4);
- const intervalId = setInterval(() => {
- const timer = this.state.activeTimers.get(timerId);
- if (!timer || updateCount >= maxUpdates) {
- clearInterval(intervalId);
- return;
- }
- const remaining = timer.endTime - Date.now();
- if (remaining > 1000) {
- const h = Math.floor(remaining / 3600000);
- const m = Math.floor((remaining % 3600000) / 60000);
- const s = Math.floor((remaining % 60000) / 1000);
- let remStr = [];
- if (h > 0) remStr.push(`${h}h`);
- if (m > 0) remStr.push(`${m}m`);
- if (s > 0) remStr.push(`${s}s`);
- this.sendMessage(`Timer ${timerId}: ${remStr.join(" ")} remaining`);
- updateCount++;
- }
- }, updateInterval);
- this.state.activeTimers.get(timerId).intervalId = intervalId;
- }
- }
- cmdStatus() {
- const status = [
- `Wall: ${this.state.wall}/${this.state.subwall}`,
- `Perms: ${["User", "Member", "Owner"][this.state.perms]}`,
- `Pos: (${this.config.position.x}, ${this.config.position.y})`,
- `Timers: ${this.state.activeTimers.size}`,
- `Color: ${this.config.color}`,
- `HS: ${this.config.heightSafetyEnabled ? "ON" : "OFF"}`,
- `Echo: ${this.config.authorityEchoEnabled ? "ON" : "OFF"}`,
- `EchoColor: ${this.config.echoColorEnabled ? "ON" : "OFF"}`,
- `Auth: ${this.config.authorizedUsers.length}`,
- `Banned: ${this.config.bannedUsers.length}/${this.config.bannedIds.length}`,
- ];
- this.sendMessage(status.join(" | "));
- }
- cmdPosition(args, sender) {
- if (args.length === 0) {
- const pos = this.getCursorPosition(sender);
- if (pos) {
- this.sendMessage(`Cursor position of ${sender}: (${pos[0]}, ${pos[1]})`);
- } else {
- this.sendMessage(`Cursor position of ${sender}: Not found in wall`);
- }
- return;
- }
- const targetUser = args[0];
- const pos = this.getCursorPosition(targetUser);
- if (pos) {
- this.sendMessage(`Cursor position of ${targetUser}: (${pos[0]}, ${pos[1]})`);
- } else {
- this.sendMessage(`Cursor position of ${targetUser}: Not found in wall`);
- }
- }
- cmdMembers() {
- if (this.state.members.length === 0) {
- this.sendMessage("No members in this wall");
- } else {
- this.sendMessage(`Members: ${this.state.members.join(", ")}`);
- }
- }
- cmdWalls() {
- if (this.state.walllist.length === 0) {
- this.sendMessage("No subwalls available");
- } else {
- const walls = [];
- for (let i = 0; i < this.state.walllist.length; i += 2) {
- const wallName = this.state.walllist[i];
- const isPrivate = this.state.walllist[i + 1];
- walls.push(`${wallName}${isPrivate ? " (private)" : ""}`);
- }
- this.sendMessage(`Subwalls: ${walls.join(", ")}`);
- }
- }
- cmdTeleport(args) {
- if (args.length < 2) {
- this.sendMessage(`Usage: ${this.config.prefix}to X Y`);
- return;
- }
- const x = parseInt(args[0]);
- const y = parseInt(args[1]);
- if (isNaN(x) || isNaN(y)) {
- this.sendMessage("Invalid coordinates. Please provide integers.");
- return;
- }
- if (Math.abs(x) > 10000 || Math.abs(y) > 10000) {
- this.sendMessage("Coordinates out of range (max +-10000)");
- return;
- }
- this.teleportCursor(x, y);
- this.sendMessage(`Teleported to (${x}, ${y})`);
- }
- cmdTp(args) {
- if (args.length < 2) {
- this.sendMessage(`Usage: ${this.config.prefix}tp X Y`);
- return;
- }
- const x = parseInt(args[0]);
- const y = parseInt(args[1]);
- if (isNaN(x) || isNaN(y)) {
- this.sendMessage("Invalid coordinates. Please provide integers.");
- return;
- }
- if (Math.abs(x) > 10000 || Math.abs(y) > 10000) {
- this.sendMessage("Coordinates out of range (max +-10000)");
- return;
- }
- if (typeof w.tp !== 'function') {
- this.sendMessage("Error: w.tp function not available");
- return;
- }
- try {
- w.tp(x, y);
- this.config.position.x = x;
- this.config.position.y = y;
- this.sendMessage(`Teleported to (${x}, ${y}) using w.tp`);
- console.log(`[TP] Teleported to (${x}, ${y}) using w.tp`);
- } catch (e) {
- this.sendMessage(`Error using w.tp: ${e.message || "Unknown error"}`);
- console.error(`[TP ERROR]`, e);
- }
- }
- cmdColor(args) {
- if (args.length < 1) {
- this.sendMessage(`Usage: ${this.config.prefix}colorid #hex or 0-15`);
- return;
- }
- const input = args[0].toLowerCase();
- let colorIndex;
- if (!isNaN(input)) {
- colorIndex = parseInt(input);
- if (colorIndex < 0 || colorIndex > 15) {
- this.sendMessage("Invalid colot");
- return;
- }
- } else if (input.startsWith("#")) {
- colorIndex = COLORS[input];
- if (colorIndex === undefined) {
- this.sendMessage("Invalid colot");
- return;
- }
- } else {
- this.sendMessage("Invalid colot");
- return;
- }
- this.setColor(colorIndex);
- this.sendMessage(`Color changed to ${colorIndex}`);
- }
- cmdBan(args) {
- if (args.length < 1) {
- this.sendMessage(`Usage: ${this.config.prefix}ban username`);
- return;
- }
- const username = args[0];
- if (this.config.authorizedUsers.includes(username)) {
- this.sendMessage(`Cannot ban authority user ${username}`);
- return;
- }
- if (this.config.bannedUsers.includes(username)) {
- this.sendMessage(`${username} is already banned`);
- return;
- }
- this.config.bannedUsers.push(username);
- Storage.save("bannedUsers", this.config.bannedUsers);
- this.sendMessage(`Banned ${username} from using bot`);
- console.log(`[BAN] ${username} has been banned`);
- }
- cmdUnban(args) {
- if (args.length < 1) {
- this.sendMessage(`Usage: ${this.config.prefix}unban username or ID`);
- return;
- }
- const input = args[0];
- if (!isNaN(input)) {
- const idToUnban = input;
- const index = this.config.bannedIds.indexOf(idToUnban);
- if (index === -1) {
- this.sendMessage(`Error: ID ${idToUnban} is not banned`);
- return;
- }
- this.config.bannedIds.splice(index, 1);
- Storage.save("bannedIds", this.config.bannedIds);
- this.sendMessage(`Unbanned ID ${idToUnban}`);
- console.log(`[UNBAN] ID ${idToUnban} has been unbanned`);
- } else {
- const username = input;
- const index = this.config.bannedUsers.indexOf(username);
- if (index === -1) {
- this.sendMessage(`Error: ${username} is not banned`);
- return;
- }
- this.config.bannedUsers.splice(index, 1);
- Storage.save("bannedUsers", this.config.bannedUsers);
- this.sendMessage(`Unbanned ${username}`);
- console.log(`[UNBAN] ${username} has been unbanned`);
- }
- }
- cmdBanId(args) {
- if (args.length < 1) {
- this.sendMessage(`Usage: ${this.config.prefix}banid username`);
- return;
- }
- const username = args[0];
- const userId = this.getUserId(username);
- if (!userId) {
- this.sendMessage(`Cannot find user ID for ${username}. User must be in wall.`);
- return;
- }
- if (this.config.authorizedUsers.includes(username)) {
- this.sendMessage(`Cannot ban authority user ${username}`);
- return;
- }
- if (this.config.bannedIds.includes(userId)) {
- this.sendMessage(`User ID ${userId} is already banned`);
- return;
- }
- this.config.bannedIds.push(userId);
- Storage.save("bannedIds", this.config.bannedIds);
- this.sendMessage(`Banned user ID for ${username} (ID: ${userId})`);
- console.log(`[BANID] ${username} (ID: ${userId}) has been banned`);
- }
- cmdUnbanId(args) {
- if (args.length < 1) {
- this.sendMessage(`Usage: ${this.config.prefix}unbanid userid`);
- return;
- }
- const userId = args[0];
- const index = this.config.bannedIds.indexOf(userId);
- if (index === -1) {
- this.sendMessage(`ID ${userId} is not banned`);
- return;
- }
- this.config.bannedIds.splice(index, 1);
- Storage.save("bannedIds", this.config.bannedIds);
- this.sendMessage(`Unbanned ID ${userId}`);
- console.log(`[UNBANID] ID ${userId} has been unbanned`);
- }
- cmdBanList() {
- const userBans = this.config.bannedUsers.length === 0 ? "None" : this.config.bannedUsers.join(", ");
- const idBans = this.config.bannedIds.length === 0 ? "None" : `${this.config.bannedIds.length} IDs`;
- this.sendMessage(`Banned users: ${userBans} | Banned IDs: ${idBans}`);
- }
- cmdAddAuth(args) {
- if (args.length < 1) {
- this.sendMessage(`Usage: ${this.config.prefix}addauth username`);
- return;
- }
- const username = args[0];
- if (this.config.authorizedUsers.includes(username)) {
- this.sendMessage(`${username} already has authority`);
- return;
- }
- const banIndex = this.config.bannedUsers.indexOf(username);
- if (banIndex !== -1) {
- this.config.bannedUsers.splice(banIndex, 1);
- Storage.save("bannedUsers", this.config.bannedUsers);
- }
- this.config.authorizedUsers.push(username);
- Storage.save("authorizedUsers", this.config.authorizedUsers);
- this.sendMessage(`Added ${username} to authority list`);
- console.log(`[AUTH+] Authority granted to: ${username}`);
- }
- cmdRemoveAuth(args) {
- if (args.length < 1) {
- this.sendMessage(`Usage: ${this.config.prefix}removeauth username`);
- return;
- }
- const username = args[0];
- if (username === "Diamond25" || username === "KiwiTest") {
- this.sendMessage(`Cannot remove default authority from ${username}`);
- return;
- }
- const index = this.config.authorizedUsers.indexOf(username);
- if (index === -1) {
- this.sendMessage(`${username} doesn't have authority`);
- return;
- }
- this.config.authorizedUsers.splice(index, 1);
- Storage.save("authorizedUsers", this.config.authorizedUsers);
- this.sendMessage(`Removed ${username} from authority list`);
- console.log(`[AUTH-] Authority revoked from: ${username}`);
- }
- cmdDisableHeightSafety() {
- this.config.heightSafetyEnabled = !this.config.heightSafetyEnabled;
- const status = this.config.heightSafetyEnabled ? "ENABLED" : "DISABLED";
- const info = this.config.heightSafetyEnabled ? "(Max height: 5)" : "(No height limit)";
- this.sendMessage(`Height safety is now ${status} ${info}`);
- console.log(`Height safety: ${status}`);
- }
- cmdToggleEcho() {
- if (!this.config.authorityEchoEnabled) {
- this.config.authorityEchoEnabled = true;
- this.sendMessage("Authority echo is now ENABLED (with recursion protection)");
- } else {
- this.config.authorityEchoEnabled = false;
- this.sendMessage("Authority echo is now DISABLED");
- }
- console.log(`Authority echo: ${this.config.authorityEchoEnabled ? "ENABLED" : "DISABLED"}`);
- }
- cmdToggleEchoColor() {
- if (!this.config.echoColorEnabled) {
- this.config.echoColorEnabled = true;
- this.sendMessage("Color echo is now ENABLED (echoes authority messages with color syntax)");
- } else {
- this.config.echoColorEnabled = false;
- this.sendMessage("Color echo is now DISABLED");
- }
- console.log(`Color echo: ${this.config.echoColorEnabled ? "ENABLED" : "DISABLED"}`);
- }
- cmdAuthList() {
- const authUsers = [...this.config.authorizedUsers];
- const adminUsers = Array.from(this.state.adminUsers);
- const allAuth = [...new Set([...authUsers, ...adminUsers])];
- this.sendMessage(`Authorized users (${allAuth.length}): ${allAuth.join(", ")}`);
- }
- setUsername(username) {
- if (typeof api !== "undefined" && api.nick) {
- api.nick(username);
- } else if (typeof setNick === "function") {
- setNick(username);
- } else if (typeof changeNick === "function") {
- changeNick(username);
- }
- console.log(`[USERNAME] ${username}`);
- }
- setColor(colorIndex) {
- if (typeof api !== "undefined" && api.color) {
- api.color(colorIndex);
- } else if (typeof setColor === "function") {
- setColor(colorIndex);
- }
- this.config.color = colorIndex;
- console.log(`[COLOR] Set to: ${colorIndex}`);
- }
- teleportCursor(x, y) {
- if (typeof api !== "undefined" && api.cursor) {
- api.cursor(x, y);
- } else if (typeof moveCursor === "function") {
- moveCursor(x, y);
- } else if (typeof cursor === "object" && cursor.move) {
- cursor.move(x, y);
- }
- this.config.position.x = x;
- this.config.position.y = y;
- }
- sendMessage(message) {
- if (this.state.disablechat && !this.state.isShuttingDown) {
- console.log("Chat is disabled, cannot send message");
- return;
- }
- // Parse colored segments
- const segments = this.parseColoredMessage(message);
- // If message has colored segments, handle them
- if (segments.length > 1 || (segments.length === 1 && segments[0].color !== null)) {
- const originalColor = this.config.color;
- let delay = 0;
- segments.forEach((segment, index) => {
- setTimeout(() => {
- if (segment.color !== null) {
- this.setColor(segment.color);
- } else if (index > 0) {
- this.setColor(originalColor);
- }
- setTimeout(() => {
- this.state.messageQueue.push(segment.text);
- if (!this.state.isProcessingQueue) {
- this.processMessageQueue();
- }
- // Restore original color after last segment
- if (index === segments.length - 1) {
- setTimeout(() => {
- this.setColor(originalColor);
- }, 100);
- }
- }, 50);
- }, delay);
- delay += 200;
- });
- return;
- }
- // Normal message without colors
- this.state.messageQueue.push(message);
- if (!this.state.isProcessingQueue) {
- this.processMessageQueue();
- }
- }
- async processMessageQueue() {
- if (this.state.messageQueue.length === 0 || (!this.running && !this.state.isShuttingDown)) {
- this.state.isProcessingQueue = false;
- return;
- }
- this.state.isProcessingQueue = true;
- const message = this.state.messageQueue.shift();
- const now = Date.now();
- const timeSinceLastMessage = now - this.state.lastMessageTime;
- if (timeSinceLastMessage < this.config.messageDelay) {
- await new Promise((resolve) => setTimeout(resolve, this.config.messageDelay - timeSinceLastMessage));
- }
- this.state.lastMessageTime = Date.now();
- try {
- if (w && w.chat && w.chat.send) {
- w.chat.send(message);
- console.log(`[SENT] ${message}`);
- } else {
- if (typeof sendChat === "function") {
- sendChat(message);
- } else if (typeof api !== "undefined" && api.chat) {
- api.chat(message);
- } else {
- console.error("No chat send method available!");
- }
- }
- } catch (error) {
- console.error("Failed to send message:", error);
- }
- setTimeout(() => this.processMessageQueue(), this.config.messageDelay);
- }
- }
- console.clear();
- console.log(`Starting TextWall Bot v${BOT_CONFIG.version}...`);
- const bot = new TextWallBot(BOT_CONFIG);
- await bot.init();
- window.diamondBot = bot;
- window.sendMessage = function (message) {
- if (!message) {
- console.error("Error: No message provided. Usage: sendMessage('your message')");
- return;
- }
- bot.sendMessage(`[SYSTEM]: ${message}`);
- console.log(`[SYSTEM MESSAGE SENT]: ${message}`);
- };
- window.unbanName = function (username) {
- if (!username) {
- console.error("Error: No username provided. Usage: unbanName('username')");
- return;
- }
- const index = bot.config.bannedUsers.indexOf(username);
- if (index === -1) {
- console.error(`Error: ${username} is not in the ban list`);
- return;
- }
- bot.config.bannedUsers.splice(index, 1);
- Storage.save("bannedUsers", bot.config.bannedUsers);
- console.log(`[CONSOLE UNBAN] ${username} has been unbanned from the ban list`);
- console.log(`Current banned users: ${bot.config.bannedUsers.length > 0 ? bot.config.bannedUsers.join(", ") : "None"}`);
- };
- window.stopBot = async function () {
- console.log("Initiating shutdown sequence...");
- bot.state.isShuttingDown = true;
- bot.state.isTyping = false;
- bot.state.countdownActive = false;
- bot.state.clearingArea = false;
- bot.sendMessage("Closing bot..");
- await new Promise((resolve) => setTimeout(resolve, 500));
- bot.running = false;
- bot.state.activeTimers.forEach((timer) => {
- clearTimeout(timer.timeout);
- if (timer.intervalId) clearInterval(timer.intervalId);
- });
- bot.state.activeCounts.forEach((count) => {
- if (count.intervalId) clearInterval(count.intervalId);
- });
- for (let [event, handler] of Object.entries(bot.eventHandlers)) {
- if (w && w.off) {
- w.off(event, handler);
- }
- }
- bot.sendMessage("Bot successfully shutdown.");
- await new Promise((resolve) => setTimeout(resolve, 500));
- bot.state.isProcessingQueue = false;
- bot.state.messageQueue = [];
- console.log("[OK] Bot stopped completely");
- };
- window.restartBot = async function () {
- console.log("Restarting bot...");
- await window.stopBot();
- await new Promise((resolve) => setTimeout(resolve, 1000));
- const newBot = new TextWallBot(BOT_CONFIG);
- await newBot.init();
- window.diamondBot = newBot;
- console.log("[OK] Bot restarted");
- };
- window.botStatus = function () {
- console.table({
- Username: bot.config.username,
- Version: bot.config.version,
- Prefix: bot.config.prefix,
- Wall: `${bot.state.wall}/${bot.state.subwall}`,
- Position: `(${bot.config.position.x}, ${bot.config.position.y})`,
- Color: bot.config.color,
- Permissions: ["User", "Member", "Owner"][bot.state.perms] || "Unknown",
- "Active Timers": bot.state.activeTimers.size,
- "Active Counts": bot.state.activeCounts.size,
- "Countdown Active": bot.state.countdownActive ? "YES" : "NO",
- "Clearing Area": bot.state.clearingArea ? "YES" : "NO",
- "Authorized Users": bot.config.authorizedUsers.length,
- "Banned Users": bot.config.bannedUsers.length,
- "Banned IDs": bot.config.bannedIds.length,
- "Height Safety": bot.config.heightSafetyEnabled ? "ON" : "OFF",
- "Authority Echo": bot.config.authorityEchoEnabled ? "ON" : "OFF",
- "Color Echo": bot.config.echoColorEnabled ? "ON" : "OFF",
- "Is Typing": bot.state.isTyping ? "YES" : "NO",
- "Queue Size": bot.state.messageQueue.length,
- });
- };
- window.showCommands = function () {
- console.log("\n====================================");
- console.log(` ALL BOT COMMANDS (v${BOT_CONFIG.version}) `);
- console.log("====================================\n");
- for (let pageNum in COMMAND_PAGES) {
- console.log(`\nPAGE ${pageNum}:`);
- console.log("-".repeat(50));
- const page = COMMAND_PAGES[pageNum];
- page.forEach((cmd) => {
- const authIcon = cmd.auth ? "[A]" : " ";
- const cmdName = `\\${cmd.cmd}`.padEnd(15);
- console.log(`${authIcon} ${cmdName} - ${cmd.desc}`);
- });
- }
- console.log("\n" + "=".repeat(50));
- console.log("[A] = Authority Required");
- console.log("Default Authorities: Diamond25, KiwiTest");
- console.log("Admins (ADMIN tag) have automatic authority");
- console.log("\nCONSOLE COMMANDS:");
- console.log(" unbanName('username') - Unban user from ban list");
- console.log("=".repeat(50) + "\n");
- };
- window.showColors = function () {
- console.log("\n====================================");
- console.log(" COLOR SYNTAX GUIDE (v7.13.3) ");
- console.log("====================================\n");
- console.log("Use: <start #HEXCOLOR>text<end>");
- console.log("Example: <start #ff0000>Hello<end> World\n");
- console.log("Available colors (HEX only):");
- console.log("-".repeat(50));
- console.log(" 0 - #000000 (black)");
- console.log(" 1 - #ffffff (white)");
- console.log(" 2 - #ff0000 (red)");
- console.log(" 3 - #00ff00 (green)");
- console.log(" 4 - #0000ff (blue)");
- console.log(" 5 - #ffff00 (yellow)");
- console.log(" 6 - #ff00ff (magenta)");
- console.log(" 7 - #00ffff (cyan)");
- console.log(" 8 - #808080 (gray)");
- console.log(" 9 - #ff8800 (orange)");
- console.log(" 10 - #8800ff (purple)");
- console.log(" 11 - #0088ff (light blue)");
- console.log(" 12 - #88ff00 (lime)");
- console.log(" 13 - #ff0088 (pink)");
- console.log(" 14 - #884400 (brown)");
- console.log(" 15 - #448800 (dark green)");
- console.log("=".repeat(50) + "\n");
- };
- window.botHelp = function () {
- console.log("====================================");
- console.log(` TextWall Bot v${BOT_CONFIG.version} - Help `);
- console.log("====================================");
- console.log(" PREFIX: \\ ");
- console.log(" ");
- console.log(" NEW IN v7.13.3: ");
- console.log(" - 10ms cleararea cooldown ");
- console.log(" - w.cursors detection for users ");
- console.log(" - Improved performance ");
- console.log(" ");
- console.log(" CONSOLE COMMANDS: ");
- console.log(" window.showCommands() - List cmds ");
- console.log(" window.showColors() - Color list");
- console.log(" window.sendMessage(msg) - System ");
- console.log(" window.unbanName(name) - Unban ");
- console.log(" window.stopBot() - Stop bot ");
- console.log(" window.restartBot() - Restart ");
- console.log(" window.botStatus() - Status ");
- console.log(" window.botHelp() - This help ");
- console.log("====================================");
- };
- window.botHelp();
- })();
Advertisement