Typereaders will be autoloaded when module loads

This commit is contained in:
Master Kwoth 2017-10-09 02:52:46 +02:00
parent 72f36270dc
commit f3513779b7
60 changed files with 316 additions and 140 deletions

View File

@ -4,11 +4,17 @@ using System.Threading.Tasks;
using Discord.Commands;
using NadekoBot.Services;
using NadekoBot.Modules.CustomReactions.Services;
using NadekoBot.Core.Common.TypeReaders;
using Discord.WebSocket;
namespace NadekoBot.Common.TypeReaders
{
public class CommandTypeReader : TypeReader
public class CommandTypeReader : NadekoTypeReader
{
public CommandTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds)
{
}
public override Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider services)
{
var _cmds = ((INServiceProvider)services).GetService<CommandService>();
@ -28,9 +34,13 @@ namespace NadekoBot.Common.TypeReaders
return Task.FromResult(TypeReaderResult.FromSuccess(cmd));
}
}
//todo dependency on the module
public class CommandOrCrTypeReader : CommandTypeReader
{
public CommandOrCrTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds)
{
}
public override async Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider services)
{
input = input.ToUpperInvariant();

View File

@ -1,40 +1,46 @@
//using System;
//using System.Threading.Tasks;
//using Discord.Commands;
//using NadekoBot.Modules.Administration.Services;
using System;
using System.Threading.Tasks;
using Discord.Commands;
using NadekoBot.Modules.Administration.Services;
using NadekoBot.Core.Common.TypeReaders;
using Discord.WebSocket;
//namespace NadekoBot.Common.TypeReaders
//{
// public class GuildDateTimeTypeReader : TypeReader
// {
// public override Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider services)
// {
// var _gts = (GuildTimezoneService)services.GetService(typeof(GuildTimezoneService));
// if (!DateTime.TryParse(input, out var dt))
// return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "Input string is in an incorrect format."));
namespace NadekoBot.Common.TypeReaders
{
public class GuildDateTimeTypeReader : NadekoTypeReader
{
public GuildDateTimeTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds)
{
}
// var tz = _gts.GetTimeZoneOrUtc(context.Guild.Id);
public override Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider services)
{
var _gts = (GuildTimezoneService)services.GetService(typeof(GuildTimezoneService));
if (!DateTime.TryParse(input, out var dt))
return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "Input string is in an incorrect format."));
// return Task.FromResult(TypeReaderResult.FromSuccess(new GuildDateTime(tz, dt)));
// }
// }
var tz = _gts.GetTimeZoneOrUtc(context.Guild.Id);
// public class GuildDateTime
// {
// public TimeZoneInfo Timezone { get; }
// public DateTime CurrentGuildTime { get; }
// public DateTime InputTime { get; }
// public DateTime InputTimeUtc { get; }
return Task.FromResult(TypeReaderResult.FromSuccess(new GuildDateTime(tz, dt)));
}
}
// private GuildDateTime() { }
public class GuildDateTime
{
public TimeZoneInfo Timezone { get; }
public DateTime CurrentGuildTime { get; }
public DateTime InputTime { get; }
public DateTime InputTimeUtc { get; }
// public GuildDateTime(TimeZoneInfo guildTimezone, DateTime inputTime)
// {
// var now = DateTime.UtcNow;
// Timezone = guildTimezone;
// CurrentGuildTime = TimeZoneInfo.ConvertTime(now, TimeZoneInfo.Utc, Timezone);
// InputTime = inputTime;
// InputTimeUtc = TimeZoneInfo.ConvertTime(inputTime, Timezone, TimeZoneInfo.Utc);
// }
// }
//}
private GuildDateTime() { }
public GuildDateTime(TimeZoneInfo guildTimezone, DateTime inputTime)
{
var now = DateTime.UtcNow;
Timezone = guildTimezone;
CurrentGuildTime = TimeZoneInfo.ConvertTime(now, TimeZoneInfo.Utc, Timezone);
InputTime = inputTime;
InputTimeUtc = TimeZoneInfo.ConvertTime(inputTime, Timezone, TimeZoneInfo.Utc);
}
}
}

View File

