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 /// 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. /// data specific to the corresponding guild for use during runtime.
/// </summary> /// </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> /// <param name="config">JSON token holding module configuration specific to this guild.</param>
/// <returns> /// <returns>
/// An object containing state and/or configuration information for the guild currently being processed. /// An object containing state and/or configuration information for the guild currently being processed.
/// </returns> /// </returns>
public abstract Task<object> CreateGuildStateAsync(JToken config); public abstract Task<object> CreateGuildStateAsync(ulong guildID, JToken config);
/// <summary> /// <summary>
/// Retrieves the state object that corresponds with the given guild. /// Retrieves the state object that corresponds with the given guild.
@ -98,10 +99,11 @@ namespace Kerobot
/// EntityCache lookup to determine the target. /// EntityCache lookup to determine the target.
/// </summary> /// </summary>
/// <param name="targetSearch">The EntityCache search string.</param> /// <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. var result = await Kerobot.EcQueryUser(guild.Id, targetSearch);
throw new NotImplementedException(); if (result == null) return new BanKickResult(null, false, true);
return await BanAsync(guild, source, result.UserID, purgeDays, reason, dmMsg);
} }
/// <summary> /// <summary>
@ -126,10 +128,11 @@ namespace Kerobot
/// EntityCache lookup to determine the target. /// EntityCache lookup to determine the target.
/// </summary> /// </summary>
/// <param name="targetSearch">The EntityCache search string.</param> /// <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. var result = await Kerobot.EcQueryUser(guild.Id, targetSearch);
throw new NotImplementedException(); 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 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> /// <summary>
/// Contains information on various success/failure outcomes for a ban or kick operation. /// Contains information on various success/failure outcomes for a ban or kick operation.
@ -12,17 +12,23 @@ namespace Kerobot
{ {
private readonly bool _userNotFound; private readonly bool _userNotFound;
internal BanKickResult(HttpException error, bool notifySuccess, bool errorNotFound) internal BanKickResult(HttpException error, bool notificationSuccess, bool errorNotFound)
{ {
OperationError = error; OperationError = error;
MessageSendSuccess = notifySuccess; MessageSendSuccess = notificationSuccess;
_userNotFound = errorNotFound; _userNotFound = errorNotFound;
} }
/// <summary> /// <summary>
/// Gets a value indicating whether the kick or ban succeeded. /// Gets a value indicating whether the kick or ban succeeded.
/// </summary> /// </summary>
public bool OperationSuccess { get => OperationError == null; } public bool OperationSuccess {
get {
if (ErrorNotFound) return false;
if (OperationError == null) return false;
return true;
}
}
/// <summary> /// <summary>
/// The exception thrown, if any, when attempting to kick or ban the target. /// 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; object state;
try try
{ {
state = await mod.CreateGuildStateAsync(guildConf[tn]); // can be null state = await mod.CreateGuildStateAsync(guildId, guildConf[tn]); // can be null
} }
catch (Exception ex) catch (Exception ex)
{ {

View file

@ -35,7 +35,7 @@ namespace Kerobot.Modules.AutoResponder
await Task.WhenAll(tasks); 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> // Guild state is a read-only IEnumerable<Definition>
if (config == null) return null; if (config == null) return null;

View file

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

View file

@ -26,8 +26,12 @@ namespace Kerobot.Modules.EntryRole
const int WaitTimeMax = 600; // 10 minutes 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>(); var cfgRole = conf["Role"]?.Value<string>();
if (string.IsNullOrWhiteSpace(cfgRole)) if (string.IsNullOrWhiteSpace(cfgRole))
throw new ModuleLoadException("Role value not specified."); throw new ModuleLoadException("Role value not specified.");