Remove old database and attribute system, replace with (mostly error-free, possibly and partially) working system with the new EFCore

This commit is contained in:
Daniel_I_Am 2020-08-05 01:09:56 +02:00
parent 63f688de9c
commit b8a1f91d0a
No known key found for this signature in database
GPG Key ID: 80C428FCC9743E84
40 changed files with 108 additions and 1551 deletions

View File

@ -1,124 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using ChaosBot.Database;
using NLog;
namespace ChaosBot.Attribute
{
public static class AssemblyController
{
private static ILogger _logger = Program.Logger;
public static void RegisterAll()
{
Assembly dbEntityAssembly = Assembly.GetAssembly(typeof(DBEntity));
if (dbEntityAssembly != null)
{
foreach (Type type in dbEntityAssembly.GetTypes())
{
RegisterDBEntityType(type);
}
}
}
public static void RegisterDBEntityType(Type type)
{
try
{
if (type.GetCustomAttributes(typeof(DBEntity), true).Length > 0)
{
// Get a reference to the attribute
DBEntity dbEntity = type.GetCustomAttributes(typeof(DBEntity)).Cast<DBEntity>().First();
// Generate columns
// name, type, constraintName, constraints,
List<Tuple<string, string, string, string>> columnList = new List<Tuple<string, string, string, string>>();
// Get the table as an easy variable
string table = dbEntity.Table;
// Loop through all fields
foreach (PropertyInfo prop in type.GetProperties())
{
string columnName = prop.Name;
string columnType = null;
if (prop.PropertyType.IsGenericType &&
prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
Type[] typeArguments = prop.PropertyType.GetGenericArguments();
if (typeArguments.Length == 1)
columnType = DBEntity.DataTypes.GetValueOrDefault(typeArguments[0]).ToString();
}
else
{
columnType = DBEntity.DataTypes.GetValueOrDefault(prop.PropertyType).ToString();
}
StringBuilder constraintNameBuilder = new StringBuilder($"{table}_{columnName}");
List<string> constraintsList = new List<string>();
// Go through every attribute
foreach (object fieldAttribute in prop.GetCustomAttributes(true))
{
if (fieldAttribute is DBFieldAttribute dBFieldAttribute)
{
string constraintSuffix =
DBEntity.ConstrainNames.GetValueOrDefault(dBFieldAttribute.GetType(), null);
if (constraintSuffix != null)
{
constraintNameBuilder.Append($"_{constraintSuffix}");
constraintsList.Add($"{dBFieldAttribute.GetSQLiteQuery()}");
}
}
}
string constraintName = constraintNameBuilder.ToString();
if (constraintsList.Count > 0)
{
constraintsList.Insert(0, "CONSTRAINT");
constraintsList.Insert(1, constraintName);
}
string constraints = String.Join(" ", constraintsList);
columnList.Add(
new Tuple<string, string, string, string>(columnName, columnType, constraintName, constraints));
}
// Check table exists
bool tableExists =
Controller.RawQuery($"SELECT name FROM sqlite_master WHERE type='table' AND name='{table}'")
.Rows.Count > 0;
if (!tableExists)
{
string columnDefs = String.Join(", ", columnList.Select(c => $"{c.Item1} {c.Item2} {c.Item4}"));
string query = $"CREATE TABLE {table} ({columnDefs})";
Controller.RawQuery(query, readOutput: false);
}
else
{
foreach (Tuple<string, string, string, string> column in columnList)
{
try
{
string query =
$"ALTER TABLE {table} ADD COLUMN {column.Item1} {column.Item2} {column.Item4}";
Controller.RawQuery(query, readOutput: false, throwError: true);
}
catch
{
// ignored
}
}
}
}
}
catch (Exception ex)
{
_logger.Error($"AssemblyController.Register: Exception [{ex}] thrown, <[{ex.Message}]>.");
}
}
}
}

View File

@ -1,13 +0,0 @@
using System;
namespace ChaosBot.Attribute
{
[AttributeUsage(AttributeTargets.Property)]
public class DBAutoIncrement : DBFieldAttribute
{
public override string GetSQLiteQuery()
{
return "AUTOINCREMENT";
}
}
}

View File

@ -1,49 +0,0 @@
using System;
using System.Collections.Generic;
using Microsoft.Data.Sqlite;
namespace ChaosBot.Attribute
{
[AttributeUsage(AttributeTargets.Class)]
public class DBEntity : System.Attribute
{
public readonly string Table;
// Yeah... this table does not exist elsewhere except human-readable documentation
public static readonly Dictionary<Type, SqliteType> DataTypes = new Dictionary<Type, SqliteType>
{
{typeof(bool), SqliteType.Integer},
{typeof(byte), SqliteType.Integer},
{typeof(byte[]), SqliteType.Blob},
{typeof(char), SqliteType.Text},
{typeof(DateTime), SqliteType.Text},
{typeof(DateTimeOffset), SqliteType.Text},
{typeof(Decimal), SqliteType.Text},
{typeof(Double), SqliteType.Real},
{typeof(Guid), SqliteType.Text},
{typeof(Int16), SqliteType.Integer},
{typeof(Int32), SqliteType.Integer},
{typeof(Int64), SqliteType.Integer},
{typeof(SByte), SqliteType.Integer},
{typeof(Single), SqliteType.Real},
{typeof(String), SqliteType.Text},
{typeof(TimeSpan), SqliteType.Text},
{typeof(UInt16), SqliteType.Integer},
{typeof(UInt32), SqliteType.Integer},
{typeof(UInt64), SqliteType.Integer}
};
public static readonly Dictionary<Type, string> ConstrainNames = new Dictionary<Type, string>
{
{typeof(DBNotNull), "nn"},
{typeof(DBUnique), "uq"},
{typeof(DBPrimaryKey), "pk"},
{typeof(DBAutoIncrement), "ai"},
};
public DBEntity(string table)
{
this.Table = table;
}
}
}

View File

@ -1,7 +0,0 @@
namespace ChaosBot.Attribute
{
public abstract class DBFieldAttribute : System.Attribute
{
public abstract string GetSQLiteQuery();
}
}

View File

@ -1,13 +0,0 @@
using System;
namespace ChaosBot.Attribute
{
[AttributeUsage(AttributeTargets.Property)]
public class DBNotNull : DBFieldAttribute
{
public override string GetSQLiteQuery()
{
return "NOT NULL";
}
}
}

View File

