Beispiel #1
0
 public async void Thread_ContinuousChecker()
 {
     while (true)
     {
         var count = 0;
         using (var context = new FantasyPortfolio_DBEntities()) {
             if (context.Coins.Any())
             {
                 foreach (var coin in context.Coins)
                 {
                     if (coin.LastUpdated <= DateTime.Now.AddMinutes(-20))
                     {
                         try {
                             await Coin.UpdateCoinValue(coin.Id);
                         }
                         catch (Exception ex) {
                             Console.WriteLine($"Failed to Update {coin.TickerName} - {ex.Message}");
                         }
                         count++;
                     }
                     if (count == 25)
                     {
                         Console.WriteLine($"{DateTime.Now} - Limit reached: Sleeping for a minute");
                         count = 0;
                         Thread.Sleep(60000);
                         Console.WriteLine($"{DateTime.Now} - Continuing");
                     }
                 }
             }
             Thread.Sleep(120000);
         }
     }
 }
Beispiel #2
0
        public async Task Share()
        {
            var sb    = new StringBuilder();
            var embed = new EmbedBuilder();


            using (var context = new FantasyPortfolio_DBEntities()) {
                var userId = Context.User.Id.ToString();

                var ports = context.LeaderboardTickers.Where(d => d.RoundId == Round.CurrentRound && d.UserId == userId);
                if (!ports.Any())
                {
                    sb.AppendLine($"You are not signed up to this round. Please ensure you have the entry fee of {EntryFee} {Preferences.BaseCurrency} and type `-join`");
                    embed.WithTitle("Not Signed Up");
                }
                else
                {
                    string  usdValue    = "";
                    decimal totalAmount = 0;

                    foreach (var p in ports)
                    {
                        totalAmount += p.DollarValue.GetValueOrDefault(0);
                        if (p.TickerName == "USD")
                        {
                            if (!p.DollarValue.HasValue || p.DollarValue == 0)
                            {
                                usdValue = "0.00";
                            }
                            else
                            {
                                usdValue = p.DollarValue?.ToString("N") ?? "0.00";
                            }
                        }
                        else
                        {
                            if (p.DollarValue == 0)
                            {
                                continue;
                            }
                            sb.AppendLine($"**{p.TickerName}** - ${Math.Round(p.DollarValue.GetValueOrDefault(0), 2):N} ({p.CoinCount} {p.TickerName})");
                        }
                    }

                    sb.AppendLine("**USD**: $" + usdValue);
                    sb.AppendLine(Environment.NewLine + $"Total Value: ${totalAmount:N}");
                    embed.Title = "Your Portfolio";
                }
            }
            embed.Description = sb.ToString();
            await ReplyAsync("", false, embed);
        }
Beispiel #3
0
        public static EmbedBuilder GetLeaderboardEmbed()
        {
            using (var context = new FantasyPortfolio_DBEntities()) {
                var leaderboards = context.Leaderboards.Where(d => d.RoundId == Round.CurrentRound).OrderByDescending(d => d.totalamount);

                var position = 1;
                var sb       = new StringBuilder();
                if (leaderboards.Any())
                {
                    foreach (var player in leaderboards)
                    {
                        sb.AppendLine($"{position} - {DiscordClientNew._client.GetUser(ulong.Parse(player.UserId))?.Username ?? player.UserId} - ${player.totalamount:N}");
                        position++;
                    }
                }
                else
                {
                    sb.AppendLine("No players currently participating in this round");
                }

                sb.AppendLine(Environment.NewLine);

                var embed = new EmbedBuilder {
                    Title       = $"{Preferences.BaseCurrency} Discord Leaderboard - Round {Round.CurrentRound}",
                    Description = sb.ToString()
                };

                TimeSpan span = (Round.CurrentRoundEnd - DateTime.Now);

                var timeRemainingStr = "";

                if (span.Days > 0)
                {
                    timeRemainingStr += $"{span.Days} {(span.Days > 1 ? "Days" : "Day")} ";
                }

                if (span.Hours > 0)
                {
                    timeRemainingStr += $"{span.Hours} {(span.Hours > 1 ? "Hours" : "Hour")} ";
                }
                if (span.Hours < 1 && span.Minutes > 0)
                {
                    timeRemainingStr += $"{span.Minutes} {(span.Minutes > 1 ? "Minutes" : "Minute")}";
                }

                var endStr = string.IsNullOrEmpty(timeRemainingStr) ? "soon" : $"in {timeRemainingStr}";

                embed.WithFooter($"Round Ends {endStr} - Grand Prize: {PrizePool} {Preferences.BaseCurrency}");
                return(embed);
            }
        }
