Merge remote-tracking branch 'refs/remotes/Kwoth/dev' into dev

This commit is contained in:
samvaio 2016-12-29 19:32:21 +05:30
commit 6013def035
20 changed files with 175 additions and 23 deletions

View File

@ -7,6 +7,7 @@ using NadekoBot.Services.Database.Models;
using NLog; using NLog;
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -23,9 +24,11 @@ namespace NadekoBot.Modules.Administration
static AutoAssignRoleCommands() static AutoAssignRoleCommands()
{ {
_log = LogManager.GetCurrentClassLogger();
var sw = Stopwatch.StartNew();
AutoAssignedRoles = new ConcurrentDictionary<ulong, ulong>(NadekoBot.AllGuildConfigs.Where(x => x.AutoAssignRoleId != 0) AutoAssignedRoles = new ConcurrentDictionary<ulong, ulong>(NadekoBot.AllGuildConfigs.Where(x => x.AutoAssignRoleId != 0)
.ToDictionary(k => k.GuildId, v => v.AutoAssignRoleId)); .ToDictionary(k => k.GuildId, v => v.AutoAssignRoleId));
_log = LogManager.GetCurrentClassLogger();
NadekoBot.Client.UserJoined += async (user) => NadekoBot.Client.UserJoined += async (user) =>
{ {
try try
@ -43,6 +46,9 @@ namespace NadekoBot.Modules.Administration
} }
catch (Exception ex) { _log.Warn(ex); } catch (Exception ex) { _log.Warn(ex); }
}; };
sw.Stop();
_log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s");
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]

View File

@ -3,7 +3,9 @@ using Discord.Commands;
using NadekoBot.Attributes; using NadekoBot.Attributes;
using NadekoBot.Extensions; using NadekoBot.Extensions;
using NadekoBot.Services; using NadekoBot.Services;
using NLog;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -17,8 +19,12 @@ namespace NadekoBot.Modules.Administration
private static bool ForwardDMs { get; set; } private static bool ForwardDMs { get; set; }
private static bool ForwardDMsToAllOwners { get; set; } private static bool ForwardDMsToAllOwners { get; set; }
private static readonly Logger _log;
static DMForwardCommands() static DMForwardCommands()
{ {
_log = LogManager.GetCurrentClassLogger();
using (var uow = DbHandler.UnitOfWork()) using (var uow = DbHandler.UnitOfWork())
{ {
var config = uow.BotConfig.GetOrCreate(); var config = uow.BotConfig.GetOrCreate();

View File

@ -11,6 +11,7 @@ using NLog;
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -37,6 +38,7 @@ namespace NadekoBot.Modules.Administration
{ {
_client = NadekoBot.Client; _client = NadekoBot.Client;
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
var sw = Stopwatch.StartNew();
using (var uow = DbHandler.UnitOfWork()) using (var uow = DbHandler.UnitOfWork())
{ {
@ -62,6 +64,9 @@ namespace NadekoBot.Modules.Administration
_log.Warn(ex); _log.Warn(ex);
} }
}, null, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10)); }, null, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10));
sw.Stop();
_log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s");
} }
public LogCommands() public LogCommands()

View File

@ -8,6 +8,7 @@ using NadekoBot.Services.Database.Models;
using NLog; using NLog;
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -79,10 +80,15 @@ namespace NadekoBot.Modules.Administration
static RepeatCommands() static RepeatCommands()
{ {
var _log = LogManager.GetCurrentClassLogger();
var sw = Stopwatch.StartNew();
using (var uow = DbHandler.UnitOfWork()) 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)); 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] [NadekoCommand, Usage, Description, Aliases]

View File

