diff --git a/src/NadekoBot/.editorconfig b/src/NadekoBot/.editorconfig index 3a05399e4..157fea39c 100644 --- a/src/NadekoBot/.editorconfig +++ b/src/NadekoBot/.editorconfig @@ -100,7 +100,7 @@ csharp_prefer_static_local_function = true csharp_preferred_modifier_order = public, private, protected, internal, static, extern, new, virtual, abstract, sealed, override, readonly, unsafe, volatile, async # Code-block preferences -csharp_prefer_braces = when_multiline:error +csharp_prefer_braces = when_multiline:warning csharp_prefer_simple_using_statement = true # Expression-level preferences @@ -354,3 +354,6 @@ resharper_csharp_braces_for_foreach = required_for_multiline resharper_csharp_braces_for_while = required_for_multiline resharper_csharp_braces_for_for = required_for_multiline resharper_arrange_redundant_parentheses_highlighting = hint + +# IDE0011: Add braces +dotnet_diagnostic.IDE0011.severity = warning diff --git a/src/NadekoBot/Common/ShmartNumber.cs b/src/NadekoBot/Common/ShmartNumber.cs index aa6b48c34..5ffd67572 100644 --- a/src/NadekoBot/Common/ShmartNumber.cs +++ b/src/NadekoBot/Common/ShmartNumber.cs @@ -1,4 +1,6 @@ #nullable disable +using System; + namespace NadekoBot.Common; public struct ShmartNumber : IEquatable diff --git a/src/NadekoBot/Modules/Gambling/BlackJack/BlackJackCommands.cs b/src/NadekoBot/Modules/Gambling/BlackJack/BlackJackCommands.cs index 1dda8914a..89b1dfd2b 100644 --- a/src/NadekoBot/Modules/Gambling/BlackJack/BlackJackCommands.cs +++ b/src/NadekoBot/Modules/Gambling/BlackJack/BlackJackCommands.cs @@ -105,7 +105,7 @@ public partial class Gambling c = p.Cards.Select(x => x.GetEmojiString()).ToList(); cStr = "-\t" + string.Concat(c.Select(x => x[..^1] + " ")); cStr += "\n-\t" + string.Concat(c.Select(x => x.Last() + " ")); - var full = $"{p.DiscordUser.ToString().TrimTo(20)} | Bet: {p.Bet} | Value: {p.GetHandValue()}"; + var full = $"{p.DiscordUser.ToString().TrimTo(20)} | Bet: {N(p.Bet)} | Value: {p.GetHandValue()}"; if (bj.State == Blackjack.GameState.Ended) { if (p.State == User.UserState.Lost) diff --git a/src/NadekoBot/Modules/Gambling/Connect4/Connect4Commands.cs b/src/NadekoBot/Modules/Gambling/Connect4/Connect4Commands.cs index 55fca4cfd..5bbf6a546 100644 --- a/src/NadekoBot/Modules/Gambling/Connect4/Connect4Commands.cs +++ b/src/NadekoBot/Modules/Gambling/Connect4/Connect4Commands.cs @@ -82,7 +82,7 @@ public partial class Gambling if (options.Bet == 0) await ReplyConfirmLocalizedAsync(strs.connect4_created); else - await ReplyErrorLocalizedAsync(strs.connect4_created_bet(options.Bet + CurrencySign)); + await ReplyErrorLocalizedAsync(strs.connect4_created_bet(N(options.Bet))); Task ClientMessageReceived(SocketMessage arg) { diff --git a/src/NadekoBot/Modules/Gambling/Events/CurrencyEventsCommands.cs b/src/NadekoBot/Modules/Gambling/Events/CurrencyEventsCommands.cs index 6b90074a2..e2b315873 100644 --- a/src/NadekoBot/Modules/Gambling/Events/CurrencyEventsCommands.cs +++ b/src/NadekoBot/Modules/Gambling/Events/CurrencyEventsCommands.cs @@ -45,16 +45,16 @@ public partial class Gambling private string GetReactionDescription(long amount, long potSize) { - var potSizeStr = Format.Bold(potSize == 0 ? "∞" + CurrencySign : potSize + CurrencySign); + var potSizeStr = Format.Bold(potSize == 0 ? "∞" + CurrencySign : N(potSize)); - return GetText(strs.new_reaction_event(CurrencySign, Format.Bold(amount + CurrencySign), potSizeStr)); + return GetText(strs.new_reaction_event(CurrencySign, Format.Bold(N(amount)), potSizeStr)); } private string GetGameStatusDescription(long amount, long potSize) { var potSizeStr = Format.Bold(potSize == 0 ? "∞" + CurrencySign : potSize + CurrencySign); - return GetText(strs.new_gamestatus_event(CurrencySign, Format.Bold(amount + CurrencySign), potSizeStr)); + return GetText(strs.new_gamestatus_event(CurrencySign, Format.Bold(N(amount)), potSizeStr)); } } } \ No newline at end of file diff --git a/src/NadekoBot/Modules/Gambling/FlipCoin/FlipCoinCommands.cs b/src/NadekoBot/Modules/Gambling/FlipCoin/FlipCoinCommands.cs index 9d449b7c0..c7ecfa830 100644 --- a/src/NadekoBot/Modules/Gambling/FlipCoin/FlipCoinCommands.cs +++ b/src/NadekoBot/Modules/Gambling/FlipCoin/FlipCoinCommands.cs @@ -65,13 +65,17 @@ public partial class Gambling await using var stream = img.ToStream(format); foreach (var i in imgs) i.Dispose(); + var msg = count != 1 - ? Format.Bold(ctx.User.ToString()) + " " + GetText(strs.flip_results(count, headCount, tailCount)) + ? Format.Bold(ctx.User.ToString()) + + " " + + GetText(strs.flip_results(count, headCount, tailCount)) : Format.Bold(ctx.User.ToString()) + " " + GetText(strs.flipped(headCount > 0 ? Format.Bold(GetText(strs.heads)) : Format.Bold(GetText(strs.tails)))); + await ctx.Channel.SendFileAsync(stream, $"{count} coins.{format.FileExtensions.First()}", msg); } @@ -106,12 +110,12 @@ public partial class Gambling if (guess == result) { var toWin = (long)(amount * Config.BetFlip.Multiplier); - str = Format.Bold(ctx.User.ToString()) + " " + GetText(strs.flip_guess(toWin + CurrencySign)); + str = Format.Bold(ctx.User.ToString()) + " " + GetText(strs.flip_guess(N(toWin))); await _cs.AddAsync(ctx.User, toWin, new("betflip", "win")); } else { - str = ctx.User + " " + GetText(strs.better_luck); + str = Format.Bold(ctx.User.ToString()) + " " + GetText(strs.better_luck); } await ctx.Channel.EmbedAsync(_eb.Create() diff --git a/src/NadekoBot/Modules/Gambling/Gambling.cs b/src/NadekoBot/Modules/Gambling/Gambling.cs index fd401dfbd..ff30c0475 100644 --- a/src/NadekoBot/Modules/Gambling/Gambling.cs +++ b/src/NadekoBot/Modules/Gambling/Gambling.cs @@ -64,16 +64,6 @@ public partial class Gambling : GamblingModule _configService = configService; } - private string N(long cur) - { - var flowersCi = (CultureInfo)Culture.Clone(); - flowersCi.NumberFormat.CurrencySymbol = CurrencySign; - flowersCi.NumberFormat.CurrencyNegativePattern = 5; - // if (cur < 0) - // cur = -cur; - return cur.ToString("C0", flowersCi); - } - public async Task GetBalanceStringAsync(ulong userId) { var wallet = await _cs.GetWalletAsync(userId); @@ -95,13 +85,12 @@ public partial class Gambling : GamblingModule var embed = _eb.Create() .WithTitle(GetText(strs.economy_state)) .AddField(GetText(strs.currency_owned), - ((BigInteger)(ec.Cash - ec.Bot)).ToString("N", Culture) + CurrencySign) + N((ec.Cash - ec.Bot))) .AddField(GetText(strs.currency_one_percent), (onePercent * 100).ToString("F2") + "%") - .AddField(GetText(strs.currency_planted), (BigInteger)ec.Planted) - .AddField(GetText(strs.owned_waifus_total), (BigInteger)ec.Waifus + CurrencySign) + .AddField(GetText(strs.currency_planted), N(ec.Planted)) + .AddField(GetText(strs.owned_waifus_total), N(ec.Waifus)) .AddField(GetText(strs.bot_currency), N(ec.Bot)) - .AddField(GetText(strs.total), - ((BigInteger)(ec.Cash + ec.Planted + ec.Waifus)).ToString("N", Culture) + CurrencySign) + .AddField(GetText(strs.total), N(ec.Cash + ec.Planted + ec.Waifus)) .WithOkColor(); // ec.Cash already contains ec.Bot as it's the total of all values in the CurrencyAmount column of the DiscordUser table @@ -332,7 +321,7 @@ public partial class Gambling : GamblingModule return; } - await ReplyConfirmLocalizedAsync(strs.gifted(N(amount), Format.Bold(receiver.ToString()))); + await ReplyConfirmLocalizedAsync(strs.gifted(N(amount.Value), Format.Bold(receiver.ToString()))); } [Cmd] @@ -502,7 +491,7 @@ public partial class Gambling : GamblingModule await ReplyConfirmLocalizedAsync(strs.roll_duel_challenge(Format.Bold(ctx.User.ToString()), Format.Bold(u.ToString()), - Format.Bold(N(amount)))); + Format.Bold(N(amount.Value)))); } async Task GameOnGameTick(RollDuelGame arg) @@ -711,7 +700,7 @@ public partial class Gambling : GamblingModule amount = (long)(amount * Config.BetFlip.Multiplier); await _cs.AddAsync(ctx.User.Id, amount, new("rps", "win")); embed.WithOkColor(); - embed.AddField(GetText(strs.won), N(amount)); + embed.AddField(GetText(strs.won), N(amount.Value)); msg = GetText(strs.rps_win(ctx.User.Mention, GetRpsPick(pick), GetRpsPick(nadekoPick))); } else diff --git a/src/NadekoBot/Modules/Gambling/GamblingTopLevelModule.cs b/src/NadekoBot/Modules/Gambling/GamblingTopLevelModule.cs index 0616282c8..87b3276ca 100644 --- a/src/NadekoBot/Modules/Gambling/GamblingTopLevelModule.cs +++ b/src/NadekoBot/Modules/Gambling/GamblingTopLevelModule.cs @@ -1,5 +1,7 @@ #nullable disable using NadekoBot.Modules.Gambling.Services; +using System.Globalization; +using System.Runtime; namespace NadekoBot.Modules.Gambling.Common; @@ -37,6 +39,14 @@ public abstract class GamblingModule : NadekoModule return true; } + + protected string N(T cur) where T : INumber + { + var flowersCi = (CultureInfo)Culture.Clone(); + flowersCi.NumberFormat.CurrencySymbol = CurrencySign; + flowersCi.NumberFormat.CurrencyNegativePattern = 5; + return cur.ToString("C0", flowersCi); + } protected Task CheckBetMandatory(long amount) { diff --git a/src/NadekoBot/Modules/Gambling/PlantPick/PlantAndPickCommands.cs b/src/NadekoBot/Modules/Gambling/PlantPick/PlantAndPickCommands.cs index 12e3cf106..1a5392a4f 100644 --- a/src/NadekoBot/Modules/Gambling/PlantPick/PlantAndPickCommands.cs +++ b/src/NadekoBot/Modules/Gambling/PlantPick/PlantAndPickCommands.cs @@ -26,7 +26,7 @@ public partial class Gambling if (picked > 0) { - var msg = await ReplyConfirmLocalizedAsync(strs.picked(picked + CurrencySign)); + var msg = await ReplyConfirmLocalizedAsync(strs.picked(N(picked))); msg.DeleteAfter(10); } @@ -61,6 +61,7 @@ public partial class Gambling ctx.User.ToString(), amount, pass); + if (!success) await ReplyErrorLocalizedAsync(strs.not_enough(CurrencySign)); } diff --git a/src/NadekoBot/Modules/Gambling/Raffle/CurrencyRaffleCommands.cs b/src/NadekoBot/Modules/Gambling/Raffle/CurrencyRaffleCommands.cs index e36d67fd1..d4d04331f 100644 --- a/src/NadekoBot/Modules/Gambling/Raffle/CurrencyRaffleCommands.cs +++ b/src/NadekoBot/Modules/Gambling/Raffle/CurrencyRaffleCommands.cs @@ -41,7 +41,7 @@ public partial class Gambling if (res.Item1 is not null) { await SendConfirmAsync(GetText(strs.rafflecur(res.Item1.GameType.ToString())), - string.Join("\n", res.Item1.Users.Select(x => $"{x.DiscordUser} ({x.Amount})")), + string.Join("\n", res.Item1.Users.Select(x => $"{x.DiscordUser} ({N(x.Amount)})")), footer: GetText(strs.rafflecur_joined(ctx.User.ToString()))); } else diff --git a/src/NadekoBot/Modules/Gambling/Shop/ShopCommands.cs b/src/NadekoBot/Modules/Gambling/Shop/ShopCommands.cs index dbb4e5466..3e0a0e4aa 100644 --- a/src/NadekoBot/Modules/Gambling/Shop/ShopCommands.cs +++ b/src/NadekoBot/Modules/Gambling/Shop/ShopCommands.cs @@ -54,7 +54,7 @@ public partial class Gambling for (var i = 0; i < theseEntries.Length; i++) { var entry = theseEntries[i]; - embed.AddField($"#{(curPage * 9) + i + 1} - {entry.Price}{CurrencySign}", + embed.AddField($"#{(curPage * 9) + i + 1} - {N(entry.Price)}", EntryToString(entry), true); } @@ -428,12 +428,12 @@ public partial class Gambling GetText(strs.shop_role(Format.Bold(ctx.Guild.GetRole(entry.RoleId)?.Name ?? "MISSING_ROLE"))), true) - .AddField(GetText(strs.price), entry.Price.ToString(), true) + .AddField(GetText(strs.price), N(entry.Price), true) .AddField(GetText(strs.type), entry.Type.ToString(), true); if (entry.Type == ShopEntryType.List) return embed.AddField(GetText(strs.name), entry.Name, true) - .AddField(GetText(strs.price), entry.Price.ToString(), true) + .AddField(GetText(strs.price), N(entry.Price), true) .AddField(GetText(strs.type), GetText(strs.random_unique_item), true); //else if (entry.Type == ShopEntryType.Infinite_List) @@ -449,10 +449,6 @@ public partial class Gambling return GetText(strs.shop_role(Format.Bold(ctx.Guild.GetRole(entry.RoleId)?.Name ?? "MISSING_ROLE"))); if (entry.Type == ShopEntryType.List) return GetText(strs.unique_items_left(entry.Items.Count)) + "\n" + entry.Name; - //else if (entry.Type == ShopEntryType.Infinite_List) - //{ - - //} return ""; } } diff --git a/src/NadekoBot/Modules/Gambling/Waifus/WaifuClaimCommands.cs b/src/NadekoBot/Modules/Gambling/Waifus/WaifuClaimCommands.cs index 1c7b76402..9aee738ed 100644 --- a/src/NadekoBot/Modules/Gambling/Waifus/WaifuClaimCommands.cs +++ b/src/NadekoBot/Modules/Gambling/Waifus/WaifuClaimCommands.cs @@ -21,7 +21,7 @@ public partial class Gambling var price = _service.GetResetPrice(ctx.User); var embed = _eb.Create() .WithTitle(GetText(strs.waifu_reset_confirm)) - .WithDescription(GetText(strs.waifu_reset_price(Format.Bold(price + CurrencySign)))); + .WithDescription(GetText(strs.waifu_reset_price(Format.Bold(N(price))))); if (!await PromptUserConfirmAsync(embed)) return; @@ -56,7 +56,7 @@ public partial class Gambling if (result == WaifuClaimResult.InsufficientAmount) { await ReplyErrorLocalizedAsync( - strs.waifu_not_enough(Math.Ceiling(w.Price * (isAffinity ? 0.88f : 1.1f)))); + strs.waifu_not_enough(N((long)Math.Ceiling(w.Price * (isAffinity ? 0.88f : 1.1f))))); return; } @@ -66,9 +66,9 @@ public partial class Gambling return; } - var msg = GetText(strs.waifu_claimed(Format.Bold(target.ToString()), amount + CurrencySign)); + var msg = GetText(strs.waifu_claimed(Format.Bold(target.ToString()), N(amount))); if (w.Affinity?.UserId == ctx.User.Id) - msg += "\n" + GetText(strs.waifu_fulfilled(target, w.Price + CurrencySign)); + msg += "\n" + GetText(strs.waifu_fulfilled(target, N(w.Price))); else msg = " " + msg; await SendConfirmAsync(ctx.User.Mention + msg); @@ -136,9 +136,9 @@ public partial class Gambling if (result == DivorceResult.SucessWithPenalty) await ReplyConfirmLocalizedAsync(strs.waifu_divorced_like(Format.Bold(w.Waifu.ToString()), - amount + CurrencySign)); + N(amount))); else if (result == DivorceResult.Success) - await ReplyConfirmLocalizedAsync(strs.waifu_divorced_notlike(amount + CurrencySign)); + await ReplyConfirmLocalizedAsync(strs.waifu_divorced_notlike(N(amount))); else if (result == DivorceResult.NotYourWife) await ReplyErrorLocalizedAsync(strs.waifu_not_yours); else @@ -149,15 +149,15 @@ public partial class Gambling [Cmd] [RequireContext(ContextType.Guild)] - public async partial Task Affinity([Leftover] IGuildUser u = null) + public async partial Task Affinity([Leftover] IGuildUser user = null) { - if (u?.Id == ctx.User.Id) + if (user?.Id == ctx.User.Id) { await ReplyErrorLocalizedAsync(strs.waifu_egomaniac); return; } - var (oldAff, sucess, remaining) = await _service.ChangeAffinityAsync(ctx.User, u); + var (oldAff, sucess, remaining) = await _service.ChangeAffinityAsync(ctx.User, user); if (!sucess) { if (remaining is not null) @@ -169,13 +169,13 @@ public partial class Gambling return; } - if (u is null) + if (user is null) await ReplyConfirmLocalizedAsync(strs.waifu_affinity_reset); else if (oldAff is null) - await ReplyConfirmLocalizedAsync(strs.waifu_affinity_set(Format.Bold(u.ToString()))); + await ReplyConfirmLocalizedAsync(strs.waifu_affinity_set(Format.Bold(user.ToString()))); else await ReplyConfirmLocalizedAsync(strs.waifu_affinity_changed(Format.Bold(oldAff.ToString()), - Format.Bold(u.ToString()))); + Format.Bold(user.ToString()))); } [Cmd] @@ -204,7 +204,7 @@ public partial class Gambling foreach (var w in waifus) { var j = i++; - embed.AddField("#" + ((page * 9) + j + 1) + " - " + w.Price + CurrencySign, w.ToString()); + embed.AddField("#" + ((page * 9) + j + 1) + " - " + N(w.Price), w.ToString()); } await ctx.Channel.EmbedAsync(embed); @@ -259,7 +259,7 @@ public partial class Gambling + " - \"the " + _service.GetClaimTitle(wi.ClaimCount) + "\"") - .AddField(GetText(strs.price), wi.Price.ToString(), true) + .AddField(GetText(strs.price), N(wi.Price), true) .AddField(GetText(strs.claimed_by), wi.ClaimerName ?? nobody, true) .AddField(GetText(strs.likes), wi.AffinityName ?? nobody, true) .AddField(GetText(strs.changes_of_heart), $"{wi.AffinityCount} - \"the {affInfo}\"", true) @@ -295,7 +295,7 @@ public partial class Gambling .ToList() .ForEach(x => embed.AddField( $"{(!x.Negative ? string.Empty : "\\💔")} {x.ItemEmoji} {x.Name}", - Format.Bold(x.Price.ToString()) + Config.Currency.Sign, + Format.Bold(N(x.Price)), true)); return embed; diff --git a/src/NadekoBot/Modules/Gambling/Wheel/WheelOfFortuneCommands.cs b/src/NadekoBot/Modules/Gambling/Wheel/WheelOfFortuneCommands.cs index 381a69a67..4f8434b26 100644 --- a/src/NadekoBot/Modules/Gambling/Wheel/WheelOfFortuneCommands.cs +++ b/src/NadekoBot/Modules/Gambling/Wheel/WheelOfFortuneCommands.cs @@ -2,7 +2,6 @@ using NadekoBot.Modules.Gambling.Common; using NadekoBot.Modules.Gambling.Services; using System.Collections.Immutable; -using Wof = NadekoBot.Modules.Gambling.Common.WheelOfFortune.WheelOfFortuneGame; namespace NadekoBot.Modules.Gambling; @@ -38,7 +37,7 @@ public partial class Gambling var result = await _service.WheelOfFortuneSpinAsync(ctx.User.Id, amount); var wofMultipliers = Config.WheelOfFortune.Multipliers; - await SendConfirmAsync(Format.Bold($@"{ctx.User.ToString()} won: {result.Amount + CurrencySign} + await SendConfirmAsync(Format.Bold($@"{ctx.User} won: {N(result.Amount)} 『{wofMultipliers[1]}』 『{wofMultipliers[0]}』 『{wofMultipliers[7]}』 diff --git a/src/NadekoBot/NadekoBot.csproj b/src/NadekoBot/NadekoBot.csproj index d150a1b89..d92ed2196 100644 --- a/src/NadekoBot/NadekoBot.csproj +++ b/src/NadekoBot/NadekoBot.csproj @@ -2,9 +2,9 @@ net6.0 - 10.0 + preview enable - True + true true @@ -15,7 +15,6 @@ - None CS1066 @@ -63,6 +62,9 @@ + + + @@ -99,4 +101,14 @@ $(NoWarn);CS1573;CS1591 + + + + + +