mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-11 01:38:27 -04:00
Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
7d5c4666b8 |
27
CHANGELOG.md
27
CHANGELOG.md
@@ -4,33 +4,6 @@ Experimental changelog. Mostly based on [keepachangelog](https://keepachangelog.
|
||||
|
||||
## Unreleased
|
||||
|
||||
## [4.3.5] - 17.08.2022
|
||||
|
||||
### Added
|
||||
|
||||
- Added a 'Use' button when a user already owns an item
|
||||
- Added a 'Pull Again' button to slots
|
||||
- Added `.roleinfo` command
|
||||
- Added `.emojiremove` command
|
||||
- Added `.threadcreate` and `.threaddelete` commands
|
||||
- Added `.bank seize` / `.bank award` owner only commands
|
||||
|
||||
### Changed
|
||||
|
||||
- Running a .timely command early now shows a pending color
|
||||
- .xp system is once again no longer opt in for servers
|
||||
- It's still opt-in for global and requires users to run .xp at least once in order to start gaining global xp
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed users not getting club xp
|
||||
|
||||
## [4.3.4] - 07.08.2022
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed users getting XP out of nowhere while voice xp is enabled
|
||||
|
||||
## [4.3.3] - 06.08.2022
|
||||
|
||||
### Added
|
||||
|
@@ -1,3 +1,8 @@
|
||||
[](https://discord.gg/nadekobot)
|
||||
[](http://nadekobot.readthedocs.io/en/v4/?badge=v4)
|
||||
[](https://top.gg/bot/116275390695079945)
|
||||
|
||||
|
||||
[](https://nadeko.bot/)
|
||||
|
||||
[](https://invite.nadeko.bot/)
|
||||
|
@@ -1,8 +1,5 @@
|
||||
namespace Nadeko.Econ.Gambling;
|
||||
|
||||
//here is a payout chart
|
||||
//https://lh6.googleusercontent.com/-i1hjAJy_kN4/UswKxmhrbPI/AAAAAAAAB1U/82wq_4ZZc-Y/DE6B0895-6FC1-48BE-AC4F-14D1B91AB75B.jpg
|
||||
//thanks to judge for helping me with this
|
||||
public class SlotGame
|
||||
{
|
||||
private static readonly NadekoRandom _rng = new NadekoRandom();
|
||||
|
@@ -10,7 +10,6 @@ public interface IEmbedBuilder
|
||||
IEmbedBuilder WithFooter(string text, string? iconUrl = null);
|
||||
IEmbedBuilder WithAuthor(string name, string? iconUrl = null, string? url = null);
|
||||
IEmbedBuilder WithColor(EmbedColor color);
|
||||
IEmbedBuilder WithDiscordColor(Color color);
|
||||
Embed Build();
|
||||
IEmbedBuilder WithUrl(string url);
|
||||
IEmbedBuilder WithImageUrl(string url);
|
||||
|
@@ -1,8 +0,0 @@
|
||||
namespace NadekoBot;
|
||||
|
||||
public interface INadekoInteractionService
|
||||
{
|
||||
public NadekoInteraction Create<T>(
|
||||
ulong userId,
|
||||
SimpleInteraction<T> inter);
|
||||
}
|
29
src/NadekoBot/Common/Interaction/NadekoActionInteraction.cs
Normal file
29
src/NadekoBot/Common/Interaction/NadekoActionInteraction.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
namespace NadekoBot;
|
||||
|
||||
public sealed class NadekoButtonActionInteraction : NadekoButtonOwnInteraction
|
||||
{
|
||||
private readonly NadekoInteractionData _data;
|
||||
private readonly Func<SocketMessageComponent, Task> _action;
|
||||
|
||||
public NadekoButtonActionInteraction(
|
||||
DiscordSocketClient client,
|
||||
ulong authorId,
|
||||
NadekoInteractionData data,
|
||||
Func<SocketMessageComponent, Task> action
|
||||
)
|
||||
: base(client, authorId)
|
||||
{
|
||||
_data = data;
|
||||
_action = action;
|
||||
}
|
||||
|
||||
protected override string Name
|
||||
=> _data.CustomId;
|
||||
protected override IEmote Emote
|
||||
=> _data.Emote;
|
||||
protected override string? Text
|
||||
=> _data.Text;
|
||||
|
||||
public override Task ExecuteOnActionAsync(SocketMessageComponent smc)
|
||||
=> _action(smc);
|
||||
}
|
@@ -1,30 +1,25 @@
|
||||
namespace NadekoBot;
|
||||
|
||||
public sealed class NadekoInteraction
|
||||
public abstract class NadekoButtonInteraction
|
||||
{
|
||||
private readonly ulong _authorId;
|
||||
private readonly ButtonBuilder _button;
|
||||
private readonly Func<SocketMessageComponent, Task> _onClick;
|
||||
private readonly bool _onlyAuthor;
|
||||
// improvements:
|
||||
// - state in OnAction
|
||||
// - configurable delay
|
||||
// -
|
||||
protected abstract string Name { get; }
|
||||
protected abstract IEmote Emote { get; }
|
||||
protected virtual string? Text { get; } = null;
|
||||
|
||||
public DiscordSocketClient Client { get; }
|
||||
|
||||
private readonly TaskCompletionSource<bool> _interactionCompletedSource;
|
||||
protected readonly TaskCompletionSource<bool> _interactionCompletedSource;
|
||||
|
||||
private IUserMessage message = null!;
|
||||
protected IUserMessage message = null!;
|
||||
|
||||
public NadekoInteraction(DiscordSocketClient client,
|
||||
ulong authorId,
|
||||
ButtonBuilder button,
|
||||
Func<SocketMessageComponent, Task> onClick,
|
||||
bool onlyAuthor)
|
||||
protected NadekoButtonInteraction(DiscordSocketClient client)
|
||||
{
|
||||
_authorId = authorId;
|
||||
_button = button;
|
||||
_onClick = onClick;
|
||||
_onlyAuthor = onlyAuthor;
|
||||
_interactionCompletedSource = new(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
Client = client;
|
||||
_interactionCompletedSource = new(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
}
|
||||
|
||||
public async Task RunAsync(IUserMessage msg)
|
||||
@@ -32,12 +27,13 @@ public sealed class NadekoInteraction
|
||||
message = msg;
|
||||
|
||||
Client.InteractionCreated += OnInteraction;
|
||||
await Task.WhenAny(Task.Delay(15_000), _interactionCompletedSource.Task);
|
||||
await Task.WhenAny(Task.Delay(10_000), _interactionCompletedSource.Task);
|
||||
Client.InteractionCreated -= OnInteraction;
|
||||
|
||||
await msg.ModifyAsync(m => m.Components = new ComponentBuilder().Build());
|
||||
}
|
||||
|
||||
|
||||
protected abstract ValueTask<bool> Validate(SocketMessageComponent smc);
|
||||
private async Task OnInteraction(SocketInteraction arg)
|
||||
{
|
||||
if (arg is not SocketMessageComponent smc)
|
||||
@@ -46,11 +42,14 @@ public sealed class NadekoInteraction
|
||||
if (smc.Message.Id != message.Id)
|
||||
return;
|
||||
|
||||
if (_onlyAuthor && smc.User.Id != _authorId)
|
||||
if (smc.Data.CustomId != Name)
|
||||
return;
|
||||
|
||||
if (smc.Data.CustomId != _button.CustomId)
|
||||
if (!await Validate(smc))
|
||||
{
|
||||
await smc.DeferAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
@@ -67,14 +66,18 @@ public sealed class NadekoInteraction
|
||||
}
|
||||
|
||||
|
||||
public MessageComponent CreateComponent()
|
||||
public virtual MessageComponent CreateComponent()
|
||||
{
|
||||
var comp = new ComponentBuilder()
|
||||
.WithButton(_button);
|
||||
.WithButton(GetButtonBuilder());
|
||||
|
||||
return comp.Build();
|
||||
}
|
||||
|
||||
public Task ExecuteOnActionAsync(SocketMessageComponent smc)
|
||||
=> _onClick(smc);
|
||||
}
|
||||
public ButtonBuilder GetButtonBuilder()
|
||||
=> new ButtonBuilder(style: ButtonStyle.Secondary, emote: Emote, customId: Name, label: Text);
|
||||
|
||||
public abstract Task ExecuteOnActionAsync(SocketMessageComponent smc);
|
||||
}
|
||||
|
||||
// this is all so wrong ...
|
43
src/NadekoBot/Common/Interaction/NadekoInteractionArray.cs
Normal file
43
src/NadekoBot/Common/Interaction/NadekoInteractionArray.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
// namespace NadekoBot;
|
||||
//
|
||||
// public class NadekoButtonInteractionArray : NadekoButtonInteraction
|
||||
// {
|
||||
// private readonly ButtonBuilder[] _bbs;
|
||||
// private readonly NadekoButtonInteraction[] _inters;
|
||||
//
|
||||
// public NadekoButtonInteractionArray(params NadekoButtonInteraction[] inters)
|
||||
// : base(inters[0].Client)
|
||||
// {
|
||||
// _inters = inters;
|
||||
// _bbs = inters.Map(x => x.GetButtonBuilder());
|
||||
// }
|
||||
//
|
||||
// protected override string Name
|
||||
// => throw new NotSupportedException();
|
||||
// protected override IEmote Emote
|
||||
// => throw new NotSupportedException();
|
||||
//
|
||||
// protected override ValueTask<bool> Validate(SocketMessageComponent smc)
|
||||
// => new(true);
|
||||
//
|
||||
// public override Task ExecuteOnActionAsync(SocketMessageComponent smc)
|
||||
// {
|
||||
// for (var i = 0; i < _bbs.Length; i++)
|
||||
// {
|
||||
// if (_bbs[i].CustomId == smc.Data.CustomId)
|
||||
// return _inters[i].ExecuteOnActionAsync(smc);
|
||||
// }
|
||||
//
|
||||
// return Task.CompletedTask;
|
||||
// }
|
||||
//
|
||||
// public override MessageComponent CreateComponent()
|
||||
// {
|
||||
// var comp = new ComponentBuilder();
|
||||
//
|
||||
// foreach (var bb in _bbs)
|
||||
// comp.WithButton(bb);
|
||||
//
|
||||
// return comp.Build();
|
||||
// }
|
||||
// }
|
42
src/NadekoBot/Common/Interaction/NadekoInteractionBuilder.cs
Normal file
42
src/NadekoBot/Common/Interaction/NadekoInteractionBuilder.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
namespace NadekoBot;
|
||||
|
||||
/// <summary>
|
||||
/// Builder class for NadekoInteractions
|
||||
/// </summary>
|
||||
public class NadekoInteractionBuilder
|
||||
{
|
||||
private NadekoInteractionData? iData;
|
||||
private Func<SocketMessageComponent, Task>? action;
|
||||
// private bool isOwn;
|
||||
|
||||
public NadekoInteractionBuilder WithData<T>(in T data)
|
||||
where T : NadekoInteractionData
|
||||
{
|
||||
iData = data;
|
||||
return this;
|
||||
}
|
||||
|
||||
// public NadekoOwnInteractionBuiler WithIsOwn(bool isOwn = true)
|
||||
// {
|
||||
// this.isOwn = isOwn;
|
||||
// return this;
|
||||
|
||||
// }
|
||||
|
||||
public NadekoInteractionBuilder WithAction(in Func<SocketMessageComponent, Task> fn)
|
||||
{
|
||||
this.action = fn;
|
||||
return this;
|
||||
}
|
||||
|
||||
public NadekoButtonActionInteraction Build(DiscordSocketClient client, ulong userId)
|
||||
{
|
||||
if (iData is null)
|
||||
throw new InvalidOperationException("You have to specify the data before building the interaction");
|
||||
|
||||
if (action is null)
|
||||
throw new InvalidOperationException("You have to specify the action before building the interaction");
|
||||
|
||||
return new(client, userId, iData, action);
|
||||
}
|
||||
}
|
@@ -1,20 +0,0 @@
|
||||
namespace NadekoBot;
|
||||
|
||||
public class NadekoInteractionService : INadekoInteractionService, INService
|
||||
{
|
||||
private readonly DiscordSocketClient _client;
|
||||
|
||||
public NadekoInteractionService(DiscordSocketClient client)
|
||||
{
|
||||
_client = client;
|
||||
}
|
||||
|
||||
public NadekoInteraction Create<T>(
|
||||
ulong userId,
|
||||
SimpleInteraction<T> inter)
|
||||
=> new NadekoInteraction(_client,
|
||||
userId,
|
||||
inter.Button,
|
||||
inter.TriggerAsync,
|
||||
onlyAuthor: true);
|
||||
}
|
15
src/NadekoBot/Common/Interaction/NadekoOwnInteraction.cs
Normal file
15
src/NadekoBot/Common/Interaction/NadekoOwnInteraction.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
namespace NadekoBot;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction which only the author can use
|
||||
/// </summary>
|
||||
public abstract class NadekoButtonOwnInteraction : NadekoButtonInteraction
|
||||
{
|
||||
protected readonly ulong _authorId;
|
||||
|
||||
protected NadekoButtonOwnInteraction(DiscordSocketClient client, ulong authorId) : base(client)
|
||||
=> _authorId = authorId;
|
||||
|
||||
protected override ValueTask<bool> Validate(SocketMessageComponent smc)
|
||||
=> new(smc.User.Id == _authorId);
|
||||
}
|
26
src/NadekoBot/Common/NInteraction.cs
Normal file
26
src/NadekoBot/Common/NInteraction.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
namespace NadekoBot.Common;
|
||||
|
||||
public abstract class NInteraction
|
||||
{
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly ulong _userId;
|
||||
private readonly Func<SocketMessageComponent, Task> _action;
|
||||
|
||||
protected abstract NadekoInteractionData Data { get; }
|
||||
|
||||
public NInteraction(
|
||||
DiscordSocketClient client,
|
||||
ulong userId,
|
||||
Func<SocketMessageComponent, Task> action)
|
||||
{
|
||||
_client = client;
|
||||
_userId = userId;
|
||||
_action = action;
|
||||
}
|
||||
|
||||
public NadekoButtonInteraction GetInteraction()
|
||||
=> new NadekoInteractionBuilder()
|
||||
.WithData(Data)
|
||||
.WithAction(_action)
|
||||
.Build(_client, _userId);
|
||||
}
|
@@ -18,7 +18,6 @@ public abstract class NadekoModule : ModuleBase
|
||||
public CommandHandler _cmdHandler { get; set; }
|
||||
public ILocalization _localization { get; set; }
|
||||
public IEmbedBuilderService _eb { get; set; }
|
||||
public INadekoInteractionService _inter { get; set; }
|
||||
|
||||
protected string prefix
|
||||
=> _cmdHandler.GetPrefix(ctx.Guild);
|
||||
@@ -37,7 +36,7 @@ public abstract class NadekoModule : ModuleBase
|
||||
string error,
|
||||
string url = null,
|
||||
string footer = null,
|
||||
NadekoInteraction inter = null)
|
||||
NadekoButtonInteraction inter = null)
|
||||
=> ctx.Channel.SendErrorAsync(_eb, title, error, url, footer);
|
||||
|
||||
public Task<IUserMessage> SendConfirmAsync(
|
||||
@@ -48,32 +47,32 @@ public abstract class NadekoModule : ModuleBase
|
||||
=> ctx.Channel.SendConfirmAsync(_eb, title, text, url, footer);
|
||||
|
||||
//
|
||||
public Task<IUserMessage> SendErrorAsync(string text, NadekoInteraction inter = null)
|
||||
public Task<IUserMessage> SendErrorAsync(string text, NadekoButtonInteraction inter = null)
|
||||
=> ctx.Channel.SendAsync(_eb, text, MessageType.Error, inter);
|
||||
public Task<IUserMessage> SendConfirmAsync(string text, NadekoInteraction inter = null)
|
||||
public Task<IUserMessage> SendConfirmAsync(string text, NadekoButtonInteraction inter = null)
|
||||
=> ctx.Channel.SendAsync(_eb, text, MessageType.Ok, inter);
|
||||
public Task<IUserMessage> SendPendingAsync(string text, NadekoInteraction inter = null)
|
||||
public Task<IUserMessage> SendPendingAsync(string text, NadekoButtonInteraction inter = null)
|
||||
=> ctx.Channel.SendAsync(_eb, text, MessageType.Pending, inter);
|
||||
|
||||
|
||||
// localized normal
|
||||
public Task<IUserMessage> ErrorLocalizedAsync(LocStr str, NadekoInteraction inter = null)
|
||||
public Task<IUserMessage> ErrorLocalizedAsync(LocStr str, NadekoButtonInteraction inter = null)
|
||||
=> SendErrorAsync(GetText(str), inter);
|
||||
|
||||
public Task<IUserMessage> PendingLocalizedAsync(LocStr str, NadekoInteraction inter = null)
|
||||
public Task<IUserMessage> PendingLocalizedAsync(LocStr str, NadekoButtonInteraction inter = null)
|
||||
=> SendPendingAsync(GetText(str), inter);
|
||||
|
||||
public Task<IUserMessage> ConfirmLocalizedAsync(LocStr str, NadekoInteraction inter = null)
|
||||
public Task<IUserMessage> ConfirmLocalizedAsync(LocStr str, NadekoButtonInteraction inter = null)
|
||||
=> SendConfirmAsync(GetText(str), inter);
|
||||
|
||||
// localized replies
|
||||
public Task<IUserMessage> ReplyErrorLocalizedAsync(LocStr str, NadekoInteraction inter = null)
|
||||
public Task<IUserMessage> ReplyErrorLocalizedAsync(LocStr str, NadekoButtonInteraction inter = null)
|
||||
=> SendErrorAsync($"{Format.Bold(ctx.User.ToString())} {GetText(str)}", inter);
|
||||
|
||||
public Task<IUserMessage> ReplyPendingLocalizedAsync(LocStr str, NadekoInteraction inter = null)
|
||||
public Task<IUserMessage> ReplyPendingLocalizedAsync(LocStr str, NadekoButtonInteraction inter = null)
|
||||
=> SendPendingAsync($"{Format.Bold(ctx.User.ToString())} {GetText(str)}", inter);
|
||||
|
||||
public Task<IUserMessage> ReplyConfirmLocalizedAsync(LocStr str, NadekoInteraction inter = null)
|
||||
public Task<IUserMessage> ReplyConfirmLocalizedAsync(LocStr str, NadekoButtonInteraction inter = null)
|
||||
=> SendConfirmAsync($"{Format.Bold(ctx.User.ToString())} {GetText(str)}", inter);
|
||||
|
||||
public async Task<bool> PromptUserConfirmAsync(IEmbedBuilder embed)
|
||||
|
@@ -49,8 +49,7 @@ public enum PunishmentAction
|
||||
ChatMute,
|
||||
VoiceMute,
|
||||
AddRole,
|
||||
Warn,
|
||||
TimeOut
|
||||
Warn
|
||||
}
|
||||
|
||||
public class AntiSpamIgnore : DbEntity
|
||||
|
@@ -17,6 +17,8 @@ public class DiscordUser : DbEntity
|
||||
public bool IsClubAdmin { get; set; }
|
||||
|
||||
public long TotalXp { get; set; }
|
||||
public DateTime LastLevelUp { get; set; } = DateTime.UtcNow;
|
||||
public DateTime LastXpGain { get; set; } = DateTime.MinValue;
|
||||
public XpNotificationLocation NotifyOnLevelUp { get; set; }
|
||||
|
||||
public long CurrencyAmount { get; set; }
|
||||
|
@@ -8,6 +8,7 @@ public class UserXpStats : DbEntity
|
||||
public long Xp { get; set; }
|
||||
public long AwardedXp { get; set; }
|
||||
public XpNotificationLocation NotifyOnLevelUp { get; set; }
|
||||
public DateTime LastLevelUp { get; set; } = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public enum XpNotificationLocation { None, Dm, Channel }
|
@@ -13,6 +13,6 @@ public class XpShopOwnedItem : DbEntity
|
||||
|
||||
public enum XpShopItemType
|
||||
{
|
||||
Background = 0,
|
||||
Frame = 1,
|
||||
Background,
|
||||
Frame,
|
||||
}
|
@@ -10,6 +10,10 @@ public sealed class MysqlContext : NadekoContext
|
||||
|
||||
protected override string CurrencyTransactionOtherIdDefaultValue
|
||||
=> "NULL";
|
||||
protected override string DiscordUserLastXpGainDefaultValue
|
||||
=> "(UTC_TIMESTAMP - INTERVAL 1 year)";
|
||||
protected override string LastLevelUpDefaultValue
|
||||
=> "(UTC_TIMESTAMP)";
|
||||
|
||||
public MysqlContext(string connStr = "Server=localhost", string version = "8.0")
|
||||
{
|
||||
|
@@ -65,6 +65,8 @@ public abstract class NadekoContext : DbContext
|
||||
#region Mandatory Provider-Specific Values
|
||||
|
||||
protected abstract string CurrencyTransactionOtherIdDefaultValue { get; }
|
||||
protected abstract string DiscordUserLastXpGainDefaultValue { get; }
|
||||
protected abstract string LastLevelUpDefaultValue { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -164,6 +166,12 @@ public abstract class NadekoContext : DbContext
|
||||
du.Property(x => x.NotifyOnLevelUp)
|
||||
.HasDefaultValue(XpNotificationLocation.None);
|
||||
|
||||
du.Property(x => x.LastXpGain)
|
||||
.HasDefaultValueSql(DiscordUserLastXpGainDefaultValue);
|
||||
|
||||
du.Property(x => x.LastLevelUp)
|
||||
.HasDefaultValueSql(LastLevelUpDefaultValue);
|
||||
|
||||
du.Property(x => x.TotalXp)
|
||||
.HasDefaultValue(0);
|
||||
|
||||
@@ -205,6 +213,9 @@ public abstract class NadekoContext : DbContext
|
||||
})
|
||||
.IsUnique();
|
||||
|
||||
xps.Property(x => x.LastLevelUp)
|
||||
.HasDefaultValueSql(LastLevelUpDefaultValue);
|
||||
|
||||
xps.HasIndex(x => x.UserId);
|
||||
xps.HasIndex(x => x.GuildId);
|
||||
xps.HasIndex(x => x.Xp);
|
||||
|
@@ -8,6 +8,10 @@ public sealed class PostgreSqlContext : NadekoContext
|
||||
|
||||
protected override string CurrencyTransactionOtherIdDefaultValue
|
||||
=> "NULL";
|
||||
protected override string DiscordUserLastXpGainDefaultValue
|
||||
=> "timezone('utc', now()) - interval '-1 year'";
|
||||
protected override string LastLevelUpDefaultValue
|
||||
=> "timezone('utc', now())";
|
||||
|
||||
public PostgreSqlContext(string connStr = "Host=localhost")
|
||||
{
|
||||
|
@@ -9,6 +9,10 @@ public sealed class SqliteContext : NadekoContext
|
||||
|
||||
protected override string CurrencyTransactionOtherIdDefaultValue
|
||||
=> "NULL";
|
||||
protected override string DiscordUserLastXpGainDefaultValue
|
||||
=> "datetime('now', '-1 years')";
|
||||
protected override string LastLevelUpDefaultValue
|
||||
=> "datetime('now')";
|
||||
|
||||
public SqliteContext(string connectionString = "Data Source=data/NadekoBot.db", int commandTimeout = 60)
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,49 +0,0 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace NadekoBot.Migrations.Mysql
|
||||
{
|
||||
public partial class removeobsoletexpcolumns : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "lastlevelup",
|
||||
table: "userxpstats");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "lastlevelup",
|
||||
table: "discorduser");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "lastxpgain",
|
||||
table: "discorduser");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<DateTime>(
|
||||
name: "lastlevelup",
|
||||
table: "userxpstats",
|
||||
type: "datetime(6)",
|
||||
nullable: false,
|
||||
defaultValueSql: "(UTC_TIMESTAMP)");
|
||||
|
||||
migrationBuilder.AddColumn<DateTime>(
|
||||
name: "lastlevelup",
|
||||
table: "discorduser",
|
||||
type: "datetime(6)",
|
||||
nullable: false,
|
||||
defaultValueSql: "(UTC_TIMESTAMP)");
|
||||
|
||||
migrationBuilder.AddColumn<DateTime>(
|
||||
name: "lastxpgain",
|
||||
table: "discorduser",
|
||||
type: "datetime(6)",
|
||||
nullable: false,
|
||||
defaultValueSql: "(UTC_TIMESTAMP - INTERVAL 1 year)");
|
||||
}
|
||||
}
|
||||
}
|
@@ -168,6 +168,18 @@ namespace NadekoBot.Migrations.Mysql
|
||||
.HasDefaultValue(false)
|
||||
.HasColumnName("isclubadmin");
|
||||
|
||||
b.Property<DateTime>("LastLevelUp")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("datetime(6)")
|
||||
.HasColumnName("lastlevelup")
|
||||
.HasDefaultValueSql("(UTC_TIMESTAMP)");
|
||||
|
||||
b.Property<DateTime>("LastXpGain")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("datetime(6)")
|
||||
.HasColumnName("lastxpgain")
|
||||
.HasDefaultValueSql("(UTC_TIMESTAMP - INTERVAL 1 year)");
|
||||
|
||||
b.Property<int>("NotifyOnLevelUp")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
@@ -2553,6 +2565,12 @@ namespace NadekoBot.Migrations.Mysql
|
||||
.HasColumnType("bigint unsigned")
|
||||
.HasColumnName("guildid");
|
||||
|
||||
b.Property<DateTime>("LastLevelUp")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("datetime(6)")
|
||||
.HasColumnName("lastlevelup")
|
||||
.HasDefaultValueSql("(UTC_TIMESTAMP)");
|
||||
|
||||
b.Property<int>("NotifyOnLevelUp")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("notifyonlevelup");
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -36,7 +36,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("balance");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<decimal>("UserId")
|
||||
@@ -101,7 +101,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<string>("Description")
|
||||
@@ -163,7 +163,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("currencyamount");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<string>("Discriminator")
|
||||
@@ -176,6 +176,18 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasDefaultValue(false)
|
||||
.HasColumnName("isclubadmin");
|
||||
|
||||
b.Property<DateTime>("LastLevelUp")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("lastlevelup")
|
||||
.HasDefaultValueSql("timezone('utc', now())");
|
||||
|
||||
b.Property<DateTime>("LastXpGain")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("lastxpgain")
|
||||
.HasDefaultValueSql("timezone('utc', now()) - interval '-1 year'");
|
||||
|
||||
b.Property<int>("NotifyOnLevelUp")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
@@ -231,7 +243,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("channelid");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
@@ -310,7 +322,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("amountcents");
|
||||
|
||||
b.Property<DateTime>("LastCharge")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("lastcharge");
|
||||
|
||||
b.Property<string>("UniquePlatformUserId")
|
||||
@@ -318,7 +330,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("uniqueplatformuserid");
|
||||
|
||||
b.Property<DateTime>("ValidThru")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("validthru");
|
||||
|
||||
b.HasKey("UserId")
|
||||
@@ -345,7 +357,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("channelid");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<decimal>("MessageId")
|
||||
@@ -376,7 +388,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<bool>("IsUsing")
|
||||
@@ -459,7 +471,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("action");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int>("GuildConfigId")
|
||||
@@ -506,7 +518,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("channelid");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.HasKey("Id")
|
||||
@@ -532,7 +544,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("action");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int>("GuildConfigId")
|
||||
@@ -583,7 +595,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("commandtext");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<decimal?>("GuildId")
|
||||
@@ -630,7 +642,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("channelid");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<decimal>("GuildId")
|
||||
@@ -664,7 +676,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("channelid");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<string>("Source")
|
||||
@@ -698,7 +710,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<decimal>("GuildId")
|
||||
@@ -729,7 +741,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<decimal>("ItemId")
|
||||
@@ -756,7 +768,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
@@ -794,7 +806,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("commandname");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
@@ -828,7 +840,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("amount");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<string>("Extra")
|
||||
@@ -878,7 +890,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("channelid");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
@@ -912,7 +924,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("command");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<decimal?>("GuildId")
|
||||
@@ -943,7 +955,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<decimal>("ItemId")
|
||||
@@ -981,7 +993,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("channelid");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int>("GuildConfigId")
|
||||
@@ -1016,7 +1028,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("channelid");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
@@ -1042,7 +1054,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
@@ -1076,7 +1088,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("channelid");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
@@ -1106,7 +1118,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("channelid");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
@@ -1136,7 +1148,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("channelid");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
@@ -1162,7 +1174,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int>("GuildConfigId")
|
||||
@@ -1241,7 +1253,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("cleverbotenabled");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<bool>("DeleteMessageOnCommand")
|
||||
@@ -1369,7 +1381,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int>("ItemType")
|
||||
@@ -1408,7 +1420,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("channelid");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int?>("LogSettingId")
|
||||
@@ -1438,7 +1450,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("channelid");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<decimal>("GuildId")
|
||||
@@ -1481,7 +1493,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("channelupdatedid");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<decimal>("GuildId")
|
||||
@@ -1617,7 +1629,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("authorid");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<string>("Name")
|
||||
@@ -1640,7 +1652,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
@@ -1682,7 +1694,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("containsanywhere");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<bool>("DmResponse")
|
||||
@@ -1721,7 +1733,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<decimal>("GuildId")
|
||||
@@ -1751,7 +1763,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
@@ -1813,7 +1825,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("channelid");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<decimal>("GuildId")
|
||||
@@ -1855,7 +1867,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int?>("MusicPlaylistId")
|
||||
@@ -1905,7 +1917,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("channelid");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<decimal>("GuildId")
|
||||
@@ -1936,7 +1948,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int>("Index")
|
||||
@@ -1970,7 +1982,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int?>("PollId")
|
||||
@@ -2013,7 +2025,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("authorname");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<decimal>("GuildId")
|
||||
@@ -2056,7 +2068,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("channelid");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<string>("Emote")
|
||||
@@ -2111,7 +2123,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("channelid");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<bool>("IsPrivate")
|
||||
@@ -2131,7 +2143,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("userid");
|
||||
|
||||
b.Property<DateTime>("When")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("when");
|
||||
|
||||
b.HasKey("Id")
|
||||
@@ -2157,7 +2169,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("channelid");
|
||||
|
||||
b.Property<DateTime>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<decimal>("GuildId")
|
||||
@@ -2204,11 +2216,11 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("amountrewardedthismonth");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<DateTime>("LastReward")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("lastreward");
|
||||
|
||||
b.Property<string>("PlatformUserId")
|
||||
@@ -2239,7 +2251,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<string>("Status")
|
||||
@@ -2266,7 +2278,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int>("Group")
|
||||
@@ -2311,7 +2323,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("authorid");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
@@ -2361,7 +2373,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int?>("ShopEntryId")
|
||||
@@ -2391,7 +2403,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
@@ -2421,7 +2433,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
@@ -2451,7 +2463,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int?>("StreamRoleSettingsId")
|
||||
@@ -2489,7 +2501,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("addroleid");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
@@ -2528,7 +2540,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int?>("StreamRoleSettingsId")
|
||||
@@ -2562,7 +2574,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
@@ -2570,7 +2582,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("guildconfigid");
|
||||
|
||||
b.Property<DateTime>("UnbanAt")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("unbanat");
|
||||
|
||||
b.Property<decimal>("UserId")
|
||||
@@ -2596,7 +2608,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
@@ -2604,7 +2616,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("guildconfigid");
|
||||
|
||||
b.Property<DateTime>("UnmuteAt")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("unmuteat");
|
||||
|
||||
b.Property<decimal>("UserId")
|
||||
@@ -2630,7 +2642,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
@@ -2642,7 +2654,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("roleid");
|
||||
|
||||
b.Property<DateTime>("UnbanAt")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("unbanat");
|
||||
|
||||
b.Property<decimal>("UserId")
|
||||
@@ -2672,13 +2684,19 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("awardedxp");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<decimal>("GuildId")
|
||||
.HasColumnType("numeric(20,0)")
|
||||
.HasColumnName("guildid");
|
||||
|
||||
b.Property<DateTime>("LastLevelUp")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("lastlevelup")
|
||||
.HasDefaultValueSql("timezone('utc', now())");
|
||||
|
||||
b.Property<int>("NotifyOnLevelUp")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("notifyonlevelup");
|
||||
@@ -2723,7 +2741,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
@@ -2765,7 +2783,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("claimerid");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<long>("Price")
|
||||
@@ -2805,7 +2823,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<string>("ItemEmoji")
|
||||
@@ -2839,7 +2857,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int?>("NewId")
|
||||
@@ -2883,7 +2901,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<bool>("Forgiven")
|
||||
@@ -2945,7 +2963,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("count");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
@@ -2987,7 +3005,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnName("amount");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int>("Level")
|
||||
@@ -3017,7 +3035,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int>("Level")
|
||||
@@ -3056,7 +3074,7 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("timestamp without time zone")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("dateadded");
|
||||
|
||||
b.Property<int>("GuildConfigId")
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,49 +0,0 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace NadekoBot.Migrations
|
||||
{
|
||||
public partial class removeobsoletexpcolumns : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "LastLevelUp",
|
||||
table: "UserXpStats");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "LastLevelUp",
|
||||
table: "DiscordUser");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "LastXpGain",
|
||||
table: "DiscordUser");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<DateTime>(
|
||||
name: "LastLevelUp",
|
||||
table: "UserXpStats",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValueSql: "datetime('now')");
|
||||
|
||||
migrationBuilder.AddColumn<DateTime>(
|
||||
name: "LastLevelUp",
|
||||
table: "DiscordUser",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValueSql: "datetime('now')");
|
||||
|
||||
migrationBuilder.AddColumn<DateTime>(
|
||||
name: "LastXpGain",
|
||||
table: "DiscordUser",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValueSql: "datetime('now', '-1 years')");
|
||||
}
|
||||
}
|
||||
}
|
@@ -134,6 +134,16 @@ namespace NadekoBot.Migrations
|
||||
.HasColumnType("INTEGER")
|
||||
.HasDefaultValue(false);
|
||||
|
||||
b.Property<DateTime>("LastLevelUp")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT")
|
||||
.HasDefaultValueSql("datetime('now')");
|
||||
|
||||
b.Property<DateTime>("LastXpGain")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT")
|
||||
.HasDefaultValueSql("datetime('now', '-1 years')");
|
||||
|
||||
b.Property<int>("NotifyOnLevelUp")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
@@ -1993,6 +2003,11 @@ namespace NadekoBot.Migrations
|
||||
b.Property<ulong>("GuildId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("LastLevelUp")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT")
|
||||
.HasDefaultValueSql("datetime('now')");
|
||||
|
||||
b.Property<int>("NotifyOnLevelUp")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
|
@@ -344,36 +344,4 @@ public partial class Administration : NadekoModule<AdministrationService>
|
||||
|
||||
await ctx.OkAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
[BotPerm(ChannelPermission.CreatePublicThreads)]
|
||||
[UserPerm(ChannelPermission.CreatePublicThreads)]
|
||||
public async Task ThreadCreate([Leftover] string name)
|
||||
{
|
||||
if (ctx.Channel is not SocketTextChannel stc)
|
||||
return;
|
||||
|
||||
await stc.CreateThreadAsync(name, message: ctx.Message.ReferencedMessage);
|
||||
await ctx.OkAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
[BotPerm(ChannelPermission.ManageThreads)]
|
||||
[UserPerm(ChannelPermission.ManageThreads)]
|
||||
public async Task ThreadDelete([Leftover] string name)
|
||||
{
|
||||
if (ctx.Channel is not SocketTextChannel stc)
|
||||
return;
|
||||
|
||||
var t = stc.Threads.FirstOrDefault(x => string.Equals(x.Name, name, StringComparison.InvariantCultureIgnoreCase));
|
||||
|
||||
if (t is null)
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.not_found);
|
||||
return;
|
||||
}
|
||||
|
||||
await t.DeleteAsync();
|
||||
await ctx.OkAsync();
|
||||
}
|
||||
}
|
@@ -38,14 +38,10 @@ public partial class Administration
|
||||
if (minAgeMinutes < 1 || punishTimeMinutes < 0)
|
||||
return;
|
||||
|
||||
var minutes = (int?)punishTime?.Time.TotalMinutes ?? 0;
|
||||
if (action is PunishmentAction.TimeOut && minutes < 1)
|
||||
minutes = 1;
|
||||
|
||||
await _service.StartAntiAltAsync(ctx.Guild.Id,
|
||||
minAgeMinutes,
|
||||
action,
|
||||
minutes);
|
||||
(int?)punishTime?.Time.TotalMinutes ?? 0);
|
||||
|
||||
await ctx.OkAsync();
|
||||
}
|
||||
@@ -60,9 +56,6 @@ public partial class Administration
|
||||
if (minAgeMinutes < 1)
|
||||
return;
|
||||
|
||||
if (action == PunishmentAction.TimeOut)
|
||||
return;
|
||||
|
||||
await _service.StartAntiAltAsync(ctx.Guild.Id, minAgeMinutes, action, roleId: role.Id);
|
||||
|
||||
await ctx.OkAsync();
|
||||
@@ -129,9 +122,6 @@ public partial class Administration
|
||||
var time = (int?)punishTime?.Time.TotalMinutes ?? 0;
|
||||
if (time is < 0 or > 60 * 24)
|
||||
return;
|
||||
|
||||
if(action is PunishmentAction.TimeOut && time < 1)
|
||||
return;
|
||||
|
||||
var stats = await _service.StartAntiRaidAsync(ctx.Guild.Id, userThreshold, seconds, action, time);
|
||||
|
||||
@@ -197,9 +187,6 @@ public partial class Administration
|
||||
if (time is < 0 or > 60 * 24)
|
||||
return;
|
||||
|
||||
if (action is PunishmentAction.TimeOut && time < 1)
|
||||
return;
|
||||
|
||||
var stats = await _service.StartAntiSpamAsync(ctx.Guild.Id, messageCount, action, time, role?.Id);
|
||||
|
||||
await SendConfirmAsync(GetText(strs.prot_enable("Anti-Spam")),
|
||||
|
@@ -345,10 +345,6 @@ public partial class Administration
|
||||
if (punish is PunishmentAction.AddRole or PunishmentAction.Warn)
|
||||
return;
|
||||
|
||||
// you must specify the time for timeout
|
||||
if (punish is PunishmentAction.TimeOut && time is null)
|
||||
return;
|
||||
|
||||
var success = _service.WarnPunish(ctx.Guild.Id, number, punish, time);
|
||||
|
||||
if (!success)
|
||||
|
@@ -193,9 +193,6 @@ public class UserPunishService : INService, IReadyExecutor
|
||||
case PunishmentAction.Warn:
|
||||
await Warn(guild, user.Id, mod, 1, reason);
|
||||
break;
|
||||
case PunishmentAction.TimeOut:
|
||||
await user.SetTimeOutAsync(TimeSpan.FromMinutes(minutes));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,8 +224,6 @@ public class UserPunishService : INService, IReadyExecutor
|
||||
return botUser.GuildPermissions.MuteMembers;
|
||||
case PunishmentAction.AddRole:
|
||||
return botUser.GuildPermissions.ManageRoles;
|
||||
case PunishmentAction.TimeOut:
|
||||
return botUser.GuildPermissions.ModerateMembers;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
@@ -356,7 +351,7 @@ public class UserPunishService : INService, IReadyExecutor
|
||||
await uow.Warnings.ForgiveAll(guildId, userId, moderator);
|
||||
else
|
||||
toReturn = uow.Warnings.Forgive(guildId, userId, moderator, index - 1);
|
||||
await uow.SaveChangesAsync();
|
||||
uow.SaveChanges();
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
@@ -377,9 +372,6 @@ public class UserPunishService : INService, IReadyExecutor
|
||||
if (punish is PunishmentAction.AddRole && role is null)
|
||||
return false;
|
||||
|
||||
if (punish is PunishmentAction.TimeOut && time is null)
|
||||
return false;
|
||||
|
||||
using var uow = _db.GetDbContext();
|
||||
var ps = uow.GuildConfigsForId(guildId, set => set.Include(x => x.WarnPunishments)).WarnPunishments;
|
||||
var toDelete = ps.Where(x => x.Count == number);
|
||||
|
@@ -11,14 +11,10 @@ public partial class Gambling
|
||||
public partial class BankCommands : GamblingModule<IBankService>
|
||||
{
|
||||
private readonly IBankService _bank;
|
||||
private readonly DiscordSocketClient _client;
|
||||
|
||||
public BankCommands(GamblingConfigService gcs,
|
||||
IBankService bank,
|
||||
DiscordSocketClient client) : base(gcs)
|
||||
public BankCommands(GamblingConfigService gcs, IBankService bank) : base(gcs)
|
||||
{
|
||||
_bank = bank;
|
||||
_client = client;
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -72,50 +68,5 @@ public partial class Gambling
|
||||
await ReplyErrorLocalizedAsync(strs.cant_dm);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task BankTakeInternalAsync(long amount, ulong userId)
|
||||
{
|
||||
if (await _bank.TakeAsync(userId, amount))
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.take_fail(N(amount),
|
||||
_client.GetUser(userId)?.ToString()
|
||||
?? userId.ToString(),
|
||||
CurrencySign));
|
||||
return;
|
||||
}
|
||||
|
||||
await ctx.OkAsync();
|
||||
}
|
||||
|
||||
private async Task BankAwardInternalAsync(long amount, ulong userId)
|
||||
{
|
||||
if (await _bank.AwardAsync(userId, amount))
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.take_fail(N(amount),
|
||||
_client.GetUser(userId)?.ToString()
|
||||
?? userId.ToString(),
|
||||
CurrencySign));
|
||||
return;
|
||||
}
|
||||
|
||||
await ctx.OkAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
[OwnerOnly]
|
||||
[Priority(1)]
|
||||
public async Task BankTake(long amount, [Leftover] IUser user)
|
||||
=> await BankTakeInternalAsync(amount, user.Id);
|
||||
|
||||
[Cmd]
|
||||
[OwnerOnly]
|
||||
[Priority(0)]
|
||||
public async Task BankTake(long amount, ulong userId)
|
||||
=> await BankTakeInternalAsync(amount, userId);
|
||||
|
||||
[Cmd]
|
||||
[OwnerOnly]
|
||||
public async Task BankAward(long amount, [Leftover] IUser user)
|
||||
=> await BankAwardInternalAsync(amount, user.Id);
|
||||
}
|
||||
}
|
@@ -15,48 +15,6 @@ public sealed class BankService : IBankService, INService
|
||||
_db = db;
|
||||
}
|
||||
|
||||
public async Task<bool> AwardAsync(ulong userId, long amount)
|
||||
{
|
||||
if (amount <= 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(amount));
|
||||
|
||||
await using var ctx = _db.GetDbContext();
|
||||
await ctx.BankUsers
|
||||
.ToLinqToDBTable()
|
||||
.InsertOrUpdateAsync(() => new()
|
||||
{
|
||||
UserId = userId,
|
||||
Balance = amount
|
||||
},
|
||||
(old) => new()
|
||||
{
|
||||
Balance = old.Balance + amount
|
||||
},
|
||||
() => new()
|
||||
{
|
||||
UserId = userId
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> TakeAsync(ulong userId, long amount)
|
||||
{
|
||||
if (amount <= 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(amount));
|
||||
|
||||
await using var ctx = _db.GetDbContext();
|
||||
var rows = await ctx.BankUsers
|
||||
.ToLinqToDBTable()
|
||||
.Where(x => x.UserId == userId && x.Balance >= amount)
|
||||
.UpdateAsync((old) => new()
|
||||
{
|
||||
Balance = old.Balance - amount
|
||||
});
|
||||
|
||||
return rows > 0;
|
||||
}
|
||||
|
||||
public async Task<bool> DepositAsync(ulong userId, long amount)
|
||||
{
|
||||
if (amount <= 0)
|
||||
|
@@ -5,6 +5,4 @@ public interface IBankService
|
||||
Task<bool> DepositAsync(ulong userId, long amount);
|
||||
Task<bool> WithdrawAsync(ulong userId, long amount);
|
||||
Task<long> GetBalanceAsync(ulong userId);
|
||||
Task<bool> AwardAsync(ulong userId, long amount);
|
||||
Task<bool> TakeAsync(ulong userId, long amount);
|
||||
}
|
13
src/NadekoBot/Modules/Gambling/CashInteraction.cs
Normal file
13
src/NadekoBot/Modules/Gambling/CashInteraction.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
#nullable disable
|
||||
namespace NadekoBot.Modules.Gambling;
|
||||
|
||||
public class CashInteraction : NInteraction
|
||||
{
|
||||
protected override NadekoInteractionData Data
|
||||
=> new NadekoInteractionData(new Emoji("🏦"), "cash:bank_show_balance");
|
||||
|
||||
public CashInteraction(DiscordSocketClient client, ulong userId, Func<SocketMessageComponent, Task> action)
|
||||
: base(client, userId, action)
|
||||
{
|
||||
}
|
||||
}
|
@@ -99,20 +99,39 @@ public partial class Gambling : GamblingModule<GamblingService>
|
||||
PrettyName = "Timely"
|
||||
};
|
||||
|
||||
private async Task RemindTimelyAction(SocketMessageComponent smc, DateTime when)
|
||||
public class RemindMeInteraction : NInteraction
|
||||
{
|
||||
var tt = TimestampTag.FromDateTime(when, TimestampTagStyles.Relative);
|
||||
public RemindMeInteraction(
|
||||
[NotNull] DiscordSocketClient client,
|
||||
ulong userId,
|
||||
[NotNull] Func<SocketMessageComponent, Task> action)
|
||||
: base(client, userId, action)
|
||||
{
|
||||
}
|
||||
|
||||
await _remind.AddReminderAsync(ctx.User.Id,
|
||||
ctx.User.Id,
|
||||
ctx.Guild.Id,
|
||||
true,
|
||||
when,
|
||||
GetText(strs.timely_time));
|
||||
|
||||
await smc.RespondConfirmAsync(_eb, GetText(strs.remind_timely(tt)), ephemeral: true);
|
||||
protected override NadekoInteractionData Data
|
||||
=> new NadekoInteractionData(
|
||||
Emote: Emoji.Parse("⏰"),
|
||||
CustomId: "timely:remind_me",
|
||||
Text: "Remind me"
|
||||
);
|
||||
}
|
||||
|
||||
private Func<SocketMessageComponent, Task> RemindTimelyAction(DateTime when)
|
||||
=> async smc =>
|
||||
{
|
||||
var tt = TimestampTag.FromDateTime(when, TimestampTagStyles.Relative);
|
||||
|
||||
await _remind.AddReminderAsync(ctx.User.Id,
|
||||
ctx.User.Id,
|
||||
ctx.Guild.Id,
|
||||
true,
|
||||
when,
|
||||
GetText(strs.timely_time));
|
||||
|
||||
await smc.RespondConfirmAsync(_eb, GetText(strs.remind_timely(tt)), ephemeral: true);
|
||||
};
|
||||
|
||||
[Cmd]
|
||||
public async Task Timely()
|
||||
{
|
||||
@@ -128,7 +147,7 @@ public partial class Gambling : GamblingModule<GamblingService>
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
var relativeTag = TimestampTag.FromDateTime(now.Add(rem), TimestampTagStyles.Relative);
|
||||
await ReplyPendingLocalizedAsync(strs.timely_already_claimed(relativeTag));
|
||||
await ReplyErrorLocalizedAsync(strs.timely_already_claimed(relativeTag));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -138,17 +157,11 @@ public partial class Gambling : GamblingModule<GamblingService>
|
||||
|
||||
await _cs.AddAsync(ctx.User.Id, val, new("timely", "claim"));
|
||||
|
||||
var inter = _inter
|
||||
.Create(ctx.User.Id,
|
||||
new SimpleInteraction<DateTime>(
|
||||
new ButtonBuilder(
|
||||
label: "Remind me",
|
||||
emote: Emoji.Parse("⏰"),
|
||||
customId: "timely:remind_me"),
|
||||
RemindTimelyAction,
|
||||
DateTime.UtcNow.Add(TimeSpan.FromHours(period))));
|
||||
|
||||
await ReplyConfirmLocalizedAsync(strs.timely(N(val), period), inter);
|
||||
var inter = new RemindMeInteraction(_client,
|
||||
ctx.User.Id,
|
||||
RemindTimelyAction(DateTime.UtcNow.Add(TimeSpan.FromHours(period))));
|
||||
|
||||
await ReplyConfirmLocalizedAsync(strs.timely(N(val), period), inter.GetInteraction());
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -349,7 +362,7 @@ public partial class Gambling : GamblingModule<GamblingService>
|
||||
await ReplyConfirmLocalizedAsync(strs.has(Format.Code(userId.ToString()), cur));
|
||||
}
|
||||
|
||||
private async Task BankAction(SocketMessageComponent smc, object _)
|
||||
private async Task BankAction(SocketMessageComponent smc)
|
||||
{
|
||||
var balance = await _bank.GetBalanceAsync(ctx.User.Id);
|
||||
|
||||
@@ -359,12 +372,8 @@ public partial class Gambling : GamblingModule<GamblingService>
|
||||
.Pipe(text => smc.RespondConfirmAsync(_eb, text, ephemeral: true));
|
||||
}
|
||||
|
||||
private NadekoInteraction CreateCashInteraction()
|
||||
=> _inter.Create<object>(ctx.User.Id,
|
||||
new(new(
|
||||
customId: "cash:bank_show_balance",
|
||||
emote: new Emoji("🏦")),
|
||||
BankAction));
|
||||
private NadekoButtonInteraction CreateCashInteraction()
|
||||
=> new CashInteraction(_client, ctx.User.Id, BankAction).GetInteraction();
|
||||
|
||||
[Cmd]
|
||||
[Priority(1)]
|
||||
|
@@ -27,6 +27,12 @@ public partial class Gambling
|
||||
private static decimal totalBet;
|
||||
private static decimal totalPaidOut;
|
||||
|
||||
private static readonly ConcurrentHashSet<ulong> _runningUsers = new();
|
||||
|
||||
//here is a payout chart
|
||||
//https://lh6.googleusercontent.com/-i1hjAJy_kN4/UswKxmhrbPI/AAAAAAAAB1U/82wq_4ZZc-Y/DE6B0895-6FC1-48BE-AC4F-14D1B91AB75B.jpg
|
||||
//thanks to judge for helping me with this
|
||||
|
||||
private readonly IImageCache _images;
|
||||
private readonly FontProvider _fonts;
|
||||
private readonly DbService _db;
|
||||
@@ -67,6 +73,16 @@ public partial class Gambling
|
||||
|
||||
await ctx.Channel.EmbedAsync(embed);
|
||||
}
|
||||
public sealed class SlotInteraction : NInteraction
|
||||
{
|
||||
public SlotInteraction(DiscordSocketClient client, ulong userId, Func<SocketMessageComponent, Task> action) : base(client, userId, action)
|
||||
{
|
||||
}
|
||||
|
||||
protected override NadekoInteractionData Data { get; } = new(Emoji.Parse("🔁"),
|
||||
"slot:again",
|
||||
"Pull Again");
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
public async Task Slot(ShmartNumber amount)
|
||||
@@ -78,34 +94,43 @@ public partial class Gambling
|
||||
|
||||
await ctx.Channel.TriggerTypingAsync();
|
||||
|
||||
if (await InternalSlotAsync(amount) is not SlotResult result)
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.not_enough(CurrencySign));
|
||||
if (!_runningUsers.Add(ctx.User.Id))
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
if (await InternalSlotAsync(amount) is not SlotResult result)
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.not_enough(CurrencySign));
|
||||
return;
|
||||
}
|
||||
|
||||
var msg = GetSlotMessageInternal(result);
|
||||
|
||||
using var image = await GenerateSlotImageAsync(amount, result);
|
||||
await using var imgStream = await image.ToStreamAsync();
|
||||
|
||||
|
||||
var eb = _eb.Create(ctx)
|
||||
.WithAuthor(ctx.User)
|
||||
.WithDescription(Format.Bold(msg))
|
||||
.WithImageUrl($"attachment://result.png")
|
||||
.WithOkColor();
|
||||
|
||||
// var inter = slotInteraction.GetInteraction();
|
||||
await ctx.Channel.SendFileAsync(imgStream,
|
||||
"result.png",
|
||||
embed: eb.Build()
|
||||
// components: inter.CreateComponent()
|
||||
);
|
||||
|
||||
// await inter.RunAsync(resMsg);
|
||||
}
|
||||
finally
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
_runningUsers.TryRemove(ctx.User.Id);
|
||||
}
|
||||
|
||||
var text = GetSlotMessageTextInternal(result);
|
||||
|
||||
using var image = await GenerateSlotImageAsync(amount, result);
|
||||
await using var imgStream = await image.ToStreamAsync();
|
||||
|
||||
|
||||
var eb = _eb.Create(ctx)
|
||||
.WithAuthor(ctx.User)
|
||||
.WithDescription(Format.Bold(text))
|
||||
.WithImageUrl($"attachment://result.png")
|
||||
.WithOkColor();
|
||||
|
||||
var bb = new ButtonBuilder(emote: Emoji.Parse("🔁"), customId: "slot:again", label: "Pull Again");
|
||||
var si = new SimpleInteraction<ShmartNumber>(bb, (_, amount) => Slot(amount), amount);
|
||||
|
||||
var inter = _inter.Create(ctx.User.Id, si);
|
||||
var msg = await ctx.Channel.SendFileAsync(imgStream,
|
||||
"result.png",
|
||||
embed: eb.Build(),
|
||||
components: inter.CreateComponent()
|
||||
);
|
||||
await inter.RunAsync(msg);
|
||||
}
|
||||
|
||||
// private SlotInteraction CreateSlotInteractionIntenal(long amount)
|
||||
@@ -156,7 +181,7 @@ public partial class Gambling
|
||||
// });
|
||||
// }
|
||||
|
||||
private string GetSlotMessageTextInternal(SlotResult result)
|
||||
private string GetSlotMessageInternal(SlotResult result)
|
||||
{
|
||||
var multi = result.Multiplier.ToString("0.##");
|
||||
var msg = result.WinType switch
|
||||
@@ -176,6 +201,7 @@ public partial class Gambling
|
||||
|
||||
if (!maybeResult.TryPickT0(out var result, out var error))
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.not_enough(CurrencySign));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@@ -424,7 +424,7 @@ public partial class Help : NadekoModule<HelpService>
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Log.Information("No old version list found. Creating a new one");
|
||||
Log.Information("No old version list found. Creating a new one.");
|
||||
}
|
||||
|
||||
var versionList = JsonSerializer.Deserialize<List<string>>(versionListString);
|
||||
@@ -469,7 +469,7 @@ public partial class Help : NadekoModule<HelpService>
|
||||
"https://nadekobot.readthedocs.io/en/latest/"));
|
||||
|
||||
|
||||
private Task SelfhostAction(SocketMessageComponent smc, object _)
|
||||
private Task SelfhostAction(SocketMessageComponent smc)
|
||||
=> smc.RespondConfirmAsync(_eb,
|
||||
@"- In case you don't want or cannot Donate to NadekoBot project, but you
|
||||
- NadekoBot is a completely free and fully [open source](https://gitlab.com/kwoth/nadekobot) project which means you can run your own ""selfhosted"" instance on your computer or server for free.
|
||||
@@ -484,13 +484,7 @@ public partial class Help : NadekoModule<HelpService>
|
||||
[OnlyPublicBot]
|
||||
public async Task Donate()
|
||||
{
|
||||
// => new NadekoInteractionData(new Emoji("🖥️"), "donate:selfhosting", "Selfhosting");
|
||||
var selfhostInter = _inter.Create(ctx.User.Id,
|
||||
new SimpleInteraction<object>(new ButtonBuilder(
|
||||
emote: new Emoji("🖥️"),
|
||||
customId: "donate:selfhosting",
|
||||
label: "Selfhosting"),
|
||||
SelfhostAction));
|
||||
var selfhostInter = new DonateSelfhostingInteraction(_client, ctx.User.Id, SelfhostAction);
|
||||
|
||||
var eb = _eb.Create(ctx)
|
||||
.WithOkColor()
|
||||
@@ -531,7 +525,7 @@ Nadeko will DM you the welcome instructions, and you may start using the patron-
|
||||
|
||||
try
|
||||
{
|
||||
await (await ctx.User.CreateDMChannelAsync()).EmbedAsync(eb, inter: selfhostInter);
|
||||
await (await ctx.User.CreateDMChannelAsync()).EmbedAsync(eb, inter: selfhostInter.GetInteraction());
|
||||
_ = ctx.OkAsync();
|
||||
}
|
||||
catch
|
||||
|
@@ -0,0 +1,12 @@
|
||||
namespace NadekoBot.Modules.Help;
|
||||
|
||||
public class DonateSelfhostingInteraction : NInteraction
|
||||
{
|
||||
protected override NadekoInteractionData Data
|
||||
=> new NadekoInteractionData(new Emoji("🖥️"), "donate:selfhosting", "Selfhosting");
|
||||
|
||||
public DonateSelfhostingInteraction(DiscordSocketClient client, ulong userId, Func<SocketMessageComponent, Task> action)
|
||||
: base(client, userId, action)
|
||||
{
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
namespace NadekoBot.Modules.Help;
|
||||
|
||||
public class DonateTroubleshootInteraction : NInteraction
|
||||
{
|
||||
protected override NadekoInteractionData Data
|
||||
=> new NadekoInteractionData(new Emoji("❓"), "donate:troubleshoot", "Troubleshoot");
|
||||
|
||||
public DonateTroubleshootInteraction(DiscordSocketClient client, ulong userId, Func<SocketMessageComponent, Task> action)
|
||||
: base(client, userId, action)
|
||||
{
|
||||
}
|
||||
}
|
@@ -97,33 +97,6 @@ public partial class Utility
|
||||
.WithOkColor();
|
||||
await ctx.Channel.EmbedAsync(embed);
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
[RequireUserPermission(GuildPermission.ManageRoles)]
|
||||
public async Task RoleInfo([Leftover] SocketRole role)
|
||||
{
|
||||
if (role.IsEveryone)
|
||||
return;
|
||||
|
||||
var createdAt = new DateTime(2015, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)
|
||||
.AddMilliseconds(role.Id >> 22);
|
||||
var usercount = role.Members.LongCount();
|
||||
var embed = _eb.Create()
|
||||
.WithTitle(role.Name.TrimTo(128))
|
||||
.WithDescription(role.Permissions.ToList().Join(" | "))
|
||||
.AddField(GetText(strs.id), role.Id.ToString(), true)
|
||||
.AddField(GetText(strs.created_at), $"{createdAt:dd.MM.yyyy HH:mm}", true)
|
||||
.AddField(GetText(strs.users), usercount.ToString(), true)
|
||||
.AddField(GetText(strs.color), $"#{role.Color.R:X2}{role.Color.G:X2}{role.Color.B:X2}", true)
|
||||
.AddField(GetText(strs.mentionable), role.IsMentionable.ToString(), true)
|
||||
.AddField(GetText(strs.hoisted), role.IsHoisted.ToString(), true)
|
||||
.WithOkColor();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(role.GetIconUrl()))
|
||||
embed = embed.WithThumbnailUrl(role.GetIconUrl());
|
||||
|
||||
await ctx.Channel.EmbedAsync(embed);
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
|
@@ -367,41 +367,6 @@ public partial class Utility : NadekoModule
|
||||
await ConfirmLocalizedAsync(strs.emoji_added(em.ToString()));
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[BotPerm(GuildPerm.ManageEmojisAndStickers)]
|
||||
[UserPerm(GuildPerm.ManageEmojisAndStickers)]
|
||||
[Priority(0)]
|
||||
public async Task EmojiRemove(params Emote[] emotes)
|
||||
{
|
||||
if (emotes.Length == 0)
|
||||
return;
|
||||
|
||||
var g = (SocketGuild)ctx.Guild;
|
||||
|
||||
var fails = new List<Emote>();
|
||||
foreach (var emote in emotes)
|
||||
{
|
||||
var guildEmote = g.Emotes.FirstOrDefault(x => x.Id == emote.Id);
|
||||
if (guildEmote is null)
|
||||
{
|
||||
fails.Add(emote);
|
||||
}
|
||||
else
|
||||
{
|
||||
await ctx.Guild.DeleteEmoteAsync(guildEmote);
|
||||
}
|
||||
}
|
||||
|
||||
if (fails.Count > 0)
|
||||
{
|
||||
await ReplyPendingLocalizedAsync(strs.emoji_not_removed(fails.Select(x => x.ToString()).Join(" ")));
|
||||
return;
|
||||
}
|
||||
|
||||
await ctx.OkAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
[OwnerOnly]
|
||||
public async Task ListServers(int page = 1)
|
||||
|
@@ -334,15 +334,15 @@ public partial class Xp : NadekoModule<XpService>
|
||||
|
||||
public enum XpShopInputType
|
||||
{
|
||||
Backgrounds = 0,
|
||||
B = 0,
|
||||
Bg = 0,
|
||||
Bgs = 0,
|
||||
Frames = 1,
|
||||
F = 1,
|
||||
Fr = 1,
|
||||
Frs = 1,
|
||||
Fs = 1,
|
||||
Backgrounds = 1,
|
||||
B = 1,
|
||||
Bg = 1,
|
||||
Bgs = 1,
|
||||
Frames = 0,
|
||||
F = 0,
|
||||
Fr = 0,
|
||||
Frs = 0,
|
||||
Fs = 0,
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -432,7 +432,8 @@ public partial class Xp : NadekoModule<XpService>
|
||||
var button = new ButtonBuilder(ownedItem.IsUsing
|
||||
? GetText(strs.in_use)
|
||||
: GetText(strs.use),
|
||||
"xpshop:use",
|
||||
"XP_SHOP_USE",
|
||||
ButtonStyle.Primary,
|
||||
emote: Emoji.Parse("👐"),
|
||||
isDisabled: ownedItem.IsUsing);
|
||||
|
||||
@@ -446,7 +447,8 @@ public partial class Xp : NadekoModule<XpService>
|
||||
else
|
||||
{
|
||||
var button = new ButtonBuilder(GetText(strs.buy),
|
||||
"xpshop:buy",
|
||||
"XP_SHOP_BUY",
|
||||
ButtonStyle.Primary,
|
||||
emote: Emoji.Parse("💰"));
|
||||
|
||||
var inter = new SimpleInteraction<(string key, XpShopItemType type)?>(
|
||||
@@ -467,22 +469,12 @@ public partial class Xp : NadekoModule<XpService>
|
||||
{
|
||||
var result = await _service.BuyShopItemAsync(ctx.User.Id, (XpShopItemType)type, key);
|
||||
|
||||
NadekoInteraction GetUseInteraction()
|
||||
{
|
||||
return _inter.Create(ctx.User.Id,
|
||||
new SimpleInteraction<object>(
|
||||
new ButtonBuilder(label: "Use", customId: "xpshop:use_item", emote: Emoji.Parse("👐")),
|
||||
async (smc, _) => await XpShopUse(type, key)
|
||||
));
|
||||
}
|
||||
|
||||
if (result != BuyResult.Success)
|
||||
{
|
||||
var _ = result switch
|
||||
{
|
||||
BuyResult.XpShopDisabled => await ReplyErrorLocalizedAsync(strs.xp_shop_disabled),
|
||||
BuyResult.InsufficientFunds => await ReplyErrorLocalizedAsync(strs.not_enough(_gss.Data.Currency.Sign)),
|
||||
BuyResult.AlreadyOwned => await ReplyErrorLocalizedAsync(strs.xpshop_already_owned, GetUseInteraction()),
|
||||
BuyResult.AlreadyOwned => await ReplyErrorLocalizedAsync(strs.xpshop_already_owned),
|
||||
BuyResult.UnknownItem => await ReplyErrorLocalizedAsync(strs.xpshop_item_not_found),
|
||||
BuyResult.InsufficientPatronTier => await ReplyErrorLocalizedAsync(strs.patron_insuff_tier),
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
@@ -491,8 +483,7 @@ public partial class Xp : NadekoModule<XpService>
|
||||
}
|
||||
|
||||
await ReplyConfirmLocalizedAsync(strs.xpshop_buy_success(type.ToString().ToLowerInvariant(),
|
||||
key.ToLowerInvariant()),
|
||||
GetUseInteraction());
|
||||
key.ToLowerInvariant()));
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
|
@@ -188,13 +188,6 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
},
|
||||
(_, n) => n);
|
||||
|
||||
await ctx.Clubs
|
||||
.Where(x => x.Members.Any(m => group.Contains(m.UserId)))
|
||||
.UpdateAsync(old => new()
|
||||
{
|
||||
Xp = old.Xp + (group.Key * old.Members.Count(m => group.Contains(m.UserId)))
|
||||
});
|
||||
|
||||
dus.AddRange(items);
|
||||
}
|
||||
|
||||
@@ -212,43 +205,8 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
Xp = old.Xp + group.Key
|
||||
},
|
||||
(_, n) => n);
|
||||
|
||||
gxps.AddRange(items);
|
||||
|
||||
var missingUserIds = group.Where(userId => !items.Any(x => x.UserId == userId)).ToArray();
|
||||
foreach (var userId in missingUserIds)
|
||||
{
|
||||
await ctx
|
||||
.UserXpStats
|
||||
.ToLinqToDBTable()
|
||||
.InsertOrUpdateAsync(() => new UserXpStats()
|
||||
{
|
||||
UserId = userId,
|
||||
GuildId = guildId,
|
||||
Xp = group.Key,
|
||||
DateAdded = DateTime.UtcNow,
|
||||
AwardedXp = 0,
|
||||
NotifyOnLevelUp = XpNotificationLocation.None
|
||||
},
|
||||
_ => new()
|
||||
{
|
||||
|
||||
},
|
||||
() => new()
|
||||
{
|
||||
UserId = userId
|
||||
});
|
||||
}
|
||||
|
||||
if (missingUserIds.Length > 0)
|
||||
{
|
||||
var missingItems = await ctx.UserXpStats
|
||||
.ToLinqToDBTable()
|
||||
.Where(x => missingUserIds.Contains(x.UserId))
|
||||
.ToArrayAsyncLinqToDB();
|
||||
|
||||
gxps.AddRange(missingItems);
|
||||
}
|
||||
gxps.AddRange(items);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1436,7 +1394,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
var conf = _xpConfig.Data;
|
||||
|
||||
if (!conf.Shop.IsEnabled)
|
||||
return BuyResult.XpShopDisabled;
|
||||
return BuyResult.UnknownItem;
|
||||
|
||||
var req = type == XpShopItemType.Background
|
||||
? conf.Shop.BgsTierRequirement
|
||||
@@ -1587,7 +1545,6 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
public enum BuyResult
|
||||
{
|
||||
Success,
|
||||
XpShopDisabled,
|
||||
AlreadyOwned,
|
||||
InsufficientFunds,
|
||||
UnknownItem,
|
||||
|
@@ -67,9 +67,6 @@ public sealed class DiscordEmbedBuilderWrapper : IEmbedBuilder
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(color), "Unsupported EmbedColor type")
|
||||
};
|
||||
|
||||
public IEmbedBuilder WithDiscordColor(Color color)
|
||||
=> Wrap(embed.WithColor(color));
|
||||
|
||||
public Embed Build()
|
||||
=> embed.Build();
|
||||
|
||||
|
@@ -7,7 +7,7 @@ namespace NadekoBot.Services;
|
||||
|
||||
public sealed class StatsService : IStatsService, IReadyExecutor, INService
|
||||
{
|
||||
public const string BOT_VERSION = "4.3.5";
|
||||
public const string BOT_VERSION = "4.3.4";
|
||||
|
||||
public string Author
|
||||
=> "Kwoth#2452";
|
||||
|
@@ -33,7 +33,7 @@ public static class MessageChannelExtensions
|
||||
public static async Task<IUserMessage> SendAsync(
|
||||
this IMessageChannel channel,
|
||||
string? plainText,
|
||||
NadekoInteraction? inter,
|
||||
NadekoButtonInteraction? inter,
|
||||
Embed? embed = null,
|
||||
IReadOnlyCollection<Embed>? embeds = null,
|
||||
bool sanitizeAll = false)
|
||||
@@ -72,7 +72,7 @@ public static class MessageChannelExtensions
|
||||
IEmbedBuilder? embed,
|
||||
string plainText = "",
|
||||
IReadOnlyCollection<IEmbedBuilder>? embeds = null,
|
||||
NadekoInteraction? inter = null)
|
||||
NadekoButtonInteraction? inter = null)
|
||||
=> ch.SendAsync(plainText,
|
||||
inter,
|
||||
embed: embed?.Build(),
|
||||
@@ -83,7 +83,7 @@ public static class MessageChannelExtensions
|
||||
IEmbedBuilderService eb,
|
||||
string text,
|
||||
MessageType type,
|
||||
NadekoInteraction? inter = null)
|
||||
NadekoButtonInteraction? inter = null)
|
||||
{
|
||||
var builder = eb.Create().WithDescription(text);
|
||||
|
||||
|
@@ -56,7 +56,7 @@ public static class SocketMessageComponentExtensions
|
||||
IEmbedBuilder? embed,
|
||||
string plainText = "",
|
||||
IReadOnlyCollection<IEmbedBuilder>? embeds = null,
|
||||
NadekoInteraction? inter = null,
|
||||
NadekoButtonInteraction? inter = null,
|
||||
bool ephemeral = false)
|
||||
=> smc.RespondAsync(plainText,
|
||||
embed: embed?.Build(),
|
||||
@@ -69,7 +69,7 @@ public static class SocketMessageComponentExtensions
|
||||
string text,
|
||||
MessageType type,
|
||||
bool ephemeral = false,
|
||||
NadekoInteraction? inter = null)
|
||||
NadekoButtonInteraction? inter = null)
|
||||
{
|
||||
var builder = eb.Create().WithDescription(text);
|
||||
|
||||
|
@@ -174,14 +174,6 @@ settopic:
|
||||
setchanlname:
|
||||
- setchanlname
|
||||
- schn
|
||||
# thread stuff
|
||||
threadcreate:
|
||||
- threadcreate
|
||||
- thcr
|
||||
threaddelete:
|
||||
- threaddelete
|
||||
- thdel
|
||||
- thrm
|
||||
prune:
|
||||
- prune
|
||||
- clear
|
||||
@@ -217,9 +209,6 @@ serverinfo:
|
||||
channelinfo:
|
||||
- channelinfo
|
||||
- cinfo
|
||||
roleinfo:
|
||||
- roleinfo
|
||||
- rinfo
|
||||
userinfo:
|
||||
- userinfo
|
||||
- uinfo
|
||||
@@ -385,7 +374,6 @@ award:
|
||||
- award
|
||||
take:
|
||||
- take
|
||||
- seize
|
||||
betroll:
|
||||
- betroll
|
||||
- br
|
||||
@@ -722,13 +710,6 @@ showemojis:
|
||||
emojiadd:
|
||||
- emojiadd
|
||||
- ea
|
||||
emojiremove:
|
||||
- emojiremove
|
||||
- emojirm
|
||||
- er
|
||||
- ed
|
||||
- emojidel
|
||||
- emojidelete
|
||||
deckshuffle:
|
||||
- deckshuffle
|
||||
- dsh
|
||||
@@ -1327,7 +1308,6 @@ medusalist:
|
||||
medusainfo:
|
||||
- medusainfo
|
||||
- meinfo
|
||||
# Bank stuff
|
||||
bankdeposit:
|
||||
- deposit
|
||||
- d
|
||||
@@ -1340,11 +1320,6 @@ bankbalance:
|
||||
- balance
|
||||
- b
|
||||
- bal
|
||||
banktake:
|
||||
- take
|
||||
- seize
|
||||
bankaward:
|
||||
- award
|
||||
# Patron
|
||||
patron:
|
||||
- patron
|
||||
|
@@ -423,10 +423,6 @@ channelinfo:
|
||||
desc: "Shows info about the channel. If no channel is supplied, it defaults to current one."
|
||||
args:
|
||||
- "#some-channel"
|
||||
roleinfo:
|
||||
desc: "Shows info about the specified role."
|
||||
args:
|
||||
- "Gamers"
|
||||
userinfo:
|
||||
desc: "Shows info about the user. If no user is supplied, it defaults a user running the command."
|
||||
args:
|
||||
@@ -1221,10 +1217,6 @@ emojiadd:
|
||||
- ":someonesCustomEmoji:"
|
||||
- "MyEmojiName :someonesCustomEmoji:"
|
||||
- "owoNice https://cdn.discordapp.com/emojis/587930873811173386.png?size=128"
|
||||
emojiremove:
|
||||
desc: "Removes the specified emoji or emojis from this server."
|
||||
args:
|
||||
- ":eagleWarrior: :plumedArcher:"
|
||||
deckshuffle:
|
||||
desc: "Reshuffles all cards back into the deck."
|
||||
args:
|
||||
@@ -2245,14 +2237,6 @@ bankbalance:
|
||||
desc: "Shows your current bank balance available for withdrawal."
|
||||
args:
|
||||
- ""
|
||||
banktake:
|
||||
desc: "Takes the specified amount of currency from a user's bank"
|
||||
args:
|
||||
- "500 @MoniLaunder"
|
||||
bankaward:
|
||||
desc: "Award the specified amount of currency to a user's bank"
|
||||
args:
|
||||
- "99999 @Bestie"
|
||||
patron:
|
||||
desc: "Check your patronage status and command usage quota. Bot owners can check targeted user's patronage status."
|
||||
args:
|
||||
@@ -2294,11 +2278,3 @@ bettest:
|
||||
- ""
|
||||
- "betflip 1000"
|
||||
- "slot 2000"
|
||||
threadcreate:
|
||||
desc: "Create a public thread with the specified title. You may optionally reply to a message to have it as a starting point."
|
||||
args:
|
||||
- "Q&A"
|
||||
threaddelete:
|
||||
desc: "Delete a thread with the specified name in this channel. Case insensitive."
|
||||
args:
|
||||
- "Q&A"
|
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"api_key_missing": "Der API Key fehlt.",
|
||||
"api_key_missing": "Der API Key der für diesen Befehl benötigt wird ist nicht angegeben.",
|
||||
"quote_deleted": "Zitat gelöscht",
|
||||
"redacted_too_long": "Wurde entfernt da es zu lang ist.",
|
||||
"trigger": "Auslöser",
|
||||
@@ -10,7 +10,7 @@
|
||||
"banned_user": "Nutzer gebannt",
|
||||
"byedel_off": "Die automatische Löschung der Verabschiedungs Nachrichten wurde deaktiviert.",
|
||||
"byedel_on": "Verabschiedungs Nachrichten werden nach {0} Sekunden gelöscht.",
|
||||
"byemsg_cur": "Derzeitige Verabschiedungs Nachricht: {0}",
|
||||
"byemsg_cur": "Derzeitige Verabschiedungs Nachricht",
|
||||
"byemsg_enable": "Beim schreiben von {0} werden die Verabschiedungs Nachrichten aktiviert.",
|
||||
"byemsg_new": "Neue Verabschiedungs Nachricht gesetzt",
|
||||
"bye_off": "Abschiedansagen ausgeschaltet.",
|
||||
@@ -922,9 +922,9 @@
|
||||
"pages": "Seiten",
|
||||
"favorites": "Favoriten",
|
||||
"tags": "Stichworte",
|
||||
"invalid_emoji_link": "Der angegebene Link is entweder kein Bild, oder größer als 256KB.",
|
||||
"emoji_add_error": "Fehler beim hinzufügen des Emoji. Es sind keine Emoji slots mehr vorhanden, oder die Bildgröße ist unangemessen.",
|
||||
"emoji_added": "Neuen Emoji hinzugefügt: {0}",
|
||||
"invalid_emoji_link": "",
|
||||
"emoji_add_error": "",
|
||||
"emoji_added": "",
|
||||
"boost_on": "",
|
||||
"boost_off": "",
|
||||
"boostmsg_cur": "",
|
||||
@@ -932,16 +932,16 @@
|
||||
"boostmsg_new": "",
|
||||
"boostdel_off": "",
|
||||
"boostdel_on": "",
|
||||
"log_ignored_channels": "Ignorierte Kanäle",
|
||||
"log_ignored_users": "Ignorierte User",
|
||||
"log_ignore_user": "Logging wird User {0} ignorieren",
|
||||
"log_not_ignore_user": "Logging wird nicht länger User {0} ignorieren",
|
||||
"log_ignore_chan": "Logging wird Kanal {0} ignorieren",
|
||||
"log_not_ignore_chan": "Logging wird nicht länger Kanal {0} ignorieren",
|
||||
"log_ignored_channels": "",
|
||||
"log_ignored_users": "",
|
||||
"log_ignore_user": "",
|
||||
"log_not_ignore_user": "",
|
||||
"log_ignore_chan": "",
|
||||
"log_not_ignore_chan": "",
|
||||
"streams_cleared": "",
|
||||
"warn_weight": "Gewicht: {0}",
|
||||
"warn_count": "{0} momentan, {1} insgesamt",
|
||||
"mass_ban_in_progress": "Es werden {0} User gebannt...",
|
||||
"warn_weight": "",
|
||||
"warn_count": "",
|
||||
"mass_ban_in_progress": "",
|
||||
"mass_ban_completed": "",
|
||||
"reminder_server_list": "",
|
||||
"imageonly_enable": "",
|
||||
@@ -975,77 +975,5 @@
|
||||
"exprs_cleared": "",
|
||||
"expr_reset": "",
|
||||
"expr_set": "",
|
||||
"expr_edited": "",
|
||||
"stream_online_delete_enabled": "",
|
||||
"stream_online_delete_disabled": "",
|
||||
"club_create_error_name": "",
|
||||
"club_desc_update": "",
|
||||
"bank_accounts": "",
|
||||
"module_description_medusa": "",
|
||||
"list_of_medusae": "",
|
||||
"list_of_unloaded": "",
|
||||
"medusa_name_not_found": "",
|
||||
"medusa_info": "",
|
||||
"sneks_count": "",
|
||||
"commands_count": "",
|
||||
"no_medusa_loaded": "",
|
||||
"no_medusa_available": "",
|
||||
"loaded_medusae": "",
|
||||
"medusa_not_loaded": "",
|
||||
"medusa_possibly_cant_unload": "",
|
||||
"medusa_loaded": "",
|
||||
"medusa_unloaded": "",
|
||||
"medusa_empty": "",
|
||||
"medusa_already_loaded": "",
|
||||
"medusa_invalid_not_found": "",
|
||||
"bank_balance": "",
|
||||
"bank_deposited": "",
|
||||
"bank_withdrew": "",
|
||||
"bank_withdraw_insuff": "",
|
||||
"cmd_group_commands": "",
|
||||
"limit_reached": "",
|
||||
"feature_limit_reached_you": "",
|
||||
"feature_limit_reached_owner": "",
|
||||
"feature_limit_reached_either": "",
|
||||
"tier": "",
|
||||
"pledge": "",
|
||||
"expires": "",
|
||||
"commands": "",
|
||||
"groups": "",
|
||||
"modules": "",
|
||||
"no_quota_found": "",
|
||||
"patron_info": "",
|
||||
"quotas": "",
|
||||
"patron_not_enabled": "",
|
||||
"results_in": "",
|
||||
"patron_msg_sent": "",
|
||||
"cards": "",
|
||||
"hand_value": "",
|
||||
"roll2": "",
|
||||
"rolls": "",
|
||||
"available_tests": "",
|
||||
"test_results_for": "",
|
||||
"multiplier": "",
|
||||
"trivia_ended": "",
|
||||
"card": "",
|
||||
"guess": "",
|
||||
"repeater_skip_next": "",
|
||||
"repeater_dont_skip_next": "",
|
||||
"remind_timely": "",
|
||||
"xp_shop_disabled": "",
|
||||
"timely_time": "",
|
||||
"buy": "",
|
||||
"use": "",
|
||||
"in_use": "",
|
||||
"xp_shop_item_cant_use": "",
|
||||
"linkonly_enable": "",
|
||||
"linkonly_disable": "",
|
||||
"xp_shop_buy_required_tier": "",
|
||||
"available_commands": "",
|
||||
"xpadd_users": "",
|
||||
"xpshop_buy_success": "",
|
||||
"patron_insuff_tier": "",
|
||||
"xpshop_already_owned": "",
|
||||
"xpshop_item_not_found": "",
|
||||
"xpshop_website": ""
|
||||
"expr_edited": ""
|
||||
}
|
@@ -12,7 +12,6 @@
|
||||
"invalid_emoji_link": "Specified link is either not an image or exceeds 256KB.",
|
||||
"emoji_add_error": "Error adding emoji. You either ran out of emoji slots, or image size is inadequate.",
|
||||
"emoji_added": "Added a new emoji: {0}",
|
||||
"emoji_not_removed": "The following emojis were not removed: {0}",
|
||||
"fw_cleared": "Removed all filtered words and filtered words channel settings.",
|
||||
"aliases_cleared": "All {0} aliases on this server have been removed.",
|
||||
"no_results": "No results found.",
|
||||
@@ -142,10 +141,6 @@
|
||||
"rar_err": "Failed to remove roles. I have insufficient permissions.",
|
||||
"rc": "Color of {0} role has been changed.",
|
||||
"rc_perms": "Error occurred due to invalid color or insufficient permissions.",
|
||||
"color": "Color",
|
||||
"icon": "Icon",
|
||||
"hoisted": "Hoisted",
|
||||
"mentionable": "Mentionable",
|
||||
"remrole": "Successfully removed role {0} from user {1}",
|
||||
"remrole_err": "Failed to remove role. I have insufficient permissions.",
|
||||
"renrole": "Role renamed.",
|
||||
|
@@ -975,77 +975,5 @@
|
||||
"exprs_cleared": "L'ensemble des {0} expressions du serveur ont été retirées.",
|
||||
"expr_reset": "L'expression avec l'id {0} ne rajoutera plus de réactions.",
|
||||
"expr_set": "L'expression avec l'id {0} ajoutera automatiquement ces réactions au message de réponse : {1}",
|
||||
"expr_edited": "Expression éditée",
|
||||
"stream_online_delete_enabled": "Aucune méduse de ce nom n'a été trouvée ou le fichier était invalide",
|
||||
"stream_online_delete_disabled": "Les notifications de diffusions en ligne ne seront plus supprimées quand la diffusion sera hors ligne.",
|
||||
"club_create_error_name": "Échec de la création du club. Un club existe du même nom existe déjà.",
|
||||
"club_desc_update": "La description du club a été mise à jour",
|
||||
"bank_accounts": "Comptes bancaires",
|
||||
"module_description_medusa": "**Unique au propriétaire du bot.** Charger, décharger et maintenez des modules dynamiques. Découvrez en plus [ici](https://nadekobot.readthedocs.io/en/latest/medusa/creating-a-medusa/)",
|
||||
"list_of_medusae": "Liste des méduses",
|
||||
"list_of_unloaded": "Liste des méduses disponible",
|
||||
"medusa_name_not_found": "Une méduse de ce nom n'existe pas ou n'est pas chargée.",
|
||||
"medusa_info": "Information de la méduse",
|
||||
"sneks_count": "Sneks ({0})",
|
||||
"commands_count": "Commandes ({0})",
|
||||
"no_medusa_loaded": "Aucunes méduses de chargées.",
|
||||
"no_medusa_available": "Aucune méduse de disponible.",
|
||||
"loaded_medusae": "Méduses chargées",
|
||||
"medusa_not_loaded": "La méduse de ce nom n'est pas chargée.",
|
||||
"medusa_possibly_cant_unload": "La méduse n'est probablement pas entièrement chargée. Redémarrez le bot si le problème persiste.",
|
||||
"medusa_loaded": "La méduse {0} a été chargée.",
|
||||
"medusa_unloaded": "La méduse {0} a été déchargée.",
|
||||
"medusa_empty": "La méduse n'a pas été chargée puisqu'elle ne contient aucun Sneks.",
|
||||
"medusa_already_loaded": "La méduse {0} est déjà chargée",
|
||||
"medusa_invalid_not_found": "Aucune méduse de ce nom n'a été trouvée ou le fichier était invalide",
|
||||
"bank_balance": "Vous disposez de {0} sur votre compte bancaire.",
|
||||
"bank_deposited": "Vous avez déposé {0} sur votre compte bancaire.",
|
||||
"bank_withdrew": "Vous avez retiré {0} de votre compte bancaire.",
|
||||
"bank_withdraw_insuff": "Vous ne disposez pas suffisamment de {0} sur votre compte bancaire.",
|
||||
"cmd_group_commands": "Groupe de commande '{0}'",
|
||||
"limit_reached": "La limite des fonctionnalités de {0} a été atteinte.",
|
||||
"feature_limit_reached_you": "Vous avez atteint la limite de {0} pour la fonctionnalité {1}. Vous pouvez augmenter cette limite en augmentant votre niveau de contribution.",
|
||||
"feature_limit_reached_owner": "Le propriétaire du serveur a atteint la limite de {0} pour la fonctionnalité {1}. Ce dernier peut augmenter cette limite en augmentant son niveau de contribution.",
|
||||
"feature_limit_reached_either": "La limite de {0} pour la fonctionnalité {1} a été atteinte. Soit vous ou le propriétaire du serveur peut augmenter cette limite en augmentant le niveau de contribution.",
|
||||
"tier": "Niveau",
|
||||
"pledge": "Promesse",
|
||||
"expires": "Expire",
|
||||
"commands": "Commandes",
|
||||
"groups": "Groupes",
|
||||
"modules": "Modules",
|
||||
"no_quota_found": "Aucun quota de trouvé.",
|
||||
"patron_info": "Info de la·e contributeur·rice",
|
||||
"quotas": "<<< Quotas >>>",
|
||||
"patron_not_enabled": "Le système de contribution est désactivé.",
|
||||
"results_in": "{0} résulte en {1}s",
|
||||
"patron_msg_sent": "L'envoi de messages aux contributeur·rice·s de niveau {1} et au-delà a été effectué. {1} ont été envoyés avec succès et {2} ont échoué.",
|
||||
"cards": "Cartes",
|
||||
"hand_value": "Valeur de la main",
|
||||
"roll2": "Lancé",
|
||||
"rolls": "Lancés",
|
||||
"available_tests": "Tests disponibles",
|
||||
"test_results_for": "Résultats du test pour {0}",
|
||||
"multiplier": "Multiplier",
|
||||
"trivia_ended": "Le jeu de culture générale est terminé",
|
||||
"card": "Carte",
|
||||
"guess": "Deviner",
|
||||
"repeater_skip_next": "Le prochain rappel de ce répéteur sera ignoré.",
|
||||
"repeater_dont_skip_next": "Le prochain rappel de ce répéteur ne sera pas ignoré.",
|
||||
"remind_timely": "Je vous notifierai à propos de votre récompense opportune {0}",
|
||||
"xp_shop_disabled": "Le magasin d'XP est désactivé par le propriétaire, ou il n'y a aucun item à vendre.",
|
||||
"timely_time": "Il est l'heure de votre récompense opportune.",
|
||||
"buy": "Acheter",
|
||||
"use": "Utiliser",
|
||||
"in_use": "En utilisation",
|
||||
"xp_shop_item_cant_use": "Vous ne pouvez pas utiliser cet item car il ne vous appartient pas ou il n'existe pas.",
|
||||
"linkonly_enable": "Ce channel est désormais limité aux liens.",
|
||||
"linkonly_disable": "Ce channel n'est désormais plus limité aux liens.",
|
||||
"xp_shop_buy_required_tier": "Acheter des items de ce magasin requiert d'être Tier Patron {0} ou au-delà.",
|
||||
"available_commands": "Commandes disponibles",
|
||||
"xpadd_users": "Ajout de {0} XP du serveur à l'utilisateur {1}.",
|
||||
"xpshop_buy_success": "Vous avez acheté avec succès `{0}/{1}`",
|
||||
"patron_insuff_tier": "Votre Tier Patron est insuffisant pour réaliser cette action.",
|
||||
"xpshop_already_owned": "Vous disposez déjà de cet item.",
|
||||
"xpshop_item_not_found": "Aucun item avec cette clé n'existe.",
|
||||
"xpshop_website": "Vous pouvez voir la liste de tous les items du magasin d'XP ici: <https://xpshop.nadeko.bot>"
|
||||
"expr_edited": "Expression éditée"
|
||||
}
|
Reference in New Issue
Block a user