@ -1,13 +0,0 @@
using System;
namespace ChaosBot.Attribute
{
[AttributeUsage(AttributeTargets.Property)]
public class DBPrimaryKey : DBFieldAttribute
{
public override string GetSQLiteQuery()
{
return "PRIMARY KEY";
}
}
}

View File

@ -1,13 +0,0 @@
using System;
namespace ChaosBot.Attribute
{
[AttributeUsage(AttributeTargets.Property)]
public class DBUnique : DBFieldAttribute
{
public override string GetSQLiteQuery()
{
return "UNIQUE";
}
}
}

View File

@ -27,4 +27,8 @@
</None>
</ItemGroup>
<ItemGroup>
<Folder Include="WebServer\App" />
</ItemGroup>
</Project>

View File

@ -1,88 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using ChaosBot.Database.Repository;
using Microsoft.Data.Sqlite;
using Microsoft.Extensions.Configuration;
using Microsoft.VisualBasic;
using NLog;
namespace ChaosBot.Database
{
public static class Controller
{
static SqliteConnection _conn = new SqliteConnection($"Data Source={System.IO.Directory.GetCurrentDirectory()}/{ConfigurationRepository.GetValue<string>("Bot:Database")}");
private static ILogger _logger = Program.Logger;
/// <summary>
/// Run a raw query on the database
/// </summary>
/// <code>
/// string query = "TRUNCATE SomeTable";
/// Controller.RawQuery(query);
/// </code>
/// <param name="query">Raw query to execute</param>
/// <param name="readOutput">Whether to read the output and return it as a <c>DataFrame</c></param>
/// <param name="throwError">Whether to throw any exceptions or to log and shrug.</param>
/// <returns></returns>
public static DataTable RawQuery(string query, Dictionary<string, object> parameters = null, bool readOutput = true, bool throwError = false)
{
DataTable dt = new DataTable();
try
{
using (_conn)
{
// Open the SQLite connection
_conn.Open();
// Start creating the command and assign the query given
SqliteCommand cmd = _conn.CreateCommand();
cmd.CommandText = query;
// Add parameters if they exist
if (parameters != null)
{
foreach (var parameter in parameters)
{
cmd.Parameters.AddWithValue(parameter.Key, parameter.Value);
}
}
// Prepare the statement
_logger.Trace($"Database.Controller.RawQuery: Running query {cmd.CommandText}");
cmd.Prepare();
if (readOutput)
{
// output needs to be read, make a reader and fill the datatable with the data
SqliteDataReader executeReader = cmd.ExecuteReader();
dt.Load(executeReader);
}
else
{
// output does not need to be read, just run the query without reading
cmd.ExecuteNonQuery();
}
// Clean up after ourselves
_conn.Close();
}
}
catch (Exception ex)
{
if (throwError)
{
// If we throw any exception, just throw it so other code can handle it
throw;
}
// We handle the exception, log it and be done
_logger.Fatal($"Database.Controller.RawQuery: Exception [{ex}] thrown, <[{ex.Message}]>.");
}
return dt;
}
}
}

View File

@ -1,30 +0,0 @@
using System;
using System.Data;
using System.Linq;
using ChaosBot.Attribute;
using ChaosBot.Database;
namespace ChaosBot.Database.Entity
{
public abstract class BaseEntity
{
protected BaseEntity() {}
public abstract void SetFromRow(DataRow row);
protected static QueryBuilder<T> Query<T>() where T : BaseEntity, new()
{
var dbEntityAttribute = typeof(T).GetCustomAttributes(
typeof(DBEntity),
true
).FirstOrDefault() as DBEntity;
if (dbEntityAttribute != null)
{
return new QueryBuilder<T>(dbEntityAttribute.Table);
}
throw new SystemException($"Class {typeof(T)} does not have an attribute of {typeof(DBEntity)} set");
}
}
}

View File

@ -1,53 +0,0 @@
using System;
using System.Data;
using ChaosBot.Attribute;
namespace ChaosBot.Database.Entity
{
[DBEntity("CommandPermissions")]
public class CommandPermission : BaseEntity
{
[DBPrimaryKey]
[DBAutoIncrement]
[DBNotNull]
[DBUnique]
public Nullable<long> id { get; private set; }
public string type { get; private set; }
public string value { get; private set; }
public string cmd { get; private set; }
public long guildId { get; private set; }
public CommandPermission() {}
public CommandPermission(int id, string type, string value, string cmd, long guildId)
{
this.id = id;
this.type = type;
this.value = value;
this.cmd = cmd;
this.guildId = guildId;
}
public CommandPermission(string type, string value, string cmd, long guildId)
{
this.type = type;
this.value = value;
this.cmd = cmd;
this.guildId = guildId;
}
public static QueryBuilder<CommandPermission> Query()
{
return BaseEntity.Query<CommandPermission>();
}
public override void SetFromRow(DataRow row)
{
id = (long)row["id"];
type = (string)row["type"];
value = (string)row["value"];
cmd = (string)row["cmd"];
guildId = (long) row["guildid"];
}
}
}

View File

@ -1,29 +0,0 @@
using ChaosBot.Attribute;
using ChaosBot.Lodestone;
namespace ChaosBot.Database.Entity
{
[DBEntity("LodestoneCharacter")]
public class LodestoneCharacter
{
[DBUnique]
[DBPrimaryKey]
public int id { get; }
public string name { get; }
public string avatar { get; }
public LodestoneCharacter(int id, string name, string avatar)
{
this.id = id;
this.name = name;
this.avatar = avatar;
}
public LodestoneCharacter(Character character)
{
this.id = (int)character.ID;
this.name = character.Name;
this.avatar = character.Avatar;
}
}
}

View File

@ -1,18 +0,0 @@
using ChaosBot.Attribute;
namespace ChaosBot.Database.Entity
{
[DBEntity("LodestoneFreeCompany")]
public class LodestoneFreeCompany
{
[DBUnique]
public string id { get; }
public string name { get; }
public LodestoneFreeCompany(string id, string name)
{
this.id = id;
this.name = name;
}
}
}

View File

@ -1,49 +0,0 @@
using System;
using System.Data;
using ChaosBot.Attribute;
namespace ChaosBot.Database.Entity
{
[DBEntity("PointsTable")]
public class Points : BaseEntity
{
[DBPrimaryKey]
[DBAutoIncrement]
[DBNotNull]
[DBUnique]
public Nullable<long> id { get; private set; }
public long points { get; private set; }
public long userId { get; private set; }
public long guildId { get; private set; }
public Points() {}
public Points(long id, long userId, long guildId, int points)
{
this.id = id;
this.userId = userId;
this.guildId = guildId;
this.points = points;
}
public Points(long userId, long guildId, long points)
{
this.points = points;
this.userId = userId;
this.guildId = guildId;
}
public static QueryBuilder<Points> Query()
{
return BaseEntity.Query<Points>();
}
public override void SetFromRow(DataRow row)
{
id = (long)row["id"];
userId = (long)row["userId"];
guildId = (long)row["guildId"];
points = (long)row["points"];
}
}
}

