Organized class files, names
This commit is contained in:
parent
120f31a88b
commit
3ff2ef28f0
12 changed files with 52 additions and 54 deletions
|
@ -1,6 +1,5 @@
|
||||||
using Discord.WebSocket;
|
using Discord.WebSocket;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using Noikoio.RegexBot.Feature.AutoMod.Responses;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -28,12 +27,12 @@ namespace Noikoio.RegexBot.Feature.AutoMod
|
||||||
[ConfigSection("automod")]
|
[ConfigSection("automod")]
|
||||||
public override async Task<object> ProcessConfiguration(JToken configSection)
|
public override async Task<object> ProcessConfiguration(JToken configSection)
|
||||||
{
|
{
|
||||||
List<Rule> rules = new List<Rule>();
|
List<ConfigItem> rules = new List<ConfigItem>();
|
||||||
|
|
||||||
foreach (var def in configSection.Children<JProperty>())
|
foreach (var def in configSection.Children<JProperty>())
|
||||||
{
|
{
|
||||||
string label = def.Name;
|
string label = def.Name;
|
||||||
var rule = new Rule(this, def);
|
var rule = new ConfigItem(this, def);
|
||||||
rules.Add(rule);
|
rules.Add(rule);
|
||||||
}
|
}
|
||||||
if (rules.Count > 0)
|
if (rules.Count > 0)
|
||||||
|
@ -56,12 +55,12 @@ namespace Noikoio.RegexBot.Feature.AutoMod
|
||||||
if (ch == null) return;
|
if (ch == null) return;
|
||||||
|
|
||||||
// Get rules
|
// Get rules
|
||||||
var rules = GetConfig(ch.Guild.Id) as IEnumerable<Rule>;
|
var rules = GetConfig(ch.Guild.Id) as IEnumerable<ConfigItem>;
|
||||||
if (rules == null) return;
|
if (rules == null) return;
|
||||||
|
|
||||||
foreach (var rule in rules)
|
foreach (var rule in rules)
|
||||||
{
|
{
|
||||||
// Checking for mod bypass here (Rule.Match isn't able to access mod list)
|
// Checking for mod bypass here (ConfigItem.Match isn't able to access mod list)
|
||||||
bool isMod = IsModerator(ch.Guild.Id, m);
|
bool isMod = IsModerator(ch.Guild.Id, m);
|
||||||
await Task.Run(async () => await ProcessMessage(m, rule, isMod));
|
await Task.Run(async () => await ProcessMessage(m, rule, isMod));
|
||||||
}
|
}
|
||||||
|
@ -70,14 +69,14 @@ namespace Noikoio.RegexBot.Feature.AutoMod
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if the incoming message matches the given rule, and executes responses if necessary.
|
/// Checks if the incoming message matches the given rule, and executes responses if necessary.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private async Task ProcessMessage(SocketMessage m, Rule r, bool isMod)
|
private async Task ProcessMessage(SocketMessage m, ConfigItem r, bool isMod)
|
||||||
{
|
{
|
||||||
if (!r.Match(m, isMod)) return;
|
if (!r.Match(m, isMod)) return;
|
||||||
|
|
||||||
// TODO make log optional; configurable
|
// TODO make log optional; configurable
|
||||||
await Log($"{r} triggered by {m.Author} in {((SocketGuildChannel)m.Channel).Guild.Name}/#{m.Channel.Name}");
|
await Log($"{r} triggered by {m.Author} in {((SocketGuildChannel)m.Channel).Guild.Name}/#{m.Channel.Name}");
|
||||||
|
|
||||||
foreach (Response resp in r.Response)
|
foreach (ResponseBase resp in r.Response)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
using Discord.WebSocket;
|
using Discord.WebSocket;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using Noikoio.RegexBot.ConfigItem;
|
using Noikoio.RegexBot.ConfigItem;
|
||||||
using Noikoio.RegexBot.Feature.AutoMod.Responses;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
@ -15,12 +14,12 @@ namespace Noikoio.RegexBot.Feature.AutoMod
|
||||||
/// Representation of a single AutoMod rule.
|
/// Representation of a single AutoMod rule.
|
||||||
/// Data stored within cannot be edited.
|
/// Data stored within cannot be edited.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class Rule
|
class ConfigItem
|
||||||
{
|
{
|
||||||
readonly AutoMod _instance;
|
readonly AutoMod _instance;
|
||||||
readonly string _label;
|
readonly string _label;
|
||||||
readonly IEnumerable<Regex> _regex;
|
readonly IEnumerable<Regex> _regex;
|
||||||
readonly ICollection<Response> _responses;
|
readonly ICollection<ResponseBase> _responses;
|
||||||
readonly FilterList _filter;
|
readonly FilterList _filter;
|
||||||
readonly int _msgMinLength;
|
readonly int _msgMinLength;
|
||||||
readonly int _msgMaxLength;
|
readonly int _msgMaxLength;
|
||||||
|
@ -29,7 +28,7 @@ namespace Noikoio.RegexBot.Feature.AutoMod
|
||||||
|
|
||||||
public string Label => _label;
|
public string Label => _label;
|
||||||
public IEnumerable<Regex> Regex => _regex;
|
public IEnumerable<Regex> Regex => _regex;
|
||||||
public ICollection<Response> Response => _responses;
|
public ICollection<ResponseBase> Response => _responses;
|
||||||
public FilterList Filter => _filter;
|
public FilterList Filter => _filter;
|
||||||
public (int?, int?) MatchLengthMinMaxLimit => (_msgMinLength, _msgMaxLength);
|
public (int?, int?) MatchLengthMinMaxLimit => (_msgMinLength, _msgMaxLength);
|
||||||
public bool AllowsModBypass => _modBypass;
|
public bool AllowsModBypass => _modBypass;
|
||||||
|
@ -41,7 +40,7 @@ namespace Noikoio.RegexBot.Feature.AutoMod
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new Rule instance to represent the given configuration.
|
/// Creates a new Rule instance to represent the given configuration.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Rule(AutoMod instance, JProperty definition)
|
public ConfigItem(AutoMod instance, JProperty definition)
|
||||||
{
|
{
|
||||||
_instance = instance;
|
_instance = instance;
|
||||||
|
|
||||||
|
@ -123,11 +122,11 @@ namespace Noikoio.RegexBot.Feature.AutoMod
|
||||||
{
|
{
|
||||||
if (rsconf.Type == JTokenType.Array)
|
if (rsconf.Type == JTokenType.Array)
|
||||||
{
|
{
|
||||||
_responses = Responses.Response.ReadConfiguration(this, rsconf.Values<string>());
|
_responses = ResponseBase.ReadConfiguration(this, rsconf.Values<string>());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_responses = Responses.Response.ReadConfiguration(this, new string[] { rsconf.Value<string>() });
|
_responses = ResponseBase.ReadConfiguration(this, new string[] { rsconf.Value<string>() });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (RuleImportException ex)
|
catch (RuleImportException ex)
|
|
@ -7,19 +7,19 @@ using System.Collections.ObjectModel;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Noikoio.RegexBot.Feature.AutoMod.Responses
|
namespace Noikoio.RegexBot.Feature.AutoMod
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Base class for all Response classes.
|
/// Base class for all Response classes.
|
||||||
/// Contains helper methods for use by response code.
|
/// Contains helper methods for use by response code.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DebuggerDisplay("Response: {_cmdline}")]
|
[DebuggerDisplay("Response: {_cmdline}")]
|
||||||
abstract class Response
|
abstract class ResponseBase
|
||||||
{
|
{
|
||||||
private readonly Rule _rule;
|
private readonly ConfigItem _rule;
|
||||||
private readonly string _cmdline;
|
private readonly string _cmdline;
|
||||||
|
|
||||||
protected Rule Rule => _rule;
|
protected ConfigItem Rule => _rule;
|
||||||
private DiscordSocketClient Client => _rule.Discord;
|
private DiscordSocketClient Client => _rule.Discord;
|
||||||
public string CmdLine => _cmdline;
|
public string CmdLine => _cmdline;
|
||||||
public string CmdArg0 {
|
public string CmdArg0 {
|
||||||
|
@ -33,7 +33,7 @@ namespace Noikoio.RegexBot.Feature.AutoMod.Responses
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deriving constructor should do validation of incoming <paramref name="cmdline"/>.
|
/// Deriving constructor should do validation of incoming <paramref name="cmdline"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Response(Rule rule, string cmdline)
|
public ResponseBase(ConfigItem rule, string cmdline)
|
||||||
{
|
{
|
||||||
_rule = rule;
|
_rule = rule;
|
||||||
_cmdline = cmdline;
|
_cmdline = cmdline;
|
||||||
|
@ -54,23 +54,23 @@ namespace Noikoio.RegexBot.Feature.AutoMod.Responses
|
||||||
new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase)
|
new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase)
|
||||||
{
|
{
|
||||||
// Define all accepted commands and their corresponding types here
|
// Define all accepted commands and their corresponding types here
|
||||||
{ "say", typeof(Say) },
|
{ "ban", typeof(Responses.Ban) },
|
||||||
{ "send", typeof(Say) },
|
{ "kick", typeof(Responses.Kick) },
|
||||||
{ "report", typeof(Report) },
|
{ "say", typeof(Responses.Say) },
|
||||||
{ "addrole", typeof(RoleManipulation) },
|
{ "send", typeof(Responses.Say) },
|
||||||
{ "grantrole", typeof(RoleManipulation) },
|
{ "delete", typeof(Responses.Remove) },
|
||||||
{ "delrole", typeof(RoleManipulation) },
|
{ "remove", typeof(Responses.Remove) },
|
||||||
{ "removerole", typeof(RoleManipulation) },
|
{ "report", typeof(Responses.Report) },
|
||||||
{ "revokerole", typeof(RoleManipulation) },
|
{ "addrole", typeof(Responses.RoleManipulation) },
|
||||||
{ "delete", typeof(Remove) },
|
{ "grantrole", typeof(Responses.RoleManipulation) },
|
||||||
{ "remove", typeof(Remove) },
|
{ "delrole", typeof(Responses.RoleManipulation) },
|
||||||
{ "kick", typeof(Kick) },
|
{ "removerole", typeof(Responses.RoleManipulation) },
|
||||||
{ "ban", typeof(Ban) }
|
{ "revokerole", typeof(Responses.RoleManipulation) }
|
||||||
});
|
});
|
||||||
|
|
||||||
public static Response[] ReadConfiguration(Rule r, IEnumerable<string> responses)
|
public static ResponseBase[] ReadConfiguration(ConfigItem r, IEnumerable<string> responses)
|
||||||
{
|
{
|
||||||
var result = new List<Response>();
|
var result = new List<ResponseBase>();
|
||||||
foreach (var line in responses)
|
foreach (var line in responses)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(line))
|
if (string.IsNullOrWhiteSpace(line))
|
||||||
|
@ -84,7 +84,7 @@ namespace Noikoio.RegexBot.Feature.AutoMod.Responses
|
||||||
if (!_commands.TryGetValue(basecmd, out rt))
|
if (!_commands.TryGetValue(basecmd, out rt))
|
||||||
throw new RuleImportException($"'{basecmd}' is not a valid response");
|
throw new RuleImportException($"'{basecmd}' is not a valid response");
|
||||||
|
|
||||||
var newresponse = Activator.CreateInstance(rt, r, line) as Response;
|
var newresponse = Activator.CreateInstance(rt, r, line) as ResponseBase;
|
||||||
if (newresponse == null)
|
if (newresponse == null)
|
||||||
throw new Exception("An unknown error occurred when attempting to create a new Response object.");
|
throw new Exception("An unknown error occurred when attempting to create a new Response object.");
|
||||||
result.Add(newresponse);
|
result.Add(newresponse);
|
|
@ -9,11 +9,11 @@ namespace Noikoio.RegexBot.Feature.AutoMod.Responses
|
||||||
/// Bans the invoking user.
|
/// Bans the invoking user.
|
||||||
/// Parameters: ban [days = 0]
|
/// Parameters: ban [days = 0]
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class Ban : Response
|
class Ban : ResponseBase
|
||||||
{
|
{
|
||||||
readonly int _purgeDays;
|
readonly int _purgeDays;
|
||||||
|
|
||||||
public Ban(Rule rule, string cmdline) : base(rule, cmdline)
|
public Ban(ConfigItem rule, string cmdline) : base(rule, cmdline)
|
||||||
{
|
{
|
||||||
var line = cmdline.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
var line = cmdline.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
if (line.Length == 1)
|
if (line.Length == 1)
|
||||||
|
|
|
@ -9,9 +9,9 @@ namespace Noikoio.RegexBot.Feature.AutoMod.Responses
|
||||||
/// Kicks the invoking user.
|
/// Kicks the invoking user.
|
||||||
/// Takes no parameters.
|
/// Takes no parameters.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class Kick : Response
|
class Kick : ResponseBase
|
||||||
{
|
{
|
||||||
public Kick(Rule rule, string cmdline) : base(rule, cmdline)
|
public Kick(ConfigItem rule, string cmdline) : base(rule, cmdline)
|
||||||
{
|
{
|
||||||
// Throw exception if extra parameters found
|
// Throw exception if extra parameters found
|
||||||
if (cmdline.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Length > 1)
|
if (cmdline.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Length > 1)
|
||||||
|
|
|
@ -9,9 +9,9 @@ namespace Noikoio.RegexBot.Feature.AutoMod.Responses
|
||||||
/// Removes the invoking message.
|
/// Removes the invoking message.
|
||||||
/// Takes no parameters.
|
/// Takes no parameters.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class Remove : Response
|
class Remove : ResponseBase
|
||||||
{
|
{
|
||||||
public Remove(Rule rule, string cmdline) : base(rule, cmdline)
|
public Remove(ConfigItem rule, string cmdline) : base(rule, cmdline)
|
||||||
{
|
{
|
||||||
// Throw exception if extra parameters found
|
// Throw exception if extra parameters found
|
||||||
if (cmdline.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Length > 1)
|
if (cmdline.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Length > 1)
|
||||||
|
|
|
@ -12,11 +12,11 @@ namespace Noikoio.RegexBot.Feature.AutoMod.Responses
|
||||||
/// about the rule making use of this command, to the given target.
|
/// about the rule making use of this command, to the given target.
|
||||||
/// Parameters: report (target)
|
/// Parameters: report (target)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class Report : Response
|
class Report : ResponseBase
|
||||||
{
|
{
|
||||||
readonly string _target;
|
readonly string _target;
|
||||||
|
|
||||||
public Report(Rule rule, string cmdline) : base(rule, cmdline)
|
public Report(ConfigItem rule, string cmdline) : base(rule, cmdline)
|
||||||
{
|
{
|
||||||
var line = cmdline.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
var line = cmdline.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
if (line.Length != 2) throw new RuleImportException("Incorrect number of parameters");
|
if (line.Length != 2) throw new RuleImportException("Incorrect number of parameters");
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace Noikoio.RegexBot.Feature.AutoMod.Responses
|
||||||
/// Manipulates a given user's role.
|
/// Manipulates a given user's role.
|
||||||
/// Parameters: (command) (target) (role ID)
|
/// Parameters: (command) (target) (role ID)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class RoleManipulation : Response
|
class RoleManipulation : ResponseBase
|
||||||
{
|
{
|
||||||
enum ManipulationType { None, Add, Remove }
|
enum ManipulationType { None, Add, Remove }
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ namespace Noikoio.RegexBot.Feature.AutoMod.Responses
|
||||||
readonly string _target;
|
readonly string _target;
|
||||||
readonly EntityName _role;
|
readonly EntityName _role;
|
||||||
|
|
||||||
public RoleManipulation(Rule rule, string cmdline) : base(rule, cmdline)
|
public RoleManipulation(ConfigItem rule, string cmdline) : base(rule, cmdline)
|
||||||
{
|
{
|
||||||
var line = cmdline.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
var line = cmdline.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
if (line.Length != 3)
|
if (line.Length != 3)
|
||||||
|
|
|
@ -9,12 +9,12 @@ namespace Noikoio.RegexBot.Feature.AutoMod.Responses
|
||||||
/// Sends a message to the given target.
|
/// Sends a message to the given target.
|
||||||
/// Parameters: say (target) (message)
|
/// Parameters: say (target) (message)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class Say : Response
|
class Say : ResponseBase
|
||||||
{
|
{
|
||||||
private readonly string _target;
|
private readonly string _target;
|
||||||
private readonly string _payload;
|
private readonly string _payload;
|
||||||
|
|
||||||
public Say(Rule rule, string cmdline) : base(rule, cmdline)
|
public Say(ConfigItem rule, string cmdline) : base(rule, cmdline)
|
||||||
{
|
{
|
||||||
var line = cmdline.Split(new char[] { ' ' }, 3, StringSplitOptions.RemoveEmptyEntries);
|
var line = cmdline.Split(new char[] { ' ' }, 3, StringSplitOptions.RemoveEmptyEntries);
|
||||||
if (line.Length != 3) throw new RuleImportException("Incorrect number of parameters.");
|
if (line.Length != 3) throw new RuleImportException("Incorrect number of parameters.");
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace Noikoio.RegexBot.Feature.AutoRespond
|
||||||
if (ch == null) return;
|
if (ch == null) return;
|
||||||
|
|
||||||
// TODO either search server by name or remove server name support entirely
|
// TODO either search server by name or remove server name support entirely
|
||||||
var defs = GetConfig(ch.Guild.Id) as IEnumerable<ResponseDefinition>;
|
var defs = GetConfig(ch.Guild.Id) as IEnumerable<ConfigItem>;
|
||||||
if (defs == null) return;
|
if (defs == null) return;
|
||||||
|
|
||||||
foreach (var def in defs)
|
foreach (var def in defs)
|
||||||
|
@ -44,11 +44,11 @@ namespace Noikoio.RegexBot.Feature.AutoRespond
|
||||||
[ConfigSection("autoresponses")]
|
[ConfigSection("autoresponses")]
|
||||||
public override async Task<object> ProcessConfiguration(JToken configSection)
|
public override async Task<object> ProcessConfiguration(JToken configSection)
|
||||||
{
|
{
|
||||||
var responses = new List<ResponseDefinition>();
|
var responses = new List<ConfigItem>();
|
||||||
foreach (var def in configSection.Children<JProperty>())
|
foreach (var def in configSection.Children<JProperty>())
|
||||||
{
|
{
|
||||||
// All validation is left to the constructor
|
// All validation is left to the constructor
|
||||||
var resp = new ResponseDefinition(def);
|
var resp = new ConfigItem(def);
|
||||||
responses.Add(resp);
|
responses.Add(resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ namespace Noikoio.RegexBot.Feature.AutoRespond
|
||||||
{
|
{
|
||||||
partial class AutoRespond
|
partial class AutoRespond
|
||||||
{
|
{
|
||||||
private async Task ProcessMessage(SocketMessage msg, ResponseDefinition def)
|
private async Task ProcessMessage(SocketMessage msg, ConfigItem def)
|
||||||
{
|
{
|
||||||
// Check filters
|
// Check filters
|
||||||
if (def.Filter.IsFiltered(msg)) return;
|
if (def.Filter.IsFiltered(msg)) return;
|
||||||
|
@ -19,8 +19,8 @@ namespace Noikoio.RegexBot.Feature.AutoRespond
|
||||||
|
|
||||||
await Log($"'{def.Label}' triggered by {msg.Author} in {((SocketGuildChannel)msg.Channel).Guild.Name}/#{msg.Channel.Name}");
|
await Log($"'{def.Label}' triggered by {msg.Author} in {((SocketGuildChannel)msg.Channel).Guild.Name}/#{msg.Channel.Name}");
|
||||||
var (type, text) = def.Response;
|
var (type, text) = def.Response;
|
||||||
if (type == ResponseDefinition.ResponseType.Reply) await ProcessReply(msg, text);
|
if (type == ConfigItem.ResponseType.Reply) await ProcessReply(msg, text);
|
||||||
else if (type == ResponseDefinition.ResponseType.Exec) await ProcessExec(msg, text);
|
else if (type == ConfigItem.ResponseType.Exec) await ProcessExec(msg, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ProcessReply(SocketMessage msg, string text)
|
private async Task ProcessReply(SocketMessage msg, string text)
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace Noikoio.RegexBot.Feature.AutoRespond
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a single autoresponse definition.
|
/// Represents a single autoresponse definition.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class ResponseDefinition
|
class ConfigItem
|
||||||
{
|
{
|
||||||
public enum ResponseType { None, Exec, Reply }
|
public enum ResponseType { None, Exec, Reply }
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ namespace Noikoio.RegexBot.Feature.AutoRespond
|
||||||
public FilterList Filter => _filter;
|
public FilterList Filter => _filter;
|
||||||
public RateLimitCache RateLimit => _limit;
|
public RateLimitCache RateLimit => _limit;
|
||||||
|
|
||||||
public ResponseDefinition(JProperty definition)
|
public ConfigItem(JProperty definition)
|
||||||
{
|
{
|
||||||
_label = definition.Name;
|
_label = definition.Name;
|
||||||
var data = (JObject)definition.Value;
|
var data = (JObject)definition.Value;
|
Loading…
Reference in a new issue