Beispiel #4
0
        public bool CheckBalance(string amount, string ticker, out string reason)
        {
            reason = "";
            var userId = Context.User.Id.ToString();

            if (decimal.TryParse(amount, out var amountDec))
            {
                using (var context = new FantasyPortfolio_DBEntities()) {
                    int tickerId;

                    if (ticker.ToUpper() == "USD")
                    {
                        tickerId = -1;
                    }
                    else
                    {
                        var coins = Coin.GetTickers(ticker);
                        if (coins.Result.Count > 1)
                        {
                            var nameStrings = new List <string>();
                            foreach (var coin in coins.Result)
                            {
                                nameStrings.Add($"`{coin.TickerName}`");
                            }
                            reason = $"Multiple coins in database with this ticker exist, please use the coin name instead: {string.Join(", ", nameStrings)})";
                            return(false);
                        }
                        else if (coins.Result.Count == 0)
                        {
                            reason = "No coin found with this ticker or name";
                            return(false);
                        }
                        else
                        {
                            // ReSharper disable once PossibleNullReferenceException - Not null as above
                            tickerId = coins.Result.FirstOrDefault().TickerId;
                        }
                    }
                    var value = context.Portfolios.FirstOrDefault(d => d.UserId == userId && d.TickerId == tickerId && d.RoundId == Round.CurrentRound);
                    if (value != null && value.CoinAmount >= amountDec)
                    {
                        return(true);
                    }
                    reason = "Not enough balance";
                    return(false);
                }
            }
            reason = "Invalid input";
            return(false);
        }
Beispiel #5
0
        private void FantasyTimerOnElapsed(object sender, ElapsedEventArgs elapsedEventArgs)
        {
            var embed          = FantasyPortfolioModule.GetLeaderboardEmbed();
            var winner         = FantasyPortfolioModule.GetWinner();
            var additionalText = "";

            TimeSpan span = (Round.CurrentRoundEnd - DateTime.Now);

            if (Round.CurrentRoundEnd <= DateTime.Now)
            {
                Console.WriteLine($"Round {Round.CurrentRoundEnd} Finished. Winner: {winner.UserId}");
                using (var context = new FantasyPortfolio_DBEntities()) {
                    if (context.Leaderboards.Any(d => d.RoundId == Round.CurrentRound))
                    {
                        if (FantasyPortfolioModule.PrizePool > 0)
                        {
                            additionalText = $"Congratulations <@{winner.UserId}>! You have won the fantasy portfolio and won {FantasyPortfolioModule.PrizePool} {Preferences.BaseCurrency}";
                            QTCommands.SendTip(_client.CurrentUser.Id, ulong.Parse(winner.UserId), FantasyPortfolioModule.PrizePool);
                        }
                        else
                        {
                            additionalText = $"Congratulations <@{winner.UserId}>! You have won the fantasy portfolio! There was no prize.";
                        }
                    }
                    else
                    {
                        embed.WithDescription("Round has finished! There were no participants in this round, so nobody wins!");
                    }
                    Round round = new Round {
                        RoundEnds = DateTime.Now.AddDays(Round.RoundDurationDays)
                    };
                    context.Rounds.Add(round);
                    context.SaveChanges();
                }
            }
            else if (span.TotalMilliseconds < fantasyTickerTimer.Interval)
            {
                //Set next interval to 5000ms after the round ends
                fantasyTimer.Interval = span.TotalMilliseconds + 5000;
                Console.WriteLine("Next fantasy interval set to 5 seconds");
            }
            else
            {
                // Set the next interval to 2 hours
                fantasyTickerTimer.Interval = 7200000;
                Console.WriteLine("Next fantasy interval set to 2 hours");
            }
            _client.GetGuild(Settings.Default.GuildId).GetTextChannel(Settings.Default.FantasyChannel).SendMessageAsync(additionalText, false, embed);
        }