View File

@ -1,45 +0,0 @@
using System;
using System.Data;
using ChaosBot.Attribute;
namespace ChaosBot.Database.Entity
{
[DBEntity("RaffleTable")]
public class Raffle : BaseEntity
{
[DBPrimaryKey]
[DBAutoIncrement]
[DBNotNull]
[DBUnique]
public Nullable<long> id { get; private set; }
public long userId { get; private set; }
public long guildId { get; private set; }
public Raffle() {}
public Raffle(int id, long userId, long guildId)
{
this.id = id;
this.userId = userId;
this.guildId = guildId;
}
public Raffle(long userId, long guildId)
{
this.userId = userId;
this.guildId = guildId;
}
public static QueryBuilder<Raffle> Query()
{
return BaseEntity.Query<Raffle>();
}
public override void SetFromRow(DataRow row)
{
id = (long)row["id"];
userId = (long)row["userid"];
guildId = (long) row["guildid"];
}
}
}

View File

@ -1,67 +0,0 @@
using System;
using System.Data;
using System.IO;
using System.Text;
using System.Text.Json;
using System.Xml.Serialization;
using ChaosBot.Attribute;
namespace ChaosBot.Database.Entity
{
[DBEntity("ServerConfigurationFlags")]
public class ServerConfigurationFlag<T> : BaseEntity
{
public string key { get; private set; }
public string serializedValue { get; set; }
public long guildId { get; private set; }
public ServerConfigurationFlag() {}
public ServerConfigurationFlag(string key, T value, ulong guildId)
{
this.serializedValue = Serialize(value);
this.key = key;
this.guildId = Convert.ToInt64(guildId);
}
public ServerConfigurationFlag(string key, T value, long guildId)
{
this.serializedValue = Serialize(value);
this.key = key;
this.guildId = guildId;
}
public ServerConfigurationFlag(string key, long guildId)
{
this.key = key;
this.guildId = guildId;
}
public static QueryBuilder<ServerConfigurationFlag<T>> Query()
{
return BaseEntity.Query<ServerConfigurationFlag<T>>();
}
public override void SetFromRow(DataRow row)
{
key = (string)row["key"];
serializedValue = (string)row["serializedValue"];
guildId = (long)row["guildId"];
}
public T GetValue()
{
return Deserialize(serializedValue);
}
public static string Serialize(T value)
{
return JsonSerializer.Serialize(value);
}
public static T Deserialize(string serializedValue)
{
return JsonSerializer.Deserialize<T>(serializedValue);
}
}
}

View File

@ -1,16 +0,0 @@
using NLog.Filters;
namespace ChaosBot.Database
{
public struct FilterValue
{
public object Value;
public string Comparison;
public FilterValue(object value, string comparison = null)
{
this.Value = value;
this.Comparison = comparison;
}
}
}

View File

@ -1,290 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;
using System.Text;
using ChaosBot.Attribute;
using ChaosBot.Database.Entity;
namespace ChaosBot.Database
{
public class QueryBuilder<T> where T : BaseEntity, new()
{
private string _table;
private bool _distinct;
private Dictionary<string, FilterValue> _whereConditions;
private Dictionary<string, object> _setList;
private List<string> _orderKeys;
private List<string> _groupByList;
private int _limit;
private int _offset;
public QueryBuilder(string table)
{
_table = table;
_distinct = false;
_whereConditions = new Dictionary<string, FilterValue>();
_setList = new Dictionary<string, object>();
_orderKeys = new List<string>();
_groupByList = new List<string>();
_limit = -1;
_offset = -1;
}
/*
* Fetch all records from a database
*/
public List<T> All()
{
QueryBuilderRaw query = new QueryBuilderRaw();
DataTable dt = query
.Select()
.Append("*")
.FromTable(_table)
.Run();
List<T> returnList = new List<T>();
foreach (DataRow row in dt.Rows)
{
T newObject = new T();
newObject.SetFromRow(row);
returnList.Add(newObject);
}
return returnList;
}
/*
* Set a where condition
*/
public QueryBuilder<T> Where(string key, object value, string comparison = null)
{
_whereConditions.Add(key, new FilterValue(value, comparison));
return this;
}
/*
* Set distinct
*/
public QueryBuilder<T> Distinct()
{
_distinct = true;
return this;
}
/*
* Set SET field
*/
public QueryBuilder<T> Set(string key, object value)
{
_setList.Add(key, value);
return this;
}
/*
* Set an order key
*/
public QueryBuilder<T> OrderBy(string key)
{
_orderKeys.Add(key);
return this;
}
/*
* Set a groupBy key
*/
public QueryBuilder<T> GroupBy(string key)
{
_groupByList.Add(key);
return this;
}
/*
* Limit amount of responses
*/
public QueryBuilder<T> Limit(int amount)
{
_limit = amount;
return this;
}
public QueryBuilder<T> Offset(int amount)
{
_offset = amount;
return this;
}
public QueryBuilder<T> Limit(int limit, int offset)
{
Limit(limit);
return Offset(offset);
}
/*
* Basic mathematical operations
*/
public int Count()
{
QueryBuilderRaw query = new QueryBuilderRaw();
query
.Select()
.Append("COUNT(*) as count")
.FromTable(_table);
if (_whereConditions.Count > 0)
query.Where(_whereConditions);
long amount = (long)query.Run().Rows[0]["count"];
return Convert.ToInt32(amount);
}
/*
* Basic logical operations
*/
public bool Exists()
{
QueryBuilderRaw query = new QueryBuilderRaw();
query
.Select()
.Append("COUNT(*)>0 as present")
.FromTable(_table);
if (_whereConditions.Count > 0)
query.Where(_whereConditions);
return (bool)query.Run().Rows[0]["present"];
}
public bool DoesNotExist()
{
QueryBuilderRaw query = new QueryBuilderRaw();
query
.Select()
.Append("COUNT(*)=0 as notPresent")
.FromTable(_table);
if (_whereConditions.Count > 0)
query.Where(_whereConditions);
return (bool)query.Run().Rows[0]["notPresent"];
}
/*
* Actions
*/
public List<T> Get()
{
List<T> returnList = new List<T>();
QueryBuilderRaw query = new QueryBuilderRaw();
query
.Select();
if (_distinct)
query.Distinct();
query
.Append("*")
.FromTable(_table);
if (_whereConditions.Keys.Count > 0)
query.Where(_whereConditions);
if (_groupByList.Count > 0)
query.GroupBy(_groupByList);
if (_orderKeys.Count > 0)
query.OrderBy(_orderKeys);
if (_limit >= 0)
{
if (_offset >= 0)
{
query.Limit(_limit, _offset);
}
else
{
query.Limit(_limit);
}
}
DataTable dt = query.Run();
foreach (DataRow row in dt.Rows)
{
T newObject = new T();
newObject.SetFromRow(row);
returnList.Add(newObject);
}
return returnList;
}
public T First()
{
Limit(1);
List<T> list = Get();
if (list.Count > 0)
return list[0];
return null;
}
public void Insert(T obj)
{
Dictionary<string, object> objectKeysAndValues = GetObjectKeysAndValues(obj);
QueryBuilderRaw query = new QueryBuilderRaw();
query
.Insert()
.IntoTable(_table)
.Columns(new List<string>(objectKeysAndValues.Keys))
.Values(objectKeysAndValues);
query.Run();
}
public void Update()
{
QueryBuilderRaw query = new QueryBuilderRaw();
query
.Update()
.Table(_table)
.Set(_setList);
if (_whereConditions.Keys.Count > 0)
query.Where(_whereConditions);
query.Run();
}
public void Delete()
{
QueryBuilderRaw query = new QueryBuilderRaw();
query
.Delete()
.FromTable(_table);
if (_whereConditions.Keys.Count > 0)
query.Where(_whereConditions);
query.Run();
}
/*
* Helpers
*/
private Dictionary<string, object> GetObjectKeysAndValues(T obj)
{
var returnValue = new Dictionary<string, object>();
foreach (PropertyInfo prop in typeof(T).GetProperties())
{
string columnName = prop.Name;
object value = prop.GetValue(obj);
if (value != null)
returnValue.Add(columnName, value);
}
return returnValue;
}
}
}

