public async Task BTCToDallar(CommandContext Context, [Description("Optional amount of BTC to covert to Dallar, default is 1")] params decimal[] Amount) { decimal ParsedAmount = 1m; if (Amount.Length > 0) { ParsedAmount = Amount[0]; } await LogHandlerService.LogUserActionAsync(Context, $"Invoked BTC command with amount {ParsedAmount}."); if (true)//!Program.DigitalPriceExchange.GetPriceInfo(out DigitalPriceCurrencyInfo PriceInfo, out bool bPriceStale)) { await DiscordHelpers.PromptUserToDeleteMessage(Context, $"{Context.User.Mention}: It appears that Dallar Bot is unable to evaluate the price of Dallar at the moment. Perhaps an exchange is down?"); return; } await Context.TriggerTypingAsync(); var Info = "error"; //String.Format("{0:#,##0.00000000}", ParsedAmount) + " BTC is " + String.Format("{0:#,##0.00000000}", decimal.Round(ParsedAmount / PriceInfo.Price, 8)) + " DAL."; if (true) //bPriceStale) { Info += "\n:warning: Info potentially out of date due to Exchange API lag."; } await DiscordHelpers.PromptUserToDeleteMessage(Context, $"{Context.User.Mention}: {Info}"); }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { try { var instocks = await _mongoService.GetAllInStocks(); if (instocks != null && instocks.Count > 0) { var roleId = _config.GetSection("Workers")["discordRoleId"]; await _webhookClient.SendMessageAsync($"<@&{roleId}> Remember that these items are still in stock!", false); Parallel.ForEach(instocks, async instock => { _logger.LogInformation($"Opening new thread for Product ({instock.EndpointItem.Title}) <ThreadID={Thread.CurrentThread.ManagedThreadId}>."); await _webhookClient.SendMessageAsync("", false, DiscordHelpers.BuildEmbed(instock.EndpointItem)); }); } _logger.LogInformation($"No Product are in stock currently."); } catch (Exception e) { _logger.LogError($"Snatcher Worker failed unexpectedly => {e}", e); // throw; } // 3 Days by Default await Task.Delay(int.Parse(_config.GetSection("Workers")["reminderInterval"]), stoppingToken); } }
public async Task FetchAllarJoke(CommandContext Context) { await LogHandlerService.LogUserActionAsync(Context, "Invoked Allar Joke"); if (!await DiscordHelpers.AttemptChargeDallarForCommand(Context, 1)) { await LogHandlerService.LogUserActionAsync(Context, "Failed charged for Allar Joke"); return; } await LogHandlerService.LogUserActionAsync(Context, "Successfully charged for Allar Joke"); await Context.TriggerTypingAsync(); var httpClient = new HttpClient(); var content = await httpClient.GetStringAsync("http://api.icndb.com/jokes/random?firstName=Michael&lastName=Allar"); try { dynamic jokeResult = JsonConvert.DeserializeObject(content); string joke = jokeResult.value.joke; joke = System.Net.WebUtility.HtmlDecode(joke); await Context.RespondAsync($"{Context.User.Mention} : {joke}"); } catch { await LogHandlerService.LogUserActionAsync(Context, "Failed to perform Allar Joke"); await Context.RespondAsync($"{Context.User.Mention}: Failed to fetch joke. Please contact an Administrator."); } }
public async Task Execute(DiscordMessage message, Command command) { await message.IsDirectMessageSupported(); if (!command.HasArgs) { return; } if (command.Args.Count != 2) { return; } var userMention = command.Args[0]; var roleMention = command.Args[1]; var userId = DiscordHelpers.ConvertMentionToUserId(userMention); var roleId = DiscordHelpers.ConvertMentionToUserId(roleMention); var result = await AssignGuildMemberToRole(message, userId, roleId); if (result) { await message.RespondAsync($"{message.Author.Mention} has added {userMention} to the {roleMention} role."); return; } await message.RespondAsync($"{message.Author.Mention} failed to add {userMention} to the {roleMention} role."); }
public async Task Execute(DiscordMessage message, Command command) { //await message.IsDirectMessageSupported(); if (command.HasArgs && command.Args.Count == 1) { if (!message.Author.Id.IsModeratorOrHigher(_config)) { await message.RespondAsync($"{message.Author.Mention} is not a moderator or higher thus you may not see other's subscription settings."); return; } var mention = command.Args[0]; var userId = DiscordHelpers.ConvertMentionToUserId(mention); if (userId <= 0) { await message.RespondAsync($"{message.Author.Mention} failed to retrieve user with mention tag {mention}."); return; } await SendUserSubscriptionSettings(message.Author, userId); return; } await SendUserSubscriptionSettings(message.Author, message.Author.Id); }
public async Task GetDallarDeposit(CommandContext Context) { if (Program.DaemonClient.GetWalletAddressFromAccount(Context.User.Id.ToString(), true, out string Wallet)) { DiscordEmbedBuilder EmbedBuilder = new DiscordEmbedBuilder(); EmbedBuilder.WithTitle("Dallar Bot Depositing Help"); EmbedBuilder.WithDescription("DallarBot is a Discord bot dedicated to allowing individual users on the server to easily tip each other in the chatbox. It generates a wallet for every Discord user, and you can withdraw into any address any time." + Environment.NewLine + Environment.NewLine + "Dallar Bot does not access anyone's wallets directly in order to protect everyone's privacy."); EmbedBuilder.AddField("Warning About Storage", "Dallar Bot should not be used as a long term storage for your Dallar. Dallar Bot is only accessible through Discord and if the Bot or Discord are down for any reason, you will *not* be able to access your stored Dallar."); EmbedBuilder.AddField("Dallar Bot Fees", $"All transactions with Dallar Bot incur a flat {Program.SettingsHandler.Dallar.Txfee} DAL fee to cover the Dallar blockchain transaction fees as well as funding and maintenance costs sent to the Dallar Bot server hoster."); EmbedBuilder.AddField("Blockchain Transactions", $"Dallar Bot uses the blockchain to keep track of its transactions, meaning your transactions will require 6 confirmation blocks before they are completed. This should take approximately 5 to 10 minutes under normal Dallar network conditions."); EmbedBuilder.AddField("Depositing", $"You can deposit Dallar into your Dallar Bot balance by sending Dallar to this address generated specifically for you: `{Wallet}`"); EmbedBuilder.WithImageUrl($"https://api.qrserver.com/v1/create-qr-code/?data=dallar:{Wallet}&qzone=2"); await LogHandlerService.LogUserActionAsync(Context, $"Fetched deposit info."); await DiscordHelpers.RespondAsDM(Context, EmbedBuilder.Build()); } else { await DiscordHelpers.RespondAsDM(Context, $"{Context.User.Mention}: Failed to fetch your wallet address. Please contact an Administrator."); await LogHandlerService.LogUserActionAsync(Context, $"Failed to fetch deposit info."); } DiscordHelpers.DeleteNonPrivateMessage(Context); }
public async Task Command(params string[] args) { var users = new List <SocketGuildUser>(); var invalidUsers = new List <string>(); foreach (string a in args) { SocketGuildUser user = DiscordHelpers.ParseGuildUser(a, Context.Guild); if (user != null) { users.Add(user); } else { invalidUsers.Add(a); } } // Embolden all users, format them in a comma separated list. string kickString = users.Humanize(x => x.ToString().ToDiscordBold(), ""); var errorSb = new StringBuilder("Failed to kick users:\n"); if (invalidUsers.Any()) { errorSb.AppendLine(invalidUsers.Humanize(x => x.ToDiscordBold(), "")); } List <Task> awaiters = new List <Task>(); foreach (SocketGuildUser user in users) { awaiters.Add(user.KickAsync()); } await Task.WhenAll(awaiters); var finalSb = new StringBuilder(); if (!String.IsNullOrWhiteSpace(kickString)) { finalSb.AppendLine(kickString); } if (!String.IsNullOrWhiteSpace(errorSb.ToString())) { finalSb.AppendLine("\n\n" + errorSb); } var embed = new KaguyaEmbedBuilder { Title = "Masskick", Description = finalSb.ToString() }; await SendEmbedAsync(embed); }
public async Task BotIfno(CommandContext Context) { await Context.TriggerTypingAsync(); DiscordEmbedBuilder embedBuilder = new DiscordEmbedBuilder(); embedBuilder.WithTitle("Dallar Bot Info"); embedBuilder.AddField("Bot Statistics", $"{Context.Client.Guilds.Count} Server{(Context.Client.Guilds.Count > 1 ? "s" : "")} across {Context.Client.ShardCount} shard{(Context.Client.ShardCount > 1 ? "s" : "")}."); await DiscordHelpers.PromptUserToDeleteMessage(Context, embedBuilder.Build()); }
public async Task Execute(DiscordMessage message, Command command) { if (!command.HasArgs) { return; } if (command.Args.Count != 3) { return; } var mention = command.Args[0]; var date = command.Args[1]; var days = command.Args[2]; var userId = DiscordHelpers.ConvertMentionToUserId(mention); if (userId == 0) { await message.RespondAsync($"{message.Author.Mention}, I failed to lookup discord user {mention}."); return; } if (!DateTime.TryParse(date, out DateTime dateDonated)) { await message.RespondAsync($"{message.Author.Mention} {date} is not a valid value for date."); return; } if (!int.TryParse(days, out int daysAvailable)) { await message.RespondAsync($"{message.Author.Mention} {days} is not a valid value for days."); return; } if (!_config.Supporters.ContainsKey(userId)) { _config.Supporters.Add(userId, new Data.Models.Donator { UserId = userId, Email = mention, DateDonated = dateDonated, DaysAvailable = daysAvailable }); } else { var donator = _config.Supporters[userId]; donator.DateDonated = dateDonated; donator.DaysAvailable = daysAvailable; } _config.Save(); await message.RespondAsync($"{message.Author.Mention} {userId} has been added to the supporters list with {daysAvailable} days available."); }
public void AvatarNull() { user.Avatar = null; Assert.Equal ($"https://cdn.discordapp.com/embed/avatars/{user.Discriminator % 5}.png", DiscordHelpers.GetAvatarUrl(user)); Assert.Equal( $"https://cdn.discordapp.com/embed/avatars/{user.Discriminator % 5}.png", DiscordHelpers.GetAvatarUrl(user, ImageType.PNG, ImageSize.x512)); }
public async Task GiveAFuck(CommandContext Context) { if (DiscordHelpers.IsUserAdmin(Context) || DiscordHelpers.IsUserModerator(Context) || DiscordHelpers.IsUserDallarDevTeam(Context)) { await LogHandlerService.LogUserActionAsync(Context, "Invoked GiveAFuck"); await Context.TriggerTypingAsync(); await Context.RespondAsync(":regional_indicator_g: :regional_indicator_i: :regional_indicator_v: :regional_indicator_e: :a: :regional_indicator_f: :regional_indicator_u: :regional_indicator_c: :regional_indicator_k:"); } }
private string FormatLink(string text, Dictionary <string, string> externUrls, bool trim = true) { text = text.Truncate(trim ? 22 : int.MaxValue); if (externUrls.ContainsKey("spotify")) { return(DiscordHelpers.BuildMarkdownUri(text, externUrls["spotify"])); } else { return(text); } }
public async Task Vote(ICommand command) { var poll = await _settings.Modify(command.GuildId, (PollSettings s) => { var p = s.Polls.FirstOrDefault(x => x.Channel == command.Message.Channel.Id); if (p != null) { if (command["Answer"].AsString.All(x => char.IsDigit(x))) { var vote = command["Answer"].AsInt.Value; if (vote > p.Answers.Count || vote < 1) throw new IncorrectParametersCommandException("There is no answer with this number."); p.Votes[command.Message.Author.Id] = vote; } else { var tokens = new string(command["Answer"].AsString.Select(c => char.IsLetterOrDigit(c) ? c : ' ').ToArray()).Split(new char[] { }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.ToLowerInvariant()).ToList(); var scores = new List<int>(); foreach (var answerTokens in p.Answers.Select(x => new string(x.Select(c => char.IsLetterOrDigit(c) ? c : ' ').ToArray()).Split(new char[] { }, StringSplitOptions.RemoveEmptyEntries).Select(y => y.ToLowerInvariant()).ToList())) scores.Add(tokens.Where(x => answerTokens.Contains(x)).Count()); if (!scores.Any(x => x > 0)) throw new UnclearParametersCommandException($"I don't recognize this answer. Try to vote with `{command.Prefix}vote answer number` instead.", false); var max = scores.Max(); if (scores.Where(x => x == max).Count() > 1) throw new UnclearParametersCommandException($"I'm not sure which answer you meant. Try to vote with `{command.Prefix}vote answer number` instead.", false); p.Votes[command.Message.Author.Id] = scores.FindIndex(x => x == max) + 1; } } return p; }); if (poll == null) { await command.ReplyError("There is no poll running in this channel."); } else { var confMessage = await command.ReplySuccess($"**{DiscordHelpers.EscapeMentions("@" + command.Message.Author.Username)}** vote cast."); if (poll.Anonymous) { if ((await command.Guild.GetCurrentUserAsync()).GetPermissions((IGuildChannel)command.Channel).ManageMessages) await command.Message.DeleteAsync(); confMessage.First().DeleteAfter(2); } } }
public void AvatarStatic() { user.Avatar = "2345243f3oim4foi34mf3k4f"; Assert.Equal( "https://cdn.discordapp.com/avatars/111/2345243f3oim4foi34mf3k4f.png?size=256", DiscordHelpers.GetAvatarUrl(user)); Assert.Equal( "https://cdn.discordapp.com/avatars/111/2345243f3oim4foi34mf3k4f.webp?size=2048", DiscordHelpers.GetAvatarUrl(user, ImageType.WEBP, ImageSize.x2048)); Assert.Equal("https://cdn.discordapp.com/avatars/111/2345243f3oim4foi34mf3k4f.jpeg?size=16", DiscordHelpers.GetAvatarUrl(user, ImageType.JPEG, ImageSize.x16)); }
public void AvatarAnimated() { user.Avatar = "a_owiejfowiejf432ijf3o"; Assert.Equal( "https://cdn.discordapp.com/avatars/111/a_owiejfowiejf432ijf3o.gif?size=256", DiscordHelpers.GetAvatarUrl(user)); Assert.Equal( "https://cdn.discordapp.com/avatars/111/a_owiejfowiejf432ijf3o.webp?size=2048", DiscordHelpers.GetAvatarUrl(user, ImageType.WEBP, ImageSize.x2048)); Assert.Equal( "https://cdn.discordapp.com/avatars/111/a_owiejfowiejf432ijf3o.jpeg?size=16", DiscordHelpers.GetAvatarUrl(user, ImageType.JPEG, ImageSize.x16)); }
public Task Start() { SocketGuild server = DiscordHelpers.GetServer(DiscordIds.ServerId, _client); if (server != null) { _channel = DiscordHelpers.GetTextChannel(server, DiscordIds.ChannelId); if (_channel != null) { _timer = new System.Threading.Timer(Check, null, 0, 1000 * PingDelaySeconds); } } return(Task.CompletedTask); }
private DiscordEmbed BuildEmbedPokemonFromAlarm(PokemonData pokemon, AlarmObject alarm) { var pkmn = _db.Pokemon[pokemon.Id.ToString()]; if (pkmn == null) { _logger.Error($"Failed to lookup Pokemon '{pokemon.Id}' in database."); return(null); } var eb = new DiscordEmbedBuilder { Title = alarm == null || string.IsNullOrEmpty(alarm.Name) ? "DIRECTIONS" : alarm.Name, Description = $"{pkmn.Name}{pokemon.Gender.GetPokemonGenderIcon()} {pokemon.CP}CP {pokemon.IV} LV{pokemon.Level} has spawned!", Url = string.Format(Strings.GoogleMaps, pokemon.Latitude, pokemon.Longitude), ImageUrl = string.Format(Strings.GoogleMapsStaticImage, pokemon.Latitude, pokemon.Longitude), ThumbnailUrl = string.Format(Strings.PokemonImage, pokemon.Id, 0), Color = DiscordHelpers.BuildColor(pokemon.IV) }; eb.AddField($"{pkmn.Name} (#{pokemon.Id}, {pokemon.Gender})", $"CP: {pokemon.CP} IV: {pokemon.IV} (Sta: {pokemon.Stamina}/Atk: {pokemon.Attack}/Def: {pokemon.Defense}) LV: {pokemon.Level}"); if (!string.IsNullOrEmpty(pokemon.FormId)) { var form = pokemon.Id.GetPokemonForm(pokemon.FormId); if (!string.IsNullOrEmpty(form)) { eb.AddField("Form:", form); } } if (pkmn.Types.Count > 0) { var types = new List <string>(); pkmn.Types.ForEach(x => { types.Add(Strings.TypeEmojis[x.Type.ToLower()]); }); eb.AddField("Types: ", string.Join("/", types)); } eb.AddField("Despawn:", $"{pokemon.DespawnTime.ToLongTimeString()} ({pokemon.SecondsLeft.ToReadableString(true)} left)"); eb.AddField("Location:", $"{Math.Round(pokemon.Latitude, 5)},{Math.Round(pokemon.Longitude, 5)}"); eb.WithImageUrl(string.Format(Strings.GoogleMapsStaticImage, pokemon.Latitude, pokemon.Longitude) + $"&key={_config.GmapsKey}"); var embed = eb.Build(); return(embed); }
public async Task Say(ICommand command) { var message = command["Message"].AsString ?? ""; var channel = command["TargetChannel"].AsTextChannel; // This is a mods-only command, but to prevent permission escalation, check // if there's any non-mentionable role and if the sender has a mention everyone perm var nonMentionableRoles = command.Message.MentionedRoleIds.Where(x => !command.Guild.GetRole(x)?.IsMentionable ?? false).ToList(); var replaceRoleMentions = (message.ContainsEveryonePings() || nonMentionableRoles.Any()) && !((IGuildUser)command.Author).GetPermissions(channel).MentionEveryone; if (replaceRoleMentions) { message = DiscordHelpers.ReplaceRoleMentions(message, nonMentionableRoles, command.Guild) .Sanitise(allowRoleMentions: true); } if (command.Message.Attachments.Count <= 0) { if (string.IsNullOrEmpty(command["Message"])) { throw new Framework.Exceptions.IncorrectParametersCommandException("Specify a message or an attachment."); } await channel.SendMessageAsync(message); } else { var attachment = command.Message.Attachments.First(); var request = WebRequest.CreateHttp(attachment.Url); using (var response = await request.GetResponseAsync()) using (var stream = response.GetResponseStream()) using (var memStream = new MemoryStream()) { await stream.CopyToAsync(memStream); memStream.Position = 0; await channel.SendFileAsync(memStream, attachment.Filename, message); } } if (command["TargetChannel"].AsTextChannel.Id != command.Message.Channel.Id) { await command.ReplySuccess("Message sent!" + (replaceRoleMentions ? " To mention roles, @here, or @everyone you must have the Mention Everyone permission." : "")); } }
public async Task FetchMommaJoke(CommandContext Context) { await LogHandlerService.LogUserActionAsync(Context, "Invoked mom joke."); if (!await DiscordHelpers.AttemptChargeDallarForCommand(Context, 1)) { await LogHandlerService.LogUserActionAsync(Context, "Failed charged for mom Joke"); return; } await LogHandlerService.LogUserActionAsync(Context, "Successfully charged for mom Joke"); await Context.TriggerTypingAsync(); await Context.RespondAsync($"{Context.User.Mention}: {Program.YoMommaJokes.GetRandomYoMommaJoke()}"); }
public async Task GetAccountBalance(CommandContext Context) { await Context.TriggerTypingAsync(); bool bDisplayUSD = false; // if (Program.DigitalPriceExchange.GetPriceInfo(out DigitalPriceCurrencyInfo PriceInfo, out bool bPriceStale)) // { // bDisplayUSD = true; // } if (Program.DaemonClient.GetWalletAddressFromAccount(Context.User.Id.ToString(), true, out string Wallet)) { decimal balance = Program.DaemonClient.GetRawAccountBalance(Context.User.Id.ToString()); decimal pendingBalance = Program.DaemonClient.GetUnconfirmedAccountBalance(Context.User.Id.ToString()); string pendingBalanceStr = pendingBalance != 0 ? $" with {pendingBalance} DAL Pending" : ""; string resultStr = $"{Context.User.Mention}: Your balance is {balance} DAL"; if (bDisplayUSD) { //resultStr += $" (${decimal.Round(balance * PriceInfo.USDValue.GetValueOrDefault(), 4)} USD){pendingBalanceStr}"; } else { resultStr += pendingBalanceStr; } await LogHandlerService.LogUserActionAsync(Context, $"Checked balance. {balance} DAL with {pendingBalance} DAL pending."); await Context.RespondAsync(resultStr); } else { await LogHandlerService.LogUserActionAsync(Context, $"Failed to check balance. Getting wallet address failed."); await Context.RespondAsync($"{Context.User.Mention}: Failed to check balance. Getting wallet address failed. Please contact an Administrator."); } DiscordHelpers.DeleteNonPrivateMessage(Context); }
public override async Task <TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services) { // a pepeLaughing 588362912494780417 string emoteStr = input .Replace("<", "") .Replace(">", ""); string[] emoteSplits = emoteStr.Split(':'); bool gifEmote = emoteStr.StartsWith("a:"); bool validEmoteId = ulong.TryParse(emoteSplits.LastOrDefault(), out ulong emoteId); if (!validEmoteId) { return(TypeReaderResult.FromError(CommandError.Exception, "Could not parse this Emote's ID from the provided input.")); } string emoteName = emoteSplits[1]; var result = DiscordHelpers.CreateInstance <Emote>(emoteId, emoteName, gifEmote); if (context.Guild.Emotes.FirstOrDefault(x => x.Id == emoteId) == null) { // If a user copy/pastes a msg with an emote in it instead of typing the emote, look for this emote anyway. GuildEmote emoteAltPossibility = context.Guild.Emotes.FirstOrDefault(x => x.Name == emoteName); if (emoteAltPossibility == null) { return(TypeReaderResult.FromError(CommandError.ObjectNotFound, "The current guild does not contain this emote.")); } return(TypeReaderResult.FromSuccess(emoteAltPossibility)); } return(TypeReaderResult.FromSuccess(result)); }
public async Task FetchDadJoke(CommandContext Context) { await LogHandlerService.LogUserActionAsync(Context, "Invoked Dad Joke"); if (!await DiscordHelpers.AttemptChargeDallarForCommand(Context, 1)) { await LogHandlerService.LogUserActionAsync(Context, "Failed charged for dad Joke"); return; } await LogHandlerService.LogUserActionAsync(Context, "Successfully charged for dad Joke"); await Context.TriggerTypingAsync(); var client = new WebClient(); client.Headers.Add("Accept", "text/plain"); var joke = await client.DownloadStringTaskAsync("https://icanhazdadjoke.com/"); await Context.RespondAsync($"{Context.User.Mention} : {joke}"); }
public async Task DallarValueInfo(CommandContext Context, [Description("Optional amount of DAL to covert to BTC and USD, default is 1")] params decimal[] Amount) { await Context.TriggerTypingAsync(); decimal ParsedAmount = 1m; if (Amount.Length > 0) { ParsedAmount = Amount[0]; } await LogHandlerService.LogUserActionAsync(Context, $"Invoked DAL command with amount {ParsedAmount}."); if (true)//!Program.DigitalPriceExchange.GetPriceInfo(out DigitalPriceCurrencyInfo PriceInfo, out bool bPriceStale)) { await DiscordHelpers.PromptUserToDeleteMessage(Context, $"{Context.User.Mention}: It appears that Dallar Bot is unable to evaluate the price of Dallar at the moment. Perhaps an exchange is down?"); return; } // float.TryParse(PriceInfo.PriceChange.TrimEnd('%'), out float PercentChange); // string ChangeEmoji = PercentChange >= 0.0f ? ":chart_with_upwards_trend:" : ":chart_with_downwards_trend:"; // decimal UsdValue = PriceInfo.USDValue.GetValueOrDefault(); // var Info = $"{ParsedAmount} DAL to BTC: {decimal.Round((PriceInfo.Price * ParsedAmount), 8, MidpointRounding.AwayFromZero):F8} BTC" + Environment.NewLine + // $"{ParsedAmount} DAL to USD: ${UsdValue * ParsedAmount} :dollar:" + Environment.NewLine + // $"24 Hour Stats: :arrow_down_small: {decimal.Round((PriceInfo.Low.GetValueOrDefault() * 100000000.0m), 0, MidpointRounding.AwayFromZero)} sats / :arrow_up_small: {decimal.Round((PriceInfo.High.GetValueOrDefault() * 100000000.0m), 0, MidpointRounding.AwayFromZero)} sats / :arrows_counterclockwise: {PriceInfo.VolumeMarket} BTC" + Environment.NewLine + // $"{ChangeEmoji} {PriceInfo.PriceChange} Change in 24 Hours"; // if (bPriceStale) // { // Info += "\n:warning: Info potentially out of date due to Exchange API lag."; // } //await DiscordHelpers.PromptUserToDeleteMessage(Context, $"{Context.User.Mention}: {Info}"); }
public async Task Execute(DiscordMessage message, Command command) { if (command.Args.Count != 1) { return; } var mention = command.Args[0]; var userId = DiscordHelpers.ConvertMentionToUserId(mention); if (userId == 0) { await message.RespondAsync($"{message.Author.Mention}, failed to find user {mention}."); return; } var member = await _client.GetMemberFromUserId(userId); if (member == null) { _logger.Error($"Failed to find member with user id {userId}."); return; } if (!await _client.AssignRole(member, TeamEliteRole)) { await message.RespondAsync($"{message.Author.Mention} failed to assign {mention} the {TeamEliteRole} role. Please check my permissions and that the role exists."); } if (!await _client.AssignRole(member, EastLA)) { await message.RespondAsync($"{message.Author.Mention} failed to assign {mention} the {EastLA} role. Please check my permissions and that the role exists."); } await message.RespondAsync($"{message.Author.Mention} assigned {mention} the {TeamEliteRole} and {EastLA} roles."); }
public async Task SendRandomUserInternal(CommandContext Context, decimal Amount, UserStatus MinimumStatus = UserStatus.Offline) { await Context.TriggerTypingAsync(); await LogHandlerService.LogUserActionAsync(Context, $"Invoked sending {Amount} to a random user with minimum status {MinimumStatus.ToString()}."); var Members = DiscordHelpers.GetHumansInContextGuild(Context, true, MinimumStatus); int randomIndex = Program.RandomManager.GetRandomInteger(0, Members.Count() - 1); var Member = Members.ElementAt(randomIndex); if (Member.Value != null) { await SendDallarToUserInternal(Context, Amount.ToString(), Member.Value, true); } else { // failed to get random member? await LogHandlerService.LogUserActionAsync(Context, $"Failed to get a random user from the guild."); await Context.RespondAsync($"{Context.User.Mention}: DallarBot has failed to get a random user from the guild. Please contact an Administrator."); _ = Context.Message.DeleteAsync(); } }
public async Task <DiscordEmbed> BuildPokemonMessage(PokemonData pokemon, ulong userId) { var pkmn = _db.Pokemon[pokemon.Id.ToString()]; if (pkmn == null) { _logger.Error($"Failed to lookup Pokemon '{pokemon.Id}' in database."); return(null); } var user = await _client.GetMemberFromUserId(userId); if (user == null) { _logger.Error($"Failed to get discord member object from user id {userId}."); return(null); } //var loc = Utils.GetGoogleAddress(pokemon.Latitude, pokemon.Longitude, _config.GmapsKey); var loc = _geofenceSvc.GetGeofence(new Location(pokemon.Latitude, pokemon.Longitude)); if (loc == null) { _logger.Error($"Failed to lookup city from coordinates {pokemon.Latitude},{pokemon.Longitude} {pkmn.Name} {pokemon.IV}, skipping..."); return(null); } if (!_config.CityRoles.Exists(x => string.Compare(x, loc.Name, true) == 0)) { File.AppendAllText("cities.txt", $"City: {loc.Name}\r\n"); return(null); } //if (!_client.HasRole(user, SanitizeCityName(loc.Name))) if (!_client.HasRole(user, loc.Name)) { _logger.Debug($"Skipping user {user.DisplayName} ({user.Id}) for {pkmn.Name} {pokemon.IV}, no city role '{loc.Name}'."); return(null); } var form = pokemon.Id.GetPokemonForm(pokemon.FormId); var eb = new DiscordEmbedBuilder { Title = loc == null || string.IsNullOrEmpty(loc.Name) ? "DIRECTIONS" : loc.Name, //Description = $"{pkmn.Name}{pokemon.Gender.GetPokemonGenderIcon()} {pokemon.CP}CP {pokemon.IV} Despawn: {pokemon.DespawnTime.ToLongTimeString()}", Url = string.Format(Strings.GoogleMaps, pokemon.Latitude, pokemon.Longitude), ImageUrl = string.Format(Strings.GoogleMapsStaticImage, pokemon.Latitude, pokemon.Longitude), ThumbnailUrl = string.Format(Strings.PokemonImage, pokemon.Id, Convert.ToInt32(string.IsNullOrEmpty(pokemon.FormId) ? "0" : pokemon.FormId)), Color = DiscordHelpers.BuildColor(pokemon.IV) }; if (pokemon.IV == "?") { eb.Description = $"{pkmn.Name} {form}{pokemon.Gender.GetPokemonGenderIcon()} Despawn: {pokemon.DespawnTime.ToLongTimeString()}\r\n"; } else { eb.Description = $"{pkmn.Name} {form}{pokemon.Gender.GetPokemonGenderIcon()} {pokemon.IV} L{pokemon.Level} Despawn: {pokemon.DespawnTime.ToLongTimeString()}\r\n\r\n"; eb.Description += $"**Details:** CP: {pokemon.CP} IV: {pokemon.IV} LV: {pokemon.Level}\r\n"; } eb.Description += $"**Despawn:** {pokemon.DespawnTime.ToLongTimeString()} ({pokemon.SecondsLeft.ToReadableStringNoSeconds()} left)\r\n"; if (pokemon.Attack != "?" && pokemon.Defense != "?" && pokemon.Stamina != "?") { eb.Description += $"**IV Stats:** Atk: {pokemon.Attack}/Def: {pokemon.Defense}/Sta: {pokemon.Stamina}\r\n"; } if (!string.IsNullOrEmpty(form)) { eb.Description += $"**Form:** {form}\r\n"; } if (int.TryParse(pokemon.Level, out int lvl) && lvl >= 30) { eb.Description += $":white_sun_rain_cloud: Boosted\r\n"; } var maxCp = _db.MaxCpAtLevel(pokemon.Id, 40); var maxWildCp = _db.MaxCpAtLevel(pokemon.Id, 35); eb.Description += $"**Max Wild CP:** {maxWildCp}, **Max CP:** {maxCp} \r\n"; if (pkmn.Types.Count > 0) { var types = new List <string>(); pkmn.Types.ForEach(x => { if (Strings.TypeEmojis.ContainsKey(x.Type.ToLower())) { types.Add($"{Strings.TypeEmojis[x.Type.ToLower()]} {x.Type}"); } }); eb.Description += $"**Types:** {string.Join("/", types)}\r\n"; } if (float.TryParse(pokemon.Height, out float height) && float.TryParse(pokemon.Weight, out float weight)) { var size = _db.GetSize(pokemon.Id, height, weight); eb.Description += $"**Size:** {size}\r\n"; } var fastMove = _db.Movesets.ContainsKey(pokemon.FastMove) ? _db.Movesets[pokemon.FastMove] : null; if (fastMove != null) { //var fastMoveIcon = Strings.TypeEmojis.ContainsKey(fastMove.Type.ToLower()) ? Strings.TypeEmojis[fastMove.Type.ToLower()] : fastMove.Type; eb.Description += $"**Fast Move:** {fastMove.Name} ({fastMove.Type})\r\n"; } var chargeMove = _db.Movesets.ContainsKey(pokemon.ChargeMove) ? _db.Movesets[pokemon.ChargeMove] : null; if (chargeMove != null) { //var chargeMoveIcon = Strings.TypeEmojis.ContainsKey(chargeMove.Type.ToLower()) ? Strings.TypeEmojis[chargeMove.Type.ToLower()] : chargeMove.Type; eb.Description += $"**Charge Move:** {chargeMove.Name} ({chargeMove.Type})\r\n"; } eb.Description += $"**Location:** {Math.Round(pokemon.Latitude, 5)},{Math.Round(pokemon.Longitude, 5)}"; eb.ImageUrl = string.Format(Strings.GoogleMapsStaticImage, pokemon.Latitude, pokemon.Longitude) + $"&key={_config.GmapsKey}"; eb.Footer = new DiscordEmbedBuilder.EmbedFooter { Text = $"versx | {DateTime.Now}" }; var embed = eb.Build(); return(embed); }
public async Task WithdrawFromWalletInstant(CommandContext Context, [Description("Amount of DAL to withdraw. Use 'all' for your entire balance")] string AmountStr, [Description("Dallar Wallet Address to withdraw Dallar to")] string PublicAddress) { // Make sure supplied address is a valid Dallar address if (!Program.DaemonClient.IsAddressValid(PublicAddress)) { // handle invalid public address await LogHandlerService.LogUserActionAsync(Context, $"Tried to withdraw but PublicAddress ({PublicAddress}) is invalid."); await Context.RespondAsync($"{Context.User.Mention}: Seems like you tried withdrawing Dallar to an invalid Dallar address. You supplied: {PublicAddress}"); DiscordHelpers.DeleteNonPrivateMessage(Context); return; } // Try to interpret the user's amount input as a sane value if (!DallarHelpers.TryParseUserAmountString(Context.User, AmountStr, out decimal Amount)) { // handle amount parse fail await LogHandlerService.LogUserActionAsync(Context, $"Tried to withdraw {Amount} but value could not be parsed."); await Context.RespondAsync($"{Context.User.Mention}: The amount you tried to withdraw can not be parsed as a number. You tried withdrawing {Amount} DAL."); DiscordHelpers.DeleteNonPrivateMessage(Context); return; } // Make sure Amount is greater than zero if (Amount <= 0) { await LogHandlerService.LogUserActionAsync(Context, $"Tried to withdraw {Amount} but value is invalid."); await Context.RespondAsync($"{Context.User.Mention}: You can not withdraw 0 or less Dallar. You tried withdrawing {Amount} DAL."); DiscordHelpers.DeleteNonPrivateMessage(Context); return; } // Verify user has requested balance to withdraw if (!DallarHelpers.CanUserAffordTransactionAmount(Context.User, Amount)) { // user can not afford requested withdraw amount await LogHandlerService.LogUserActionAsync(Context, $"Tried to withdraw {Amount} but has insufficient funds. ({Program.DaemonClient.GetRawAccountBalance(Context.User.Id.ToString())})"); await Context.RespondAsync($"{Context.User.Mention}: Looks like you don't have enough funds withdraw {Amount} DAL! Remember, there is a {Program.SettingsHandler.Dallar.Txfee} DAL fee for performing bot transactions."); DiscordHelpers.DeleteNonPrivateMessage(Context); return; } // Amount should be guaranteed a good value to withdraw // Fetch user's wallet if (Program.DaemonClient.GetWalletAddressFromAccount(Context.User.Id.ToString(), true, out string Wallet)) { if (Program.DaemonClient.SendMinusFees(Context.User.Id.ToString(), PublicAddress, Amount, Program.SettingsHandler.Dallar.Txfee, Program.SettingsHandler.Dallar.FeeAccount)) { // Successfully withdrew await LogHandlerService.LogUserActionAsync(Context, $"Successfully withdrew {Amount} from wallet ({Wallet})."); await Context.RespondAsync($"You have successfully withdrawn {Amount} DAL" + (Context.Member == null ? "." : $" to address {PublicAddress}.")); } else { // unable to send dallar await LogHandlerService.LogUserActionAsync(Context, $"Tried to withdraw {Amount} from wallet ({Wallet}) but daemon failed to send transaction."); await Context.RespondAsync("Something went wrong trying to send your Dallar through the Dallar daemon. (Please contact the Administrators!)"); DiscordHelpers.DeleteNonPrivateMessage(Context); return; } } else { // unable to fetch user's wallet await LogHandlerService.LogUserActionAsync(Context, $"Tried to withdraw {Amount} but bot could not determine user's wallet."); await Context.RespondAsync("Something went wrong trying to get your DallarBot Dallar Address. (Please contact the Administrators!)"); DiscordHelpers.DeleteNonPrivateMessage(Context); return; } // After withdraw success DiscordHelpers.DeleteNonPrivateMessage(Context); }
public async Task <DiscordEmbed> BuildRaidMessage(RaidData raid, ulong userId) { var pkmn = _db.Pokemon[raid.PokemonId.ToString()]; if (pkmn == null) { _logger.Error($"Failed to lookup Raid Pokemon '{raid.PokemonId}' in database."); return(null); } var user = await _client.GetMemberFromUserId(userId); if (user == null) { _logger.Error($"Failed to get discord member object from user id {userId}."); return(null); } //var loc = Utils.GetGoogleAddress(raid.Latitude, raid.Longitude, _config.GmapsKey); var loc = _geofenceSvc.GetGeofence(new Location(raid.Latitude, raid.Longitude)); if (loc == null) { _logger.Error($"Failed to lookup city for coordinates {raid.Latitude},{raid.Longitude}, skipping..."); return(null); } if (!_config.CityRoles.Exists(x => string.Compare(x, loc.Name, true) == 0)) { File.AppendAllText("cities.txt", $"City: {loc.Name}\r\n"); } if (!_client.HasRole(user, loc.Name)) { _logger.Debug($"Skipping notification for user {user.DisplayName} ({user.Id}) for Pokemon {pkmn.Name} because they do not have the city role '{loc.Name}'."); return(null); } var eb = new DiscordEmbedBuilder { Title = loc == null || string.IsNullOrEmpty(loc.Name) ? "DIRECTIONS" : loc.Name, //Description = $"{pkmn.Name} raid available until {raid.EndTime.ToLongTimeString()}!", Url = string.Format(Strings.GoogleMaps, raid.Latitude, raid.Longitude), ImageUrl = string.Format(Strings.GoogleMapsStaticImage, raid.Latitude, raid.Longitude), ThumbnailUrl = string.Format(Strings.PokemonImage, raid.PokemonId, 0), Color = DiscordHelpers.BuildRaidColor(Convert.ToInt32(raid.Level)) }; var fixedEndTime = DateTime.Parse(raid.EndTime.ToLongTimeString()); var remaining = GetTimeRemaining(fixedEndTime); eb.Description = $"{pkmn.Name} Raid Ends: {raid.EndTime.ToLongTimeString()}\r\n\r\n"; eb.Description += $"**Starts:** {raid.StartTime.ToLongTimeString()}\r\n"; eb.Description += $"**Ends:** {raid.EndTime.ToLongTimeString()} ({remaining.ToReadableStringNoSeconds()} left)\r\n"; var perfectRange = _db.GetPokemonCpRange(raid.PokemonId, 20); var boostedRange = _db.GetPokemonCpRange(raid.PokemonId, 25); eb.Description += $"**Perfect CP:** {perfectRange.Best} / :white_sun_rain_cloud: {boostedRange.Best}\r\n"; if (pkmn.Types.Count > 0) { var types = new List <string>(); pkmn.Types.ForEach(x => { if (Strings.TypeEmojis.ContainsKey(x.Type.ToLower())) { types.Add(Strings.TypeEmojis[x.Type.ToLower()] + " " + x.Type); } }); eb.Description += $"**Types:** {string.Join("/", types)}\r\n"; } var fastMove = _db.Movesets.ContainsKey(raid.FastMove) ? _db.Movesets[raid.FastMove] : null; if (fastMove != null) { eb.Description += $"**Fast Move:** {Strings.TypeEmojis[fastMove.Type.ToLower()]} {fastMove.Name}\r\n"; } var chargeMove = _db.Movesets.ContainsKey(raid.ChargeMove) ? _db.Movesets[raid.ChargeMove] : null; if (chargeMove != null) { eb.Description += $"**Charge Move:** {Strings.TypeEmojis[chargeMove.Type.ToLower()]} {chargeMove.Name}\r\n"; } var strengths = new List <string>(); var weaknesses = new List <string>(); foreach (var type in pkmn.Types) { foreach (var strength in PokemonExtensions.GetStrengths(type.Type)) { if (!strengths.Contains(strength)) { strengths.Add(strength); } } foreach (var weakness in PokemonExtensions.GetWeaknesses(type.Type)) { if (!weaknesses.Contains(weakness)) { weaknesses.Add(weakness); } } } if (strengths.Count > 0) { eb.Description += $"**Strong Against:** {string.Join(", ", strengths)}\r\n"; } if (weaknesses.Count > 0) { eb.Description += $"**Weaknesses:** {string.Join(", ", weaknesses)}\r\n"; } eb.Description += $"**Location:** {Math.Round(raid.Latitude, 5)},{Math.Round(raid.Longitude, 5)}"; eb.ImageUrl = string.Format(Strings.GoogleMapsStaticImage, raid.Latitude, raid.Longitude) + $"&key={_config.GmapsKey}"; eb.Footer = new DiscordEmbedBuilder.EmbedFooter { Text = $"versx | {DateTime.Now}" }; var embed = eb.Build(); return(embed); }
public async Task DefaultHelpAsync(CommandContext ctx, [Description("Optional command to provide help for.")] params string[] command) { // We have to use reflection because TopLevelCommands is marked private and we're not forking DSharpPlus PropertyInfo TopLevelCommandsProp = typeof(CommandsNextExtension).GetProperty("TopLevelCommands", BindingFlags.NonPublic | BindingFlags.Instance); MethodInfo TopLevelCommandsGetter = TopLevelCommandsProp.GetGetMethod(nonPublic: true); var toplevel = ((Dictionary <string, Command>)TopLevelCommandsGetter.Invoke(ctx.CommandsNext, null)).Values.Distinct(); // We instance our help formatter directly because we don't have access to the help formatting factory var helpbuilder = new HelpFormatter(ctx); if (command != null && command.Any()) { Command cmd = null; var search_in = toplevel; foreach (var c in command) { if (search_in == null) { cmd = null; break; } // We don't have access to config so f**k it, case insensitive help //if (ctx.Config.CaseSensitive) // cmd = search_in.FirstOrDefault(xc => xc.Name == c || (xc.Aliases != null && xc.Aliases.Contains(c))); //else cmd = search_in.FirstOrDefault(xc => xc.Name.ToLowerInvariant() == c.ToLowerInvariant() || (xc.Aliases != null && xc.Aliases.Select(xs => xs.ToLowerInvariant()).Contains(c.ToLowerInvariant()))); if (cmd == null) { break; } var cfl = await cmd.RunChecksAsync(ctx, true).ConfigureAwait(false); if (cfl.Any()) { throw new ChecksFailedException(cmd, ctx, cfl); } if (cmd is CommandGroup) { search_in = (cmd as CommandGroup).Children; } else { search_in = null; } } if (cmd == null) { throw new CommandNotFoundException(string.Join(" ", command)); } helpbuilder.WithCommand(cmd); if (cmd is CommandGroup gx) { var sxs = gx.Children.Where(xc => !xc.IsHidden); var scs = new List <Command>(); foreach (var sc in sxs) { if (sc.ExecutionChecks == null || !sc.ExecutionChecks.Any()) { scs.Add(sc); continue; } var cfl = await sc.RunChecksAsync(ctx, true).ConfigureAwait(false); if (!cfl.Any()) { scs.Add(sc); } } if (scs.Any()) { helpbuilder.WithSubcommands(scs.OrderBy(xc => xc.Name)); } } } else { var sxs = toplevel.Where(xc => !xc.IsHidden); var scs = new List <Command>(); foreach (var sc in sxs) { if (sc.ExecutionChecks == null || !sc.ExecutionChecks.Any()) { scs.Add(sc); continue; } var cfl = await sc.RunChecksAsync(ctx, true).ConfigureAwait(false); if (!cfl.Any()) { scs.Add(sc); } } if (scs.Any()) { helpbuilder.WithSubcommands(scs.OrderBy(xc => xc.Name)); } } var hmsg = helpbuilder.Build(); // The main reason for this change, allowing help to be DM'd and the original command deleted. DiscordHelpers.DeleteNonPrivateMessage(ctx); await DiscordHelpers.RespondAsDM(ctx, hmsg.Embed).ConfigureAwait(false); }
private void OnNotify(object state) { TaskHelper.FireForget(async() => { try { var(serverId, _) = ((ulong, int))state; if (!_notifications.TryGetValue(serverId, out var context)) { return; } using (await context.Lock.ClaimAsync()) { if (!context.ValidateCallback(state)) { return; // Old timer (can happen due to timer race conditions) } var guild = _client.GetGuild(serverId) as IGuild; if (guild == null) { _logger.LogInformation("Server {" + LogFields.GuildId + "} not found", serverId); return; } var logger = _logger.WithScope(guild); var settings = await _settings.Read <ScheduleSettings>(serverId, false); if (settings == null) { logger.LogWarning("Settings for server not found"); return; } var dueTime = context.UtcDueTime.Value.Add(settings.TimezoneOffset); var events = settings.Events.Where(x => x.Date == dueTime && x.HasTime && x.Notify); foreach (var e in events) { foreach (var s in settings.Notifications.Where(x => e.FitsTag(x.Tag))) { try { var channel = await guild.GetTextChannelAsync(s.Channel); if (channel == null) { continue; } var role = s.Role != default ? guild.GetRole(s.Role) : null; var embed = new EmbedBuilder() .WithTitle("🔔 Schedule") .WithDescription($"{(e.HasLink ? DiscordHelpers.BuildMarkdownUri(e.Description, e.Link) : e.Description)} is now on!"); await channel.SendMessageAsync(role != null ? $"{role.Mention} " : "", embed: embed.Build()); logger.LogInformation("Notified event {ScheduleEventDescription} ({ScheduleEventDate}, TZ: {ScheduleTimezone}, ID: {ScheduleEventId})", e.Description, e.Date, settings.TimezoneOffset, e.Id); } catch (Exception ex) { logger.LogError(ex, "Failed to notify event {ScheduleEventDescription} ({ScheduleEventId})", e.Description, e.Id); } } } var now = DateTime.UtcNow.Add(settings.TimezoneOffset); var next = settings.Events.SkipWhile(x => x.Date <= dueTime).FirstOrDefault(x => x.Notify && x.HasTime); if (next == default) { context.Disable(); return; } context.Replan(next.Date - now, next.Date.Subtract(settings.TimezoneOffset)); } } catch (Exception ex) { _logger.LogError(ex, "Failed to process event notifications"); } }); }