Beispiel #6
0
        public async Task Flip(string side, string amount)
        {
            if (CanRunTipCommands)
            {
                if (Enum.TryParse(side.ToLower(), out CoinSide coinSide))
                {
                    if (decimal.TryParse(amount, out var betAmount))
                    {
                        if (QTCommands.CheckBalance(Context.User.Id, betAmount))
                        {
                            if (betAmount < MinBetAmount)
                            {
                                await ReplyAsync($"Minimum bet {MinBetAmount} {Preferences.BaseCurrency}");

                                return;
                            }

                            decimal balance          = 0;
                            var     houseBalanceCall = QTCommands.GetBalance(Context.Client.CurrentUser.Id).Result;
                            decimal.TryParse(houseBalanceCall, out balance);

                            decimal maxBet = balance / 10;

                            if (betAmount > maxBet)
                            {
                                await ReplyAsync($"Maximum bet exceeded. Max: {maxBet} {Preferences.BaseCurrency}");

                                return;
                            }

                            var rewardValue = betAmount * (decimal)BetWin;
                            if (QTCommands.CheckBalance(Context.Client.CurrentUser.Id, rewardValue + FantasyPortfolioModule.PrizePool))
                            {
                                QTCommands.SendTip(Context.User.Id, Context.Client.CurrentUser.Id, betAmount);
                                try {
                                    var coin = (CoinSide)RandomInteger(0, 2);
                                    //var coin = (CoinSide)Generator.Next(0, 2);

                                    var embed = new EmbedBuilder();

                                    string message;

                                    if (coin == coinSide)
                                    {
                                        QTCommands.SendTip(DiscordClientNew._client.CurrentUser.Id, Context.User.Id, rewardValue);
                                        embed.AddInlineField("Flipped", FirstCharToUpper(coin.ToString()));
                                        embed.AddInlineField("Prize", $"{rewardValue} {Preferences.BaseCurrency}");
                                        embed.AddInlineField("Profit", $"{(rewardValue - betAmount)} {Preferences.BaseCurrency}");
                                        embed.WithColor(Discord.Color.Green);
                                        message = $"You won! Congratulations {Context.User.Mention}!";
                                    }
                                    else
                                    {
                                        embed.AddInlineField("Flipped", FirstCharToUpper(coin.ToString()));
                                        embed.AddInlineField("Lost", $"{betAmount} {Preferences.BaseCurrency}");
                                        embed.WithColor(Discord.Color.Red);
                                        message = $"Unlucky {Context.User.Mention}, you lost :(";
                                    }
                                    embed.WithFooter(Preferences.FooterText);
                                    await ReplyAsync(message, false, embed);

                                    using (var context = new FantasyPortfolio_DBEntities()) {
                                        var result = new FlipResults();
                                        result.DateTime   = DateTime.Now;
                                        result.UserId     = Context.User.Id.ToString();
                                        result.FlipResult = (byte)coin;
                                        result.UserFlip   = (byte)coinSide;
                                        result.FlipValue  = betAmount;
                                        context.FlipResults.Add(result);
                                        context.SaveChanges();
                                    }

                                    Console.WriteLine($"{Context.User.Id} ({Context.User.Username}) bet on {side} and flipped {coin}");
                                }
                                catch (Exception e) {
                                    Console.WriteLine(e.Message);
                                    QTCommands.SendTip(DiscordClientNew._client.CurrentUser.Id, Context.User.Id, betAmount);
                                    await ReplyAsync("Sorry something went wrong. You have been refunded your bet.");
                                }
                            }
                            else
                            {
                                await ReplyAsync("Sorry, the bot is too poor to reward you if you won :(");
                            }
                        }
                        else
                        {
                            await ReplyAsync("You do not have enough balance to perform this action");
                        }
                    }
                }
            }
            else
            {
                await ReplyAsync($"Please use the <#{Preferences.TipBotChannel}> channel");
            }
        }
Beispiel #7
0
 public static Leaderboard GetWinner()
 {
     using (var context = new FantasyPortfolio_DBEntities()) {
         return(context.Leaderboards.FirstOrDefault(d => d.RoundId == Round.CurrentRound));
     }
 }