View File

@ -1,175 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
namespace ChaosBot.Database
{
public class QueryBuilderRaw
{
private StringBuilder _query;
private Dictionary<string, object> _parameters;
private int keyIndex = 0;
public QueryBuilderRaw()
{
_query = new StringBuilder();
_parameters = new Dictionary<string, object>();
}
public QueryBuilderRaw Append(string text)
{
_query.Append(text);
if (!text.EndsWith(" "))
_query.Append(" ");
return this;
}
public DataTable Run()
{
return Controller.RawQuery(_query.ToString(), _parameters);
}
public QueryBuilderRaw Select()
{
return Append("SELECT");
}
public QueryBuilderRaw Insert(string alternativeAction = null)
{
Append("INSERT");
if (alternativeAction != null)
Append(alternativeAction);
return this;
}
public QueryBuilderRaw Update(string alternativeAction = null)
{
Append("UPDATE");
if (alternativeAction != null)
Append(alternativeAction);
return this;
}
public QueryBuilderRaw Delete()
{
return Append("DELETE");
}
public QueryBuilderRaw Distinct()
{
return Append("DISTINCT");
}
public QueryBuilderRaw Table(string table)
{
return Append(table);
}
public QueryBuilderRaw FromTable(string table)
{
Append("FROM");
return Table(table);
}
public QueryBuilderRaw IntoTable(string table)
{
Append("INTO");
return Table(table);
}
public QueryBuilderRaw Columns(List<string> columnList)
{
Append("(");
Append(String.Join(", ", columnList));
Append(")");
return this;
}
public QueryBuilderRaw Values(Dictionary<string, object> keyValueList)
{
Append("VALUES (");
List<string> parameterKeys = new List<string>();
foreach (KeyValuePair<string, object> pair in keyValueList)
{
string parameterName = AddParameterAndReturnKey(pair.Key, pair.Value);
parameterKeys.Add(parameterName);
}
Append(string.Join(", ", parameterKeys));
Append(")");
return this;
}
public QueryBuilderRaw Set(Dictionary<string, object> keyValueList)
{
Append("SET");
List<string> parameterKeys = new List<string>();
foreach (KeyValuePair<string, object> pair in keyValueList)
{
string parameterName = AddParameterAndReturnKey(pair.Key, pair.Value);
parameterKeys.Add($"{pair.Key} = {parameterName}");
}
Append(string.Join(", ", parameterKeys));
return this;
}
public QueryBuilderRaw Where(Dictionary<string, FilterValue> whereCondition)
{
Append("WHERE");
List<string> whereConditionList = new List<string>();
foreach (string key in whereCondition.Keys)
{
FilterValue value = whereCondition.GetValueOrDefault(key);
string parameterName = AddParameterAndReturnKey(key, value.Value);
whereConditionList.Add($"{key} {value.Comparison ?? "="} {parameterName}");
}
Append(string.Join(" AND ", whereConditionList));
return this;
}
public QueryBuilderRaw GroupBy(List<string> groupByList)
{
Append("GROUP BY");
return Append(string.Join(", ", groupByList));
}
public QueryBuilderRaw OrderBy(List<string> orderKeys)
{
Append("ORDER BY");
return Append(string.Join(", ", orderKeys));
}
public QueryBuilderRaw Limit(int limit)
{
return Append($"LIMIT {limit}");
}
public QueryBuilderRaw Limit(int limit, int offset)
{
return Append($"LIMIT {limit} OFFSET {offset}");
}
private void AddParameter(string parameterName, object value)
{
_parameters.Add(parameterName, value);
}
private string AddParameterAndReturnKey(string key, object value)
{
string parameterKey = GetUniqueParameterName(key);
AddParameter(parameterKey, value);
return parameterKey;
}
private string GetStaticParameterName(string key)
{
return $"@databasevalue{key}";
}
private string GetUniqueParameterName(string key)
{
return $"{GetStaticParameterName(key)}_{keyIndex++}";
}
}
}

View File

