diff --git a/CLI/Program.cs b/CLI/Program.cs
index 58b4db1d6..77af7b603 100644
--- a/CLI/Program.cs
+++ b/CLI/Program.cs
@@ -217,7 +217,8 @@ public static class Program {
if (part.Length == 0) continue;
ConsoleColor color = GetConsoleColor(curCol);
- if (color == ConsoleColor.White) {
+ if (color == ConsoleColor.White) {
+ // show in user's preferred console text color
Console.ResetColor();
} else {
Console.ForegroundColor = color;
diff --git a/MCGalaxy/Database/Backends/MySQL.cs b/MCGalaxy/Database/Backends/MySQL.cs
index 49d322577..1d40d9236 100644
--- a/MCGalaxy/Database/Backends/MySQL.cs
+++ b/MCGalaxy/Database/Backends/MySQL.cs
@@ -22,9 +22,10 @@
using System.Text;
using MySql.Data.MySqlClient;
-namespace MCGalaxy.SQL {
-
- public sealed class MySQLBackend : IDatabaseBackend {
+namespace MCGalaxy.SQL
+{
+ public sealed class MySQLBackend : IDatabaseBackend
+ {
public static IDatabaseBackend Instance = new MySQLBackend();
public MySQLBackend() {
// MySQL uses case insensitive collation by default
@@ -33,7 +34,8 @@ public sealed class MySQLBackend : IDatabaseBackend {
}
public override bool EnforcesTextLength { get { return true; } }
- public override bool MultipleSchema { get { return true; } }
+ public override bool MultipleSchema { get { return true; } }
+ public override string EngineName { get { return "MySQL"; } }
internal override IDbConnection CreateConnection() {
const string format = "Data Source={0};Port={1};User ID={2};Password={3};Pooling={4};Treat Tiny As Boolean=false;";
@@ -51,6 +53,9 @@ public sealed class MySQLBackend : IDatabaseBackend {
}
+ public override void LoadDependencies() {
+ }
+
public override void CreateDatabase() {
string sql = "CREATE DATABASE if not exists `" + Server.Config.MySQLDatabaseName + "`";
Database.Do(sql, true, null, null);
diff --git a/MCGalaxy/Database/Backends/SQLite.cs b/MCGalaxy/Database/Backends/SQLite.cs
index d1a4421f1..2fddce14a 100644
--- a/MCGalaxy/Database/Backends/SQLite.cs
+++ b/MCGalaxy/Database/Backends/SQLite.cs
@@ -21,17 +21,19 @@
using System.IO;
using System.Text;
-namespace MCGalaxy.SQL {
-
- public sealed class SQLiteBackend : IDatabaseBackend {
+namespace MCGalaxy.SQL
+{
+ public sealed class SQLiteBackend : IDatabaseBackend
+ {
public static IDatabaseBackend Instance = new SQLiteBackend();
public SQLiteBackend() {
CaselessWhereSuffix = " COLLATE NOCASE";
- CaselessLikeSuffix = " COLLATE NOCASE";
+ CaselessLikeSuffix = " COLLATE NOCASE";
}
public override bool EnforcesTextLength { get { return false; } }
public override bool MultipleSchema { get { return false; } }
+ public override string EngineName { get { return "SQLite"; } }
internal override IDbConnection CreateConnection() {
return new MCGSQLiteConnection();
@@ -43,9 +45,26 @@ public sealed class SQLiteBackend : IDatabaseBackend {
internal override IDbDataParameter CreateParameter() {
return new SQLiteParameter();
+ }
+
+
+ public override void LoadDependencies() {
+ // on macOS/Linux, use the system provided sqlite3 native library
+ if (!IOperatingSystem.DetectOS().IsWindows) return;
+
+ Server.CheckFile("sqlite3_x32.dll");
+ Server.CheckFile("sqlite3_x64.dll");
+
+ // sqlite3.dll is the .DLL that MCGalaxy will actually load on Windows
+ try {
+ string dll = IntPtr.Size == 8 ? "sqlite3_x64.dll" : "sqlite3_x32.dll";
+ if (File.Exists(dll)) File.Copy(dll, "sqlite3.dll", true);
+ } catch (Exception ex) {
+ // e.g. can happen when multiple server instances running
+ Logger.LogError("Error moving SQLite dll", ex);
+ }
}
-
-
+
public override void CreateDatabase() { }
public override string RawGetDateTime(IDataRecord record, int col) {
diff --git a/MCGalaxy/Database/IDatabaseBackend.cs b/MCGalaxy/Database/IDatabaseBackend.cs
index a2feaf7e0..0b479be52 100644
--- a/MCGalaxy/Database/IDatabaseBackend.cs
+++ b/MCGalaxy/Database/IDatabaseBackend.cs
@@ -30,6 +30,7 @@ public abstract class IDatabaseBackend
public abstract bool EnforcesTextLength { get; }
/// Whether this backend supports multiple database schemas.
public abstract bool MultipleSchema { get; }
+ public abstract string EngineName { get; }
internal abstract IDbConnection CreateConnection();
internal abstract IDbCommand CreateCommand(string sql, IDbConnection conn);
@@ -41,6 +42,8 @@ public abstract class IDatabaseBackend
public string CaselessLikeSuffix { get; protected set; }
+ /// Downloads and/or moves required DLLs
+ public abstract void LoadDependencies();
/// Creates the schema for this database (if required).
public abstract void CreateDatabase();
diff --git a/MCGalaxy/Database/PlayerData.cs b/MCGalaxy/Database/PlayerData.cs
index 9a24d5d40..bbb5169e8 100644
--- a/MCGalaxy/Database/PlayerData.cs
+++ b/MCGalaxy/Database/PlayerData.cs
@@ -62,12 +62,12 @@ public class PlayerData {
"totalDeaths, Money, totalBlocks, totalKicked, Messages, TimeSpent",
p.name, p.ip, now, now, 1, "", 0, 0, 0, 0, 0, (long)p.TotalTime.TotalSeconds);
- int id = -100000;
+ int id = -200;
Database.ReadRows("Players", "ID",
record => id = record.GetInt32(0),
"WHERE Name=@0", p.name);
- if (id >= 0) {
+ if (id != -200) {
p.DatabaseID = id;
} else {
p.DatabaseID = NameConverter.InvalidNameID(p.name);
@@ -136,7 +136,6 @@ record => id = record.GetInt32(0),
data.TotalDeleted = UnpackHi(drawn);
return data;
}
- internal static object Read(IDataRecord record, object arg) { return Parse(record); }
internal static long ParseLong(string value) {
return (value.Length == 0 || value.CaselessEq("null")) ? 0 : long.Parse(value);
diff --git a/MCGalaxy/Server/OperatingSystem.cs b/MCGalaxy/Server/OperatingSystem.cs
index 300cf29a3..b18647d6a 100644
--- a/MCGalaxy/Server/OperatingSystem.cs
+++ b/MCGalaxy/Server/OperatingSystem.cs
@@ -35,9 +35,16 @@ public abstract class IOperatingSystem
/// Does not return when restart is successful
/// (since current process image is replaced)
public abstract void RestartProcess();
+ public abstract bool IsWindows { get; }
+ static IOperatingSystem detectedOS;
public unsafe static IOperatingSystem DetectOS() {
+ detectedOS = detectedOS ?? DoDetectOS();
+ return detectedOS;
+ }
+
+ unsafe static IOperatingSystem DoDetectOS() {
PlatformID platform = Environment.OSVersion.Platform;
if (platform == PlatformID.Win32NT || platform == PlatformID.Win32Windows)
return new WindowsOS();
@@ -71,6 +78,7 @@ class WindowsOS : IOperatingSystem
static extern int GetSystemTimes(out ulong idleTime, out ulong kernelTime, out ulong userTime);
public override void RestartProcess() { }
+ public override bool IsWindows { get { return true; } }
}
class macOS : UnixOS
@@ -134,6 +142,7 @@ class UnixOS : IOperatingSystem
public override void RestartProcess() {
if (Server.CLIMode) HACK_Execvp();
}
+ public override bool IsWindows { get { return false; } }
#if !NETSTANDARD
[DllImport("libc", SetLastError = true)]
diff --git a/MCGalaxy/Server/Server.DB.cs b/MCGalaxy/Server/Server.DB.cs
index 3b65d63df..542798ccd 100644
--- a/MCGalaxy/Server/Server.DB.cs
+++ b/MCGalaxy/Server/Server.DB.cs
@@ -53,7 +53,8 @@ public sealed partial class Server {
static void InitDatabase() {
if (!Directory.Exists("blockdb")) Directory.CreateDirectory("blockdb");
-
+
+ Logger.Log(LogType.SystemActivity, "Using {0} for database backend", Database.Backend.EngineName);
try {
Database.Backend.CreateDatabase();
} catch (Exception e) {
diff --git a/MCGalaxy/Server/Server.cs b/MCGalaxy/Server/Server.cs
index a21c566ff..9024071de 100644
--- a/MCGalaxy/Server/Server.cs
+++ b/MCGalaxy/Server/Server.cs
@@ -20,7 +20,6 @@
using System.Diagnostics;
using System.IO;
using System.Net;
-using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
@@ -33,6 +32,7 @@
using MCGalaxy.Games;
using MCGalaxy.Network;
using MCGalaxy.Scripting;
+using MCGalaxy.SQL;
using MCGalaxy.Tasks;
using MCGalaxy.Util;
using MCGalaxy.Modules.Awards;
@@ -60,7 +60,7 @@ public sealed partial class Server
Logger.Log(type, message);
}
- static void CheckFile(string file) {
+ public static void CheckFile(string file) {
if (File.Exists(file)) return;
Logger.Log(LogType.SystemActivity, file + " doesn't exist, Downloading..");
@@ -91,14 +91,12 @@ public sealed partial class Server
shuttingDown = false;
Logger.Log(LogType.SystemActivity, "Starting Server");
ServicePointManager.Expect100Continue = false;
- ForceEnableTLS();
-
- CheckFile("MySql.Data.dll");
- CheckFile("sqlite3_x32.dll");
- CheckFile("sqlite3_x64.dll");
+ ForceEnableTLS();
+
+ SQLiteBackend.Instance.LoadDependencies();
+ CheckFile("MySql.Data.dll"); // TODO move to MySQL backend ?
EnsureFilesExist();
- MoveSqliteDll();
MoveOutdatedFiles();
LoadAllSettings();
@@ -128,15 +126,6 @@ public sealed partial class Server
try { ServicePointManager.SecurityProtocol |= (SecurityProtocolType)0xC00; } catch { }
}
- static void MoveSqliteDll() {
- try {
- string dll = IntPtr.Size == 8 ? "sqlite3_x64.dll" : "sqlite3_x32.dll";
- if (File.Exists(dll)) File.Copy(dll, "sqlite3.dll", true);
- } catch (Exception ex) {
- Logger.LogError("Error moving SQLite dll", ex);
- }
- }
-
static void EnsureFilesExist() {
EnsureDirectoryExists("properties");
EnsureDirectoryExists("levels");