Beispiel #8
0
        public async Task Buy(string amount, string ticker)
        {
            var userId = Context.User.Id.ToString();

            if (amount != "all")
            {
                if (!CheckBalance(amount, "USD", out var reason))
                {
                    await ReplyAsync($"Error Buying {ticker.ToUpper()} - {reason}");

                    return;
                }
            }

            using (var context = new FantasyPortfolio_DBEntities()) {
                var coins = await Coin.GetTickers(ticker);

                var embed = new EmbedBuilder();

                if (coins.Count > 1)
                {
                    embed.WithTitle("Multiple Coins Found");
                    foreach (var coin in coins)
                    {
                        embed.AddInlineField(coin.TickerName, $"${decimal.Parse(Math.Round(coin.PriceUSD, 8).ToString(), NumberStyles.AllowExponent | NumberStyles.AllowDecimalPoint)}");
                    }

                    embed.WithDescription("Multiple coins found with the same ticker, please use the name below.");
                    await ReplyAsync("", false, embed);

                    return;
                }
                else if (coins.Count == 0)
                {
                    embed.WithTitle("No coin found with this ticker");
                    embed.WithDescription("No coin with this ticker has been found.");
                    await ReplyAsync("", false, embed);

                    return;
                }
                else
                {
                    var coin = coins.FirstOrDefault();

                    if (coin.Volume24 != null && coin.Volume24 < 50000)
                    {
                        embed.WithTitle("Volume is too low for this ticker");
                        embed.WithDescription($"Volume is too low for this ticker. Minimum volume: $50,000 (Current: ${coin.Volume24:N})");
                        await ReplyAsync("", false, embed);

                        return;
                    }

                    if (amount == "all")
                    {
                        amount = context.Portfolios.FirstOrDefault(d => d.UserId == userId && d.TickerId == -1 && Round.CurrentRound == d.RoundId)?.CoinAmount.ToString();
                    }

                    if (decimal.TryParse(amount, out var amountDec))
                    {
                        amountDec = Math.Round(amountDec, 8);

                        var feeAmount = amountDec * (decimal)0.005;
                        amountDec = amountDec * (decimal)0.995;

                        var usdAmount = context.Portfolios.FirstOrDefault(d => d.RoundId == Round.CurrentRound && d.UserId == userId && d.TickerId == -1);

                        var usdAmount2 = usdAmount.CoinAmount;

                        var portCoin = context.Portfolios.FirstOrDefault(d => d.RoundId == Round.CurrentRound && d.UserId == userId && d.TickerId == coin.TickerId);

                        var roundedAmount = Math.Round(amountDec / coin.PriceUSD, 8);

                        if (roundedAmount == 0)
                        {
                            await ReplyAsync("Buy failed: Amount bought would be 0.");

                            return;
                        }

                        if (portCoin == null)
                        {
                            portCoin = new Portfolio {
                                UserId     = Context.User.Id.ToString(),
                                TickerId   = coin.TickerId,
                                RoundId    = Round.CurrentRound,
                                CoinAmount = 0
                            };
                            context.Portfolios.Add(portCoin);
                        }
                        else
                        {
                            context.Portfolios.Attach(portCoin);
                        }

                        portCoin.CoinAmount += roundedAmount;
                        if (usdAmount != null)
                        {
                            usdAmount.CoinAmount = usdAmount.CoinAmount - amountDec - feeAmount;
                        }
                        try {
                            context.SaveChanges();
                        }
                        catch (Exception e) {
                            await ReplyAsync(e.Message + Environment.NewLine + Environment.NewLine + e.InnerException?.Message);

                            return;
                        }

                        await ReplyAsync($"Successfully bought {roundedAmount} {ticker.ToUpper()}");

                        return;
                    }
                }
            }
            await ReplyAsync("Error... Please try again.");
        }
Beispiel #9
0
        public async Task Sell(string amount, string ticker)
        {
            var userId = Context.User.Id.ToString();

            if (amount != "all")
            {
                if (!CheckBalance(amount, ticker, out var reason))
                {
                    await ReplyAsync($"Error Selling {ticker.ToUpper()} - {reason}");

                    return;
                }
            }
            using (var context = new FantasyPortfolio_DBEntities()) {
                var coins = await Coin.GetTickers(ticker);

                var embed = new EmbedBuilder();

                if (coins.Count > 1)
                {
                    embed.WithTitle("Multiple Coins Found");
                    foreach (var coin in coins)
                    {
                        embed.AddInlineField(coin.TickerName, $"${decimal.Parse(Math.Round(coin.PriceUSD, 8).ToString(), NumberStyles.AllowExponent | NumberStyles.AllowDecimalPoint)}");
                    }
                    embed.WithDescription("Multiple coins found with the same ticker, please use the name below.");
                    await ReplyAsync("", false, embed);

                    return;
                }
                else if (coins.Count == 0)
                {
                    embed.WithTitle("No coin found with this ticker");
                    embed.WithDescription("No coin with this ticker has been found.");
                    await ReplyAsync("", false, embed);

                    return;
                }
                else
                {
                    var coin = coins.FirstOrDefault();

                    var portCoin = context.Portfolios.FirstOrDefault(d => d.RoundId == Round.CurrentRound && d.UserId == userId && d.TickerId == coin.TickerId);

                    if (amount == "all")
                    {
                        amount = portCoin?.CoinAmount.ToString();
                    }

                    if (decimal.TryParse(amount, out var amountDec))
                    {
                        amountDec = Math.Round(amountDec, 8);

                        var usdAmount = context.Portfolios.FirstOrDefault(d => d.RoundId == Round.CurrentRound && d.UserId == userId && d.TickerId == -1);

                        var roundedAmount = Math.Round(amountDec * coin.PriceUSD, 8) * (decimal)0.995;

                        if (portCoin == null)
                        {
                            portCoin = new Portfolio {
                                UserId     = Context.User.Id.ToString(),
                                TickerId   = coin.TickerId,
                                RoundId    = Round.CurrentRound,
                                CoinAmount = 0
                            };
                            context.Portfolios.Add(portCoin);
                        }
                        else
                        {
                            context.Portfolios.Attach(portCoin);
                        }
                        portCoin.CoinAmount -= amountDec;
                        Debug.Assert(usdAmount != null, nameof(usdAmount) + " != null");
                        usdAmount.CoinAmount = usdAmount.CoinAmount + roundedAmount;
                        try {
                            context.SaveChanges();
                        }
                        catch (Exception e) {
                            await ReplyAsync(e.Message + Environment.NewLine + Environment.NewLine + e.InnerException?.Message);

                            return;
                        }
                        await ReplyAsync($"Successfully sold {amountDec} {ticker.ToUpper()}");

                        return;
                    }
                }
            }
            await ReplyAsync("Error connecting to database... Please try again");
        }