@ -1,41 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using ChaosBot.Database.Entity;
using Microsoft.Data.Sqlite;
namespace ChaosBot.Database.Repository
{
public static class CommandPermissionRepository
{
private static readonly string Table = "CommandPermissions";
/// <summary>
/// Fetch all <c>CommandPermission</c>s filtered by guildId
/// </summary>
/// <param name="guildId"></param>
/// <returns>List of Commands and Permissions</returns>
public static CommandPermission[] All(long guildId)
{
var cmds = CommandPermission.Query().Where("guildId", guildId).All();
return cmds.ToArray();
}
/// <summary>
/// Get all <c>CommandPermission</c>s for a command filtered by guild
/// </summary>
/// <param name="cmd"></param>
/// <param name="guildId"></param>
/// <returns>List of raffles</returns>
public static CommandPermission[] getPerm(string cmd, long guildId)
{
List<CommandPermission> cmds = CommandPermission.Query().Where("cmd", cmd).Where("guildId", guildId).Get();
if(cmds.Count != 0) return cmds.ToArray();
return null;
}
}
}

View File

@ -1,98 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data;
using ChaosBot.Database.Entity;
using Microsoft.Extensions.Configuration;
using NLog;
namespace ChaosBot.Database.Repository
{
public static class ConfigurationRepository
{
private static ILogger _logger = Program.Logger;
public static IConfiguration AppSettingsHandler { get; set; }
private static readonly string ServersTable = "ServerConfigurationFlags";
/// <summary>
/// Get global configuration option
/// </summary>
/// <param name="configurationFlag"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static T GetValue<T>(string configurationFlag)
{
return AppSettingsHandler.GetValue<T>(configurationFlag);
}
/// <summary>
/// Get guild specific configuration option
/// </summary>
/// <param name="configurationFlag"></param>
/// <param name="guildId"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static T GetValue<T>(string configurationFlag, ulong guildId)
{
if (_logger == null) return AppSettingsHandler.GetValue<T>($"Servers:{guildId}:{configurationFlag}");
string valueSerialized = GetValueRaw(configurationFlag, Convert.ToInt64(guildId));
if (valueSerialized != null)
return ServerConfigurationFlag<T>.Deserialize(valueSerialized);
return AppSettingsHandler.GetValue<T>($"Servers:{guildId}:{configurationFlag}");
}
public static string GetValueRaw(string configurationFlag, long guildId)
{
Dictionary<string, FilterValue> filterColumns = new Dictionary<string, FilterValue>();
filterColumns.Add("key", new FilterValue(configurationFlag));
filterColumns.Add("guildId", new FilterValue(guildId));
ServerConfigurationFlag<string> serverConfigurationFlag = ServerConfigurationFlag<string>.Query().Where("key", configurationFlag).Where("guildId", guildId).First();
if (serverConfigurationFlag != null)
{
return serverConfigurationFlag.serializedValue;
}
return null;
}
/// <summary>
/// Get guild specific configuration option
/// </summary>
/// <param name="configurationFlag"></param>
/// <param name="guildId"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static void SetValue<T>(string configurationFlag, ulong guildId, T value)
{
SetValueRaw(configurationFlag, Convert.ToInt64(guildId), ServerConfigurationFlag<T>.Serialize(value));
}
public static void SetValueRaw(string configurationFlag, long guildId, string serializedValue)
{
try
{
int matchCount = ServerConfigurationFlag<string>.Query().Where("key", configurationFlag).Where("guildId", guildId).Count();
if (matchCount > 0)
{
ServerConfigurationFlag<string>.Query()
.Where("key", configurationFlag)
.Where("guildId", guildId)
.Set("key", configurationFlag)
.Set("guildId", guildId)
.Set("serializedValue", serializedValue)
.Update();
return;
}
ServerConfigurationFlag<string> newValue = new ServerConfigurationFlag<string>(configurationFlag, guildId);
newValue.serializedValue = serializedValue;
ServerConfigurationFlag<string>.Query().Insert(newValue);
}
catch (Exception ex)
{
_logger.Fatal($"ConfigurationRepository.SetValueRaw: Exception [{ex}] thrown, <[{ex.Message}]>.");
}
}
}
}

View File

@ -1,75 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data;
using ChaosBot.Database.Entity;
namespace ChaosBot.Database.Repository
{
public static class PointsRepository
{
private static readonly string Table = "PointsTable";
public static Points[] All()
{
List<Points> pointsList = Points.Query().All();
return pointsList.ToArray();
}
public static Points[] All(long guildId)
{
List<Points> pointsList = Points.Query().Where("guildId", guildId).All();
return pointsList.ToArray();
}
public static long Total(long userId, long guildId)
{
Points userPoints = Points.Query().Where("userId", userId).Where("guildId", guildId).First();
if (userPoints != null)
return userPoints.points;
Points emptyUserPoints = new Points(userId, guildId, 0);
Points.Query().Insert(emptyUserPoints);
return 0;
}
public static int Count(long userId, long guildId)
{
return Points.Query().Where("userId", userId).Where("guildId", guildId).Count();
}
public static long Add(long userId, long points, long guildId)
{
Points userPoints = Points.Query().Where("userId", userId).Where("guildId", guildId).First();
if (userPoints != null)
{
Points.Query().Where("userId", userId).Where("guildId", guildId).Set("points", userPoints.points + points).Update();
return userPoints.points + points;
}
Points newUserPoints = new Points(userId, guildId, points);
Points.Query().Insert(newUserPoints);
return points;
}
public static long Remove(long userId, long points, long guildId)
{
Points userPoints = Points.Query().Where("userId", userId).Where("guildId", guildId).First();
Points.Query().Where("userId", userId).Where("guildId", guildId).Set("points", userPoints.points - points).Update();
return userPoints.points - points;
}
public static void Delete(int userId)
{
Points.Query().Where("userId", userId).Delete();
}
}
}

View File

