public async Task ShardStats(int page = 1) { if (page < 1) { return; } var status = string.Join(", ", NadekoBot.Client.Shards.GroupBy(x => x.ConnectionState) .Select(x => $"{x.Count()} {x.Key}") .ToArray()); var allShardStrings = NadekoBot.Client.Shards .Select(x => GetText("shard_stats_txt", x.ShardId.ToString(), Format.Bold(x.ConnectionState.ToString()), Format.Bold(x.Guilds.Count.ToString()))) .ToArray(); await Context.Channel.SendPaginatedConfirmAsync(page, (curPage) => { var str = string.Join("\n", allShardStrings.Skip(25 * (curPage - 1)).Take(25)); if (string.IsNullOrWhiteSpace(str)) { str = GetText("no_shards_on_page"); } return(new EmbedBuilder() .WithAuthor(a => a.WithName(GetText("shard_stats"))) .WithTitle(status) .WithOkColor() .WithDescription(str)); }, allShardStrings.Length / 25); }
public async Task ListQuotes(int page = 1, OrderType order = OrderType.Keyword) { page -= 1; if (page < 0) { return; } IEnumerable <Quote> quotes; using (var uow = _db.UnitOfWork) { quotes = uow.Quotes.GetGroup(Context.Guild.Id, page, order); } if (quotes.Any()) { await Context.Channel.SendConfirmAsync(GetText("quotes_page", page + 1), string.Join("\n", quotes.Select(q => $"`#{q.Id}` {Format.Bold(q.Keyword.SanitizeMentions()),-20} by {q.AuthorName.SanitizeMentions()}"))) .ConfigureAwait(false); } else { await ReplyErrorLocalized("quotes_page_none").ConfigureAwait(false); } }
public async Task Convert(string origin, string target, decimal value) { //todo why am i selecting them every time? var originUnit = _service.Units.FirstOrDefault(x => x.Triggers.Select(y => y.ToUpperInvariant()).Contains(origin.ToUpperInvariant())); var targetUnit = _service.Units.FirstOrDefault(x => x.Triggers.Select(y => y.ToUpperInvariant()).Contains(target.ToUpperInvariant())); if (originUnit == null || targetUnit == null) { await ReplyErrorLocalizedAsync("convert_not_found", Format.Bold(origin), Format.Bold(target)).ConfigureAwait(false); return; } if (originUnit.UnitType != targetUnit.UnitType) { await ReplyErrorLocalizedAsync("convert_type_error", Format.Bold(originUnit.Triggers.First()), Format.Bold(targetUnit.Triggers.First())).ConfigureAwait(false); return; } decimal res; if (originUnit.Triggers == targetUnit.Triggers) { res = value; } else if (originUnit.UnitType == "temperature") { //don't really care too much about efficiency, so just convert to Kelvin, then to target switch (originUnit.Triggers.First().ToUpperInvariant()) { case "C": res = value + 273.15m; //celcius! break; case "F": res = (value + 459.67m) * (5m / 9m); break; default: res = value; break; } //from Kelvin to target switch (targetUnit.Triggers.First().ToUpperInvariant()) { case "C": res = res - 273.15m; //celcius! break; case "F": res = res * (9m / 5m) - 459.67m; break; } } else { if (originUnit.UnitType == "currency") { res = (value * targetUnit.Modifier) / originUnit.Modifier; } else { res = (value * originUnit.Modifier) / targetUnit.Modifier; } } res = Math.Round(res, 4); await Context.Channel.SendConfirmAsync(GetText("convert", value, (originUnit.Triggers.First()).SnPl(value.IsInteger() ? (int)value : 2), res, (targetUnit.Triggers.First() + "s").SnPl(res.IsInteger() ? (int)res : 2))).ConfigureAwait(false); }
/// <summary> /// Creates a collection of <see cref="EmbedBuilder"/> objects representing historical values. /// </summary> /// <param name="historicalCurrencyValues">A collection of <see cref="WorldCurrencyResponse"/> objects.</param> /// <param name="currencyName">The currency name.</param> /// <returns>A list of embeds ready to be built.</returns> public List <EmbedBuilder> CreateHistoricalValuesEmbedsAsync(List <WorldCurrencyResponse> historicalCurrencyValues, string currencyName, DateTime?startDate, DateTime?endDate) { var emojis = Configuration.GetSection("customEmojis"); Emoji upEmoji = new(emojis["arrowUpRed"]); Emoji downEmoji = new(emojis["arrowDownGreen"]); Emoji neutralEmoji = new(emojis["neutral"]); Emoji calendarEmoji = new(":calendar_spiral:"); string chartImageUrl = Configuration.GetSection("images").GetSection("chart")["64"]; int pageCount = 0; int totalPages = (int)Math.Ceiling(Convert.ToDecimal(historicalCurrencyValues.Count) / HISTORICAL_DATES_PER_PAGE); List <IEnumerable <WorldCurrencyResponse> > historicalCurrencyValuesPages = historicalCurrencyValues.ChunkBy(HISTORICAL_DATES_PER_PAGE); if (!startDate.HasValue) { startDate = historicalCurrencyValues.First().Fecha.Date; } if (!endDate.HasValue || endDate.Value.Date > DateTime.Now.Date) { endDate = DateTime.Now.Date; } bool isSingleDate = startDate.Value.Date == endDate.Value.Date; List <EmbedBuilder> embeds = new(); for (int i = 0; i < historicalCurrencyValuesPages.Count; i++) { IEnumerable <WorldCurrencyResponse> page = historicalCurrencyValuesPages.ElementAt(i); StringBuilder sbField = new(); for (int j = 0; j < page.Count(); j++) { WorldCurrencyResponse currencyValue = page.ElementAt(j); bool rateIsNumeric = decimal.TryParse(currencyValue.Valor, NumberStyles.Any, DolarBotApiService.GetApiCulture(), out decimal currencyRate); Emoji fieldEmoji = isSingleDate ? calendarEmoji : neutralEmoji; if (i > 0 || j > 0) { WorldCurrencyResponse previousCurrencyValue = j > 0 ? page.ElementAt(j - 1) : historicalCurrencyValuesPages.ElementAt(i - 1).Last(); bool previousValueIsNumeric = decimal.TryParse(previousCurrencyValue.Valor, NumberStyles.Any, DolarBotApiService.GetApiCulture(), out decimal previousRate); if (rateIsNumeric && previousValueIsNumeric) { if (currencyRate >= previousRate) { fieldEmoji = currencyRate > previousRate ? upEmoji : neutralEmoji; } else { fieldEmoji = downEmoji; } } } string fieldText = $"{fieldEmoji} {Format.Code(currencyValue.Fecha.ToString("dd/MM/yyyy"))}: {Format.Bold($"$ {currencyRate}")}"; sbField = sbField.AppendLine(fieldText); } string worldCurrencyCode = historicalCurrencyValues.First().Code; string embedTitle = isSingleDate ? "Cotización por fecha" : "Cotizaciones por Fecha"; string embedDescription = $"{(isSingleDate ? "Cotización oficial" : "Cotizaciones oficiales")} de {Format.Bold($"{currencyName} ({worldCurrencyCode})")} {(isSingleDate ? $"para el día {Format.Code(startDate.Value.Date.ToString("dd/MM/yyyy"))}" : $"entre el {Format.Code(startDate.Value.Date.ToString("dd/MM/yyyy"))} y el {Format.Code(endDate.Value.Date.ToString("dd/MM/yyyy"))}")}, expresada en {Format.Bold("pesos argentinos")}.".AppendLineBreak(); EmbedBuilder embed = new EmbedBuilder().WithColor(GlobalConfiguration.Colors.Currency) .WithTitle($"{currencyName} ({worldCurrencyCode})") .WithDescription(embedDescription) .WithThumbnailUrl(chartImageUrl) .WithFooter($"Página {++pageCount} de {totalPages}") .AddField(embedTitle, sbField.AppendLineBreak().ToString()); embeds.Add(embed); } return(embeds); }
public async Task Connect4(params string[] args) { var(options, _) = OptionsParser.ParseFrom(new Connect4Game.Options(), args); if (!await CheckBetOptional(options.Bet).ConfigureAwait(false)) { return; } var newGame = new Connect4Game(ctx.User.Id, ctx.User.ToString(), options, _cs); Connect4Game game; if ((game = _service.Connect4Games.GetOrAdd(ctx.Channel.Id, newGame)) != newGame) { if (game.CurrentPhase != Connect4Game.Phase.Joining) { return; } newGame.Dispose(); //means game already exists, try to join var joined = await game.Join(ctx.User.Id, ctx.User.ToString(), options.Bet).ConfigureAwait(false); return; } if (options.Bet > 0) { if (!await _cs.RemoveAsync(ctx.User.Id, "Connect4-bet", options.Bet, true).ConfigureAwait(false)) { await ReplyErrorLocalizedAsync("not_enough", CurrencySign).ConfigureAwait(false); _service.Connect4Games.TryRemove(ctx.Channel.Id, out _); game.Dispose(); return; } } game.OnGameStateUpdated += Game_OnGameStateUpdated; game.OnGameFailedToStart += Game_OnGameFailedToStart; game.OnGameEnded += Game_OnGameEnded; _client.MessageReceived += _client_MessageReceived; game.Initialize(); if (options.Bet == 0) { await ReplyConfirmLocalizedAsync("connect4_created").ConfigureAwait(false); } else { await ReplyConfirmLocalizedAsync("connect4_created_bet", options.Bet + CurrencySign).ConfigureAwait(false); } Task _client_MessageReceived(SocketMessage arg) { if (ctx.Channel.Id != arg.Channel.Id) { return(Task.CompletedTask); } var _ = Task.Run(async() => { bool success = false; if (int.TryParse(arg.Content, out var col)) { success = await game.Input(arg.Author.Id, col).ConfigureAwait(false); } if (success) { try { await arg.DeleteAsync().ConfigureAwait(false); } catch { } } else { if (game.CurrentPhase == Connect4Game.Phase.Joining || game.CurrentPhase == Connect4Game.Phase.Ended) { return; } RepostCounter++; if (RepostCounter == 0) { try { msg = await ctx.Channel.SendMessageAsync("", embed: (Embed)msg.Embeds.First()).ConfigureAwait(false); } catch { } } } }); return(Task.CompletedTask); } Task Game_OnGameFailedToStart(Connect4Game arg) { if (_service.Connect4Games.TryRemove(ctx.Channel.Id, out var toDispose)) { _client.MessageReceived -= _client_MessageReceived; toDispose.Dispose(); } return(ErrorLocalizedAsync("connect4_failed_to_start")); } Task Game_OnGameEnded(Connect4Game arg, Connect4Game.Result result) { if (_service.Connect4Games.TryRemove(ctx.Channel.Id, out var toDispose)) { _client.MessageReceived -= _client_MessageReceived; toDispose.Dispose(); } string title; if (result == Connect4Game.Result.CurrentPlayerWon) { title = GetText("connect4_won", Format.Bold(arg.CurrentPlayer.Username), Format.Bold(arg.OtherPlayer.Username)); } else if (result == Connect4Game.Result.OtherPlayerWon) { title = GetText("connect4_won", Format.Bold(arg.OtherPlayer.Username), Format.Bold(arg.CurrentPlayer.Username)); } else { title = GetText("connect4_draw"); } return(msg.ModifyAsync(x => x.Embed = new EmbedBuilder() .WithTitle(title) .WithDescription(GetGameStateText(game)) .WithOkColor() .Build())); } }
public async Task WaifuClaimerAffinity([Remainder] IGuildUser u = null) { if (u?.Id == Context.User.Id) { await ReplyErrorLocalized("waifu_egomaniac").ConfigureAwait(false); return; } DiscordUser oldAff = null; var sucess = false; var cooldown = false; var difference = TimeSpan.Zero; using (var uow = _db.UnitOfWork) { var w = uow.Waifus.ByWaifuUserId(Context.User.Id); var newAff = u == null ? null : uow.DiscordUsers.GetOrCreate(u); var now = DateTime.UtcNow; if (w?.Affinity?.UserId == u?.Id) { } else if (_service.AffinityCooldowns.AddOrUpdate(Context.User.Id, now, (key, old) => ((difference = now.Subtract(old)) > _affinityLimit) ? now : old) != now) { cooldown = true; } else if (w == null) { var thisUser = uow.DiscordUsers.GetOrCreate(Context.User); uow.Waifus.Add(new WaifuInfo() { Affinity = newAff, Waifu = thisUser, Price = 1, Claimer = null }); sucess = true; uow._context.WaifuUpdates.Add(new WaifuUpdate() { User = thisUser, Old = null, New = newAff, UpdateType = WaifuUpdateType.AffinityChanged }); } else { if (w.Affinity != null) { oldAff = w.Affinity; } w.Affinity = newAff; sucess = true; uow._context.WaifuUpdates.Add(new WaifuUpdate() { User = w.Waifu, Old = oldAff, New = newAff, UpdateType = WaifuUpdateType.AffinityChanged }); } await uow.CompleteAsync().ConfigureAwait(false); } if (!sucess) { if (cooldown) { var remaining = _affinityLimit.Subtract(difference); await ReplyErrorLocalized("waifu_affinity_cooldown", Format.Bold(((int)remaining.TotalHours).ToString()), Format.Bold(remaining.Minutes.ToString())).ConfigureAwait(false); } else { await ReplyErrorLocalized("waifu_affinity_already").ConfigureAwait(false); } return; } if (u == null) { await ReplyConfirmLocalized("waifu_affinity_reset").ConfigureAwait(false); } else if (oldAff == null) { await ReplyConfirmLocalized("waifu_affinity_set", Format.Bold(u.ToString())).ConfigureAwait(false); } else { await ReplyConfirmLocalized("waifu_affinity_changed", Format.Bold(oldAff.ToString()), Format.Bold(u.ToString())).ConfigureAwait(false); } }
public async Task WaifuClaim(int amount, [Remainder] IUser target) { if (amount < 50) { await ReplyErrorLocalized("waifu_isnt_cheap", 50 + _bc.BotConfig.CurrencySign).ConfigureAwait(false); return; } if (target.Id == Context.User.Id) { await ReplyErrorLocalized("waifu_not_yourself").ConfigureAwait(false); return; } WaifuClaimResult result; WaifuInfo w; bool isAffinity; using (var uow = _db.UnitOfWork) { w = uow.Waifus.ByWaifuUserId(target.Id); isAffinity = (w?.Affinity?.UserId == Context.User.Id); if (w == null) { var claimer = uow.DiscordUsers.GetOrCreate(Context.User); var waifu = uow.DiscordUsers.GetOrCreate(target); if (!await _cs.RemoveAsync(Context.User.Id, "Claimed Waifu", amount, uow).ConfigureAwait(false)) { result = WaifuClaimResult.NotEnoughFunds; } else { uow.Waifus.Add(w = new WaifuInfo() { Waifu = waifu, Claimer = claimer, Affinity = null, Price = amount }); uow._context.WaifuUpdates.Add(new WaifuUpdate() { User = waifu, Old = null, New = claimer, UpdateType = WaifuUpdateType.Claimed }); result = WaifuClaimResult.Success; } } else if (isAffinity && amount > w.Price * 0.88f) { if (!await _cs.RemoveAsync(Context.User.Id, "Claimed Waifu", amount, uow).ConfigureAwait(false)) { result = WaifuClaimResult.NotEnoughFunds; } else { var oldClaimer = w.Claimer; w.Claimer = uow.DiscordUsers.GetOrCreate(Context.User); w.Price = amount + (amount / 4); result = WaifuClaimResult.Success; uow._context.WaifuUpdates.Add(new WaifuUpdate() { User = w.Waifu, Old = oldClaimer, New = w.Claimer, UpdateType = WaifuUpdateType.Claimed }); } } else if (amount >= w.Price * 1.1f) // if no affinity { if (!await _cs.RemoveAsync(Context.User.Id, "Claimed Waifu", amount, uow).ConfigureAwait(false)) { result = WaifuClaimResult.NotEnoughFunds; } else { var oldClaimer = w.Claimer; w.Claimer = uow.DiscordUsers.GetOrCreate(Context.User); w.Price = amount; result = WaifuClaimResult.Success; uow._context.WaifuUpdates.Add(new WaifuUpdate() { User = w.Waifu, Old = oldClaimer, New = w.Claimer, UpdateType = WaifuUpdateType.Claimed }); } } else { result = WaifuClaimResult.InsufficientAmount; } await uow.CompleteAsync().ConfigureAwait(false); } if (result == WaifuClaimResult.InsufficientAmount) { await ReplyErrorLocalized("waifu_not_enough", Math.Ceiling(w.Price * (isAffinity ? 0.88f : 1.1f))).ConfigureAwait(false); return; } if (result == WaifuClaimResult.NotEnoughFunds) { await ReplyErrorLocalized("not_enough", _bc.BotConfig.CurrencySign).ConfigureAwait(false); return; } var msg = GetText("waifu_claimed", Format.Bold(target.ToString()), amount + _bc.BotConfig.CurrencySign); if (w.Affinity?.UserId == Context.User.Id) { msg += "\n" + GetText("waifu_fulfilled", target, w.Price + _bc.BotConfig.CurrencySign); } else { msg = " " + msg; } await Context.Channel.SendConfirmAsync(Context.User.Mention + msg).ConfigureAwait(false); }
public async Task DelTxtChanl([Remainder] ITextChannel toDelete) { await toDelete.DeleteAsync().ConfigureAwait(false); await ReplyConfirmLocalized("deltextchan", Format.Bold(toDelete.Name)).ConfigureAwait(false); }
public async Task CreaTxtChanl([Remainder] string channelName) { var txtCh = await Context.Guild.CreateTextChannelAsync(channelName).ConfigureAwait(false); await ReplyConfirmLocalized("createtextchan", Format.Bold(txtCh.Name)).ConfigureAwait(false); }
public async Task DelVoiChanl([Remainder] IVoiceChannel voiceChannel) { await voiceChannel.DeleteAsync().ConfigureAwait(false); await ReplyConfirmLocalized("delvoich", Format.Bold(voiceChannel.Name)).ConfigureAwait(false); }
public async Task CreatVoiChanl([Remainder] string channelName) { var ch = await Context.Guild.CreateVoiceChannelAsync(channelName).ConfigureAwait(false); await ReplyConfirmLocalized("createvoich", Format.Bold(ch.Name)).ConfigureAwait(false); }
public async Task RoleHoist(IRole role) { await role.ModifyAsync(r => r.Hoist = !role.IsHoisted).ConfigureAwait(false); await ReplyConfirmLocalized("rh", Format.Bold(role.Name), Format.Bold(role.IsHoisted.ToString())).ConfigureAwait(false); }
public async Task Divorce([Remainder] ulong targetId) { if (targetId == Context.User.Id) { return; } DivorceResult result; TimeSpan? remaining = null; var amount = 0; WaifuInfo w = null; using (var uow = _db.UnitOfWork) { w = uow.Waifus.ByWaifuUserId(targetId); var now = DateTime.UtcNow; if (w?.Claimer == null || w.Claimer.UserId != Context.User.Id) { result = DivorceResult.NotYourWife; } else if (!_cache.TryAddDivorceCooldown(Context.User.Id, out remaining)) { result = DivorceResult.Cooldown; } else { amount = w.Price / 2; if (w.Affinity?.UserId == Context.User.Id) { await _cs.AddAsync(w.Waifu.UserId, "Waifu Compensation", amount, gamble : true).ConfigureAwait(false); w.Price = (int)Math.Floor(w.Price * 0.75f); result = DivorceResult.SucessWithPenalty; } else { await _cs.AddAsync(Context.User.Id, "Waifu Refund", amount, gamble : true).ConfigureAwait(false); result = DivorceResult.Success; } var oldClaimer = w.Claimer; w.Claimer = null; uow._context.WaifuUpdates.Add(new WaifuUpdate() { User = w.Waifu, Old = oldClaimer, New = null, UpdateType = WaifuUpdateType.Claimed }); } await uow.CompleteAsync().ConfigureAwait(false); } if (result == DivorceResult.SucessWithPenalty) { await ReplyConfirmLocalized("waifu_divorced_like", Format.Bold(w.Waifu.ToString()), amount + Bc.BotConfig.CurrencySign).ConfigureAwait(false); } else if (result == DivorceResult.Success) { await ReplyConfirmLocalized("waifu_divorced_notlike", amount + Bc.BotConfig.CurrencySign).ConfigureAwait(false); } else if (result == DivorceResult.NotYourWife) { await ReplyErrorLocalized("waifu_not_yours").ConfigureAwait(false); } else { await ReplyErrorLocalized("waifu_recent_divorce", Format.Bold(((int)remaining?.TotalHours).ToString()), Format.Bold(remaining?.Minutes.ToString())).ConfigureAwait(false); } }
public async Task Flip(int count = 1) { if (count == 1) { var coins = _images.ImageUrls.Coins; if (rng.Next(0, 2) == 1) { await Context.Channel.EmbedAsync(new EmbedBuilder() .WithOkColor() .WithImageUrl(coins.Heads[rng.Next(0, coins.Heads.Length)]) .WithDescription(Context.User.Mention + " " + GetText("flipped", Format.Bold(GetText("heads"))))); } else { await Context.Channel.EmbedAsync(new EmbedBuilder() .WithOkColor() .WithImageUrl(coins.Tails[rng.Next(0, coins.Tails.Length)]) .WithDescription(Context.User.Mention + " " + GetText("flipped", Format.Bold(GetText("tails"))))); } return; } if (count > 10 || count < 1) { await ReplyErrorLocalized("flip_invalid", 10).ConfigureAwait(false); return; } var imgs = new Image <Rgba32> [count]; for (var i = 0; i < count; i++) { using (var heads = _images.Heads[rng.Next(0, _images.Heads.Length)].ToStream()) using (var tails = _images.Tails[rng.Next(0, _images.Tails.Length)].ToStream()) { if (rng.Next(0, 10) < 5) { imgs[i] = Image.Load(heads); } else { imgs[i] = Image.Load(tails); } } } await Context.Channel.SendFileAsync(imgs.Merge().ToStream(), $"{count} coins.png").ConfigureAwait(false); }
public async Task Give(long amount, [Remainder] IGuildUser receiver) { if (amount > 0) { if (Context.User.Id != receiver.Id) { var reason = $"Gift to {receiver.Username} ({receiver.Id})."; if (await _currency.RemoveAsync((IGuildUser)Context.User, reason, amount).ConfigureAwait(false)) { await _currency.AddAsync(receiver, $"Gift from {Context.User.Username} ({Context.User.Id}).", amount).ConfigureAwait(false); await ReplyConfirmLocalized("gifted", $"{amount}{CurrencySign}", Format.Bold(receiver.ToString())).ConfigureAwait(false); try { await receiver.SendConfirmAsync($"`You received:` {amount}{CurrencySign} on Server with ID {receiver.GuildId}.\n`Reason:` {reason}").ConfigureAwait(false); } catch { } } else { await ReplyErrorLocalized("not_enough", CurrencyPluralName).ConfigureAwait(false); } } else { // FIXME: Use translations. await Context.Channel.SendMessageAsync("Geld kann man nicht an sich selbst verschenken!"); } } else { // FIXME: Use translations. await Context.Channel.SendMessageAsync($"Geldbeträge von 0{CurrencySign} oder weniger können nicht verschenkt werden!"); } }
public async Task SetNick(IGuildUser gu, [Remainder] string newNick = null) { await gu.ModifyAsync(u => u.Nickname = newNick).ConfigureAwait(false); await ReplyConfirmLocalizedAsync("user_nick", Format.Bold(gu.ToString()), Format.Bold(newNick) ?? "-").ConfigureAwait(false); }
public async Task Divorce([Remainder] ulong targetId) { if (targetId == Context.User.Id) { return; } DivorceResult result; var difference = TimeSpan.Zero; var amount = 0; WaifuInfo w = null; using (var uow = _db.UnitOfWork) { w = uow.Waifus.ByWaifuUserId(targetId); var now = DateTime.UtcNow; if (w?.Claimer == null || w.Claimer.UserId != Context.User.Id) { result = DivorceResult.NotYourWife; } else if (_service.DivorceCooldowns.AddOrUpdate(Context.User.Id, now, (key, old) => ((difference = now.Subtract(old)) > _divorceLimit) ? now : old) != now) { result = DivorceResult.Cooldown; } else { amount = w.Price / 2; if (w.Affinity?.UserId == Context.User.Id) { await _cs.AddAsync(w.Waifu.UserId, "Waifu Compensation", amount, uow).ConfigureAwait(false); w.Price = (int)Math.Floor(w.Price * 0.75f); result = DivorceResult.SucessWithPenalty; } else { await _cs.AddAsync(Context.User.Id, "Waifu Refund", amount, uow).ConfigureAwait(false); result = DivorceResult.Success; } var oldClaimer = w.Claimer; w.Claimer = null; uow._context.WaifuUpdates.Add(new WaifuUpdate() { User = w.Waifu, Old = oldClaimer, New = null, UpdateType = WaifuUpdateType.Claimed }); } await uow.CompleteAsync().ConfigureAwait(false); } if (result == DivorceResult.SucessWithPenalty) { await ReplyConfirmLocalized("waifu_divorced_like", Format.Bold(w.Waifu.ToString()), amount + _bc.BotConfig.CurrencySign).ConfigureAwait(false); } else if (result == DivorceResult.Success) { await ReplyConfirmLocalized("waifu_divorced_notlike", amount + _bc.BotConfig.CurrencySign).ConfigureAwait(false); } else if (result == DivorceResult.NotYourWife) { await ReplyErrorLocalized("waifu_not_yours").ConfigureAwait(false); } else { var remaining = _divorceLimit.Subtract(difference); await ReplyErrorLocalized("waifu_recent_divorce", Format.Bold(((int)remaining.TotalHours).ToString()), Format.Bold(remaining.Minutes.ToString())).ConfigureAwait(false); } }
public async Task SetStatus([Remainder] SettableUserStatus status) { await _client.SetStatusAsync(SettableUserStatusToUserStatus(status)).ConfigureAwait(false); await ReplyConfirmLocalizedAsync("bot_status", Format.Bold(status.ToString())).ConfigureAwait(false); }
public async Task WaifuGift(WaifuItem.ItemName item, [Remainder] IUser waifu) { if (waifu.Id == Context.User.Id) { return; } var itemObj = WaifuItem.GetItem(item); using (var uow = _db.UnitOfWork) { var w = uow.Waifus.ByWaifuUserId(waifu.Id); //try to buy the item first if (!await _cs.RemoveAsync(Context.User.Id, "Bought waifu item", itemObj.Price, uow)) { await ReplyErrorLocalized("not_enough", _bc.BotConfig.CurrencySign).ConfigureAwait(false); return; } if (w == null) { uow.Waifus.Add(w = new WaifuInfo() { Affinity = null, Claimer = null, Price = 1, Waifu = uow.DiscordUsers.GetOrCreate(waifu), }); w.Waifu.Username = waifu.Username; w.Waifu.Discriminator = waifu.Discriminator; } w.Items.Add(itemObj); if (w.Claimer?.UserId == Context.User.Id) { w.Price += itemObj.Price; } else { w.Price += itemObj.Price / 2; } await uow.CompleteAsync().ConfigureAwait(false); } await ReplyConfirmLocalized("waifu_gift", Format.Bold(item.ToString() + " " + itemObj.ItemEmoji), Format.Bold(waifu.ToString())).ConfigureAwait(false); }
static string FormatUnixArgs(KeyValuePair <string[], string> kvp) => $"{Format.Bold(kvp.Key.Select(name => $"-{name}").Join(" or "))}: {kvp.Value}";
/// <summary> /// Creates a collection of <see cref="EmbedBuilder"/> objects representing a list of currency codes. /// </summary> /// <param name="currenciesList">A collection of <see cref="WorldCurrencyCodeResponse"/> objects.</param> /// <param name="currencyCommand">The executing currency command.</param> /// <param name="username">The executing user name.</param> /// <param name="interactive">Indicates whether the embed message allows interactivity.</param> /// <returns>A list of embeds ready to be built.</returns> public List <EmbedBuilder> CreateWorldCurrencyListEmbedAsync(List <WorldCurrencyCodeResponse> currenciesList, string currencyCommand, string username, bool interactive = false) { int replyTimeout = Convert.ToInt32(Configuration["interactiveMessageReplyTimeout"]); Emoji coinEmoji = new(":coin:"); string coinsImageUrl = Configuration.GetSection("images").GetSection("coins")["64"]; TimeZoneInfo localTimeZone = GlobalConfiguration.GetLocalTimeZoneInfo(); int pageCount = 0; int totalPages = (int)Math.Ceiling(Convert.ToDecimal(currenciesList.Count) / CURRENCIES_PER_PAGE); List <IEnumerable <WorldCurrencyCodeResponse> > currenciesListPages = currenciesList.ChunkBy(CURRENCIES_PER_PAGE); List <EmbedBuilder> embeds = new(); foreach (IEnumerable <WorldCurrencyCodeResponse> currenciesPage in currenciesListPages) { string currencyList = string.Join(Environment.NewLine, currenciesPage.Select(x => $"{coinEmoji} {Format.Code(x.Code)}: {Format.Italics(x.Name)}.")); EmbedBuilder embed = new EmbedBuilder() .WithColor(GlobalConfiguration.Colors.Currency) .WithThumbnailUrl(coinsImageUrl) .WithTitle("Monedas del mundo disponibles") .WithDescription($"Códigos de monedas disponibles para utilizar como parámetro del comando {Format.Code($"/{currencyCommand}")}.") .WithFooter($"Página {++pageCount} de {totalPages}") .AddField(GlobalConfiguration.Constants.BLANK_SPACE, currencyList); if (interactive) { embed.AddField(GlobalConfiguration.Constants.BLANK_SPACE, $"{Format.Bold(username)}, para ver una cotización, respondé a este mensaje antes de las {Format.Bold(TimeZoneInfo.ConvertTime(DateTime.Now.AddSeconds(replyTimeout), localTimeZone).ToString("HH:mm:ss"))} con el {Format.Bold("código de 3 dígitos")} de la moneda.{Environment.NewLine}Por ejemplo: {Format.Code(currenciesList.First().Code)}.") .AddField(GlobalConfiguration.Constants.BLANK_SPACE, $"{Format.Bold("Tip")}: {Format.Italics("Si ya sabés el código de la moneda, podés indicárselo al comando directamente, por ejemplo:")} {Format.Code($"/{currencyCommand} {currenciesList.First().Code}")}."); } else { embed.AddField(GlobalConfiguration.Constants.BLANK_SPACE, $"{Format.Bold("Tip")}: {Format.Italics("Para ver una cotización, indica el código de la moneda. Por ejemplo:")} {Format.Code($"/{currencyCommand} {currenciesList.First().Code}")}."); } embeds.Add(embed); } return(embeds); }
private async Task InternallDndRoll(string arg, bool ordered) { Match match; int n1; int n2; if ((match = fudgeRegex.Match(arg)).Length != 0 && int.TryParse(match.Groups["n1"].ToString(), out n1) && n1 > 0 && n1 < 500) { var rng = new NadekoRandom(); var rolls = new List <char>(); for (int i = 0; i < n1; i++) { rolls.Add(_fateRolls[rng.Next(0, _fateRolls.Length)]); } var embed = new EmbedBuilder().WithOkColor().WithDescription(Context.User.Mention + " " + GetText("dice_rolled_num", Format.Bold(n1.ToString()))) .AddField(efb => efb.WithName(Format.Bold("Result")) .WithValue(string.Join(" ", rolls.Select(c => Format.Code($"[{c}]"))))); await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); } else if ((match = dndRegex.Match(arg)).Length != 0) { var rng = new NadekoRandom(); if (int.TryParse(match.Groups["n1"].ToString(), out n1) && int.TryParse(match.Groups["n2"].ToString(), out n2) && n1 <= 50 && n2 <= 100000 && n1 > 0 && n2 > 0) { var add = 0; var sub = 0; int.TryParse(match.Groups["add"].Value, out add); int.TryParse(match.Groups["sub"].Value, out sub); var arr = new int[n1]; for (int i = 0; i < n1; i++) { arr[i] = rng.Next(1, n2 + 1); } var sum = arr.Sum(); var embed = new EmbedBuilder().WithOkColor().WithDescription(Context.User.Mention + " " + GetText("dice_rolled_num", n1) + $"`1 - {n2}`") .AddField(efb => efb.WithName(Format.Bold("Rolls")) .WithValue(string.Join(" ", (ordered ? arr.OrderBy(x => x).AsEnumerable() : arr).Select(x => Format.Code(x.ToString()))))) .AddField(efb => efb.WithName(Format.Bold("Sum")) .WithValue(sum + " + " + add + " - " + sub + " = " + (sum + add - sub))); await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); } } }
/// <summary> /// Creates an <see cref="EmbedBuilder"/> object for a <see cref="WorldCurrencyResponse"/>. /// </summary> /// <param name="worldCurrencyResponse">The world currency response.</param> /// <param name="currencyName">The currency name.</param> /// <param name="amount">The amount to rate against.</param> /// <returns>An <see cref="EmbedBuilder"/> object ready to be built.</returns> public async Task <EmbedBuilder> CreateWorldCurrencyEmbedAsync(WorldCurrencyResponse worldCurrencyResponse, string currencyName, decimal amount = 1) { var emojis = Configuration.GetSection("customEmojis"); Emoji currencyEmoji = Emoji.Parse(":flag_ar:"); Emoji whatsappEmoji = new(emojis["whatsapp"]); Emoji amountEmoji = Emoji.Parse(":moneybag:"); string currencyImageUrl = Configuration.GetSection("images").GetSection("coins")["64"]; string footerImageUrl = Configuration.GetSection("images").GetSection("clock")["32"]; string blankSpace = GlobalConfiguration.Constants.BLANK_SPACE; TimeZoneInfo localTimeZone = GlobalConfiguration.GetLocalTimeZoneInfo(); int utcOffset = localTimeZone.GetUtcOffset(DateTime.UtcNow).Hours; string lastUpdated = worldCurrencyResponse.Fecha.ToString(worldCurrencyResponse.Fecha.Date == TimeZoneInfo.ConvertTime(DateTime.UtcNow, localTimeZone).Date ? "HH:mm" : "dd/MM/yyyy - HH:mm"); string amountField = Format.Bold($"{amountEmoji} {blankSpace} {amount} {worldCurrencyResponse.Code}"); decimal?valuePrice = decimal.TryParse(worldCurrencyResponse?.Valor, NumberStyles.Any, DolarBotApiService.GetApiCulture(), out decimal v) ? v * amount : null; string value = valuePrice.HasValue ? valuePrice.Value.ToString("N2", GlobalConfiguration.GetLocalCultureInfo()) : "?"; string shareText = $"*{currencyName} ({worldCurrencyResponse.Code})*{Environment.NewLine}{Environment.NewLine}*{amount} {worldCurrencyResponse.Code}*{Environment.NewLine}Valor: \t$ *{value}*{Environment.NewLine}Hora: \t{lastUpdated} (UTC {utcOffset})"; EmbedBuilder embed = new EmbedBuilder().WithColor(GlobalConfiguration.Colors.Currency) .WithTitle($"{currencyName} ({worldCurrencyResponse.Code})") .WithDescription($"Cotización de {Format.Bold($"{currencyName} ({worldCurrencyResponse.Code})")} expresada en {Format.Bold("pesos argentinos")}.".AppendLineBreak()) .WithThumbnailUrl(currencyImageUrl) .WithFooter(new EmbedFooterBuilder() { Text = $"Ultima actualización: {lastUpdated} (UTC {utcOffset})", IconUrl = footerImageUrl }) .AddInlineField("Monto", amountField) .AddInlineField($"Valor", $"{Format.Bold($"{currencyEmoji} ${blankSpace} {value.AppendLineBreak()}")}"); await embed.AddFieldWhatsAppShare(whatsappEmoji, shareText, Api.Cuttly.ShortenUrl); return(embed.AddPlayStoreLink(Configuration)); }
public async Task Run() { try { var cancelToken = _client.CancelToken; StringBuilder builder = new StringBuilder(); StatusResult content; while (!_client.CancelToken.IsCancellationRequested) { //Wait 1 minute between full updates await Task.Delay(60000, cancelToken); //Get all current and recent incidents try { content = await _client.StatusAPI.Send(new GetAllIncidentsRequest()); } catch (Exception) { _client.Log.Warning("Status", $"Unable to get Discord's current status."); continue; } foreach (var pair in _settings.AllServers) { DateTimeOffset?newDate = null; builder.Clear(); var settings = pair.Value; var channelId = pair.Value.Channel; //Go through all incidents and see if any were updated since our last loop foreach (var incident in content.Incidents) { var date = incident.UpdatedAt; if (date > settings.LastUpdate) { if (channelId.HasValue) { if (builder.Length != 0) { builder.AppendLine(); } builder.AppendLine(Format.Bold(incident.Name)); builder.AppendLine($"{incident.Status}: {incident.Updates.OrderByDescending(x => x.UpdatedAt).First().Body}"); } if (newDate == null || date > newDate.Value) { newDate = date; } } } if (newDate != null) //Was anything new found? { //Announce if a channel is registered if (channelId.HasValue) { var channel = _client.GetChannel(channelId.Value); if (channel != null) { try { await channel.SendMessage(builder.ToString()); } catch (Exception) { } } } //Update LastUpdated settings.LastUpdate = newDate.Value; await _settings.Save(pair.Key, settings); } } } } catch (TaskCanceledException) { } }
public async Task VcRole([Remainder] IRole role = null) { var user = (IGuildUser)Context.User; var vc = user.VoiceChannel; if (vc == null || vc.GuildId != user.GuildId) { await ReplyErrorLocalized("must_be_in_voice").ConfigureAwait(false); return; } var guildVcRoles = vcRoles.GetOrAdd(user.GuildId, new ConcurrentDictionary <ulong, IRole>()); if (role == null) { if (guildVcRoles.TryRemove(vc.Id, out role)) { await ReplyConfirmLocalized("vcrole_removed", Format.Bold(vc.Name)).ConfigureAwait(false); using (var uow = DbHandler.UnitOfWork()) { var conf = uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.VcRoleInfos)); conf.VcRoleInfos.RemoveWhere(x => x.VoiceChannelId == vc.Id); uow.Complete(); } } } else { guildVcRoles.AddOrUpdate(vc.Id, role, (key, old) => role); using (var uow = DbHandler.UnitOfWork()) { var conf = uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.VcRoleInfos)); conf.VcRoleInfos.RemoveWhere(x => x.VoiceChannelId == vc.Id); // remove old one conf.VcRoleInfos.Add(new VcRoleInfo() { VoiceChannelId = vc.Id, RoleId = role.Id, }); // add new one uow.Complete(); } await ReplyConfirmLocalized("vcrole_added", Format.Bold(vc.Name), Format.Bold(role.Name)).ConfigureAwait(false); } }
public async Task Award(int amount, [Remainder] IRole role) { var users = (await Context.Guild.GetUsersAsync()).Where(u => u.GetRoles().Contains(role)).ToList(); await Task.WhenAll(users.Select(u => _currency.AddAsync(Context.Guild.Id, u.Id, $"Awarded by bot owner to **{role.Name}** role. ({Context.User.Username}/{Context.User.Id})", amount))).ConfigureAwait(false); await ReplyConfirmLocalized("mass_award", $"{amount}{CurrencySign}", Format.Bold(users.Count.ToString()), Format.Bold(role.Name)).ConfigureAwait(false); }
public async Task ExecuteAsync(int id, [Remainder] string edit) { var user = await Context.Database.Users.FirstOrDefaultAsync(x => x.Id == Context.User.Id); if (user is null || user.Notes.Count < 1) { await ReplyAsync(embed : SimpleEmbed("You have no self notes!", false)); return; } var note = user.Notes.FirstOrDefault(x => x.Id == id); if (note is null) { await ReplyAsync(embed : SimpleEmbed("The note Id you specified does not exist! Please double-check & try again.", false)); return; } if (edit.Length > 1800) { await ReplyAsync(embed : SimpleEmbed("Notes can only be 1800 characters maximum.", false)); return; } note.Text = edit; await ReplyAsync(embed : SimpleEmbed(string.Format("Self Note (ID: {0}) Updated: {1}", Format.Bold(id.ToString()), Format.BlockQuote(edit)))); }
public async Task Take(long amount, [Remainder] IGuildUser user) { if (amount > 0) { var reason = $"Taken by bot owner.({Context.User.Username}/{Context.User.Id})"; if (await _currency.RemoveAsync(user, reason, amount).ConfigureAwait(false)) { await ReplyConfirmLocalized("take", $"{amount}{CurrencySign}", Format.Bold(user.ToString())).ConfigureAwait(false); try { // FIXME: Use translations. await user.SendErrorAsync($"`You lost:` {amount}{CurrencySign} on Server with ID {user.GuildId}.\n`Reason:` {reason}").ConfigureAwait(false); } catch { } } else { await ReplyErrorLocalized("take_fail", $"{amount}{CurrencySign}", Format.Bold(user.ToString()), CurrencyPluralName).ConfigureAwait(false); } } }
public async Task Repeat(GuildDateTime dt, params string[] options) { if (!_service.RepeaterReady) { return; } var(opts, _) = OptionsParser.Default.ParseFrom(new Repeater.Options(), options); if (string.IsNullOrWhiteSpace(opts.Message)) { return; } var toAdd = new GuildRepeater() { ChannelId = Context.Channel.Id, GuildId = Context.Guild.Id, Interval = TimeSpan.FromMinutes(opts.Interval), Message = opts.Message, NoRedundant = opts.NoRedundant, StartTimeOfDay = dt?.InputTimeUtc.TimeOfDay, }; using (var uow = _db.UnitOfWork) { var gc = uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.GuildRepeaters)); if (gc.GuildRepeaters.Count >= 5) { return; } gc.GuildRepeaters.Add(toAdd); await uow.CompleteAsync().ConfigureAwait(false); } var rep = new RepeatRunner(_client, (SocketGuild)Context.Guild, toAdd); _service.Repeaters.AddOrUpdate(Context.Guild.Id, new ConcurrentQueue <RepeatRunner>(new[] { rep }), (key, old) => { old.Enqueue(rep); return(old); }); string secondPart = ""; if (dt != null) { secondPart = GetText("repeater_initial", Format.Bold(rep.InitialInterval.Hours.ToString()), Format.Bold(rep.InitialInterval.Minutes.ToString())); } await Context.Channel.SendConfirmAsync( "🔁 " + GetText("repeater", Format.Bold(((IGuildUser)Context.User).GuildPermissions.MentionEveryone ? rep.Repeater.Message : rep.Repeater.Message.SanitizeMentions()), Format.Bold(rep.Repeater.Interval.Days.ToString()), Format.Bold(rep.Repeater.Interval.Hours.ToString()), Format.Bold(rep.Repeater.Interval.Minutes.ToString())) + " " + secondPart).ConfigureAwait(false); }
public async Task RotateRoleColor(int timeout, IRole role, params string[] hexes) { var channel = (ITextChannel)Context.Channel; if ((timeout < 60 && timeout != 0) || timeout > 3600) { return; } Timer t; if (timeout == 0 || hexes.Length == 0) { if (_rotatingRoleColors.TryRemove(role.Id, out t)) { t.Change(Timeout.Infinite, Timeout.Infinite); await ReplyConfirmLocalized("rrc_stop", Format.Bold(role.Name)).ConfigureAwait(false); } return; } var hexColors = hexes.Select(hex => { try { return((ImageSharp.Color?)ImageSharp.Color.FromHex(hex.Replace("#", ""))); } catch { return(null); } }) .Where(c => c != null) .Select(c => c.Value) .ToArray(); if (!hexColors.Any()) { await ReplyErrorLocalized("rrc_no_colors").ConfigureAwait(false); return; } var images = hexColors.Select(color => { var img = new ImageSharp.Image(50, 50); img.BackgroundColor(color); return(img); }).Merge().ToStream(); var i = 0; t = new Timer(async(_) => { try { var color = hexColors[i]; await role.ModifyAsync(r => r.Color = new Discord.Color(color.R, color.G, color.B)).ConfigureAwait(false); ++i; if (i >= hexColors.Length) { i = 0; } } catch { } }, null, 0, timeout * 1000); _rotatingRoleColors.AddOrUpdate(role.Id, t, (key, old) => { old.Change(Timeout.Infinite, Timeout.Infinite); return(t); }); await channel.SendFileAsync(images, "magicalgirl.jpg", GetText("rrc_start", Format.Bold(role.Name))).ConfigureAwait(false); }