A utility bot for anarchy minecraft servers with more than 100 commands, a database size of 50GB saving player data for more than 1.5 million Minecraft players and over 100 million messages.
I also monetized and sold $20 usage rights to over 15 different server owners.
Closed-source. Source code available for review upon request.
- Engineering Challenges
- Migration History
- Key Features
- User Commands
- Admin Commands/Tools/Configuration
graph TD
%% --- Section 1: UUID Caching ---
Bot[UUID Parsing] -->|1. Resolve User| Check{In Cache?}
Check -->|Yes| DB[(SQLite DB)]
Check -->|No / Stale| API[Mojang API]
API -->|2. Backfill Data| DB
DB -->|3. Return UUID| Bot
%% --- Section 2: Message Grouping ---
subgraph "Message Grouping/Queuing"
Msg1[Chat 1] & Msg2[Chat 2] & Msg3[Chat 3] --> Aggregator[Grouper]
end
Aggregator -->|Single Embed Count <= 10| Batch[Add to queue]
Batch -->|Wait 1000ms/embed| Discord[Discord API]
%% --- Section 3: Smart Server Pinger ---
subgraph "Connection Logic (Smart Pinger)"
Disconnected([Disconnected]) --> Timer[/Wait 3s/]
Timer --> Ping[Ping Packet]
Ping --> Status{Online & Players > 0?}
Status --No--> Timer
Status --Yes--> Join[Initiate Join]
end
Benchmark Results (20M Rows Active Dataset):
- Legacy Search (
LIKE): 5.599s (Thread Blocking) - Optimized Search (
FTS5): 0.010s (Instant)
Query Latency Comparison:
Legacy (LIKE): |==================================================| 5600ms
FTS5 (Match): | | 10ms
My messages were constantly getting blocked for being too similar so I added some code to check if a message was sent by the server after 2 seconds, and if it wasn't, the message is automatically resent with extra characters at the end.
I wanted to avoid hammering the Mojang API, so I added a UUID caching system. Usernames are locked for 37 days following a name change, so I set my limit to 35 days. UUIDs are stale after 35 days and will automatically be regrabbed upon request. This resulted in much fewer api requests as I was essentially the API.
Same concept of the message queuer but for discord. I added the bot to a server with nearly 30K players all chatting at the same time and there was around 10 messages every second. The discord rate limit is 4/s with 10 embeds per group. So I created the grouper and queuer which brought my limit from 4 msgs/s up to 40 msgs/s
Originally the bot was just sending out messages whenever players sent commands, but sometimes multiple players want to run commands at once, so this feature automatically queues up messages so the bot is never limited by the antispam.
I wanted to avoid hammering the Mojang Auth API which logged in my account everytime I tried to connect to a server. Instead of logging in, I just added a pinger which detects exactly when a server comes online and if theres more than 0 players, so I can instantly join.
All migration scripts have been archived and can be found in /migrationscripts
I was trying to scrape 2b2t.vc for historical playerdata to fill in the missing gaps, and had to deal with rate limits. Instead of a static 10 second cooldown, I added a feature that automatically adjusted the cooldown to get the max number of requests without getting errored. I also added a feature to automatically cut new players (that haven't been checked yet) to the front of the queue so data was as accurate as possible without having to wait 2 months for all data to be scraped.
graph LR
subgraph "Historical Data"
New[Recently Joined Players] -->|High Priority| PQueue[("Scrape Queue")]
Old[Inactive Players] -->|Low Priority| PQueue
end
PQueue -->|Pop Next Item| Worker[Scraper Worker]
Worker -->|Request| Site[2b2t.vc]
Site -->|Response| Check{Status Code?}
%% Success Path
Check -->|200 OK| Success[Process Data]
Success -->|Save| DB[(Database)]
Success -->|"Decrease Delay (-150ms)"| AdjustDelay[Throttler Config]
%% Failure Path
Check -->|429 Rate Limit| Fail[Backoff]
Fail -->|"Increase Delay (+500ms)"| AdjustDelay
Fail -->|Re-queue Item| PQueue
AdjustDelay -.->|Apply Cooldown| Worker
FTS-5 is essentially a copy of the messages table and takes up a ton of space. I realized there's a lot of useless spam on these servers and added a command to delete all rows containing certain phrases like discord links. This cut the database size in half.
I wanted to add a !clout command which shows how many times a phrase has been said in chat, normally this SQL query takes 10+ seconds to run as it has to go through millions of messages, but I added FTS-5 support which makes it incredibly efficient to search through text. With 20 million rows, the legacy LIKE operator took 5600ms, while FTS5 match took only 10ms.
I had some missing data that was never saved which I was able to grab from the logs I kept going back to 2021. I was able to add new commands (like !joins to show how many times a player joined) and backfill the data from the logs. I also saved all death messages going back to 2021 so I could add commands like !lastdeath. I was also able to fill in missing data caused by a bug years ago that didn't save join dates for a few months.
For my messages table I was using an array of messages converted into a string for each player which wasn't ideal. I converted everything into per row and later added FTS-5 support to make searches instantaneous.
Originally, the bot was using JSON files saved for each individual player. This is a terrible way of storing data with files randomly corrupting, and I even ended up reaching the Linux INode limit. (df -i) Once that happened I immediately got to work and started migrating everything to an SQLite database which is much more efficient and allows for commands that would never be possible with a bunch of JSON files.
Back when I first created the bot, one of the very first migrations I had to do was converting the format of the files.
The bot has full support in discord for cross chatting and running commands!
The bot uses sqlite3 to store all kinds of player statistics and messages.
The bot will queue up messages so all messages can go through and the bot won't get kicked for spam.
The bot automatically groups up messages (up to 10 embeds per message) to avoid getting rate limited by discord with lots of chat messages
The bot will automatically retry messages that fail to send after a few seconds.
The bot will automatically save kill and death messages without requiring a regex statement. This works by checking for usernames in the message. Use OppositeDeathMessages if the killer comes first
The bot includes an advanced configurable regex system for custom chat regexes if the default doesn't suit your needs.
The bot will automatically ping the server every 3 secs before joining to make sure it's online, has more than 0 players online in case the main server is down, and avoids constant logins.
Never miss a message with a full logging system. The bot will automatically log messages and join/leave msgs and automatically compress log files to save space.
The bot will automatically accept TPA requests.
When enabled the bot will automatically run /realname USERNAME for any nicknamed players.
UUIDs are cached to a database and recached after 35 days to avoid hammering the Mojang API (Minecraft usernames are locked for 37 days before they can be taken)
All players have their own mailbox and other players are able to send them messages while they are offline so they can recieve it once they go back online.
Find out how many bedrock players have joined. Check how many times someone has joined or left (extracted from logs going back to 2021) Find out how many times a word/message has been said on the server!!! See your first death message (Death messages have been extracted from logs and now go back to 2021!!) See your first kill message (Death messages have been extracted from logs and now go back to 2021!!) See your last death message (Death messages have been extracted from logs and now go back to 2021!!) See your last kill message (Death messages have been extracted from logs and now go back to 2021!!) See a random death message (Death messages have been extracted from logs and now go back to 2021!!) See a random kill message (Death messages have been extracted from logs and now go back to 2021!!)
Download all of you or someone elses data and messages! Added nolife - now possible to change number Added nolife - Players with the highest stats that are currently online Get a random message someone has said! Now a phrase can be added! Shows amount of new players that joined before a certain time/date. Find out how much of your life was wasted playing the server, starting from firstjoin. It uses playtime divided by total time since first join. Also tells you the average time per day wasted. Command also useful for seeing moobots lifetime uptime. First message the bot has saved from player Last message the bot has saved from player Last time the bot has seen someone online. Also tells you how long someone has been online if they are logged in. (inaccurate if bot has disconnected while they were online) First time the bot has seen someone online. - NOTE: Any firstseen times after July 10th, 2021, and before December 21st, 2021 have not been saved, and will show the most recent seen time. Get you or someone elses playtime. Works on nearly all servers, it checks for usernames in messages Get total messages the bot has saved from a player. (Counting all messages is not supported due to lag) Save a message to be played back later with !playmsg Play a message you saved from !savemsg Tell the bot who you are See who people are Find a minecraft player's uuid (if server is cracked, will only show name)
Total number of players and a list of current players online. In game, it shows the total amount of players that the bot has saved data for. Get players with lowest jitter. Get players with highest jitter. Get ping of yourself or someone else. Now shows jitter! Get player with lowest ping. Get player with highest ping.
Save a message for someone and moobot will send them the message once they are online. NOW SUPPORTS UP TO 6 MESSAGES/2 PER AUTHOR! prevent someone from !offlinemsging you. allow someone to !offlinemsg you.
Mount any boat or minecart within 5 blocks of the bot. Warning: Anyone can find the coords of the bot, don't bring it to your base!!! Dismount from the boat or minecart. Time in ticks, and NOW tells you how long until you can sleep. Tells you if you can sleep or not and NOW tells you how long until you can sleep. Get all players and coordinates in radius of bot. Coords of the bot Kill the bot. Check tps of server - NOT ACCURATE (THIS IS APPROXIMATE. IT PROBABLY ISN'T THE RIGHT NUMBER.) Get discord invite for chat bridge Health and food level of bot Uptime of bot
Use !grok reset to reset - Ask Grok a prompt and respond with the bot Use !gemini reset to reset - Ask Google Gemini a prompt and respond with the bot! Now supports message history! Use !gpt reset to reset - Ask chatgpt a prompt and respond with the bot Now supports message history! Use !deepseek reset to reset - Ask deepseek (chinese gpt) a prompt and respond with the bot Get current or historical price of stock with flexible date and time option. Get a dad joke. Get query from WolframAlpha Get title of any website Check if a website is down Get top urban dictionary definition 2b2t queue Want to check 2b2t queue stats? https://queue.moomoo.me/ Check how many players are online on a minecraft server. find location and isp of an ip or domain.
Play a game of blackjack! Use !blackjack hit/stand Spin a roulette wheel! Curse a player! Ban a player! Kick a player! Mute a player! Report someone to server moderators for breaking the rules. Rules of the server NO YES dupe an item! get someones coords! 100% working 2020 Yes or no Roll a die Leak coords Change your gamemode infect someone. ask give someone something teleport! go back Op yourself or someone else Request teleport to someone Request someone to teleport to you Accept a teleport request Deny a teleport request Set your home go to your home start a vote to execute someone, use /kill yes or /kill no to vote. bless someone. You are a good person. recieve a kit!
Permanently ignore a phrase in chat, saved to blockedphrases.json
Permanently ignore a players death messages in chat, saved to blockeddeaths.json
Run process.exit and restart bot
Hide death messages and join/leave messages
Permanently ignore a phrase in chat, saved to blockedphrases.json
Permanently ignore a players death messages in chat, saved to blockeddeaths.json
Add a message to the queue, so you aren't hitting antispam limits.
Enable client side connection messages if server doesn't have them.
Delete all messages associated with certain phrases. For example deleting discord advertisements can save tons of storage.
Run a backup of all moobot instances, it vacuums into a new file and the rsyncs it to another server.
Run a cold backup of all moobot instances; Meaning data is dumped into txt files and then compressed to save storage, often 80% less.
MooBot automatically compresses logs on start, but this is if you need to manually compress logs.
I have 20 different instances, so this makes it easy to copy new code to all 20 at once.
Remove a file from all instances.
This file updates packages for all instances.
Vacuum all databases
Server ip
Server port
Server version
Command prefix (!)
Enable if server is cracked to not use uuids
Login for cracked server
Discord command prefix
Array of all chat channels, make sure you also fill guilds
Array of all guilds, make sure both chatchannels and guilds are in the same index [0,1] etc
If you want to give players more prefix options
Not generally needed as users can run commands in chat channels.
Disable any commands you don't want players to be able to use
Specify owner id for access to some special commands.
Disable the default anti-afk system
Enable more prefixes from moreprefixes
How often to make announcements from messages.json
Command cooldown per player
Enable a global cooldown, not recommended since you can queue up messages instead
How long to wait in between commands from all players
Cooldown time for whispers
Remove the default join messages
Walk forward to bypass antispam
Constantly walk in a circle - not recommended as anticheats don't like it
Constantly kill your player, may help bypass antiafks
How often to kill your player
Death command /kill
May help get you unstuck
Max characters that can be sent in a message, any more will get cut off
Use the default regex system for mineflayer
Experimental
Experimental
Useful for servers with janky chat plugins that don't use the typical format.
Custom whisper regex
Hide Mineflayer errors
Automatically restart the bot when it finds a message in chat
Whether to enable a command upon login
Specified command to run upon login
Another command if needed
How long to wait before sending login command
Disable the server pinger, not recommended as the bot will constantly be hammering mojang auth
How often to ping server if its down
Useful if server is at full capacity with no queue and you need to bruteforce your way in
Maximum players before bot will not connect
Whether to allow the bot to join no matter how few players are online
Don't allow the bot to join if there's no one online, will automatically ping and join once it detects someone.
Whether the bot will only whisper command responses, useful to avoid getting muted.
Command used for whispering, default /w. If your server uses a different command, specify here.
Message to send when receiving a tpa request to accept.
Enable a message that gets triggered from a regex
Command ran after recieving a specific message.
Enable chat reporting, note you may be reported. Recommend to only use the bot on servers that disable it.
Not recommended - Instead of queueing messages, the bot will send them all at once
How long in between messages queued.
How many messages can be queued up
Not recommended. Whether to disable the discord message grouping queue.
How often in between discord embeds, which group up to 10 messages each.
Specific phrases to block
Whether to automatically check players for nicknames if their name doesn't show up in player list.
Max messages per mailbox
How many messages can be sent to one player from someone
Whether to reverse death messages based on server.
Automatically append random string to the end if message isn't sent after 2 seconds
Check Mojang api for uuid if they can't be found in the player list
Disable checking to make sure the bot is still on the server and not in limbo
2b2t options
Regex strings. tpa1, tpa2, cracked_login_pattern, chat, whisper, leavemessage, triggermessage