@ -1,141 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using ChaosBot.Database.Entity;
using Microsoft.Data.Sqlite;
namespace ChaosBot.Database.Repository
{
public static class RaffleRepository
{
private static readonly string Table = "RaffleTable";
/// <summary>
/// Fetch all <c>Raffle</c>s
/// </summary>
/// <returns>List of raffles</returns>
public static Raffle[] All()
{
var raffles = Raffle.Query().All();
return raffles.ToArray();
}
/// <summary>
/// Fetch all <c>Raffle</c>s filtered by guildId
/// </summary>
/// <param name="guildId"></param>
/// <returns>List of raffles</returns>
public static Raffle[] All(long guildId)
{
var raffles = Raffle.Query().Where("guildId", guildId).All();
return raffles.ToArray();
}
/// <summary>
/// Count amount of <c>Raffle</c>s
/// </summary>
/// <returns>Amount of raffles</returns>
public static int Count()
{
return Raffle.Query().Count();
}
/// <summary>
/// Count amount of <c>Raffle</c>s filtered by guildId
/// </summary>
/// <param name="guildId"></param>
/// <returns>Amount of raffles</returns>
public static int Count(long guildId)
{
return Raffle.Query().Where("guildId", guildId).Count();
}
/// <summary>
/// Count amount of <c>Raffle</c>s filtered by guildId
/// </summary>
/// <param name="userId"></param>
/// <param name="guildId"></param>
/// <returns>Amount of raffles</returns>
public static int Count(long userId, long guildId)
{
return Raffle.Query().Where("userId", userId).Where("guildId", guildId).Count();
}
/// <summary>
/// Get all <c>Raffle</c>s from a user
/// </summary>
/// <param name="userId"></param>
/// <returns>List of raffles</returns>
public static Raffle[] SelectUser(long userId)
{
List<Raffle> raffles = Raffle.Query().Where("userId", userId).Get();
return raffles.ToArray();
}
/// <summary>
/// Get all <c>Raffle</c>s from a user filtered by guild
/// </summary>
/// <param name="userId"></param>
/// <param name="guildId"></param>
/// <returns>List of raffles</returns>
public static Raffle[] SelectUser(long userId, long guildId)
{
List<Raffle> raffles = Raffle.Query().Where("userId", userId).Where("guildId", guildId).Get();
return raffles.ToArray();
}
/// <summary>
/// Insert a <c>Raffle</c> into the database
/// </summary>
/// <param name="raffle"></param>
public static void Insert(Raffle raffle)
{
Raffle.Query().Insert(raffle);
}
/// <summary>
/// Insert a <c>List</c> of <c>Raffle</c>s into the database
/// </summary>
/// <param name="raffles"></param>
public static void MassInsert(List<Raffle> raffles)
{
foreach (var raf in raffles)
{
Raffle.Query().Insert(raf);
}
}
/// <summary>
/// Pick a random raffle from the database filtered to a guild
/// </summary>
/// <param name="guildId"></param>
/// <returns>Random raffle</returns>
public static Raffle PickRandom(long guildId)
{
return Raffle.Query().Where("guildId", guildId).OrderBy("RANDOM()").First();
}
/// <summary>
/// Clear all <c>Raffle</c>s for a given guild
/// </summary>
/// <param name="guildId"></param>
public static void ClearRaffle(long guildId)
{
Raffle.Query().Where("guildId", guildId).Delete();
}
/// <summary>
/// Delete a <c>Raffle</c> by id
/// </summary>
/// <param name="id"></param>
public static void Delete(long id)
{
Raffle.Query().Where("id", id).Delete();
}
}
}

View File

@ -4,7 +4,6 @@ using Discord;
using Discord.Commands;
using Discord.WebSocket;
using System.Threading.Tasks;
using ChaosBot.Database.Repository;
using ChaosBot.Discord.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
@ -34,7 +33,7 @@ namespace ChaosBot.Discord
services.GetRequiredService<CommandService>().Log += Log;
// this is where we get the Token value from the configuration file, and start the bot
await client.LoginAsync(TokenType.Bot, ConfigurationRepository.GetValue<string>("Discord:Token"));
await client.LoginAsync(TokenType.Bot, Program.AppSettingsHandler.GetValue<string>("Discord:Token"));
await client.StartAsync();
// we get the CommandHandler class here and call the InitializeAsync method to start things up for the CommandHandler service

View File

