Exemple #1
0
        // Main loop
        public static Task Start()
        {
            // Begin bot process in its own thread
            new Thread(delegate()
            {
                new RainBorg().RunBotAsync().GetAwaiter().GetResult();
            }).Start();

            // Begin timeout loop in its own thread
            new Thread(delegate()
            {
                UserTimeout();
            }).Start();

            // Get console commands
            string command = "";

            while (command.ToLower() != "exit")
            {
                // Get command
                command = Console.ReadLine();

                if (command.ToLower().StartsWith("dotip"))
                {
                    Waiting = waitTime;
                    Console.WriteLine("Tip sent.");
                }
                else if (command.ToLower().StartsWith("reset"))
                {
                    foreach (KeyValuePair <ulong, List <ulong> > Entry in UserPools)
                    {
                        Entry.Value.Clear();
                    }
                    Greylist.Clear();
                    Console.WriteLine("Pools reset.");
                }
                else if (command.ToLower().StartsWith("loglevel"))
                {
                    logLevel = int.Parse(command.Substring(command.IndexOf(' ')));
                    Config.Save();
                    Console.WriteLine("Log level changed.");
                }
                else if (command.ToLower().StartsWith("say"))
                {
                    foreach (ulong Channel in StatusChannel)
                    {
                        (_client.GetChannel(Channel) as SocketTextChannel).SendMessageAsync(command.Substring(command.IndexOf(' ')));
                    }
                    Console.WriteLine("Sent message.");
                }
                else if (command.ToLower().StartsWith("addoperator"))
                {
                    if (!Operators.ContainsKey(ulong.Parse(command.Substring(command.IndexOf(' ')))))
                    {
                        Operators.Add(ulong.Parse(command.Substring(command.IndexOf(' '))));
                    }
                    Console.WriteLine("Added operator.");
                }
                else if (command.ToLower().StartsWith("removeoperator"))
                {
                    if (Operators.ContainsKey(ulong.Parse(command.Substring(command.IndexOf(' ')))))
                    {
                        Operators.Remove(ulong.Parse(command.Substring(command.IndexOf(' '))));
                    }
                    Console.WriteLine("Removed operator.");
                }
                else if (command.ToLower().StartsWith("test"))
                {
                    Stats.Tip(DateTime.Now, 1, 1, 1000000);
                    Console.WriteLine("Added tip to database.");
                }
                else if (command.ToLower().StartsWith("restart"))
                {
                    Log("RainBorg", "Relaunching bot...");
                    Paused = true;
                    JObject Resuming = new JObject
                    {
                        ["userPools"]    = JToken.FromObject(UserPools),
                        ["greylist"]     = JToken.FromObject(Greylist),
                        ["userMessages"] = JToken.FromObject(UserMessages)
                    };
                    File.WriteAllText(resumeFile, Resuming.ToString());
                    Process.Start("RelaunchUtility.exe", "RainBorg.exe");
                    ConsoleEventCallback(2);
                    Environment.Exit(0);
                }
            }

            // Completed, exit bot
            return(Task.CompletedTask);
        }
