2026-01-24 23:35:39 -06:00
using System.IO.Compression ;
using LANCommander.Server.Data ;
2024-08-04 18:44:33 -05:00
using LANCommander.Server.Data.Models ;
2024-10-07 18:04:26 -05:00
using LANCommander.Server.Services.Extensions ;
2025-02-01 02:21:34 -06:00
using AutoMapper ;
2026-01-24 23:35:39 -06:00
using LANCommander.SDK.Enums ;
using LANCommander.SDK.Services ;
2025-02-09 18:53:40 -06:00
using Microsoft.AspNetCore.Http ;
2024-10-07 18:04:26 -05:00
using Microsoft.Extensions.Logging ;
2024-10-11 01:09:12 -05:00
using Microsoft.EntityFrameworkCore ;
2024-10-30 17:44:10 -05:00
using ZiggyCreatures.Caching.Fusion ;
2023-10-18 01:14:31 -05:00
2024-08-04 18:44:33 -05:00
namespace LANCommander.Server.Services
2023-10-18 01:14:31 -05:00
{
2025-02-01 02:21:34 -06:00
public sealed class RedistributableService (
2025-09-24 20:58:23 -05:00
ILogger < SDK . Services . RedistributableClient > logger ,
2026-01-24 23:35:39 -06:00
ArchiveService archiveService ,
2025-11-16 12:31:25 -06:00
SettingsProvider < Settings . Settings > settingsProvider ,
2026-01-24 23:35:39 -06:00
ScriptClient scriptClient ,
2025-02-01 02:21:34 -06:00
IFusionCache cache ,
IMapper mapper ,
2025-02-09 18:53:40 -06:00
IHttpContextAccessor httpContextAccessor ,
2025-11-16 12:31:25 -06:00
IDbContextFactory < DatabaseContext > contextFactory ) : BaseDatabaseService < Redistributable > ( logger , settingsProvider , cache , mapper , httpContextAccessor , contextFactory )
2023-10-18 01:14:31 -05:00
{
2025-02-23 08:49:43 -06:00
public override async Task < Redistributable > AddAsync ( Redistributable entity )
{
await cache . ExpireGameCacheAsync ( ) ;
return await base . AddAsync ( entity , async context = >
{
await context . UpdateRelationshipAsync ( r = > r . Archives ) ;
await context . UpdateRelationshipAsync ( r = > r . Games ) ;
await context . UpdateRelationshipAsync ( r = > r . Pages ) ;
await context . UpdateRelationshipAsync ( r = > r . Scripts ) ;
} ) ;
}
2025-02-02 14:58:07 -06:00
public override async Task < Redistributable > UpdateAsync ( Redistributable entity )
2024-10-11 01:09:12 -05:00
{
2025-02-04 02:31:23 -06:00
if ( entity . Games ! = null & & entity . Games . Any ( ) )
{
foreach ( var game in entity . Games )
{
await cache . ExpireGameCacheAsync ( game ? . Id ) ;
}
}
2025-02-02 14:58:07 -06:00
return await base . UpdateAsync ( entity , async context = >
{
await context . UpdateRelationshipAsync ( r = > r . Archives ) ;
await context . UpdateRelationshipAsync ( r = > r . Games ) ;
await context . UpdateRelationshipAsync ( r = > r . Pages ) ;
await context . UpdateRelationshipAsync ( r = > r . Scripts ) ;
} ) ;
2024-10-11 01:09:12 -05:00
}
2025-04-11 02:31:29 -05:00
public async Task < SDK . Models . Manifest . Redistributable > GetManifestAsync ( Guid manifestId )
{
var redistributable = await AsNoTracking ( )
. AsSplitQuery ( )
. Query ( q = >
{
return q
. Include ( r = > r . Archives )
. Include ( r = > r . Scripts ) ;
} )
2025-10-05 19:41:24 -05:00
. GetAsync ( manifestId ) ;
2025-04-11 02:31:29 -05:00
2025-10-05 19:41:24 -05:00
return mapper . Map < SDK . Models . Manifest . Redistributable > ( redistributable ) ;
2025-04-11 02:31:29 -05:00
}
2026-01-24 23:35:39 -06:00
public async Task PackageAsync ( Guid id )
{
var redistributable = await AsNoTracking ( )
. AsSplitQuery ( )
. Include ( r = > r . Archives )
. Include ( r = > r . Scripts )
. Include ( r = > r . Games )
. GetAsync ( id ) ;
logger ? . LogInformation ( "Packaging redistributable {RedistributableName}" , redistributable . Name ) ;
var latestArchive = redistributable . Archives ? . OrderByDescending ( r = > r . CreatedOn ) . FirstOrDefault ( ) ;
var storageLocationId = latestArchive ? . StorageLocationId ;
if ( redistributable . Scripts ? . Any ( s = > s . Type = = ScriptType . Package ) ? ? false )
{
foreach ( var script in redistributable . Scripts . Where ( s = > s . Type = = ScriptType . Package ) )
{
2026-02-10 17:34:35 -06:00
var package = await scriptClient . Redistributable_RunPackageScriptAsync ( mapper . Map < SDK . Models . Script > ( script ) , mapper . Map < SDK . Models . Redistributable > ( redistributable ) ) ;
2026-01-24 23:35:39 -06:00
if ( ! Directory . Exists ( package . Path ) )
{
logger ? . LogError (
"Could not package redistributable {RedistributableName}, the path {Path} could not be found" ,
redistributable . Name , package . Path ) ;
}
var archive = new Archive
{
Version = package . Version ,
RedistributableId = redistributable . Id ,
ObjectKey = Guid . NewGuid ( ) . ToString ( ) ,
LastVersion = latestArchive ,
StorageLocationId = storageLocationId . GetValueOrDefault ( ) ,
} ;
archive = await archiveService . AddAsync ( archive ) ;
var destination = await archiveService . GetArchiveFileLocationAsync ( archive ) ;
ZipFile . CreateFromDirectory ( package . Path , destination ) ;
logger ? . LogInformation ( "Successfully packaged {RedistributableName} and create new archive with version number {RedistributableVersion}" , redistributable . Name , archive . Version ) ;
}
}
else
{
logger ? . LogWarning ( "Could not package redistributable {RedistributableName}, no packaging scripts are defined" , redistributable . Name ) ;
}
}
2023-10-18 01:14:31 -05:00
}
}