@ -1,18 +1,20 @@
using System;
using System.Linq;
using Discord;
using Discord.Commands;
using System.Threading.Tasks;
using NLog;
using System.Text;
using ChaosBot.Database.Repository;
using System.Text.Json;
using ChaosBot.Discord.PreConditions;
using ChaosBot.Models;
using ChaosBot.Repositories;
namespace ChaosBot.Discord.Modules
{
public class ConfigCommands : ModuleBase
{
private static readonly ILogger _logger = Program.Logger;
private static readonly string _prefix = ConfigurationRepository.GetValue<string>("Discord:Prefix");
private static readonly ILogger _logger = Program.Logger;
[Command("config")]
[CheckCommandPerm]
@ -25,10 +27,19 @@ namespace ChaosBot.Discord.Modules
{
if (configFlag == null || value == null)
{
await ReplyAsync($"Syntax Wrong. Please see {_prefix}config help");
string prefix = ConfigurationRepository.GetValue<string>("Discord:Prefix", Context.Guild.Id, "!");
await ReplyAsync($"Syntax Wrong. Please see {prefix}config help");
return;
}
ConfigurationRepository.SetValue<String>(configFlag, Context.Guild.Id, value);
using (ChaosbotContext dbContext = new ChaosbotContext())
{
// ConfigurationRepository.SetValue<String>(configFlag, Context.Guild.Id, value);
Configuration config = dbContext.Configuration
.FirstOrDefault(c => c.DiscordGuildId == Context.Guild.Id && c.Key == configFlag);
// TODO: Is this warning valid?
config.SerializedValue = JsonSerializer.Serialize(value);
dbContext.SaveChanges();
}
embed.WithColor(new Color(255, 255, 0));
embed.Title = $"Configuration Management";
sb.AppendLine($"{Context.User.Mention} has changed the Configuration.");
@ -56,13 +67,15 @@ namespace ChaosBot.Discord.Modules
[RequireUserPermission(GuildPermission.ManageGuild)]
public async Task helpConfig(string configFlag = null, string value = null)
{
string prefix = ConfigurationRepository.GetValue<string>("Discord:Prefix", Context.Guild.Id, "!");
var sb = new StringBuilder();
var embed = new EmbedBuilder();
embed.WithColor(new Color(255, 255, 0));
embed.Title = $"Configuration Management Help";
sb.AppendLine();
sb.AppendLine($"{_prefix}config <configFlag> <value>");
sb.AppendLine($"{prefix}config <configFlag> <value>");
/*
* Add the string to the Embed

View File

@ -3,8 +3,6 @@ using Discord;
using System.Text;
using Discord.Commands;
using System.Threading.Tasks;
using ChaosBot.Database;
using ChaosBot.Database.Repository;
using Microsoft.Extensions.Configuration;
using NLog;
@ -26,11 +24,11 @@ namespace ChaosBot.Discord.Modules
embed.WithColor(new Color(255, 255,0));
embed.Title = $"General Information";
sb.AppendLine($"{Context.User.Mention} has requested information from {ConfigurationRepository.GetValue<string>("Bot:Name")}.");
// TODO: pull bot nickname
sb.AppendLine($"{Context.User.Mention} has requested information from {Program.AppSettingsHandler.GetValue<string>("Bot:Name")}.");
sb.AppendLine();
sb.AppendLine($"Bot Version: {ConfigurationRepository.GetValue<string>("Bot:Version")}");
sb.AppendLine($"Bot Prefix: {ConfigurationRepository.GetValue<string>("Discord:Prefix")}");
sb.AppendLine($"{Controller.RawQuery("select * from RaffleTable where Id = (abs(random()) % (select (select max(Id) from RaffleTable)+1)) or rowid = (select min(Id) from RaffleTable) order by Id DESC limit 1;").Rows[0]["userId"]}");
sb.AppendLine($"Bot Version: {Program.AppSettingsHandler.GetValue<string>("Bot:Version")}");
sb.AppendLine($"Bot Prefix: {Program.AppSettingsHandler.GetValue<string>("Discord:Prefix")}");
/*
* Add the string to the Embed

View File

@ -5,11 +5,9 @@ using Discord.Commands;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
using ChaosBot.Database;
using ChaosBot.Lodestone;
using ChaosBot.Services;
using Discord.Net;
using Microsoft.Extensions.Configuration;
using NLog;

View File

@ -1,15 +1,10 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using ChaosBot.Database.Entity;
using Discord;
using Discord.Commands;
using Microsoft.Extensions.Configuration;
using NLog;
using ChaosBot.Database.Repository;
using ChaosBot.Database;
using System.Data;
using ChaosBot.Repositories;
namespace ChaosBot.Discord.Modules
{
@ -24,7 +19,7 @@ namespace ChaosBot.Discord.Modules
{
var sb = new StringBuilder();
var embed = new EmbedBuilder();
string prefix = ConfigurationRepository.GetValue<string>("Discord:Prefix");
string prefix = ConfigurationRepository.GetValue<string>("Discord:Prefix", Context.Guild.Id, "!");
embed.WithColor(new Color(255, 255, 0));
embed.Title = $"Points system";

View File

@ -1,12 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ChaosBot.Database.Entity;
using Discord;
using Discord.Commands;
using NLog;
using ChaosBot.Database.Repository;
using ChaosBot.Models;
using ChaosBot.Repositories;
namespace ChaosBot.Discord.Modules
{
@ -39,7 +40,7 @@ namespace ChaosBot.Discord.Modules
{
var eb = new EmbedBuilder();
var sb = new StringBuilder();
string prefix = ConfigurationRepository.GetValue<string>("Discord.Prefix", Context.Guild.Id);
string prefix = ConfigurationRepository.GetValue("Discord.Prefix", Context.Guild.Id, "!");
sb.AppendLine($"{Context.User.Mention} has requested raffle information.");
sb.AppendLine();

View File

@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ChaosBot.Database.Repository;
using ChaosBot.Models;
using ChaosBot.Repositories;
using Discord.Commands;
using Discord.WebSocket;
using NLog;
@ -21,29 +23,36 @@ namespace ChaosBot.Discord.PreConditions
if (!(context.User is SocketGuildUser gUser)) return Task.FromResult(PreconditionResult.FromError("You must be in a guild to run this command."));
// Get the possible permissions
var commandPermissions = CommandPermissionRepository.getPerm(command.Name, Convert.ToInt64(context.Guild.Id));
List<CommandPermission> commandPermissions;
using (ChaosbotContext dbContext = new ChaosbotContext())
{
IQueryable<CommandPermission> permissions = dbContext.CommandPermissions;
commandPermissions = permissions.Where(p => p.Command.Equals(command.Name))
.Where(p => p.DiscordGuildId == context.Guild.Id)
.ToList();
}
// If we can find a permission
if(commandPermissions != null)
{
// Loop through all permissions
foreach (var perm in commandPermissions)
foreach (CommandPermission perm in commandPermissions)
{
string requiredGroup;
ulong requiredGroup;
// Check if it's a role or group permission and fetch the right type
if (perm.type.ToLower() == "role")
if (perm.TargetType == (int)PermissionTarget.Role)
{
// If it's a role, check the configuration for the role otherwise return the permission value
requiredGroup = ConfigurationRepository.GetValue<string>($"Role:{perm.value}", context.Guild.Id) ?? perm.value;
requiredGroup = ConfigurationRepository.GetValue<ulong>($"Role:{perm.TargetId}", context.Guild.Id, perm.TargetId);
}
else
{
// Return the permission value
requiredGroup = perm.value;
requiredGroup = perm.TargetId;
}
// Check if any of the users roles are of the required group, if so, permission granted
if (gUser.Roles.Any(r => r.Name == requiredGroup))
if (gUser.Roles.Any(r => r.Id == requiredGroup))
return Task.FromResult(PreconditionResult.FromSuccess());
}
}

View File

@ -1,7 +1,7 @@
using System;
using System.Reflection;
using System.Threading.Tasks;
using ChaosBot.Database.Repository;
using ChaosBot.Repositories;
using Microsoft.Extensions.DependencyInjection;
using Discord;
using Discord.Commands;
@ -51,14 +51,13 @@ namespace ChaosBot.Discord.Services
if (message.Source != MessageSource.User)
return;
var argPos = 0;
SocketCommandContext context = new SocketCommandContext(_client, message);
char prefix = Char.Parse(ConfigurationRepository.GetValue<string>("Discord:Prefix"));
if (!(message.HasMentionPrefix(_client.CurrentUser, ref argPos) || message.HasCharPrefix(prefix, ref argPos)))
int argPos = 0;
string prefix = ConfigurationRepository.GetValue<string>("Discord:Prefix", context.Guild.Id, "!");
if (!(message.HasMentionPrefix(_client.CurrentUser, ref argPos) || message.HasStringPrefix(prefix, ref argPos)))
return;
var context = new SocketCommandContext(_client, message);
await _commands.ExecuteAsync(context, argPos, _services);
}

View File

@ -1,6 +1,4 @@
using System;
using System.Threading.Tasks;
using ChaosBot.Database.Repository;
using ChaosBot.Services;
using Discord;
using Discord.WebSocket;
@ -19,7 +17,7 @@ namespace ChaosBot.Discord.Services
{
_client = services.GetRequiredService<DiscordSocketClient>();
foreach (IConfigurationSection serverConfig in ConfigurationRepository.AppSettingsHandler.GetSection("Servers").GetChildren())
foreach (IConfigurationSection serverConfig in Program.AppSettingsHandler.GetSection("Servers").GetChildren())
{
long? lodestoneChannelSloganDescriptionId = serverConfig.GetValue<long?>("Lodestone:SloganDescription:Channel", null);
int refreshMinutes = serverConfig.GetValue<int>("Lodestone:SloganDescription:RefreshMinutes", 60);

View File

@ -1,5 +1,4 @@
using System;
using ChaosBot.Database.Repository;
using Microsoft.Extensions.Configuration;
using NLog;
using NLog.Extensions.Logging;

View File

@ -1,4 +1,5 @@
using Microsoft.EntityFrameworkCore.Metadata;
using ChaosBot.Models;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
namespace ChaosBot.Migrations
@ -32,10 +33,4 @@ namespace ChaosBot.Migrations
migrationBuilder.DropTable(Table);
}
}
public enum PermissionTarget
{
User,
Role
}
}

View File

@ -1,4 +1,3 @@
using ChaosBot.Database.Repository;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
@ -17,17 +16,17 @@ namespace ChaosBot.Models
{
if (!optionsBuilder.IsConfigured)
{
if (ConfigurationRepository.AppSettingsHandler == null)
if (Program.AppSettingsHandler == null)
{
ConfigurationRepository.AppSettingsHandler = new ConfigurationBuilder()
Program.AppSettingsHandler = new ConfigurationBuilder()
.SetBasePath(System.IO.Directory.GetCurrentDirectory())
.AddJsonFile("./appsettings.json", optional: false, reloadOnChange: true).Build();
}
string server = ConfigurationRepository.GetValue<string>("Database:Host");
int port = ConfigurationRepository.GetValue<int>("Database:Port");
string user = ConfigurationRepository.GetValue<string>("Database:User");
string pass = ConfigurationRepository.GetValue<string>("Database:Pass");
string name = ConfigurationRepository.GetValue<string>("Database:Name");
string server = Program.AppSettingsHandler.GetValue<string>("Database:Host");
int port = Program.AppSettingsHandler.GetValue<int>("Database:Port");
string user = Program.AppSettingsHandler.GetValue<string>("Database:User");
string pass = Program.AppSettingsHandler.GetValue<string>("Database:Pass");
string name = Program.AppSettingsHandler.GetValue<string>("Database:Name");
optionsBuilder.UseMySql(
$"server={server};port={port};user={user};password={pass};database={name}",
x => x.ServerVersion("5.5.64-mariadb"));

View File

@ -18,4 +18,10 @@ namespace ChaosBot.Models
public string Command { get; set; }
}
#endregion
public enum PermissionTarget
{
User,
Role
}
}

View File

@ -3,8 +3,6 @@ using System;
using System.Runtime.CompilerServices;
using ChaosBot.Discord;
using System.Threading.Tasks;
using ChaosBot.Attribute;
using ChaosBot.Database.Repository;
using Microsoft.Extensions.Configuration;
[assembly: InternalsVisibleTo("ChaosBot.UnitTests")]
@ -13,6 +11,8 @@ namespace ChaosBot
internal class Program
{
public static ILogger Logger;
public static IConfiguration AppSettingsHandler;
private static string _appsettingsPath;
private static void Main(string[] args)
@ -38,17 +38,12 @@ namespace ChaosBot
/*
* Set AppSettingsHandler on ConfigurationRepository
*/
ConfigurationRepository.AppSettingsHandler = configurationHandler;
/*
* Attempt to load our custom assemblies
*/
RegisterAssemblyController();
AppSettingsHandler = configurationHandler;
/*
* Initialize the Discord Client and Login
*/
Logger.Info($"Starting Up {ConfigurationRepository.GetValue<string>("Bot:Name")} v{ConfigurationRepository.GetValue<string>("Bot:Version")}");
Logger.Info($"Starting Up {AppSettingsHandler.GetValue<string>("Bot:Name")} v{AppSettingsHandler.GetValue<string>("Bot:Version")}");
var discordBot = LoadDiscord();
@ -68,11 +63,6 @@ namespace ChaosBot
.AddJsonFile(appsettingsPath, optional: false, reloadOnChange: true).Build();
}
public static void RegisterAssemblyController()
{
AssemblyController.RegisterAll();
}
public static void LoadWebServer()
{
WebServer.WebServer.Start(new string[]{});

View File

@ -0,0 +1,27 @@
using System;
using System.Linq;
using ChaosBot.Models;
using System.Text.Json;
namespace ChaosBot.Repositories
{
public static class ConfigurationRepository
{
public static T GetValue<T>(string key, ulong guildId)
{
return GetValue<T>(key, guildId, default);
}
public static T GetValue<T>(string key, ulong guildId, T defaultValue)
{
using (ChaosbotContext dbContext = new ChaosbotContext())
{
Configuration config = dbContext.Configuration
.SingleOrDefault(c => c.DiscordGuildId == guildId && c.Key == key);
if (String.IsNullOrEmpty(config.SerializedValue))
return defaultValue;
return JsonSerializer.Deserialize<T>(config.SerializedValue);
}
}
}
}

View File

@ -1,26 +0,0 @@
using System;
using ChaosBot.Database.Repository;
using Microsoft.AspNetCore.Mvc;
using NLog;
namespace ChaosBot.WebServer.App.Controller
{
[ApiController]
[Route("/config/{guildId}/{flag}")]
public class ConfigurationController
{
private readonly ILogger _logger = Program.Logger;
[HttpGet]
public string GetConfigurationFlag(long guildId, string flag)
{
return ConfigurationRepository.GetValueRaw(flag, guildId);
}
[HttpPost]
public void SetConfigurationFlag(long guildId, string flag, [FromBody] string serializedValue)
{
ConfigurationRepository.SetValueRaw(flag, guildId, serializedValue);
}
}
}

View File

@ -1,8 +1,8 @@
using System.Net;
using ChaosBot.Database.Repository;
using NLog.Extensions.Logging;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
@ -21,7 +21,7 @@ namespace ChaosBot.WebServer
{
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Listen(IPAddress.Any, ConfigurationRepository.GetValue<int>("WebServer:Port"),
serverOptions.Listen(IPAddress.Any, Program.AppSettingsHandler.GetValue<int>("WebServer:Port"),
listenOptions =>
{
listenOptions.UseConnectionLogging();
@ -31,7 +31,7 @@ namespace ChaosBot.WebServer
{
logging.ClearProviders();
logging.SetMinimumLevel(LogLevel.Trace);
logging.AddNLog(new NLogLoggingConfiguration(ConfigurationRepository.AppSettingsHandler.GetSection("NLog")));
logging.AddNLog(new NLogLoggingConfiguration(Program.AppSettingsHandler.GetSection("NLog")));
})
.UseStartup<Startup>();
});