Exemple #2
0
        // Megatip
        public static Task MegaTipAsync(decimal amount)
        {
            Log("RainBorg", "Megatip called");

            // Get balance
            tipBalance = GetBalance();

            // Check that tip amount is within bounds
            if (amount + (tipFee * UserPools.Keys.Count) > tipBalance && tipBalance >= 0)
            {
                Log("RainBorg", "Insufficient balance for megatip, need {0}", RainBorg.Format(tipBalance + (tipFee * UserPools.Keys.Count)));
                // Insufficient balance
                return(Task.CompletedTask);
            }

            // Get total user amount
            int TotalUsers = 0;

            foreach (List <ulong> List in UserPools.Values)
            {
                foreach (ulong User in List)
                {
                    TotalUsers++;
                }
            }

            // Set tip amount
            tipAmount = amount / TotalUsers;
            tipAmount = Floor(tipAmount);

            // Loop through user pools and add them to tip
            decimal  tipTotal = 0;
            DateTime tipTime  = DateTime.Now;

            foreach (ulong ChannelId in UserPools.Keys)
            {
                if (UserPools[ChannelId].Count > 0)
                {
                    string m = $"{RainBorg.tipPrefix}tip " + RainBorg.Format(tipAmount) + " ";
                    for (int i = 0; i < UserPools[ChannelId].Count; i++)
                    {
                        try
                        {
                            // Make sure the message size is below the max discord message size
                            if ((m + _client.GetUser(UserPools[ChannelId][i]).Mention + " ").Length <= 2000)
                            {
                                // Add a username mention
                                m += _client.GetUser(UserPools[ChannelId][i]).Mention + " ";

                                // Add to tip total
                                tipTotal += tipAmount;

                                // Add tip to stats
                                try
                                {
                                    Stats.Tip(tipTime, ChannelId, UserPools[ChannelId][i], tipAmount);
                                }
                                catch (Exception e)
                                {
                                    Console.WriteLine("Error adding tip to stat sheet: " + e.Message);
                                }
                            }
                        }
                        catch { }
                    }

                    // Send tip message to channel
                    (_client.GetChannel(ChannelId) as SocketTextChannel).SendMessageAsync(m);

                    // Clear list
                    if (flushPools)
                    {
                        UserPools[ChannelId].Clear();
                    }
                }
            }

            // Clear greylist
            Greylist.Clear();

            // Begin building status message
            var builder = new EmbedBuilder();

            builder.WithTitle("TUT TUT");
            builder.ImageUrl    = statusImages[new Random().Next(0, statusImages.Count)];
            builder.Description = "Wow, a megatip! " + RainBorg.Format(tipTotal) + " " + currencyName + " just rained on " + TotalUsers + " chatty user";
            if (TotalUsers > 1)
            {
                builder.Description += "s";
            }
            builder.Description += ", they ";
            if (TotalUsers > 1)
            {
                builder.Description += "each ";
            }
            builder.Description += "got " + RainBorg.Format(tipAmount) + " " + currencyName + "!";
            builder.WithColor(Color.Green);

            // Send status message to all status channels
            foreach (ulong u in StatusChannel)
            {
                (_client.GetChannel(u) as SocketTextChannel).SendMessageAsync("", false, builder);
            }

            // Completed
            return(Task.CompletedTask);
        }
