2022-07-21 01:55:08 +00:00
|
|
|
|
using System.Collections;
|
2018-09-02 04:33:02 +00:00
|
|
|
|
|
2022-03-29 05:03:01 +00:00
|
|
|
|
namespace RegexBot.Common;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Represents a commonly-used configuration structure: an array of strings consisting of <see cref="EntityName"/> values.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class EntityList : IEnumerable<EntityName> {
|
|
|
|
|
private readonly IReadOnlyCollection<EntityName> _innerList;
|
2018-09-02 04:33:02 +00:00
|
|
|
|
|
2022-03-29 05:03:01 +00:00
|
|
|
|
/// <summary>Gets an enumerable collection of all role names defined in this list.</summary>
|
|
|
|
|
public IEnumerable<EntityName> Roles
|
|
|
|
|
=> _innerList.Where(n => n.Type == EntityType.Role);
|
2018-09-02 04:33:02 +00:00
|
|
|
|
|
2022-03-29 05:03:01 +00:00
|
|
|
|
/// <summary>Gets an enumerable collection of all channel names defined in this list.</summary>
|
|
|
|
|
public IEnumerable<EntityName> Channels
|
|
|
|
|
=> _innerList.Where(n => n.Type == EntityType.Channel);
|
2018-09-02 04:33:02 +00:00
|
|
|
|
|
2022-03-29 05:03:01 +00:00
|
|
|
|
/// <summary>Gets an enumerable collection of all user names defined in this list.</summary>
|
|
|
|
|
public IEnumerable<EntityName> Users
|
|
|
|
|
=> _innerList.Where(n => n.Type == EntityType.User);
|
2018-09-02 04:33:02 +00:00
|
|
|
|
|
2022-03-29 05:03:01 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Creates a new EntityList instance with no data.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public EntityList() : this(null, false) { }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Creates a new EntityList instance using the given JSON token as input.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="input">JSON array to be used for input. For ease of use, null values are also accepted.</param>
|
|
|
|
|
/// <param name="enforceTypes">Specifies if all entities defined in configuration must have their type specified.</param>
|
|
|
|
|
/// <exception cref="ArgumentException">The input is not a JSON array.</exception>
|
|
|
|
|
/// <exception cref="ArgumentNullException">
|
|
|
|
|
/// Unintiutively, this exception is thrown if a user-provided configuration value is blank.
|
|
|
|
|
/// </exception>
|
|
|
|
|
/// <exception cref="FormatException">
|
|
|
|
|
/// When enforceTypes is set, this is thrown if an EntityName results in having its Type be Unspecified.
|
|
|
|
|
/// </exception>
|
|
|
|
|
public EntityList(JToken? input, bool enforceTypes) {
|
|
|
|
|
if (input == null) {
|
|
|
|
|
_innerList = new List<EntityName>().AsReadOnly();
|
|
|
|
|
return;
|
|
|
|
|
}
|
2018-09-02 04:33:02 +00:00
|
|
|
|
|
2022-03-29 05:03:01 +00:00
|
|
|
|
if (input.Type != JTokenType.Array)
|
|
|
|
|
throw new ArgumentException("JToken input must be a JSON array.");
|
|
|
|
|
var inputArray = (JArray)input;
|
2018-09-02 04:33:02 +00:00
|
|
|
|
|
2022-03-29 05:03:01 +00:00
|
|
|
|
var list = new List<EntityName>();
|
|
|
|
|
foreach (var item in inputArray.Values<string>()) {
|
|
|
|
|
if (string.IsNullOrWhiteSpace(item)) continue;
|
|
|
|
|
var itemName = new EntityName(item);
|
|
|
|
|
if (enforceTypes && itemName.Type == EntityType.Unspecified)
|
|
|
|
|
throw new FormatException($"The following value is not prefixed: {item}");
|
|
|
|
|
list.Add(itemName);
|
2018-09-02 04:33:02 +00:00
|
|
|
|
}
|
2022-03-29 05:03:01 +00:00
|
|
|
|
_innerList = list.AsReadOnly();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Checks if the parameters of the given <see cref="SocketMessage"/> matches with
|
|
|
|
|
/// any entity specified in this list.
|
|
|
|
|
/// </summary>
|
2022-07-21 01:55:08 +00:00
|
|
|
|
/// <param name="msg">The incoming message object with which to scan for a match.</param>
|
2022-03-29 05:03:01 +00:00
|
|
|
|
/// <param name="keepId">
|
|
|
|
|
/// Specifies if EntityName instances within this list should have their internal ID value
|
|
|
|
|
/// updated if found during the matching process.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <returns>
|
|
|
|
|
/// True if the message author exists in this list, or if the message's channel exists in this list,
|
|
|
|
|
/// or if the message author contains a role that exists in this list.
|
|
|
|
|
/// </returns>
|
|
|
|
|
public bool IsListMatch(SocketMessage msg, bool keepId) {
|
|
|
|
|
var author = (SocketGuildUser)msg.Author;
|
|
|
|
|
var authorRoles = author.Roles;
|
|
|
|
|
var channel = msg.Channel;
|
|
|
|
|
|
|
|
|
|
foreach (var entry in this) {
|
|
|
|
|
if (entry.Type == EntityType.Role) {
|
|
|
|
|
if (entry.Id.HasValue) {
|
2022-07-28 01:03:12 +00:00
|
|
|
|
if (authorRoles.Any(r => r.Id == entry.Id.Value)) return true;
|
2022-03-29 05:03:01 +00:00
|
|
|
|
} else {
|
|
|
|
|
foreach (var r in authorRoles) {
|
|
|
|
|
if (!string.Equals(r.Name, entry.Name, StringComparison.OrdinalIgnoreCase)) break;
|
|
|
|
|
if (keepId) entry.SetId(r.Id);
|
2018-09-02 04:33:02 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-03-29 05:03:01 +00:00
|
|
|
|
} else if (entry.Type == EntityType.Channel) {
|
|
|
|
|
if (entry.Id.HasValue) {
|
2022-07-28 01:03:12 +00:00
|
|
|
|
if (entry.Id.Value == channel.Id) return true;
|
2022-03-29 05:03:01 +00:00
|
|
|
|
} else {
|
|
|
|
|
if (!string.Equals(channel.Name, entry.Name, StringComparison.OrdinalIgnoreCase)) break;
|
|
|
|
|
if (keepId) entry.SetId(channel.Id);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2022-07-28 01:03:12 +00:00
|
|
|
|
} else { // User
|
2022-03-29 05:03:01 +00:00
|
|
|
|
if (entry.Id.HasValue) {
|
2022-07-28 01:03:12 +00:00
|
|
|
|
if (entry.Id.Value == author.Id) return true;
|
2022-03-29 05:03:01 +00:00
|
|
|
|
} else {
|
|
|
|
|
if (!string.Equals(author.Username, entry.Name, StringComparison.OrdinalIgnoreCase)) break;
|
|
|
|
|
if (keepId) entry.SetId(author.Id);
|
|
|
|
|
return true;
|
2018-09-02 04:33:02 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-03-29 05:03:01 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2018-11-05 03:37:52 +00:00
|
|
|
|
|
2022-03-29 05:03:01 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Determines if this list contains no entries.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public bool IsEmpty() => _innerList.Count == 0;
|
2018-09-02 04:33:02 +00:00
|
|
|
|
|
2022-06-18 06:23:25 +00:00
|
|
|
|
/// <inheritdoc/>
|
2022-03-29 05:03:01 +00:00
|
|
|
|
public override string ToString() => $"Entity list contains {_innerList.Count} item(s).";
|
2018-09-02 04:33:02 +00:00
|
|
|
|
|
2022-06-18 06:23:25 +00:00
|
|
|
|
/// <inheritdoc/>
|
2022-03-29 05:03:01 +00:00
|
|
|
|
public IEnumerator<EntityName> GetEnumerator() => _innerList.GetEnumerator();
|
2018-09-02 04:33:02 +00:00
|
|
|
|
|
2022-03-29 05:03:01 +00:00
|
|
|
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
2022-07-21 01:55:08 +00:00
|
|
|
|
}
|