using 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.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 MySql.Data.MySqlClient;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("CrimsonSQL")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A V Rising Framework for using MySQL")]
[assembly: AssemblyFileVersion("1.1.1.0")]
[assembly: AssemblyInformationalVersion("1.1.1+Branch.master.Sha.72f5c0043010b75f50c100c9b35de7dda0b5b894.72f5c0043010b75f50c100c9b35de7dda0b5b894")]
[assembly: AssemblyProduct("CrimsonSQL")]
[assembly: AssemblyTitle("CrimsonSQL")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.1.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.1.1")]
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 ISQLService SQLService { get; private set; }
public override void Load()
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Expected O, but got Unknown
Instance = this;
Settings = default(Settings);
Settings.InitConfig();
_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.1.1";
}
}
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("MySql.Data"))
{
text = "CrimsonSQL._9._1._0.lib.net6._0.MySql.Data.dll";
}
else if (name.StartsWith("System.Diagnostics.DiagnosticSource"))
{
text = "CrimsonSQL._8._0._1.lib.net6._0.System.Diagnostics.DiagnosticSource.dll";
}
else if (name.StartsWith("System.Security.Permissions"))
{
text = "CrimsonSQL._8._0._0.lib.net6._0.System.Security.Permissions.dll";
}
else if (name.StartsWith("System.Configuration.ConfigurationManager"))
{
text = "CrimsonSQL._8._0._0.lib.net6._0.System.Configuration.ConfigurationManager.dll";
}
else
{
if (!name.StartsWith("System.Text.Encoding.CodePages"))
{
goto IL_00a8;
}
text = "CrimsonSQL._8._0._0.lib.net6._0.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
{
[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;
}
}
}
namespace CrimsonSQL.Services
{
internal class SQLService : ISQLService
{
private static string connectionString;
public SQLService()
{
AssemblyResolver.Resolve();
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_0032: Expected O, but got Unknown
try
{
MySqlConnection val = new MySqlConnection(connectionString);
try
{
((DbConnection)(object)val).Open();
Plugin.LogInstance.LogInfo((object)"Connected to MySQL database.");
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: {((ExternalException)(object)val3).ErrorCode} " + $"\nNumber: {val3.Number} " + "\nMessage: " + ((Exception)(object)val3).Message + "\nInner: " + ((Exception)(object)val3).InnerException.Message));
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.");
}
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 int Insert(string tableName, Dictionary<string, object> values)
{
//IL_013a: Expected O, but got Unknown
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Expected O, but got Unknown
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Expected O, but got Unknown
if (!Settings.MySQLConfigured)
{
Plugin.LogInstance.LogError((object)"Attempted to use CrimsonSQL with a misconfigured SQL.");
}
string value = string.Join(", ", values.Keys);
string value2 = string.Join(", ", values.Keys.Select((string k) => "@" + k));
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;
Plugin.LogInstance.LogError((object)("MySQL Exception occurred: " + $"\nError Code: {((ExternalException)(object)val4).ErrorCode} " + $"\nNumber: {val4.Number} " + "\nMessage: " + ((Exception)(object)val4).Message + "\nInner: " + ((Exception)(object)val4).InnerException?.Message));
return -1;
}
}
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.");
}
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.");
}
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 bool Replace(string tableName, Dictionary<string, object> whereConditions, Dictionary<string, object> newValues)
{
//IL_013d: Expected O, but got Unknown
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Expected O, but got Unknown
if (!Settings.MySQLConfigured)
{
Plugin.LogInstance.LogError((object)"Attempted to use CrimsonSQL with a misconfigured SQL.");
return false;
}
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));
string query = "DELETE FROM " + tableName + " WHERE " + text;
ExecuteNonQuery(query, whereConditions);
string value = string.Join(", ", newValues.Keys);
string value2 = string.Join(", ", newValues.Keys.Select((string k) => "@" + k));
string query2 = $"INSERT INTO {tableName} ({value}) VALUES ({value2})";
ExecuteNonQuery(query2, newValues);
((DbTransaction)(object)val2).Commit();
return true;
}
catch (MySqlException val3)
{
MySqlException val4 = val3;
((DbTransaction)(object)val2).Rollback();
Plugin.LogInstance.LogError((object)("MySQL Exception occurred during Replace: " + $"\nError Code: {((ExternalException)(object)val4).ErrorCode} " + $"\nNumber: {val4.Number} " + "\nMessage: " + ((Exception)(object)val4).Message + "\nInner: " + ((Exception)(object)val4).InnerException?.Message));
return false;
}
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();
}
}
}
}
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);
void Delete(string tableName, Dictionary<string, object> whereConditions);
DataTable Select(string tableName, string[] columns = null, Dictionary<string, object> whereConditions = null);
bool Replace(string tableName, Dictionary<string, object> whereConditions, Dictionary<string, object> newValues);
}
}
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";
}