Exemple #3
0
        // Tip loop
        public static async Task DoTipAsync()
        {
Start:
            // If client is connected
            if (_client.ConnectionState == ConnectionState.Connected)
            {
                // Create a randomizer
                Random r = new Random();

                try
                {
                    // Get balance
                    tipBalance = GetBalance();

                    // Check tip balance against minimum tip
                    if (tipBalance - tipFee < tipMin && tipBalance >= 0)
                    {
                        // Log low balance message
                        Log("Tipper", "Balance does not meet minimum tip threshold.");

                        // Check if bot should show a donation message
                        if (ShowDonation)
                        {
                            // Create message
                            var builder = new EmbedBuilder();
                            builder.ImageUrl = donationImages[r.Next(0, donationImages.Count)];
                            builder.WithTitle("UH OH");
                            builder.WithColor(Color.Green);
                            builder.Description = String.Format(tipBalanceError, RainBorg.Format(tipMin + tipFee - tipBalance));

                            // Cast message to all status channels
                            foreach (ulong u in StatusChannel)
                            {
                                await(_client.GetChannel(u) as SocketTextChannel).SendMessageAsync("", false, builder);
                            }

                            // Reset donation message
                            ShowDonation = false;
                        }
                    }

                    // Grab eligible channels
                    List <ulong> Channels = EligibleChannels();

                    // No eligible channels
                    if (Channels.Count < 1)
                    {
                        Log("Tipper", "No eligible tipping channels.");
                    }
                    else
                    {
                        // Roll for a megatip
                        if (r.NextDouble() * 100 <= megaTipChance)
                        {
                            // Do megatip
                            await MegaTipAsync(megaTipAmount);
                        }
                        else
                        {
                            // Roll until an eligible channel is chosen
                            ulong ChannelId = 0;
                            while (!Channels.Contains(ChannelId))
                            {
                                ChannelId = ChannelWeight[r.Next(0, ChannelWeight.Count)];
                            }

                            // Add developer donation
                            try
                            {
                                if (developerDonations && (_client.GetChannel(ChannelId) as SocketGuildChannel).GetUser(DID) != null)
                                {
                                    if (!UserPools[ChannelId].Contains(DID))
                                    {
                                        UserPools[ChannelId].Add(DID);
                                    }
                                }
                            }
                            catch { }

                            // Check user count
                            if (tipBalance - tipFee < tipMin && UserPools[ChannelId].Count < userMin)
                            {
                                Log("Tipper", "Not enough users to meet threshold, will try again next tipping cycle.");
                            }

                            // Do a tip cycle
                            else if (tipBalance - tipFee >= tipMin && UserPools[ChannelId].Count >= userMin)
                            {
                                // Set tip amount
                                if (tipBalance - tipFee > tipMax)
                                {
                                    tipAmount = tipMax / UserPools[ChannelId].Count;
                                }
                                else
                                {
                                    tipAmount = (tipBalance - tipFee) / UserPools[ChannelId].Count;
                                }

                                // Round tip amount down
                                tipAmount = Floor(tipAmount);

                                // Begin creating tip message
                                int      userCount = 0;
                                decimal  tipTotal  = 0;
                                DateTime tipTime   = DateTime.Now;
                                Log("Tipper", "Sending tip of {0} to {1} users in channel #{2}", RainBorg.Format(tipAmount),
                                    UserPools[ChannelId].Count, _client.GetChannel(ChannelId));
                                string m = $"{RainBorg.tipPrefix}tip " + RainBorg.Format(tipAmount) + " ";

                                // Loop through user pool and add them to tip
                                for (int i = 0; i < UserPools[ChannelId].Count; i++)
                                {
                                    try
                                    {
                                        // Make sure the message size is below the max discord message size
                                        if ((m + _client.GetUser(UserPools[ChannelId][i]).Mention + " ").Length <= 2000)
                                        {
                                            // Add a username mention
                                            m += _client.GetUser(UserPools[ChannelId][i]).Mention + " ";

                                            // Increment user count
                                            userCount++;

                                            // Add to tip total
                                            tipTotal += tipAmount;

                                            // Add tip to stats
                                            try
                                            {
                                                await Stats.Tip(tipTime, ChannelId, UserPools[ChannelId][i], tipAmount);
                                            }
                                            catch (Exception e)
                                            {
                                                Console.WriteLine("Error adding tip to stat sheet: " + e.Message);
                                            }
                                        }
                                    }
                                    catch { }
                                }

                                // Send tip message to channel
                                await(_client.GetChannel(ChannelId) as SocketTextChannel).SendMessageAsync(m);

                                // Begin building status message
                                var builder = new EmbedBuilder();
                                builder.WithTitle("TUT TUT");
                                builder.ImageUrl    = statusImages[r.Next(0, statusImages.Count)];
                                builder.Description = "Huzzah, " + RainBorg.Format(tipTotal) + " " + currencyName + " just rained on " + userCount +
                                                      " chatty user";
                                if (UserPools[ChannelId].Count > 1)
                                {
                                    builder.Description += "s";
                                }
                                builder.Description += " in #" + _client.GetChannel(ChannelId) + ", they ";
                                if (UserPools[ChannelId].Count > 1)
                                {
                                    builder.Description += "each ";
                                }
                                builder.Description += "got " + RainBorg.Format(tipAmount) + " " + currencyName + "!";
                                builder.WithColor(Color.Green);

                                // Send status message to all status channels
                                foreach (ulong u in StatusChannel)
                                {
                                    await(_client.GetChannel(u) as SocketTextChannel).SendMessageAsync("", false, builder);
                                }

                                // Clear user pool
                                if (flushPools)
                                {
                                    UserPools[ChannelId].Clear();
                                }
                                Greylist.Clear();
                                ShowDonation = true;
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine("Error sending tip: " + e);
                }

                // Calculate wait time until next tip
                if (waitMin < waitMax)
                {
                    waitTime = r.Next(waitMin, waitMax);
                }
                else
                {
                    waitTime = 10 * 60 * 1000;
                }
                waitNext = DateTime.Now.AddSeconds(waitTime).ToString("HH:mm:ss") + " " + _timezone;
                Log("Tipper", "Next tip in {0} seconds({1})", waitTime, waitNext);

                // Wait for X seconds
                Waiting = 0;
                while (Waiting < waitTime || Paused)
                {
                    await Task.Delay(1000);

                    Waiting += 1;
                }
            }

            // Restart tip loop
            goto Start;
        }
Exemple #4
0
        // Tip loop
        public static async Task DoTipAsync()
        {
Start:
            // If client is connected
            if (_client.ConnectionState == ConnectionState.Connected)
            {
                // Create a randomizer
                Random r = new Random();

                try
                {
                    // Get balance
                    using (WebClient client = new WebClient())
                    {
                        string  dl = client.DownloadString(Constants.BalanceURL);
                        JObject j  = JObject.Parse(dl);
                        tipBalance = (double)j["balance"] / 100;
                    }

                    // Check tip balance against minimum tip
                    if (tipBalance - tipFee < tipMin)
                    {
                        // Log low balance message
                        Console.WriteLine("{0} {1}      {2}", DateTime.Now.ToString("HH:mm:ss"), "Tipper",
                                          "Balance does not meet minimum tip threshold.");

                        // Check if bot should show a donation message
                        if (ShowDonation)
                        {
                            // Create message
                            var builder = new EmbedBuilder();
                            builder.WithTitle("UH OH");
                            builder.WithColor(Color.Green);
                            builder.Description = String.Format(tipBalanceError, String.Format("{0:n}", tipMin + tipFee - tipBalance));

                            // Cast message to all status channels
                            foreach (ulong u in StatusChannel)
                            {
                                await(_client.GetChannel(u) as SocketTextChannel).SendMessageAsync("", false, builder);
                            }

                            // Reset donation message
                            ShowDonation = false;
                        }
                    }

                    // Grab eligible channels
                    List <ulong> Channels = EligibleChannels();

                    // No eligible channels
                    if (Channels.Count < 1)
                    {
                        Console.WriteLine("{0} {1}      {2}", DateTime.Now.ToString("HH:mm:ss"), "Tipper",
                                          "No eligible tipping channels.");
                    }
                    else
                    {
                        // Roll until an eligible channel is chosen
                        ulong ChannelId = 0;
                        while (!Channels.Contains(ChannelId))
                        {
                            ChannelId = ChannelWeight[r.Next(0, ChannelWeight.Count)];
                        }

                        // Check user count
                        if (tipBalance - tipFee < tipMin && UserPools[ChannelId].Count < userMin)
                        {
                            Console.WriteLine("{0} {1}      {2}", DateTime.Now.ToString("HH:mm:ss"), "Tipper",
                                              "Not enough users to meet threshold, will try again next tipping cycle.");
                        }

                        // Do a tip cycle
                        else if (tipBalance - tipFee >= tipMin && UserPools[ChannelId].Count >= userMin)
                        {
                            // Set tip amount
                            if (tipBalance - tipFee > tipMax)
                            {
                                tipAmount = tipMax / UserPools[ChannelId].Count;
                            }
                            else
                            {
                                tipAmount = (tipBalance - tipFee) / UserPools[ChannelId].Count;
                            }

                            // Round tip amount down
                            tipAmount = Math.Floor(tipAmount * 100) / 100;

                            // Begin creating tip message
                            int      userCount = 0;
                            double   tipTotal  = 0;
                            DateTime tipTime   = DateTime.Now;
                            Console.WriteLine("{0} {1}      Sending tip of {2} to {3} users in channel #{4}", DateTime.Now.ToString("HH:mm:ss"), "Tipper",
                                              tipAmount.ToString("F"), UserPools[ChannelId].Count, _client.GetChannel(ChannelId));
                            string m = ".tip " + tipAmount.ToString("F") + " ";

                            // Loop through user pool and add them to tip
                            for (int i = 0; i < UserPools[ChannelId].Count; i++)
                            {
                                try
                                {
                                    // Make sure the message size is below the max discord message size
                                    if ((m + _client.GetUser(UserPools[ChannelId][i]).Mention + " ").Length <= 2000)
                                    {
                                        // Add a username mention
                                        m += _client.GetUser(UserPools[ChannelId][i]).Mention + " ";

                                        // Increment user count
                                        userCount++;

                                        // Add to tip total
                                        tipTotal += tipAmount;

                                        // Add tip to stats
                                        try
                                        {
                                            await Stats.Tip(tipTime, ChannelId, UserPools[ChannelId][i], tipAmount);
                                        }
                                        catch (Exception e)
                                        {
                                            Console.WriteLine("Error adding tip to stat sheet: " + e.Message);
                                        }
                                    }
                                }
                                catch { }
                            }

                            // Send tip message to channel
                            await(_client.GetChannel(ChannelId) as SocketTextChannel).SendMessageAsync(m);

                            // Begin building status message
                            var builder = new EmbedBuilder();
                            builder.WithTitle("TUT TUT");
                            builder.ImageUrl    = RaindanceImages[r.Next(0, RaindanceImages.Count)];
                            builder.Description = "Huzzah, " + tipTotal + " TRTL just rained on " + userCount +
                                                  " chatty turtle";
                            if (UserPools[ChannelId].Count > 1)
                            {
                                builder.Description += "s";
                            }
                            builder.Description += " in #" + _client.GetChannel(ChannelId) + ", they ";
                            if (UserPools[ChannelId].Count > 1)
                            {
                                builder.Description += "each ";
                            }
                            builder.Description += "got " + tipAmount + " TRTL!";
                            builder.WithColor(Color.Green);

                            // Send status message to all status channels
                            foreach (ulong u in StatusChannel)
                            {
                                await(_client.GetChannel(u) as SocketTextChannel).SendMessageAsync("", false, builder);
                            }

                            // Clear user pool
                            UserPools[ChannelId].Clear();
                            Greylist.Clear();
                            ShowDonation = true;

                            // Update stat sheet
                            try
                            {
                                await Stats.Update();
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine("Error saving stat sheet: " + e.Message);
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine("Error sending tip: " + e);
                }

                // Calculate wait time until next tip
                if (waitMin < waitMax)
                {
                    waitTime = r.Next(waitMin, waitMax);
                }
                else
                {
                    waitTime = 10 * 60 * 1000;
                }
                waitNext = DateTime.Now.AddSeconds(waitTime).ToString("HH:mm:ss") + " " + _timezone;
                Console.WriteLine("{0} {1}      Next tip in {2} seconds ({3})", DateTime.Now.ToString("HH:mm:ss"), "Tipper", waitTime, waitNext);

                // Wait for X seconds
                Waiting = 0;
                while (Waiting < waitTime || Paused)
                {
                    await Task.Delay(1000);

                    Waiting += 1;
                }
            }

            // Restart tip loop
            goto Start;
        }
Exemple #5
0
        // Main loop
        public static Task Start()
        {
            // Begin bot process in its own thread
            new Thread(delegate()
            {
                new RainBorg().RunBotAsync().GetAwaiter().GetResult();
            }).Start();

            // Begin timeout loop in its own thread

            /*new Thread(delegate ()
             * {
             *  UserTimeout();
             * }).Start();*/

            // Get console commands
            string command = "";

            while (command.ToLower() != "exit")
            {
                // Get command
                command = Console.ReadLine();

                if (command.ToLower().StartsWith("dotip"))
                {
                    waitTime = 0;
                    Log(0, "Console", "Tip sent.");
                }
                else if (command.ToLower().StartsWith("reset"))
                {
                    foreach (KeyValuePair <ulong, LimitedList <ulong> > Entry in UserPools)
                    {
                        Entry.Value.Clear();
                    }
                    Greylist.Clear();
                    Log(0, "Console", "Pools reset.");
                }
                else if (command.ToLower().StartsWith("loglevel"))
                {
                    logLevel = int.Parse(command.Substring(command.IndexOf(' ')));
                    Config.Save();
                    Log(0, "Console", "Log level changed.");
                }
                else if (command.ToLower().StartsWith("say"))
                {
                    foreach (ulong Channel in StatusChannel)
                    {
                        (_client.GetChannel(Channel) as SocketTextChannel).SendMessageAsync(command.Substring(command.IndexOf(' ')));
                    }
                    Log(0, "Console", "Sent message.");
                }
                else if (command.ToLower().StartsWith("addoperator"))
                {
                    if (!Operators.ContainsKey(ulong.Parse(command.Substring(command.IndexOf(' ')))))
                    {
                        Operators.Add(ulong.Parse(command.Substring(command.IndexOf(' '))));
                    }
                    Log(0, "Console", "Added operator.");
                }
                else if (command.ToLower().StartsWith("removeoperator"))
                {
                    if (Operators.ContainsKey(ulong.Parse(command.Substring(command.IndexOf(' ')))))
                    {
                        Operators.Remove(ulong.Parse(command.Substring(command.IndexOf(' '))));
                    }
                    Log(0, "Console", "Removed operator.");
                }
                else if (command.ToLower().StartsWith("pause") && !Paused)
                {
                    Paused = true;
                    Log(0, "Console", "Bot paused.");
                }
                else if (command.ToLower().StartsWith("resume") && Paused)
                {
                    Paused = false;
                    Log(0, "Console", "Bot resumed.");
                }
                else if (command.ToLower().StartsWith("restart"))
                {
                    Log(0, "Console", "Relaunching bot.");
                    Relaunch();
                }
            }

            // Completed, exit bot
            return(Task.CompletedTask);
        }
Exemple #6
0
        // Tip loop
        public static async Task DoTipAsync()
        {
            // Create a randomizer
            Random r = new Random();

            while (true)
            {
                // Calculate wait time until next tip
                if (waitMin < waitMax)
                {
                    waitTime = r.Next(waitMin, waitMax);
                }
                else
                {
                    waitTime = 10 * 60;
                }
                waitNext = DateTime.Now.AddSeconds(waitTime).ToString("HH:mm:ss") + " " + _timezone;
                Log(1, "Tipping", "Next tip in {0} seconds({1})", waitTime, waitNext);

                // Wait a period of time
                while (waitTime > 0)
                {
                    await Task.Delay(1000);

                    waitTime--;
                }

                // Check if paused or tip bot is offline
                while (Paused || !IsTipBotOnline())
                {
                    await Task.Delay(1000);
                }

                // If client is connected
                if (_client.ConnectionState != ConnectionState.Connected)
                {
                    Log(1, "Tipping", "Client not connected.");

                    // Delay then return to start
                    await Task.Delay(1000);

                    continue;
                }

                // Get balance
                tipBalance = GetBalance();

                // Check for sufficient funds
                if (tipBalance - tipFee < tipMin && tipBalance >= 0)
                {
                    // Log low balance message
                    Log(1, "Tipping", "Balance does not meet minimum tip threshold.");

                    // Check if bot should show a donation message
                    if (ShowDonation)
                    {
                        // Create message
                        var donationBuilder = new EmbedBuilder();
                        donationBuilder.ImageUrl = donationImages[r.Next(0, donationImages.Count)];
                        donationBuilder.WithTitle("UH OH");
                        donationBuilder.WithColor(Color.Green);
                        donationBuilder.Description = String.Format(tipBalanceError, RainBorg.Format(tipMin + tipFee - tipBalance));

                        // Cast message to all status channels
                        foreach (ulong u in StatusChannel)
                        {
                            await(_client.GetChannel(u) as SocketTextChannel).SendMessageAsync("", false, donationBuilder);
                        }

                        // Reset donation message
                        ShowDonation = false;
                    }

                    // Delay then return to start
                    await Task.Delay(1000);

                    continue;
                }

                // Grab eligible channels
                List <ulong> Channels = GetEligibleChannels();

                // No eligible channels
                if (Channels.Count < 1)
                {
                    Log(1, "Tipping", "No eligible tipping channels.");

                    // Delay then return to start
                    await Task.Delay(1000);

                    continue;
                }

                // Megatip chance
                if (r.NextDouble() * 100 <= megaTipChance)
                {
                    // Do megatip
                    await MegaTipAsync(megaTipAmount);

                    // Delay then return to start
                    await Task.Delay(1000);

                    continue;
                }

                // Roll for eligible channel
                List <ulong> EligibleChannels = ChannelWeight.Where(x => Channels.Contains(x)).ToList();
                ulong        ChannelId        = EligibleChannels[r.Next(0, EligibleChannels.Count)];

                // Check that channel is valid
                if (_client.GetChannel(ChannelId) == null)
                {
                    Log(1, "Tipping", "Error tipping on channel id {0} - channel doesn't appear to be valid");

                    // Delay then return to start
                    await Task.Delay(1000);

                    continue;
                }

                // Add developer donation
                if (developerDonations && (_client.GetChannel(ChannelId) as SocketGuildChannel).GetUser(DID) != null)
                {
                    if (!UserPools[ChannelId].Contains(DID))
                    {
                        UserPools[ChannelId].Add(DID);
                    }
                }

                // Check user count
                if (UserPools[ChannelId].Count < userMin)
                {
                    Log(1, "Tipping", "Not enough users to meet threshold, will try again next tipping cycle.");

                    // Delay then return to start
                    await Task.Delay(1000);

                    continue;
                }

                // Set tip amount
                if (tipBalance - tipFee > tipMax)
                {
                    tipAmount = tipMax / UserPools[ChannelId].Count;
                }
                else
                {
                    tipAmount = (tipBalance - tipFee) / UserPools[ChannelId].Count;
                }
                tipAmount = Floor(tipAmount);

                // Begin creating tip message
                int      userCount = 0;
                decimal  tipTotal  = 0;
                DateTime tipTime   = DateTime.Now;
                Log(1, "Tipping", "Sending tip of {0} to {1} users in channel #{2}", Format(tipAmount),
                    UserPools[ChannelId].Count, _client.GetChannel(ChannelId));
                string m = $"{tipPrefix}tip {Format(tipAmount)} ";

                // Loop through user pool and add them to tip
                for (int i = 0; i < UserPools[ChannelId].Count; i++)
                {
                    // Get user ID
                    ulong UserId = UserPools[ChannelId][i];

                    // Check that user is valid
                    if (_client.GetUser(UserId) == null)
                    {
                        continue;
                    }

                    // Make sure the message size is below the max discord message size
                    if ((m + _client.GetUser(UserId).Mention + " ").Length <= 2000)
                    {
                        // Add a username mention
                        m += _client.GetUser(UserId).Mention + " ";

                        // Increment user count
                        userCount++;

                        // Add to tip total
                        tipTotal += tipAmount;

                        // Add tip to stats
                        try
                        {
                            await Stats.Tip(tipTime, ChannelId, UserId, tipAmount);
                        }
                        catch (Exception e)
                        {
                            Log(1, "Error", "Error adding tip to stat sheet: " + e.Message);
                        }
                    }
                    else
                    {
                        break;
                    }
                }

                // Send tip message to channel
                try { await(_client.GetChannel(ChannelId) as SocketTextChannel).SendMessageAsync(m); }
                catch { }

                // Begin building status message
                var statusBuilder = new EmbedBuilder();
                statusBuilder.WithTitle("TUT TUT");
                statusBuilder.ImageUrl    = statusImages[r.Next(0, statusImages.Count)];
                statusBuilder.Description = "Huzzah, " + Format(tipTotal) + " " + currencyName + " just rained on " + userCount +
                                            " chatty user";
                if (UserPools[ChannelId].Count > 1)
                {
                    statusBuilder.Description += "s";
                }
                statusBuilder.Description += " in #" + _client.GetChannel(ChannelId) + ", they ";
                if (UserPools[ChannelId].Count > 1)
                {
                    statusBuilder.Description += "each ";
                }
                statusBuilder.Description += "got " + Format(tipAmount) + " " + currencyName + "!";
                statusBuilder.WithColor(Color.Green);

                // Send status message to all status channels
                foreach (ulong u in StatusChannel)
                {
                    try { await(_client.GetChannel(u) as SocketTextChannel).SendMessageAsync("", false, statusBuilder); }
                    catch { }
                }

                // Clear user pool
                if (flushPools)
                {
                    UserPools[ChannelId].Clear();
                }
                Greylist.Clear();
                ShowDonation = true;
            }
        }
        // Checks a message for spam
        private Task CheckForSpamAsync(SocketUserMessage message, out bool result)
        {
            // Set default to not spam
            result = false;

            // Check if bot
            if (message.Author.IsBot)
            {
                result = true;
            }

            // Check blacklist and greylist and optedout
            if (Blacklist.ContainsKey(message.Author.Id) ||
                Greylist.Contains(message.Author.Id) ||
                OptedOut.ContainsKey(message.Author.Id))
            {
                result = true;
            }

            // Check if command
            if (message.Content.StartsWith("!") ||
                message.Content.StartsWith("$") ||
                message.Content.StartsWith(".") ||
                message.Content.StartsWith("^"))
            {
                if (logLevel >= 4)
                {
                    Log("Filter", "{0} Command ignored", message.Author);
                }
                result = true;
            }

            // Check user created time
            try
            {
                if (DateTimeOffset.Now.ToUnixTimeMilliseconds() - message.Author.CreatedAt.ToUnixTimeMilliseconds() < accountAge * 60 * 60 * 1000)
                {
                    if (logLevel >= 4)
                    {
                        Log("Filter", "Account age filter triggered: {0} - {1} = {2} < {3}",
                            DateTimeOffset.Now.ToUnixTimeMilliseconds(), message.Author.CreatedAt.ToUnixTimeMilliseconds(),
                            DateTimeOffset.Now.ToUnixTimeMilliseconds() - message.Author.CreatedAt.ToUnixTimeMilliseconds(),
                            accountAge * 60 * 60 * 1000);
                    }
                    result = true;
                }
            }
            catch { }

            // Check minimum number of spaces
            if (message.Content.Count(char.IsWhiteSpace) < 3)
            {
                if (logLevel >= 4)
                {
                    Log("Filter", "{0} Less than 3 spaces", message.Author);
                }
                result = true;
            }

            // Check if message doesn't contain any alphanumeric
            if (new Regex("[^a-zA-Z0-9]").Replace(message.Content, "").Length < 14)
            {
                if (logLevel >= 4)
                {
                    Log("Filter", "{0} Not enough alphanumeric", message.Author);
                }
                result = true;
            }

            // Check that message contains at least 1 lowercase letter
            if (!message.Content.Any(char.IsLower))
            {
                if (logLevel >= 4)
                {
                    Log("Filter", "{0} No lower case letters", message.Author);
                }
                result = true;
            }

            // Check ignored word list
            foreach (string ignore in wordFilter)
            {
                if (message.Content.ToLower().Contains(ignore))
                {
                    if (logLevel >= 4)
                    {
                        Log("Filter", "{0} Ignored word found", message.Author);
                    }
                    result = true;
                    break;
                }
            }

            // Check that last message was different
            if (!UserMessages.ContainsKey(message.Author.Id))
            {
                UserMessages[message.Author.Id] = new UserMessage(message);
            }
            else if (UserMessages[message.Author.Id].Content == message.Content)
            {
                if (logLevel >= 4)
                {
                    Log("Filter", "{0} Last message same as current one", message.Author);
                }
                result = true;
            }

            // Check exiled nickname list
            try
            {
                foreach (string ignore in ignoredNicknames)
                {
                    if ((message.Author as SocketGuildUser).Nickname.ToLower().Contains(ignore))
                    {
                        if (logLevel >= 4)
                        {
                            Log("Filter", "{0} Nickname contains blacklisted term", message.Author);
                        }
                        result = true;
                        break;
                    }
                }
            }
            catch { }

            // Check that user has at least one required role (if applicable)
            if (requiredRoles.Count > 0)
            {
                var  user    = message.Author as SocketGuildUser;
                bool HasRole = false;
                foreach (string Role in requiredRoles)
                {
                    var role = (user as IGuildUser).Guild.Roles.FirstOrDefault(x => x.Name.ToLower() == Role);
                    if (user.Roles.Contains(role))
                    {
                        HasRole = true;
                        break;
                    }
                }
                if (!HasRole)
                {
                    if (logLevel >= 4)
                    {
                        Log("Filter", "{0} No required role", message.Author);
                    }
                    result = true;
                }
            }

            // Completed
            UserMessages[message.Author.Id] = new UserMessage(message);
            return(Task.CompletedTask);
        }