Beispiel #10
0
        public static async Task <Embed> GetPriceEmbed(string ticker)
        {
            var  tickerFormatted = ticker.ToUpper().Trim();
            long?tickerId;

            using (var context = new FantasyPortfolio_DBEntities()) {
                var coin = context.Coins.FirstOrDefault(d => d.TickerName.ToUpper().Trim() == tickerFormatted);
                if (coin == null)
                {
                    var listings = await priceClientNew.GetListingsAsync();

                    var listingSingle = listings.Data.FirstOrDefault(d => d.Symbol == tickerFormatted);

                    if (listingSingle != null)
                    {
                        coin = new Coin {
                            TickerId    = (int)listingSingle.Id,
                            TickerName  = listingSingle.Symbol,
                            LastUpdated = new DateTime(2000, 1, 1)
                        };
                        context.Coins.Add(coin);
                        context.SaveChanges();
                    }
                }
                tickerId = coin?.TickerId;
            }
            if (tickerId != null)
            {
                var tickerResponse = await priceClientNew.GetTickerAsync((int)tickerId, "BTC");

                var emb = new EmbedBuilder();
                emb.WithTitle($"Price of {tickerResponse.Data.Name} [{tickerFormatted}]");
                var sb = new StringBuilder();
                sb.AppendLine($"**Rank:** {tickerResponse.Data.Rank}");
                sb.Append(Environment.NewLine);

                foreach (var quote in tickerResponse.Data.Quotes)
                {
                    if (quote.Key == "USD")
                    {
                        sb.AppendLine("**Price " + quote.Key + ":** " + "$" + decimal.Parse(Math.Round(quote.Value.Price.GetValueOrDefault(0), 5).ToString(), NumberStyles.AllowExponent | NumberStyles.AllowDecimalPoint));
                    }
                    else
                    {
                        sb.AppendLine("**Price " + quote.Key + ":** " + decimal.Parse(Math.Round(quote.Value.Price.GetValueOrDefault(0), 8).ToString(), NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent) + " " + quote.Key);
                    }
                }

                sb.Append(Environment.NewLine);
                sb.AppendLine($"**Market Cap: **${tickerResponse.Data.Quotes.FirstOrDefault(d => d.Key == "USD").Value.MarketCap:n}");
                sb.AppendLine($"**24h volume: **${tickerResponse.Data.Quotes.FirstOrDefault(d => d.Key == "USD").Value.Volume24H:n}");
                sb.AppendLine($"**Supply: **{tickerResponse.Data.TotalSupply:n}");
                sb.Append(Environment.NewLine);
                sb.AppendLine($"**Change 1h: **{tickerResponse.Data.Quotes.FirstOrDefault(d => d.Key == "USD").Value.PercentChange1H:n}%");
                sb.AppendLine($"**Change 24h: **{tickerResponse.Data.Quotes.FirstOrDefault(d => d.Key == "USD").Value.PercentChange24H:n}%");
                sb.AppendLine($"**Change 7 days: **{tickerResponse.Data.Quotes.FirstOrDefault(d => d.Key == "USD").Value.PercentChange7D:n}%");

                emb.WithDescription(sb.ToString());
                try {
                    emb.WithUrl($"https://coinmarketcap.com/currencies/{tickerResponse.Data.WebsiteSlug}/");
                }
                catch {
                    // ignored
                }

                emb.ThumbnailUrl = $"https://s2.coinmarketcap.com/static/img/coins/32x32/{tickerId}.png";

                emb.WithFooter(Preferences.FooterText);
                return(emb);
            }
            return(null);
        }