The current BepInExPack is broken due to the Oakveil update, and mods installed through a mod manager may not work. Join the modding Discord for more information.
Decompiled source of CrimsonSQL v1.4.0
CrimsonSQL.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.Json; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using Costura; using CrimsonSQL.API; using CrimsonSQL.Services; using CrimsonSQL.Structs; using CrimsonSQL.Utility; using HarmonyLib; using Microsoft.CodeAnalysis; using MySqlConnector; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("SkyTech6, CrimsonMods")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("MySQL for IL2CPP BepInEx")] [assembly: AssemblyFileVersion("1.4.0.0")] [assembly: AssemblyInformationalVersion("1.4.0+Branch.master.Sha.f122611510bedd1390453eca7da5a715817e53cd.f122611510bedd1390453eca7da5a715817e53cd")] [assembly: AssemblyProduct("CrimsonSQL")] [assembly: AssemblyTitle("CrimsonSQL")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.4.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] internal class <Module> { static <Module>() { AssemblyLoader.Attach(); } } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace CrimsonSQL { [BepInPlugin("CrimsonSQL", "CrimsonSQL", "1.4.0")] public class Plugin : BasePlugin { private Harmony _harmony; public static Settings Settings; internal static Plugin Instance { get; private set; } public static Harmony Harmony => Instance._harmony; public static ManualLogSource LogInstance => ((BasePlugin)Instance).Log; public static SQLService SQLService { get; private set; } public static TableMapping TableMapping { get; private set; } public override void Load() { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown Instance = this; string[] manifestResourceNames = Assembly.GetExecutingAssembly().GetManifestResourceNames(); LogInstance.LogDebug((object)"=== Embedded Resources ==="); string[] array = manifestResourceNames; foreach (string text in array) { LogInstance.LogDebug((object)text); } LogInstance.LogDebug((object)"========================"); Settings = default(Settings); Settings.InitConfig(); TableMapping = new TableMapping(); AssemblyResolver.Resolve(); _harmony = new Harmony("CrimsonSQL"); _harmony.PatchAll(Assembly.GetExecutingAssembly()); if (Settings.MySQLConfigured) { SQLService = new SQLService(); } } public override bool Unload() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } return true; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "CrimsonSQL"; public const string PLUGIN_NAME = "CrimsonSQL"; public const string PLUGIN_VERSION = "1.4.0"; } } namespace CrimsonSQL.Utility { public static class AssemblyResolver { public static void Resolve() { Assembly assembly = Assembly.GetExecutingAssembly(); AppDomain.CurrentDomain.AssemblyResolve += delegate(object? sender, ResolveEventArgs args) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Expected O, but got Unknown ManualLogSource logInstance = Plugin.LogInstance; bool flag = default(bool); BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(23, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Attempting to resolve: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(args.Name); } logInstance.LogDebug(val); string name = args.Name; if (name == null) { goto IL_00a8; } string text; if (name.StartsWith("MySqlConnector")) { text = "CrimsonSQL.MySqlConnector.dll"; } else if (name.StartsWith("System.Diagnostics.DiagnosticSource")) { text = "CrimsonSQL.System.Diagnostics.DiagnosticSource.dll"; } else if (name.StartsWith("System.Security.Permissions")) { text = "CrimsonSQL.System.Security.Permissions.dll"; } else if (name.StartsWith("System.Configuration.ConfigurationManager")) { text = "CrimsonSQL.System.Configuration.ConfigurationManager.dll"; } else { if (!name.StartsWith("System.Text.Encoding.CodePages")) { goto IL_00a8; } text = "CrimsonSQL.System.Text.Encoding.CodePages.dll"; } goto IL_00ab; IL_00ab: string text2 = text; if (text2 != null) { ManualLogSource logInstance2 = Plugin.LogInstance; val = new BepInExDebugLogInterpolatedStringHandler(25, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Resource name mapped to: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text2); } logInstance2.LogDebug(val); using Stream stream = assembly.GetManifestResourceStream(text2); ManualLogSource logInstance3 = Plugin.LogInstance; val = new BepInExDebugLogInterpolatedStringHandler(14, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Stream found: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(stream != null); } logInstance3.LogDebug(val); if (stream != null) { byte[] array = new byte[stream.Length]; stream.Read(array, 0, array.Length); return Assembly.Load(array); } } return null; IL_00a8: text = null; goto IL_00ab; }; } } } namespace CrimsonSQL.Structs { public enum BatchOperationType { Insert, Delete, Update, Replace, CustomSQL } public class BatchOperation { public BatchOperationType OperationType { get; set; } public string TableName { get; set; } public Dictionary<string, object> Values { get; set; } public Dictionary<string, object> WhereConditions { get; set; } public int ResultId { get; set; } = -1; public List<int> HandledExceptions { get; set; } public string CustomQuery { get; set; } public static BatchOperation CreateInsert(string tableName, Dictionary<string, object> values, List<int> handledExceptions = null) { return new BatchOperation { OperationType = BatchOperationType.Insert, TableName = tableName, Values = values, HandledExceptions = handledExceptions }; } public static BatchOperation CreateDelete(string tableName, Dictionary<string, object> whereConditions) { return new BatchOperation { OperationType = BatchOperationType.Delete, TableName = tableName, WhereConditions = whereConditions }; } public static BatchOperation CreateUpdate(string tableName, Dictionary<string, object> values, Dictionary<string, object> whereConditions) { return new BatchOperation { OperationType = BatchOperationType.Update, TableName = tableName, Values = values, WhereConditions = whereConditions }; } public static BatchOperation CreateReplace(string tableName, Dictionary<string, object> whereConditions, Dictionary<string, object> newValues) { return new BatchOperation { OperationType = BatchOperationType.Replace, TableName = tableName, Values = newValues, WhereConditions = whereConditions }; } public static BatchOperation CreateCustomSQL(string tableName, string customQuery, Dictionary<string, object> parameters) { return new BatchOperation { OperationType = BatchOperationType.CustomSQL, TableName = tableName, Values = parameters, CustomQuery = customQuery }; } } [StructLayout(LayoutKind.Sequential, Size = 1)] public readonly struct Settings { public static ConfigEntry<string> DatabaseName { get; private set; } public static ConfigEntry<string> Host { get; private set; } public static ConfigEntry<int> Port { get; private set; } public static ConfigEntry<string> UserName { get; private set; } public static ConfigEntry<string> Password { get; private set; } public static ConfigEntry<string> Parameters { get; private set; } public static bool MySQLConfigured { get; set; } public static void InitConfig() { DatabaseName = InitConfigEntry("ServerConnection", "DatabaseName", "", "The name of your MySQL database."); Host = InitConfigEntry("ServerConnection", "Host", "", "The host address of your MySQL database."); Port = InitConfigEntry("ServerConnection", "Port", 3306, "The port of your database server."); UserName = InitConfigEntry("ServerConnection", "Username", "", "The login username for your database."); Password = InitConfigEntry("ServerConnection", "Password", "", "The login password for your database."); Parameters = InitConfigEntry("ServerConnection", "AdditionalParameters", "", "Some variations of MySQL require additional parameters on the connection string; such as \"CharSet=utf8mb4;Convert Zero Datetime=True;Allow Zero Datetime=True;\" put those here if needed."); if (!string.IsNullOrEmpty(DatabaseName.Value) && !string.IsNullOrEmpty(Host.Value) && Port.Value != 0 && !string.IsNullOrEmpty(UserName.Value) && !string.IsNullOrEmpty(Password.Value)) { MySQLConfigured = true; } } private static ConfigEntry<T> InitConfigEntry<T>(string section, string key, T defaultValue, string description) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) ConfigEntry<T> val = ((BasePlugin)Plugin.Instance).Config.Bind<T>(section, key, defaultValue, description); string text = Path.Combine(Paths.ConfigPath, "CrimsonSQL.cfg"); ConfigEntry<T> val2 = default(ConfigEntry<T>); if (File.Exists(text) && new ConfigFile(text, true).TryGetEntry<T>(section, key, ref val2)) { val.Value = val2.Value; } return val; } } public class TableMapping { private static string mappingFilePath = Path.Combine(Paths.ConfigPath, "CrimsonSQL_TableMappings.json"); private Dictionary<string, string> _tableMappings; public TableMapping() { _tableMappings = new Dictionary<string, string>(); LoadMappings(); } public string GetMappedTableName(string originalTableName) { if (_tableMappings.TryGetValue(originalTableName, out var value)) { return value; } SetMapping(originalTableName, originalTableName); return originalTableName; } public void SetMapping(string originalTableName, string mappedTableName) { _tableMappings[originalTableName] = mappedTableName; SaveMappings(); } public void RemoveMapping(string originalTableName) { if (_tableMappings.ContainsKey(originalTableName)) { _tableMappings.Remove(originalTableName); SaveMappings(); } } public Dictionary<string, string> GetAllMappings() { return new Dictionary<string, string>(_tableMappings); } private void LoadMappings() { //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown bool flag = default(bool); try { if (File.Exists(mappingFilePath)) { string json = File.ReadAllText(mappingFilePath); _tableMappings = JsonSerializer.Deserialize<Dictionary<string, string>>(json) ?? new Dictionary<string, string>(); ManualLogSource logInstance = Plugin.LogInstance; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(41, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Loaded "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_tableMappings.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" table mappings from configuration"); } logInstance.LogInfo(val); ApplyTableRenamesInDatabase(); } else { Plugin.LogInstance.LogInfo((object)"No table mapping configuration found. Creating new file."); SaveMappings(); } } catch (Exception ex) { ManualLogSource logInstance2 = Plugin.LogInstance; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(30, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Error loading table mappings: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message); } logInstance2.LogError(val2); _tableMappings = new Dictionary<string, string>(); } } private void SaveMappings() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown try { JsonSerializerOptions options = new JsonSerializerOptions { WriteIndented = true }; string contents = JsonSerializer.Serialize(_tableMappings, options); File.WriteAllText(mappingFilePath, contents); } catch (Exception ex) { ManualLogSource logInstance = Plugin.LogInstance; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(29, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Error saving table mappings: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message); } logInstance.LogError(val); } } private void ApplyTableRenamesInDatabase() { //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Expected O, but got Unknown if (Plugin.SQLService == null || !Settings.MySQLConfigured) { return; } try { string query = "SHOW TABLES;"; DataTable dataTable = Plugin.SQLService.ExecuteQuery(query); if (dataTable == null || dataTable.Rows.Count <= 0) { return; } List<string> list = new List<string>(); foreach (DataRow row in dataTable.Rows) { list.Add(row[0].ToString()); } foreach (KeyValuePair<string, string> tableMapping in _tableMappings) { if (list.Contains(tableMapping.Key) && tableMapping.Key != tableMapping.Value && !list.Contains(tableMapping.Value)) { RenameTableInDatabase(tableMapping.Key, tableMapping.Value); } } } catch (Exception ex) { ManualLogSource logInstance = Plugin.LogInstance; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(42, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Error applying table renames in database: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message); } logInstance.LogError(val); } } private void RenameTableInDatabase(string oldName, string newName) { //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Expected O, but got Unknown //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown bool flag = default(bool); try { if (string.IsNullOrEmpty(oldName) || string.IsNullOrEmpty(newName) || oldName == newName) { return; } string query = "SHOW TABLES LIKE '" + oldName + "';"; DataTable dataTable = Plugin.SQLService.ExecuteQuery(query); if (dataTable == null || dataTable.Rows.Count == 0) { ManualLogSource logInstance = Plugin.LogInstance; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(57, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Cannot rename table '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(oldName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' to '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(newName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': source table does not exist"); } logInstance.LogWarning(val); return; } string query2 = "SHOW TABLES LIKE '" + newName + "';"; DataTable dataTable2 = Plugin.SQLService.ExecuteQuery(query2); if (dataTable2 != null && dataTable2.Rows.Count > 0) { ManualLogSource logInstance2 = Plugin.LogInstance; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(57, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Cannot rename table '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(oldName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' to '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(newName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': target table already exists"); } logInstance2.LogWarning(val); return; } string query3 = $"RENAME TABLE `{oldName}` TO `{newName}`;"; Plugin.SQLService.ExecuteNonQuery(query3); ManualLogSource logInstance3 = Plugin.LogInstance; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(35, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Renamed table in database: '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(oldName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' to '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(newName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'"); } logInstance3.LogInfo(val2); } catch (Exception ex) { ManualLogSource logInstance4 = Plugin.LogInstance; BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(33, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Failed to rename table '"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(oldName); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("' to '"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(newName); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("': "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ex.Message); } logInstance4.LogError(val3); } } } } namespace CrimsonSQL.Services { public class SQLService : ISQLService { private static string connectionString; private static bool reportConnection = true; public SQLService() { connectionString = $"Server={Settings.Host.Value};Database={Settings.DatabaseName.Value};User ID={Settings.UserName.Value};Password={Settings.Password.Value};{Settings.Parameters.Value}"; Connect(); } public bool Connect() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0045: Expected O, but got Unknown //IL_0079: Unknown result type (might be due to invalid IL or missing references) try { MySqlConnection val = new MySqlConnection(connectionString); try { ((DbConnection)(object)val).Open(); if (reportConnection) { reportConnection = false; Plugin.LogInstance.LogInfo((object)"Connected to MySQL database."); Settings.MySQLConfigured = true; } return true; } finally { ((IDisposable)val)?.Dispose(); } } catch (MySqlException val2) { MySqlException val3 = val2; Settings.MySQLConfigured = false; Plugin.LogInstance.LogError((object)("Failed to connect to MySQL database. \nError Info:" + $"\nError Code: {val3.ErrorCode} " + $"\nNumber: {val3.Number} " + "\nMessage: " + ((Exception)(object)val3).Message + "\nInner: " + ((Exception)(object)val3).InnerException?.Message)); reportConnection = true; return false; } } public void CreateTable(string tableName, Dictionary<string, string> columns) { if (!Settings.MySQLConfigured) { Plugin.LogInstance.LogError((object)"Attempted to use CrimsonSQL with a misconfigured SQL."); return; } tableName = GetMappedTableName(tableName); string value = string.Join(", ", columns.Select((KeyValuePair<string, string> kvp) => kvp.Key + " " + kvp.Value)); string query = $"CREATE TABLE IF NOT EXISTS {tableName} ({value});"; ExecuteNonQuery(query); } public void ClearTable(string tableName) { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown if (!Settings.MySQLConfigured) { Plugin.LogInstance.LogError((object)"Attempted to use CrimsonSQL with a misconfigured SQL."); return; } tableName = GetMappedTableName(tableName); string query = "TRUNCATE TABLE " + tableName + ";"; bool flag = default(bool); try { ExecuteNonQuery(query); ManualLogSource logInstance = Plugin.LogInstance; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(39, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Table '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(tableName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' has been cleared successfully."); } logInstance.LogInfo(val); } catch (MySqlException) { string query2 = "DELETE FROM " + tableName + ";"; ExecuteNonQuery(query2); ManualLogSource logInstance2 = Plugin.LogInstance; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(46, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Table '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(tableName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' has been cleared using DELETE method."); } logInstance2.LogInfo(val); } } public int Insert(string tableName, Dictionary<string, object> values, List<int> handledExceptions = null) { //IL_0145: Expected O, but got Unknown //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown if (!Settings.MySQLConfigured) { Plugin.LogInstance.LogError((object)"Attempted to use CrimsonSQL with a misconfigured SQL."); return -1; } string value = string.Join(", ", values.Keys); string value2 = string.Join(", ", values.Keys.Select((string k) => "@" + k)); tableName = GetMappedTableName(tableName); string text = $"INSERT INTO {tableName} ({value}) VALUES ({value2}); SELECT LAST_INSERT_ID();"; MySqlConnection val = new MySqlConnection(connectionString); try { MySqlCommand val2 = new MySqlCommand(text, val); try { if (values != null) { foreach (KeyValuePair<string, object> value3 in values) { val2.Parameters.AddWithValue("@" + value3.Key, value3.Value); } } try { ((DbConnection)(object)val).Open(); return Convert.ToInt32(((DbCommand)(object)val2).ExecuteScalar()); } catch (MySqlException val3) { MySqlException val4 = val3; if (handledExceptions == null || !handledExceptions.Contains(val4.Number)) { Plugin.LogInstance.LogError((object)("MySQL Exception occurred: " + $"\nError Code: {val4.ErrorCode} " + $"\nNumber: {val4.Number} " + "\nMessage: " + ((Exception)(object)val4).Message + "\nInner: " + ((Exception)(object)val4).InnerException?.Message)); } return -val4.Number; } } finally { ((IDisposable)val2)?.Dispose(); } } finally { ((IDisposable)val)?.Dispose(); } } public void Delete(string tableName, Dictionary<string, object> whereConditions) { if (!Settings.MySQLConfigured) { Plugin.LogInstance.LogError((object)"Attempted to use CrimsonSQL with a misconfigured SQL."); return; } tableName = GetMappedTableName(tableName); string text = string.Join(" AND ", whereConditions.Keys.Select((string k) => k + " = @" + k)); string query = "DELETE FROM " + tableName + " WHERE " + text; ExecuteNonQuery(query, whereConditions); } public DataTable Select(string tableName, string[] columns = null, Dictionary<string, object> whereConditions = null) { if (!Settings.MySQLConfigured) { Plugin.LogInstance.LogError((object)"Attempted to use CrimsonSQL with a misconfigured SQL."); return null; } tableName = GetMappedTableName(tableName); string text = ((columns != null && columns.Any()) ? string.Join(", ", columns) : "*"); string text2 = "SELECT " + text + " FROM " + tableName; if (whereConditions != null && whereConditions.Any()) { string text3 = string.Join(" AND ", whereConditions.Keys.Select((string k) => k + " = @" + k)); text2 = text2 + " WHERE " + text3; } return ExecuteQuery(text2, whereConditions); } public int Replace(string tableName, Dictionary<string, object> whereConditions, Dictionary<string, object> newValues) { //IL_0211: Expected O, but got Unknown //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Expected O, but got Unknown if (!Settings.MySQLConfigured) { Plugin.LogInstance.LogError((object)"Attempted to use CrimsonSQL with a misconfigured SQL."); return -1; } tableName = GetMappedTableName(tableName); MySqlConnection val = new MySqlConnection(connectionString); try { ((DbConnection)(object)val).Open(); MySqlTransaction val2 = val.BeginTransaction(); try { string text = string.Join(" AND ", whereConditions.Keys.Select((string k) => k + " = @" + k)); MySqlCommand val3 = new MySqlCommand("DELETE FROM " + tableName + " WHERE " + text, val, val2); try { foreach (KeyValuePair<string, object> whereCondition in whereConditions) { val3.Parameters.AddWithValue("@" + whereCondition.Key, whereCondition.Value); } ((DbCommand)(object)val3).ExecuteNonQuery(); } finally { ((IDisposable)val3)?.Dispose(); } string value = string.Join(", ", newValues.Keys); string value2 = string.Join(", ", newValues.Keys.Select((string k) => "@" + k)); MySqlCommand val4 = new MySqlCommand($"INSERT INTO {tableName} ({value}) VALUES ({value2}); SELECT LAST_INSERT_ID();", val, val2); try { foreach (KeyValuePair<string, object> newValue in newValues) { val4.Parameters.AddWithValue("@" + newValue.Key, newValue.Value); } int result = Convert.ToInt32(((DbCommand)(object)val4).ExecuteScalar()); ((DbTransaction)(object)val2).Commit(); return result; } finally { ((IDisposable)val4)?.Dispose(); } } catch (MySqlException val5) { MySqlException val6 = val5; ((DbTransaction)(object)val2).Rollback(); Plugin.LogInstance.LogError((object)("MySQL Exception occurred during Replace: " + $"\nError Code: {val6.ErrorCode} " + $"\nNumber: {val6.Number} " + "\nMessage: " + ((Exception)(object)val6).Message + "\nInner: " + ((Exception)(object)val6).InnerException?.Message)); return -val6.Number; } finally { ((IDisposable)val2)?.Dispose(); } } finally { ((IDisposable)val)?.Dispose(); } } public DataTable ExecuteQuery(string query, Dictionary<string, object> parameters = null) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown if (!Settings.MySQLConfigured) { Plugin.LogInstance.LogError((object)"Attempted to use CrimsonSQL with a misconfigured SQL."); } MySqlConnection val = new MySqlConnection(connectionString); try { MySqlCommand val2 = new MySqlCommand(query, val); try { if (parameters != null) { foreach (KeyValuePair<string, object> parameter in parameters) { val2.Parameters.AddWithValue("@" + parameter.Key, parameter.Value); } } ((DbConnection)(object)val).Open(); MySqlDataReader val3 = val2.ExecuteReader(); try { DataTable dataTable = new DataTable(); dataTable.Load((IDataReader)val3); return dataTable; } finally { ((IDisposable)val3)?.Dispose(); } } finally { ((IDisposable)val2)?.Dispose(); } } finally { ((IDisposable)val)?.Dispose(); } } public void ExecuteNonQuery(string query, Dictionary<string, object> parameters = null) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown if (!Settings.MySQLConfigured) { Plugin.LogInstance.LogError((object)"Attempted to use CrimsonSQL with a misconfigured SQL."); } MySqlConnection val = new MySqlConnection(connectionString); try { MySqlCommand val2 = new MySqlCommand(query, val); try { if (parameters != null) { foreach (KeyValuePair<string, object> parameter in parameters) { val2.Parameters.AddWithValue("@" + parameter.Key, parameter.Value); } } ((DbConnection)(object)val).Open(); ((DbCommand)(object)val2).ExecuteNonQuery(); } finally { ((IDisposable)val2)?.Dispose(); } } finally { ((IDisposable)val)?.Dispose(); } } public List<int> ExecuteBatch(List<BatchOperation> operations) { //IL_0165: Expected O, but got Unknown //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown if (!Settings.MySQLConfigured) { Plugin.LogInstance.LogError((object)"Attempted to use CrimsonSQL with a misconfigured SQL."); return operations.Select((BatchOperation o) => -1).ToList(); } foreach (BatchOperation operation in operations) { operation.TableName = GetMappedTableName(operation.TableName); } MySqlConnection val = new MySqlConnection(connectionString); try { ((DbConnection)(object)val).Open(); MySqlTransaction val2 = val.BeginTransaction(); try { List<int> list = new List<int>(); foreach (BatchOperation operation2 in operations) { int num = -1; switch (operation2.OperationType) { case BatchOperationType.Insert: num = ExecuteInsertInBatch(val, val2, operation2); break; case BatchOperationType.Delete: ExecuteDeleteInBatch(val, val2, operation2); num = 0; break; case BatchOperationType.Update: num = ExecuteUpdateInBatch(val, val2, operation2); break; case BatchOperationType.Replace: num = ExecuteReplaceInBatch(val, val2, operation2); break; case BatchOperationType.CustomSQL: num = ExecuteCustomSQLInBatch(val, val2, operation2); break; } operation2.ResultId = num; list.Add(num); } ((DbTransaction)(object)val2).Commit(); return list; } catch (MySqlException val3) { MySqlException val4 = val3; MySqlException e = val4; ((DbTransaction)(object)val2).Rollback(); Plugin.LogInstance.LogError((object)("MySQL Exception occurred during batch operation: " + $"\nError Code: {e.ErrorCode} " + $"\nNumber: {e.Number} " + "\nMessage: " + ((Exception)(object)e).Message + "\nInner: " + ((Exception)(object)e).InnerException?.Message)); return operations.Select((BatchOperation o) => -e.Number).ToList(); } finally { ((IDisposable)val2)?.Dispose(); } } finally { ((IDisposable)val)?.Dispose(); } } private int ExecuteInsertInBatch(MySqlConnection connection, MySqlTransaction transaction, BatchOperation operation) { //IL_011d: Expected O, but got Unknown //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown string value = string.Join(", ", operation.Values.Keys); string value2 = string.Join(", ", operation.Values.Keys.Select((string k) => "@" + k)); MySqlCommand val = new MySqlCommand($"INSERT INTO {operation.TableName} ({value}) VALUES ({value2}); SELECT LAST_INSERT_ID();", connection, transaction); try { foreach (KeyValuePair<string, object> value3 in operation.Values) { val.Parameters.AddWithValue("@" + value3.Key, value3.Value); } try { return Convert.ToInt32(((DbCommand)(object)val).ExecuteScalar()); } catch (MySqlException val2) { MySqlException val3 = val2; if (operation.HandledExceptions == null || !operation.HandledExceptions.Contains(val3.Number)) { throw; } return -val3.Number; } } finally { ((IDisposable)val)?.Dispose(); } } private void ExecuteDeleteInBatch(MySqlConnection connection, MySqlTransaction transaction, BatchOperation operation) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown string text = string.Join(" AND ", operation.WhereConditions.Keys.Select((string k) => k + " = @" + k)); MySqlCommand val = new MySqlCommand("DELETE FROM " + operation.TableName + " WHERE " + text, connection, transaction); try { foreach (KeyValuePair<string, object> whereCondition in operation.WhereConditions) { val.Parameters.AddWithValue("@" + whereCondition.Key, whereCondition.Value); } ((DbCommand)(object)val).ExecuteNonQuery(); } finally { ((IDisposable)val)?.Dispose(); } } private int ExecuteUpdateInBatch(MySqlConnection connection, MySqlTransaction transaction, BatchOperation operation) { //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Expected O, but got Unknown string value = string.Join(", ", operation.Values.Keys.Select((string k) => k + " = @" + k)); string value2 = string.Join(" AND ", operation.WhereConditions.Keys.Select((string k) => k + " = @where_" + k)); MySqlCommand val = new MySqlCommand($"UPDATE {operation.TableName} SET {value} WHERE {value2}", connection, transaction); try { foreach (KeyValuePair<string, object> value3 in operation.Values) { val.Parameters.AddWithValue("@" + value3.Key, value3.Value); } foreach (KeyValuePair<string, object> whereCondition in operation.WhereConditions) { val.Parameters.AddWithValue("@where_" + whereCondition.Key, whereCondition.Value); } return ((DbCommand)(object)val).ExecuteNonQuery(); } finally { ((IDisposable)val)?.Dispose(); } } private int ExecuteReplaceInBatch(MySqlConnection connection, MySqlTransaction transaction, BatchOperation operation) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Expected O, but got Unknown string text = string.Join(" AND ", operation.WhereConditions.Keys.Select((string k) => k + " = @" + k)); MySqlCommand val = new MySqlCommand("DELETE FROM " + operation.TableName + " WHERE " + text, connection, transaction); try { foreach (KeyValuePair<string, object> whereCondition in operation.WhereConditions) { val.Parameters.AddWithValue("@" + whereCondition.Key, whereCondition.Value); } ((DbCommand)(object)val).ExecuteNonQuery(); } finally { ((IDisposable)val)?.Dispose(); } string value = string.Join(", ", operation.Values.Keys); string value2 = string.Join(", ", operation.Values.Keys.Select((string k) => "@" + k)); MySqlCommand val2 = new MySqlCommand($"INSERT INTO {operation.TableName} ({value}) VALUES ({value2}); SELECT LAST_INSERT_ID();", connection, transaction); try { foreach (KeyValuePair<string, object> value3 in operation.Values) { val2.Parameters.AddWithValue("@" + value3.Key, value3.Value); } return Convert.ToInt32(((DbCommand)(object)val2).ExecuteScalar()); } finally { ((IDisposable)val2)?.Dispose(); } } private int ExecuteCustomSQLInBatch(MySqlConnection connection, MySqlTransaction transaction, BatchOperation operation) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown MySqlCommand val = new MySqlCommand(operation.CustomQuery, connection, transaction); try { foreach (KeyValuePair<string, object> value in operation.Values) { val.Parameters.AddWithValue("@" + value.Key, value.Value); } if (operation.CustomQuery.Contains("SELECT LAST_INSERT_ID()")) { return Convert.ToInt32(((DbCommand)(object)val).ExecuteScalar()); } return ((DbCommand)(object)val).ExecuteNonQuery(); } finally { ((IDisposable)val)?.Dispose(); } } private string GetMappedTableName(string originalTableName) { return Plugin.TableMapping.GetMappedTableName(originalTableName); } } } namespace CrimsonSQL.API { public interface ISQLService { bool Connect(); void ExecuteNonQuery(string query, Dictionary<string, object> parameters = null); DataTable ExecuteQuery(string query, Dictionary<string, object> parameters = null); void CreateTable(string tableName, Dictionary<string, string> columns); int Insert(string tableName, Dictionary<string, object> values, List<int> handledExceptions = null); void Delete(string tableName, Dictionary<string, object> whereConditions); DataTable Select(string tableName, string[] columns = null, Dictionary<string, object> whereConditions = null); int Replace(string tableName, Dictionary<string, object> whereConditions, Dictionary<string, object> newValues); List<int> ExecuteBatch(List<BatchOperation> operations); void ClearTable(string tableName); } } namespace Costura { [CompilerGenerated] internal static class AssemblyLoader { private static object nullCacheLock = new object(); private static Dictionary<string, bool> nullCache = new Dictionary<string, bool>(); private static Dictionary<string, string> assemblyNames = new Dictionary<string, string>(); private static Dictionary<string, string> symbolNames = new Dictionary<string, string>(); private static int isAttached; private static string CultureToString(CultureInfo culture) { if (culture == null) { return ""; } return culture.Name; } private static Assembly ReadExistingAssembly(AssemblyName name) { AppDomain currentDomain = AppDomain.CurrentDomain; Assembly[] assemblies = currentDomain.GetAssemblies(); Assembly[] array = assemblies; foreach (Assembly assembly in array) { AssemblyName name2 = assembly.GetName(); if (string.Equals(name2.Name, name.Name, StringComparison.InvariantCultureIgnoreCase) && string.Equals(CultureToString(name2.CultureInfo), CultureToString(name.CultureInfo), StringComparison.InvariantCultureIgnoreCase)) { return assembly; } } return null; } private static void CopyTo(Stream source, Stream destination) { byte[] array = new byte[81920]; int count; while ((count = source.Read(array, 0, array.Length)) != 0) { destination.Write(array, 0, count); } } private static Stream LoadStream(string fullName) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); if (fullName.EndsWith(".compressed")) { using (Stream stream = executingAssembly.GetManifestResourceStream(fullName)) { using DeflateStream source = new DeflateStream(stream, CompressionMode.Decompress); MemoryStream memoryStream = new MemoryStream(); CopyTo(source, memoryStream); memoryStream.Position = 0L; return memoryStream; } } return executingAssembly.GetManifestResourceStream(fullName); } private static Stream LoadStream(Dictionary<string, string> resourceNames, string name) { if (resourceNames.TryGetValue(name, out var value)) { return LoadStream(value); } return null; } private static byte[] ReadStream(Stream stream) { byte[] array = new byte[stream.Length]; stream.Read(array, 0, array.Length); return array; } private static Assembly ReadFromEmbeddedResources(Dictionary<string, string> assemblyNames, Dictionary<string, string> symbolNames, AssemblyName requestedAssemblyName) { string text = requestedAssemblyName.Name.ToLowerInvariant(); if (requestedAssemblyName.CultureInfo != null && !string.IsNullOrEmpty(requestedAssemblyName.CultureInfo.Name)) { text = requestedAssemblyName.CultureInfo.Name + "." + text; } byte[] rawAssembly; using (Stream stream = LoadStream(assemblyNames, text)) { if (stream == null) { return null; } rawAssembly = ReadStream(stream); } using (Stream stream2 = LoadStream(symbolNames, text)) { if (stream2 != null) { byte[] rawSymbolStore = ReadStream(stream2); return Assembly.Load(rawAssembly, rawSymbolStore); } } return Assembly.Load(rawAssembly); } public static Assembly ResolveAssembly(object sender, ResolveEventArgs e) { lock (nullCacheLock) { if (nullCache.ContainsKey(e.Name)) { return null; } } AssemblyName assemblyName = new AssemblyName(e.Name); Assembly assembly = ReadExistingAssembly(assemblyName); if ((object)assembly != null) { return assembly; } assembly = ReadFromEmbeddedResources(assemblyNames, symbolNames, assemblyName); if ((object)assembly == null) { lock (nullCacheLock) { nullCache[e.Name] = true; } if ((assemblyName.Flags & AssemblyNameFlags.Retargetable) != 0) { assembly = Assembly.Load(assemblyName); } } return assembly; } public static void Attach() { if (Interlocked.Exchange(ref isAttached, 1) == 1) { return; } AppDomain currentDomain = AppDomain.CurrentDomain; currentDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs e) { lock (nullCacheLock) { if (nullCache.ContainsKey(e.Name)) { return null; } } AssemblyName assemblyName = new AssemblyName(e.Name); Assembly assembly = ReadExistingAssembly(assemblyName); if ((object)assembly != null) { return assembly; } assembly = ReadFromEmbeddedResources(assemblyNames, symbolNames, assemblyName); if ((object)assembly == null) { lock (nullCacheLock) { nullCache[e.Name] = true; } if ((assemblyName.Flags & AssemblyNameFlags.Retargetable) != 0) { assembly = Assembly.Load(assemblyName); } } return assembly; }; } } } internal class CrimsonSQL_ProcessedByFody { internal const string FodyVersion = "6.9.1.0"; internal const string Costura = "5.7.0"; }