mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-10 09:18:27 -04:00
Compare commits
50 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
699a5e0c8c | ||
|
76fedc5ff1 | ||
|
992aa781fa | ||
|
e52bf798cf | ||
|
710f4f2ed8 | ||
|
dcc27a4a99 | ||
|
032b6bfd57 | ||
|
737bbb8ec1 | ||
|
e71708f5e8 | ||
|
9841d72622 | ||
|
391a3f0513 | ||
|
aa3409a9cf | ||
|
9a80383327 | ||
|
7e61f7fb46 | ||
|
d526a2fac6 | ||
|
80efb954f1 | ||
|
67c156e40f | ||
|
26f76ef7b9 | ||
|
90cee1bfa9 | ||
|
26171a0ff7 | ||
|
59447d7aa8 | ||
|
a4053d0666 | ||
|
fcd016aed3 | ||
|
719f62a0ac | ||
|
9b9fa2f357 | ||
|
823f4731c3 | ||
|
5feff8f4b2 | ||
|
95d20609a8 | ||
|
b416b9f963 | ||
|
a7c48b13a0 | ||
|
003b71ba00 | ||
|
89593dcc2c | ||
|
fa9352d1f8 | ||
|
4a2f7ffc76 | ||
|
fb1555c075 | ||
|
7a0b409d88 | ||
|
c869f2e335 | ||
|
01da7e813e | ||
|
76b7e09905 | ||
|
8dca948224 | ||
|
ffcbfe6467 | ||
|
d5c70def93 | ||
|
34dccab16b | ||
|
2fab61c4f8 | ||
|
9f96edbb46 | ||
|
3c23b58088 | ||
|
e10530bc0e | ||
|
f24692e79b | ||
|
8a6edc17e4 | ||
|
9ce2837f5a |
32
CHANGELOG.md
32
CHANGELOG.md
@@ -2,6 +2,38 @@
|
||||
|
||||
Experimental changelog. Mostly based on [keepachangelog](https://keepachangelog.com/en/1.0.0/) except date format. a-c-f-r-o
|
||||
|
||||
## [4.3.11] - 21.01.2023
|
||||
|
||||
### Added
|
||||
|
||||
- Added `.doas` Bot owner only command
|
||||
- Added `.stickeradd` command
|
||||
|
||||
### Changed
|
||||
|
||||
- `.waifuinfo` optimized
|
||||
- You can now specify an optional custom message in `.feed` and `.yun` which will be posted along with an update
|
||||
- Greet/bye messages will now get disabled if they're set to a deleted/unknown channel
|
||||
- Updated response strings
|
||||
- `.translate` now supports many more languages
|
||||
- `.translangs` prettier output
|
||||
|
||||
### Fixed
|
||||
|
||||
- Added logging for thread events
|
||||
- Fixed a bug for `.quotedeleteauthor` causing the executing user to delete own messages
|
||||
- Fixed TimeOut punishment not alklowing duration
|
||||
- Fixed a nullref in streamrole service
|
||||
- Fixed some potential causes for ratelimit due to default message retry settings
|
||||
- Fixed a patron rewards bug caused by monthly donation checking not accounting for year increase
|
||||
- Fixed a patron rewards bug for users who connected the same discord account with multiple patreon accounts
|
||||
- `.deletecurrency` will now also reset banked currency
|
||||
- Fixed DMHelpText reply
|
||||
- `.h` command show now properly show both channel and server user permission requirements
|
||||
- Many fixes and improvements to medusa system
|
||||
- Fixed trivia --nohint
|
||||
- `.joinrace` will no longer fail if the user isn't in the database yet
|
||||
|
||||
## [4.3.10] - 10.11.2022
|
||||
|
||||
### Added
|
||||
|
@@ -15,11 +15,14 @@ w# Setting up NadekoBot on Linux
|
||||
|
||||
It is recommended that you use **Ubuntu 20.04**, as there have been nearly no problems with it. Also, **32-bit systems are incompatible**.
|
||||
|
||||
|
||||
### Ubuntu 22.04 is ruled as incompatible so double check which ubuntu version you are using.
|
||||
|
||||
##### Compatible operating systems:
|
||||
|
||||
- Ubuntu: 16.04, 18.04, 20.04, 21.04, 21.10, 22.04
|
||||
- Ubuntu: 16.04, 18.04, 20.04, 21.04, 21.10
|
||||
- Mint: 19, 20
|
||||
- Debian: 9, 10
|
||||
- Debian: 10, 11
|
||||
- CentOS: 7
|
||||
- openSUSE
|
||||
- Fedora: 33, 34, 35
|
||||
|
@@ -147,6 +147,7 @@ This section will guide you through how to create a simple custom medusa. You ca
|
||||
<!-- Use latest .net features -->
|
||||
<LangVersion>preview</LangVersion>
|
||||
<EnablePreviewFeatures>true</EnablePreviewFeatures>
|
||||
<GenerateRequiresPreviewFeaturesAttribute>true</GenerateRequiresPreviewFeaturesAttribute>
|
||||
|
||||
<!-- tell .net that this library will be used as a plugin -->
|
||||
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||
|
10
src/Nadeko.Medusa/Attributes/MedusaPermAttribute.cs
Normal file
10
src/Nadeko.Medusa/Attributes/MedusaPermAttribute.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace Nadeko.Snake;
|
||||
|
||||
/// <summary>
|
||||
/// Used as a marker class for bot_perm and user_perm Attributes
|
||||
/// Has no functionality.
|
||||
/// </summary>
|
||||
public abstract class MedusaPermAttribute : Attribute
|
||||
{
|
||||
|
||||
}
|
7
src/Nadeko.Medusa/Attributes/bot_owner_onlyAttribute.cs
Normal file
7
src/Nadeko.Medusa/Attributes/bot_owner_onlyAttribute.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Nadeko.Snake;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public sealed class bot_owner_onlyAttribute : MedusaPermAttribute
|
||||
{
|
||||
|
||||
}
|
23
src/Nadeko.Medusa/Attributes/bot_permAttribute.cs
Normal file
23
src/Nadeko.Medusa/Attributes/bot_permAttribute.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using Discord;
|
||||
|
||||
namespace Nadeko.Snake;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
||||
public sealed class bot_permAttribute : MedusaPermAttribute
|
||||
{
|
||||
public GuildPermission? GuildPerm { get; }
|
||||
public ChannelPermission? ChannelPerm { get; }
|
||||
|
||||
|
||||
public bot_permAttribute(GuildPermission perm)
|
||||
{
|
||||
GuildPerm = perm;
|
||||
ChannelPerm = null;
|
||||
}
|
||||
|
||||
public bot_permAttribute(ChannelPermission perm)
|
||||
{
|
||||
ChannelPerm = perm;
|
||||
GuildPerm = null;
|
||||
}
|
||||
}
|
22
src/Nadeko.Medusa/Attributes/user_permAttribute.cs
Normal file
22
src/Nadeko.Medusa/Attributes/user_permAttribute.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using Discord;
|
||||
|
||||
namespace Nadeko.Snake;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
||||
public sealed class user_permAttribute : MedusaPermAttribute
|
||||
{
|
||||
public GuildPermission? GuildPerm { get; }
|
||||
public ChannelPermission? ChannelPerm { get; }
|
||||
|
||||
public user_permAttribute(GuildPermission perm)
|
||||
{
|
||||
GuildPerm = perm;
|
||||
ChannelPerm = null;
|
||||
}
|
||||
|
||||
public user_permAttribute(ChannelPermission perm)
|
||||
{
|
||||
ChannelPerm = perm;
|
||||
GuildPerm = null;
|
||||
}
|
||||
}
|
@@ -22,6 +22,11 @@ public abstract class AnyContext
|
||||
/// The user who invoked the command
|
||||
/// </summary>
|
||||
public abstract IUser User { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Bot user
|
||||
/// </summary>
|
||||
public abstract ISelfUser Bot { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Provides access to strings used by this medusa
|
||||
|
@@ -10,7 +10,7 @@ public static class MedusaExtensions
|
||||
embed: embed.Build(),
|
||||
options: new()
|
||||
{
|
||||
RetryMode = RetryMode.AlwaysRetry
|
||||
RetryMode = RetryMode.Retry502
|
||||
});
|
||||
|
||||
// unlocalized
|
||||
|
@@ -69,7 +69,7 @@ public sealed class Bot
|
||||
: GatewayIntents.AllUnprivileged,
|
||||
LogGatewayIntentWarnings = false,
|
||||
FormatUsersInBidirectionalUnicode = false,
|
||||
DefaultRetryMode = RetryMode.AlwaysRetry ^ RetryMode.RetryRatelimit
|
||||
DefaultRetryMode = RetryMode.Retry502
|
||||
});
|
||||
|
||||
_commandService = new(new()
|
||||
|
@@ -3,7 +3,7 @@ using NadekoBot.Modules.Administration.Services;
|
||||
|
||||
namespace Discord;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
||||
public class UserPermAttribute : RequireUserPermissionAttribute
|
||||
{
|
||||
public UserPermAttribute(GuildPerm permission)
|
||||
|
@@ -29,4 +29,7 @@ public enum LogType
|
||||
VoicePresenceTts,
|
||||
UserMuted,
|
||||
UserWarned,
|
||||
|
||||
ThreadDeleted,
|
||||
ThreadCreated
|
||||
}
|
@@ -5,9 +5,11 @@ public sealed class DmContextAdapter : DmContext
|
||||
public override IMedusaStrings Strings { get; }
|
||||
public override IDMChannel Channel { get; }
|
||||
public override IUserMessage Message { get; }
|
||||
public override ISelfUser Bot { get; }
|
||||
public override IUser User
|
||||
=> Message.Author;
|
||||
|
||||
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly Lazy<IEmbedBuilderService> _ebs;
|
||||
private readonly Lazy<IBotStrings> _botStrings;
|
||||
@@ -26,6 +28,7 @@ public sealed class DmContextAdapter : DmContext
|
||||
|
||||
Channel = ch;
|
||||
Message = ctx.Message;
|
||||
Bot = ctx.Client.CurrentUser;
|
||||
|
||||
|
||||
_ebs = new(_services.GetRequiredService<IEmbedBuilderService>());
|
||||
|
31
src/NadekoBot/Common/Medusa/Adapters/FilterAdapter.cs
Normal file
31
src/NadekoBot/Common/Medusa/Adapters/FilterAdapter.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
namespace Nadeko.Medusa.Adapters;
|
||||
|
||||
public class FilterAdapter : PreconditionAttribute
|
||||
{
|
||||
private readonly FilterAttribute _filterAttribute;
|
||||
private readonly IMedusaStrings _strings;
|
||||
|
||||
public FilterAdapter(FilterAttribute filterAttribute,
|
||||
IMedusaStrings strings)
|
||||
{
|
||||
_filterAttribute = filterAttribute;
|
||||
_strings = strings;
|
||||
}
|
||||
|
||||
public override async Task<PreconditionResult> CheckPermissionsAsync(
|
||||
ICommandContext context,
|
||||
CommandInfo command,
|
||||
IServiceProvider services)
|
||||
{
|
||||
var medusaContext = ContextAdapterFactory.CreateNew(context,
|
||||
_strings,
|
||||
services);
|
||||
|
||||
var result = await _filterAttribute.CheckAsync(medusaContext);
|
||||
|
||||
if (!result)
|
||||
return PreconditionResult.FromError($"Precondition '{_filterAttribute.GetType().Name}' failed.");
|
||||
|
||||
return PreconditionResult.FromSuccess();
|
||||
}
|
||||
}
|
@@ -11,6 +11,7 @@ public sealed class GuildContextAdapter : GuildContext
|
||||
public override IMedusaStrings Strings { get; }
|
||||
public override IGuild Guild { get; }
|
||||
public override ITextChannel Channel { get; }
|
||||
public override ISelfUser Bot { get; }
|
||||
public override IUserMessage Message
|
||||
=> _ctx.Message;
|
||||
|
||||
@@ -28,6 +29,7 @@ public sealed class GuildContextAdapter : GuildContext
|
||||
|
||||
Strings = strings;
|
||||
User = (IGuildUser)ctx.User;
|
||||
Bot = ctx.Client.CurrentUser;
|
||||
|
||||
_services = services;
|
||||
_ebs = new(_services.GetRequiredService<IEmbedBuilderService>());
|
||||
|
@@ -22,8 +22,6 @@ public sealed class MedusaConfigService : ConfigServiceBase<MedusaConfig>, IMedu
|
||||
|
||||
public void AddLoadedMedusa(string name)
|
||||
{
|
||||
name = name.Trim().ToLowerInvariant();
|
||||
|
||||
ModifyConfig(conf =>
|
||||
{
|
||||
if (conf.Loaded is null)
|
||||
@@ -36,8 +34,6 @@ public sealed class MedusaConfigService : ConfigServiceBase<MedusaConfig>, IMedu
|
||||
|
||||
public void RemoveLoadedMedusa(string name)
|
||||
{
|
||||
name = name.Trim().ToLowerInvariant();
|
||||
|
||||
ModifyConfig(conf =>
|
||||
{
|
||||
if (conf.Loaded is null)
|
||||
|
@@ -1,5 +1,6 @@
|
||||
using Discord.Commands.Builders;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Nadeko.Medusa.Adapters;
|
||||
using NadekoBot.Common.ModuleBehaviors;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
@@ -382,6 +383,11 @@ public sealed class MedusaLoaderService : IMedusaLoaderService, IReadyExecutor,
|
||||
{
|
||||
var m = mb.WithName(snekInfo.Name);
|
||||
|
||||
foreach (var f in snekInfo.Filters)
|
||||
{
|
||||
m.AddPrecondition(new FilterAdapter(f, strings));
|
||||
}
|
||||
|
||||
foreach (var cmd in snekInfo.Commands)
|
||||
{
|
||||
m.AddCommand(cmd.Aliases.First(),
|
||||
@@ -390,7 +396,7 @@ public sealed class MedusaLoaderService : IMedusaLoaderService, IReadyExecutor,
|
||||
new(cmd),
|
||||
new(medusaServices),
|
||||
strings),
|
||||
CreateCommandFactory(medusaName, cmd));
|
||||
CreateCommandFactory(medusaName, cmd, strings));
|
||||
}
|
||||
|
||||
foreach (var subInfo in snekInfo.Subsneks)
|
||||
@@ -399,7 +405,7 @@ public sealed class MedusaLoaderService : IMedusaLoaderService, IReadyExecutor,
|
||||
|
||||
private static readonly RequireContextAttribute _reqGuild = new RequireContextAttribute(ContextType.Guild);
|
||||
private static readonly RequireContextAttribute _reqDm = new RequireContextAttribute(ContextType.DM);
|
||||
private Action<CommandBuilder> CreateCommandFactory(string medusaName, SnekCommandData cmd)
|
||||
private Action<CommandBuilder> CreateCommandFactory(string medusaName, SnekCommandData cmd, IMedusaStrings strings)
|
||||
=> (cb) =>
|
||||
{
|
||||
cb.AddAliases(cmd.Aliases.Skip(1).ToArray());
|
||||
@@ -408,6 +414,31 @@ public sealed class MedusaLoaderService : IMedusaLoaderService, IReadyExecutor,
|
||||
cb.AddPrecondition(_reqGuild);
|
||||
else if (cmd.ContextType == CommandContextType.Dm)
|
||||
cb.AddPrecondition(_reqDm);
|
||||
|
||||
foreach (var f in cmd.Filters)
|
||||
cb.AddPrecondition(new FilterAdapter(f, strings));
|
||||
|
||||
foreach (var ubp in cmd.UserAndBotPerms)
|
||||
{
|
||||
if (ubp is user_permAttribute up)
|
||||
{
|
||||
if (up.GuildPerm is { } gp)
|
||||
cb.AddPrecondition(new UserPermAttribute(gp));
|
||||
else if (up.ChannelPerm is { } cp)
|
||||
cb.AddPrecondition(new UserPermAttribute(cp));
|
||||
}
|
||||
else if (ubp is bot_permAttribute bp)
|
||||
{
|
||||
if (bp.GuildPerm is { } gp)
|
||||
cb.AddPrecondition(new BotPermAttribute(gp));
|
||||
else if (bp.ChannelPerm is { } cp)
|
||||
cb.AddPrecondition(new BotPermAttribute(cp));
|
||||
}
|
||||
else if (ubp is bot_owner_onlyAttribute)
|
||||
{
|
||||
cb.AddPrecondition(new OwnerOnlyAttribute());
|
||||
}
|
||||
}
|
||||
|
||||
cb.WithPriority(cmd.Priority);
|
||||
|
||||
@@ -750,8 +781,10 @@ public sealed class MedusaLoaderService : IMedusaLoaderService, IReadyExecutor,
|
||||
var cmds = new List<SnekCommandData>();
|
||||
foreach (var method in methodInfos)
|
||||
{
|
||||
var filters = method.GetCustomAttributes<FilterAttribute>().ToArray();
|
||||
var prio = method.GetCustomAttribute<prioAttribute>()?.Priority ?? 0;
|
||||
var filters = method.GetCustomAttributes<FilterAttribute>(true).ToArray();
|
||||
var userAndBotPerms = method.GetCustomAttributes<MedusaPermAttribute>(true)
|
||||
.ToArray();
|
||||
var prio = method.GetCustomAttribute<prioAttribute>(true)?.Priority ?? 0;
|
||||
|
||||
var paramInfos = method.GetParameters();
|
||||
var cmdParams = new List<ParamData>();
|
||||
@@ -828,7 +861,7 @@ public sealed class MedusaLoaderService : IMedusaLoaderService, IReadyExecutor,
|
||||
}
|
||||
|
||||
|
||||
var cmdAttribute = method.GetCustomAttribute<cmdAttribute>()!;
|
||||
var cmdAttribute = method.GetCustomAttribute<cmdAttribute>(true)!;
|
||||
var aliases = cmdAttribute.Aliases;
|
||||
if (aliases.Length == 0)
|
||||
aliases = new[] { method.Name.ToLowerInvariant() };
|
||||
@@ -838,6 +871,7 @@ public sealed class MedusaLoaderService : IMedusaLoaderService, IReadyExecutor,
|
||||
method,
|
||||
instance,
|
||||
filters,
|
||||
userAndBotPerms,
|
||||
cmdContext,
|
||||
diParams,
|
||||
cmdParams,
|
||||
|
@@ -11,6 +11,7 @@ public sealed class SnekCommandData
|
||||
MethodInfo methodInfo,
|
||||
Snek module,
|
||||
FilterAttribute[] filters,
|
||||
MedusaPermAttribute[] userAndBotPerms,
|
||||
CommandContextType contextType,
|
||||
IReadOnlyList<Type> injectedParams,
|
||||
IReadOnlyList<ParamData> parameters,
|
||||
@@ -21,6 +22,7 @@ public sealed class SnekCommandData
|
||||
MethodInfo = methodInfo;
|
||||
Module = module;
|
||||
Filters = filters;
|
||||
UserAndBotPerms = userAndBotPerms;
|
||||
ContextType = contextType;
|
||||
InjectedParams = injectedParams;
|
||||
Parameters = parameters;
|
||||
@@ -28,6 +30,8 @@ public sealed class SnekCommandData
|
||||
OptionalStrings = strings;
|
||||
}
|
||||
|
||||
public MedusaPermAttribute[] UserAndBotPerms { get; set; }
|
||||
|
||||
public CommandStrings OptionalStrings { get; set; }
|
||||
|
||||
public IReadOnlyCollection<string> Aliases { get; }
|
||||
|
@@ -10,6 +10,7 @@ namespace NadekoBot.Db;
|
||||
|
||||
public class WaifuInfoStats
|
||||
{
|
||||
public int WaifuId { get; init; }
|
||||
public string FullName { get; init; }
|
||||
public long Price { get; init; }
|
||||
public string ClaimerName { get; init; }
|
||||
@@ -17,9 +18,6 @@ public class WaifuInfoStats
|
||||
public int AffinityCount { get; init; }
|
||||
public int DivorceCount { get; init; }
|
||||
public int ClaimCount { get; init; }
|
||||
public List<WaifuItem> Items { get; init; }
|
||||
public List<string> Claims { get; init; }
|
||||
public List<string> Fans { get; init; }
|
||||
}
|
||||
|
||||
public static class WaifuExtensions
|
||||
@@ -103,6 +101,7 @@ public static class WaifuExtensions
|
||||
.FirstOrDefault())
|
||||
.Select(w => new WaifuInfoStats
|
||||
{
|
||||
WaifuId = w.WaifuId,
|
||||
FullName =
|
||||
ctx.Set<DiscordUser>()
|
||||
.AsQueryable()
|
||||
@@ -135,17 +134,6 @@ public static class WaifuExtensions
|
||||
&& x.NewId == null
|
||||
&& x.UpdateType == WaifuUpdateType.Claimed),
|
||||
Price = w.Price,
|
||||
Claims = ctx.WaifuInfo.AsQueryable()
|
||||
.Include(x => x.Waifu)
|
||||
.Where(x => x.ClaimerId == w.WaifuId)
|
||||
.Select(x => x.Waifu.Username + "#" + x.Waifu.Discriminator)
|
||||
.ToList(),
|
||||
Fans = ctx.WaifuInfo.AsQueryable()
|
||||
.Include(x => x.Waifu)
|
||||
.Where(x => x.AffinityId == w.WaifuId)
|
||||
.Select(x => x.Waifu.Username + "#" + x.Waifu.Discriminator)
|
||||
.ToList(),
|
||||
Items = w.Items
|
||||
})
|
||||
.FirstOrDefault();
|
||||
|
||||
|
@@ -8,6 +8,8 @@ public class FeedSub : DbEntity
|
||||
|
||||
public ulong ChannelId { get; set; }
|
||||
public string Url { get; set; }
|
||||
|
||||
public string Message { get; set; }
|
||||
|
||||
public override int GetHashCode()
|
||||
=> Url.GetHashCode(StringComparison.InvariantCulture) ^ GuildConfigId.GetHashCode();
|
||||
|
@@ -19,6 +19,10 @@ public class LogSetting : DbEntity
|
||||
public ulong? ChannelCreatedId { get; set; }
|
||||
public ulong? ChannelDestroyedId { get; set; }
|
||||
public ulong? ChannelUpdatedId { get; set; }
|
||||
|
||||
|
||||
public ulong? ThreadDeletedId { get; set; }
|
||||
public ulong? ThreadCreatedId { get; set; }
|
||||
|
||||
public ulong? UserMutedId { get; set; }
|
||||
|
||||
|
@@ -7,7 +7,7 @@ public class WaifuInfo : DbEntity
|
||||
{
|
||||
public int WaifuId { get; set; }
|
||||
public DiscordUser Waifu { get; set; }
|
||||
|
||||
|
||||
public int? ClaimerId { get; set; }
|
||||
public DiscordUser Claimer { get; set; }
|
||||
|
||||
|
@@ -7,4 +7,4 @@ public class WaifuItem : DbEntity
|
||||
public int? WaifuInfoId { get; set; }
|
||||
public string ItemEmoji { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
|
3624
src/NadekoBot/Migrations/Mysql/20221118195208_log-thread.Designer.cs
generated
Normal file
3624
src/NadekoBot/Migrations/Mysql/20221118195208_log-thread.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
35
src/NadekoBot/Migrations/Mysql/20221118195208_log-thread.cs
Normal file
35
src/NadekoBot/Migrations/Mysql/20221118195208_log-thread.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace NadekoBot.Migrations.Mysql
|
||||
{
|
||||
public partial class logthread : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<ulong>(
|
||||
name: "threadcreatedid",
|
||||
table: "logsettings",
|
||||
type: "bigint unsigned",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<ulong>(
|
||||
name: "threaddeletedid",
|
||||
table: "logsettings",
|
||||
type: "bigint unsigned",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "threadcreatedid",
|
||||
table: "logsettings");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "threaddeletedid",
|
||||
table: "logsettings");
|
||||
}
|
||||
}
|
||||
}
|
3628
src/NadekoBot/Migrations/Mysql/20221122204432_feed-text.Designer.cs
generated
Normal file
3628
src/NadekoBot/Migrations/Mysql/20221122204432_feed-text.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
26
src/NadekoBot/Migrations/Mysql/20221122204432_feed-text.cs
Normal file
26
src/NadekoBot/Migrations/Mysql/20221122204432_feed-text.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace NadekoBot.Migrations.Mysql
|
||||
{
|
||||
public partial class feedtext : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "message",
|
||||
table: "feedsub",
|
||||
type: "longtext",
|
||||
nullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "message",
|
||||
table: "feedsub");
|
||||
}
|
||||
}
|
||||
}
|
@@ -975,6 +975,10 @@ namespace NadekoBot.Migrations.Mysql
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("guildconfigid");
|
||||
|
||||
b.Property<string>("Message")
|
||||
.HasColumnType("longtext")
|
||||
.HasColumnName("message");
|
||||
|
||||
b.Property<string>("Url")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(255)")
|
||||
@@ -1518,6 +1522,14 @@ namespace NadekoBot.Migrations.Mysql
|
||||
.HasColumnType("bigint unsigned")
|
||||
.HasColumnName("messageupdatedid");
|
||||
|
||||
b.Property<ulong?>("ThreadCreatedId")
|
||||
.HasColumnType("bigint unsigned")
|
||||
.HasColumnName("threadcreatedid");
|
||||
|
||||
b.Property<ulong?>("ThreadDeletedId")
|
||||
.HasColumnType("bigint unsigned")
|
||||
.HasColumnName("threaddeletedid");
|
||||
|
||||
b.Property<ulong?>("UserBannedId")
|
||||
.HasColumnType("bigint unsigned")
|
||||
.HasColumnName("userbannedid");
|
||||
|
3772
src/NadekoBot/Migrations/PostgreSql/20221118195200_log-thread.Designer.cs
generated
Normal file
3772
src/NadekoBot/Migrations/PostgreSql/20221118195200_log-thread.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,35 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace NadekoBot.Migrations.PostgreSql
|
||||
{
|
||||
public partial class logthread : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<decimal>(
|
||||
name: "threadcreatedid",
|
||||
table: "logsettings",
|
||||
type: "numeric(20,0)",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<decimal>(
|
||||
name: "threaddeletedid",
|
||||
table: "logsettings",
|
||||
type: "numeric(20,0)",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "threadcreatedid",
|
||||
table: "logsettings");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "threaddeletedid",
|
||||
table: "logsettings");
|
||||
}
|
||||
}
|
||||
}
|
3776
src/NadekoBot/Migrations/PostgreSql/20221122204423_feed-text.Designer.cs
generated
Normal file
3776
src/NadekoBot/Migrations/PostgreSql/20221122204423_feed-text.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,25 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace NadekoBot.Migrations.PostgreSql
|
||||
{
|
||||
public partial class feedtext : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "message",
|
||||
table: "feedsub",
|
||||
type: "text",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "message",
|
||||
table: "feedsub");
|
||||
}
|
||||
}
|
||||
}
|
@@ -1023,6 +1023,10 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("guildconfigid");
|
||||
|
||||
b.Property<string>("Message")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("message");
|
||||
|
||||
b.Property<string>("Url")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
@@ -1590,6 +1594,14 @@ namespace NadekoBot.Migrations.PostgreSql
|
||||
.HasColumnType("numeric(20,0)")
|
||||
.HasColumnName("messageupdatedid");
|
||||
|
||||
b.Property<decimal?>("ThreadCreatedId")
|
||||
.HasColumnType("numeric(20,0)")
|
||||
.HasColumnName("threadcreatedid");
|
||||
|
||||
b.Property<decimal?>("ThreadDeletedId")
|
||||
.HasColumnType("numeric(20,0)")
|
||||
.HasColumnName("threaddeletedid");
|
||||
|
||||
b.Property<decimal?>("UserBannedId")
|
||||
.HasColumnType("numeric(20,0)")
|
||||
.HasColumnName("userbannedid");
|
||||
|
2907
src/NadekoBot/Migrations/Sqlite/20221118195152_log-thread.Designer.cs
generated
Normal file
2907
src/NadekoBot/Migrations/Sqlite/20221118195152_log-thread.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
35
src/NadekoBot/Migrations/Sqlite/20221118195152_log-thread.cs
Normal file
35
src/NadekoBot/Migrations/Sqlite/20221118195152_log-thread.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace NadekoBot.Migrations
|
||||
{
|
||||
public partial class logthread : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<ulong>(
|
||||
name: "ThreadCreatedId",
|
||||
table: "LogSettings",
|
||||
type: "INTEGER",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<ulong>(
|
||||
name: "ThreadDeletedId",
|
||||
table: "LogSettings",
|
||||
type: "INTEGER",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "ThreadCreatedId",
|
||||
table: "LogSettings");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "ThreadDeletedId",
|
||||
table: "LogSettings");
|
||||
}
|
||||
}
|
||||
}
|
2910
src/NadekoBot/Migrations/Sqlite/20221122204324_feed-text.Designer.cs
generated
Normal file
2910
src/NadekoBot/Migrations/Sqlite/20221122204324_feed-text.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
25
src/NadekoBot/Migrations/Sqlite/20221122204324_feed-text.cs
Normal file
25
src/NadekoBot/Migrations/Sqlite/20221122204324_feed-text.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace NadekoBot.Migrations
|
||||
{
|
||||
public partial class feedtext : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "Message",
|
||||
table: "FeedSub",
|
||||
type: "TEXT",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Message",
|
||||
table: "FeedSub");
|
||||
}
|
||||
}
|
||||
}
|
@@ -37,7 +37,7 @@ namespace NadekoBot.Migrations
|
||||
b.HasIndex("GuildId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("AutoPublishChannel");
|
||||
b.ToTable("AutoPublishChannel", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Db.Models.BankUser", b =>
|
||||
@@ -60,7 +60,7 @@ namespace NadekoBot.Migrations
|
||||
b.HasIndex("UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("BankUsers");
|
||||
b.ToTable("BankUsers", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Db.Models.ClubApplicants", b =>
|
||||
@@ -75,7 +75,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("ClubApplicants");
|
||||
b.ToTable("ClubApplicants", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Db.Models.ClubBans", b =>
|
||||
@@ -90,7 +90,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("ClubBans");
|
||||
b.ToTable("ClubBans", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Db.Models.ClubInfo", b =>
|
||||
@@ -126,7 +126,7 @@ namespace NadekoBot.Migrations
|
||||
b.HasIndex("OwnerId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Clubs");
|
||||
b.ToTable("Clubs", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Db.Models.DiscordUser", b =>
|
||||
@@ -185,7 +185,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("DiscordUser");
|
||||
b.ToTable("DiscordUser", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Db.Models.FollowedStream", b =>
|
||||
@@ -219,7 +219,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("FollowedStream");
|
||||
b.ToTable("FollowedStream", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Db.Models.PatronQuota", b =>
|
||||
@@ -246,7 +246,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("PatronQuotas");
|
||||
b.ToTable("PatronQuotas", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Db.Models.PatronUser", b =>
|
||||
@@ -272,7 +272,7 @@ namespace NadekoBot.Migrations
|
||||
b.HasIndex("UniquePlatformUserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Patrons");
|
||||
b.ToTable("Patrons", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Db.Models.StreamOnlineMessage", b =>
|
||||
@@ -298,7 +298,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("StreamOnlineMessages");
|
||||
b.ToTable("StreamOnlineMessages", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Db.Models.XpShopOwnedItem", b =>
|
||||
@@ -328,7 +328,7 @@ namespace NadekoBot.Migrations
|
||||
b.HasIndex("UserId", "ItemType", "ItemKey")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("XpShopOwnedItem");
|
||||
b.ToTable("XpShopOwnedItem", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiAltSetting", b =>
|
||||
@@ -357,7 +357,7 @@ namespace NadekoBot.Migrations
|
||||
b.HasIndex("GuildConfigId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("AntiAltSetting");
|
||||
b.ToTable("AntiAltSetting", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiRaidSetting", b =>
|
||||
@@ -389,7 +389,7 @@ namespace NadekoBot.Migrations
|
||||
b.HasIndex("GuildConfigId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("AntiRaidSetting");
|
||||
b.ToTable("AntiRaidSetting", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiSpamIgnore", b =>
|
||||
@@ -411,7 +411,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("AntiSpamSettingId");
|
||||
|
||||
b.ToTable("AntiSpamIgnore");
|
||||
b.ToTable("AntiSpamIgnore", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiSpamSetting", b =>
|
||||
@@ -443,7 +443,7 @@ namespace NadekoBot.Migrations
|
||||
b.HasIndex("GuildConfigId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("AntiSpamSetting");
|
||||
b.ToTable("AntiSpamSetting", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.AutoCommand", b =>
|
||||
@@ -481,7 +481,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("AutoCommands");
|
||||
b.ToTable("AutoCommands", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.AutoTranslateChannel", b =>
|
||||
@@ -509,7 +509,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("GuildId");
|
||||
|
||||
b.ToTable("AutoTranslateChannels");
|
||||
b.ToTable("AutoTranslateChannels", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.AutoTranslateUser", b =>
|
||||
@@ -537,7 +537,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasAlternateKey("ChannelId", "UserId");
|
||||
|
||||
b.ToTable("AutoTranslateUsers");
|
||||
b.ToTable("AutoTranslateUsers", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.BanTemplate", b =>
|
||||
@@ -563,7 +563,7 @@ namespace NadekoBot.Migrations
|
||||
b.HasIndex("GuildId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("BanTemplates");
|
||||
b.ToTable("BanTemplates", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.BlacklistEntry", b =>
|
||||
@@ -583,7 +583,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Blacklist");
|
||||
b.ToTable("Blacklist", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandAlias", b =>
|
||||
@@ -608,7 +608,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("CommandAlias");
|
||||
b.ToTable("CommandAlias", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandCooldown", b =>
|
||||
@@ -633,7 +633,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("CommandCooldown");
|
||||
b.ToTable("CommandCooldown", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.CurrencyTransaction", b =>
|
||||
@@ -671,7 +671,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("CurrencyTransactions");
|
||||
b.ToTable("CurrencyTransactions", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.DelMsgOnCmdChannel", b =>
|
||||
@@ -696,7 +696,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("DelMsgOnCmdChannel");
|
||||
b.ToTable("DelMsgOnCmdChannel", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.DiscordPermOverride", b =>
|
||||
@@ -722,7 +722,7 @@ namespace NadekoBot.Migrations
|
||||
b.HasIndex("GuildId", "Command")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("DiscordPermOverrides");
|
||||
b.ToTable("DiscordPermOverrides", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.ExcludedItem", b =>
|
||||
@@ -747,7 +747,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("XpSettingsId");
|
||||
|
||||
b.ToTable("ExcludedItem");
|
||||
b.ToTable("ExcludedItem", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.FeedSub", b =>
|
||||
@@ -765,6 +765,9 @@ namespace NadekoBot.Migrations
|
||||
b.Property<int>("GuildConfigId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Message")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Url")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
@@ -773,7 +776,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasAlternateKey("GuildConfigId", "Url");
|
||||
|
||||
b.ToTable("FeedSub");
|
||||
b.ToTable("FeedSub", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterChannelId", b =>
|
||||
@@ -795,7 +798,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("FilterChannelId");
|
||||
b.ToTable("FilterChannelId", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.FilteredWord", b =>
|
||||
@@ -817,7 +820,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("FilteredWord");
|
||||
b.ToTable("FilteredWord", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterLinksChannelId", b =>
|
||||
@@ -839,7 +842,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("FilterLinksChannelId");
|
||||
b.ToTable("FilterLinksChannelId", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterWordsChannelId", b =>
|
||||
@@ -861,7 +864,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("FilterWordsChannelId");
|
||||
b.ToTable("FilterWordsChannelId", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.GamblingStats", b =>
|
||||
@@ -887,7 +890,7 @@ namespace NadekoBot.Migrations
|
||||
b.HasIndex("Feature")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("GamblingStats");
|
||||
b.ToTable("GamblingStats", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.GCChannelId", b =>
|
||||
@@ -909,7 +912,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("GCChannelId");
|
||||
b.ToTable("GCChannelId", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.GroupName", b =>
|
||||
@@ -935,7 +938,7 @@ namespace NadekoBot.Migrations
|
||||
b.HasIndex("GuildConfigId", "Number")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("GroupName");
|
||||
b.ToTable("GroupName", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildConfig", b =>
|
||||
@@ -1067,7 +1070,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("WarnExpireHours");
|
||||
|
||||
b.ToTable("GuildConfigs");
|
||||
b.ToTable("GuildConfigs", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredLogItem", b =>
|
||||
@@ -1093,7 +1096,7 @@ namespace NadekoBot.Migrations
|
||||
b.HasIndex("LogSettingId", "LogItemId", "ItemType")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("IgnoredLogChannels");
|
||||
b.ToTable("IgnoredLogChannels", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
|
||||
@@ -1115,7 +1118,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("LogSettingId");
|
||||
|
||||
b.ToTable("IgnoredVoicePresenceCHannels");
|
||||
b.ToTable("IgnoredVoicePresenceCHannels", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.ImageOnlyChannel", b =>
|
||||
@@ -1141,7 +1144,7 @@ namespace NadekoBot.Migrations
|
||||
b.HasIndex("ChannelId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("ImageOnlyChannels");
|
||||
b.ToTable("ImageOnlyChannels", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.LogSetting", b =>
|
||||
@@ -1186,6 +1189,12 @@ namespace NadekoBot.Migrations
|
||||
b.Property<ulong?>("MessageUpdatedId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong?>("ThreadCreatedId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong?>("ThreadDeletedId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong?>("UserBannedId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
@@ -1209,7 +1218,7 @@ namespace NadekoBot.Migrations
|
||||
b.HasIndex("GuildId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("LogSettings");
|
||||
b.ToTable("LogSettings", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.MusicPlayerSettings", b =>
|
||||
@@ -1246,7 +1255,7 @@ namespace NadekoBot.Migrations
|
||||
b.HasIndex("GuildId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("MusicPlayerSettings");
|
||||
b.ToTable("MusicPlayerSettings", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.MusicPlaylist", b =>
|
||||
@@ -1269,7 +1278,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("MusicPlaylists");
|
||||
b.ToTable("MusicPlaylists", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.MutedUserId", b =>
|
||||
@@ -1291,7 +1300,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("MutedUserId");
|
||||
b.ToTable("MutedUserId", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.NadekoExpression", b =>
|
||||
@@ -1329,7 +1338,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Expressions");
|
||||
b.ToTable("Expressions", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.NsfwBlacklistedTag", b =>
|
||||
@@ -1351,7 +1360,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("GuildId");
|
||||
|
||||
b.ToTable("NsfwBlacklistedTags");
|
||||
b.ToTable("NsfwBlacklistedTags", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.Permissionv2", b =>
|
||||
@@ -1391,7 +1400,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("Permissions");
|
||||
b.ToTable("Permissions", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.PlantedCurrency", b =>
|
||||
@@ -1428,7 +1437,7 @@ namespace NadekoBot.Migrations
|
||||
b.HasIndex("MessageId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("PlantedCurrency");
|
||||
b.ToTable("PlantedCurrency", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.PlaylistSong", b =>
|
||||
@@ -1462,7 +1471,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("MusicPlaylistId");
|
||||
|
||||
b.ToTable("PlaylistSong");
|
||||
b.ToTable("PlaylistSong", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.Poll", b =>
|
||||
@@ -1488,7 +1497,7 @@ namespace NadekoBot.Migrations
|
||||
b.HasIndex("GuildId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Poll");
|
||||
b.ToTable("Poll", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.PollAnswer", b =>
|
||||
@@ -1513,7 +1522,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("PollId");
|
||||
|
||||
b.ToTable("PollAnswer");
|
||||
b.ToTable("PollAnswer", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.PollVote", b =>
|
||||
@@ -1538,7 +1547,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("PollId");
|
||||
|
||||
b.ToTable("PollVote");
|
||||
b.ToTable("PollVote", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.Quote", b =>
|
||||
@@ -1574,7 +1583,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("Keyword");
|
||||
|
||||
b.ToTable("Quotes");
|
||||
b.ToTable("Quotes", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.ReactionRoleV2", b =>
|
||||
@@ -1615,7 +1624,7 @@ namespace NadekoBot.Migrations
|
||||
b.HasIndex("MessageId", "Emote")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("ReactionRoles");
|
||||
b.ToTable("ReactionRoles", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.Reminder", b =>
|
||||
@@ -1649,7 +1658,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("When");
|
||||
|
||||
b.ToTable("Reminders");
|
||||
b.ToTable("Reminders", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.Repeater", b =>
|
||||
@@ -1684,7 +1693,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Repeaters");
|
||||
b.ToTable("Repeaters", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.RewardedUser", b =>
|
||||
@@ -1713,7 +1722,7 @@ namespace NadekoBot.Migrations
|
||||
b.HasIndex("PlatformUserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("RewardedUsers");
|
||||
b.ToTable("RewardedUsers", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.RotatingPlayingStatus", b =>
|
||||
@@ -1733,7 +1742,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("RotatingStatus");
|
||||
b.ToTable("RotatingStatus", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.SelfAssignedRole", b =>
|
||||
@@ -1764,7 +1773,7 @@ namespace NadekoBot.Migrations
|
||||
b.HasIndex("GuildId", "RoleId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("SelfAssignableRoles");
|
||||
b.ToTable("SelfAssignableRoles", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntry", b =>
|
||||
@@ -1807,7 +1816,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("ShopEntry");
|
||||
b.ToTable("ShopEntry", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntryItem", b =>
|
||||
@@ -1829,7 +1838,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("ShopEntryId");
|
||||
|
||||
b.ToTable("ShopEntryItem");
|
||||
b.ToTable("ShopEntryItem", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredRole", b =>
|
||||
@@ -1851,7 +1860,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("SlowmodeIgnoredRole");
|
||||
b.ToTable("SlowmodeIgnoredRole", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredUser", b =>
|
||||
@@ -1873,7 +1882,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("SlowmodeIgnoredUser");
|
||||
b.ToTable("SlowmodeIgnoredUser", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleBlacklistedUser", b =>
|
||||
@@ -1898,7 +1907,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("StreamRoleSettingsId");
|
||||
|
||||
b.ToTable("StreamRoleBlacklistedUser");
|
||||
b.ToTable("StreamRoleBlacklistedUser", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleSettings", b =>
|
||||
@@ -1930,7 +1939,7 @@ namespace NadekoBot.Migrations
|
||||
b.HasIndex("GuildConfigId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("StreamRoleSettings");
|
||||
b.ToTable("StreamRoleSettings", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleWhitelistedUser", b =>
|
||||
@@ -1955,7 +1964,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("StreamRoleSettingsId");
|
||||
|
||||
b.ToTable("StreamRoleWhitelistedUser");
|
||||
b.ToTable("StreamRoleWhitelistedUser", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.UnbanTimer", b =>
|
||||
@@ -1980,7 +1989,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("UnbanTimer");
|
||||
b.ToTable("UnbanTimer", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.UnmuteTimer", b =>
|
||||
@@ -2005,7 +2014,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("UnmuteTimer");
|
||||
b.ToTable("UnmuteTimer", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.UnroleTimer", b =>
|
||||
@@ -2033,7 +2042,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("UnroleTimer");
|
||||
b.ToTable("UnroleTimer", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.UserXpStats", b =>
|
||||
@@ -2073,7 +2082,7 @@ namespace NadekoBot.Migrations
|
||||
b.HasIndex("UserId", "GuildId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("UserXpStats");
|
||||
b.ToTable("UserXpStats", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.VcRoleInfo", b =>
|
||||
@@ -2098,7 +2107,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("VcRoleInfo");
|
||||
b.ToTable("VcRoleInfo", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuInfo", b =>
|
||||
@@ -2133,7 +2142,7 @@ namespace NadekoBot.Migrations
|
||||
b.HasIndex("WaifuId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("WaifuInfo");
|
||||
b.ToTable("WaifuInfo", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuItem", b =>
|
||||
@@ -2158,7 +2167,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("WaifuInfoId");
|
||||
|
||||
b.ToTable("WaifuItem");
|
||||
b.ToTable("WaifuItem", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuUpdate", b =>
|
||||
@@ -2190,7 +2199,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("WaifuUpdates");
|
||||
b.ToTable("WaifuUpdates", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.Warning", b =>
|
||||
@@ -2233,7 +2242,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Warnings");
|
||||
b.ToTable("Warnings", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.WarningPunishment", b =>
|
||||
@@ -2264,7 +2273,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("WarningPunishment");
|
||||
b.ToTable("WarningPunishment", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.XpCurrencyReward", b =>
|
||||
@@ -2289,7 +2298,7 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.HasIndex("XpSettingsId");
|
||||
|
||||
b.ToTable("XpCurrencyReward");
|
||||
b.ToTable("XpCurrencyReward", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.XpRoleReward", b =>
|
||||
@@ -2318,7 +2327,7 @@ namespace NadekoBot.Migrations
|
||||
b.HasIndex("XpSettingsId", "Level")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("XpRoleReward");
|
||||
b.ToTable("XpRoleReward", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.XpSettings", b =>
|
||||
@@ -2341,7 +2350,7 @@ namespace NadekoBot.Migrations
|
||||
b.HasIndex("GuildConfigId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("XpSettings");
|
||||
b.ToTable("XpSettings", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Db.Models.ClubApplicants", b =>
|
||||
|
@@ -78,6 +78,7 @@ public class DangerousCommandsService : INService
|
||||
|
||||
await ctx.CurrencyTransactions.DeleteAsync();
|
||||
await ctx.PlantedCurrency.DeleteAsync();
|
||||
await ctx.BankUsers.DeleteAsync();
|
||||
await ctx.SaveChangesAsync();
|
||||
}
|
||||
|
||||
|
@@ -191,7 +191,7 @@ public class GreetService : INService, IReadyExecutor
|
||||
if (conf.AutoDeleteByeMessagesTimer > 0)
|
||||
toDelete.DeleteAfter(conf.AutoDeleteByeMessagesTimer);
|
||||
}
|
||||
catch (HttpException ex) when (ex.DiscordCode == DiscordErrorCode.InsufficientPermissions)
|
||||
catch (HttpException ex) when (ex.DiscordCode == DiscordErrorCode.InsufficientPermissions || ex.DiscordCode == DiscordErrorCode.UnknownChannel)
|
||||
{
|
||||
Log.Warning(ex, "Missing permissions to send a bye message, the bye message will be disabled on server: {GuildId}", channel.GuildId);
|
||||
await SetBye(channel.GuildId, channel.Id, false);
|
||||
@@ -224,7 +224,7 @@ public class GreetService : INService, IReadyExecutor
|
||||
if (conf.AutoDeleteGreetMessagesTimer > 0)
|
||||
toDelete.DeleteAfter(conf.AutoDeleteGreetMessagesTimer);
|
||||
}
|
||||
catch (HttpException ex) when (ex.DiscordCode == DiscordErrorCode.InsufficientPermissions)
|
||||
catch (HttpException ex) when (ex.DiscordCode == DiscordErrorCode.InsufficientPermissions || ex.DiscordCode == DiscordErrorCode.UnknownChannel)
|
||||
{
|
||||
Log.Warning(ex, "Missing permissions to send a bye message, the greet message will be disabled on server: {GuildId}", channel.GuildId);
|
||||
await SetGreet(channel.GuildId, channel.Id, false);
|
||||
|
@@ -457,6 +457,7 @@ public class ProtectionService : INService
|
||||
case PunishmentAction.ChatMute:
|
||||
case PunishmentAction.VoiceMute:
|
||||
case PunishmentAction.AddRole:
|
||||
case PunishmentAction.TimeOut:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
138
src/NadekoBot/Modules/Administration/Self/DoAsUserMessage.cs
Normal file
138
src/NadekoBot/Modules/Administration/Self/DoAsUserMessage.cs
Normal file
@@ -0,0 +1,138 @@
|
||||
using MessageType = Discord.MessageType;
|
||||
|
||||
namespace NadekoBot.Modules.Administration;
|
||||
|
||||
public sealed class DoAsUserMessage : IUserMessage
|
||||
{
|
||||
private readonly string _message;
|
||||
private IUserMessage _msg;
|
||||
private readonly IUser _user;
|
||||
|
||||
public DoAsUserMessage(SocketUserMessage msg, IUser user, string message)
|
||||
{
|
||||
_msg = msg;
|
||||
_user = user;
|
||||
_message = message;
|
||||
}
|
||||
|
||||
public ulong Id => _msg.Id;
|
||||
|
||||
public DateTimeOffset CreatedAt => _msg.CreatedAt;
|
||||
|
||||
public Task DeleteAsync(RequestOptions? options = null)
|
||||
{
|
||||
return _msg.DeleteAsync(options);
|
||||
}
|
||||
|
||||
public Task AddReactionAsync(IEmote emote, RequestOptions? options = null)
|
||||
{
|
||||
return _msg.AddReactionAsync(emote, options);
|
||||
}
|
||||
|
||||
public Task RemoveReactionAsync(IEmote emote, IUser user, RequestOptions? options = null)
|
||||
{
|
||||
return _msg.RemoveReactionAsync(emote, user, options);
|
||||
}
|
||||
|
||||
public Task RemoveReactionAsync(IEmote emote, ulong userId, RequestOptions? options = null)
|
||||
{
|
||||
return _msg.RemoveReactionAsync(emote, userId, options);
|
||||
}
|
||||
|
||||
public Task RemoveAllReactionsAsync(RequestOptions? options = null)
|
||||
{
|
||||
return _msg.RemoveAllReactionsAsync(options);
|
||||
}
|
||||
|
||||
public Task RemoveAllReactionsForEmoteAsync(IEmote emote, RequestOptions? options = null)
|
||||
{
|
||||
return _msg.RemoveAllReactionsForEmoteAsync(emote, options);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<IReadOnlyCollection<IUser>> GetReactionUsersAsync(IEmote emoji, int limit,
|
||||
RequestOptions? options = null)
|
||||
{
|
||||
return _msg.GetReactionUsersAsync(emoji, limit, options);
|
||||
}
|
||||
|
||||
public MessageType Type => _msg.Type;
|
||||
|
||||
public MessageSource Source => _msg.Source;
|
||||
|
||||
public bool IsTTS => _msg.IsTTS;
|
||||
|
||||
public bool IsPinned => _msg.IsPinned;
|
||||
|
||||
public bool IsSuppressed => _msg.IsSuppressed;
|
||||
|
||||
public bool MentionedEveryone => _msg.MentionedEveryone;
|
||||
|
||||
public string Content => _message;
|
||||
|
||||
public string CleanContent => _msg.CleanContent;
|
||||
|
||||
public DateTimeOffset Timestamp => _msg.Timestamp;
|
||||
|
||||
public DateTimeOffset? EditedTimestamp => _msg.EditedTimestamp;
|
||||
|
||||
public IMessageChannel Channel => _msg.Channel;
|
||||
|
||||
public IUser Author => _user;
|
||||
|
||||
public IReadOnlyCollection<IAttachment> Attachments => _msg.Attachments;
|
||||
|
||||
public IReadOnlyCollection<IEmbed> Embeds => _msg.Embeds;
|
||||
|
||||
public IReadOnlyCollection<ITag> Tags => _msg.Tags;
|
||||
|
||||
public IReadOnlyCollection<ulong> MentionedChannelIds => _msg.MentionedChannelIds;
|
||||
|
||||
public IReadOnlyCollection<ulong> MentionedRoleIds => _msg.MentionedRoleIds;
|
||||
|
||||
public IReadOnlyCollection<ulong> MentionedUserIds => _msg.MentionedUserIds;
|
||||
|
||||
public MessageActivity Activity => _msg.Activity;
|
||||
|
||||
public MessageApplication Application => _msg.Application;
|
||||
|
||||
public MessageReference Reference => _msg.Reference;
|
||||
|
||||
public IReadOnlyDictionary<IEmote, ReactionMetadata> Reactions => _msg.Reactions;
|
||||
|
||||
public IReadOnlyCollection<IMessageComponent> Components => _msg.Components;
|
||||
|
||||
public IReadOnlyCollection<IStickerItem> Stickers => _msg.Stickers;
|
||||
|
||||
public MessageFlags? Flags => _msg.Flags;
|
||||
|
||||
public IMessageInteraction Interaction => _msg.Interaction;
|
||||
|
||||
public Task ModifyAsync(Action<MessageProperties> func, RequestOptions? options = null)
|
||||
{
|
||||
return _msg.ModifyAsync(func, options);
|
||||
}
|
||||
|
||||
public Task PinAsync(RequestOptions? options = null)
|
||||
{
|
||||
return _msg.PinAsync(options);
|
||||
}
|
||||
|
||||
public Task UnpinAsync(RequestOptions? options = null)
|
||||
{
|
||||
return _msg.UnpinAsync(options);
|
||||
}
|
||||
|
||||
public Task CrosspostAsync(RequestOptions? options = null)
|
||||
{
|
||||
return _msg.CrosspostAsync(options);
|
||||
}
|
||||
|
||||
public string Resolve(TagHandling userHandling = TagHandling.Name, TagHandling channelHandling = TagHandling.Name,
|
||||
TagHandling roleHandling = TagHandling.Name,
|
||||
TagHandling everyoneHandling = TagHandling.Ignore, TagHandling emojiHandling = TagHandling.Name)
|
||||
{
|
||||
return _msg.Resolve(userHandling, channelHandling, roleHandling, everyoneHandling, emojiHandling);
|
||||
}
|
||||
|
||||
public IUserMessage ReferencedMessage => _msg.ReferencedMessage;
|
||||
}
|
@@ -35,6 +35,26 @@ public partial class Administration
|
||||
_medusaLoader = medusaLoader;
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
[OwnerOnly]
|
||||
public async Task DoAs(IUser user, [Leftover] string message)
|
||||
{
|
||||
if (ctx.User is not IGuildUser { GuildPermissions.Administrator: true })
|
||||
return;
|
||||
|
||||
if (ctx.Guild is SocketGuild sg && ctx.Channel is ISocketMessageChannel ch
|
||||
&& ctx.Message is SocketUserMessage msg)
|
||||
{
|
||||
var fakeMessage = new DoAsUserMessage(msg, user, message);
|
||||
|
||||
await _cmdHandler.TryRunCommand(sg, ch, fakeMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.error_occured);
|
||||
}
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[UserPerm(GuildPerm.Administrator)]
|
||||
|
@@ -78,6 +78,9 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
||||
_client.ChannelDestroyed += _client_ChannelDestroyed;
|
||||
_client.ChannelUpdated += _client_ChannelUpdated;
|
||||
_client.RoleDeleted += _client_RoleDeleted;
|
||||
|
||||
_client.ThreadCreated += _client_ThreadCreated;
|
||||
_client.ThreadDeleted += _client_ThreadDeleted;
|
||||
|
||||
_mute.UserMuted += MuteCommands_UserMuted;
|
||||
_mute.UserUnmuted += MuteCommands_UserUnmuted;
|
||||
@@ -87,6 +90,73 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
||||
_punishService.OnUserWarned += PunishServiceOnOnUserWarned;
|
||||
}
|
||||
|
||||
private Task _client_ThreadDeleted(Cacheable<SocketThreadChannel, ulong> sch)
|
||||
{
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (sch.HasValue || sch.Value is not IGuildChannel ch)
|
||||
return;
|
||||
|
||||
if (!GuildLogSettings.TryGetValue(ch.Guild.Id, out var logSetting)
|
||||
|| logSetting.ThreadDeletedId is null)
|
||||
return;
|
||||
|
||||
ITextChannel? logChannel;
|
||||
if ((logChannel = await TryGetLogChannel(ch.Guild, logSetting, LogType.ThreadDeleted)) is null)
|
||||
return;
|
||||
|
||||
var title = GetText(logChannel.Guild, strs.thread_deleted);
|
||||
|
||||
await logChannel.EmbedAsync(_eb.Create()
|
||||
.WithOkColor()
|
||||
.WithTitle("🆕 " + title)
|
||||
.WithDescription($"{ch.Name} | {ch.Id}")
|
||||
.WithFooter(CurrentTime(ch.Guild)));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
});
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task _client_ThreadCreated(SocketThreadChannel sch)
|
||||
{
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (sch.Guild is not IGuildChannel ch)
|
||||
return;
|
||||
|
||||
if (!GuildLogSettings.TryGetValue(ch.Guild.Id, out var logSetting)
|
||||
|| logSetting.ThreadCreatedId is null)
|
||||
return;
|
||||
|
||||
ITextChannel? logChannel;
|
||||
if ((logChannel = await TryGetLogChannel(ch.Guild, logSetting, LogType.ThreadCreated)) is null)
|
||||
return;
|
||||
|
||||
var title = GetText(logChannel.Guild, strs.thread_created);
|
||||
|
||||
await logChannel.EmbedAsync(_eb.Create()
|
||||
.WithOkColor()
|
||||
.WithTitle("🆕 " + title)
|
||||
.WithDescription($"{ch.Name} | {ch.Id}")
|
||||
.WithFooter(CurrentTime(ch.Guild)));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
});
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public async Task OnReadyAsync()
|
||||
=> await Task.WhenAll(PresenceUpdateTask(), IgnoreMessageIdsClearTask());
|
||||
|
||||
@@ -725,6 +795,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
||||
ITextChannel? logChannel;
|
||||
if ((logChannel = await TryGetLogChannel(ch.Guild, logSetting, LogType.ChannelDestroyed)) is null)
|
||||
return;
|
||||
|
||||
string title;
|
||||
if (ch is IVoiceChannel)
|
||||
title = GetText(logChannel.Guild, strs.voice_chan_destroyed);
|
||||
@@ -744,7 +815,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
||||
});
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
private Task _client_ChannelCreated(IChannel ich)
|
||||
{
|
||||
_ = Task.Run(async () =>
|
||||
|
@@ -88,10 +88,6 @@ public class GameStatusEvent : ICurrencyEvent
|
||||
await msg.ModifyAsync(m =>
|
||||
{
|
||||
m.Embed = GetEmbed(PotSize).Build();
|
||||
},
|
||||
new()
|
||||
{
|
||||
RetryMode = RetryMode.AlwaysRetry
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -79,10 +79,6 @@ public class ReactionEvent : ICurrencyEvent
|
||||
await msg.ModifyAsync(m =>
|
||||
{
|
||||
m.Embed = GetEmbed(PotSize).Build();
|
||||
},
|
||||
new()
|
||||
{
|
||||
RetryMode = RetryMode.AlwaysRetry
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -244,20 +244,29 @@ public partial class Gambling
|
||||
|
||||
var waifuItems = _service.GetWaifuItems().ToDictionary(x => x.ItemEmoji, x => x);
|
||||
|
||||
|
||||
var nobody = GetText(strs.nobody);
|
||||
var itemsStr = !wi.Items.Any()
|
||||
var itemList = await _service.GetItems(wi.WaifuId);
|
||||
var itemsStr = !itemList.Any()
|
||||
? "-"
|
||||
: string.Join("\n",
|
||||
wi.Items.Where(x => waifuItems.TryGetValue(x.ItemEmoji, out _))
|
||||
.OrderBy(x => waifuItems[x.ItemEmoji].Price)
|
||||
.GroupBy(x => x.ItemEmoji)
|
||||
.Select(x => $"{x.Key} x{x.Count(),-3}")
|
||||
.Chunk(2)
|
||||
.Select(x => string.Join(" ", x)));
|
||||
itemList.Where(x => waifuItems.TryGetValue(x.ItemEmoji, out _))
|
||||
.OrderBy(x => waifuItems[x.ItemEmoji].Price)
|
||||
.GroupBy(x => x.ItemEmoji)
|
||||
.Select(x => $"{x.Key} x{x.Count(),-3}")
|
||||
.Chunk(2)
|
||||
.Select(x => string.Join(" ", x)));
|
||||
|
||||
var fansStr = wi.Fans.Shuffle().Take(30).Select(x => wi.Claims.Contains(x) ? $"{x} 💞" : x).Join('\n');
|
||||
var claimsNames = (await _service.GetClaimNames(wi.WaifuId));
|
||||
var claimsStr = claimsNames
|
||||
.Shuffle()
|
||||
.Take(30)
|
||||
.Join('\n');
|
||||
|
||||
var fansList = await _service.GetFansNames(wi.WaifuId);
|
||||
var fansStr = fansList
|
||||
.Select((x) => claimsNames.Contains(x) ? $"{x} 💞" : x).Join('\n');
|
||||
|
||||
|
||||
if (string.IsNullOrWhiteSpace(fansStr))
|
||||
fansStr = "-";
|
||||
|
||||
@@ -275,9 +284,9 @@ public partial class Gambling
|
||||
.AddField(GetText(strs.changes_of_heart), $"{wi.AffinityCount} - \"the {affInfo}\"", true)
|
||||
.AddField(GetText(strs.divorces), wi.DivorceCount.ToString(), true)
|
||||
.AddField("\u200B", "\u200B", true)
|
||||
.AddField(GetText(strs.fans(wi.Fans.Count)), fansStr, true)
|
||||
.AddField(GetText(strs.fans(fansList.Count)), fansStr, true)
|
||||
.AddField($"Waifus ({wi.ClaimCount})",
|
||||
wi.ClaimCount == 0 ? nobody : string.Join("\n", wi.Claims.Shuffle().Take(30)),
|
||||
wi.ClaimCount == 0 ? nobody : claimsStr,
|
||||
true)
|
||||
.AddField(GetText(strs.gifts), itemsStr, true);
|
||||
|
||||
|
@@ -414,11 +414,8 @@ public class WaifuService : INService, IReadyExecutor
|
||||
AffinityName = null,
|
||||
ClaimCount = 0,
|
||||
ClaimerName = null,
|
||||
Claims = new(),
|
||||
Fans = new(),
|
||||
DivorceCount = 0,
|
||||
FullName = null,
|
||||
Items = new(),
|
||||
Price = 1
|
||||
};
|
||||
}
|
||||
@@ -426,14 +423,6 @@ public class WaifuService : INService, IReadyExecutor
|
||||
return wi;
|
||||
}
|
||||
|
||||
public async Task<WaifuInfoStats> GetFullWaifuInfoAsync(IGuildUser target)
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
_ = uow.GetOrCreateUser(target);
|
||||
|
||||
return await GetFullWaifuInfoAsync(target.Id);
|
||||
}
|
||||
|
||||
public string GetClaimTitle(int count)
|
||||
{
|
||||
ClaimTitle title;
|
||||
@@ -557,4 +546,38 @@ public class WaifuService : INService, IReadyExecutor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyCollection<string>> GetClaimNames(int waifuId)
|
||||
{
|
||||
await using var ctx = _db.GetDbContext();
|
||||
return await ctx.GetTable<DiscordUser>()
|
||||
.Where(x => ctx.GetTable<WaifuInfo>()
|
||||
.Where(wi => wi.ClaimerId == waifuId)
|
||||
.Select(wi => wi.WaifuId)
|
||||
.Contains(x.Id))
|
||||
.Select(x => $"{x.Username}#{x.Discriminator}")
|
||||
.ToListAsyncEF();
|
||||
}
|
||||
public async Task<IReadOnlyCollection<string>> GetFansNames(int waifuId)
|
||||
{
|
||||
await using var ctx = _db.GetDbContext();
|
||||
return await ctx.GetTable<DiscordUser>()
|
||||
.Where(x => ctx.GetTable<WaifuInfo>()
|
||||
.Where(wi => wi.AffinityId == waifuId)
|
||||
.Select(wi => wi.WaifuId)
|
||||
.Contains(x.Id))
|
||||
.Select(x => $"{x.Username}#{x.Discriminator}")
|
||||
.ToListAsyncEF();
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyCollection<WaifuItem>> GetItems(int waifuId)
|
||||
{
|
||||
await using var ctx = _db.GetDbContext();
|
||||
return await ctx.GetTable<WaifuItem>()
|
||||
.Where(x => x.WaifuInfoId == ctx.GetTable<WaifuInfo>()
|
||||
.Where(x => x.WaifuId == waifuId)
|
||||
.Select(x => x.Id)
|
||||
.FirstOrDefault())
|
||||
.ToListAsyncEF();
|
||||
}
|
||||
}
|
@@ -74,11 +74,7 @@ public class TypingGame
|
||||
|
||||
var time = _options.StartTime;
|
||||
|
||||
var msg = await Channel.SendMessageAsync($"Starting new typing contest in **{time}**...",
|
||||
options: new()
|
||||
{
|
||||
RetryMode = RetryMode.AlwaysRetry
|
||||
});
|
||||
var msg = await Channel.SendMessageAsync($"Starting new typing contest in **{time}**...");
|
||||
|
||||
do
|
||||
{
|
||||
|
@@ -131,9 +131,12 @@ public sealed class TriviaGame
|
||||
hintSent = true;
|
||||
// start a new countdown of the same length
|
||||
halfGuessTimerTask = TimeOutFactory();
|
||||
// send a hint out
|
||||
await OnHint(this, question);
|
||||
|
||||
if (!_opts.NoHint)
|
||||
{
|
||||
// send a hint out
|
||||
await OnHint(this, question);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@@ -45,7 +45,7 @@ public class HelpService : IExecNoCommand, INService
|
||||
|
||||
// only send dm help text if it contains one of the keywords, if they're specified
|
||||
// if they're not, then reply to every DM
|
||||
if (settings.DmHelpTextKeywords.Any() && !settings.DmHelpTextKeywords.Any(k => msg.Content.Contains(k)))
|
||||
if (settings.DmHelpTextKeywords is not null && !settings.DmHelpTextKeywords.Any(k => msg.Content.Contains(k)))
|
||||
return Task.CompletedTask;
|
||||
|
||||
var rep = new ReplacementBuilder().WithOverride("%prefix%", () => _bss.Data.Prefix)
|
||||
@@ -152,18 +152,22 @@ public class HelpService : IExecNoCommand, INService
|
||||
.Any(x => x is OnlyPublicBotAttribute))
|
||||
toReturn.Add("Only Public Bot");
|
||||
|
||||
var userPerm = (UserPermAttribute)cmd.Preconditions.FirstOrDefault(ca => ca is UserPermAttribute);
|
||||
var userPermString = cmd.Preconditions
|
||||
.Where(ca => ca is UserPermAttribute)
|
||||
.Cast<UserPermAttribute>()
|
||||
.Select(userPerm =>
|
||||
{
|
||||
if (userPerm.ChannelPermission is { } cPerm)
|
||||
return GetPreconditionString(cPerm);
|
||||
|
||||
var userPermString = string.Empty;
|
||||
if (userPerm is not null)
|
||||
{
|
||||
if (userPerm.ChannelPermission is { } cPerm)
|
||||
userPermString = GetPreconditionString(cPerm);
|
||||
|
||||
if (userPerm.GuildPermission is { } gPerm)
|
||||
userPermString = GetPreconditionString(gPerm);
|
||||
}
|
||||
if (userPerm.GuildPermission is { } gPerm)
|
||||
return GetPreconditionString(gPerm);
|
||||
|
||||
return string.Empty;
|
||||
})
|
||||
.Where(x => !string.IsNullOrWhiteSpace(x))
|
||||
.Join('\n');
|
||||
|
||||
if (overrides is null)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(userPermString))
|
||||
@@ -188,4 +192,4 @@ public class HelpService : IExecNoCommand, INService
|
||||
|
||||
private string GetText(LocStr str, IGuild guild)
|
||||
=> _strings.GetText(str, guild?.Id);
|
||||
}
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@ public partial class Searches
|
||||
[Cmd]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[UserPerm(GuildPerm.ManageMessages)]
|
||||
public Task YtUploadNotif(string url, [Leftover] ITextChannel channel = null)
|
||||
public Task YtUploadNotif(string url, ITextChannel channel = null, [Leftover] string message = null)
|
||||
{
|
||||
var m = _ytChannelRegex.Match(url);
|
||||
if (!m.Success)
|
||||
@@ -24,19 +24,19 @@ public partial class Searches
|
||||
|
||||
var channelId = m.Groups["channelid"].Value;
|
||||
|
||||
return Feed("https://www.youtube.com/feeds/videos.xml?channel_id=" + channelId, channel);
|
||||
return Feed("https://www.youtube.com/feeds/videos.xml?channel_id=" + channelId, channel, message);
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[UserPerm(GuildPerm.ManageMessages)]
|
||||
public async Task Feed(string url, [Leftover] ITextChannel channel = null)
|
||||
public async Task Feed(string url, ITextChannel channel = null, [Leftover] string message = null)
|
||||
{
|
||||
if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)
|
||||
|| (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps))
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.feed_invalid_url);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
channel ??= (ITextChannel)ctx.Channel;
|
||||
@@ -51,7 +51,10 @@ public partial class Searches
|
||||
return;
|
||||
}
|
||||
|
||||
var result = _service.AddFeed(ctx.Guild.Id, channel.Id, url);
|
||||
if (ctx.User is not IGuildUser gu || !gu.GuildPermissions.Administrator)
|
||||
message = message?.SanitizeMentions(true);
|
||||
|
||||
var result = _service.AddFeed(ctx.Guild.Id, channel.Id, url, message);
|
||||
if (result == FeedAddResult.Success)
|
||||
{
|
||||
await ReplyConfirmLocalizedAsync(strs.feed_added);
|
||||
|
@@ -162,7 +162,6 @@ public class FeedsService : INService
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
embed.WithTitle(title.TrimTo(256));
|
||||
|
||||
var desc = feedItem.Description?.StripHtml();
|
||||
@@ -171,15 +170,15 @@ public class FeedsService : INService
|
||||
|
||||
//send the created embed to all subscribed channels
|
||||
var feedSendTasks = kvp.Value
|
||||
.Where(x => x.GuildConfig is not null)
|
||||
.Select(x => _client.GetGuild(x.GuildConfig.GuildId)
|
||||
?.GetTextChannel(x.ChannelId))
|
||||
.Where(x => x is not null)
|
||||
.Select(x => x.EmbedAsync(embed));
|
||||
.Where(x => x.GuildConfig is not null)
|
||||
.Select(x => _client.GetGuild(x.GuildConfig.GuildId)
|
||||
?.GetTextChannel(x.ChannelId)
|
||||
?.EmbedAsync(embed, x.Message))
|
||||
.Where(x => x is not null);
|
||||
|
||||
allSendTasks.Add(feedSendTasks.WhenAll());
|
||||
|
||||
// as data retrieval was sucessful, reset error counter
|
||||
// as data retrieval was successful, reset error counter
|
||||
ClearErrors(rssUrl);
|
||||
}
|
||||
}
|
||||
@@ -207,7 +206,7 @@ public class FeedsService : INService
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public FeedAddResult AddFeed(ulong guildId, ulong channelId, string rssFeed)
|
||||
public FeedAddResult AddFeed(ulong guildId, ulong channelId, string rssFeed, string message)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(rssFeed, nameof(rssFeed));
|
||||
|
||||
|
@@ -220,5 +220,5 @@ public sealed class TranslateService : ITranslateService, IExecNoCommand, IReady
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetLanguages()
|
||||
=> _google.Languages.Select(x => x.Key);
|
||||
=> _google.Languages.GroupBy(x => x.Value).Select(x => $"{x.AsEnumerable().Select(y => y.Key).Join(", ")}");
|
||||
}
|
@@ -77,6 +77,19 @@ public partial class Searches
|
||||
[Cmd]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Translangs()
|
||||
=> await ctx.Channel.SendTableAsync(_service.GetLanguages(), str => $"{str,-15}");
|
||||
{
|
||||
var langs = _service.GetLanguages().ToList();
|
||||
|
||||
var eb = _eb.Create()
|
||||
.WithTitle(GetText(strs.supported_languages))
|
||||
.WithOkColor();
|
||||
|
||||
foreach (var chunk in langs.Chunk(15))
|
||||
{
|
||||
eb.AddField("", chunk.Join("\n"), isInline: true);
|
||||
}
|
||||
|
||||
await ctx.Channel.EmbedAsync(eb);
|
||||
}
|
||||
}
|
||||
}
|
@@ -199,7 +199,7 @@ public sealed class PatronageService
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dbPatron.LastCharge.Month < lastChargeUtc.Month)
|
||||
if (dbPatron.LastCharge.Month < lastChargeUtc.Month || dbPatron.LastCharge.Year < lastChargeUtc.Year)
|
||||
{
|
||||
// user is charged again for this month
|
||||
// if his sub would end in teh future, extend it by one month.
|
||||
|
@@ -270,7 +270,7 @@ public partial class Utility
|
||||
|
||||
if (userId == ctx.User.Id || hasManageMessages)
|
||||
{
|
||||
var deleted = await _qs.DeleteAllAuthorQuotesAsync(ctx.Guild.Id, ctx.User.Id);
|
||||
var deleted = await _qs.DeleteAllAuthorQuotesAsync(ctx.Guild.Id, userId);
|
||||
await ReplyConfirmLocalizedAsync(strs.quotes_deleted_count(deleted));
|
||||
}
|
||||
else
|
||||
|
@@ -1,12 +1,9 @@
|
||||
#nullable disable
|
||||
using NadekoBot.Common.ModuleBehaviors;
|
||||
using NadekoBot.Common.ModuleBehaviors;
|
||||
using NadekoBot.Db;
|
||||
using NadekoBot.Modules.Utility.Common;
|
||||
using NadekoBot.Modules.Utility.Common.Exceptions;
|
||||
using NadekoBot.Services.Database.Models;
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using Nadeko.Common;
|
||||
|
||||
namespace NadekoBot.Modules.Utility.Services;
|
||||
|
||||
@@ -31,15 +28,16 @@ public class StreamRoleService : IReadyExecutor, INService
|
||||
_queueRunner = new QueueRunner();
|
||||
}
|
||||
|
||||
private Task OnPresenceUpdate(SocketUser user, SocketPresence oldPresence, SocketPresence newPresence)
|
||||
private Task OnPresenceUpdate(SocketUser user, SocketPresence? oldPresence, SocketPresence? newPresence)
|
||||
{
|
||||
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
if (oldPresence.Activities.Count != newPresence.Activities.Count)
|
||||
if (oldPresence?.Activities?.Count != newPresence?.Activities?.Count)
|
||||
{
|
||||
var guildUsers = _client.Guilds
|
||||
.Select(x => x.GetUser(user.Id));
|
||||
.Select(x => x.GetUser(user.Id))
|
||||
.Where(x => x is not null);
|
||||
|
||||
foreach (var guildUser in guildUsers)
|
||||
{
|
||||
@@ -131,7 +129,7 @@ public class StreamRoleService : IReadyExecutor, INService
|
||||
/// <param name="guild">Guild Id</param>
|
||||
/// <param name="keyword">Keyword to set</param>
|
||||
/// <returns>The keyword set</returns>
|
||||
public async Task<string> SetKeyword(IGuild guild, string keyword)
|
||||
public async Task<string?> SetKeyword(IGuild guild, string? keyword)
|
||||
{
|
||||
keyword = keyword?.Trim().ToLowerInvariant();
|
||||
|
||||
@@ -221,15 +219,15 @@ public class StreamRoleService : IReadyExecutor, INService
|
||||
await RescanUsers(guild);
|
||||
}
|
||||
|
||||
private async ValueTask RescanUser(IGuildUser user, StreamRoleSettings setting, IRole addRole = null)
|
||||
private async ValueTask RescanUser(IGuildUser user, StreamRoleSettings setting, IRole? addRole = null)
|
||||
=> await _queueRunner.EnqueueAsync(() => RescanUserInternal(user, setting, addRole));
|
||||
|
||||
private async Task RescanUserInternal(IGuildUser user, StreamRoleSettings setting, IRole addRole = null)
|
||||
private async Task RescanUserInternal(IGuildUser user, StreamRoleSettings setting, IRole? addRole = null)
|
||||
{
|
||||
if (user.IsBot)
|
||||
return;
|
||||
|
||||
var g = (StreamingGame)user.Activities.FirstOrDefault(a
|
||||
var g = (StreamingGame?)user.Activities.FirstOrDefault(a
|
||||
=> a is StreamingGame
|
||||
&& (string.IsNullOrWhiteSpace(setting.Keyword)
|
||||
|| a.Name.ToUpperInvariant().Contains(setting.Keyword.ToUpperInvariant())
|
||||
|
@@ -402,6 +402,103 @@ public partial class Utility : NadekoModule
|
||||
await ctx.OkAsync();
|
||||
}
|
||||
|
||||
|
||||
[Cmd]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[BotPerm(GuildPerm.ManageEmojisAndStickers)]
|
||||
[UserPerm(GuildPerm.ManageEmojisAndStickers)]
|
||||
public async Task StickerAdd(string name = null, string description = null, params string[] tags)
|
||||
{
|
||||
string format;
|
||||
Stream stream;
|
||||
|
||||
if (ctx.Message.Stickers.Count is 1 && ctx.Message.Stickers.First() is SocketSticker ss)
|
||||
{
|
||||
name ??= ss.Name;
|
||||
description = ss.Description;
|
||||
tags = tags is null or { Length: 0 } ? ss.Tags.ToArray() : tags;
|
||||
format = FormatToExtension(ss.Format);
|
||||
|
||||
using var http = _httpFactory.CreateClient();
|
||||
stream = await http.GetStreamAsync(ss.GetStickerUrl());
|
||||
}
|
||||
// else if (ctx.Message.Attachments.FirstOrDefault() is { } attachment)
|
||||
// {
|
||||
// var url = attachment?.Url;
|
||||
//
|
||||
// if (url is null)
|
||||
// return;
|
||||
//
|
||||
// if (name is null)
|
||||
// {
|
||||
// await ReplyErrorLocalizedAsync(strs.sticker_missing_name);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// format = Path.GetExtension(attachment.Filename);
|
||||
//
|
||||
// if (attachment is not { Width: 300, Height: 300 })
|
||||
// {
|
||||
// await ReplyErrorLocalizedAsync(strs.sticker_invalid_size);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// using var http = _httpFactory.CreateClient();
|
||||
//
|
||||
// using var res = await http.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
|
||||
// if (res.GetContentLength() > 512.Kilobytes().Bytes)
|
||||
// {
|
||||
// await ReplyErrorLocalizedAsync(strs.invalid_emoji_link);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// stream = await res.Content.ReadAsStreamAsync();
|
||||
// }
|
||||
else
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.sticker_error);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (tags.Length == 0)
|
||||
tags = new[] { name };
|
||||
|
||||
await ctx.Guild.CreateStickerAsync(name,
|
||||
string.IsNullOrWhiteSpace(description) ? "Missing description" : description,
|
||||
tags,
|
||||
stream,
|
||||
$"{name}.{format}");
|
||||
|
||||
await ctx.OkAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Warning(ex, "Error occurred while adding a sticker: {Message}", ex.Message);
|
||||
await ReplyErrorLocalizedAsync(strs.error_occured);
|
||||
}
|
||||
finally
|
||||
{
|
||||
await stream.DisposeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private static string FormatToExtension(StickerFormatType format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case StickerFormatType.None:
|
||||
case StickerFormatType.Png:
|
||||
case StickerFormatType.Apng:
|
||||
return "png";
|
||||
case StickerFormatType.Lottie:
|
||||
return "lottie";
|
||||
default:
|
||||
throw new ArgumentException(nameof (format));
|
||||
}
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
[OwnerOnly]
|
||||
public async Task ListServers(int page = 1)
|
||||
|
@@ -302,7 +302,7 @@ public class CommandHandler : INService, IReadyExecutor
|
||||
}
|
||||
|
||||
public Task<(bool Success, string Error, CommandInfo Info)> ExecuteCommandAsync(
|
||||
CommandContext context,
|
||||
ICommandContext context,
|
||||
string input,
|
||||
int argPos,
|
||||
IServiceProvider serviceProvider,
|
||||
@@ -311,7 +311,7 @@ public class CommandHandler : INService, IReadyExecutor
|
||||
|
||||
|
||||
public async Task<(bool Success, string Error, CommandInfo Info)> ExecuteCommand(
|
||||
CommandContext context,
|
||||
ICommandContext context,
|
||||
string input,
|
||||
IServiceProvider services,
|
||||
MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception)
|
||||
|
@@ -88,6 +88,9 @@ public sealed class CurrencyService : ICurrencyService, INService
|
||||
long amount,
|
||||
TxData txData)
|
||||
{
|
||||
if (amount == 0)
|
||||
return true;
|
||||
|
||||
var wallet = await GetWalletAsync(userId);
|
||||
var result = await wallet.Take(amount, txData);
|
||||
if(result)
|
||||
|
@@ -10,143 +10,11 @@ using System.Xml;
|
||||
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
public class GoogleApiService : IGoogleApiService, INService
|
||||
public sealed partial class GoogleApiService : IGoogleApiService, INService
|
||||
{
|
||||
private static readonly Regex
|
||||
_plRegex = new("(?:youtu\\.be\\/|list=)(?<id>[\\da-zA-Z\\-_]*)", RegexOptions.Compiled);
|
||||
|
||||
public IReadOnlyDictionary<string, string> Languages { get; } = new Dictionary<string, string>
|
||||
{
|
||||
{ "afrikaans", "af" },
|
||||
{ "albanian", "sq" },
|
||||
{ "arabic", "ar" },
|
||||
{ "armenian", "hy" },
|
||||
{ "azerbaijani", "az" },
|
||||
{ "basque", "eu" },
|
||||
{ "belarusian", "be" },
|
||||
{ "bengali", "bn" },
|
||||
{ "bulgarian", "bg" },
|
||||
{ "catalan", "ca" },
|
||||
{ "chinese-traditional", "zh-TW" },
|
||||
{ "chinese-simplified", "zh-CN" },
|
||||
{ "chinese", "zh-CN" },
|
||||
{ "croatian", "hr" },
|
||||
{ "czech", "cs" },
|
||||
{ "danish", "da" },
|
||||
{ "dutch", "nl" },
|
||||
{ "english", "en" },
|
||||
{ "esperanto", "eo" },
|
||||
{ "estonian", "et" },
|
||||
{ "filipino", "tl" },
|
||||
{ "finnish", "fi" },
|
||||
{ "french", "fr" },
|
||||
{ "galician", "gl" },
|
||||
{ "german", "de" },
|
||||
{ "georgian", "ka" },
|
||||
{ "greek", "el" },
|
||||
{ "haitian Creole", "ht" },
|
||||
{ "hebrew", "iw" },
|
||||
{ "hindi", "hi" },
|
||||
{ "hungarian", "hu" },
|
||||
{ "icelandic", "is" },
|
||||
{ "indonesian", "id" },
|
||||
{ "irish", "ga" },
|
||||
{ "italian", "it" },
|
||||
{ "japanese", "ja" },
|
||||
{ "korean", "ko" },
|
||||
{ "lao", "lo" },
|
||||
{ "latin", "la" },
|
||||
{ "latvian", "lv" },
|
||||
{ "lithuanian", "lt" },
|
||||
{ "macedonian", "mk" },
|
||||
{ "malay", "ms" },
|
||||
{ "maltese", "mt" },
|
||||
{ "norwegian", "no" },
|
||||
{ "persian", "fa" },
|
||||
{ "polish", "pl" },
|
||||
{ "portuguese", "pt" },
|
||||
{ "romanian", "ro" },
|
||||
{ "russian", "ru" },
|
||||
{ "serbian", "sr" },
|
||||
{ "slovak", "sk" },
|
||||
{ "slovenian", "sl" },
|
||||
{ "spanish", "es" },
|
||||
{ "swahili", "sw" },
|
||||
{ "swedish", "sv" },
|
||||
{ "tamil", "ta" },
|
||||
{ "telugu", "te" },
|
||||
{ "thai", "th" },
|
||||
{ "turkish", "tr" },
|
||||
{ "ukrainian", "uk" },
|
||||
{ "urdu", "ur" },
|
||||
{ "vietnamese", "vi" },
|
||||
{ "welsh", "cy" },
|
||||
{ "yiddish", "yi" },
|
||||
{ "af", "af" },
|
||||
{ "sq", "sq" },
|
||||
{ "ar", "ar" },
|
||||
{ "hy", "hy" },
|
||||
{ "az", "az" },
|
||||
{ "eu", "eu" },
|
||||
{ "be", "be" },
|
||||
{ "bn", "bn" },
|
||||
{ "bg", "bg" },
|
||||
{ "ca", "ca" },
|
||||
{ "zh-tw", "zh-TW" },
|
||||
{ "zh-cn", "zh-CN" },
|
||||
{ "hr", "hr" },
|
||||
{ "cs", "cs" },
|
||||
{ "da", "da" },
|
||||
{ "nl", "nl" },
|
||||
{ "en", "en" },
|
||||
{ "eo", "eo" },
|
||||
{ "et", "et" },
|
||||
{ "tl", "tl" },
|
||||
{ "fi", "fi" },
|
||||
{ "fr", "fr" },
|
||||
{ "gl", "gl" },
|
||||
{ "de", "de" },
|
||||
{ "ka", "ka" },
|
||||
{ "el", "el" },
|
||||
{ "ht", "ht" },
|
||||
{ "iw", "iw" },
|
||||
{ "hi", "hi" },
|
||||
{ "hu", "hu" },
|
||||
{ "is", "is" },
|
||||
{ "id", "id" },
|
||||
{ "ga", "ga" },
|
||||
{ "it", "it" },
|
||||
{ "ja", "ja" },
|
||||
{ "ko", "ko" },
|
||||
{ "lo", "lo" },
|
||||
{ "la", "la" },
|
||||
{ "lv", "lv" },
|
||||
{ "lt", "lt" },
|
||||
{ "mk", "mk" },
|
||||
{ "ms", "ms" },
|
||||
{ "mt", "mt" },
|
||||
{ "no", "no" },
|
||||
{ "fa", "fa" },
|
||||
{ "pl", "pl" },
|
||||
{ "pt", "pt" },
|
||||
{ "ro", "ro" },
|
||||
{ "ru", "ru" },
|
||||
{ "sr", "sr" },
|
||||
{ "sk", "sk" },
|
||||
{ "sl", "sl" },
|
||||
{ "es", "es" },
|
||||
{ "sw", "sw" },
|
||||
{ "sv", "sv" },
|
||||
{ "ta", "ta" },
|
||||
{ "te", "te" },
|
||||
{ "th", "th" },
|
||||
{ "tr", "tr" },
|
||||
{ "uk", "uk" },
|
||||
{ "ur", "ur" },
|
||||
{ "vi", "vi" },
|
||||
{ "cy", "cy" },
|
||||
{ "yi", "yi" }
|
||||
};
|
||||
|
||||
private readonly YouTubeService _yt;
|
||||
private readonly UrlshortenerService _sh;
|
||||
@@ -155,7 +23,7 @@ public class GoogleApiService : IGoogleApiService, INService
|
||||
private readonly IBotCredsProvider _creds;
|
||||
private readonly IHttpClientFactory _httpFactory;
|
||||
|
||||
public GoogleApiService(IBotCredsProvider creds, IHttpClientFactory factory)
|
||||
public GoogleApiService(IBotCredsProvider creds, IHttpClientFactory factory) : this()
|
||||
{
|
||||
_creds = creds;
|
||||
_httpFactory = factory;
|
||||
|
@@ -0,0 +1,158 @@
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
public sealed partial class GoogleApiService
|
||||
{
|
||||
private const string SUPPORTED = @"afrikaans af
|
||||
albanian sq
|
||||
amharic am
|
||||
arabic ar
|
||||
armenian hy
|
||||
assamese as
|
||||
aymara ay
|
||||
azerbaijani az
|
||||
bambara bm
|
||||
basque eu
|
||||
belarusian be
|
||||
bengali bn
|
||||
bhojpuri bho
|
||||
bosnian bs
|
||||
bulgarian bg
|
||||
catalan ca
|
||||
cebuano ceb
|
||||
chinese zh-CN
|
||||
chinese-trad zh-TW
|
||||
corsican co
|
||||
croatian hr
|
||||
czech cs
|
||||
danish da
|
||||
dhivehi dv
|
||||
dogri doi
|
||||
dutch nl
|
||||
english en
|
||||
esperanto eo
|
||||
estonian et
|
||||
ewe ee
|
||||
filipino fil
|
||||
finnish fi
|
||||
french fr
|
||||
frisian fy
|
||||
galician gl
|
||||
georgian ka
|
||||
german de
|
||||
greek el
|
||||
guarani gn
|
||||
gujarati gu
|
||||
haitian ht
|
||||
hausa ha
|
||||
hawaiian haw
|
||||
hebrew he
|
||||
hindi hi
|
||||
hmong hmn
|
||||
hungarian hu
|
||||
icelandic is
|
||||
igbo ig
|
||||
ilocano ilo
|
||||
indonesian id
|
||||
irish ga
|
||||
italian it
|
||||
japanese ja
|
||||
javanese jv
|
||||
kannada kn
|
||||
kazakh kk
|
||||
khmer km
|
||||
kinyarwanda rw
|
||||
konkani gom
|
||||
korean ko
|
||||
krio kri
|
||||
kurdish ku
|
||||
kurdish-sor ckb
|
||||
kyrgyz ky
|
||||
lao lo
|
||||
latin la
|
||||
latvian lv
|
||||
lingala ln
|
||||
lithuanian lt
|
||||
luganda lg
|
||||
luxembourgish lb
|
||||
macedonian mk
|
||||
maithili mai
|
||||
malagasy mg
|
||||
malay ms
|
||||
malayalam ml
|
||||
maltese mt
|
||||
maori mi
|
||||
marathi mr
|
||||
meiteilon mni-Mtei
|
||||
mizo lus
|
||||
mongolian mn
|
||||
myanmar my
|
||||
nepali ne
|
||||
norwegian no
|
||||
nyanja ny
|
||||
odia or
|
||||
oromo om
|
||||
pashto ps
|
||||
persian fa
|
||||
polish pl
|
||||
portuguese pt
|
||||
punjabi pa
|
||||
quechua qu
|
||||
romanian ro
|
||||
russian ru
|
||||
samoan sm
|
||||
sanskrit sa
|
||||
scots gd
|
||||
sepedi nso
|
||||
serbian sr
|
||||
sesotho st
|
||||
shona sn
|
||||
sindhi sd
|
||||
sinhala si
|
||||
slovak sk
|
||||
slovenian sl
|
||||
somali so
|
||||
spanish es
|
||||
sundanese su
|
||||
swahili sw
|
||||
swedish sv
|
||||
tagalog tl
|
||||
tajik tg
|
||||
tamil ta
|
||||
tatar tt
|
||||
telugu te
|
||||
thai th
|
||||
tigrinya ti
|
||||
tsonga ts
|
||||
turkish tr
|
||||
turkmen tk
|
||||
twi ak
|
||||
ukrainian uk
|
||||
urdu ur
|
||||
uyghur ug
|
||||
uzbek uz
|
||||
vietnamese vi
|
||||
welsh cy
|
||||
xhosa xh
|
||||
yiddish yi
|
||||
yoruba yo
|
||||
zulu zu";
|
||||
|
||||
|
||||
public IReadOnlyDictionary<string, string> Languages { get; }
|
||||
|
||||
private GoogleApiService()
|
||||
{
|
||||
var langs = SUPPORTED.Split("\n")
|
||||
.Select(x => x.Split(' '))
|
||||
.ToDictionary(x => x[0].Trim(), x => x[1].Trim());
|
||||
|
||||
foreach (var (_, v) in langs.ToArray())
|
||||
{
|
||||
langs.Add(v, v);
|
||||
}
|
||||
|
||||
Languages = langs;
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -7,7 +7,7 @@ namespace NadekoBot.Services;
|
||||
|
||||
public sealed class StatsService : IStatsService, IReadyExecutor, INService
|
||||
{
|
||||
public const string BOT_VERSION = "4.3.10";
|
||||
public const string BOT_VERSION = "4.3.11";
|
||||
|
||||
public string Author
|
||||
=> "Kwoth#2452";
|
||||
|
@@ -23,11 +23,7 @@ public static class MessageChannelExtensions
|
||||
embeds: embeds is null
|
||||
? null
|
||||
: embeds as Embed[] ?? embeds.ToArray(),
|
||||
components: components,
|
||||
options: new()
|
||||
{
|
||||
RetryMode = RetryMode.AlwaysRetry
|
||||
});
|
||||
components: components);
|
||||
}
|
||||
|
||||
public static async Task<IUserMessage> SendAsync(
|
||||
@@ -155,27 +151,6 @@ public static class MessageChannelExtensions
|
||||
string? footer = null)
|
||||
=> ch.SendAsync(eb, MessageType.Error, title, text, url, footer);
|
||||
|
||||
// weird stuff
|
||||
|
||||
public static Task<IUserMessage> SendTableAsync<T>(
|
||||
this IMessageChannel ch,
|
||||
string seed,
|
||||
IEnumerable<T> items,
|
||||
Func<T, string> howToPrint,
|
||||
int columns = 3)
|
||||
=> ch.SendMessageAsync($@"{seed}```css
|
||||
{items.Chunk(columns)
|
||||
.Select(ig => string.Concat(ig.Select(howToPrint)))
|
||||
.Join("\n")}
|
||||
```");
|
||||
|
||||
public static Task<IUserMessage> SendTableAsync<T>(
|
||||
this IMessageChannel ch,
|
||||
IEnumerable<T> items,
|
||||
Func<T, string> howToPrint,
|
||||
int columns = 3)
|
||||
=> ch.SendTableAsync("", items, howToPrint, columns);
|
||||
|
||||
public static Task SendPaginatedConfirmAsync(
|
||||
this ICommandContext ctx,
|
||||
int currentPage,
|
||||
|
@@ -23,11 +23,7 @@ public static class SocketMessageComponentExtensions
|
||||
? null
|
||||
: embeds as Embed[] ?? embeds.ToArray(),
|
||||
components: components,
|
||||
ephemeral: ephemeral,
|
||||
options: new()
|
||||
{
|
||||
RetryMode = RetryMode.AlwaysRetry
|
||||
});
|
||||
ephemeral: ephemeral);
|
||||
}
|
||||
|
||||
public static Task RespondAsync(
|
||||
|
@@ -728,6 +728,9 @@ showemojis:
|
||||
emojiadd:
|
||||
- emojiadd
|
||||
- ea
|
||||
stickeradd:
|
||||
- stickeradd
|
||||
- sa
|
||||
emojiremove:
|
||||
- emojiremove
|
||||
- emojirm
|
||||
@@ -1383,4 +1386,7 @@ patronmessage:
|
||||
eval:
|
||||
- eval
|
||||
autopublish:
|
||||
- autopublish
|
||||
- autopublish
|
||||
doas:
|
||||
- doas
|
||||
- execas
|
@@ -1245,6 +1245,11 @@ emojiremove:
|
||||
desc: "Removes the specified emoji or emojis from this server."
|
||||
args:
|
||||
- ":eagleWarrior: :plumedArcher:"
|
||||
stickeradd:
|
||||
desc: "Adds the sticker from your message to this server. Send the sticker along with this command (in the same message)."
|
||||
args:
|
||||
- ""
|
||||
- "name \"description\" tag1 tag2 tagN"
|
||||
deckshuffle:
|
||||
desc: "Reshuffles all cards back into the deck."
|
||||
args:
|
||||
@@ -1991,13 +1996,22 @@ ytuploadnotif:
|
||||
desc: |-
|
||||
Subscribe to a youtube channel's upload rss feed.
|
||||
Shortcut for `.feed https://www.youtube.com/feeds/videos.xml?channel_id=%3Cyoutube_channel_id`
|
||||
You can optionally specify a message which will be posted with an update.
|
||||
args:
|
||||
- "https://www.youtube.com/channel/UCSJ4gkVC6NrvII8umztf0Ow"
|
||||
- "https://www.youtube.com/channel/UCSJ4gkVC6NrvII8umztf0Ow"
|
||||
- "https://www.youtube.com/channel/UCSJ4gkVC6NrvII8umztf0Ow New video is posted"
|
||||
feed:
|
||||
desc: "Subscribes to a feed. Bot will post an update up to once every 10 seconds. You can have up to 10 feeds on one server. All feeds must have unique URLs. Set a channel as a second optional parameter to specify where to send the updates."
|
||||
desc: |-
|
||||
Subscribes to a feed.
|
||||
Bot will post an update up to once every 10 seconds.
|
||||
You can have up to 10 feeds on one server.
|
||||
All feeds must have unique URLs.
|
||||
Set a channel as a second optional parameter to specify where to send the updates.
|
||||
You can optionally specify a message after the channel name which will be posted with an update.
|
||||
args:
|
||||
- "https://blog.playstation.com/feed/"
|
||||
- "https://blog.playstation.com/feed/ #updates"
|
||||
- "https://blog.playstation.com/feed/ #updates New playstation rss feed post!"
|
||||
feedremove:
|
||||
desc: "Stops tracking a feed on the given index. Use `{0}feeds` command to see a list of feeds and their indexes."
|
||||
args:
|
||||
@@ -2345,4 +2359,8 @@ threaddelete:
|
||||
autopublish:
|
||||
desc: "Make the bot automatically publish all messages posted in the news channel this command was executed in."
|
||||
args:
|
||||
- ""
|
||||
- ""
|
||||
doas:
|
||||
desc: "Execute the command as if you were the target user. Requires bot ownership and server administrator permission."
|
||||
args:
|
||||
- "@Thief .give all @Admin"
|
||||
|
@@ -977,14 +977,14 @@
|
||||
"created_by": "Created by {0}",
|
||||
"module_footer": "{0}cmds {1}",
|
||||
"module_page_empty": "No module on this page.",
|
||||
"module_description_help": "Get command help, descriptions and usage examples",
|
||||
"module_description_gambling": "Bet on dice rolls, blackjack, slots, coinflips and others",
|
||||
"module_description_games": "Play trivia, nunchi, hangman, connect4 and other games",
|
||||
"module_description_nsfw": "NSFW commands.",
|
||||
"module_description_music": "Play music from youtube, local files soundcloud and radio streams",
|
||||
"module_description_utility": "Manage custom quotes, repeating messages and check facts about the server",
|
||||
"module_description_help": "Get command help, descriptions and usage examples",
|
||||
"module_description_gambling": "Bet on dice rolls, blackjack, slots, coinflips and others",
|
||||
"module_description_games": "Play trivia, nunchi, hangman, connect4 and other games",
|
||||
"module_description_nsfw": "NSFW commands.",
|
||||
"module_description_music": "Play music from youtube, local files soundcloud and radio streams",
|
||||
"module_description_utility": "Manage custom quotes, repeating messages and check facts about the server",
|
||||
"module_description_administration": "Moderation, punish users, setup self assignable roles and greet messages",
|
||||
"module_description_expressions": "Setup custom bot responses to certain words or phrases",
|
||||
"module_description_expressions": "Setup custom bot responses to certain words or phrases",
|
||||
"module_description_permissions": "Setup perms for commands, filter words and set up command cooldowns",
|
||||
"module_description_searches": "Search for jokes, images of animals, anime and manga",
|
||||
"module_description_xp": "Gain xp based on chat activity, check users' xp cards",
|
||||
@@ -1005,7 +1005,7 @@
|
||||
"linkonly_disable": "This channel is no longer link-only.",
|
||||
"deleted_x_servers": "Deleted {0} servers.",
|
||||
"curtr_gift": "Gift from {0} [{1}]",
|
||||
"curtr_award": "Awarded by bot owner {0} [{1}]",
|
||||
"curtr_award": "Awarded by bot owner {0} [{1}]",
|
||||
"curtr_take": "Taken by bot owner {0} [{1}]",
|
||||
"list_of_medusae": "List of Medusae",
|
||||
"list_of_unloaded": "List of Available Medusae",
|
||||
@@ -1051,5 +1051,11 @@
|
||||
"patron_insuff_tier": "Your Patron Tier insufficient to perform this action.",
|
||||
"xpshop_already_owned": "You already own this item.",
|
||||
"xpshop_item_not_found": "An item with that key doesn't exist.",
|
||||
"xpshop_website": "You can see the list of all Xp Shop items here: <https://xpshop.nadeko.bot>"
|
||||
"xpshop_website": "You can see the list of all Xp Shop items here: <https://xpshop.nadeko.bot>",
|
||||
"sticker_invalid_size": "Stickers must be exactly 300x300 pixels.",
|
||||
"sticker_error": "You must either send a sticker along with this command, or upload a 300x300 .png or .apng image.",
|
||||
"sticker_missing_name": "Please specify a name for the sticker.",
|
||||
"thread_deleted": "Thread Deleted",
|
||||
"thread_created": "Thread Created",
|
||||
"supported_languages": "Supported Languages"
|
||||
}
|
||||
|
@@ -946,106 +946,106 @@
|
||||
"reminder_server_list": "Lista przypomnień serwera",
|
||||
"imageonly_enable": "Ten kanał działa od teraz w trybie tylko obrazki.",
|
||||
"imageonly_disable": "Ten kanał już nie działa w trybie tylko obrazki.",
|
||||
"transaction": "",
|
||||
"finished_track": "",
|
||||
"playing_track": "",
|
||||
"queued_track": "",
|
||||
"removed_track": "",
|
||||
"autoplaying": "",
|
||||
"music_autoplay_on": "",
|
||||
"music_autoplay_off": "",
|
||||
"track_moved": "",
|
||||
"atl_not_enabled": "",
|
||||
"channels": "",
|
||||
"track_not_found": "",
|
||||
"removed_track_error": "",
|
||||
"market_cap_dominance": "",
|
||||
"circulating_supply": "",
|
||||
"module_description_expressions": "",
|
||||
"deleted_x_servers": "",
|
||||
"curtr_gift": "",
|
||||
"curtr_award": "",
|
||||
"curtr_take": "",
|
||||
"expr_deleted": "",
|
||||
"expr_insuff_perms": "",
|
||||
"expressions": "",
|
||||
"expr_new": "",
|
||||
"expr_no_found": "",
|
||||
"expr_no_found_id": "",
|
||||
"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": ""
|
||||
"transaction": "Transakcja Walutowa",
|
||||
"finished_track": "Utwór zakończony",
|
||||
"playing_track": "Odtwarzam utwór #{0}",
|
||||
"queued_track": "Utwór zakolejkowany",
|
||||
"removed_track": "Utwór usunięty",
|
||||
"autoplaying": "Automatycznie dodaje powiązane utwory.",
|
||||
"music_autoplay_on": "Automatyczne odtwarzanie muzyki włączone. Będę samodzielnie kolejkować powiązane utwory po zakończeniu bieżącego odtwarzania.",
|
||||
"music_autoplay_off": "Automatyczne odtwarzanie muzyki wyłączone.",
|
||||
"track_moved": "Utwór przesunięty",
|
||||
"atl_not_enabled": "Automatyczne tłumaczenie nie jest włączone na tym kanale lub podano niewłaściwy język.",
|
||||
"channels": "Kanały",
|
||||
"track_not_found": "Nie znaleziono utworu.",
|
||||
"removed_track_error": "Utwór o podanym indeksie nie istnieje",
|
||||
"market_cap_dominance": "Dominacja",
|
||||
"circulating_supply": "Podaż obiegowa",
|
||||
"module_description_expressions": "Ustaw własne odpowiedzi bota na wybrane słowa lub wyrażenia",
|
||||
"deleted_x_servers": "Usunięto {0} serwerów.",
|
||||
"curtr_gift": "Prezent od {0} [{1}]",
|
||||
"curtr_award": "Przyznane przez właściciela bota {0} [{1}]",
|
||||
"curtr_take": "Zabrane przez właściciela bota {0} [{1}]",
|
||||
"expr_deleted": "Wyrażenie usunięte",
|
||||
"expr_insuff_perms": "Niewystarczające uprawnienia. Wymaga uprawnień Właściciela Bota dla globalnych wyrażeń, a uprawnień Administratora dla serwerowych wyrażeń.",
|
||||
"expressions": "Wyrażenia",
|
||||
"expr_new": "Nowe Wyrażenie",
|
||||
"expr_no_found": "Nie znaleziono wyrażeń.",
|
||||
"expr_no_found_id": "Nie znaleziono wyrażenia o podanym id.",
|
||||
"exprs_cleared": "Wszystkie {0} wyrażenia na tym serwerze zostały usunięte.",
|
||||
"expr_reset": "Wyrażenia o id {0} nie będą już dodawać reakcji.",
|
||||
"expr_set": "Wyrażenia o id {0} będą dodawać następujące reakcje do odpowiedzi: {1}",
|
||||
"expr_edited": "Wyrażenie Zedytowane",
|
||||
"stream_online_delete_enabled": "Powiadomienia o trwającym streamie będą teraz usuwane kiedy stream się zakończy.",
|
||||
"stream_online_delete_disabled": "Powiadomienia o trwającym streamie nie będą już usuwane kiedy stream się zakończy.",
|
||||
"club_create_error_name": "Nie udało się utworzyć klubu. Klub o podanej nazwie już istnieje.",
|
||||
"club_desc_update": "Zaktualizowano Opis Klubu",
|
||||
"bank_accounts": "Konta Bankowe",
|
||||
"module_description_medusa": "**Tylko dla Właściciela Bota.** Załaduj, rozładuj i zarządzaj dynamicznymi modułami. Czytaj więcej [tutaj](https://nadekobot.readthedocs.io/en/latest/medusa/creating-a-medusa/)",
|
||||
"list_of_medusae": "Lista Meduz",
|
||||
"list_of_unloaded": "Lista Dostępnych Meduz",
|
||||
"medusa_name_not_found": "Meduza o podanej nazwie nie istnieje lub nie jest załadowana.",
|
||||
"medusa_info": "Informacje o Meduzie",
|
||||
"sneks_count": "Wonsze ({0})",
|
||||
"commands_count": "Komendy ({0})",
|
||||
"no_medusa_loaded": "Brak załadowanych meduz.",
|
||||
"no_medusa_available": "Brak dostępnych meduz.",
|
||||
"loaded_medusae": "Załadowane Meduzy",
|
||||
"medusa_not_loaded": "Meduza o podanej nazwie nie jest załadowana.",
|
||||
"medusa_possibly_cant_unload": "Meduza prawdopodobnie nie została załadowana w pełni. Zrestartuj bota jeśli pojawią się problemy.",
|
||||
"medusa_loaded": "Meduza {0} została załadowana.",
|
||||
"medusa_unloaded": "Meduza {0} została rozładowana.",
|
||||
"medusa_empty": "Meduza nie została załadowana ponieważ nie zawiera żadnych Wonszy.",
|
||||
"medusa_already_loaded": "Meduza {0} jest już załadowana",
|
||||
"medusa_invalid_not_found": "Meduza o podanej nazwie nie została znaleziona lub plik był błędny",
|
||||
"bank_balance": "Masz {0} na swoim koncie bankowym.",
|
||||
"bank_deposited": "Wpłacono {0} na twoje konto bankowe.",
|
||||
"bank_withdrew": "Wypłacono {0} z twojego konta bankowego.",
|
||||
"bank_withdraw_insuff": "Nie masz wystarczającej ilości {0} na swoim koncie bankowym.",
|
||||
"cmd_group_commands": "grupa komend '{0}'",
|
||||
"limit_reached": "Osiągnięto limit funkcji wynoszący {0}.",
|
||||
"feature_limit_reached_you": "Osiągnięto limit {0} funkcji {1}. Być może zwiększenie progu wspierania pozwoli podnieść ten limit.",
|
||||
"feature_limit_reached_owner": "Właściciel servera osiągnął limit {0} funkcji {1}. Właściciel serwera może być w stanie zwiększyć ten limit przez zwiększenie progu wspierania.",
|
||||
"feature_limit_reached_either": "Osiągnięto limit {0} funkcji {1}. Albo ty albo właściciel serwera możecie być w stanie zwiększyć ten limit przez zwiększenie progu wspierania.",
|
||||
"tier": "Próg",
|
||||
"pledge": "Deklaracja",
|
||||
"expires": "Wygasa",
|
||||
"commands": "Komendy",
|
||||
"groups": "Grupy",
|
||||
"modules": "Moduły",
|
||||
"no_quota_found": "Nie znaleziono wartości",
|
||||
"patron_info": "Informacje o Patronie",
|
||||
"quotas": "<<< Kwoty >>>",
|
||||
"patron_not_enabled": "System patronów jest wyłączony.",
|
||||
"results_in": "wynikiem {0} jest {1}",
|
||||
"patron_msg_sent": "Zakończono wysyłanie wiadomości do patronów na i powyżej progu {1}. {1} wysłano pomyślnie, a {2} nie udało się.",
|
||||
"cards": "Karty",
|
||||
"hand_value": "Siła ręki",
|
||||
"roll2": "Rzut",
|
||||
"rolls": "Rzuty",
|
||||
"available_tests": "Dostępne Testy",
|
||||
"test_results_for": "Wyniki testu na {0}",
|
||||
"multiplier": "Mnożnik",
|
||||
"trivia_ended": "Quiz zakończony",
|
||||
"card": "Karta",
|
||||
"guess": "Zgadnięcie",
|
||||
"repeater_skip_next": "Następne wyzwolenie tego powtórzenia zostanie pominięte.",
|
||||
"repeater_dont_skip_next": "Następne wyzwolenie tego powtórzenia nie będzie pominięte.",
|
||||
"remind_timely": "Przypomnę ci o twojej nagrodzie okresowej {0}",
|
||||
"xp_shop_disabled": "Sklep Xp został wyłączony przez właściciela, lub nie ma towarów na sprzedaż.",
|
||||
"timely_time": "Czas odebrać twoją nagrodę okresową.",
|
||||
"buy": "Kup",
|
||||
"use": "Użyj",
|
||||
"in_use": "W użyciu",
|
||||
"xp_shop_item_cant_use": "Nie możesz użyć tego przedmiotu ponieważ nie istnieje lub nie posiadasz go.",
|
||||
"linkonly_enable": "Ten kanał jest teraz w trybie tylko linki.",
|
||||
"linkonly_disable": "Ten kanał nie jest już w trybie tylko linki.",
|
||||
"xp_shop_buy_required_tier": "Kupowanie towarów w tym sklepie wymaga posiadania Rangi Patrona {0} lub wyższej.",
|
||||
"available_commands": "Dostępne Komendy",
|
||||
"xpadd_users": "Dodano {0} XP serwerowego dla {1} użytkowników.",
|
||||
"xpshop_buy_success": "Pomyślnie zakupiono `{0}/{1}`",
|
||||
"patron_insuff_tier": "Twoja Ranga Patrona jest niewystarczająca do wykonania tej akcji.",
|
||||
"xpshop_already_owned": "Już posiadasz ten przedmiot.",
|
||||
"xpshop_item_not_found": "Przedmiot o podanym kluczu nie istnieje.",
|
||||
"xpshop_website": "Możesz sprawdzić listę wszystkich towarów Sklepu Xp tutaj: <https://xpshop.nadeko.bot>"
|
||||
}
|
@@ -195,7 +195,7 @@
|
||||
"trivia_times_up": "Час вийшов! Правильна відповідь {0}",
|
||||
"ttt_against_yourself": "Ви не можете грати проти себе.",
|
||||
"ttt_already_running": "Хрестики-нулики наразі розпочато на цьому сервері.",
|
||||
"ttt_a_draw": "Нічия",
|
||||
"ttt_a_draw": "Нічия!",
|
||||
"ttt_created": "створив гру в Хрестики-нулики.",
|
||||
"ttt_has_won": "{0} виграв!",
|
||||
"ttt_matched_three": "Зібрав три",
|
||||
@@ -976,76 +976,76 @@
|
||||
"expr_reset": "Вираз з id {0} більше не получає реакцій.",
|
||||
"expr_set": "Вираз з цим id {0} буде получати вказані реакції до відповіді: {1}",
|
||||
"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": ""
|
||||
"stream_online_delete_enabled": "Сповіщення про онлайн-стрім тепер видалятимуться, коли стрім переходить у режим офлайн.",
|
||||
"stream_online_delete_disabled": "Сповіщення про онлайн-стрім більше не видалятимуться, коли стрім переходить у режим офлайн.",
|
||||
"club_create_error_name": "Не вдалося створити клуб. Клуб з такою назвою вже існує.",
|
||||
"club_desc_update": "Опис клубу оновлено",
|
||||
"bank_accounts": "Банківські рахунки",
|
||||
"module_description_medusa": "**Лише власник бота.** Завантажуйте, вивантажуйте та обробляйте динамічні модулі. Докладніше [тут](https://nadekobot.readthedocs.io/en/latest/medusa/creating-a-medusa/)",
|
||||
"list_of_medusae": "Список Медуз",
|
||||
"list_of_unloaded": "Список доступних Медуз",
|
||||
"medusa_name_not_found": "Медуза з такою назвою не існує або не завантажується.",
|
||||
"medusa_info": "Інформація про медузу",
|
||||
"sneks_count": "Снеки ({0})",
|
||||
"commands_count": "Команди ({0})",
|
||||
"no_medusa_loaded": "Завантажених медуз немає.",
|
||||
"no_medusa_available": "Медуза недоступна.",
|
||||
"loaded_medusae": "Завантажені медузи",
|
||||
"medusa_not_loaded": "Медуза з такою назвою не завантажується.",
|
||||
"medusa_possibly_cant_unload": "Медуза, ймовірно, не повністю розвантажена. Перезапустіть бота, якщо виникнуть проблеми.",
|
||||
"medusa_loaded": "Медуза {0} завантажена.",
|
||||
"medusa_unloaded": "Медузу {0} вивантажено.",
|
||||
"medusa_empty": "Медуза не була завантажена, оскільки не містила Снеків.",
|
||||
"medusa_already_loaded": "Медуза {0} уже завантажено",
|
||||
"medusa_invalid_not_found": "Медуза з такою назвою не знайдено або файл недійсний",
|
||||
"bank_balance": "На вашому банківському рахунку є {0}.",
|
||||
"bank_deposited": "Ви внесли {0} на свій банківський рахунок.",
|
||||
"bank_withdrew": "Ви зняли {0} зі свого банківського рахунку.",
|
||||
"bank_withdraw_insuff": "На вашому банківському рахунку недостатньо {0}.",
|
||||
"cmd_group_commands": "Група команд '{0}'.",
|
||||
"limit_reached": "Досягнуто ліміту функцій у {0}.",
|
||||
"feature_limit_reached_you": "Ви досягли обмеження в {0} для функції {1}. Ви можете збільшити цей ліміт, підвищивши рівень свого патрона.",
|
||||
"feature_limit_reached_owner": "Власник сервера досяг ліміту в {0} для функції {1}. Власник сервера може збільшити цей ліміт, підвищивши рівень патрона.",
|
||||
"feature_limit_reached_either": "Досягнуто обмеження в {0} для функції {1}. Ви або власник сервера можете підвищити цей ліміт, підвищивши рівень патрона.",
|
||||
"tier": "Рівень",
|
||||
"pledge": "Застава",
|
||||
"expires": "Вичерпується",
|
||||
"commands": "Команди",
|
||||
"groups": "Групи",
|
||||
"modules": "Модулі",
|
||||
"no_quota_found": "Цитата не знайдена",
|
||||
"patron_info": "Інформація про патрона",
|
||||
"quotas": "<<< Цитата >>>",
|
||||
"patron_not_enabled": "Система патрона вимкнена.",
|
||||
"results_in": "{0} призводить до {1}с",
|
||||
"patron_msg_sent": "Надсилання повідомлень патронам рівня {1} і вище закінчено. {1} успішно надіслано та {2} не надіслано.",
|
||||
"cards": "Карти",
|
||||
"hand_value": "Вартість руки",
|
||||
"roll2": "Кидок",
|
||||
"rolls": "Кидки",
|
||||
"available_tests": "Доступні тести",
|
||||
"test_results_for": "Результати тесту для {0}",
|
||||
"multiplier": "Множник",
|
||||
"trivia_ended": "Гра вікторини закінчилася",
|
||||
"card": "Карта",
|
||||
"guess": "Вгадай",
|
||||
"repeater_skip_next": "Наступний тригер цього повторювача буде пропущено.",
|
||||
"repeater_dont_skip_next": "Наступний тригер цього повторювача не буде пропущено.",
|
||||
"remind_timely": "Я нагадаю вам про вашу своєчасну винагороду {0}",
|
||||
"xp_shop_disabled": "Магазин Xp відключений власником, або немає товарів у продажу.",
|
||||
"timely_time": "Настав час вашої своєчасної винагороди.",
|
||||
"buy": "Купити",
|
||||
"use": "Використати",
|
||||
"in_use": "У використані",
|
||||
"xp_shop_item_cant_use": "Ви не можете використовувати цей предмет, оскільки він не існує або вам не належить.",
|
||||
"linkonly_enable": "Цей канал тепер доступний лише для посилань.",
|
||||
"linkonly_disable": "Цей канал більше не доступний лише для посилань.",
|
||||
"xp_shop_buy_required_tier": "Для купівлі товарів у цьому магазині потрібен рівень патрона {0} або вищий.",
|
||||
"available_commands": "Доступні команди",
|
||||
"xpadd_users": "Додано {0} сервер XP до {1} користувачів.",
|
||||
"xpshop_buy_success": "Успішно придбано `{0}/{1}`",
|
||||
"patron_insuff_tier": "Рівень вашого патрона недостатній для виконання цієї дії.",
|
||||
"xpshop_already_owned": "Ви вже володієте цим товаром.",
|
||||
"xpshop_item_not_found": "Елемент із таким ключем не існує.",
|
||||
"xpshop_website": "Ви можете переглянути список усіх товарів Xp магазина тут: <https://xpshop.nadeko.bot>"
|
||||
}
|
Reference in New Issue
Block a user