- Most if not all gambling commands should now use locale-specific currency format

- Enabled preview language features
This commit is contained in:
Kwoth
2022-02-03 13:51:50 +01:00
parent eecccc8100
commit f77f2f433f
14 changed files with 72 additions and 56 deletions

View File

@@ -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

View File

@@ -1,4 +1,6 @@
#nullable disable
using System;
namespace NadekoBot.Common;
public struct ShmartNumber : IEquatable<ShmartNumber>

View File

@@ -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)

View File

@@ -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)
{

View File

@@ -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));
}
}
}

View File

@@ -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()

View File

@@ -64,16 +64,6 @@ public partial class Gambling : GamblingModule<GamblingService>
_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<string> GetBalanceStringAsync(ulong userId)
{
var wallet = await _cs.GetWalletAsync(userId);
@@ -95,13 +85,12 @@ public partial class Gambling : GamblingModule<GamblingService>
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<GamblingService>
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<GamblingService>
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<GamblingService>
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

View File

@@ -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<TService> : NadekoModule<TService>
return true;
}
protected string N<T>(T cur) where T : INumber<T>
{
var flowersCi = (CultureInfo)Culture.Clone();
flowersCi.NumberFormat.CurrencySymbol = CurrencySign;
flowersCi.NumberFormat.CurrencyNegativePattern = 5;
return cur.ToString("C0", flowersCi);
}
protected Task<bool> CheckBetMandatory(long amount)
{

View File

@@ -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));
}

View File

@@ -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

View File

@@ -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 "";
}
}

View File

@@ -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;

View File

@@ -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]}』

View File

@@ -2,9 +2,9 @@
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<LangVersion>10.0</LangVersion>
<LangVersion>preview</LangVersion>
<Nullable>enable</Nullable>
<EnablePreviewFeatures>True</EnablePreviewFeatures>
<EnablePreviewFeatures>true</EnablePreviewFeatures>
<ImplicitUsings>true</ImplicitUsings>
<!-- Output/build -->
@@ -15,7 +15,6 @@
<!-- Analysis/Warnings -->
<!-- <AnalysisMode>Recommended</AnalysisMode>-->
<!-- <AnalysisModeGlobalization>None</AnalysisModeGlobalization>-->
<AnalysisModeNaming>None</AnalysisModeNaming>
<NoWarn>CS1066</NoWarn>
</PropertyGroup>
@@ -63,6 +62,9 @@
<PackageReference Include="linq2db.EntityFrameworkCore" Version="6.6.1"/>
<PackageReference Include="Humanizer" Version="2.13.14"/>
<PackageReference Include="JetBrains.Annotations" Version="2021.3.0"/>
<!-- Remove this when static abstract interface members support is released -->
<PackageReference Include="System.Runtime.Experimental" Version="6.0.0" />
</ItemGroup>
<ItemGroup>
@@ -99,4 +101,14 @@
<NoWarn>$(NoWarn);CS1573;CS1591</NoWarn>
</PropertyGroup>
<!-- TODO: Remove this when the conflict issue is fixed -->
<Target Name="RemoveSystemRuntimeFromRefPack"
BeforeTargets="_HandlePackageFileConflicts"
Condition="'@(Reference -> WithMetadataValue('NugetPackageId', 'System.Runtime.Experimental'))' != ''">
<ItemGroup>
<Reference Remove="@(Reference)"
Condition="$([System.String]::Copy(%(Reference.Identity)).Contains('System.Runtime.dll')) and
'%(Reference.NuGetPackageId)' == 'Microsoft.NETCore.App.Ref'" />
</ItemGroup>
</Target>
</Project>