Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // --- BOT METADATA AND START TIME ---
- const START_TIME = Date.now(); // Record the moment the script starts running
- const BOT_VERSION = "0.1";
- const CREATOR_NAME = "Coinbot Developer";
- // --- GLOBAL EVENT STATE ---
- const EVENT_INTERVAL = 600000; // 10 minutes in milliseconds
- const EVENT_DURATION = 300000; // 5 minutes in milliseconds
- let eventActive = false;
- let eventAmount = 0;
- let eventTimeout = null;
- let eventStartTime = 0; // Track the exact moment the event started
- let lastEventStartTime = START_TIME; // Track the last time the interval successfully triggered (INITIALIZED TO BOT START TIME)
- // Function to handle the end of the event window if nobody collects the coins
- function endEventTimeout() {
- eventActive = false;
- eventAmount = 0;
- eventTimeout = null;
- eventStartTime = 0; // Reset start time
- w.chat.send("Nobody got the coins in time.");
- }
- // Function to trigger the event manually (called from w.on("msg"))
- function triggerEvent() {
- eventActive = true;
- eventAmount = Math.floor(Math.random() * 301) + 100; // 100 to 400
- lastEventStartTime = Date.now(); // Record the current time as the new interval start time
- eventStartTime = Date.now(); // Record the exact event start time
- w.chat.send(
- `${eventAmount} coins fell from the sky, !collect them before anybody else.`
- );
- // Set a timer for the event to expire after 5 minutes
- eventTimeout = setTimeout(endEventTimeout, EVENT_DURATION);
- }
- // Welcome message (fixed event name)
- w.on("join", () => {
- w.chat.send("Coinbot Version 0.1 - Type !help for commands");
- });
- // Data storage
- const balances = {};
- // Global statistics object
- const globalStats = {
- totalSearches: 0,
- totalBets: 0,
- betsWon: 0,
- betsLost: 0,
- totalFlips: 0,
- flipsWon: 0,
- flipsLost: 0,
- coinsGiven: 0,
- coinsReceived: 0,
- coinsTransferred: 0
- };
- const searchCooldown = {};
- const coinflipCooldown = {};
- // Message handler
- w.on("msg", (data) => {
- const nick = data.nick;
- const now = Date.now();
- // --- EVENT TRIGGER CHECK (Runs on every message regardless of content) ---
- // If event is not active AND the required interval has passed, trigger the event
- if (!eventActive && (now - lastEventStartTime >= EVENT_INTERVAL)) {
- triggerEvent();
- }
- // -------------------------------------------------------------------------
- // --- !collect: Only processes collection, cannot trigger the event ---
- if (data.msg.toLowerCase() === "!collect") {
- if (eventActive) {
- // 1. Give coins to the first user
- if (!balances[nick]) balances[nick] = 0;
- balances[nick] += eventAmount;
- // 2. Clear timeout and set event inactive
- clearTimeout(eventTimeout);
- eventActive = false;
- eventStartTime = 0; // Reset start time after collection
- // 3. Update global stats
- globalStats.coinsGiven += eventAmount;
- // 4. Send success message
- w.chat.send(
- `${nick} was the fastest and successfully collected ${eventAmount} coins! New balance: ${balances[nick]}.`
- );
- // Stop processing after collection
- return;
- } else {
- // Event is not active
- w.chat.send(`${nick}, there are no fallen coins to collect right now.`);
- return;
- }
- }
- // Exit if message does not start with '!'
- if (!data.msg.startsWith("!")) {
- return;
- }
- const args = data.msg.slice(1).trim().split(" ");
- const command = args[0];
- // --- !help ---
- if (command === "help") {
- w.chat.send(
- `${nick}, Commands: !help, !search, !balance, !bet <amount>, !coinflip <h/t> <amount>, !stats, !leaderboard, !give <nick> <amount>, !info, !uptime, !collect`
- );
- return;
- }
- // --- !info ---
- if (command === "info") {
- let eventStatus = '';
- const formatTime = (ms) => {
- const totalSeconds = Math.ceil(Math.max(0, ms) / 1000);
- const minutes = Math.floor(totalSeconds / 60);
- const seconds = totalSeconds % 60;
- return `${minutes}m ${seconds}s`;
- };
- if (eventActive) {
- // Calculate remaining time using the known start time and duration
- const timeElapsed = now - eventStartTime;
- const remainingTimeMs = EVENT_DURATION - timeElapsed;
- const timeString = formatTime(remainingTimeMs);
- eventStatus = ` | Coins Event: ACTIVE (Ends in ${timeString})`;
- } else {
- // FIX: Calculate time until next event using modulo for full cycle accuracy
- const timeElapsedSinceLastStart = now - lastEventStartTime;
- // The remaining time is the interval minus the time passed, modulo the interval.
- // Adding EVENT_INTERVAL ensures a positive number before the modulo.
- const timeToNextEventMs = (EVENT_INTERVAL + lastEventStartTime - now) % EVENT_INTERVAL;
- const timeString = formatTime(timeToNextEventMs);
- eventStatus = ` | Next Coins Event in: ${timeString}`;
- }
- w.chat.send(
- `Coinbot Info: Version ${BOT_VERSION} | Creator: ${CREATOR_NAME}${eventStatus}`
- );
- return;
- }
- // --- !uptime ---
- if (command === "uptime") {
- const uptimeMs = now - START_TIME;
- // Calculate time components (seconds, minutes, hours, days)
- const seconds = Math.floor(uptimeMs / 1000);
- const minutes = Math.floor(seconds / 60);
- const hours = Math.floor(minutes / 60);
- const days = Math.floor(hours / 24);
- // Calculate remaining time for display
- const displayHours = hours % 24;
- const displayMinutes = minutes % 60;
- const displaySeconds = seconds % 60;
- let uptimeString = '';
- if (days > 0) uptimeString += `${days}d `;
- if (hours > 0) uptimeString += `${displayHours}h `;
- if (minutes > 0) uptimeString += `${displayMinutes}m `;
- uptimeString += `${displaySeconds}s`; // Always show seconds
- w.chat.send(
- `The bot has been active for: ${uptimeString.trim()}`
- );
- return;
- }
- // --- !search ---
- if (command === "search") {
- if (!searchCooldown[nick] || now - searchCooldown[nick] >= 60000) {
- const found = Math.floor(Math.random() * 25) + 1;
- if (!balances[nick]) balances[nick] = 0;
- balances[nick] += found;
- searchCooldown[nick] = now;
- // Update Global Stats for !search
- globalStats.totalSearches++;
- globalStats.coinsGiven += found;
- w.chat.send(
- `${nick}, searched the area and found ${found} coins!`
- );
- } else {
- const wait = Math.ceil((60000 - (now - searchCooldown[nick])) / 1000);
- w.chat.send(`${nick}, wait ${wait}s before searching again.`);
- }
- return;
- }
- // --- !balance ---
- if (command === "balance") {
- const bal = balances[nick] || 0;
- w.chat.send(`${nick}, you currently have ${bal} coins.`);
- return;
- }
- // --- !bet ---
- if (command === "bet") {
- const amount = parseInt(args[1]);
- if (isNaN(amount) || amount <= 0) {
- w.chat.send(`${nick}, usage: !bet <amount> (must be a positive number)`);
- return;
- }
- if (!balances[nick] || balances[nick] < amount) {
- w.chat.send(`${nick}, you don't have enough coins to bet ${amount}.`);
- return;
- }
- // Increment total bets before processing win/loss
- globalStats.totalBets++;
- // 50% win/lose
- const win = Math.random() < 0.5;
- if (win) {
- // WIN → user gains the amount they bet
- balances[nick] += amount;
- // Update Global Stats for bet win
- globalStats.betsWon++;
- globalStats.coinsGiven += amount;
- w.chat.send(
- `${nick}, you won the bet! You gained ${amount} coins! Your new balance is ${balances[nick]}.`
- );
- } else {
- // LOSS → user loses the amount they bet
- balances[nick] -= amount;
- // Update Global Stats for bet loss
- globalStats.betsLost++;
- globalStats.coinsReceived += amount;
- w.chat.send(
- `${nick}, You lost ${amount} coins and now have ${balances[nick]} coins.`
- );
- }
- return;
- }
- // --- !coinflip ---
- if (command === "coinflip") {
- const COOLDOWN_TIME = 300000; // 5 minutes in milliseconds
- // 1. Check Cooldown (This correctly calculates and displays the remaining time)
- if (coinflipCooldown[nick] && now - coinflipCooldown[nick] < COOLDOWN_TIME) {
- const wait = Math.ceil((COOLDOWN_TIME - (now - coinflipCooldown[nick])) / 1000);
- w.chat.send(`${nick}, wait ${wait}s before flipping the coin again.`);
- return;
- }
- const userGuess = args[1] ? args[1].toLowerCase() : null;
- const amount = parseInt(args[2]);
- const validGuesses = ["heads", "h", "tails", "t"];
- // Validation checks
- if (!userGuess || !amount || isNaN(amount) || amount <= 0 || !validGuesses.includes(userGuess)) {
- w.chat.send(`${nick}, usage: !coinflip <heads/tails or h/t> <amount>`);
- return;
- }
- if (!balances[nick] || balances[nick] < amount) {
- w.chat.send(`${nick}, you don't have enough coins to bet ${amount}.`);
- return;
- }
- // Determine the flip result
- const flipResult = Math.random() < 0.5 ? "heads" : "tails";
- const isWin = (userGuess === "heads" || userGuess === "h") && flipResult === "heads" ||
- (userGuess === "tails" || userGuess === "t") && flipResult === "tails";
- // Set Cooldown
- coinflipCooldown[nick] = now;
- // Update global stats
- globalStats.totalFlips++;
- if (isWin) {
- // WIN: win 4x the amount bet
- const winnings = amount * 4;
- balances[nick] += winnings;
- globalStats.flipsWon++;
- globalStats.coinsGiven += winnings;
- w.chat.send(
- `${nick} flipped a ${flipResult}! You won ${winnings} coins! New balance: ${balances[nick]}.`
- );
- } else {
- // LOSS: lose the amount bet
- balances[nick] -= amount;
- globalStats.flipsLost++;
- globalStats.coinsReceived += amount;
- w.chat.send(
- `${nick} flipped a ${flipResult}! You lost ${amount} coins. New balance: ${balances[nick]}.`
- );
- }
- return;
- }
- // --- !stats ---
- if (command === "stats") {
- const totalCoins = Object.values(balances).reduce(
- (sum, balance) => sum + balance,
- 0
- );
- const userCount = Object.keys(balances).length;
- const betWinRate = globalStats.totalBets > 0
- ? ((globalStats.betsWon / globalStats.totalBets) * 100).toFixed(2)
- : 'N/A';
- const flipWinRate = globalStats.totalFlips > 0
- ? ((globalStats.flipsWon / globalStats.totalFlips) * 100).toFixed(2)
- : 'N/A';
- // Detailed Stats Output
- w.chat.send(
- `COIN STATS: ${userCount} users hold ${totalCoins} coins. | Searches: ${globalStats.totalSearches}. | Bets: ${globalStats.totalBets} (W:${globalStats.betsWon} / L:${globalStats.betsLost} | Rate: ${betWinRate}%). | Flips: ${globalStats.totalFlips} (W:${globalStats.flipsWon} / L:${globalStats.flipsLost} | Rate: ${flipWinRate}%). | Economy: Given: ${globalStats.coinsGiven} | Received: ${globalStats.coinsReceived} | Transferred: ${globalStats.coinsTransferred}`
- );
- return;
- }
- // --- !leaderboard ---
- if (command === "leaderboard") {
- // 1. Convert balances object into an array of [nick, balance] pairs
- const sortedUsers = Object.entries(balances)
- // 2. Sort the array from smallest (a[1]) to biggest (b[1]).
- .sort((a, b) => a[1] - b[1]);
- if (sortedUsers.length === 0) {
- w.chat.send(`${nick}, no users have collected any coins yet!`);
- return;
- }
- // 3. Format the output string
- const leaderboardText = sortedUsers
- .reverse()
- .map((user, index) => {
- const rank = index + 1;
- const userNick = user[0];
- const coinAmount = user[1];
- return `#${rank}: ${userNick} - ${coinAmount} coins`;
- })
- .join(" | ");
- w.chat.send(`Leaderboard: ${leaderboardText}`);
- return;
- }
- // --- !give ---
- if (command === "give") {
- const recipient = args[1];
- const amount = parseInt(args[2]);
- // Validation checks
- if (!recipient || isNaN(amount) || amount <= 0) {
- w.chat.send(`${nick}, usage: !give <recipient_nick> <amount>`);
- return;
- }
- if (nick === recipient) {
- w.chat.send(`${nick}, you cannot give coins to yourself.`);
- return;
- }
- if (!balances[nick] || balances[nick] < amount) {
- w.chat.send(`${nick}, you only have ${balances[nick] || 0} coins, which is not enough to give ${amount}.`);
- return;
- }
- // 1. Deduct from sender
- balances[nick] -= amount;
- // 2. Initialize recipient balance if necessary and add amount
- if (!balances[recipient]) {
- balances[recipient] = 0;
- }
- balances[recipient] += amount;
- // 3. Update Global Stats
- globalStats.coinsTransferred += amount;
- // 4. Send confirmation message
- w.chat.send(
- `${nick} gave ${amount} coins to ${recipient}! ` +
- `(${nick}: ${balances[nick]} coins | ${recipient}: ${balances[recipient]} coins)`
- );
- return;
- }
- });
Advertisement
Comments
-
Comment was deleted
-
- bro really tried reviving coinbot
Add Comment
Please, Sign In to add comment