Redesigned the DiscordBotCore by splitting it into multiple projects. Created a WebUI and preparing to remove the DiscordBot application
This commit is contained in:
113
DiscordBotCore.Configuration/Configuration.cs
Normal file
113
DiscordBotCore.Configuration/Configuration.cs
Normal file
@@ -0,0 +1,113 @@
|
||||
using DiscordBotCore.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace DiscordBotCore.Configuration;
|
||||
|
||||
public class Configuration : ConfigurationBase
|
||||
{
|
||||
private readonly bool _EnableAutoAddOnGetWithDefault;
|
||||
private Configuration(ILogger logger, string diskLocation, bool enableAutoAddOnGetWithDefault): base(logger, diskLocation)
|
||||
{
|
||||
_EnableAutoAddOnGetWithDefault = enableAutoAddOnGetWithDefault;
|
||||
}
|
||||
|
||||
public override async Task SaveToFile()
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(_InternalDictionary, Formatting.Indented);
|
||||
await File.WriteAllTextAsync(_DiskLocation, json);
|
||||
}
|
||||
|
||||
public override T Get<T>(string key, T defaultValue)
|
||||
{
|
||||
T value = base.Get(key, defaultValue);
|
||||
|
||||
if (_EnableAutoAddOnGetWithDefault && value.Equals(defaultValue))
|
||||
{
|
||||
Add(key, defaultValue);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public override List<T> GetList<T>(string key, List<T> defaultValue)
|
||||
{
|
||||
List<T> value = base.GetList(key, defaultValue);
|
||||
|
||||
if (_EnableAutoAddOnGetWithDefault && value.All(defaultValue.Contains))
|
||||
{
|
||||
Add(key, defaultValue);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public override async void LoadFromFile()
|
||||
{
|
||||
if (!File.Exists(_DiskLocation))
|
||||
{
|
||||
await SaveToFile();
|
||||
return;
|
||||
}
|
||||
|
||||
string jsonContent = await File.ReadAllTextAsync(_DiskLocation);
|
||||
var jObject = JsonConvert.DeserializeObject<JObject>(jsonContent);
|
||||
|
||||
if (jObject is null)
|
||||
{
|
||||
await SaveToFile();
|
||||
return;
|
||||
}
|
||||
|
||||
_InternalDictionary.Clear();
|
||||
|
||||
foreach (var kvp in jObject)
|
||||
{
|
||||
AddPairToDictionary(kvp, _InternalDictionary);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddPairToDictionary(KeyValuePair<string, JToken> kvp, IDictionary<string, object> dict)
|
||||
{
|
||||
if (kvp.Value is JObject nestedJObject)
|
||||
{
|
||||
dict[kvp.Key] = nestedJObject.ToObject<Dictionary<string, object>>();
|
||||
|
||||
foreach (var nestedKvp in nestedJObject)
|
||||
{
|
||||
AddPairToDictionary(nestedKvp, dict[kvp.Key] as Dictionary<string, object>);
|
||||
}
|
||||
}
|
||||
else if (kvp.Value is JArray nestedJArray)
|
||||
{
|
||||
dict[kvp.Key] = nestedJArray.ToObject<List<object>>();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (kvp.Value.Type == JTokenType.Integer)
|
||||
dict[kvp.Key] = kvp.Value.Value<int>();
|
||||
else if (kvp.Value.Type == JTokenType.Float)
|
||||
dict[kvp.Key] = kvp.Value.Value<float>();
|
||||
else if (kvp.Value.Type == JTokenType.Boolean)
|
||||
dict[kvp.Key] = kvp.Value.Value<bool>();
|
||||
else if (kvp.Value.Type == JTokenType.String)
|
||||
dict[kvp.Key] = kvp.Value.Value<string>();
|
||||
else if (kvp.Value.Type == JTokenType.Date)
|
||||
dict[kvp.Key] = kvp.Value.Value<DateTime>();
|
||||
else
|
||||
dict[kvp.Key] = kvp.Value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new Settings Dictionary from a file
|
||||
/// </summary>
|
||||
/// <param name="baseFile">The file location</param>
|
||||
/// <param name="enableAutoAddOnGetWithDefault">Set this to true if you want to update the dictionary with default values on get</param>
|
||||
public static Configuration CreateFromFile(ILogger logger, string baseFile, bool enableAutoAddOnGetWithDefault)
|
||||
{
|
||||
var settings = new Configuration(logger, baseFile, enableAutoAddOnGetWithDefault);
|
||||
settings.LoadFromFile();
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
167
DiscordBotCore.Configuration/ConfigurationBase.cs
Normal file
167
DiscordBotCore.Configuration/ConfigurationBase.cs
Normal file
@@ -0,0 +1,167 @@
|
||||
using System.Collections;
|
||||
using System.Net.Mime;
|
||||
using DiscordBotCore.Logging;
|
||||
|
||||
namespace DiscordBotCore.Configuration;
|
||||
|
||||
public abstract class ConfigurationBase : IConfiguration
|
||||
{
|
||||
protected readonly IDictionary<string, object> _InternalDictionary = new Dictionary<string, object>();
|
||||
protected readonly string _DiskLocation;
|
||||
protected readonly ILogger _Logger;
|
||||
|
||||
protected ConfigurationBase(ILogger logger, string diskLocation)
|
||||
{
|
||||
this._DiskLocation = diskLocation;
|
||||
this._Logger = logger;
|
||||
}
|
||||
|
||||
public virtual void Add(string key, object value)
|
||||
{
|
||||
if (_InternalDictionary.ContainsKey(key))
|
||||
return;
|
||||
|
||||
if (value is null)
|
||||
return;
|
||||
|
||||
_InternalDictionary.Add(key, value);
|
||||
}
|
||||
|
||||
public virtual void Set(string key, object value)
|
||||
{
|
||||
_InternalDictionary[key] = value;
|
||||
}
|
||||
|
||||
public virtual object Get(string key)
|
||||
{
|
||||
return _InternalDictionary[key];
|
||||
}
|
||||
|
||||
public virtual T Get<T>(string key, T defaulobject)
|
||||
{
|
||||
if (_InternalDictionary.TryGetValue(key, out var value))
|
||||
{
|
||||
return (T)Convert.ChangeType(value, typeof(T));
|
||||
}
|
||||
|
||||
return defaulobject;
|
||||
}
|
||||
|
||||
public virtual T? Get<T>(string key)
|
||||
{
|
||||
if (_InternalDictionary.TryGetValue(key, out var value))
|
||||
{
|
||||
return (T)Convert.ChangeType(value, typeof(T));
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
public virtual IDictionary<TSubKey, TSubValue> GetDictionary<TSubKey, TSubValue>(string key)
|
||||
{
|
||||
if (_InternalDictionary.TryGetValue(key, out var value))
|
||||
{
|
||||
if (value is not IDictionary)
|
||||
{
|
||||
throw new Exception("The value is not a dictionary");
|
||||
}
|
||||
|
||||
var dictionary = new Dictionary<TSubKey, TSubValue>();
|
||||
foreach (DictionaryEntry item in (IDictionary)value)
|
||||
{
|
||||
dictionary.Add((TSubKey)Convert.ChangeType(item.Key, typeof(TSubKey)), (TSubValue)Convert.ChangeType(item.Value, typeof(TSubValue)));
|
||||
}
|
||||
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
return new Dictionary<TSubKey, TSubValue>();
|
||||
}
|
||||
|
||||
public virtual List<T> GetList<T>(string key, List<T> defaulobject)
|
||||
{
|
||||
if(_InternalDictionary.TryGetValue(key, out var value))
|
||||
{
|
||||
if (value is not IList)
|
||||
{
|
||||
throw new Exception("The value is not a list");
|
||||
}
|
||||
|
||||
var list = new List<T>();
|
||||
foreach (object? item in (IList)value)
|
||||
{
|
||||
list.Add((T)Convert.ChangeType(item, typeof(T)));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
_Logger.Log($"Key '{key}' not found in settings dictionary. Adding default value.", LogType.Warning);
|
||||
|
||||
return defaulobject;
|
||||
}
|
||||
|
||||
public virtual void Remove(string key)
|
||||
{
|
||||
_InternalDictionary.Remove(key);
|
||||
}
|
||||
|
||||
public virtual IEnumerator<KeyValuePair<string, object>> GetEnumerator()
|
||||
{
|
||||
return _InternalDictionary.GetEnumerator();
|
||||
}
|
||||
|
||||
public virtual void Clear()
|
||||
{
|
||||
_InternalDictionary.Clear();
|
||||
}
|
||||
|
||||
public virtual bool ContainsKey(string key)
|
||||
{
|
||||
return _InternalDictionary.ContainsKey(key);
|
||||
}
|
||||
|
||||
public virtual IEnumerable<KeyValuePair<string, object>> Where(Func<KeyValuePair<string, object>, bool> predicate)
|
||||
{
|
||||
return _InternalDictionary.Where(predicate);
|
||||
}
|
||||
|
||||
public virtual IEnumerable<KeyValuePair<string, object>> Where(Func<KeyValuePair<string, object>, int, bool> predicate)
|
||||
{
|
||||
return _InternalDictionary.Where(predicate);
|
||||
}
|
||||
|
||||
public virtual IEnumerable<TResult> Where<TResult>(Func<KeyValuePair<string, object>, TResult> selector)
|
||||
{
|
||||
return _InternalDictionary.Select(selector);
|
||||
}
|
||||
|
||||
public virtual IEnumerable<TResult> Where<TResult>(Func<KeyValuePair<string, object>, int, TResult> selector)
|
||||
{
|
||||
return _InternalDictionary.Select(selector);
|
||||
}
|
||||
|
||||
public virtual KeyValuePair<string, object> FirstOrDefault(Func<KeyValuePair<string, object>, bool> predicate)
|
||||
{
|
||||
return _InternalDictionary.FirstOrDefault(predicate);
|
||||
}
|
||||
|
||||
public virtual KeyValuePair<string, object> FirstOrDefault()
|
||||
{
|
||||
return _InternalDictionary.FirstOrDefault();
|
||||
}
|
||||
|
||||
public virtual bool ContainsAllKeys(params string[] keys)
|
||||
{
|
||||
return keys.All(ContainsKey);
|
||||
}
|
||||
|
||||
public virtual bool TryGetValue(string key, out object? value)
|
||||
{
|
||||
return _InternalDictionary.TryGetValue(key, out value);
|
||||
}
|
||||
|
||||
public abstract Task SaveToFile();
|
||||
|
||||
public abstract void LoadFromFile();
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DiscordBotCore.Logging\DiscordBotCore.Logging.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
132
DiscordBotCore.Configuration/IConfiguration.cs
Normal file
132
DiscordBotCore.Configuration/IConfiguration.cs
Normal file
@@ -0,0 +1,132 @@
|
||||
namespace DiscordBotCore.Configuration;
|
||||
|
||||
public interface IConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds an element to the custom settings dictionary
|
||||
/// </summary>
|
||||
/// <param name="key">The key</param>
|
||||
/// <param name="value">The value</param>
|
||||
void Add(string key, object value);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value of a key in the custom settings dictionary
|
||||
/// </summary>
|
||||
/// <param name="key">The key</param>
|
||||
/// <param name="value">The value</param>
|
||||
void Set(string key, object value);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of a key in the custom settings dictionary. If the T type is different then the object type, it will try to convert it.
|
||||
/// </summary>
|
||||
/// <param name="key">The key</param>
|
||||
/// <param name="defaulobject">The default value to be returned if the searched value is not found</param>
|
||||
/// <typeparam name="T">The type of the returned value</typeparam>
|
||||
/// <returns></returns>
|
||||
T Get<T>(string key, T defaulobject);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of a key in the custom settings dictionary. If the T type is different then the object type, it will try to convert it.
|
||||
/// </summary>
|
||||
/// <param name="key">The key</param>
|
||||
/// <typeparam name="T">The type of the returned value</typeparam>
|
||||
/// <returns></returns>
|
||||
T? Get<T>(string key);
|
||||
|
||||
/// <summary>
|
||||
/// Get a list of values from the custom settings dictionary
|
||||
/// </summary>
|
||||
/// <param name="key">The key</param>
|
||||
/// <param name="defaulobject">The default list to be returned if nothing is found</param>
|
||||
/// <typeparam name="T">The type of the returned value</typeparam>
|
||||
/// <returns></returns>
|
||||
List<T> GetList<T>(string key, List<T> defaulobject);
|
||||
|
||||
/// <summary>
|
||||
/// Remove a key from the custom settings dictionary
|
||||
/// </summary>
|
||||
/// <param name="key">The key</param>
|
||||
void Remove(string key);
|
||||
|
||||
/// <summary>
|
||||
/// Get the enumerator of the custom settings dictionary
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IEnumerator<KeyValuePair<string, object>> GetEnumerator();
|
||||
|
||||
/// <summary>
|
||||
/// Clear the custom settings dictionary
|
||||
/// </summary>
|
||||
void Clear();
|
||||
|
||||
/// <summary>
|
||||
/// Check if the custom settings dictionary contains a key
|
||||
/// </summary>
|
||||
/// <param name="key">The key</param>
|
||||
/// <returns></returns>
|
||||
bool ContainsKey(string key);
|
||||
|
||||
/// <summary>
|
||||
/// Filter the custom settings dictionary based on a predicate
|
||||
/// </summary>
|
||||
/// <param name="predicate">The predicate</param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<KeyValuePair<string, object>> Where(Func<KeyValuePair<string, object>, bool> predicate);
|
||||
|
||||
/// <summary>
|
||||
/// Filter the custom settings dictionary based on a predicate
|
||||
/// </summary>
|
||||
/// <param name="predicate">The predicate</param>
|
||||
IEnumerable<KeyValuePair<string, object>> Where(Func<KeyValuePair<string, object>, int, bool> predicate);
|
||||
|
||||
/// <summary>
|
||||
/// Filter the custom settings dictionary based on a predicate
|
||||
/// </summary>
|
||||
/// <param name="selector">The predicate</param>
|
||||
IEnumerable<TResult> Where<TResult>(Func<KeyValuePair<string, object>, TResult> selector);
|
||||
|
||||
/// <summary>
|
||||
/// Filter the custom settings dictionary based on a predicate
|
||||
/// </summary>
|
||||
/// <param name="selector">The predicate</param>
|
||||
IEnumerable<TResult> Where<TResult>(Func<KeyValuePair<string, object>, int, TResult> selector);
|
||||
|
||||
/// <summary>
|
||||
/// Get the first element of the custom settings dictionary based on a predicate
|
||||
/// </summary>
|
||||
/// <param name="predicate">The predicate</param>
|
||||
KeyValuePair<string, object> FirstOrDefault(Func<KeyValuePair<string, object>, bool> predicate);
|
||||
|
||||
/// <summary>
|
||||
/// Get the first element of the custom settings dictionary
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
KeyValuePair<string, object> FirstOrDefault();
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the custom settings dictionary contains all the keys
|
||||
/// </summary>
|
||||
/// <param name="keys">A list of keys</param>
|
||||
/// <returns></returns>
|
||||
bool ContainsAllKeys(params string[] keys);
|
||||
|
||||
/// <summary>
|
||||
/// Try to get the value of a key in the custom settings dictionary
|
||||
/// </summary>
|
||||
/// <param name="key">The key</param>
|
||||
/// <param name="value">The value</param>
|
||||
/// <returns></returns>
|
||||
bool TryGetValue(string key, out object? value);
|
||||
|
||||
/// <summary>
|
||||
/// Save the custom settings dictionary to a file
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task SaveToFile();
|
||||
|
||||
/// <summary>
|
||||
/// Load the custom settings dictionary from a file
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
void LoadFromFile();
|
||||
}
|
||||
Reference in New Issue
Block a user