Merge remote-tracking branch 'Kwoth/1.9' into 1.9
This commit is contained in:
commit
6b2a1473ec
@ -261,7 +261,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
public async Task CreatVoiChanl([Remainder] string channelName)
|
public async Task CreatVoiChanl([Remainder] string channelName)
|
||||||
{
|
{
|
||||||
var ch = await Context.Guild.CreateVoiceChannelAsync(channelName).ConfigureAwait(false);
|
var ch = await Context.Guild.CreateVoiceChannelAsync(channelName).ConfigureAwait(false);
|
||||||
await ReplyConfirmLocalized("createvoich",Format.Bold(ch.Name)).ConfigureAwait(false);
|
await ReplyConfirmLocalized("createvoich", Format.Bold(ch.Name)).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
@ -312,7 +312,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
[RequireUserPermission(GuildPermission.MentionEveryone)]
|
[RequireUserPermission(GuildPermission.MentionEveryone)]
|
||||||
public async Task MentionRole(params IRole[] roles)
|
public async Task MentionRole(params IRole[] roles)
|
||||||
{
|
{
|
||||||
string send = "❕" +GetText("menrole",Context.User.Mention);
|
string send = "❕" + GetText("menrole", Context.User.Mention);
|
||||||
foreach (var role in roles)
|
foreach (var role in roles)
|
||||||
{
|
{
|
||||||
send += $"\n**{role.Name}**\n";
|
send += $"\n**{role.Name}**\n";
|
||||||
|
@ -18,10 +18,15 @@ namespace NadekoBot.Modules.Administration
|
|||||||
public class UserPunishCommands : NadekoSubmodule<UserPunishService>
|
public class UserPunishCommands : NadekoSubmodule<UserPunishService>
|
||||||
{
|
{
|
||||||
private readonly DbService _db;
|
private readonly DbService _db;
|
||||||
|
private readonly CurrencyService _cs;
|
||||||
|
private readonly IBotConfigProvider _bc;
|
||||||
|
|
||||||
public UserPunishCommands(DbService db, MuteService muteService)
|
public UserPunishCommands(DbService db, MuteService muteService,
|
||||||
|
CurrencyService cs, IBotConfigProvider bc)
|
||||||
{
|
{
|
||||||
_db = db;
|
_db = db;
|
||||||
|
_cs = cs;
|
||||||
|
_bc = bc;
|
||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
@ -397,6 +402,92 @@ namespace NadekoBot.Modules.Administration
|
|||||||
.AddField(efb => efb.WithName("ID").WithValue(user.Id.ToString()).WithIsInline(true)))
|
.AddField(efb => efb.WithName("ID").WithValue(user.Id.ToString()).WithIsInline(true)))
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
|
[RequireContext(ContextType.Guild)]
|
||||||
|
[RequireUserPermission(GuildPermission.BanMembers)]
|
||||||
|
[RequireBotPermission(GuildPermission.BanMembers)]
|
||||||
|
[OwnerOnly]
|
||||||
|
public async Task MassKill([Remainder] string people)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(people))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var gusers = ((SocketGuild)Context.Guild).Users;
|
||||||
|
//get user objects and reasons
|
||||||
|
var bans = people.Split("\n")
|
||||||
|
.Select(x =>
|
||||||
|
{
|
||||||
|
var split = x.Trim().Split(" ");
|
||||||
|
|
||||||
|
var reason = string.Join(" ", split.Skip(1));
|
||||||
|
|
||||||
|
if (ulong.TryParse(split[0], out var id))
|
||||||
|
return (Original: split[0], Id: id, Reason: reason);
|
||||||
|
|
||||||
|
return (Original: split[0],
|
||||||
|
Id: gusers
|
||||||
|
.FirstOrDefault(u => u.ToString().ToLowerInvariant() == x)
|
||||||
|
?.Id,
|
||||||
|
Reason: reason);
|
||||||
|
})
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
//if user is null, means that person couldn't be found
|
||||||
|
var missing = bans
|
||||||
|
.Where(x => !x.Id.HasValue)
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
//get only data for found users
|
||||||
|
var found = bans
|
||||||
|
.Where(x => x.Id.HasValue)
|
||||||
|
.Select(x => x.Id.Value)
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
var missStr = string.Join("\n", missing);
|
||||||
|
if (string.IsNullOrWhiteSpace(missStr))
|
||||||
|
missStr = "-";
|
||||||
|
|
||||||
|
//send a message but don't wait for it
|
||||||
|
var banningMessageTask = Context.Channel.EmbedAsync(new EmbedBuilder()
|
||||||
|
.WithDescription(GetText("mass_kill_in_progress", bans.Length))
|
||||||
|
.AddField(GetText("invalid", missing.Length), missStr)
|
||||||
|
.WithOkColor());
|
||||||
|
|
||||||
|
using (var uow = _db.UnitOfWork)
|
||||||
|
{
|
||||||
|
var bc = uow.BotConfig.GetOrCreate(set => set.Include(x => x.Blacklist));
|
||||||
|
//blacklist the users
|
||||||
|
bc.Blacklist.AddRange(found.Select(x =>
|
||||||
|
new BlacklistItem
|
||||||
|
{
|
||||||
|
ItemId = x,
|
||||||
|
Type = BlacklistType.User,
|
||||||
|
}));
|
||||||
|
//clear their currencies
|
||||||
|
uow.Currency.RemoveFromMany(found.Select(x => (long)x).ToList());
|
||||||
|
uow.Complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
_bc.Reload();
|
||||||
|
|
||||||
|
//do the banning
|
||||||
|
await Task.WhenAll(bans
|
||||||
|
.Where(x => x.Id.HasValue)
|
||||||
|
.Select(x => Context.Guild.AddBanAsync(x.Id.Value, 7, x.Reason, new RequestOptions() {
|
||||||
|
RetryMode = RetryMode.AlwaysRetry,
|
||||||
|
})))
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
|
//wait for the message and edit it
|
||||||
|
var banningMessage = await banningMessageTask.ConfigureAwait(false);
|
||||||
|
|
||||||
|
await banningMessage.ModifyAsync(x => x.Embed = new EmbedBuilder()
|
||||||
|
.WithDescription(GetText("mass_kill_completed", bans.Length))
|
||||||
|
.AddField(GetText("invalid", missing.Length), missStr)
|
||||||
|
.WithOkColor()
|
||||||
|
.Build()).ConfigureAwait(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,6 +107,22 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
await Context.Channel.SendConfirmAsync("🎟 "+ GetText("raffled_user"), $"**{usr.Username}#{usr.Discriminator}**", footer: $"ID: {usr.Id}").ConfigureAwait(false);
|
await Context.Channel.SendConfirmAsync("🎟 "+ GetText("raffled_user"), $"**{usr.Username}#{usr.Discriminator}**", footer: $"ID: {usr.Id}").ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
|
[RequireContext(ContextType.Guild)]
|
||||||
|
public async Task RaffleAny([Remainder] IRole role = null)
|
||||||
|
{
|
||||||
|
role = role ?? Context.Guild.EveryoneRole;
|
||||||
|
|
||||||
|
var members = (await role.GetMembersAsync());
|
||||||
|
var membersArray = members as IUser[] ?? members.ToArray();
|
||||||
|
if (membersArray.Length == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var usr = membersArray[new NadekoRandom().Next(0, membersArray.Length)];
|
||||||
|
await Context.Channel.SendConfirmAsync("🎟 " + GetText("raffled_user"), $"**{usr.Username}#{usr.Discriminator}**", footer: $"ID: {usr.Id}").ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[Priority(1)]
|
[Priority(1)]
|
||||||
public async Task Cash([Remainder] IUser user = null)
|
public async Task Cash([Remainder] IUser user = null)
|
||||||
|
@ -26,7 +26,7 @@ namespace NadekoBot.Modules.Searches
|
|||||||
|
|
||||||
if (novelData == null)
|
if (novelData == null)
|
||||||
{
|
{
|
||||||
await ReplyErrorLocalized("failed_finding_novel").ConfigureAwait(false);
|
await ReplyErrorLocalized("error_finding_novel").ConfigureAwait(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,10 +53,28 @@ namespace NadekoBot.Modules.Searches.Services
|
|||||||
private readonly ConcurrentDictionary<ulong, HashSet<string>> _blacklistedTags = new ConcurrentDictionary<ulong, HashSet<string>>();
|
private readonly ConcurrentDictionary<ulong, HashSet<string>> _blacklistedTags = new ConcurrentDictionary<ulong, HashSet<string>>();
|
||||||
private readonly Timer _t;
|
private readonly Timer _t;
|
||||||
|
|
||||||
|
private readonly SemaphoreSlim _cryptoLock = new SemaphoreSlim(1, 1);
|
||||||
public async Task<CryptoData[]> CryptoData()
|
public async Task<CryptoData[]> CryptoData()
|
||||||
{
|
{
|
||||||
var data = await _cache.Redis.GetDatabase()
|
string data;
|
||||||
.StringGetAsync("crypto_data").ConfigureAwait(false);
|
var r = _cache.Redis.GetDatabase();
|
||||||
|
await _cryptoLock.WaitAsync().ConfigureAwait(false);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
data = await r.StringGetAsync("crypto_data").ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (data == null)
|
||||||
|
{
|
||||||
|
data = await Http.GetStringAsync("https://api.coinmarketcap.com/v1/ticker/")
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
|
await r.StringSetAsync("crypto_data", data, TimeSpan.FromHours(1)).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_cryptoLock.Release();
|
||||||
|
}
|
||||||
|
|
||||||
return JsonConvert.DeserializeObject<CryptoData[]>(data);
|
return JsonConvert.DeserializeObject<CryptoData[]>(data);
|
||||||
}
|
}
|
||||||
@ -121,14 +139,7 @@ namespace NadekoBot.Modules.Searches.Services
|
|||||||
var r = _cache.Redis.GetDatabase();
|
var r = _cache.Redis.GetDatabase();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var data = (string)(await r.StringGetAsync("crypto_data").ConfigureAwait(false));
|
|
||||||
if (data == null)
|
|
||||||
{
|
|
||||||
data = await Http.GetStringAsync("https://api.coinmarketcap.com/v1/ticker/")
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
|
|
||||||
await r.StringSetAsync("crypto_data", data, TimeSpan.FromHours(6)).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -9,5 +9,6 @@ namespace NadekoBot.Core.Services.Database.Repositories
|
|||||||
long GetUserCurrency(ulong userId);
|
long GetUserCurrency(ulong userId);
|
||||||
bool TryUpdateState(ulong userId, long change);
|
bool TryUpdateState(ulong userId, long change);
|
||||||
IEnumerable<Currency> GetTopRichest(int count, int skip);
|
IEnumerable<Currency> GetTopRichest(int count, int skip);
|
||||||
|
void RemoveFromMany(List<long> ids);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,11 @@ namespace NadekoBot.Core.Services.Database.Repositories.Impl
|
|||||||
public long GetUserCurrency(ulong userId) =>
|
public long GetUserCurrency(ulong userId) =>
|
||||||
GetOrCreate(userId).Amount;
|
GetOrCreate(userId).Amount;
|
||||||
|
|
||||||
|
public void RemoveFromMany(List<long> ids)
|
||||||
|
{
|
||||||
|
_set.RemoveRange(_set.Where(x => ids.Contains((long)x.UserId)));
|
||||||
|
}
|
||||||
|
|
||||||
public bool TryUpdateState(ulong userId, long change)
|
public bool TryUpdateState(ulong userId, long change)
|
||||||
{
|
{
|
||||||
var cur = GetOrCreate(userId);
|
var cur = GetOrCreate(userId);
|
||||||
|
@ -6,11 +6,14 @@ namespace NadekoBot.Core.Services.Impl
|
|||||||
public class BotConfigProvider : IBotConfigProvider
|
public class BotConfigProvider : IBotConfigProvider
|
||||||
{
|
{
|
||||||
private readonly DbService _db;
|
private readonly DbService _db;
|
||||||
|
private readonly IDataCache _cache;
|
||||||
|
|
||||||
public BotConfig BotConfig { get; private set; }
|
public BotConfig BotConfig { get; private set; }
|
||||||
|
|
||||||
public BotConfigProvider(DbService db, BotConfig bc)
|
public BotConfigProvider(DbService db, BotConfig bc, IDataCache cache)
|
||||||
{
|
{
|
||||||
_db = db;
|
_db = db;
|
||||||
|
_cache = cache;
|
||||||
BotConfig = bc;
|
BotConfig = bc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ namespace NadekoBot.Core.Services.Impl
|
|||||||
static Localization()
|
static Localization()
|
||||||
{
|
{
|
||||||
_commandData = JsonConvert.DeserializeObject<Dictionary<string, CommandData>>(
|
_commandData = JsonConvert.DeserializeObject<Dictionary<string, CommandData>>(
|
||||||
File.ReadAllText("./data/command_strings.json"));
|
File.ReadAllText("./_strings/cmd/command_strings.json"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Localization() { }
|
private Localization() { }
|
||||||
|
@ -21,7 +21,7 @@ namespace NadekoBot.Core.Services.Impl
|
|||||||
private readonly IBotCredentials _creds;
|
private readonly IBotCredentials _creds;
|
||||||
private readonly DateTime _started;
|
private readonly DateTime _started;
|
||||||
|
|
||||||
public const string BotVersion = "2.4.1";
|
public const string BotVersion = "2.4.3";
|
||||||
|
|
||||||
public string Author => "Kwoth#2560";
|
public string Author => "Kwoth#2560";
|
||||||
public string Library => "Discord.Net";
|
public string Library => "Discord.Net";
|
||||||
|
@ -129,7 +129,7 @@ namespace NadekoBot
|
|||||||
{
|
{
|
||||||
AllGuildConfigs = uow.GuildConfigs.GetAllGuildConfigs(startingGuildIdList).ToImmutableArray();
|
AllGuildConfigs = uow.GuildConfigs.GetAllGuildConfigs(startingGuildIdList).ToImmutableArray();
|
||||||
|
|
||||||
IBotConfigProvider botConfigProvider = new BotConfigProvider(_db, _botConfig);
|
IBotConfigProvider botConfigProvider = new BotConfigProvider(_db, _botConfig, Cache);
|
||||||
|
|
||||||
//initialize Services
|
//initialize Services
|
||||||
Services = new NServiceProvider()
|
Services = new NServiceProvider()
|
||||||
|
@ -1,33 +1,43 @@
|
|||||||
# NadekoBot a Discord bot
|
# Setting up NadekoBot on Docker
|
||||||
Nadeko is written in C# and Discord.Net for more information visit <https://github.com/Kwoth/NadekoBot>
|
Nadeko is written in C# and Discord.Net for more information visit <https://github.com/Kwoth/NadekoBot>
|
||||||
|
|
||||||
## Install Docker
|
#### Prerequisites
|
||||||
Follow the respective guide for your operating system found here [Docker Engine Install Guide](https://docs.docker.com/engine/installation/)
|
- [Docker](https://docs.docker.com/engine/installation/)
|
||||||
|
- [Create Discord Bot application](http://nadekobot.readthedocs.io/en/latest/JSON%20Explanations/#creating-discord-bot-application) and [Invite the bot to your server](http://nadekobot.readthedocs.io/en/latest/JSON%20Explanations/#inviting-your-bot-to-your-server).
|
||||||
|
|
||||||
## Nadeko Setup Guide
|
#### Setting up the container
|
||||||
For this guide we will be using the folder /nadeko as our config root folder.
|
For this guide we will be using the folder /nadeko as our config root folder.
|
||||||
|
```
|
||||||
```bash
|
|
||||||
docker create --name=nadeko -v /nadeko/conf/:/root/nadeko -v /nadeko/data:/opt/NadekoBot/src/NadekoBot/bin/Release/netcoreapp1.1/data uirel/nadeko:1.4
|
docker create --name=nadeko -v /nadeko/conf/:/root/nadeko -v /nadeko/data:/opt/NadekoBot/src/NadekoBot/bin/Release/netcoreapp1.1/data uirel/nadeko:1.4
|
||||||
```
|
```
|
||||||
-If you are coming from a previous version of nadeko (the old docker) make sure your credentials.json has been copied into this directory and is the only thing in this folder.
|
|
||||||
|
|
||||||
-If you are making a fresh install, create your credentials.json from the following guide and place it in the /nadeko folder [Nadeko JSON Guide](http://nadekobot.readthedocs.io/en/latest/JSON%20Explanations/)
|
#### Moving `credentials.json` into the docker container.
|
||||||
|
|
||||||
Next start the docker up with `docker start nadeko; docker logs -f nadeko`
|
- If you are coming from a previous version of nadeko (the old docker) make sure your credentials.json has been copied into this directory and is the only thing in this folder.
|
||||||
|
- If you are making a fresh install, create your credentials.json from the following guide and place it in the /nadeko folder [Nadeko JSON Guide](http://nadekobot.readthedocs.io/en/latest/JSON%20Explanations/).
|
||||||
|
- To copy the the file from your computer to a container:
|
||||||
|
```
|
||||||
|
docker cp /Directory/That/Contains/Your/credentials.json nadeko:/credentials.json
|
||||||
|
```
|
||||||
|
|
||||||
The docker will start and the log file will start scrolling past. Depending on hardware the bot start can take up to 5 minutes on a small DigitalOcean droplet.
|
#### Start up docker
|
||||||
Once the log ends with "NadekoBot | Starting NadekoBot v1.0-rc2" the bot is ready and can be invited to your server. Ctrl+C at this point to stop viewing the logs.
|
```
|
||||||
|
docker start nadeko; docker logs -f nadeko
|
||||||
|
```
|
||||||
|
The docker will start and the log file will start scrolling past. This may take a long time. The bot start can take up to 5 minutes on a small DigitalOcean droplet.
|
||||||
|
Once the log ends with "NadekoBot | Starting NadekoBot vX.X" the bot is ready and can be invited to your server. Ctrl+C at this point if you would like to stop viewing the logs.
|
||||||
|
|
||||||
After a few moments you should be able to invite Nadeko to your server. If you cannot, check the log file for errors.
|
After a few moments, Nadeko should come online on your server. If it doesn't, check the log file for errors.
|
||||||
|
|
||||||
## Monitoring
|
#### Monitoring
|
||||||
|
**To monitor the logs of the container in realtime**
|
||||||
|
```
|
||||||
|
docker logs -f nadeko
|
||||||
|
```
|
||||||
|
|
||||||
* Monitor the logs of the container in realtime `docker logs -f nadeko`.
|
### Updates
|
||||||
|
|
||||||
## Updates
|
#### Manual
|
||||||
|
|
||||||
# Manual
|
|
||||||
Updates are handled by pulling the new layer of the Docker Container which contains a pre compiled update to Nadeko.
|
Updates are handled by pulling the new layer of the Docker Container which contains a pre compiled update to Nadeko.
|
||||||
The following commands are required for the default options
|
The following commands are required for the default options
|
||||||
|
|
||||||
@ -42,17 +52,17 @@ docker create --name=nadeko -v /nadeko/conf/:/root/nadeko -v /nadeko/data:/opt/N
|
|||||||
`docker start nadeko`
|
`docker start nadeko`
|
||||||
|
|
||||||
|
|
||||||
# Automatic Updates
|
#### Automatic
|
||||||
Automatic update are now handled by WatchTower [WatchTower GitHub](https://github.com/CenturyLinkLabs/watchtower)
|
Automatic update are handled by [WatchTower](https://github.com/CenturyLinkLabs/watchtower).
|
||||||
To setup WatchTower to keep Nadeko up-to-date for you with the default settings, use the following command
|
To setup WatchTower to keep Nadeko up-to-date for you with the default settings, use the following command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run -d --name watchtower -v /var/run/docker.sock:/var/run/docker.sock centurylink/watchtower --cleanup nadeko
|
docker run -d --name watchtower -v /var/run/docker.sock:/var/run/docker.sock centurylink/watchtower --cleanup nadeko --interval 300
|
||||||
```
|
```
|
||||||
|
|
||||||
This will check for updates to the docker every 5 minutes and update immediately. Alternatively using the `--interval X` command to change the interval, where X is the amount of time in seconds to wait. e.g 21600 for 6 hours.
|
This will check for updates to the docker every 5 minutes and update immediately. To check in different intervals, change `X`. X is the amount of time, in seconds. (e.g 21600 for 6 hours)
|
||||||
|
|
||||||
|
|
||||||
|
### Additional Info
|
||||||
If you have any issues with the docker setup, please ask in #help channel on our [Discord server](https://discordapp.com/invite/nadekobot) but indicate you are using the docker.
|
If you have any issues with the docker setup, please ask in #help channel on our [Discord server](https://discordapp.com/invite/nadekobot) but indicate you are using the docker.
|
||||||
|
|
||||||
For information about configuring your bot or its functionality, please check the [documentation](http://nadekobot.readthedocs.io/en/latest).
|
For information about configuring your bot or its functionality, please check the [documentation](http://nadekobot.readthedocs.io/en/latest).
|
||||||
|
@ -26,6 +26,8 @@ brew install libsodium
|
|||||||
brew install tmux
|
brew install tmux
|
||||||
brew install python
|
brew install python
|
||||||
brew install youtube-dl
|
brew install youtube-dl
|
||||||
|
brew install redis
|
||||||
|
brew services start redis
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Installing .NET Core SDK
|
#### Installing .NET Core SDK
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
<None Update="data\**\*">
|
<None Update="data\**\*">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Update="_strings\*">
|
<None Update="_strings\**">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Update="libsodium.dll;opus.dll;libsodium.so;libopus.so">
|
<None Update="libsodium.dll;opus.dll;libsodium.so;libopus.so">
|
||||||
|
@ -919,5 +919,9 @@
|
|||||||
"searches_crypto_not_found": "Cryptocurrency with that name was not found.",
|
"searches_crypto_not_found": "Cryptocurrency with that name was not found.",
|
||||||
"searches_did_you_mean": "Did you mean {0}?",
|
"searches_did_you_mean": "Did you mean {0}?",
|
||||||
"administration_self_assign_level_req": "Self assignable role {0} now requires at least server level {1}.",
|
"administration_self_assign_level_req": "Self assignable role {0} now requires at least server level {1}.",
|
||||||
"administration_self_assign_not_level": "That self-assignable role requires at least server level {0}."
|
"administration_self_assign_not_level": "That self-assignable role requires at least server level {0}.",
|
||||||
|
"administration_invalid": "Invalid / Can't be found ({0})",
|
||||||
|
"administration_mass_kill_in_progress": "Mass Banning and Blacklisting of {0} users is in progress...",
|
||||||
|
"administration_mass_kill_completed": "Mass Banning and Blacklisting of {0} users is complete.",
|
||||||
|
"searches_error_finding_novel": "Can't find that novel. Make sure you've typed the exact full name, and that it exists on novelupdates.com"
|
||||||
}
|
}
|
@ -940,12 +940,20 @@
|
|||||||
},
|
},
|
||||||
"raffle": {
|
"raffle": {
|
||||||
"Cmd": "raffle",
|
"Cmd": "raffle",
|
||||||
"Desc": "Prints a name and ID of a random user from the online list from the (optional) role.",
|
"Desc": "Prints a name and ID of a random online user from the server, or from the online user in the specified role.",
|
||||||
"Usage": [
|
"Usage": [
|
||||||
"{0}raffle",
|
"{0}raffle",
|
||||||
"{0}raffle RoleName"
|
"{0}raffle RoleName"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"raffleany": {
|
||||||
|
"Cmd": "raffleany",
|
||||||
|
"Desc": "Prints a name and ID of a random user from the server, or from the specified role.",
|
||||||
|
"Usage": [
|
||||||
|
"{0}raffleany",
|
||||||
|
"{0}raffleany RoleName"
|
||||||
|
]
|
||||||
|
},
|
||||||
"give": {
|
"give": {
|
||||||
"Cmd": "give",
|
"Cmd": "give",
|
||||||
"Desc": "Give someone a certain amount of currency.",
|
"Desc": "Give someone a certain amount of currency.",
|
||||||
@ -3105,5 +3113,12 @@
|
|||||||
"usage": [
|
"usage": [
|
||||||
"{0}rlr 5 SomeRole"
|
"{0}rlr 5 SomeRole"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"masskill": {
|
||||||
|
"cmd": "masskill",
|
||||||
|
"desc": "Specify a new-line separated list of `userid reason`. You can use Username#discrim instead of UserId. Specified users will be banned from the current server, blacklisted from the bot, and have all of their flowers taken away.",
|
||||||
|
"usage": [
|
||||||
|
"{0}masskill BadPerson#1234 Toxic person"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user