Merge remote-tracking branch 'refs/remotes/Kwoth/dev' into dev
This commit is contained in:
commit
6013def035
@ -7,6 +7,7 @@ using NadekoBot.Services.Database.Models;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -23,9 +24,11 @@ namespace NadekoBot.Modules.Administration
|
||||
|
||||
static AutoAssignRoleCommands()
|
||||
{
|
||||
_log = LogManager.GetCurrentClassLogger();
|
||||
var sw = Stopwatch.StartNew();
|
||||
|
||||
AutoAssignedRoles = new ConcurrentDictionary<ulong, ulong>(NadekoBot.AllGuildConfigs.Where(x => x.AutoAssignRoleId != 0)
|
||||
.ToDictionary(k => k.GuildId, v => v.AutoAssignRoleId));
|
||||
_log = LogManager.GetCurrentClassLogger();
|
||||
NadekoBot.Client.UserJoined += async (user) =>
|
||||
{
|
||||
try
|
||||
@ -43,6 +46,9 @@ namespace NadekoBot.Modules.Administration
|
||||
}
|
||||
catch (Exception ex) { _log.Warn(ex); }
|
||||
};
|
||||
|
||||
sw.Stop();
|
||||
_log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s");
|
||||
}
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
|
@ -3,7 +3,9 @@ using Discord.Commands;
|
||||
using NadekoBot.Attributes;
|
||||
using NadekoBot.Extensions;
|
||||
using NadekoBot.Services;
|
||||
using NLog;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -17,8 +19,12 @@ namespace NadekoBot.Modules.Administration
|
||||
private static bool ForwardDMs { get; set; }
|
||||
private static bool ForwardDMsToAllOwners { get; set; }
|
||||
|
||||
private static readonly Logger _log;
|
||||
|
||||
static DMForwardCommands()
|
||||
{
|
||||
_log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
using (var uow = DbHandler.UnitOfWork())
|
||||
{
|
||||
var config = uow.BotConfig.GetOrCreate();
|
||||
|
@ -11,6 +11,7 @@ using NLog;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@ -37,6 +38,7 @@ namespace NadekoBot.Modules.Administration
|
||||
{
|
||||
_client = NadekoBot.Client;
|
||||
_log = LogManager.GetCurrentClassLogger();
|
||||
var sw = Stopwatch.StartNew();
|
||||
|
||||
using (var uow = DbHandler.UnitOfWork())
|
||||
{
|
||||
@ -62,6 +64,9 @@ namespace NadekoBot.Modules.Administration
|
||||
_log.Warn(ex);
|
||||
}
|
||||
}, null, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10));
|
||||
|
||||
sw.Stop();
|
||||
_log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s");
|
||||
}
|
||||
|
||||
public LogCommands()
|
||||
|
@ -8,6 +8,7 @@ using NadekoBot.Services.Database.Models;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@ -79,10 +80,15 @@ namespace NadekoBot.Modules.Administration
|
||||
|
||||
static RepeatCommands()
|
||||
{
|
||||
var _log = LogManager.GetCurrentClassLogger();
|
||||
var sw = Stopwatch.StartNew();
|
||||
using (var uow = DbHandler.UnitOfWork())
|
||||
{
|
||||
repeaters = new ConcurrentDictionary<ulong, RepeatRunner>(uow.Repeaters.GetAll().Select(r => new RepeatRunner(r)).Where(r => r != null).ToDictionary(r => r.Repeater.ChannelId));
|
||||
}
|
||||
|
||||
sw.Stop();
|
||||
_log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s");
|
||||
}
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
|
@ -6,9 +6,11 @@ using NadekoBot.Attributes;
|
||||
using NadekoBot.Extensions;
|
||||
using NadekoBot.Services;
|
||||
using NadekoBot.Services.Database.Models;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@ -34,21 +36,25 @@ namespace NadekoBot.Modules.Administration
|
||||
All
|
||||
}
|
||||
|
||||
static MuteCommands() {
|
||||
using (var uow = DbHandler.UnitOfWork())
|
||||
{
|
||||
var configs = NadekoBot.AllGuildConfigs;
|
||||
GuildMuteRoles = new ConcurrentDictionary<ulong, string>(configs
|
||||
.Where(c => !string.IsNullOrWhiteSpace(c.MuteRoleName))
|
||||
.ToDictionary(c => c.GuildId, c => c.MuteRoleName));
|
||||
static MuteCommands()
|
||||
{
|
||||
var _log = LogManager.GetCurrentClassLogger();
|
||||
var sw = Stopwatch.StartNew();
|
||||
|
||||
MutedUsers = new ConcurrentDictionary<ulong, ConcurrentHashSet<ulong>>(configs.ToDictionary(
|
||||
k => k.GuildId,
|
||||
v => new ConcurrentHashSet<ulong>(v.MutedUsers.Select(m => m.UserId))
|
||||
));
|
||||
}
|
||||
var configs = NadekoBot.AllGuildConfigs;
|
||||
GuildMuteRoles = new ConcurrentDictionary<ulong, string>(configs
|
||||
.Where(c => !string.IsNullOrWhiteSpace(c.MuteRoleName))
|
||||
.ToDictionary(c => c.GuildId, c => c.MuteRoleName));
|
||||
|
||||
MutedUsers = new ConcurrentDictionary<ulong, ConcurrentHashSet<ulong>>(configs.ToDictionary(
|
||||
k => k.GuildId,
|
||||
v => new ConcurrentHashSet<ulong>(v.MutedUsers.Select(m => m.UserId))
|
||||
));
|
||||
|
||||
NadekoBot.Client.UserJoined += Client_UserJoined;
|
||||
|
||||
sw.Stop();
|
||||
_log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s");
|
||||
}
|
||||
|
||||
private static async void Client_UserJoined(IGuildUser usr)
|
||||
|
@ -8,6 +8,7 @@ using NadekoBot.Services.Database.Models;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -22,8 +23,11 @@ namespace NadekoBot.Modules.Administration
|
||||
public static List<PlayingStatus> RotatingStatusMessages { get; }
|
||||
public static bool RotatingStatuses { get; private set; } = false;
|
||||
|
||||
//todo wtf is with this while(true) in constructor
|
||||
static PlayingRotateCommands()
|
||||
{
|
||||
_log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
using (var uow = DbHandler.UnitOfWork())
|
||||
{
|
||||
var conf = uow.BotConfig.GetOrCreate();
|
||||
@ -31,7 +35,6 @@ namespace NadekoBot.Modules.Administration
|
||||
RotatingStatuses = conf.RotatingStatuses;
|
||||
}
|
||||
|
||||
_log = LogManager.GetCurrentClassLogger();
|
||||
var t = Task.Run(async () =>
|
||||
{
|
||||
var index = 0;
|
||||
|
@ -4,8 +4,10 @@ using Discord.WebSocket;
|
||||
using NadekoBot.Attributes;
|
||||
using NadekoBot.Extensions;
|
||||
using NadekoBot.Services;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
@ -22,11 +24,16 @@ namespace NadekoBot.Modules.Administration
|
||||
private static ConcurrentHashSet<ulong> voicePlusTextCache { get; }
|
||||
static VoicePlusTextCommands()
|
||||
{
|
||||
var _log = LogManager.GetCurrentClassLogger();
|
||||
var sw = Stopwatch.StartNew();
|
||||
using (var uow = DbHandler.UnitOfWork())
|
||||
{
|
||||
voicePlusTextCache = new ConcurrentHashSet<ulong>(NadekoBot.AllGuildConfigs.Where(g => g.VoicePlusTextEnabled).Select(g => g.GuildId));
|
||||
}
|
||||
NadekoBot.Client.UserVoiceStateUpdated += UserUpdatedEventHandler;
|
||||
|
||||
sw.Stop();
|
||||
_log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s");
|
||||
}
|
||||
|
||||
private static async void UserUpdatedEventHandler(IUser iuser, IVoiceState before, IVoiceState after)
|
||||
|
@ -10,6 +10,8 @@ using Discord.WebSocket;
|
||||
using NadekoBot.Services.Database.Models;
|
||||
using System.Collections.Generic;
|
||||
using NadekoBot.Services.Database;
|
||||
using NLog;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace NadekoBot.Modules.Gambling
|
||||
{
|
||||
|
@ -7,6 +7,7 @@ using NLog;
|
||||
using Services.CleverBotApi;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -30,6 +31,7 @@ namespace NadekoBot.Modules.Games
|
||||
static CleverBotCommands()
|
||||
{
|
||||
_log = LogManager.GetCurrentClassLogger();
|
||||
var sw = Stopwatch.StartNew();
|
||||
|
||||
using (var uow = DbHandler.UnitOfWork())
|
||||
{
|
||||
@ -39,6 +41,9 @@ namespace NadekoBot.Modules.Games
|
||||
.Where(gc => gc.CleverbotEnabled)
|
||||
.ToDictionary(gc => gc.GuildId, gc => bot.CreateSession()));
|
||||
}
|
||||
|
||||
sw.Stop();
|
||||
_log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s");
|
||||
}
|
||||
|
||||
public static async Task<bool> TryAsk(IUserMessage msg) {
|
||||
|
@ -10,6 +10,7 @@ using NLog;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
@ -44,6 +45,8 @@ namespace NadekoBot.Modules.Games
|
||||
static PlantPickCommands()
|
||||
{
|
||||
_log = LogManager.GetCurrentClassLogger();
|
||||
var sw = Stopwatch.StartNew();
|
||||
|
||||
NadekoBot.Client.MessageReceived += PotentialFlowerGeneration;
|
||||
|
||||
using (var uow = DbHandler.UnitOfWork())
|
||||
@ -55,6 +58,9 @@ namespace NadekoBot.Modules.Games
|
||||
chance = conf.CurrencyGenerationChance;
|
||||
cooldown = conf.CurrencyGenerationCooldown;
|
||||
}
|
||||
|
||||
sw.Stop();
|
||||
_log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s");
|
||||
}
|
||||
|
||||
private static async void PotentialFlowerGeneration(IMessage imsg)
|
||||
|
@ -11,12 +11,17 @@ using System.Text.RegularExpressions;
|
||||
using System.Xml.Linq;
|
||||
using NadekoBot.Extensions;
|
||||
using System.Xml;
|
||||
using System.Threading;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace NadekoBot.Modules.NSFW
|
||||
{
|
||||
[NadekoModule("NSFW", "~")]
|
||||
public class NSFW : DiscordModule
|
||||
{
|
||||
//ulong/cancel
|
||||
private static ConcurrentDictionary<ulong, Timer> AutoHentaiTimers { get; } = new ConcurrentDictionary<ulong, Timer>();
|
||||
|
||||
public NSFW() : base()
|
||||
{
|
||||
}
|
||||
@ -54,7 +59,52 @@ namespace NadekoBot.Modules.NSFW
|
||||
if (string.IsNullOrWhiteSpace(link))
|
||||
await channel.SendErrorAsync("No results found.").ConfigureAwait(false);
|
||||
else
|
||||
await channel.SendMessageAsync(link).ConfigureAwait(false);
|
||||
await channel.EmbedAsync(new EmbedBuilder().WithOkColor()
|
||||
.WithImageUrl(link)
|
||||
.WithDescription("Tag: " + tag)
|
||||
.Build()).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task AutoHentai(IUserMessage umsg, int interval = 0, string tags = null)
|
||||
{
|
||||
Timer t;
|
||||
|
||||
if (interval == 0)
|
||||
{
|
||||
if (AutoHentaiTimers.TryRemove(umsg.Channel.Id, out t))
|
||||
{
|
||||
t.Change(Timeout.Infinite, Timeout.Infinite); //proper way to disable the timer
|
||||
await umsg.Channel.SendConfirmAsync("Autohentai stopped.").ConfigureAwait(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (interval < 20)
|
||||
return;
|
||||
|
||||
var tagsArr = tags?.Split('|');
|
||||
|
||||
t = new Timer(async (state) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (tagsArr == null || tagsArr.Length == 0)
|
||||
await Hentai(umsg, null).ConfigureAwait(false);
|
||||
else
|
||||
await Hentai(umsg, tagsArr[new NadekoRandom().Next(0, tagsArr.Length)]);
|
||||
}
|
||||
catch { }
|
||||
}, null, interval * 1000, interval * 1000);
|
||||
|
||||
AutoHentaiTimers.AddOrUpdate(umsg.Channel.Id, t, (key, old) =>
|
||||
{
|
||||
old.Change(Timeout.Infinite, Timeout.Infinite);
|
||||
return t;
|
||||
});
|
||||
|
||||
await umsg.Channel.SendConfirmAsync($"Autohentai started. Reposting every {interval}s with one of the following tags:\n{string.Join(", ", tagsArr)}").ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
||||
|
@ -8,6 +8,8 @@ using Discord;
|
||||
using NadekoBot.Services.Database.Models;
|
||||
using System.Collections.Concurrent;
|
||||
using NadekoBot.Extensions;
|
||||
using NLog;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace NadekoBot.Modules.Permissions
|
||||
{
|
||||
@ -26,6 +28,9 @@ namespace NadekoBot.Modules.Permissions
|
||||
|
||||
static Permissions()
|
||||
{
|
||||
var _log = LogManager.GetCurrentClassLogger();
|
||||
var sw = Stopwatch.StartNew();
|
||||
|
||||
using (var uow = DbHandler.UnitOfWork())
|
||||
{
|
||||
Cache = new ConcurrentDictionary<ulong, PermissionCache>(uow.GuildConfigs
|
||||
@ -38,6 +43,9 @@ namespace NadekoBot.Modules.Permissions
|
||||
PermRole = v.PermissionRole
|
||||
}));
|
||||
}
|
||||
|
||||
sw.Stop();
|
||||
_log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s");
|
||||
}
|
||||
|
||||
public Permissions() : base()
|
||||
|
@ -8,6 +8,7 @@ using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
@ -27,6 +28,7 @@ namespace NadekoBot.Modules.Searches
|
||||
static JokeCommands()
|
||||
{
|
||||
_log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
if (File.Exists("data/wowjokes.json"))
|
||||
{
|
||||
wowJokes = JsonConvert.DeserializeObject<List<WoWJoke>>(File.ReadAllText("data/wowjokes.json"));
|
||||
|
@ -18,7 +18,7 @@ namespace NadekoBot.Modules.Searches
|
||||
[Group]
|
||||
public class OverwatchCommands
|
||||
{
|
||||
private Logger _log;
|
||||
private readonly Logger _log;
|
||||
public OverwatchCommands()
|
||||
{
|
||||
_log = LogManager.GetCurrentClassLogger();
|
||||
|
@ -6,6 +6,7 @@ using NadekoBot.Modules.Searches.Models;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
@ -28,6 +29,8 @@ namespace NadekoBot.Modules.Searches
|
||||
static PokemonSearchCommands()
|
||||
{
|
||||
_log = LogManager.GetCurrentClassLogger();
|
||||
var sw = Stopwatch.StartNew();
|
||||
|
||||
if (File.Exists(PokemonListFile))
|
||||
{
|
||||
pokemons = JsonConvert.DeserializeObject<Dictionary<string, SearchPokemon>>(File.ReadAllText(PokemonListFile));
|
||||
@ -38,6 +41,9 @@ namespace NadekoBot.Modules.Searches
|
||||
pokemonAbilities = JsonConvert.DeserializeObject<Dictionary<string, SearchPokemonAbility>>(File.ReadAllText(PokemonAbilitiesFile));
|
||||
else
|
||||
_log.Warn(PokemonAbilitiesFile + " is missing. Pokemon abilities not loaded.");
|
||||
|
||||
sw.Stop();
|
||||
_log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s");
|
||||
}
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
|
@ -17,6 +17,7 @@ using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using NadekoBot.Services.Database;
|
||||
using NadekoBot.Extensions;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace NadekoBot.Modules.Searches
|
||||
{
|
||||
@ -78,8 +79,8 @@ namespace NadekoBot.Modules.Searches
|
||||
|
||||
static StreamNotificationCommands()
|
||||
{
|
||||
_log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
_log = NLog.LogManager.GetCurrentClassLogger();
|
||||
checkTimer = new Timer(async (state) =>
|
||||
{
|
||||
oldCachedStatuses = new ConcurrentDictionary<string, StreamStatus>(cachedStatuses);
|
||||
|
@ -20,14 +20,11 @@ namespace NadekoBot.Modules.Searches
|
||||
[Group]
|
||||
public class TranslateCommands
|
||||
{
|
||||
private static ConcurrentDictionary<ulong, bool> TranslatedChannels { get; }
|
||||
private static ConcurrentDictionary<UserChannelPair, string> UserLanguages { get; }
|
||||
private static ConcurrentDictionary<ulong, bool> TranslatedChannels { get; } = new ConcurrentDictionary<ulong, bool>();
|
||||
private static ConcurrentDictionary<UserChannelPair, string> UserLanguages { get; } = new ConcurrentDictionary<UserChannelPair, string>();
|
||||
|
||||
static TranslateCommands()
|
||||
{
|
||||
TranslatedChannels = new ConcurrentDictionary<ulong, bool>();
|
||||
UserLanguages = new ConcurrentDictionary<UserChannelPair, string>();
|
||||
|
||||
NadekoBot.Client.MessageReceived += async (msg) =>
|
||||
{
|
||||
try
|
||||
|
@ -9,6 +9,7 @@ using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
@ -32,7 +33,6 @@ namespace NadekoBot.Modules.Utility
|
||||
static UnitConverterCommands()
|
||||
{
|
||||
_log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
try
|
||||
{
|
||||
var data = JsonConvert.DeserializeObject<List<MeasurementUnit>>(File.ReadAllText("data/units.json")).Select(u => new ConvertUnit()
|
||||
|
27
src/NadekoBot/Resources/CommandStrings.Designer.cs
generated
27
src/NadekoBot/Resources/CommandStrings.Designer.cs
generated
@ -599,6 +599,33 @@ namespace NadekoBot.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to autohentai.
|
||||
/// </summary>
|
||||
public static string autohentai_cmd {
|
||||
get {
|
||||
return ResourceManager.GetString("autohentai_cmd", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Posts a hentai every X seconds with a random tag from the provided tags. Use `|` to separate tags. 20 seconds minimum. Provide no arguments to disable..
|
||||
/// </summary>
|
||||
public static string autohentai_desc {
|
||||
get {
|
||||
return ResourceManager.GetString("autohentai_desc", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to `{0}autohentai 30 yuri|tail|long_hair` or `{0}autohentai`.
|
||||
/// </summary>
|
||||
public static string autohentai_usage {
|
||||
get {
|
||||
return ResourceManager.GetString("autohentai_usage", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to autoplay ap.
|
||||
/// </summary>
|
||||
|
@ -2844,4 +2844,13 @@
|
||||
<data name="activity_usage" xml:space="preserve">
|
||||
<value>`{0}activity`</value>
|
||||
</data>
|
||||
<data name="autohentai_cmd" xml:space="preserve">
|
||||
<value>autohentai</value>
|
||||
</data>
|
||||
<data name="autohentai_desc" xml:space="preserve">
|
||||
<value>Posts a hentai every X seconds with a random tag from the provided tags. Use `|` to separate tags. 20 seconds minimum. Provide no arguments to disable.</value>
|
||||
</data>
|
||||
<data name="autohentai_usage" xml:space="preserve">
|
||||
<value>`{0}autohentai 30 yuri|tail|long_hair` or `{0}autohentai`</value>
|
||||
</data>
|
||||
</root>
|
Loading…
Reference in New Issue
Block a user