Merged with dev

This commit is contained in:
Master Kwoth 2017-05-17 14:28:50 +02:00
commit 2344624838
16 changed files with 153 additions and 106 deletions

View File

@ -26,7 +26,7 @@ Commands and aliases | Description | Usage
`.renamerole` `.renr` | Renames a role. The role you are renaming must be lower than bot's highest role. **Requires ManageRoles server permission.** | `.renr "First role" SecondRole`
`.removeallroles` `.rar` | Removes all roles from a mentioned user. **Requires ManageRoles server permission.** | `.rar @User`
`.createrole` `.cr` | Creates a role with a given name. **Requires ManageRoles server permission.** | `.cr Awesome Role`
`.rolehoist` `.rh` | Toggles if this role is displayed in the sidebar or not **Requires ManageRoles server permission.** | `.rh Guests true` or `.rh "Space Wizards" true
`.rolehoist` `.rh` | Toggles if this role is displayed in the sidebar or not **Requires ManageRoles server permission.** | `.rh Guests true` or `.rh "Space Wizards" true`
`.rolecolor` `.rc` | Set a role's color to the hex or 0-255 rgb color value provided. **Requires ManageRoles server permission.** | `.rc Admin 255 200 100` or `.rc Admin ffba55`
`.deafen` `.deaf` | Deafens mentioned user or users. **Requires DeafenMembers server permission.** | `.deaf "@Someguy"` or `.deaf "@Someguy" "@Someguy"`
`.undeafen` `.undef` | Undeafens mentioned user or users. **Requires DeafenMembers server permission.** | `.undef "@Someguy"` or `.undef "@Someguy" "@Someguy"`
@ -73,7 +73,7 @@ Commands and aliases | Description | Usage
`.lsar` | Lists all self-assignable roles. | `.lsar`
`.togglexclsar` `.tesar` | Toggles whether the self-assigned roles are exclusive. (So that any person can have only one of the self assignable roles) **Requires ManageRoles server permission.** | `.tesar`
`.iam` | Adds a role to you that you choose. Role must be on a list of self-assignable roles. | `.iam Gamer`
`.iamnot` `.iamn` | Removes a role to you that you choose. Role must be on a list of self-assignable roles. | `.iamn Gamer`
`.iamnot` `.iamn` | Removes a specified role from you. Role must be on a list of self-assignable roles. | `.iamn Gamer`
`.scadd` | Adds a command to the list of commands which will be executed automatically in the current channel, in the order they were added in, by the bot when it startups up. **Bot owner only** | `.scadd .stats`
`.sclist` | Lists all startup commands in the order they will be executed in. **Bot owner only** | `.sclist`
`.wait` | Used only as a startup command. Waits a certain number of miliseconds before continuing the execution of the following startup commands. **Bot owner only** | `.wait 3000`
@ -94,11 +94,11 @@ Commands and aliases | Description | Usage
`.reloadimages` | Reloads images bot is using. Safe to use even when bot is being used heavily. **Bot owner only** | `.reloadimages`
`.greetdel` `.grdel` | Sets the time it takes (in seconds) for greet messages to be auto-deleted. Set it to 0 to disable automatic deletion. **Requires ManageServer server permission.** | `.greetdel 0` or `.greetdel 30`
`.greet` | Toggles anouncements on the current channel when someone joins the server. **Requires ManageServer server permission.** | `.greet`
`.greetmsg` | Sets a new join announcement message which will be shown in the server's channel. Type `%user%` if you want to mention the new member. Using it with no message will show the current greet message. You can use embed json from <http://nadekobot.xyz/embedbuilder/> instead of a regular text, if you want the message to be embedded. **Requires ManageServer server permission.** | `.greetmsg Welcome, %user%.`
`.greetmsg` | Sets a new join announcement message which will be shown in the server's channel. Type `%user%` if you want to mention the new member. Using it with no message will show the current greet message. You can use embed json from <http://nadekobot.me/embedbuilder/> instead of a regular text, if you want the message to be embedded. **Requires ManageServer server permission.** | `.greetmsg Welcome, %user%.`
`.greetdm` | Toggles whether the greet messages will be sent in a DM (This is separate from greet - you can have both, any or neither enabled). **Requires ManageServer server permission.** | `.greetdm`
`.greetdmmsg` | Sets a new join announcement message which will be sent to the user who joined. Type `%user%` if you want to mention the new member. Using it with no message will show the current DM greet message. You can use embed json from <http://nadekobot.xyz/embedbuilder/> instead of a regular text, if you want the message to be embedded. **Requires ManageServer server permission.** | `.greetdmmsg Welcome to the server, %user%`.
`.greetdmmsg` | Sets a new join announcement message which will be sent to the user who joined. Type `%user%` if you want to mention the new member. Using it with no message will show the current DM greet message. You can use embed json from <http://nadekobot.me/embedbuilder/> instead of a regular text, if you want the message to be embedded. **Requires ManageServer server permission.** | `.greetdmmsg Welcome to the server, %user%`.
`.bye` | Toggles anouncements on the current channel when someone leaves the server. **Requires ManageServer server permission.** | `.bye`
`.byemsg` | Sets a new leave announcement message. Type `%user%` if you want to show the name the user who left. Type `%id%` to show id. Using this command with no message will show the current bye message. You can use embed json from <http://nadekobot.xyz/embedbuilder/> instead of a regular text, if you want the message to be embedded. **Requires ManageServer server permission.** | `.byemsg %user% has left.`
`.byemsg` | Sets a new leave announcement message. Type `%user%` if you want to show the name the user who left. Type `%id%` to show id. Using this command with no message will show the current bye message. You can use embed json from <http://nadekobot.me/embedbuilder/> instead of a regular text, if you want the message to be embedded. **Requires ManageServer server permission.** | `.byemsg %user% has left.`
`.byedel` | Sets the time it takes (in seconds) for bye messages to be auto-deleted. Set it to `0` to disable automatic deletion. **Requires ManageServer server permission.** | `.byedel 0` or `.byedel 30`
`.warn` | Warns a user. **Requires BanMembers server permission.** | `.warn @b1nzy Very rude person`
`.warnlog` | See a list of warnings of a certain user. **Requires BanMembers server permission.** | `.warnlog @b1nzy`
@ -170,7 +170,7 @@ Commands and aliases | Description | Usage
`$buy` | Buys an item from the shop on a given index. If buying items, make sure that the bot can DM you. | `$buy 2`
`$shopadd` | Adds an item to the shop by specifying type price and name. Available types are role and list. **Requires Administrator server permission.** | `$shopadd role 1000 Rich`
`$shoplistadd` | Adds an item to the list of items for sale in the shop entry given the index. You usually want to run this command in the secret channel, so that the unique items are not leaked. **Requires Administrator server permission.** | `$shoplistadd 1 Uni-que-Steam-Key`
`$shoprem` `$shoprm` | Removes an item from the shop by its color. **Requires Administrator server permission.** | `$shoprm 1`
`$shoprem` `$shoprm` | Removes an item from the shop by its ID. **Requires Administrator server permission.** | `$shoprm 1`
`$slotstats` | Shows the total stats of the slot command for this bot's session. **Bot owner only** | `$slotstats`
`$slottest` | Tests to see how much slots payout for X number of plays. **Bot owner only** | `$slottest 1000`
`$slot` | Play Nadeko slots. Max bet is 9999. 1.5 second cooldown per user. | `$slot 5`
@ -311,8 +311,8 @@ Commands and aliases | Description | Usage
`;fw` | Adds or removes (if it exists) a word from the list of filtered words. Use`;sfw` or `;cfw` to toggle filtering. | `;fw poop`
`;lstfilterwords` `;lfw` | Shows a list of filtered words. | `;lfw`
`;listglobalperms` `;lgp` | Lists global permissions set by the bot owner. **Bot owner only** | `;lgp`
`;globalmodule` `;gmod` | Enable or disable a module from use on all servers. **Bot owner only** | `;gmod nsfw disable`
`;globalcommand` `;gcmd` | Enables or disables a command from use on all servers. **Bot owner only** | `;gcmd `
`;globalmodule` `;gmod` | Toggles whether a module can be used on any server. **Bot owner only** | `;gmod nsfw`
`;globalcommand` `;gcmd` | Toggles whether a command can be used on any server. **Bot owner only** | `;gcmd .stats`
###### [Back to ToC](#table-of-contents)
@ -362,7 +362,7 @@ Commands and aliases | Description | Usage
`~manga` `~mang` `~mq` | Queries anilist for a manga and shows the first result. | `~mq Shingeki no kyojin`
`~yomama` `~ym` | Shows a random joke from <http://api.yomomma.info/> | `~ym`
`~randjoke` `~rj` | Shows a random joke from <http://tambal.azurewebsites.net/joke/random> | `~rj`
`~chucknorris` `~cn` | Shows a random Chuck Norris joke from <http://tambal.azurewebsites.net/joke/random> | `~cn`
`~chucknorris` `~cn` | Shows a random Chuck Norris joke from <http://api.icndb.com/jokes/random/> | `~cn`
`~wowjoke` | Get one of Kwoth's penultimate WoW jokes. | `~wowjoke`
`~magicitem` `~mi` | Shows a random magic item from <https://1d4chan.org/wiki/List_of_/tg/%27s_magic_items> | `~mi`
`~memelist` | Pulls a list of memes you can use with `~memegen` from http://memegen.link/templates/ | `~memelist`

View File

@ -41,7 +41,7 @@ namespace NadekoBot.Modules.Administration
var channel = msg.Channel as SocketTextChannel;
if (channel == null)
return;
if (deleteMessagesOnCommand.Contains(channel.Guild.Id) && cmd.Name != "prune")
if (deleteMessagesOnCommand.Contains(channel.Guild.Id) && cmd.Name != "prune" && cmd.Name != "pick")
await msg.DeleteAsync().ConfigureAwait(false);
}
catch (Exception ex)
@ -118,7 +118,7 @@ namespace NadekoBot.Modules.Administration
{
var guser = (IGuildUser)Context.User;
var maxRole = guser.GetRoles().Max(x => x.Position);
if (maxRole < role.Position || maxRole <= usr.GetRoles().Max(x => x.Position))
if ((Context.User.Id != Context.Guild.OwnerId) && (maxRole < role.Position || maxRole <= usr.GetRoles().Max(x => x.Position)))
return;
try
{
@ -378,12 +378,14 @@ namespace NadekoBot.Modules.Administration
{
var user = await Context.Guild.GetCurrentUserAsync().ConfigureAwait(false);
var enumerable = (await Context.Channel.GetMessagesAsync().Flatten()).AsEnumerable();
enumerable = enumerable.Where(x => x.Author.Id == user.Id);
var enumerable = (await Context.Channel.GetMessagesAsync().Flatten())
.Where(x => x.Author.Id == user.Id && DateTime.Now - x.CreatedAt < twoWeeks);
await Context.Channel.DeleteMessagesAsync(enumerable).ConfigureAwait(false);
Context.Message.DeleteAfter(3);
}
private TimeSpan twoWeeks => TimeSpan.FromDays(14);
// prune x
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
@ -396,7 +398,8 @@ namespace NadekoBot.Modules.Administration
return;
await Context.Message.DeleteAsync().ConfigureAwait(false);
int limit = (count < 100) ? count + 1 : 100;
var enumerable = (await Context.Channel.GetMessagesAsync(limit: limit).Flatten().ConfigureAwait(false));
var enumerable = (await Context.Channel.GetMessagesAsync(limit: limit).Flatten().ConfigureAwait(false))
.Where(x => DateTime.Now - x.CreatedAt < twoWeeks);
if (enumerable.FirstOrDefault()?.Id == Context.Message.Id)
enumerable = enumerable.Skip(1).ToArray();
else
@ -419,7 +422,8 @@ namespace NadekoBot.Modules.Administration
count += 1;
int limit = (count < 100) ? count : 100;
var enumerable = (await Context.Channel.GetMessagesAsync(limit: limit).Flatten()).Where(m => m.Author == user);
var enumerable = (await Context.Channel.GetMessagesAsync(limit: limit).Flatten())
.Where(m => m.Author == user && DateTime.Now - m.CreatedAt < twoWeeks);
await Context.Channel.DeleteMessagesAsync(enumerable).ConfigureAwait(false);
Context.Message.DeleteAfter(3);
@ -434,7 +438,9 @@ namespace NadekoBot.Modules.Administration
foreach (var role in roles)
{
send += $"\n**{role.Name}**\n";
send += string.Join(", ", (await Context.Guild.GetUsersAsync()).Where(u => u.GetRoles().Contains(role)).Take(50).Select(u => u.Mention));
send += string.Join(", ", (await Context.Guild.GetUsersAsync())
.Where(u => u.GetRoles().Contains(role))
.Take(50).Select(u => u.Mention));
}
while (send.Length > 2000)

View File

@ -10,6 +10,8 @@ using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading.Tasks;
using System.Threading;
using System.Collections.Generic;
namespace NadekoBot.Modules.Administration
{
@ -35,30 +37,51 @@ namespace NadekoBot.Modules.Administration
= new ConcurrentDictionary<ulong, UserSpamStats>();
}
public class UserSpamStats
public class UserSpamStats : IDisposable
{
public int Count { get; set; }
public int Count => timers.Count;
public string LastMessage { get; set; }
public UserSpamStats(string msg)
{
Count = 1;
LastMessage = msg.ToUpperInvariant();
}
private ConcurrentQueue<Timer> timers { get; }
public UserSpamStats(IUserMessage msg)
{
LastMessage = msg.Content.ToUpperInvariant();
timers = new ConcurrentQueue<Timer>();
ApplyNextMessage(msg);
}
private readonly object applyLock = new object();
public void ApplyNextMessage(IUserMessage message)
{
var upperMsg = message.Content.ToUpperInvariant();
if (upperMsg != LastMessage || (string.IsNullOrWhiteSpace(upperMsg) && message.Attachments.Any()))
{
LastMessage = upperMsg;
Count = 0;
}
else
{
Count++;
lock(applyLock){
var upperMsg = message.Content.ToUpperInvariant();
if (upperMsg != LastMessage || (string.IsNullOrWhiteSpace(upperMsg) && message.Attachments.Any()))
{
LastMessage = upperMsg;
//todo c#7
Timer old;
while(timers.TryDequeue(out old))
old.Change(Timeout.Infinite, Timeout.Infinite);
}
var t = new Timer((_) => {
//todo c#7
Timer __;
if(timers.TryDequeue(out __))
__.Change(Timeout.Infinite, Timeout.Infinite);
}, null, TimeSpan.FromMinutes(30), TimeSpan.FromMinutes(30));
timers.Enqueue(t);
}
}
public void Dispose()
{
//todo c#7
Timer old;
while(timers.TryDequeue(out old))
old.Change(Timeout.Infinite, Timeout.Infinite);
}
}
[Group]
@ -112,7 +135,7 @@ namespace NadekoBot.Modules.Administration
}))
return;
var stats = spamSettings.UserStats.AddOrUpdate(msg.Author.Id, new UserSpamStats(msg.Content),
var stats = spamSettings.UserStats.AddOrUpdate(msg.Author.Id, (id) => new UserSpamStats(msg),
(id, old) =>
{
old.ApplyNextMessage(msg); return old;
@ -122,6 +145,7 @@ namespace NadekoBot.Modules.Administration
{
if (spamSettings.UserStats.TryRemove(msg.Author.Id, out stats))
{
stats.Dispose();
await PunishUsers(spamSettings.AntiSpamSettings.Action, ProtectionType.Spamming, (IGuildUser)msg.Author)
.ConfigureAwait(false);
}
@ -317,6 +341,7 @@ namespace NadekoBot.Modules.Administration
AntiSpamStats throwaway;
if (_antiSpamGuilds.TryRemove(Context.Guild.Id, out throwaway))
{
throwaway.UserStats.ForEach(x => x.Value.Dispose());
using (var uow = DbHandler.UnitOfWork())
{
var gc = uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.AntiSpamSetting)

View File

@ -108,7 +108,6 @@ namespace NadekoBot.Modules.Administration
using (var uow = DbHandler.UnitOfWork())
{
var roleModels = uow.SelfAssignedRoles.GetFromGuild(Context.Guild.Id).ToList();
roleCnt = roleModels.Count;
msg.AppendLine();
foreach (var roleModel in roleModels)
@ -116,11 +115,13 @@ namespace NadekoBot.Modules.Administration
var role = Context.Guild.Roles.FirstOrDefault(r => r.Id == roleModel.RoleId);
if (role == null)
{
toRemove.Add(roleModel);
uow.SelfAssignedRoles.Remove(roleModel);
}
else
{
msg.Append($"**{role.Name}**, ");
roleCnt++;
}
}
foreach (var role in toRemove)

View File

@ -73,7 +73,7 @@ namespace NadekoBot.Modules.Administration
await guild.AddBanAsync(user).ConfigureAwait(false);
break;
case PunishmentAction.Softban:
await guild.AddBanAsync(user).ConfigureAwait(false);
await guild.AddBanAsync(user, 7).ConfigureAwait(false);
try
{
await guild.RemoveBanAsync(user).ConfigureAwait(false);
@ -214,25 +214,15 @@ namespace NadekoBot.Modules.Administration
using (var uow = DbHandler.UnitOfWork())
{
var ps = uow.GuildConfigs.For(Context.Guild.Id).WarnPunishments;
var p = ps.FirstOrDefault(x => x.Count == number);
var ps = uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.WarnPunishments)).WarnPunishments;
ps.RemoveAll(x => x.Count == number);
if (p == null)
ps.Add(new WarningPunishment()
{
ps.Add(new WarningPunishment()
{
Count = number,
Punishment = punish,
Time = time,
});
}
else
{
p.Count = number;
p.Punishment = punish;
p.Time = time;
uow._context.Update(p);
}
Count = number,
Punishment = punish,
Time = time,
});
uow.Complete();
}

View File

@ -173,6 +173,8 @@ namespace NadekoBot.Modules.Gambling
amount + CurrencySign);
if (w.Affinity?.UserId == Context.User.Id)
msg += "\n" + GetText("waifu_fulfilled", target, w.Price + CurrencySign);
else
msg = " " + msg;
await Context.Channel.SendConfirmAsync(Context.User.Mention + msg).ConfigureAwait(false);
}
@ -188,9 +190,15 @@ namespace NadekoBot.Modules.Gambling
private static readonly TimeSpan _divorceLimit = TimeSpan.FromHours(6);
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task Divorce([Remainder]IGuildUser target)
[Priority(1)]
public Task Divorce([Remainder]IGuildUser target) => Divorce(target.Id);
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[Priority(0)]
public async Task Divorce([Remainder]ulong targetId)
{
if (target.Id == Context.User.Id)
if (targetId == Context.User.Id)
return;
DivorceResult result;
@ -199,7 +207,7 @@ namespace NadekoBot.Modules.Gambling
WaifuInfo w = null;
using (var uow = DbHandler.UnitOfWork())
{
w = uow.Waifus.ByWaifuUserId(target.Id);
w = uow.Waifus.ByWaifuUserId(targetId);
var now = DateTime.UtcNow;
if (w?.Claimer == null || w.Claimer.UserId != Context.User.Id)
result = DivorceResult.NotYourWife;

View File

@ -15,7 +15,7 @@ namespace NadekoBot.Modules.Games.Hangman
{
public class HangmanTermPool
{
const string termsPath = "data/hangman2.json";
const string termsPath = "data/hangman3.json";
public static IReadOnlyDictionary<string, HangmanObject[]> data { get; }
static HangmanTermPool()
{

View File

@ -82,9 +82,9 @@ namespace NadekoBot.Modules.Games
var prefix = NadekoBot.ModulePrefixes[typeof(Games).Name];
var toSend = dropAmount == 1
? GetLocalText(channel, "curgen_sn", NadekoBot.BotConfig.CurrencySign)
+ GetLocalText(channel, "pick_sn", prefix)
+ " " + GetLocalText(channel, "pick_sn", prefix)
: GetLocalText(channel, "curgen_pl", dropAmount, NadekoBot.BotConfig.CurrencySign)
+ GetLocalText(channel, "pick_pl", prefix);
+ " " + GetLocalText(channel, "pick_pl", prefix);
var file = GetRandomCurrencyImage();
using (var fileStream = file.Value.ToStream())
{

View File

@ -26,7 +26,11 @@ namespace NadekoBot.Modules.Music.Classes
{
public SongInfo SongInfo { get; }
public MusicPlayer MusicPlayer { get; set; }
public string QueuerName { get; set; }
private string _queuerName;
public string QueuerName { get{
return Discord.Format.Sanitize(_queuerName);
} set { _queuerName = value; } }
public TimeSpan TotalTime { get; set; } = TimeSpan.Zero;
public TimeSpan CurrentTime => TimeSpan.FromSeconds(BytesSent / (float)_frameBytes / (1000 / (float)_milliseconds));

View File

@ -65,6 +65,9 @@ namespace NadekoBot.Modules.Permissions
private async Task Blacklist(AddRemove action, ulong id, BlacklistType type)
{
if(action == AddRemove.Add && NadekoBot.Credentials.OwnerIds.Contains(id))
return;
using (var uow = DbHandler.UnitOfWork())
{
if (action == AddRemove.Add)

View File

@ -190,7 +190,7 @@ namespace NadekoBot.Modules.Permissions
{
var config = uow.GuildConfigs.For(channel.Guild.Id, set => set.Include(gc => gc.FilteredWords));
removed = config.FilteredWords.RemoveWhere(fw => fw.Word == word);
removed = config.FilteredWords.RemoveWhere(fw => fw.Word.Trim().ToLowerInvariant() == word);
if (removed == 0)
config.FilteredWords.Add(new Services.Database.Models.FilteredWord() { Word = word });

View File

@ -126,7 +126,7 @@ namespace NadekoBot.Modules.Utility
}
await Context.Channel.EmbedAsync(new EmbedBuilder()
.WithTitle(GetText("activity_page", page))
.WithTitle(GetText("activity_page", page + 1))
.WithOkColor()
.WithFooter(efb => efb.WithText(GetText("activity_users_total",
NadekoBot.CommandHandler.UserMessagesSent.Count)))

View File

@ -123,8 +123,19 @@ namespace NadekoBot.Modules.Utility
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.ManageMessages)]
[Priority(0)]
public Task Remind(ITextChannel channel, string timeStr, [Remainder] string message) =>
RemindInternal(channel.Id, false, timeStr, message);
public async Task Remind(ITextChannel channel, string timeStr, [Remainder] string message)
{
var perms = ((IGuildUser)Context.User).GetPermissions((ITextChannel)channel);
if (!perms.SendMessages || !perms.ReadMessages)
{
await ReplyErrorLocalized("cant_read_or_send").ConfigureAwait(false);
return;
}
else
{
var _ = RemindInternal(channel.Id, false, timeStr, message).ConfigureAwait(false);
}
}
public async Task RemindInternal(ulong targetId, bool isPrivate, string timeStr, [Remainder] string message)
{

View File

@ -503,7 +503,6 @@ namespace NadekoBot.Modules.Utility
await JsonConvert.SerializeObject(grouping, Formatting.Indented).ToStream().ConfigureAwait(false), title, title).ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task Ping()
{
var sw = Stopwatch.StartNew();

View File

@ -418,7 +418,7 @@
<value>iamnot iamn</value>
</data>
<data name="iamnot_desc" xml:space="preserve">
<value>Removes a role to you that you choose. Role must be on a list of self-assignable roles.</value>
<value>Removes a specified role from you. Role must be on a list of self-assignable roles.</value>
</data>
<data name="iamnot_usage" xml:space="preserve">
<value>`{0}iamn Gamer`</value>
@ -2038,7 +2038,7 @@
<value>chucknorris cn</value>
</data>
<data name="chucknorris_desc" xml:space="preserve">
<value>Shows a random Chuck Norris joke from &lt;http://tambal.azurewebsites.net/joke/random&gt;</value>
<value>Shows a random Chuck Norris joke from &lt;http://api.icndb.com/jokes/random/&gt;</value>
</data>
<data name="chucknorris_usage" xml:space="preserve">
<value>`{0}cn`</value>
@ -3388,7 +3388,7 @@
<value>shoprem shoprm</value>
</data>
<data name="shopremove_desc" xml:space="preserve">
<value>Removes an item from the shop by its color.</value>
<value>Removes an item from the shop by its ID.</value>
</data>
<data name="shop_cmd" xml:space="preserve">
<value>shop</value>
@ -3406,7 +3406,7 @@
<value>Toggles whether this role is displayed in the sidebar or not.</value>
</data>
<data name="rolehoist_usage" xml:space="preserve">
<value>`{0}rh Guests` or `{0}rh "Space Wizards"</value>
<value>`{0}rh Guests` or `{0}rh "Space Wizards"`</value>
</data>
<data name="buy_cmd" xml:space="preserve">
<value>buy</value>
@ -3442,19 +3442,19 @@
<value>globalcommand gcmd</value>
</data>
<data name="gcmd_desc" xml:space="preserve">
<value>Enables or disables a command from use on all servers.</value>
<value>Toggles whether a command can be used on any server.</value>
</data>
<data name="gcmd_usage" xml:space="preserve">
<value>`{0}gcmd `</value>
<value>`{0}gcmd .stats`</value>
</data>
<data name="gmod_cmd" xml:space="preserve">
<value>globalmodule gmod</value>
</data>
<data name="gmod_desc" xml:space="preserve">
<value>Enable or disable a module from use on all servers.</value>
<value>Toggles whether a module can be used on any server.</value>
</data>
<data name="gmod_usage" xml:space="preserve">
<value>`{0}gmod nsfw disable`</value>
<value>`{0}gmod nsfw`</value>
</data>
<data name="lgp_cmd" xml:space="preserve">
<value>listglobalperms lgp</value>

