using LANCommander.Server.Data; using LANCommander.Server.Data.Models; using LANCommander.SDK.Helpers; using System.Diagnostics; using System.IO.Compression; using LANCommander.SDK.Enums; using Microsoft.Extensions.Logging; using LANCommander.Server.Services.Extensions; using LANCommander.Server.Services.Models; using ZiggyCreatures.Caching.Fusion; namespace LANCommander.Server.Services { public class ServerService : BaseDatabaseService { private readonly GameService GameService; private readonly ArchiveService ArchiveService; private readonly StorageLocationService StorageLocationService; private readonly Settings Settings = SettingService.GetSettings(); public ServerService( ILogger logger, IFusionCache cache, RepositoryFactory repositoryFactory, GameService gameService, ArchiveService archiveService, StorageLocationService storageLocationService) : base(logger, cache, repositoryFactory) { GameService = gameService; ArchiveService = archiveService; StorageLocationService = storageLocationService; } public override async Task UpdateAsync(Data.Models.Server entity) { await Cache.ExpireGameCacheAsync(entity.GameId); return await base.UpdateAsync(entity); } public async Task ImportAsync(Guid objectKey) { var importArchive = await ArchiveService.FirstOrDefaultAsync(a => a.ObjectKey == objectKey.ToString()); var importArchivePath = await ArchiveService.GetArchiveFileLocationAsync(importArchive); var storageLocation = await StorageLocationService.GetAsync(importArchive.StorageLocationId); Data.Models.Server server; using (var importZip = ZipFile.OpenRead(importArchivePath)) { var manifest = ManifestHelper.Deserialize(await importZip.ReadAllTextAsync(ManifestHelper.ManifestFilename)); var exists = await ExistsAsync(manifest.Id); if (!exists) server = new Data.Models.Server() { Id = manifest.Id, }; else { server = await Include(s => s.Game) .Include(s => s.Actions) .Include(s => s.Scripts) .Include(s => s.HttpPaths) .Include(s => s.ServerConsoles) .FirstOrDefaultAsync(s => s.Id == manifest.Id); } server.Name = manifest.Name; server.Autostart = manifest.Autostart; server.AutostartMethod = (ServerAutostartMethod)(int)manifest.AutostartMethod; server.AutostartDelay = manifest.AutostartDelay; server.WorkingDirectory = Path.Combine(Settings.Servers.StoragePath, server.Name.SanitizeFilename()); server.Path = manifest.Path.Replace(manifest.WorkingDirectory, server.WorkingDirectory); server.Arguments = manifest.Arguments.Replace(manifest.WorkingDirectory, server.WorkingDirectory); server.UseShellExecute = manifest.UseShellExecute; server.ProcessTerminationMethod = manifest.ProcessTerminationMethod; server.OnStartScriptPath = manifest.OnStartScriptPath; server.OnStopScriptPath = manifest.OnStopScriptPath; server.Port = manifest.Port; #region Game if (manifest.Game != null) { var game = await GameService.GetAsync(manifest.Game.Id); server.Game = game; } #endregion #region Consoles if (server.ServerConsoles == null) server.ServerConsoles = new List(); foreach (var serverConsole in server.ServerConsoles) { var manifestConsole = manifest.ServerConsoles.FirstOrDefault(c => c.Id == serverConsole.Id); if (manifestConsole != null) { serverConsole.ServerId = server.Id; serverConsole.Name = manifestConsole.Name; serverConsole.Type = (ServerConsoleType)(int)manifestConsole.Type; serverConsole.Path = manifestConsole.Path; serverConsole.Host = manifestConsole.Host; serverConsole.Port = manifestConsole.Port; // serverConsole.Password = manifestConsole.Password; } else server.ServerConsoles.Remove(serverConsole); } if (manifest.ServerConsoles != null) { foreach (var manifestConsole in manifest.ServerConsoles.Where(mc => !server.ServerConsoles.Any(c => c.Id != mc.Id))) { server.ServerConsoles.Add(new ServerConsole() { Id = manifestConsole.Id, ServerId = server.Id, Name = manifestConsole.Name, Type = (ServerConsoleType)(int)manifestConsole.Type, Path = manifestConsole.Path, Host = manifestConsole.Host, Port = manifestConsole.Port, // Password = manifestConsole.Password }); } } #endregion #region HTTP Paths if (server.HttpPaths == null) server.HttpPaths = new List(); foreach (var httpPath in server.HttpPaths) { var manifestHttpPath = manifest.HttpPaths.FirstOrDefault(p => p.Id == httpPath.Id); if (manifestHttpPath != null) { httpPath.LocalPath = manifestHttpPath.LocalPath.Replace(manifest.WorkingDirectory, server.WorkingDirectory); httpPath.Path = manifestHttpPath.Path; } else server.HttpPaths.Remove(httpPath); } if (manifest.HttpPaths != null) { foreach (var manifestPath in manifest.HttpPaths.Where(mp => !server.HttpPaths.Any(p => p.Id != mp.Id))) { server.HttpPaths.Add(new ServerHttpPath() { Id = manifestPath.Id, Path = manifestPath.Path, LocalPath = manifestPath.LocalPath }); } } #endregion #region Scripts if (server.Scripts == null) server.Scripts = new List