@ -3,17 +3,19 @@ using System.Linq;
using System.Threading.Tasks;
using Discord.Commands;
using Discord.WebSocket;
using NadekoBot.Core.Common.TypeReaders;
namespace NadekoBot.Common.TypeReaders
{
public class GuildTypeReader : TypeReader
public class GuildTypeReader : NadekoTypeReader
{
private readonly DiscordSocketClient _client;
public GuildTypeReader(DiscordSocketClient client)
public GuildTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds)
{
_client = client;
}
public override Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider _)
{
input = input.Trim().ToLowerInvariant();

View File

@ -3,14 +3,16 @@ using System.Linq;
using System.Threading.Tasks;
using Discord.Commands;
using NadekoBot.Extensions;
using NadekoBot.Core.Common.TypeReaders;
using Discord.WebSocket;
namespace NadekoBot.Common.TypeReaders
{
public class ModuleTypeReader : TypeReader
public class ModuleTypeReader : NadekoTypeReader
{
private readonly CommandService _cmds;
public ModuleTypeReader(CommandService cmds)
public ModuleTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds)
{
_cmds = cmds;
}
@ -26,11 +28,11 @@ namespace NadekoBot.Common.TypeReaders
}
}
public class ModuleOrCrTypeReader : TypeReader
public class ModuleOrCrTypeReader : NadekoTypeReader
{
private readonly CommandService _cmds;
public ModuleOrCrTypeReader(CommandService cmds)
public ModuleOrCrTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds)
{
_cmds = cmds;
}

View File

@ -0,0 +1,18 @@
using Discord.Commands;
using Discord.WebSocket;
namespace NadekoBot.Core.Common.TypeReaders
{
public abstract class NadekoTypeReader : TypeReader
{
private readonly DiscordSocketClient _client;
private readonly CommandService _cmds;
private NadekoTypeReader() { }
public NadekoTypeReader(DiscordSocketClient client, CommandService cmds)
{
_client = client;
_cmds = cmds;
}
}
}

View File

