// LiteDbManager.cs using LiteDB; using System; using System.Collections.Generic; using System.IO; using System.Linq; namespace FreelancerListServer { public class LiteDbManager : IDisposable { private readonly LiteDatabase _db; private readonly ILiteCollection _servers; private readonly ILiteCollection _monitoring; private readonly ILiteCollection _configurations; private readonly Logger _logger; public LiteDbManager(string dbPath = "freelancer.db") { // Shared Mode var connectionString = new ConnectionString(dbPath) { Connection = ConnectionType.Shared }; _db = new LiteDatabase(connectionString); _servers = _db.GetCollection("servers"); _monitoring = _db.GetCollection("monitoring"); _configurations = _db.GetCollection("configurations"); _logger = new Logger(); // Indizes für schnellere Abfragen _servers.EnsureIndex(x => x.GameId); _monitoring.EnsureIndex(x => x.GameId); _configurations.EnsureIndex(x => x.Key); // Standard-Konfigurationswerte setzen InitializeDefaultConfigurations(); } private void InitializeDefaultConfigurations() { var defaultConfigs = new Dictionary { { "LocalServerIp", "192.168.200.10" }, { "PublicServerIp", "195.201.106.232" } }; foreach (var config in defaultConfigs) { if (_configurations.FindOne(x => x.Key == config.Key) == null) { _configurations.Insert(new Configuration { Key = config.Key, Value = config.Value }); _logger.Log($"Initialized default configuration: {config.Key} = {config.Value}"); } } } public string GetConfiguration(string key, string defaultValue = null) { var config = _configurations.FindOne(x => x.Key == key); if (config == null) { _logger.Log($"Configuration key {key} not found, returning default: {defaultValue}"); return defaultValue; } return config.Value; } public void SetConfiguration(string key, string value) { var config = _configurations.FindOne(x => x.Key == key); if (config != null) { config.Value = value; _configurations.Update(config); _logger.Log($"Updated configuration: {key} = {value}"); } else { _configurations.Insert(new Configuration { Key = key, Value = value }); _logger.Log($"Inserted new configuration: {key} = {value}"); } } public void UpdateServer(string gameId, ServerInfo server) { var existingServer = _servers.FindOne(x => x.GameId == gameId); if (existingServer != null) { existingServer.Name = ConvertNameToHtmlEntities(server.Name ?? "Unknown"); existingServer.IP = server.IP; existingServer.GamePort = server.GamePort; existingServer.ClientPort = server.ClientPort; existingServer.MaxPlayers = server.MaxPlayers ?? "0"; existingServer.Pass = server.Pass ?? "0"; existingServer.PvP = server.PvP ?? "0"; existingServer.GameOpts = server.GameOpts ?? ""; existingServer.Active = server.Active; existingServer.LastSeen = server.LastSeen; existingServer.Id = server.Id; _servers.Update(existingServer); } else { server.GameId = gameId; server.Name = ConvertNameToHtmlEntities(server.Name ?? "Unknown"); _servers.Insert(server); } _logger.Log($"Updated server in LiteDB: GameId={gameId}, Name={server.Name}, IP={server.IP}, GamePort={server.GamePort}"); } public void UpdateMonitoring(string gameId, string session, string maxPlayers, string players, string instanceGuid, string name) { var monitoringInfo = _monitoring.FindOne(x => x.GameId == gameId); if (monitoringInfo != null) { monitoringInfo.Session = session; monitoringInfo.MaxPlayers = maxPlayers; monitoringInfo.Players = players; monitoringInfo.InstanceGuid = instanceGuid; monitoringInfo.Name = name; _monitoring.Update(monitoringInfo); } else { _monitoring.Insert(new MonitoringInfo { GameId = gameId, Session = session, MaxPlayers = maxPlayers, Players = players, InstanceGuid = instanceGuid, Name = name }); } _logger.Log($"Updated monitoring in LiteDB: GameId={gameId}, Players={players}/{maxPlayers}, Name={name}"); } public Dictionary> GetServers() { var result = new Dictionary>(); foreach (var server in _servers.FindAll()) { var dict = new Dictionary { ["GameId"] = server.GameId, ["Name"] = server.Name, ["IP"] = server.IP, ["GamePort"] = server.GamePort.ToString(), ["MaxPlayers"] = server.MaxPlayers, ["Pass"] = server.Pass, ["PvP"] = server.PvP, ["GameOpts"] = server.GameOpts }; result[$"Server_{server.GameId}"] = dict; } return result; } public void MigrateFromIni(string serversIniPath, string monitoringIniPath, bool updateExisting = false) { int serversImported = 0; int serversSkipped = 0; int monitoringImported = 0; int monitoringSkipped = 0; // Migration für servers.ini if (File.Exists(serversIniPath)) { var iniFile = new IniFile(serversIniPath); var servers = iniFile.GetServers(); foreach (var section in servers) { var serverData = section.Value; if (serverData.TryGetValue("GameId", out var gameId) && !string.IsNullOrEmpty(gameId)) { // Prüfen, ob der Server bereits in der Datenbank existiert if (_servers.FindOne(x => x.GameId == gameId) != null) { if (updateExisting) { // Bestehenden Server aktualisieren var serverInfo = new ServerInfo { GameId = gameId, Name = serverData.GetValueOrDefault("Name", "Unknown"), IP = serverData.GetValueOrDefault("IP", "0.0.0.0"), GamePort = int.TryParse(serverData.GetValueOrDefault("GamePort", "2300"), out var port) ? port : 2300, MaxPlayers = serverData.GetValueOrDefault("MaxPlayers", "0"), Pass = serverData.GetValueOrDefault("Pass", "0"), PvP = serverData.GetValueOrDefault("PvP", "0"), GameOpts = serverData.GetValueOrDefault("GameOpts", ""), Active = false, LastSeen = DateTime.MinValue }; UpdateServer(gameId, serverInfo); serversImported++; _logger.Log($"Updated existing server from {serversIniPath}: GameId={gameId}"); } else { serversSkipped++; _logger.Log($"Skipped existing server from {serversIniPath}: GameId={gameId}"); } } else { // Neuen Server importieren var serverInfo = new ServerInfo { GameId = gameId, Name = serverData.GetValueOrDefault("Name", "Unknown"), IP = serverData.GetValueOrDefault("IP", "0.0.0.0"), GamePort = int.TryParse(serverData.GetValueOrDefault("GamePort", "2300"), out var port) ? port : 2300, MaxPlayers = serverData.GetValueOrDefault("MaxPlayers", "0"), Pass = serverData.GetValueOrDefault("Pass", "0"), PvP = serverData.GetValueOrDefault("PvP", "0"), GameOpts = serverData.GetValueOrDefault("GameOpts", ""), Active = false, LastSeen = DateTime.MinValue }; UpdateServer(gameId, serverInfo); serversImported++; _logger.Log($"Imported new server from {serversIniPath}: GameId={gameId}"); } } } _logger.Log($"Migrated {serversImported} servers, skipped {serversSkipped} existing servers from {serversIniPath} to LiteDB."); } // Migration für monitoring.ini if (File.Exists(monitoringIniPath)) { var monitoringIni = new MonitoringIniFile(monitoringIniPath); var monitoringData = monitoringIni.GetServers(); foreach (var section in monitoringData) { var data = section.Value; if (data.TryGetValue("GameId", out var gameId) && !string.IsNullOrEmpty(gameId)) { // Prüfen, ob der Monitoring-Eintrag bereits existiert if (_monitoring.FindOne(x => x.GameId == gameId) != null) { if (updateExisting) { // Bestehenden Monitoring-Eintrag aktualisieren UpdateMonitoring( gameId, data.GetValueOrDefault("Session", "unknown"), data.GetValueOrDefault("MaxPlayers", "0"), data.GetValueOrDefault("Players", "0"), data.GetValueOrDefault("InstanceGuid", "unknown"), data.GetValueOrDefault("Name", "Unknown") ); monitoringImported++; _logger.Log($"Updated existing monitoring entry from {monitoringIniPath}: GameId={gameId}"); } else { monitoringSkipped++; _logger.Log($"Skipped existing monitoring entry from {monitoringIniPath}: GameId={gameId}"); } } else { // Neuen Monitoring-Eintrag importieren UpdateMonitoring( gameId, data.GetValueOrDefault("Session", "unknown"), data.GetValueOrDefault("MaxPlayers", "0"), data.GetValueOrDefault("Players", "0"), data.GetValueOrDefault("InstanceGuid", "unknown"), data.GetValueOrDefault("Name", "Unknown") ); monitoringImported++; _logger.Log($"Imported new monitoring entry from {monitoringIniPath}: GameId={gameId}"); } } } _logger.Log($"Migrated {monitoringImported} monitoring entries, skipped {monitoringSkipped} existing entries from {monitoringIniPath} to LiteDB."); } } private string ConvertNameToHtmlEntities(string name) { if (string.IsNullOrEmpty(name)) return "Unknown"; return name.Replace(">", ">").Replace("<", "<"); } public void Dispose() { _db?.Dispose(); _logger.Log("LiteDB connection disposed."); } // Temporäre INI-Klassen für die Migration private class IniFile { private readonly string _path; private readonly Dictionary> _sections; private readonly object _lock = new object(); public IniFile(string path) { _path = path; _sections = new Dictionary>(); Load(); } private void Load() { lock (_lock) { if (!File.Exists(_path)) return; string currentSection = null; foreach (var line in File.ReadAllLines(_path)) { var trimmed = line.Trim(); if (string.IsNullOrEmpty(trimmed) || trimmed.StartsWith(";")) continue; if (trimmed.StartsWith("[") && trimmed.EndsWith("]")) { currentSection = trimmed.Substring(1, trimmed.Length - 2); _sections[currentSection] = new Dictionary(); } else if (currentSection != null && trimmed.Contains("=")) { var parts = trimmed.Split('=', 2); _sections[currentSection][parts[0].Trim()] = parts[1].Trim(); } } } } public Dictionary> GetServers() { lock (_lock) { return new Dictionary>(_sections); } } } private class MonitoringIniFile { private readonly string _path; private readonly Dictionary> _sections; private readonly object _lock = new object(); public MonitoringIniFile(string path) { _path = path; _sections = new Dictionary>(); Load(); } private void Load() { lock (_lock) { if (!File.Exists(_path)) return; string currentSection = null; foreach (var line in File.ReadAllLines(_path)) { var trimmed = line.Trim(); if (string.IsNullOrEmpty(trimmed) || trimmed.StartsWith(";")) continue; if (trimmed.StartsWith("[") && trimmed.EndsWith("]")) { currentSection = trimmed.Substring(1, trimmed.Length - 2); _sections[currentSection] = new Dictionary(); } else if (currentSection != null && trimmed.Contains("=")) { var parts = trimmed.Split('=', 2); _sections[currentSection][parts[0].Trim()] = parts[1].Trim(); } } } } public Dictionary> GetServers() { lock (_lock) { return new Dictionary>(_sections); } } } public ILiteCollection GetCollection(string collectionName) { return _db.GetCollection(collectionName); } } }