@ -6,9 +6,11 @@ using NadekoBot.Attributes;
using NadekoBot.Extensions; using NadekoBot.Extensions;
using NadekoBot.Services; using NadekoBot.Services;
using NadekoBot.Services.Database.Models; using NadekoBot.Services.Database.Models;
using NLog;
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -34,9 +36,11 @@ namespace NadekoBot.Modules.Administration
All All
} }
static MuteCommands() { static MuteCommands()
using (var uow = DbHandler.UnitOfWork())
{ {
var _log = LogManager.GetCurrentClassLogger();
var sw = Stopwatch.StartNew();
var configs = NadekoBot.AllGuildConfigs; var configs = NadekoBot.AllGuildConfigs;
GuildMuteRoles = new ConcurrentDictionary<ulong, string>(configs GuildMuteRoles = new ConcurrentDictionary<ulong, string>(configs
.Where(c => !string.IsNullOrWhiteSpace(c.MuteRoleName)) .Where(c => !string.IsNullOrWhiteSpace(c.MuteRoleName))
@ -46,9 +50,11 @@ namespace NadekoBot.Modules.Administration
k => k.GuildId, k => k.GuildId,
v => new ConcurrentHashSet<ulong>(v.MutedUsers.Select(m => m.UserId)) v => new ConcurrentHashSet<ulong>(v.MutedUsers.Select(m => m.UserId))
)); ));
}
NadekoBot.Client.UserJoined += Client_UserJoined; NadekoBot.Client.UserJoined += Client_UserJoined;
sw.Stop();
_log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s");
} }
private static async void Client_UserJoined(IGuildUser usr) private static async void Client_UserJoined(IGuildUser usr)

View File