@ -1,15 +1,21 @@
using System;
using System.Threading.Tasks;
using Discord.Commands;
using Discord.WebSocket;
using NadekoBot.Common.TypeReaders.Models;
using NadekoBot.Core.Common.TypeReaders;
namespace NadekoBot.Common.TypeReaders
{
/// <summary>
/// Used instead of bool for more flexible keywords for true/false only in the permission module
/// </summary>
public class PermissionActionTypeReader : TypeReader
public class PermissionActionTypeReader : NadekoTypeReader
{
public PermissionActionTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds)
{
}
public override Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider _)
{
input = input.ToUpperInvariant();

View File

@ -308,7 +308,6 @@ namespace NadekoBot.Services.Database
.WithOne(x => x.XpSettings);
#endregion
//todo major bug
#region XpRoleReward
modelBuilder.Entity<XpRoleReward>()
.HasIndex(x => new { x.XpSettingsId, x.Level })

View File

@ -23,6 +23,7 @@ using NadekoBot.Services.Database;
using StackExchange.Redis;
using Newtonsoft.Json;
using System.Runtime.Loader;
using NadekoBot.Core.Common.TypeReaders;
namespace NadekoBot
{
@ -138,6 +139,8 @@ namespace NadekoBot
.AddManual(Client)
.AddManual(CommandService)
.AddManual(botConfigProvider)
//todo this needs to reload whenever a new service is supposed to be loaded
//except at startup for obvious reasons
.AddManual<IEnumerable<GuildConfig>>(AllGuildConfigs) //todo wrap this
.AddManual<NadekoBot>(this)
.AddManual<IUnitOfWork>(uow)
@ -147,19 +150,50 @@ namespace NadekoBot
var commandHandler = Services.GetService<CommandHandler>();
commandHandler.AddServices(Services);
LoadTypeReaders(typeof(NadekoBot).Assembly);
//setup typereaders
CommandService.AddTypeReader<PermissionAction>(new PermissionActionTypeReader());
CommandService.AddTypeReader<CommandInfo>(new CommandTypeReader());
CommandService.AddTypeReader<PermissionAction>(new PermissionActionTypeReader(Client, CommandService));
CommandService.AddTypeReader<CommandInfo>(new CommandTypeReader(Client, CommandService));
//todo module dependency
CommandService.AddTypeReader<CommandOrCrInfo>(new CommandOrCrTypeReader());
CommandService.AddTypeReader<ModuleInfo>(new ModuleTypeReader(CommandService));
CommandService.AddTypeReader<ModuleOrCrInfo>(new ModuleOrCrTypeReader(CommandService));
CommandService.AddTypeReader<IGuild>(new GuildTypeReader(Client));
CommandService.AddTypeReader<CommandOrCrInfo>(new CommandOrCrTypeReader(Client, CommandService));
CommandService.AddTypeReader<ModuleInfo>(new ModuleTypeReader(Client, CommandService));
CommandService.AddTypeReader<ModuleOrCrInfo>(new ModuleOrCrTypeReader(Client, CommandService));
CommandService.AddTypeReader<IGuild>(new GuildTypeReader(Client, CommandService));
//CommandService.AddTypeReader<GuildDateTime>(new GuildDateTimeTypeReader());
}
Services.Unload(typeof(IUnitOfWork)); // unload it after the startup
}
private IEnumerable<NadekoTypeReader> LoadTypeReaders(Assembly assembly)
{
Type[] allTypes;
try
{
allTypes = assembly.GetTypes();
}
catch (ReflectionTypeLoadException ex)
{
Console.WriteLine(ex.LoaderExceptions[0]);
return Enumerable.Empty<NadekoTypeReader>();
}
var filteredTypes = allTypes
.Where(x => x.IsSubclassOf(typeof(NadekoTypeReader))
&& !x.IsAbstract);
var toReturn = new List<NadekoTypeReader>();
foreach (var ft in filteredTypes)
{
//:yayyy:
var x = (NadekoTypeReader)Activator.CreateInstance(ft, Client, CommandService);
CommandService.AddTypeReader(x.GetType(), x);
toReturn.Add(x);
_log.Info("Loaded {0} typereader.", x.GetType().Name);
}
return toReturn;
}
private async Task LoginAsync(string token)
{
var clientReady = new TaskCompletionSource<bool>();
@ -254,7 +288,6 @@ namespace NadekoBot
Ready.TrySetResult(true);
HandleStatusChanges();
_log.Info($"Shard {Client.ShardId} ready.");
//_log.Info(await stats.Print().ConfigureAwait(false));
}
private Task Client_Log(LogMessage arg)
@ -400,6 +433,7 @@ namespace NadekoBot
_log.Info("Unloaded {0} types.", i);
}
return true;
}
finally
@ -426,6 +460,13 @@ namespace NadekoBot
$"NadekoBot.Modules.{name}.dll"));
var types = Services.LoadFrom(package);
var added = await CommandService.AddModulesAsync(package).ConfigureAwait(false);
var trs = LoadTypeReaders(package);
/* i don't have to unload typereaders
* (and there's no api for it)
* because they get overwritten anyway, and since
* the only time I'd unload typereaders, is when unloading a module
* which means they won't have a chance to be used
* */
_log.Info("Loaded {0} modules and {1} types.", added.Count(), types.Count());
_packageModules.Add(name, added);
_packageTypes.Add(name, types);

View File

@ -15,4 +15,8 @@
<ProjectReference Include="..\NadekoBot.Core\NadekoBot.Core.csproj" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="2.0.0" />
</ItemGroup>
</Project>

View File