View File

@ -772,7 +772,7 @@
},
{
"Word": "Antigua and Barbuda",
"ImageUrl": "https://www.randomlists.com/img/national-flags/antigua-and-barbuda.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/antigua_and_barbuda.gif"
},
{
"Word": "Argentina",
@ -836,7 +836,7 @@
},
{
"Word": "Bosnia and Herzegovina",
"ImageUrl": "https://www.randomlists.com/img/national-flags/bosnia-and-herzegovina.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/bosnia_and_herzegovina.gif"
},
{
"Word": "Botswana",
@ -856,7 +856,7 @@
},
{
"Word": "Burkina Faso",
"ImageUrl": "https://www.randomlists.com/img/national-flags/burkina-faso.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/burkina_faso.gif"
},
{
"Word": "Burma",
@ -880,11 +880,11 @@
},
{
"Word": "Cape Verde",
"ImageUrl": "https://www.randomlists.com/img/national-flags/cape-verde.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/cape_verde.gif"
},
{
"Word": "Central African Republic",
"ImageUrl": "https://www.randomlists.com/img/national-flags/central-african-republic.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/central_african_republic.gif"
},
{
"Word": "Chad",
@ -912,7 +912,7 @@
},
{
"Word": "Costa Rica",
"ImageUrl": "https://www.randomlists.com/img/national-flags/costa-rica.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/costa_rica.gif"
},
{
"Word": "Croatia",
@ -928,7 +928,7 @@
},
{
"Word": "Czech Republic",
"ImageUrl": "https://www.randomlists.com/img/national-flags/czech-republic.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/czech_republic.gif"
},
{
"Word": "Denmark",
@ -944,11 +944,11 @@
},
{
"Word": "Dominican Republic",
"ImageUrl": "https://www.randomlists.com/img/national-flags/dominican-republic.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/dominican_republic.gif"
},
{
"Word": "East Timor",
"ImageUrl": "https://www.randomlists.com/img/national-flags/east-timor.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/east_timor.gif"
},
{
"Word": "Ecuador",
@ -960,7 +960,7 @@
},
{
"Word": "El Salvador",
"ImageUrl": "https://www.randomlists.com/img/national-flags/el-salvador.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/el_salvador.gif"
},
{
"Word": "England",
@ -968,7 +968,7 @@
},
{
"Word": "Equatorial Guinea",
"ImageUrl": "https://www.randomlists.com/img/national-flags/equatorial-guinea.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/equatorial_guinea.gif"
},
{
"Word": "Eritrea",
@ -1032,7 +1032,7 @@
},
{
"Word": "Guinea-Bissau",
"ImageUrl": "https://www.randomlists.com/img/national-flags/guinea-bissau.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/guinea_bissau.gif"
},
{
"Word": "Guyana",
@ -1048,7 +1048,7 @@
},
{
"Word": "Hong Kong",
"ImageUrl": "https://www.randomlists.com/img/national-flags/hong-kong.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/hong_kong.gif"
},
{
"Word": "Hungary",
@ -1080,7 +1080,7 @@
},
{
"Word": "Isle of Man",
"ImageUrl": "https://www.randomlists.com/img/national-flags/isle-of-man.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/isle_of_man.gif"
},
{
"Word": "Israel",
@ -1116,11 +1116,11 @@
},
{
"Word": "North Korea",
"ImageUrl": "https://www.randomlists.com/img/national-flags/korea-north.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/korea_north.gif"
},
{
"Word": "South Korea",
"ImageUrl": "https://www.randomlists.com/img/national-flags/korea-south.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/korea_south.gif"
},
{
"Word": "Kosovo",
@ -1204,7 +1204,7 @@
},
{
"Word": "Marshall Islands",
"ImageUrl": "https://www.randomlists.com/img/national-flags/marshall-islands.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/marshall_islands.gif"
},
{
"Word": "Mauritania",
@ -1264,7 +1264,7 @@
},
{
"Word": "New Zealand",
"ImageUrl": "https://www.randomlists.com/img/national-flags/new-zealand.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/new_zealand.gif"
},
{
"Word": "Nicaragua",
@ -1300,7 +1300,7 @@
},
{
"Word": "Papua New Guinea",
"ImageUrl": "https://www.randomlists.com/img/national-flags/papua-new-guinea.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/papua_new_guinea.gif"
},
{
"Word": "Paraguay",
@ -1324,7 +1324,7 @@
},
{
"Word": "Puerto Rico",
"ImageUrl": "https://www.randomlists.com/img/national-flags/puerto-rico.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/puerto_rico.gif"
},
{
"Word": "Qatar",
@ -1344,15 +1344,15 @@
},
{
"Word": "Saint Kitts and Nevis",
"ImageUrl": "https://www.randomlists.com/img/national-flags/saint-kitts-and-nevis.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/saint_kitts_and_nevis.gif"
},
{
"Word": "Saint Lucia",
"ImageUrl": "https://www.randomlists.com/img/national-flags/saint-lucia.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/saint_lucia.gif"
},
{
"Word": "Saint Vincent and the Grenadines",
"ImageUrl": "https://www.randomlists.com/img/national-flags/saint-vincent-and-the-grenadines.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/saint_vincent_and_the_grenadines.gif"
},
{
"Word": "Samoa",
@ -1360,11 +1360,11 @@
},
{
"Word": "San Marino",
"ImageUrl": "https://www.randomlists.com/img/national-flags/san-marino.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/san_marino.gif"
},
{
"Word": "Saudi Arabia",
"ImageUrl": "https://www.randomlists.com/img/national-flags/saudi-arabia.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/saudi_arabia.gif"
},
{
"Word": "Scotland",
@ -1384,7 +1384,7 @@
},
{
"Word": "Sierra Leone",
"ImageUrl": "https://www.randomlists.com/img/national-flags/sierra-leone.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/sierra_leone.gif"
},
{
"Word": "Singapore",
@ -1400,7 +1400,7 @@
},
{
"Word": "Solomon Islands",
"ImageUrl": "https://www.randomlists.com/img/national-flags/solomon-islands.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/solomon_islands.gif"
},
{
"Word": "Somalia",
@ -1408,7 +1408,7 @@
},
{
"Word": "South Africa",
"ImageUrl": "https://www.randomlists.com/img/national-flags/south-africa.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/south_africa.gif"
},
{
"Word": "Spain",
@ -1416,7 +1416,7 @@
},
{
"Word": "Sri Lanka",
"ImageUrl": "https://www.randomlists.com/img/national-flags/sri-lanka.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/sri_lanka.gif"
},
{
"Word": "Sudan",
@ -1468,7 +1468,7 @@
},
{
"Word": "Trinidad and Tobago",
"ImageUrl": "https://www.randomlists.com/img/national-flags/trinidad-and-tobago.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/trinidad_and_tobago.gif"
},
{
"Word": "Tunisia",
@ -1496,15 +1496,15 @@
},
{
"Word": "United Arab Emirates",
"ImageUrl": "https://www.randomlists.com/img/national-flags/united-arab-emirates.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/united_arab_emirates.gif"
},
{
"Word": "United Kingdom",
"ImageUrl": "https://www.randomlists.com/img/national-flags/united-kingdom.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/united_kingdom.gif"
},
{
"Word": "United States of America",
"ImageUrl": "https://www.randomlists.com/img/national-flags/united-states-of-america.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/united_states_of_america.gif"
},
{
"Word": "Uruguay",
@ -1524,7 +1524,7 @@
},
{
"Word": "Vatican City",
"ImageUrl": "https://www.randomlists.com/img/national-flags/vatican-city.gif"
"ImageUrl": "https://www.randomlists.com/img/national-flags/vatican_city.gif"
},
{
"Word": "Venezuela",