@ -8,6 +8,7 @@ using NadekoBot.Services.Database.Models;
using NLog; using NLog;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -22,8 +23,11 @@ namespace NadekoBot.Modules.Administration
public static List<PlayingStatus> RotatingStatusMessages { get; } public static List<PlayingStatus> RotatingStatusMessages { get; }
public static bool RotatingStatuses { get; private set; } = false; public static bool RotatingStatuses { get; private set; } = false;
//todo wtf is with this while(true) in constructor
static PlayingRotateCommands() static PlayingRotateCommands()
{ {
_log = LogManager.GetCurrentClassLogger();
using (var uow = DbHandler.UnitOfWork()) using (var uow = DbHandler.UnitOfWork())
{ {
var conf = uow.BotConfig.GetOrCreate(); var conf = uow.BotConfig.GetOrCreate();
@ -31,7 +35,6 @@ namespace NadekoBot.Modules.Administration
RotatingStatuses = conf.RotatingStatuses; RotatingStatuses = conf.RotatingStatuses;
} }
_log = LogManager.GetCurrentClassLogger();
var t = Task.Run(async () => var t = Task.Run(async () =>
{ {
var index = 0; var index = 0;

View File

@ -4,8 +4,10 @@ using Discord.WebSocket;
using NadekoBot.Attributes; using NadekoBot.Attributes;
using NadekoBot.Extensions; using NadekoBot.Extensions;
using NadekoBot.Services; using NadekoBot.Services;
using NLog;
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -22,11 +24,16 @@ namespace NadekoBot.Modules.Administration
private static ConcurrentHashSet<ulong> voicePlusTextCache { get; } private static ConcurrentHashSet<ulong> voicePlusTextCache { get; }
static VoicePlusTextCommands() static VoicePlusTextCommands()
{ {
var _log = LogManager.GetCurrentClassLogger();
var sw = Stopwatch.StartNew();
using (var uow = DbHandler.UnitOfWork()) using (var uow = DbHandler.UnitOfWork())
{ {
voicePlusTextCache = new ConcurrentHashSet<ulong>(NadekoBot.AllGuildConfigs.Where(g => g.VoicePlusTextEnabled).Select(g => g.GuildId)); voicePlusTextCache = new ConcurrentHashSet<ulong>(NadekoBot.AllGuildConfigs.Where(g => g.VoicePlusTextEnabled).Select(g => g.GuildId));
} }
NadekoBot.Client.UserVoiceStateUpdated += UserUpdatedEventHandler; 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) private static async void UserUpdatedEventHandler(IUser iuser, IVoiceState before, IVoiceState after)

View File

@ -10,6 +10,8 @@ using Discord.WebSocket;
using NadekoBot.Services.Database.Models; using NadekoBot.Services.Database.Models;
using System.Collections.Generic; using System.Collections.Generic;
using NadekoBot.Services.Database; using NadekoBot.Services.Database;
using NLog;
using System.Diagnostics;
namespace NadekoBot.Modules.Gambling namespace NadekoBot.Modules.Gambling
{ {

View File

@ -7,6 +7,7 @@ using NLog;
using Services.CleverBotApi; using Services.CleverBotApi;
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -30,6 +31,7 @@ namespace NadekoBot.Modules.Games
static CleverBotCommands() static CleverBotCommands()
{ {
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
var sw = Stopwatch.StartNew();
using (var uow = DbHandler.UnitOfWork()) using (var uow = DbHandler.UnitOfWork())
{ {
@ -39,6 +41,9 @@ namespace NadekoBot.Modules.Games
.Where(gc => gc.CleverbotEnabled) .Where(gc => gc.CleverbotEnabled)
.ToDictionary(gc => gc.GuildId, gc => bot.CreateSession())); .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) { public static async Task<bool> TryAsk(IUserMessage msg) {

View File

@ -10,6 +10,7 @@ using NLog;
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Security.Cryptography; using System.Security.Cryptography;
@ -44,6 +45,8 @@ namespace NadekoBot.Modules.Games
static PlantPickCommands() static PlantPickCommands()
{ {
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
var sw = Stopwatch.StartNew();
NadekoBot.Client.MessageReceived += PotentialFlowerGeneration; NadekoBot.Client.MessageReceived += PotentialFlowerGeneration;
using (var uow = DbHandler.UnitOfWork()) using (var uow = DbHandler.UnitOfWork())
@ -55,6 +58,9 @@ namespace NadekoBot.Modules.Games
chance = conf.CurrencyGenerationChance; chance = conf.CurrencyGenerationChance;
cooldown = conf.CurrencyGenerationCooldown; cooldown = conf.CurrencyGenerationCooldown;
} }
sw.Stop();
_log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s");
} }
private static async void PotentialFlowerGeneration(IMessage imsg) private static async void PotentialFlowerGeneration(IMessage imsg)

View File

@ -11,12 +11,17 @@ using System.Text.RegularExpressions;
using System.Xml.Linq; using System.Xml.Linq;
using NadekoBot.Extensions; using NadekoBot.Extensions;
using System.Xml; using System.Xml;
using System.Threading;
using System.Collections.Concurrent;
namespace NadekoBot.Modules.NSFW namespace NadekoBot.Modules.NSFW
{ {
[NadekoModule("NSFW", "~")] [NadekoModule("NSFW", "~")]
public class NSFW : DiscordModule public class NSFW : DiscordModule
{ {
//ulong/cancel
private static ConcurrentDictionary<ulong, Timer> AutoHentaiTimers { get; } = new ConcurrentDictionary<ulong, Timer>();
public NSFW() : base() public NSFW() : base()
{ {
} }
@ -54,7 +59,52 @@ namespace NadekoBot.Modules.NSFW
if (string.IsNullOrWhiteSpace(link)) if (string.IsNullOrWhiteSpace(link))
await channel.SendErrorAsync("No results found.").ConfigureAwait(false); await channel.SendErrorAsync("No results found.").ConfigureAwait(false);
else 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);
} }

View File

@ -8,6 +8,8 @@ using Discord;
using NadekoBot.Services.Database.Models; using NadekoBot.Services.Database.Models;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using NadekoBot.Extensions; using NadekoBot.Extensions;
using NLog;
using System.Diagnostics;
namespace NadekoBot.Modules.Permissions namespace NadekoBot.Modules.Permissions
{ {
@ -26,6 +28,9 @@ namespace NadekoBot.Modules.Permissions
static Permissions() static Permissions()
{ {
var _log = LogManager.GetCurrentClassLogger();
var sw = Stopwatch.StartNew();
using (var uow = DbHandler.UnitOfWork()) using (var uow = DbHandler.UnitOfWork())
{ {
Cache = new ConcurrentDictionary<ulong, PermissionCache>(uow.GuildConfigs Cache = new ConcurrentDictionary<ulong, PermissionCache>(uow.GuildConfigs
@ -38,6 +43,9 @@ namespace NadekoBot.Modules.Permissions
PermRole = v.PermissionRole PermRole = v.PermissionRole
})); }));
} }
sw.Stop();
_log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s");
} }
public Permissions() : base() public Permissions() : base()

View File

@ -8,6 +8,7 @@ using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using NLog; using NLog;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net.Http; using System.Net.Http;
@ -27,6 +28,7 @@ namespace NadekoBot.Modules.Searches
static JokeCommands() static JokeCommands()
{ {
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
if (File.Exists("data/wowjokes.json")) if (File.Exists("data/wowjokes.json"))
{ {
wowJokes = JsonConvert.DeserializeObject<List<WoWJoke>>(File.ReadAllText("data/wowjokes.json")); wowJokes = JsonConvert.DeserializeObject<List<WoWJoke>>(File.ReadAllText("data/wowjokes.json"));

View File

@ -18,7 +18,7 @@ namespace NadekoBot.Modules.Searches
[Group] [Group]
public class OverwatchCommands public class OverwatchCommands
{ {
private Logger _log; private readonly Logger _log;
public OverwatchCommands() public OverwatchCommands()
{ {
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();

View File

@ -6,6 +6,7 @@ using NadekoBot.Modules.Searches.Models;
using Newtonsoft.Json; using Newtonsoft.Json;
using NLog; using NLog;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -28,6 +29,8 @@ namespace NadekoBot.Modules.Searches
static PokemonSearchCommands() static PokemonSearchCommands()
{ {
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
var sw = Stopwatch.StartNew();
if (File.Exists(PokemonListFile)) if (File.Exists(PokemonListFile))
{ {
pokemons = JsonConvert.DeserializeObject<Dictionary<string, SearchPokemon>>(File.ReadAllText(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)); pokemonAbilities = JsonConvert.DeserializeObject<Dictionary<string, SearchPokemonAbility>>(File.ReadAllText(PokemonAbilitiesFile));
else else
_log.Warn(PokemonAbilitiesFile + " is missing. Pokemon abilities not loaded."); _log.Warn(PokemonAbilitiesFile + " is missing. Pokemon abilities not loaded.");
sw.Stop();
_log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s");
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]

View File

@ -17,6 +17,7 @@ using Newtonsoft.Json;
using NLog; using NLog;
using NadekoBot.Services.Database; using NadekoBot.Services.Database;
using NadekoBot.Extensions; using NadekoBot.Extensions;
using System.Diagnostics;
namespace NadekoBot.Modules.Searches namespace NadekoBot.Modules.Searches
{ {
@ -78,8 +79,8 @@ namespace NadekoBot.Modules.Searches
static StreamNotificationCommands() static StreamNotificationCommands()
{ {
_log = LogManager.GetCurrentClassLogger();
_log = NLog.LogManager.GetCurrentClassLogger();
checkTimer = new Timer(async (state) => checkTimer = new Timer(async (state) =>
{ {
oldCachedStatuses = new ConcurrentDictionary<string, StreamStatus>(cachedStatuses); oldCachedStatuses = new ConcurrentDictionary<string, StreamStatus>(cachedStatuses);

View File

@ -20,14 +20,11 @@ namespace NadekoBot.Modules.Searches
[Group] [Group]
public class TranslateCommands public class TranslateCommands
{ {
private static ConcurrentDictionary<ulong, bool> TranslatedChannels { get; } private static ConcurrentDictionary<ulong, bool> TranslatedChannels { get; } = new ConcurrentDictionary<ulong, bool>();
private static ConcurrentDictionary<UserChannelPair, string> UserLanguages { get; } private static ConcurrentDictionary<UserChannelPair, string> UserLanguages { get; } = new ConcurrentDictionary<UserChannelPair, string>();
static TranslateCommands() static TranslateCommands()
{ {
TranslatedChannels = new ConcurrentDictionary<ulong, bool>();
UserLanguages = new ConcurrentDictionary<UserChannelPair, string>();
NadekoBot.Client.MessageReceived += async (msg) => NadekoBot.Client.MessageReceived += async (msg) =>
{ {
try try

View File

@ -9,6 +9,7 @@ using Newtonsoft.Json;
using NLog; using NLog;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net.Http; using System.Net.Http;
@ -32,7 +33,6 @@ namespace NadekoBot.Modules.Utility
static UnitConverterCommands() static UnitConverterCommands()
{ {
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
try try
{ {
var data = JsonConvert.DeserializeObject<List<MeasurementUnit>>(File.ReadAllText("data/units.json")).Select(u => new ConvertUnit() var data = JsonConvert.DeserializeObject<List<MeasurementUnit>>(File.ReadAllText("data/units.json")).Select(u => new ConvertUnit()

View File

@ -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> /// <summary>
/// Looks up a localized string similar to autoplay ap. /// Looks up a localized string similar to autoplay ap.
/// </summary> /// </summary>

View File

@ -2844,4 +2844,13 @@
<data name="activity_usage" xml:space="preserve"> <data name="activity_usage" xml:space="preserve">
<value>`{0}activity`</value> <value>`{0}activity`</value>
</data> </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> </root>