@ -44,7 +44,7 @@ namespace NadekoBot.Modules.Gambling
Depraved,
Harlot
}
//todo unclaimed waifus should lose 5% of their value a day
//todo unclaimed waifus should lose 3% of their value a day
[Group]
public class WaifuClaimCommands : NadekoSubmodule
{

View File

@ -11,6 +11,7 @@ namespace NadekoBot.Modules.Games.Common.Hangman
public class Hangman : IDisposable
{
public string TermType { get; }
public TermPool TermPool { get; }
public HangmanObject Term { get; }
public string ScrambledWord => "`" + String.Concat(Term.Word.Select(c =>
@ -56,10 +57,11 @@ namespace NadekoBot.Modules.Games.Common.Hangman
public Task EndedTask => _endingCompletionSource.Task;
public Hangman(string type)
public Hangman(string type, TermPool tp = null)
{
this.TermType = type.Trim().ToLowerInvariant().ToTitleCase();
this.Term = TermPool.GetTerm(type);
this.TermPool = tp ?? new TermPool();
this.Term = this.TermPool.GetTerm(type);
}
private void AddError()

View File

@ -5,27 +5,35 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using NLog;
namespace NadekoBot.Modules.Games.Common.Hangman
{
public class TermPool
{
const string termsPath = "data/hangman3.json";
public static IReadOnlyDictionary<string, HangmanObject[]> Data { get; } = new Dictionary<string, HangmanObject[]>();
static TermPool()
private readonly Logger _log;
public IReadOnlyDictionary<string, HangmanObject[]> Data { get; } = new Dictionary<string, HangmanObject[]>();
public TermPool()
{
_log = LogManager.GetCurrentClassLogger();
try
{
Data = JsonConvert.DeserializeObject<Dictionary<string, HangmanObject[]>>(File.ReadAllText(termsPath));
Data = Data.ToDictionary(
x => x.Key.ToLowerInvariant(),
x => x.Value);
}
catch (Exception)
catch (Exception ex)
{
//ignored
_log.Warn(ex);
}
}
public static HangmanObject GetTerm(string type)
public HangmanObject GetTerm(string type)
{
type = type?.Trim().ToLowerInvariant();
var rng = new NadekoRandom();
if (type == "random")

View File

@ -26,14 +26,14 @@ namespace NadekoBot.Modules.Games
[RequireContext(ContextType.Guild)]
public async Task Hangmanlist()
{
await Context.Channel.SendConfirmAsync(Format.Code(GetText("hangman_types", Prefix)) + "\n" + string.Join("\n", TermPool.Data.Keys));
await Context.Channel.SendConfirmAsync(Format.Code(GetText("hangman_types", Prefix)) + "\n" + string.Join("\n", _service.TermPool.Data.Keys));
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task Hangman([Remainder]string type = "random")
{
var hm = new Hangman(type);
var hm = new Hangman(type, _service.TermPool);
if (!_service.HangmanGames.TryAdd(Context.Channel.Id, hm))
{

View File

@ -19,4 +19,8 @@
<ProjectReference Include="..\NadekoBot.Core\NadekoBot.Core.csproj" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="2.0.0" />
</ItemGroup>
</Project>

View File

@ -46,7 +46,10 @@ namespace NadekoBot.Modules.Games.Services
//channelId, game
public ConcurrentDictionary<ulong, Acrophobia> AcrophobiaGames { get; } = new ConcurrentDictionary<ulong, Acrophobia>();
public ConcurrentDictionary<ulong, Connect4Game> Connect4Games { get; } = new ConcurrentDictionary<ulong, Connect4Game>();
public ConcurrentDictionary<ulong, Hangman> HangmanGames { get; } = new ConcurrentDictionary<ulong, Hangman>();
public TermPool TermPool { get; } = new TermPool();
public ConcurrentDictionary<ulong, TriviaGame> RunningTrivias { get; } = new ConcurrentDictionary<ulong, TriviaGame>();
public Dictionary<ulong, TicTacToe> TicTacToeGames { get; } = new Dictionary<ulong, TicTacToe>();
public ConcurrentDictionary<ulong, TypingGame> RunningContests { get; } = new ConcurrentDictionary<ulong, TypingGame>();

View File

@ -16,4 +16,8 @@
<ProjectReference Include="..\NadekoBot.Core\NadekoBot.Core.csproj" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="2.0.0" />
</ItemGroup>
</Project>

View File

@ -2,11 +2,4 @@
namespace NadekoBot.Modules.NSFW.Exceptions
{
public class TagBlacklistedException : Exception
{
public TagBlacklistedException() : base("Tag you used is blacklisted.")
{
}
}
}

View File

@ -12,6 +12,7 @@ using NadekoBot.Common.Collections;
using NadekoBot.Modules.Searches.Common;
using NadekoBot.Modules.Searches.Services;
using NadekoBot.Modules.NSFW.Exceptions;
using NadekoBot.Modules.Searches.Exceptions;
namespace NadekoBot.Modules.NSFW
{
@ -85,7 +86,7 @@ namespace NadekoBot.Modules.NSFW
if (interval == 0)
{
if (!_autoHentaiTimers.TryRemove(Context.Channel.Id, out t)) return;
if (!_service.AutoHentaiTimers.TryRemove(Context.Channel.Id, out t)) return;
t.Change(Timeout.Infinite, Timeout.Infinite); //proper way to disable the timer
await ReplyConfirmLocalized("stopped").ConfigureAwait(false);
@ -112,7 +113,7 @@ namespace NadekoBot.Modules.NSFW
}
}, null, interval * 1000, interval * 1000);
_autoHentaiTimers.AddOrUpdate(Context.Channel.Id, t, (key, old) =>
_service.AutoHentaiTimers.AddOrUpdate(Context.Channel.Id, t, (key, old) =>
{
old.Change(Timeout.Infinite, Timeout.Infinite);
return t;
@ -131,7 +132,7 @@ namespace NadekoBot.Modules.NSFW
if (interval == 0)
{
if (!_autoBoobTimers.TryRemove(Context.Channel.Id, out t)) return;
if (!_service.AutoBoobTimers.TryRemove(Context.Channel.Id, out t)) return;
t.Change(Timeout.Infinite, Timeout.Infinite); //proper way to disable the timer
await ReplyConfirmLocalized("stopped").ConfigureAwait(false);
@ -153,7 +154,7 @@ namespace NadekoBot.Modules.NSFW
}
}, null, interval * 1000, interval * 1000);
_autoBoobTimers.AddOrUpdate(Context.Channel.Id, t, (key, old) =>
_service.AutoBoobTimers.AddOrUpdate(Context.Channel.Id, t, (key, old) =>
{
old.Change(Timeout.Infinite, Timeout.Infinite);
return t;
@ -170,7 +171,7 @@ namespace NadekoBot.Modules.NSFW
if (interval == 0)
{
if (!_autoButtTimers.TryRemove(Context.Channel.Id, out t)) return;
if (!_service.AutoButtTimers.TryRemove(Context.Channel.Id, out t)) return;
t.Change(Timeout.Infinite, Timeout.Infinite); //proper way to disable the timer
await ReplyConfirmLocalized("stopped").ConfigureAwait(false);
@ -192,7 +193,7 @@ namespace NadekoBot.Modules.NSFW
}
}, null, interval * 1000, interval * 1000);
_autoButtTimers.AddOrUpdate(Context.Channel.Id, t, (key, old) =>
_service.AutoButtTimers.AddOrUpdate(Context.Channel.Id, t, (key, old) =>
{
old.Change(Timeout.Infinite, Timeout.Infinite);
return t;

View File

@ -17,7 +17,11 @@
<ItemGroup>
<ProjectReference Include="..\NadekoBot.Core\NadekoBot.Core.csproj" />
<ProjectReference Include="..\NadekoBot.Module.Searches\NadekoBot.Modules.Searches.csproj" />
<ProjectReference Include="..\NadekoBot.Modules.Searches\NadekoBot.Modules.Searches.csproj" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="2.0.0" />
</ItemGroup>
</Project>

View File

@ -15,4 +15,8 @@
<ProjectReference Include="..\NadekoBot.Core\NadekoBot.Core.csproj" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="2.0.0" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,12 @@
using System;
namespace NadekoBot.Modules.Searches.Exceptions
{
public class TagBlacklistedException : Exception
{
public TagBlacklistedException() : base("Tag you used is blacklisted.")
{
}
}
}

View File

@ -17,6 +17,7 @@ using System.Net.Http;
using Newtonsoft.Json.Linq;
using AngleSharp;
using System.Threading;
using NadekoBot.Modules.Searches.Exceptions;
namespace NadekoBot.Modules.Searches.Services
{
@ -43,9 +44,9 @@ namespace NadekoBot.Modules.Searches.Services
private readonly ConcurrentDictionary<ulong, SearchImageCacher> _imageCacher = new ConcurrentDictionary<ulong, SearchImageCacher>();
//todo clear when module unloaded
public ConcurrentDictionary<ulong, Timer> _autoHentaiTimers { get; } = new ConcurrentDictionary<ulong, Timer>();
public ConcurrentDictionary<ulong, Timer> _autoBoobTimers { get; } = new ConcurrentDictionary<ulong, Timer>();
public ConcurrentDictionary<ulong, Timer> _autoButtTimers { get; } = new ConcurrentDictionary<ulong, Timer>();
public ConcurrentDictionary<ulong, Timer> AutoHentaiTimers { get; } = new ConcurrentDictionary<ulong, Timer>();
public ConcurrentDictionary<ulong, Timer> AutoBoobTimers { get; } = new ConcurrentDictionary<ulong, Timer>();
public ConcurrentDictionary<ulong, Timer> AutoButtTimers { get; } = new ConcurrentDictionary<ulong, Timer>();
private readonly ConcurrentDictionary<ulong, HashSet<string>> _blacklistedTags = new ConcurrentDictionary<ulong, HashSet<string>>();
@ -147,8 +148,7 @@ namespace NadekoBot.Modules.Searches.Services
if (blacklistedTags
.Any(x => tag.ToLowerInvariant().Contains(x)))
{
//todo tag blacklisted
throw new Exception();
throw new TagBlacklistedException();
}
var cacher = _imageCacher.GetOrAdd(guild.Value, (key) => new SearchImageCacher());
@ -231,12 +231,12 @@ namespace NadekoBot.Modules.Searches.Services
public Task Unload()
{
_autoBoobTimers.ForEach(x => x.Value.Change(Timeout.Infinite, Timeout.Infinite));
_autoBoobTimers.Clear();
_autoButtTimers.ForEach(x => x.Value.Change(Timeout.Infinite, Timeout.Infinite));
_autoButtTimers.Clear();
_autoHentaiTimers.ForEach(x => x.Value.Change(Timeout.Infinite, Timeout.Infinite));
_autoHentaiTimers.Clear();
AutoBoobTimers.ForEach(x => x.Value.Change(Timeout.Infinite, Timeout.Infinite));
AutoBoobTimers.Clear();
AutoButtTimers.ForEach(x => x.Value.Change(Timeout.Infinite, Timeout.Infinite));
AutoButtTimers.Clear();
AutoHentaiTimers.ForEach(x => x.Value.Change(Timeout.Infinite, Timeout.Infinite));
AutoHentaiTimers.Clear();
_imageCacher.Clear();
return Task.CompletedTask;

View File

@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup>
<OutputPath>..\src\NadekoBot\bin\$(Configuration)\netcoreapp2.0\modules\$(AssemblyName)\</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AngleSharp" Version="0.9.9" />
<PackageReference Include="Discord.Net" Version="2.0.0-alpha-build-00832" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NadekoBot.Core\NadekoBot.Core.csproj" />
</ItemGroup>
</Project>

View File

@ -20,4 +20,12 @@
<ProjectReference Include="..\NadekoBot.Core\NadekoBot.Core.csproj" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="2.0.0" />
</ItemGroup>
<ItemGroup>
<None Include="NadekoBot.Modules.Searches.csproj" />
</ItemGroup>
</Project>

View File

@ -147,59 +147,57 @@ namespace NadekoBot.Modules.Utility
Format.Bold(rep.Repeater.Interval.Minutes.ToString()))).ConfigureAwait(false);
}
//todo guild date time
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.ManageMessages)]
[Priority(1)]
public async Task Repeat(GuildDateTime gt, [Remainder] string message)
{
if (!_service.RepeaterReady)
return;
//[NadekoCommand, Usage, Description, Aliases]
//[RequireContext(ContextType.Guild)]
//[RequireUserPermission(GuildPermission.ManageMessages)]
//[Priority(1)]
//public async Task Repeat(GuildDateTime gt, [Remainder] string message)
//{
// if (!_service.RepeaterReady)
// return;
if (string.IsNullOrWhiteSpace(message))
return;
// if (string.IsNullOrWhiteSpace(message))
// return;
var toAdd = new GuildRepeater()
{
ChannelId = Context.Channel.Id,
GuildId = Context.Guild.Id,
Interval = TimeSpan.FromHours(24),
StartTimeOfDay = gt.InputTimeUtc.TimeOfDay,
Message = message
};
// var toAdd = new GuildRepeater()
// {
// ChannelId = Context.Channel.Id,
// GuildId = Context.Guild.Id,
// Interval = TimeSpan.FromHours(24),
// StartTimeOfDay = gt.InputTimeUtc.TimeOfDay,
// Message = message
// };
using (var uow = _db.UnitOfWork)
{
var gc = uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.GuildRepeaters));
// using (var uow = _db.UnitOfWork)
// {
// var gc = uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.GuildRepeaters));
if (gc.GuildRepeaters.Count >= 5)
return;
gc.GuildRepeaters.Add(toAdd);
// if (gc.GuildRepeaters.Count >= 5)
// return;
// gc.GuildRepeaters.Add(toAdd);
await uow.CompleteAsync().ConfigureAwait(false);
}
// await uow.CompleteAsync().ConfigureAwait(false);
// }
var rep = new RepeatRunner(_client, (SocketGuild)Context.Guild, toAdd);
// var rep = new RepeatRunner(_client, (SocketGuild)Context.Guild, toAdd);
_service.Repeaters.AddOrUpdate(Context.Guild.Id, new ConcurrentQueue<RepeatRunner>(new[] { rep }), (key, old) =>
{
old.Enqueue(rep);
return old;
});
// _service.Repeaters.AddOrUpdate(Context.Guild.Id, new ConcurrentQueue<RepeatRunner>(new[] { rep }), (key, old) =>
// {
// old.Enqueue(rep);
// return old;
// });
var secondPart = GetText("repeater_initial",
Format.Bold(rep.InitialInterval.Hours.ToString()),
Format.Bold(rep.InitialInterval.Minutes.ToString()));
// var secondPart = GetText("repeater_initial",
// Format.Bold(rep.InitialInterval.Hours.ToString()),
// Format.Bold(rep.InitialInterval.Minutes.ToString()));
// await Context.Channel.SendConfirmAsync(
// "🔁 " + GetText("repeater",
// Format.Bold(((IGuildUser)Context.User).GuildPermissions.MentionEveryone ? rep.Repeater.Message : rep.Repeater.Message.SanitizeMentions()),
// Format.Bold(rep.Repeater.Interval.Days.ToString()),
// Format.Bold(rep.Repeater.Interval.Hours.ToString()),
// Format.Bold(rep.Repeater.Interval.Minutes.ToString())) + " " + secondPart).ConfigureAwait(false);
//}
await Context.Channel.SendConfirmAsync(
"🔁 " + GetText("repeater",
Format.Bold(((IGuildUser)Context.User).GuildPermissions.MentionEveryone ? rep.Repeater.Message : rep.Repeater.Message.SanitizeMentions()),
Format.Bold(rep.Repeater.Interval.Days.ToString()),
Format.Bold(rep.Repeater.Interval.Hours.ToString()),
Format.Bold(rep.Repeater.Interval.Minutes.ToString())) + " " + secondPart).ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]

View File

@ -19,4 +19,8 @@
<ProjectReference Include="..\NadekoBot.Core\NadekoBot.Core.csproj" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="2.0.0" />
</ItemGroup>
</Project>

View File

@ -19,8 +19,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NadekoBot.Modules.Xp", "Nad
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NadekoBot.Modules.Utility", "NadekoBot.Modules.Utility\NadekoBot.Modules.Utility.csproj", "{07606931-CB55-4D20-8369-4E086B00EC52}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NadekoBot.Modules.Searches", "NadekoBot.Module.Searches\NadekoBot.Modules.Searches.csproj", "{8BEE9984-3EB3-45BE-A5CF-0DB912626B81}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NadekoBot.Modules.Nsfw", "NadekoBot.Modules.Nsfw\NadekoBot.Modules.Nsfw.csproj", "{75ED72EC-7AB3-4B12-A2DA-3655C740B356}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NadekoBot.Modules.Games", "NadekoBot.Modules.Games\NadekoBot.Modules.Games.csproj", "{FF6BDE61-24B4-4DC2-99EE-409EA1650180}"
@ -31,6 +29,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NadekoBot.Modules.Pokemon",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NadekoBot.Modules.Music", "NadekoBot.Modules.Music\NadekoBot.Modules.Music.csproj", "{674E28A6-30B1-413D-BBD3-E5F71614A00F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NadekoBot.Modules.Searches", "NadekoBot.Modules.Searches\NadekoBot.Modules.Searches.csproj", "{ED6DCB6E-66BE-45F4-A1D6-67FE01BCACD9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -62,12 +62,6 @@ Global
{07606931-CB55-4D20-8369-4E086B00EC52}.GlobalNadeko|Any CPU.Build.0 = Debug|Any CPU
{07606931-CB55-4D20-8369-4E086B00EC52}.Release|Any CPU.ActiveCfg = Release|Any CPU
{07606931-CB55-4D20-8369-4E086B00EC52}.Release|Any CPU.Build.0 = Release|Any CPU
{8BEE9984-3EB3-45BE-A5CF-0DB912626B81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8BEE9984-3EB3-45BE-A5CF-0DB912626B81}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8BEE9984-3EB3-45BE-A5CF-0DB912626B81}.GlobalNadeko|Any CPU.ActiveCfg = Debug|Any CPU
{8BEE9984-3EB3-45BE-A5CF-0DB912626B81}.GlobalNadeko|Any CPU.Build.0 = Debug|Any CPU
{8BEE9984-3EB3-45BE-A5CF-0DB912626B81}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8BEE9984-3EB3-45BE-A5CF-0DB912626B81}.Release|Any CPU.Build.0 = Release|Any CPU
{75ED72EC-7AB3-4B12-A2DA-3655C740B356}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{75ED72EC-7AB3-4B12-A2DA-3655C740B356}.Debug|Any CPU.Build.0 = Debug|Any CPU
{75ED72EC-7AB3-4B12-A2DA-3655C740B356}.GlobalNadeko|Any CPU.ActiveCfg = Debug|Any CPU
@ -98,6 +92,12 @@ Global
{674E28A6-30B1-413D-BBD3-E5F71614A00F}.GlobalNadeko|Any CPU.Build.0 = Debug|Any CPU
{674E28A6-30B1-413D-BBD3-E5F71614A00F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{674E28A6-30B1-413D-BBD3-E5F71614A00F}.Release|Any CPU.Build.0 = Release|Any CPU
{ED6DCB6E-66BE-45F4-A1D6-67FE01BCACD9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ED6DCB6E-66BE-45F4-A1D6-67FE01BCACD9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ED6DCB6E-66BE-45F4-A1D6-67FE01BCACD9}.GlobalNadeko|Any CPU.ActiveCfg = Debug|Any CPU
{ED6DCB6E-66BE-45F4-A1D6-67FE01BCACD9}.GlobalNadeko|Any CPU.Build.0 = Debug|Any CPU
{ED6DCB6E-66BE-45F4-A1D6-67FE01BCACD9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ED6DCB6E-66BE-45F4-A1D6-67FE01BCACD9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -107,12 +107,12 @@ Global
{A6CCEFBD-DCF2-482C-9643-47664683548F} = {04929013-5BAB-42B0-B9B2-8F2BB8F16AF2}
{41A2DEBA-E8AE-4EC8-A58F-01C4B6E599E5} = {04929013-5BAB-42B0-B9B2-8F2BB8F16AF2}
{07606931-CB55-4D20-8369-4E086B00EC52} = {04929013-5BAB-42B0-B9B2-8F2BB8F16AF2}
{8BEE9984-3EB3-45BE-A5CF-0DB912626B81} = {04929013-5BAB-42B0-B9B2-8F2BB8F16AF2}
{75ED72EC-7AB3-4B12-A2DA-3655C740B356} = {04929013-5BAB-42B0-B9B2-8F2BB8F16AF2}
{FF6BDE61-24B4-4DC2-99EE-409EA1650180} = {04929013-5BAB-42B0-B9B2-8F2BB8F16AF2}
{6436A700-694E-412C-92AE-B793FCD44E84} = {04929013-5BAB-42B0-B9B2-8F2BB8F16AF2}
{30463C26-555B-4760-9459-A16DFA015DFA} = {04929013-5BAB-42B0-B9B2-8F2BB8F16AF2}
{674E28A6-30B1-413D-BBD3-E5F71614A00F} = {04929013-5BAB-42B0-B9B2-8F2BB8F16AF2}
{ED6DCB6E-66BE-45F4-A1D6-67FE01BCACD9} = {04929013-5BAB-42B0-B9B2-8F2BB8F16AF2}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5F3F555C-855F-4BE8-B526-D062D3E8ACA4}

20
watchbuildall.ps1 Normal file
View File

@ -0,0 +1,20 @@
$cur = (Get-Item -Path ".\" -Verbose).FullName
function WatchBuild([string] $path, [string] $args)
{
cd $cur
cd $path
cmd.exe /c "dotnet watch"
cd $cur
}
WatchBuild(".\NadekoBot.Modules.CustomReactions")
WatchBuild(".\NadekoBot.Modules.Gambling")
WatchBuild(".\NadekoBot.Modules.Games")
WatchBuild(".\NadekoBot.Modules.Music")
WatchBuild(".\NadekoBot.Modules.Nsfw")
WatchBuild(".\NadekoBot.Modules.Pokemon")
WatchBuild(".\NadekoBot.Modules.Searches")
WatchBuild(".\NadekoBot.Modules.Utility")
WatchBuild(".\NadekoBot.Modules.Xp")