Upgrade libraries
This commit is contained in:
@@ -9,3 +9,4 @@
|
|||||||
*.Development.json
|
*.Development.json
|
||||||
*.Release.json
|
*.Release.json
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
*.lic
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<LangVersion>default</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -15,7 +16,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="8.0.8"/>
|
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="10.0.9"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -35,11 +35,12 @@ public class LhContainerTests
|
|||||||
|
|
||||||
foreach (var file in files)
|
foreach (var file in files)
|
||||||
{
|
{
|
||||||
Assert.That(file.FileName, Is.Not.Null, "Filename is {0}", file.FileName);
|
Assert.IsNotNull(file.FileName, "Filename is {0}", file.FileName);
|
||||||
Assert.That(file.CompressedSize, Is.GreaterThan(0), "Compressed size is {0}", file.CompressedSize);
|
Assert.Greater(file.CompressedSize, 0, "Compressed size is {0}", file.CompressedSize);
|
||||||
Assert.That(file.UncompressedSize, Is.GreaterThan(0), "Uncompressed size is {0}", file.UncompressedSize);
|
Assert.Greater(file.CompressedSize, 0, "Compressed size is {0}", file.CompressedSize);
|
||||||
|
Assert.Greater(file.UncompressedSize, 0, "Uncompressed size is {0}", file.UncompressedSize);
|
||||||
Assert.That(file.UncompressedSize, Is.GreaterThan(file.CompressedSize), "Uncompressed is larger than compressed");
|
Assert.That(file.UncompressedSize, Is.GreaterThan(file.CompressedSize), "Uncompressed is larger than compressed");
|
||||||
Assert.That(file.MethodId, Is.Not.Null, "Method id is {0}", file.MethodId);
|
Assert.IsNotNull(file.MethodId, "Method id is {0}", file.MethodId);
|
||||||
Assert.That(file.MethodId, Does.StartWith("-l"));
|
Assert.That(file.MethodId, Does.StartWith("-l"));
|
||||||
Assert.That(file.MethodId, Does.EndWith("-"));
|
Assert.That(file.MethodId, Does.EndWith("-"));
|
||||||
Console.WriteLine($"Archive name: {file.FileName}, compression method: {file.MethodId}, file at {file.FileDataPosition}");
|
Console.WriteLine($"Archive name: {file.FileName}, compression method: {file.MethodId}, file at {file.FileDataPosition}");
|
||||||
|
|||||||
@@ -1,26 +1,27 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
<IsTestProject>true</IsTestProject>
|
<IsTestProject>true</IsTestProject>
|
||||||
|
<LangVersion>default</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0"/>
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.7.0"/>
|
||||||
<PackageReference Include="NUnit" Version="3.13.3"/>
|
<PackageReference Include="NUnit" Version="4.6.1"/>
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1"/>
|
<PackageReference Include="NUnit3TestAdapter" Version="6.2.0"/>
|
||||||
<PackageReference Include="NUnit.Analyzers" Version="3.6.1"/>
|
<PackageReference Include="NUnit.Analyzers" Version="4.14.0">
|
||||||
<PackageReference Include="coverlet.collector" Version="6.0.0"/>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</ItemGroup>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
<ItemGroup>
|
<PackageReference Include="coverlet.collector" Version="10.0.1">
|
||||||
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions">
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<HintPath>..\..\..\..\..\usr\local\share\dotnet\shared\Microsoft.AspNetCore.App\8.0.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</Reference>
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
[assembly: InternalsVisibleTo("fxl.codes.kisekae.data.test")]
|
||||||
|
|
||||||
namespace fxl.codes.kisekae.data.Archives;
|
namespace fxl.codes.kisekae.data.Archives;
|
||||||
|
|
||||||
internal class LhContainer
|
internal class LhContainer
|
||||||
@@ -13,10 +16,10 @@ internal class LhContainer
|
|||||||
var span = bytes.AsSpan();
|
var span = bytes.AsSpan();
|
||||||
Level = span[20];
|
Level = span[20];
|
||||||
MethodId = Encoding.ASCII.GetString(span[2..7]);
|
MethodId = Encoding.ASCII.GetString(span[2..7]);
|
||||||
CompressedSize = EndianUtility.ToLittleEndian(span[7..11]);
|
CompressedSize = span[7..11].ToLittleEndian();
|
||||||
CompressedFile = new byte[CompressedSize];
|
CompressedFile = new byte[CompressedSize];
|
||||||
UncompressedSize = EndianUtility.ToLittleEndian(span[11..15]);
|
UncompressedSize = span[11..15].ToLittleEndian();
|
||||||
Created = EndianUtility.ToDateTime(span[15..19]);
|
Created = span[15..19].ToDateTime();
|
||||||
FileOrDirectory = span[19];
|
FileOrDirectory = span[19];
|
||||||
|
|
||||||
switch (Level)
|
switch (Level)
|
||||||
|
|||||||
@@ -1,22 +1,23 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<UserSecretsId>c3253549-351f-4bcb-9c52-ce67c39cbeaf</UserSecretsId>
|
<UserSecretsId>c3253549-351f-4bcb-9c52-ce67c39cbeaf</UserSecretsId>
|
||||||
|
<LangVersion>default</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.8"/>
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.9"/>
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.8">
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.9">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0"/>
|
<PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.9"/>
|
||||||
<PackageReference Include="Npgsql" Version="8.0.4"/>
|
<PackageReference Include="Npgsql" Version="10.0.3"/>
|
||||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.4"/>
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.2"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using fxl.codes.kisekae.data.Entities;
|
using fxl.codes.kisekae.data.Entities;
|
||||||
|
|
||||||
namespace fxl.codes.kisekae.Models
|
namespace fxl.codes.kisekae.Models;
|
||||||
{
|
|
||||||
public class CelModel
|
public class CelModel
|
||||||
{
|
{
|
||||||
internal CelModel(CelConfig celConfig, int zIndex)
|
internal CelModel(CelConfig celConfig, int zIndex)
|
||||||
@@ -30,4 +30,3 @@ namespace fxl.codes.kisekae.Models
|
|||||||
public IDictionary<int, CoordinateModel> InitialPositions { get; set; } = new Dictionary<int, CoordinateModel>();
|
public IDictionary<int, CoordinateModel> InitialPositions { get; set; } = new Dictionary<int, CoordinateModel>();
|
||||||
public CoordinateModel Offset { get; set; }
|
public CoordinateModel Offset { get; set; }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
namespace fxl.codes.kisekae.Models
|
namespace fxl.codes.kisekae.Models;
|
||||||
{
|
|
||||||
public class CoordinateModel
|
public class CoordinateModel
|
||||||
{
|
{
|
||||||
internal CoordinateModel(int x, int y)
|
internal CoordinateModel(int x, int y)
|
||||||
@@ -11,4 +11,3 @@ namespace fxl.codes.kisekae.Models
|
|||||||
public int X { get; set; }
|
public int X { get; set; }
|
||||||
public int Y { get; set; }
|
public int Y { get; set; }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
namespace fxl.codes.kisekae.Models
|
namespace fxl.codes.kisekae.Models;
|
||||||
{
|
|
||||||
public class ErrorViewModel
|
public class ErrorViewModel
|
||||||
{
|
{
|
||||||
public string RequestId { get; set; }
|
public string RequestId { get; init; }
|
||||||
|
|
||||||
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
@@ -4,7 +4,7 @@ using fxl.codes.kisekae.data.Entities;
|
|||||||
|
|
||||||
namespace fxl.codes.kisekae.Models;
|
namespace fxl.codes.kisekae.Models;
|
||||||
|
|
||||||
public class PlaysetModel
|
public record PlaysetModel
|
||||||
{
|
{
|
||||||
[JsonIgnore] public readonly string BorderColor;
|
[JsonIgnore] public readonly string BorderColor;
|
||||||
|
|
||||||
@@ -24,9 +24,9 @@ public class PlaysetModel
|
|||||||
for (var index = 0; index < 10; index++) Sets[index] = configuration.Cels.Any(x => x.Positions.Any(y => y.Set == index));
|
for (var index = 0; index < 10; index++) Sets[index] = configuration.Cels.Any(x => x.Positions.Any(y => y.Set == index));
|
||||||
}
|
}
|
||||||
|
|
||||||
public CelModel[] Cels { get; set; }
|
public CelModel[] Cels { get; init; }
|
||||||
public int Height { get; set; }
|
public int Height { get; init; }
|
||||||
public string Name { get; set; }
|
public string Name { get; init; }
|
||||||
public bool[] Sets { get; set; } = new bool[10];
|
public bool[] Sets { get; init; } = new bool[10];
|
||||||
public int Width { get; set; }
|
public int Width { get; init; }
|
||||||
}
|
}
|
||||||
@@ -8,26 +8,19 @@ using Microsoft.Extensions.Logging;
|
|||||||
|
|
||||||
namespace fxl.codes.kisekae.Services;
|
namespace fxl.codes.kisekae.Services;
|
||||||
|
|
||||||
public class ConfigurationReaderService
|
public class ConfigurationReaderService(ILogger<ConfigurationReaderService> logger)
|
||||||
{
|
{
|
||||||
private const string CelRegex = @"#(?<Mark>\d*)\.?(?<Fix>\d*)\s*(?<FileName>[\w\d\-]*\.[cCeElL]*)\s*\*?"
|
private const string CelRegex = @"#(?<Mark>\d*)\.?(?<Fix>\d*)\s*(?<FileName>[\w\d\-]*\.[cCeElL]*)\s*\*?"
|
||||||
+ @"(?<PaletteIndex>\d*)?\s*\:?(?<Sets>[\d\s]*)?;?(?<Comment>[\w\d\-\s\%]*)";
|
+ @"(?<PaletteIndex>\d*)?\s*\:?(?<Sets>[\d\s]*)?;?(?<Comment>[\w\d\-\s\%]*)";
|
||||||
|
|
||||||
private const string ResolutionRegexPattern = @"\((?<Width>[0-9]*).(?<Height>[0-9]*)\)";
|
private const string ResolutionRegexPattern = @"\((?<Width>[0-9]*).(?<Height>[0-9]*)\)";
|
||||||
|
|
||||||
private readonly ILogger<ConfigurationReaderService> _logger;
|
|
||||||
|
|
||||||
public ConfigurationReaderService(ILogger<ConfigurationReaderService> logger)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ReadConfiguration(Configuration dto,
|
public void ReadConfiguration(Configuration dto,
|
||||||
IDictionary<Configuration, int> backgroundColors,
|
IDictionary<Configuration, int> backgroundColors,
|
||||||
IDictionary<string, Cel> cels,
|
IDictionary<string, Cel> cels,
|
||||||
Dictionary<string, Palette> palettes)
|
Dictionary<string, Palette> palettes)
|
||||||
{
|
{
|
||||||
_logger.LogInformation($"Reading {dto.Name}");
|
logger.LogInformation("Reading {Name}", dto.Name);
|
||||||
var initialPositions = new StringBuilder();
|
var initialPositions = new StringBuilder();
|
||||||
var backgroundColorIndex = 0;
|
var backgroundColorIndex = 0;
|
||||||
var paletteOrder = new List<Palette>();
|
var paletteOrder = new List<Palette>();
|
||||||
|
|||||||
@@ -10,36 +10,21 @@ using fxl.codes.kisekae.data;
|
|||||||
using fxl.codes.kisekae.data.Entities;
|
using fxl.codes.kisekae.data.Entities;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using SixLabors.ImageSharp;
|
using SixLabors.ImageSharp;
|
||||||
using Configuration = fxl.codes.kisekae.data.Entities.Configuration;
|
using Configuration = fxl.codes.kisekae.data.Entities.Configuration;
|
||||||
|
|
||||||
namespace fxl.codes.kisekae.Services;
|
namespace fxl.codes.kisekae.Services;
|
||||||
|
|
||||||
public class DatabaseService
|
public class DatabaseService(
|
||||||
{
|
|
||||||
private readonly ConfigurationReaderService _configurationReaderService;
|
|
||||||
private readonly IDbContextFactory<KisekaeContext> _contextFactory;
|
|
||||||
|
|
||||||
private readonly FileParserService _fileParserService;
|
|
||||||
private readonly ILogger<DatabaseService> _logger;
|
|
||||||
private readonly IsolatedStorageFile _storage;
|
|
||||||
|
|
||||||
public DatabaseService(ILogger<DatabaseService> logger,
|
|
||||||
ConfigurationReaderService configurationReaderService,
|
ConfigurationReaderService configurationReaderService,
|
||||||
FileParserService fileParserService,
|
FileParserService fileParserService,
|
||||||
IDbContextFactory<KisekaeContext> contextFactory)
|
IDbContextFactory<KisekaeContext> contextFactory)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
private readonly IsolatedStorageFile _storage = IsolatedStorageFile.GetUserStoreForApplication();
|
||||||
_configurationReaderService = configurationReaderService;
|
|
||||||
_fileParserService = fileParserService;
|
|
||||||
_contextFactory = contextFactory;
|
|
||||||
_storage = IsolatedStorageFile.GetUserStoreForApplication();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<Kisekae> GetAll()
|
public IEnumerable<Kisekae> GetAll()
|
||||||
{
|
{
|
||||||
using var context = _contextFactory.CreateDbContext();
|
using var context = contextFactory.CreateDbContext();
|
||||||
return context.KisekaeSets
|
return context.KisekaeSets
|
||||||
.Include(x => x.Configurations)
|
.Include(x => x.Configurations)
|
||||||
.ToArray();
|
.ToArray();
|
||||||
@@ -47,7 +32,7 @@ public class DatabaseService
|
|||||||
|
|
||||||
public Configuration GetConfig(int id)
|
public Configuration GetConfig(int id)
|
||||||
{
|
{
|
||||||
using var context = _contextFactory.CreateDbContext();
|
using var context = contextFactory.CreateDbContext();
|
||||||
return context.Configurations
|
return context.Configurations
|
||||||
.Include(x => x.Cels).ThenInclude(x => x.Render)
|
.Include(x => x.Cels).ThenInclude(x => x.Render)
|
||||||
.Include(x => x.Cels).ThenInclude(x => x.Cel)
|
.Include(x => x.Cels).ThenInclude(x => x.Cel)
|
||||||
@@ -63,14 +48,14 @@ public class DatabaseService
|
|||||||
var checksum = Convert.ToBase64String(SHA256.HashData(memoryStream.GetBuffer()));
|
var checksum = Convert.ToBase64String(SHA256.HashData(memoryStream.GetBuffer()));
|
||||||
memoryStream.Position = 0; // Reset for re-read
|
memoryStream.Position = 0; // Reset for re-read
|
||||||
|
|
||||||
await using var context = await _contextFactory.CreateDbContextAsync();
|
await using var context = await contextFactory.CreateDbContextAsync();
|
||||||
var existing = await context.KisekaeSets
|
var existing = await context.KisekaeSets
|
||||||
.FirstOrDefaultAsync(x => string.Equals(x.FileName, file.FileName)
|
.FirstOrDefaultAsync(x => string.Equals(x.FileName, file.FileName)
|
||||||
|| string.Equals(x.CheckSum, checksum));
|
|| string.Equals(x.CheckSum, checksum));
|
||||||
if (existing != null) context.KisekaeSets.Remove(existing);
|
if (existing != null) context.KisekaeSets.Remove(existing);
|
||||||
await context.SaveChangesAsync();
|
await context.SaveChangesAsync();
|
||||||
|
|
||||||
await _fileParserService.UnzipLzh(file, memoryStream);
|
await fileParserService.UnzipLzh(file, memoryStream);
|
||||||
|
|
||||||
var directory = Path.GetFileNameWithoutExtension(file.FileName);
|
var directory = Path.GetFileNameWithoutExtension(file.FileName);
|
||||||
|
|
||||||
@@ -85,7 +70,7 @@ public class DatabaseService
|
|||||||
|
|
||||||
var backgroundColors = new Dictionary<Configuration, int>();
|
var backgroundColors = new Dictionary<Configuration, int>();
|
||||||
foreach (var config in kisekae.Configurations)
|
foreach (var config in kisekae.Configurations)
|
||||||
_configurationReaderService.ReadConfiguration(config,
|
configurationReaderService.ReadConfiguration(config,
|
||||||
backgroundColors,
|
backgroundColors,
|
||||||
kisekae.Cels.ToDictionary(x => x.FileName.ToLowerInvariant()),
|
kisekae.Cels.ToDictionary(x => x.FileName.ToLowerInvariant()),
|
||||||
kisekae.Palettes.ToDictionary(x => x.FileName.ToLowerInvariant()));
|
kisekae.Palettes.ToDictionary(x => x.FileName.ToLowerInvariant()));
|
||||||
@@ -95,7 +80,7 @@ public class DatabaseService
|
|||||||
foreach (var (config, colorIndex) in backgroundColors)
|
foreach (var (config, colorIndex) in backgroundColors)
|
||||||
config.BackgroundColorHex = kisekae.Palettes.First()?.Colors[colorIndex].Hex ?? Color.White.ToHex();
|
config.BackgroundColorHex = kisekae.Palettes.First()?.Colors[colorIndex].Hex ?? Color.White.ToHex();
|
||||||
foreach (var celConfig in kisekae.Configurations.SelectMany(config => config.Cels))
|
foreach (var celConfig in kisekae.Configurations.SelectMany(config => config.Cels))
|
||||||
_fileParserService.RenderCel(celConfig);
|
fileParserService.RenderCel(celConfig);
|
||||||
|
|
||||||
await context.AddAsync(kisekae);
|
await context.AddAsync(kisekae);
|
||||||
await context.SaveChangesAsync();
|
await context.SaveChangesAsync();
|
||||||
@@ -109,7 +94,7 @@ public class DatabaseService
|
|||||||
if (!reader.CanRead) throw new InvalidDataException();
|
if (!reader.CanRead) throw new InvalidDataException();
|
||||||
|
|
||||||
var bytes = new byte[reader.Length];
|
var bytes = new byte[reader.Length];
|
||||||
reader.Read(bytes, 0, bytes.Length);
|
reader.ReadExactly(bytes);
|
||||||
|
|
||||||
switch (Path.GetExtension(filename).ToLower())
|
switch (Path.GetExtension(filename).ToLower())
|
||||||
{
|
{
|
||||||
@@ -142,7 +127,7 @@ public class DatabaseService
|
|||||||
{
|
{
|
||||||
foreach (var palette in palettes)
|
foreach (var palette in palettes)
|
||||||
{
|
{
|
||||||
var colors = _fileParserService.ParsePalette(palette, out var groups, out var colorsPerGroup);
|
var colors = fileParserService.ParsePalette(palette, out var groups, out var colorsPerGroup);
|
||||||
|
|
||||||
for (var groupIndex = 0; groupIndex < groups; groupIndex++)
|
for (var groupIndex = 0; groupIndex < groups; groupIndex++)
|
||||||
for (var colorIndex = 0; colorIndex < colorsPerGroup; colorIndex++)
|
for (var colorIndex = 0; colorIndex < colorsPerGroup; colorIndex++)
|
||||||
|
|||||||
@@ -14,30 +14,23 @@ using SixLabors.ImageSharp.PixelFormats;
|
|||||||
|
|
||||||
namespace fxl.codes.kisekae.Services;
|
namespace fxl.codes.kisekae.Services;
|
||||||
|
|
||||||
public class FileParserService
|
public class FileParserService(ILogger<FileParserService> logger)
|
||||||
{
|
{
|
||||||
private static readonly byte[] KissHeader = "KiSS"u8.ToArray();
|
private static readonly byte[] KissHeader = "KiSS"u8.ToArray();
|
||||||
private static readonly Color Transparent = Color.Black.WithAlpha(0);
|
private static readonly Color Transparent = Color.Black.WithAlpha(0);
|
||||||
|
|
||||||
private readonly ILogger<FileParserService> _logger;
|
private readonly IsolatedStorageFile _storage = IsolatedStorageFile.GetUserStoreForApplication();
|
||||||
private readonly IsolatedStorageFile _storage;
|
|
||||||
|
|
||||||
public FileParserService(ILogger<FileParserService> logger)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
_storage = IsolatedStorageFile.GetUserStoreForApplication();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task UnzipLzh(IFormFile file, MemoryStream memoryStream = null)
|
public async Task UnzipLzh(IFormFile file, MemoryStream memoryStream = null)
|
||||||
{
|
{
|
||||||
if (!_storage.FileExists(file.FileName))
|
if (!_storage.FileExists(file.FileName))
|
||||||
{
|
{
|
||||||
using var writer = _storage.CreateFile(file.FileName);
|
await using var writer = _storage.CreateFile(file.FileName);
|
||||||
|
|
||||||
if (memoryStream != null)
|
if (memoryStream != null)
|
||||||
memoryStream.CopyTo(writer);
|
await memoryStream.CopyToAsync(writer);
|
||||||
else
|
else
|
||||||
file.CopyTo(writer);
|
await file.CopyToAsync(writer);
|
||||||
|
|
||||||
writer.Flush();
|
writer.Flush();
|
||||||
writer.Close();
|
writer.Close();
|
||||||
@@ -58,7 +51,7 @@ public class FileParserService
|
|||||||
await process.WaitForExitAsync();
|
await process.WaitForExitAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Color[] ParsePalette(Palette palette, out int groups, out int colorsPerGroup)
|
public Rgba32[] ParsePalette(Palette palette, out int groups, out int colorsPerGroup)
|
||||||
{
|
{
|
||||||
groups = 0;
|
groups = 0;
|
||||||
colorsPerGroup = 0;
|
colorsPerGroup = 0;
|
||||||
@@ -67,7 +60,7 @@ public class FileParserService
|
|||||||
if (!palette.Data[..KissHeader.Length].SequenceEqual(KissHeader)) return GetColors(palette.Data);
|
if (!palette.Data[..KissHeader.Length].SequenceEqual(KissHeader)) return GetColors(palette.Data);
|
||||||
|
|
||||||
// Verify palette mark?
|
// Verify palette mark?
|
||||||
if (palette.Data[4] != 16) _logger.LogError($"{palette.FileName} is not a valid palette file");
|
if (palette.Data[4] != 16) logger.LogError("{PaletteFileName} is not a valid palette file", palette.FileName);
|
||||||
|
|
||||||
var colorDepth = Convert.ToInt32(palette.Data[5]);
|
var colorDepth = Convert.ToInt32(palette.Data[5]);
|
||||||
colorsPerGroup = BitConverter.ToInt16(palette.Data, 8);
|
colorsPerGroup = BitConverter.ToInt16(palette.Data, 8);
|
||||||
@@ -78,14 +71,14 @@ public class FileParserService
|
|||||||
|
|
||||||
public void RenderCel(CelConfig celConfig)
|
public void RenderCel(CelConfig celConfig)
|
||||||
{
|
{
|
||||||
_logger.LogTrace($"Reading cel {celConfig.Cel.FileName}");
|
logger.LogTrace("Reading cel {CelFileName}", celConfig.Cel.FileName);
|
||||||
var buffer = celConfig.Cel?.Data?.ToArray();
|
var buffer = celConfig.Cel.Data.ToArray();
|
||||||
if (buffer == null || buffer.Length == 0) return;
|
if (buffer.Length == 0) return;
|
||||||
|
|
||||||
if (buffer[..KissHeader.Length].SequenceEqual(KissHeader))
|
if (buffer[..KissHeader.Length].SequenceEqual(KissHeader))
|
||||||
{
|
{
|
||||||
// Verify cel mark?
|
// Verify cel mark?
|
||||||
if (buffer[4] != 32) _logger.LogError($"{celConfig.Cel.FileName} is not a valid cel file");
|
if (buffer[4] != 32) logger.LogError("{CelFileName} is not a valid cel file", celConfig.Cel.FileName);
|
||||||
|
|
||||||
var pixelBits = Convert.ToInt32(buffer[5]);
|
var pixelBits = Convert.ToInt32(buffer[5]);
|
||||||
var width = BitConverter.ToInt16(buffer, 8);
|
var width = BitConverter.ToInt16(buffer, 8);
|
||||||
@@ -111,11 +104,11 @@ public class FileParserService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Color[] GetColors(IReadOnlyCollection<byte> bytes, int depth = 12, int colorsPerGroup = 16, int groups = 10)
|
private Rgba32[] GetColors(IReadOnlyCollection<byte> bytes, int depth = 12, int colorsPerGroup = 16, int groups = 10)
|
||||||
{
|
{
|
||||||
_logger.LogTrace("Converting byte array to colors");
|
logger.LogTrace("Converting byte array to colors");
|
||||||
var colorValues = GetValues(bytes, depth / 3);
|
var colorValues = GetValues(bytes, depth / 3);
|
||||||
var colors = new Color[colorsPerGroup * groups];
|
var colors = new Rgba32[colorsPerGroup * groups];
|
||||||
var length = depth == 12 ? 4 : 3;
|
var length = depth == 12 ? 4 : 3;
|
||||||
var multiplier = depth == 12 ? 16 : 1;
|
var multiplier = depth == 12 ? 16 : 1;
|
||||||
// Nibbles order for 12 bits: R, B, 0, G
|
// Nibbles order for 12 bits: R, B, 0, G
|
||||||
@@ -127,7 +120,7 @@ public class FileParserService
|
|||||||
var red = colorValues[start] * multiplier;
|
var red = colorValues[start] * multiplier;
|
||||||
var green = colorValues[start + (depth == 12 ? 3 : 1)] * multiplier;
|
var green = colorValues[start + (depth == 12 ? 3 : 1)] * multiplier;
|
||||||
var blue = colorValues[start + (depth == 12 ? 1 : 2)] * multiplier;
|
var blue = colorValues[start + (depth == 12 ? 1 : 2)] * multiplier;
|
||||||
colors[groupIndex + colorIndex] = Color.FromRgb(Convert.ToByte(red), Convert.ToByte(green), Convert.ToByte(blue));
|
colors[groupIndex + colorIndex] = new Rgba32(Convert.ToByte(red), Convert.ToByte(green), Convert.ToByte(blue));
|
||||||
}
|
}
|
||||||
|
|
||||||
return colors;
|
return colors;
|
||||||
@@ -139,7 +132,7 @@ public class FileParserService
|
|||||||
int height,
|
int height,
|
||||||
int pixelBits = 4)
|
int pixelBits = 4)
|
||||||
{
|
{
|
||||||
_logger.LogTrace("Converting byte array to base64 encoded gifs per palette");
|
logger.LogTrace("Converting byte array to base64 encoded gifs per palette");
|
||||||
var values = GetValues(bytes, pixelBits);
|
var values = GetValues(bytes, pixelBits);
|
||||||
|
|
||||||
using var bitmap = new Image<Rgba32>(width, height);
|
using var bitmap = new Image<Rgba32>(width, height);
|
||||||
@@ -153,7 +146,7 @@ public class FileParserService
|
|||||||
{
|
{
|
||||||
var value = values[index];
|
var value = values[index];
|
||||||
var isTransparent = value == 0 || value >= palette.Colors.Count;
|
var isTransparent = value == 0 || value >= palette.Colors.Count;
|
||||||
row[x] = isTransparent ? Transparent : Color.ParseHex(palette.Colors[value].Hex);
|
row[x] = (isTransparent ? Transparent : Color.ParseHex(palette.Colors[value].Hex)).ToPixel<Rgba32>();
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<CopyRazorGenerateFilesToPublishDirectory>true</CopyRazorGenerateFilesToPublishDirectory>
|
<CopyRazorGenerateFilesToPublishDirectory>true</CopyRazorGenerateFilesToPublishDirectory>
|
||||||
<LangVersion>latestmajor</LangVersion>
|
<LangVersion>default</LangVersion>
|
||||||
|
<UserSecretsId>b2886b11-62f3-4354-b5c5-eaa9ea9678d3</UserSecretsId>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="8.0.8"/>
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="10.0.9"/>
|
||||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.5"/>
|
<PackageReference Include="SixLabors.ImageSharp" Version="4.0.0"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
Reference in New Issue
Block a user