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.9",
- 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,
- };
- 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,
- };
- 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", "colorid", "addauth", "removeauth", "disablehs", "echoauth", "csay", "ban", "unban", "banid", "unbanid", "type"];
- const INVISIBLE_CHAR = "\u200B";
- 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: "calculate", desc: "Calculate p1^p2", auth: false },
- ],
- 2: [
- { 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 },
- { cmd: "count", desc: "Count from 1 to n with cooldown", auth: false },
- ],
- 3: [
- { 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 },
- { cmd: "page", desc: "Show detailed page info", auth: false },
- { cmd: "members", desc: "List wall members", auth: false },
- ],
- 4: [
- { cmd: "walls", desc: "List available subwalls", auth: false },
- { cmd: "authlist", desc: "Show authorized users", auth: false },
- { cmd: "to", desc: "Teleport bot to X Y (Authority)", auth: true },
- { cmd: "colorid", desc: "Change bot color (Authority)", auth: true },
- { cmd: "csay", desc: "Say colored text (Authority)", auth: true },
- ],
- 5: [
- { 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 },
- ],
- 6: [
- { 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 },
- ],
- };
- 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("===================================");
- }
- 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;
- 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;
- }
- 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}`);
- if (this.config.authorityEchoEnabled && !message.startsWith(this.config.prefix) && !message.includes("[AUTHORITY]") && 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;
- const cursorInfo = { name: data.n || "", location: data.l || [0, 0], color: data.c || 0 };
- this.state.cursors.set(data.id, cursorInfo);
- if (data.n) {
- this.state.userPositions.set(data.n, data.l || [0, 0]);
- this.state.userIds.set(data.n, data.id);
- }
- if (data.n === this.config.username && data.l) {
- this.config.position.x = data.l[0];
- this.config.position.y = data.l[1];
- }
- }
- 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(),
- 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),
- status: () => this.cmdStatus(),
- pos: () => this.cmdPosition(args, sender),
- page: () => this.cmdPage(args),
- members: () => this.cmdMembers(),
- walls: () => this.cmdWalls(),
- authlist: () => this.cmdAuthList(),
- to: () => (hasAuth ? this.cmdTeleport(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")),
- 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")),
- };
- 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);
- });
- }
- 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"}`,
- `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})`);
- }
- 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"}`);
- }
- 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;
- }
- 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.stopBot = async function () {
- console.log("Initiating shutdown sequence...");
- bot.state.isShuttingDown = true;
- bot.state.isTyping = 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,
- "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",
- "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("=".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.9: ");
- console.log(" - \\help now has 0.7s cooldown ");
- console.log(" - \\thelp uses step 1 for typing ");
- console.log(" - \\page command updated ");
- console.log(" ");
- console.log(" CONSOLE COMMANDS: ");
- console.log(" window.showCommands() - List cmds ");
- console.log(" window.sendMessage(msg) - System ");
- 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