mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-10 17:28:27 -04:00
- Most if not all gambling commands should now use locale-specific currency format
- Enabled preview language features
This commit is contained in:
@@ -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
|
||||
|
@@ -1,4 +1,6 @@
|
||||
#nullable disable
|
||||
using System;
|
||||
|
||||
namespace NadekoBot.Common;
|
||||
|
||||
public struct ShmartNumber : IEquatable<ShmartNumber>
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
@@ -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()
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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));
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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 "";
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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]}』
|
||||
|
||||
|
@@ -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>
|
||||
|
Reference in New Issue
Block a user