Various changes

-Add Guild ID parameter to guild state setup method
-Add EntityCache support to ban and kick methods in ModuleBase
-EntryRole waiting list now preserved between state reloads
This commit is contained in:
Noikoio 2019-03-16 16:41:55 -07:00
parent 6f7ffda63b
commit c843104e3c
6 changed files with 35 additions and 22 deletions

View file

@ -43,11 +43,12 @@ namespace Kerobot
/// Called when a guild becomes available. The implementing class should construct an object to hold
/// data specific to the corresponding guild for use during runtime.
/// </summary>
/// <param name="guildID">Corresponding guild ID for the state data being used. Can be useful when reloading.</param>
/// <param name="config">JSON token holding module configuration specific to this guild.</param>
/// <returns>
/// An object containing state and/or configuration information for the guild currently being processed.
/// </returns>
public abstract Task<object> CreateGuildStateAsync(JToken config);
public abstract Task<object> CreateGuildStateAsync(ulong guildID, JToken config);
/// <summary>
/// Retrieves the state object that corresponds with the given guild.
@ -98,10 +99,11 @@ namespace Kerobot
/// EntityCache lookup to determine the target.
/// </summary>
/// <param name="targetSearch">The EntityCache search string.</param>
protected Task<BanKickResult> BanAsync(SocketGuild guild, SocketGuildUser source, string targetSearch, string reason, string dmMsg)
protected async Task<BanKickResult> BanAsync(SocketGuild guild, string source, string targetSearch, int purgeDays, string reason, string dmMsg)
{
// TODO requires EntityCache lookup. Do this when that feature gets implemented.
throw new NotImplementedException();
var result = await Kerobot.EcQueryUser(guild.Id, targetSearch);
if (result == null) return new BanKickResult(null, false, true);
return await BanAsync(guild, source, result.UserID, purgeDays, reason, dmMsg);
}
/// <summary>
@ -126,10 +128,11 @@ namespace Kerobot
/// EntityCache lookup to determine the target.
/// </summary>
/// <param name="targetSearch">The EntityCache search string.</param>
protected Task<BanKickResult> KickAsync(SocketGuild guild, string source, string targetSearch, string reason, string dmMsg)
protected async Task<BanKickResult> KickAsync(SocketGuild guild, string source, string targetSearch, string reason, string dmMsg)
{
// TODO requires EntityCache lookup. Do this when that feature gets implemented.
throw new NotImplementedException();
var result = await Kerobot.EcQueryUser(guild.Id, targetSearch);
if (result == null) return new BanKickResult(null, false, true);
return await KickAsync(guild, source, result.UserID, reason, dmMsg);
}
}

View file

@ -1,9 +1,9 @@
using System;
using Discord.Net;
using Discord.Net;
namespace Kerobot
{
// Instances created by CommonFunctionService, but are meant to be sent to modules. Hence its namespace.
// Instances of this are created by CommonFunctionService and by ModuleBase on behalf of CommonFunctionService,
// and are meant to be sent to modules. This class has therefore been put within the Kerobot namespace.
/// <summary>
/// Contains information on various success/failure outcomes for a ban or kick operation.
@ -12,17 +12,23 @@ namespace Kerobot
{
private readonly bool _userNotFound;
internal BanKickResult(HttpException error, bool notifySuccess, bool errorNotFound)
internal BanKickResult(HttpException error, bool notificationSuccess, bool errorNotFound)
{
OperationError = error;
MessageSendSuccess = notifySuccess;
MessageSendSuccess = notificationSuccess;
_userNotFound = errorNotFound;
}
/// <summary>
/// Gets a value indicating whether the kick or ban succeeded.
/// </summary>
public bool OperationSuccess { get => OperationError == null; }
public bool OperationSuccess {
get {
if (ErrorNotFound) return false;
if (OperationError == null) return false;
return true;
}
}
/// <summary>
/// The exception thrown, if any, when attempting to kick or ban the target.

View file

@ -130,7 +130,7 @@ namespace Kerobot.Services.GuildState
object state;
try
{
state = await mod.CreateGuildStateAsync(guildConf[tn]); // can be null
state = await mod.CreateGuildStateAsync(guildId, guildConf[tn]); // can be null
}
catch (Exception ex)
{

View file

@ -35,7 +35,7 @@ namespace Kerobot.Modules.AutoResponder
await Task.WhenAll(tasks);
}
public override Task<object> CreateGuildStateAsync(JToken config)
public override Task<object> CreateGuildStateAsync(ulong guild, JToken config)
{
// Guild state is a read-only IEnumerable<Definition>
if (config == null) return null;

View file

@ -40,17 +40,17 @@ namespace Kerobot.Modules.EntryRole
return Task.CompletedTask;
}
public override Task<object> CreateGuildStateAsync(JToken config)
public override Task<object> CreateGuildStateAsync(ulong guildID, JToken config)
{
if (config == null) return null;
// preserve previously running timers?
// research: can GetState be called here or is it undefined?
if (config.Type != JTokenType.Object)
throw new ModuleLoadException("Configuration is not properly defined.");
return Task.FromResult<object>(new GuildData((JObject)config));
// Attempt to preserve existing timer list on reload
var oldconf = GetGuildState<GuildData>(guildID);
if (oldconf == null) return Task.FromResult<object>(new GuildData((JObject)config));
else return Task.FromResult<object>(new GuildData((JObject)config, oldconf.WaitingList));
}
/// <summary>
@ -79,7 +79,7 @@ namespace Kerobot.Modules.EntryRole
var gconf = GetGuildState<GuildData>(g.Id);
if (gconf == null) return;
// Get users to be affected
// Get list of users to be affected
ulong[] userIds;
lock (gconf.WaitingList)
{

View file

@ -26,8 +26,12 @@ namespace Kerobot.Modules.EntryRole
const int WaitTimeMax = 600; // 10 minutes
public GuildData(JObject conf)
public GuildData(JObject conf) : this(conf, new Dictionary<ulong, DateTimeOffset>()) { }
public GuildData(JObject conf, Dictionary<ulong, DateTimeOffset> _waitingList)
{
WaitingList = _waitingList;
var cfgRole = conf["Role"]?.Value<string>();
if (string.IsNullOrWhiteSpace(cfgRole))
throw new ModuleLoadException("Role value not specified.");