Converting to EF, need to work on TS

This commit is contained in:
Lani Aung
2021-11-19 23:04:15 -07:00
parent 1fd14ebafd
commit 744fc6bc57
43 changed files with 2159 additions and 542 deletions
+3 -4
View File
@@ -1,7 +1,6 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using fxl.codes.kisekae.Models; using fxl.codes.kisekae.Models;
using fxl.codes.kisekae.Services; using fxl.codes.kisekae.Services;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
@@ -21,10 +20,10 @@ namespace fxl.codes.kisekae.Controllers
_databaseService = databaseService; _databaseService = databaseService;
} }
public async Task<IActionResult> Index() public IActionResult Index()
{ {
var files = await _databaseService.GetAll(); var files = _databaseService.GetAll();
return View(files.Select(x => new ConfigurationModel(x))); return View(files.Select(x => new KisekaeModel(x)));
} }
[HttpPost] [HttpPost]
+5 -5
View File
@@ -1,4 +1,4 @@
using System.Threading.Tasks; using fxl.codes.kisekae.Models;
using fxl.codes.kisekae.Services; using fxl.codes.kisekae.Services;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@@ -13,11 +13,11 @@ namespace fxl.codes.kisekae.Controllers
_databaseService = databaseService; _databaseService = databaseService;
} }
public async Task<IActionResult> Index(int id) public IActionResult Index(int id)
{ {
var model = await _databaseService.LoadConfig(id); var config = _databaseService.GetConfig(id);
return View(model); return View(new PlaysetModel(config));
} }
} }
} }
+8
View File
@@ -0,0 +1,8 @@
namespace fxl.codes.kisekae.Entities
{
public class Action
{
public int Id { get; set; }
public string Name { get; set; }
}
}
+16
View File
@@ -0,0 +1,16 @@
using System.Collections.Generic;
namespace fxl.codes.kisekae.Entities
{
public class Cel
{
public int Id { get; set; }
public string FileName { get; set; }
public byte[] Data { get; set; }
public int OffsetX { get; set; }
public int OffsetY { get; set; }
public int Height { get; set; }
public int Width { get; set; }
public Kisekae Kisekae { get; set; }
}
}
+19
View File
@@ -0,0 +1,19 @@
namespace fxl.codes.kisekae.Entities
{
public class CelConfig
{
public int Id { get; set; }
public Cel Cel { get; set; }
public Configuration Configuration { get; set; }
public int Mark { get; set; }
public int Fix { get; set; }
public Palette Palette { get; set; }
public int PaletteGroup { get; set; }
public string Comment { get; set; }
public int X { get; set; }
public int Y { get; set; }
public int Transparency { get; set; }
public Set Sets { get; set; }
public Render Render { get; set; }
}
}
-23
View File
@@ -1,23 +0,0 @@
using System.ComponentModel.DataAnnotations.Schema;
using System.Runtime.Serialization;
namespace fxl.codes.kisekae.Entities
{
[Table("cel_config")]
public class CelConfigDto
{
public int Id { get; set; }
[Column("cel_id")] public int CelId { get; set; }
[Column("config_id")] public int ConfigId { get; set; }
public int Mark { get; set; }
public int Fix { get; set; }
public Set Sets { get; set; } = Set.Unset;
public int Transparency { get; set; }
public string Comment { get; set; }
[Column("palette_id")] public int PaletteId { get; set; }
[IgnoreDataMember] public int PaletteIndex { get; set; }
[Column("palette_group")] public int PaletteGroup { get; set; }
public int X { get; set; }
public int Y { get; set; }
}
}
-13
View File
@@ -1,13 +0,0 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace fxl.codes.kisekae.Entities
{
[Table("cel")]
public class CelDto : IKisekaeFile, IKisekaeParseable
{
public int Id { get; set; }
[Column("kisekae_id")] public int KisekaeId { get; set; }
public string Filename { get; set; }
public byte[] Data { get; set; }
}
}
-13
View File
@@ -1,13 +0,0 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace fxl.codes.kisekae.Entities
{
[Table("cel_render")]
public class CelRenderDto
{
public int Id { get; set; }
[Column("cel_id")] public int CelId { get; set; }
[Column("palette_id")] public int PaletteId { get; set; }
public byte[] Data { get; set; }
}
}
+18
View File
@@ -0,0 +1,18 @@
using System.Collections.Generic;
namespace fxl.codes.kisekae.Entities
{
public class Configuration
{
public int Id { get; set; }
public string Name { get; set; }
public Kisekae Kisekae { get; set; }
public List<CelConfig> Cels { get; set; } = new();
public List<Action> Actions { get; set; } = new();
public string Data { get; set; }
public int Height { get; set; }
public int Width { get; set; }
public int BorderIndex { get; set; }
}
}
-19
View File
@@ -1,19 +0,0 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
namespace fxl.codes.kisekae.Entities
{
[Table("configuration")]
public class ConfigurationDto : IKisekaeFile
{
public string Data { get; set; }
public int? Height { get; set; }
public int? Width { get; set; }
[Column("border_index")] public int? BorderIndex { get; set; }
public List<CelConfigDto> Cels { get; set; } = new();
public List<PaletteDto> Palettes { get; set; } = new();
public int Id { get; set; }
[Column("kisekae_id")] public int KisekaeId { get; set; }
public string Filename { get; set; }
}
}
-14
View File
@@ -1,14 +0,0 @@
namespace fxl.codes.kisekae.Entities
{
public interface IKisekaeFile
{
int Id { get; set; }
int KisekaeId { get; set; }
string Filename { get; set; }
}
public interface IKisekaeParseable
{
byte[] Data { get; set; }
}
}
+14
View File
@@ -0,0 +1,14 @@
using System.Collections.Generic;
namespace fxl.codes.kisekae.Entities
{
public class Kisekae
{
public int Id { get; set; }
public string FileName { get; set; }
public string CheckSum { get; set; }
public List<Configuration> Configurations { get; set; } = new();
public List<Cel> Cels { get; set; } = new();
public List<Palette> Palettes { get; set; } = new();
}
}
-15
View File
@@ -1,15 +0,0 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
namespace fxl.codes.kisekae.Entities
{
[Table("kisekae")]
public class KisekaeDto
{
public int Id { get; set; }
public string Name { get; init; }
public string Filename { get; init; }
public string Checksum { get; set; }
public IEnumerable<ConfigurationDto> Configurations { get; set; }
}
}
+14
View File
@@ -0,0 +1,14 @@
using System.Collections.Generic;
namespace fxl.codes.kisekae.Entities
{
public class Palette
{
public int Id { get; set; }
public Kisekae Kisekae { get; set; }
public string FileName { get; set; }
public string Comment { get; set; }
public List<PaletteColor> Colors { get; set; } = new();
public byte[] Data { get; set; }
}
}
+10
View File
@@ -0,0 +1,10 @@
namespace fxl.codes.kisekae.Entities
{
public class PaletteColor
{
public int Id { get; set; }
public Palette Palette { get; set; }
public int Group { get; set; }
public string Hex { get; set; }
}
}
-13
View File
@@ -1,13 +0,0 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace fxl.codes.kisekae.Entities
{
[Table("palette_color")]
public class PaletteColorDto
{
public int Id { get; set; }
[Column("palette_id")] public int PaletteId { get; set; }
public int Group { get; set; }
public string Hex { get; set; }
}
}
-14
View File
@@ -1,14 +0,0 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace fxl.codes.kisekae.Entities
{
[Table("palette")]
public class PaletteDto : IKisekaeFile, IKisekaeParseable
{
public string Comment { get; set; }
public int Id { get; set; }
[Column("kisekae_id")] public int KisekaeId { get; set; }
public string Filename { get; set; }
public byte[] Data { get; set; }
}
}
+8
View File
@@ -0,0 +1,8 @@
namespace fxl.codes.kisekae.Entities
{
public class Render
{
public int Id { get; set; }
public byte[] Image { get; set; }
}
}
-96
View File
@@ -1,96 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Dapper;
namespace fxl.codes.kisekae.Extensions
{
public static class DapperExtensions
{
public static async Task<int> InsertAsync<T>(this IDbConnection connection, T item)
{
var info = GetTableInfo(typeof(T));
var statement = $"insert into {info.TableName} ({string.Join(",", info.Columns)}) values ({string.Join(",", info.Parameters)}) returning id";
return await connection.QuerySingleAsync<int>(statement, item);
}
public static async Task<int> InsertAsync<T>(this IDbConnection connection, IEnumerable<T> items)
{
var info = GetTableInfo(typeof(T));
var statement = $"insert into {info.TableName} ({string.Join(",", info.Columns)}) values ({string.Join(",", info.Parameters)}) returning id";
var count = 0;
foreach (var item in items)
{
await connection.ExecuteAsync(statement, item);
count++;
}
return count;
}
public static async Task<int> UpdateAsync<T>(this IDbConnection connection, T item)
{
var list = new List<T> { item };
return await UpdateAsync<T>(connection, list);
}
public static async Task<int> UpdateAsync<T>(this IDbConnection connection, IEnumerable<T> items)
{
var info = GetTableInfo(typeof(T));
var statement = new StringBuilder().AppendLine($"update {info.TableName} set");
var sets = new List<string>();
for (var index = 0; index < info.Columns.Length; index++)
if (!info.Columns[index].Contains("_id"))
sets.Add($"{info.Columns[index]} = {info.Parameters[index]}");
statement.AppendLine(string.Join(",", sets));
statement.AppendLine("where id = @Id");
var count = 0;
foreach (var item in items)
{
await connection.ExecuteAsync(statement.ToString(), item);
count++;
}
return count;
}
private static TableInfo GetTableInfo(Type type)
{
var tableAttribute = type.GetCustomAttribute<TableAttribute>();
var tableName = tableAttribute?.Name ?? type.Name.ToLowerInvariant();
var columns = new List<string>();
var parameters = new List<string>();
foreach (var property in type.GetProperties(BindingFlags.Default | BindingFlags.Public | BindingFlags.Instance))
{
if (string.Equals(property.Name, "id", StringComparison.InvariantCultureIgnoreCase) || property.PropertyType.IsGenericType) continue;
var columnAttribute = property.GetCustomAttribute<ColumnAttribute>();
columns.Add($"\"{columnAttribute?.Name ?? property.Name.ToLowerInvariant()}\"");
parameters.Add($"@{property.Name}");
}
return new TableInfo
{
TableName = tableName,
Columns = columns.ToArray(),
Parameters = parameters.ToArray()
};
}
private class TableInfo
{
public string TableName { get; set; }
public string[] Columns { get; set; }
public string[] Parameters { get; set; }
}
}
}
+20
View File
@@ -0,0 +1,20 @@
using fxl.codes.kisekae.Entities;
using Microsoft.EntityFrameworkCore;
namespace fxl.codes.kisekae
{
public class KisekaeContext : DbContext
{
public KisekaeContext(DbContextOptions<KisekaeContext> options) : base(options)
{
}
public DbSet<Kisekae> KisekaeSets { get; set; }
public DbSet<Configuration> Configurations { get; set; }
public DbSet<Cel> Cels { get; set; }
public DbSet<CelConfig> CelConfigs { get; set; }
public DbSet<Render> Renders { get; set; }
public DbSet<Palette> Palettes { get; set; }
public DbSet<PaletteColor> PaletteColors { get; set; }
}
}
+367
View File
@@ -0,0 +1,367 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using fxl.codes.kisekae;
#nullable disable
namespace fxl.codes.kisekae.Migrations
{
[DbContext(typeof(KisekaeContext))]
[Migration("20211120044959_Startup")]
partial class Startup
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("fxl.codes.kisekae.Entities.Action", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("ConfigurationId")
.HasColumnType("integer");
b.Property<string>("Name")
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("ConfigurationId");
b.ToTable("Action");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Cel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<byte[]>("Data")
.HasColumnType("bytea");
b.Property<string>("FileName")
.HasColumnType("text");
b.Property<int>("Height")
.HasColumnType("integer");
b.Property<int?>("KisekaeId")
.HasColumnType("integer");
b.Property<int>("OffsetX")
.HasColumnType("integer");
b.Property<int>("OffsetY")
.HasColumnType("integer");
b.Property<int>("Width")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("KisekaeId");
b.ToTable("Cels");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.CelConfig", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("CelId")
.HasColumnType("integer");
b.Property<string>("Comment")
.HasColumnType("text");
b.Property<int?>("ConfigurationId")
.HasColumnType("integer");
b.Property<int>("Fix")
.HasColumnType("integer");
b.Property<int>("Mark")
.HasColumnType("integer");
b.Property<int>("PaletteGroup")
.HasColumnType("integer");
b.Property<int?>("PaletteId")
.HasColumnType("integer");
b.Property<int>("Sets")
.HasColumnType("integer");
b.Property<int>("Transparency")
.HasColumnType("integer");
b.Property<int>("X")
.HasColumnType("integer");
b.Property<int>("Y")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("CelId");
b.HasIndex("ConfigurationId");
b.HasIndex("PaletteId");
b.ToTable("CelConfigs");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Configuration", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("BorderIndex")
.HasColumnType("integer");
b.Property<string>("Data")
.HasColumnType("text");
b.Property<int>("Height")
.HasColumnType("integer");
b.Property<int?>("KisekaeId")
.HasColumnType("integer");
b.Property<string>("Name")
.HasColumnType("text");
b.Property<int>("Width")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("KisekaeId");
b.ToTable("Configurations");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Kisekae", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("CheckSum")
.HasColumnType("text");
b.Property<string>("FileName")
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("KisekaeSets");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Palette", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Comment")
.HasColumnType("text");
b.Property<byte[]>("Data")
.HasColumnType("bytea");
b.Property<string>("FileName")
.HasColumnType("text");
b.Property<int?>("KisekaeId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("KisekaeId");
b.ToTable("Palettes");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.PaletteColor", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("Group")
.HasColumnType("integer");
b.Property<string>("Hex")
.HasColumnType("text");
b.Property<int?>("PaletteId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("PaletteId");
b.ToTable("PaletteColors");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Render", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("CelId")
.HasColumnType("integer");
b.Property<byte[]>("Image")
.HasColumnType("bytea");
b.Property<int?>("PaletteId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("CelId");
b.HasIndex("PaletteId");
b.ToTable("Renders");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Action", b =>
{
b.HasOne("fxl.codes.kisekae.Entities.Configuration", null)
.WithMany("Actions")
.HasForeignKey("ConfigurationId");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Cel", b =>
{
b.HasOne("fxl.codes.kisekae.Entities.Kisekae", "Kisekae")
.WithMany("Cels")
.HasForeignKey("KisekaeId");
b.Navigation("Kisekae");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.CelConfig", b =>
{
b.HasOne("fxl.codes.kisekae.Entities.Cel", "Cel")
.WithMany()
.HasForeignKey("CelId");
b.HasOne("fxl.codes.kisekae.Entities.Configuration", "Configuration")
.WithMany("Cels")
.HasForeignKey("ConfigurationId");
b.HasOne("fxl.codes.kisekae.Entities.Palette", "Palette")
.WithMany()
.HasForeignKey("PaletteId");
b.Navigation("Cel");
b.Navigation("Configuration");
b.Navigation("Palette");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Configuration", b =>
{
b.HasOne("fxl.codes.kisekae.Entities.Kisekae", "Kisekae")
.WithMany("Configurations")
.HasForeignKey("KisekaeId");
b.Navigation("Kisekae");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Palette", b =>
{
b.HasOne("fxl.codes.kisekae.Entities.Kisekae", "Kisekae")
.WithMany("Palettes")
.HasForeignKey("KisekaeId");
b.Navigation("Kisekae");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.PaletteColor", b =>
{
b.HasOne("fxl.codes.kisekae.Entities.Palette", "Palette")
.WithMany("Colors")
.HasForeignKey("PaletteId");
b.Navigation("Palette");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Render", b =>
{
b.HasOne("fxl.codes.kisekae.Entities.Cel", "Cel")
.WithMany()
.HasForeignKey("CelId");
b.HasOne("fxl.codes.kisekae.Entities.Palette", "Palette")
.WithMany()
.HasForeignKey("PaletteId");
b.Navigation("Cel");
b.Navigation("Palette");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Configuration", b =>
{
b.Navigation("Actions");
b.Navigation("Cels");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Kisekae", b =>
{
b.Navigation("Cels");
b.Navigation("Configurations");
b.Navigation("Palettes");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Palette", b =>
{
b.Navigation("Colors");
});
#pragma warning restore 612, 618
}
}
}
+275
View File
@@ -0,0 +1,275 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace fxl.codes.kisekae.Migrations
{
public partial class Startup : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "KisekaeSets",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
FileName = table.Column<string>(type: "text", nullable: true),
CheckSum = table.Column<string>(type: "text", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_KisekaeSets", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Cels",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
FileName = table.Column<string>(type: "text", nullable: true),
Data = table.Column<byte[]>(type: "bytea", nullable: true),
OffsetX = table.Column<int>(type: "integer", nullable: false),
OffsetY = table.Column<int>(type: "integer", nullable: false),
Height = table.Column<int>(type: "integer", nullable: false),
Width = table.Column<int>(type: "integer", nullable: false),
KisekaeId = table.Column<int>(type: "integer", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Cels", x => x.Id);
table.ForeignKey(
name: "FK_Cels_KisekaeSets_KisekaeId",
column: x => x.KisekaeId,
principalTable: "KisekaeSets",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
name: "Configurations",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: true),
KisekaeId = table.Column<int>(type: "integer", nullable: true),
Data = table.Column<string>(type: "text", nullable: true),
Height = table.Column<int>(type: "integer", nullable: false),
Width = table.Column<int>(type: "integer", nullable: false),
BorderIndex = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Configurations", x => x.Id);
table.ForeignKey(
name: "FK_Configurations_KisekaeSets_KisekaeId",
column: x => x.KisekaeId,
principalTable: "KisekaeSets",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
name: "Palettes",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
KisekaeId = table.Column<int>(type: "integer", nullable: true),
FileName = table.Column<string>(type: "text", nullable: true),
Comment = table.Column<string>(type: "text", nullable: true),
Data = table.Column<byte[]>(type: "bytea", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Palettes", x => x.Id);
table.ForeignKey(
name: "FK_Palettes_KisekaeSets_KisekaeId",
column: x => x.KisekaeId,
principalTable: "KisekaeSets",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
name: "Action",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: true),
ConfigurationId = table.Column<int>(type: "integer", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Action", x => x.Id);
table.ForeignKey(
name: "FK_Action_Configurations_ConfigurationId",
column: x => x.ConfigurationId,
principalTable: "Configurations",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
name: "CelConfigs",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
CelId = table.Column<int>(type: "integer", nullable: true),
ConfigurationId = table.Column<int>(type: "integer", nullable: true),
Mark = table.Column<int>(type: "integer", nullable: false),
Fix = table.Column<int>(type: "integer", nullable: false),
PaletteId = table.Column<int>(type: "integer", nullable: true),
PaletteGroup = table.Column<int>(type: "integer", nullable: false),
Comment = table.Column<string>(type: "text", nullable: true),
X = table.Column<int>(type: "integer", nullable: false),
Y = table.Column<int>(type: "integer", nullable: false),
Transparency = table.Column<int>(type: "integer", nullable: false),
Sets = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_CelConfigs", x => x.Id);
table.ForeignKey(
name: "FK_CelConfigs_Cels_CelId",
column: x => x.CelId,
principalTable: "Cels",
principalColumn: "Id");
table.ForeignKey(
name: "FK_CelConfigs_Configurations_ConfigurationId",
column: x => x.ConfigurationId,
principalTable: "Configurations",
principalColumn: "Id");
table.ForeignKey(
name: "FK_CelConfigs_Palettes_PaletteId",
column: x => x.PaletteId,
principalTable: "Palettes",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
name: "PaletteColors",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
PaletteId = table.Column<int>(type: "integer", nullable: true),
Group = table.Column<int>(type: "integer", nullable: false),
Hex = table.Column<string>(type: "text", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_PaletteColors", x => x.Id);
table.ForeignKey(
name: "FK_PaletteColors_Palettes_PaletteId",
column: x => x.PaletteId,
principalTable: "Palettes",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
name: "Renders",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
CelId = table.Column<int>(type: "integer", nullable: true),
PaletteId = table.Column<int>(type: "integer", nullable: true),
Image = table.Column<byte[]>(type: "bytea", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Renders", x => x.Id);
table.ForeignKey(
name: "FK_Renders_Cels_CelId",
column: x => x.CelId,
principalTable: "Cels",
principalColumn: "Id");
table.ForeignKey(
name: "FK_Renders_Palettes_PaletteId",
column: x => x.PaletteId,
principalTable: "Palettes",
principalColumn: "Id");
});
migrationBuilder.CreateIndex(
name: "IX_Action_ConfigurationId",
table: "Action",
column: "ConfigurationId");
migrationBuilder.CreateIndex(
name: "IX_CelConfigs_CelId",
table: "CelConfigs",
column: "CelId");
migrationBuilder.CreateIndex(
name: "IX_CelConfigs_ConfigurationId",
table: "CelConfigs",
column: "ConfigurationId");
migrationBuilder.CreateIndex(
name: "IX_CelConfigs_PaletteId",
table: "CelConfigs",
column: "PaletteId");
migrationBuilder.CreateIndex(
name: "IX_Cels_KisekaeId",
table: "Cels",
column: "KisekaeId");
migrationBuilder.CreateIndex(
name: "IX_Configurations_KisekaeId",
table: "Configurations",
column: "KisekaeId");
migrationBuilder.CreateIndex(
name: "IX_PaletteColors_PaletteId",
table: "PaletteColors",
column: "PaletteId");
migrationBuilder.CreateIndex(
name: "IX_Palettes_KisekaeId",
table: "Palettes",
column: "KisekaeId");
migrationBuilder.CreateIndex(
name: "IX_Renders_CelId",
table: "Renders",
column: "CelId");
migrationBuilder.CreateIndex(
name: "IX_Renders_PaletteId",
table: "Renders",
column: "PaletteId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Action");
migrationBuilder.DropTable(
name: "CelConfigs");
migrationBuilder.DropTable(
name: "PaletteColors");
migrationBuilder.DropTable(
name: "Renders");
migrationBuilder.DropTable(
name: "Configurations");
migrationBuilder.DropTable(
name: "Cels");
migrationBuilder.DropTable(
name: "Palettes");
migrationBuilder.DropTable(
name: "KisekaeSets");
}
}
}
+372
View File
@@ -0,0 +1,372 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using fxl.codes.kisekae;
#nullable disable
namespace fxl.codes.kisekae.Migrations
{
[DbContext(typeof(KisekaeContext))]
[Migration("20211120052043_Renders")]
partial class Renders
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("fxl.codes.kisekae.Entities.Action", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("ConfigurationId")
.HasColumnType("integer");
b.Property<string>("Name")
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("ConfigurationId");
b.ToTable("Action");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Cel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<byte[]>("Data")
.HasColumnType("bytea");
b.Property<string>("FileName")
.HasColumnType("text");
b.Property<int>("Height")
.HasColumnType("integer");
b.Property<int?>("KisekaeId")
.HasColumnType("integer");
b.Property<int>("OffsetX")
.HasColumnType("integer");
b.Property<int>("OffsetY")
.HasColumnType("integer");
b.Property<int>("Width")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("KisekaeId");
b.ToTable("Cels");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.CelConfig", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("CelId")
.HasColumnType("integer");
b.Property<string>("Comment")
.HasColumnType("text");
b.Property<int?>("ConfigurationId")
.HasColumnType("integer");
b.Property<int>("Fix")
.HasColumnType("integer");
b.Property<int>("Mark")
.HasColumnType("integer");
b.Property<int>("PaletteGroup")
.HasColumnType("integer");
b.Property<int?>("PaletteId")
.HasColumnType("integer");
b.Property<int>("Sets")
.HasColumnType("integer");
b.Property<int>("Transparency")
.HasColumnType("integer");
b.Property<int>("X")
.HasColumnType("integer");
b.Property<int>("Y")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("CelId");
b.HasIndex("ConfigurationId");
b.HasIndex("PaletteId");
b.ToTable("CelConfigs");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Configuration", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("BorderIndex")
.HasColumnType("integer");
b.Property<string>("Data")
.HasColumnType("text");
b.Property<int>("Height")
.HasColumnType("integer");
b.Property<int?>("KisekaeId")
.HasColumnType("integer");
b.Property<string>("Name")
.HasColumnType("text");
b.Property<int>("Width")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("KisekaeId");
b.ToTable("Configurations");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Kisekae", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("CheckSum")
.HasColumnType("text");
b.Property<string>("FileName")
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("KisekaeSets");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Palette", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Comment")
.HasColumnType("text");
b.Property<byte[]>("Data")
.HasColumnType("bytea");
b.Property<string>("FileName")
.HasColumnType("text");
b.Property<int?>("KisekaeId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("KisekaeId");
b.ToTable("Palettes");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.PaletteColor", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("Group")
.HasColumnType("integer");
b.Property<string>("Hex")
.HasColumnType("text");
b.Property<int?>("PaletteId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("PaletteId");
b.ToTable("PaletteColors");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Render", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("CelId")
.HasColumnType("integer");
b.Property<byte[]>("Image")
.HasColumnType("bytea");
b.Property<int?>("PaletteId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("CelId");
b.HasIndex("PaletteId");
b.ToTable("Renders");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Action", b =>
{
b.HasOne("fxl.codes.kisekae.Entities.Configuration", null)
.WithMany("Actions")
.HasForeignKey("ConfigurationId");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Cel", b =>
{
b.HasOne("fxl.codes.kisekae.Entities.Kisekae", "Kisekae")
.WithMany("Cels")
.HasForeignKey("KisekaeId");
b.Navigation("Kisekae");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.CelConfig", b =>
{
b.HasOne("fxl.codes.kisekae.Entities.Cel", "Cel")
.WithMany()
.HasForeignKey("CelId");
b.HasOne("fxl.codes.kisekae.Entities.Configuration", "Configuration")
.WithMany("Cels")
.HasForeignKey("ConfigurationId");
b.HasOne("fxl.codes.kisekae.Entities.Palette", "Palette")
.WithMany()
.HasForeignKey("PaletteId");
b.Navigation("Cel");
b.Navigation("Configuration");
b.Navigation("Palette");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Configuration", b =>
{
b.HasOne("fxl.codes.kisekae.Entities.Kisekae", "Kisekae")
.WithMany("Configurations")
.HasForeignKey("KisekaeId");
b.Navigation("Kisekae");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Palette", b =>
{
b.HasOne("fxl.codes.kisekae.Entities.Kisekae", "Kisekae")
.WithMany("Palettes")
.HasForeignKey("KisekaeId");
b.Navigation("Kisekae");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.PaletteColor", b =>
{
b.HasOne("fxl.codes.kisekae.Entities.Palette", "Palette")
.WithMany("Colors")
.HasForeignKey("PaletteId");
b.Navigation("Palette");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Render", b =>
{
b.HasOne("fxl.codes.kisekae.Entities.Cel", "Cel")
.WithMany("Renders")
.HasForeignKey("CelId");
b.HasOne("fxl.codes.kisekae.Entities.Palette", "Palette")
.WithMany()
.HasForeignKey("PaletteId");
b.Navigation("Cel");
b.Navigation("Palette");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Cel", b =>
{
b.Navigation("Renders");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Configuration", b =>
{
b.Navigation("Actions");
b.Navigation("Cels");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Kisekae", b =>
{
b.Navigation("Cels");
b.Navigation("Configurations");
b.Navigation("Palettes");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Palette", b =>
{
b.Navigation("Colors");
});
#pragma warning restore 612, 618
}
}
}
+19
View File
@@ -0,0 +1,19 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace fxl.codes.kisekae.Migrations
{
public partial class Renders : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
}
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}
+353
View File
@@ -0,0 +1,353 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using fxl.codes.kisekae;
#nullable disable
namespace fxl.codes.kisekae.Migrations
{
[DbContext(typeof(KisekaeContext))]
[Migration("20211120054914_RendersP2")]
partial class RendersP2
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("fxl.codes.kisekae.Entities.Action", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("ConfigurationId")
.HasColumnType("integer");
b.Property<string>("Name")
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("ConfigurationId");
b.ToTable("Action");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Cel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<byte[]>("Data")
.HasColumnType("bytea");
b.Property<string>("FileName")
.HasColumnType("text");
b.Property<int>("Height")
.HasColumnType("integer");
b.Property<int?>("KisekaeId")
.HasColumnType("integer");
b.Property<int>("OffsetX")
.HasColumnType("integer");
b.Property<int>("OffsetY")
.HasColumnType("integer");
b.Property<int>("Width")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("KisekaeId");
b.ToTable("Cels");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.CelConfig", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("CelId")
.HasColumnType("integer");
b.Property<string>("Comment")
.HasColumnType("text");
b.Property<int?>("ConfigurationId")
.HasColumnType("integer");
b.Property<int>("Fix")
.HasColumnType("integer");
b.Property<int>("Mark")
.HasColumnType("integer");
b.Property<int>("PaletteGroup")
.HasColumnType("integer");
b.Property<int?>("PaletteId")
.HasColumnType("integer");
b.Property<int?>("RenderId")
.HasColumnType("integer");
b.Property<int>("Sets")
.HasColumnType("integer");
b.Property<int>("Transparency")
.HasColumnType("integer");
b.Property<int>("X")
.HasColumnType("integer");
b.Property<int>("Y")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("CelId");
b.HasIndex("ConfigurationId");
b.HasIndex("PaletteId");
b.HasIndex("RenderId");
b.ToTable("CelConfigs");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Configuration", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("BorderIndex")
.HasColumnType("integer");
b.Property<string>("Data")
.HasColumnType("text");
b.Property<int>("Height")
.HasColumnType("integer");
b.Property<int?>("KisekaeId")
.HasColumnType("integer");
b.Property<string>("Name")
.HasColumnType("text");
b.Property<int>("Width")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("KisekaeId");
b.ToTable("Configurations");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Kisekae", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("CheckSum")
.HasColumnType("text");
b.Property<string>("FileName")
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("KisekaeSets");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Palette", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Comment")
.HasColumnType("text");
b.Property<byte[]>("Data")
.HasColumnType("bytea");
b.Property<string>("FileName")
.HasColumnType("text");
b.Property<int?>("KisekaeId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("KisekaeId");
b.ToTable("Palettes");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.PaletteColor", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("Group")
.HasColumnType("integer");
b.Property<string>("Hex")
.HasColumnType("text");
b.Property<int?>("PaletteId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("PaletteId");
b.ToTable("PaletteColors");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Render", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<byte[]>("Image")
.HasColumnType("bytea");
b.HasKey("Id");
b.ToTable("Renders");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Action", b =>
{
b.HasOne("fxl.codes.kisekae.Entities.Configuration", null)
.WithMany("Actions")
.HasForeignKey("ConfigurationId");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Cel", b =>
{
b.HasOne("fxl.codes.kisekae.Entities.Kisekae", "Kisekae")
.WithMany("Cels")
.HasForeignKey("KisekaeId");
b.Navigation("Kisekae");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.CelConfig", b =>
{
b.HasOne("fxl.codes.kisekae.Entities.Cel", "Cel")
.WithMany()
.HasForeignKey("CelId");
b.HasOne("fxl.codes.kisekae.Entities.Configuration", "Configuration")
.WithMany("Cels")
.HasForeignKey("ConfigurationId");
b.HasOne("fxl.codes.kisekae.Entities.Palette", "Palette")
.WithMany()
.HasForeignKey("PaletteId");
b.HasOne("fxl.codes.kisekae.Entities.Render", "Render")
.WithMany()
.HasForeignKey("RenderId");
b.Navigation("Cel");
b.Navigation("Configuration");
b.Navigation("Palette");
b.Navigation("Render");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Configuration", b =>
{
b.HasOne("fxl.codes.kisekae.Entities.Kisekae", "Kisekae")
.WithMany("Configurations")
.HasForeignKey("KisekaeId");
b.Navigation("Kisekae");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Palette", b =>
{
b.HasOne("fxl.codes.kisekae.Entities.Kisekae", "Kisekae")
.WithMany("Palettes")
.HasForeignKey("KisekaeId");
b.Navigation("Kisekae");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.PaletteColor", b =>
{
b.HasOne("fxl.codes.kisekae.Entities.Palette", "Palette")
.WithMany("Colors")
.HasForeignKey("PaletteId");
b.Navigation("Palette");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Configuration", b =>
{
b.Navigation("Actions");
b.Navigation("Cels");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Kisekae", b =>
{
b.Navigation("Cels");
b.Navigation("Configurations");
b.Navigation("Palettes");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Palette", b =>
{
b.Navigation("Colors");
});
#pragma warning restore 612, 618
}
}
}
+105
View File
@@ -0,0 +1,105 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace fxl.codes.kisekae.Migrations
{
public partial class RendersP2 : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Renders_Cels_CelId",
table: "Renders");
migrationBuilder.DropForeignKey(
name: "FK_Renders_Palettes_PaletteId",
table: "Renders");
migrationBuilder.DropIndex(
name: "IX_Renders_CelId",
table: "Renders");
migrationBuilder.DropIndex(
name: "IX_Renders_PaletteId",
table: "Renders");
migrationBuilder.DropColumn(
name: "CelId",
table: "Renders");
migrationBuilder.DropColumn(
name: "PaletteId",
table: "Renders");
migrationBuilder.AddColumn<int>(
name: "RenderId",
table: "CelConfigs",
type: "integer",
nullable: true);
migrationBuilder.CreateIndex(
name: "IX_CelConfigs_RenderId",
table: "CelConfigs",
column: "RenderId");
migrationBuilder.AddForeignKey(
name: "FK_CelConfigs_Renders_RenderId",
table: "CelConfigs",
column: "RenderId",
principalTable: "Renders",
principalColumn: "Id");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_CelConfigs_Renders_RenderId",
table: "CelConfigs");
migrationBuilder.DropIndex(
name: "IX_CelConfigs_RenderId",
table: "CelConfigs");
migrationBuilder.DropColumn(
name: "RenderId",
table: "CelConfigs");
migrationBuilder.AddColumn<int>(
name: "CelId",
table: "Renders",
type: "integer",
nullable: true);
migrationBuilder.AddColumn<int>(
name: "PaletteId",
table: "Renders",
type: "integer",
nullable: true);
migrationBuilder.CreateIndex(
name: "IX_Renders_CelId",
table: "Renders",
column: "CelId");
migrationBuilder.CreateIndex(
name: "IX_Renders_PaletteId",
table: "Renders",
column: "PaletteId");
migrationBuilder.AddForeignKey(
name: "FK_Renders_Cels_CelId",
table: "Renders",
column: "CelId",
principalTable: "Cels",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_Renders_Palettes_PaletteId",
table: "Renders",
column: "PaletteId",
principalTable: "Palettes",
principalColumn: "Id");
}
}
}
+351
View File
@@ -0,0 +1,351 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using fxl.codes.kisekae;
#nullable disable
namespace fxl.codes.kisekae.Migrations
{
[DbContext(typeof(KisekaeContext))]
partial class KisekaeContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("fxl.codes.kisekae.Entities.Action", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("ConfigurationId")
.HasColumnType("integer");
b.Property<string>("Name")
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("ConfigurationId");
b.ToTable("Action");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Cel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<byte[]>("Data")
.HasColumnType("bytea");
b.Property<string>("FileName")
.HasColumnType("text");
b.Property<int>("Height")
.HasColumnType("integer");
b.Property<int?>("KisekaeId")
.HasColumnType("integer");
b.Property<int>("OffsetX")
.HasColumnType("integer");
b.Property<int>("OffsetY")
.HasColumnType("integer");
b.Property<int>("Width")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("KisekaeId");
b.ToTable("Cels");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.CelConfig", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("CelId")
.HasColumnType("integer");
b.Property<string>("Comment")
.HasColumnType("text");
b.Property<int?>("ConfigurationId")
.HasColumnType("integer");
b.Property<int>("Fix")
.HasColumnType("integer");
b.Property<int>("Mark")
.HasColumnType("integer");
b.Property<int>("PaletteGroup")
.HasColumnType("integer");
b.Property<int?>("PaletteId")
.HasColumnType("integer");
b.Property<int?>("RenderId")
.HasColumnType("integer");
b.Property<int>("Sets")
.HasColumnType("integer");
b.Property<int>("Transparency")
.HasColumnType("integer");
b.Property<int>("X")
.HasColumnType("integer");
b.Property<int>("Y")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("CelId");
b.HasIndex("ConfigurationId");
b.HasIndex("PaletteId");
b.HasIndex("RenderId");
b.ToTable("CelConfigs");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Configuration", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("BorderIndex")
.HasColumnType("integer");
b.Property<string>("Data")
.HasColumnType("text");
b.Property<int>("Height")
.HasColumnType("integer");
b.Property<int?>("KisekaeId")
.HasColumnType("integer");
b.Property<string>("Name")
.HasColumnType("text");
b.Property<int>("Width")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("KisekaeId");
b.ToTable("Configurations");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Kisekae", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("CheckSum")
.HasColumnType("text");
b.Property<string>("FileName")
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("KisekaeSets");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Palette", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Comment")
.HasColumnType("text");
b.Property<byte[]>("Data")
.HasColumnType("bytea");
b.Property<string>("FileName")
.HasColumnType("text");
b.Property<int?>("KisekaeId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("KisekaeId");
b.ToTable("Palettes");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.PaletteColor", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("Group")
.HasColumnType("integer");
b.Property<string>("Hex")
.HasColumnType("text");
b.Property<int?>("PaletteId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("PaletteId");
b.ToTable("PaletteColors");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Render", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<byte[]>("Image")
.HasColumnType("bytea");
b.HasKey("Id");
b.ToTable("Renders");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Action", b =>
{
b.HasOne("fxl.codes.kisekae.Entities.Configuration", null)
.WithMany("Actions")
.HasForeignKey("ConfigurationId");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Cel", b =>
{
b.HasOne("fxl.codes.kisekae.Entities.Kisekae", "Kisekae")
.WithMany("Cels")
.HasForeignKey("KisekaeId");
b.Navigation("Kisekae");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.CelConfig", b =>
{
b.HasOne("fxl.codes.kisekae.Entities.Cel", "Cel")
.WithMany()
.HasForeignKey("CelId");
b.HasOne("fxl.codes.kisekae.Entities.Configuration", "Configuration")
.WithMany("Cels")
.HasForeignKey("ConfigurationId");
b.HasOne("fxl.codes.kisekae.Entities.Palette", "Palette")
.WithMany()
.HasForeignKey("PaletteId");
b.HasOne("fxl.codes.kisekae.Entities.Render", "Render")
.WithMany()
.HasForeignKey("RenderId");
b.Navigation("Cel");
b.Navigation("Configuration");
b.Navigation("Palette");
b.Navigation("Render");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Configuration", b =>
{
b.HasOne("fxl.codes.kisekae.Entities.Kisekae", "Kisekae")
.WithMany("Configurations")
.HasForeignKey("KisekaeId");
b.Navigation("Kisekae");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Palette", b =>
{
b.HasOne("fxl.codes.kisekae.Entities.Kisekae", "Kisekae")
.WithMany("Palettes")
.HasForeignKey("KisekaeId");
b.Navigation("Kisekae");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.PaletteColor", b =>
{
b.HasOne("fxl.codes.kisekae.Entities.Palette", "Palette")
.WithMany("Colors")
.HasForeignKey("PaletteId");
b.Navigation("Palette");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Configuration", b =>
{
b.Navigation("Actions");
b.Navigation("Cels");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Kisekae", b =>
{
b.Navigation("Cels");
b.Navigation("Configurations");
b.Navigation("Palettes");
});
modelBuilder.Entity("fxl.codes.kisekae.Entities.Palette", b =>
{
b.Navigation("Colors");
});
#pragma warning restore 612, 618
}
}
}
+13 -17
View File
@@ -1,25 +1,21 @@
using System.Collections.Generic; using System;
using System.Text.Json.Serialization; using fxl.codes.kisekae.Entities;
namespace fxl.codes.kisekae.Models namespace fxl.codes.kisekae.Models
{ {
public class CelModel public class CelModel
{ {
public Dictionary<int, string> ImageByPalette = new(); public readonly int Fix;
public readonly string Image;
public readonly int Mark;
public readonly int ZIndex;
public int Id { get; init; } internal CelModel(CelConfig celConfig, Render render, int zIndex)
public int Fix { get; init; } {
public string FileName { get; init; } Mark = celConfig.Mark;
public int PaletteId { get; init; } Fix = celConfig.Fix;
public bool[] Sets { get; } = new bool[10]; ZIndex = zIndex;
public string Comment { get; init; } Image = Convert.ToBase64String(render.Image);
[JsonIgnore] public int Transparency { get; set; } }
public double Opacity { get; internal set; } = 1.0;
public Coordinate[] InitialPositions { get; } = new Coordinate[10];
[JsonIgnore] public string DefaultImage => ImageByPalette.ContainsKey(PaletteId) ? ImageByPalette[PaletteId] : null;
public Coordinate Offset { get; set; }
[JsonIgnore] public int Height { get; internal set; }
[JsonIgnore] public int Width { get; internal set; }
[JsonIgnore] public int ZIndex { get; internal set; }
} }
} }
-21
View File
@@ -1,21 +0,0 @@
using System.Collections.Generic;
using fxl.codes.kisekae.Entities;
namespace fxl.codes.kisekae.Models
{
public class ConfigurationModel
{
public ConfigurationModel(KisekaeDto dto)
{
Id = dto.Id;
Name = dto.Name;
Configurations = new Dictionary<int, string>();
foreach (var config in dto.Configurations) Configurations.Add(config.Id, config.Filename);
}
public int Id { get; }
public string Name { get; }
public IDictionary<int, string> Configurations { get; }
}
}
-14
View File
@@ -1,14 +0,0 @@
namespace fxl.codes.kisekae.Models
{
public class Coordinate
{
public Coordinate(int x = 0, int y = 0)
{
X = x;
Y = y;
}
public int X { get; }
public int Y { get; }
}
}
-2
View File
@@ -1,5 +1,3 @@
using System;
namespace fxl.codes.kisekae.Models namespace fxl.codes.kisekae.Models
{ {
public class ErrorViewModel public class ErrorViewModel
+18
View File
@@ -0,0 +1,18 @@
using System.Collections.Generic;
using System.Linq;
using fxl.codes.kisekae.Entities;
namespace fxl.codes.kisekae.Models
{
public class KisekaeModel
{
public readonly IEnumerable<KeyValuePair<int, string>> Configurations;
public readonly string Name;
internal KisekaeModel(Kisekae kisekae)
{
Name = kisekae.FileName;
Configurations = kisekae.Configurations.Select(x => new KeyValuePair<int, string>(x.Id, x.Name)).ToArray();
}
}
}
-12
View File
@@ -1,12 +0,0 @@
using System;
using SixLabors.ImageSharp;
namespace fxl.codes.kisekae.Models
{
public class PaletteModel
{
public string FileName { get; internal set; }
public string Comment { get; internal set; }
public Color[] Colors { get; internal set; } = Array.Empty<Color>();
}
}
+14 -6
View File
@@ -1,17 +1,25 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using SixLabors.ImageSharp; using SixLabors.ImageSharp;
using Configuration = fxl.codes.kisekae.Entities.Configuration;
namespace fxl.codes.kisekae.Models namespace fxl.codes.kisekae.Models
{ {
public class PlaysetModel public class PlaysetModel
{ {
public readonly int Height;
public readonly string Name;
public readonly int Width;
public readonly CelModel[] Cels;
[JsonIgnore] public Color BorderColor = Color.Black; [JsonIgnore] public Color BorderColor = Color.Black;
public string Name { get; set; }
public int Height { get; set; } internal PlaysetModel(Configuration configuration)
public int Width { get; set; } {
[JsonIgnore] public List<PaletteModel> Palettes { get; } = new(); Name = configuration.Name;
public List<CelModel> Cels { get; } = new(); Height = configuration.Height;
public bool[] EnabledSets { get; } = new bool[10]; Width = configuration.Width;
Cels = new CelModel[0];
}
} }
} }
+18 -11
View File
@@ -22,7 +22,7 @@ namespace fxl.codes.kisekae.Services
_logger = logger; _logger = logger;
} }
public void ReadConfigurationToDto(ConfigurationDto dto, IDictionary<string, CelDto> cels, IDictionary<string, PaletteDto> palettes) public void ReadConfigurationToDto(Configuration dto, IDictionary<string, Cel> cels, IDictionary<string, Palette> palettes)
{ {
var initialPositions = new StringBuilder(); var initialPositions = new StringBuilder();
@@ -41,10 +41,10 @@ namespace fxl.codes.kisekae.Services
dto.BorderIndex = int.Parse(borderValue); dto.BorderIndex = int.Parse(borderValue);
break; break;
case '%': case '%':
dto.Palettes.Add(SetPalette(line, palettes)); UpdatePalette(line, palettes);
break; break;
case '#': case '#':
dto.Cels.Add(SetCel(line, dto, cels)); dto.Cels.Add(SetCelConfig(line, dto, cels, palettes.Values.ToArray()));
break; break;
case '$': case '$':
case ' ': case ' ':
@@ -55,11 +55,11 @@ namespace fxl.codes.kisekae.Services
SetInitialPositions(dto, initialPositions.ToString()); SetInitialPositions(dto, initialPositions.ToString());
} }
private CelConfigDto SetCel(string line, IKisekaeFile configuration, IDictionary<string, CelDto> cels) private static CelConfig SetCelConfig(string line, Configuration configuration, IDictionary<string, Cel> cels, IReadOnlyList<Palette> palettes)
{ {
var cel = new CelConfigDto var cel = new CelConfig
{ {
ConfigId = configuration.Id Configuration = configuration
}; };
if (line.Contains("%t")) if (line.Contains("%t"))
@@ -81,11 +81,17 @@ namespace fxl.codes.kisekae.Services
if (string.Equals(groupName, "FileName")) if (string.Equals(groupName, "FileName"))
{ {
cel.CelId = cels[group.Value.ToLowerInvariant()].Id; cel.Cel = cels[group.Value.ToLowerInvariant()];
continue; continue;
} }
var property = typeof(CelConfigDto).GetProperty(groupName); if (string.Equals(groupName, "PaletteIndex"))
{
cel.Palette = palettes[int.Parse(group.Value)];
continue;
}
var property = typeof(CelConfig).GetProperty(groupName);
if (property == null) continue; if (property == null) continue;
var value = group.Value.Trim(); var value = group.Value.Trim();
@@ -106,18 +112,19 @@ namespace fxl.codes.kisekae.Services
} }
} }
cel.Palette ??= palettes[0];
return cel; return cel;
} }
private static PaletteDto SetPalette(string line, IDictionary<string, PaletteDto> palettes) private static void UpdatePalette(string line, IDictionary<string, Palette> palettes)
{ {
var parts = line.Split(';'); var parts = line.Split(';');
var palette = palettes[parts[0].Trim().ToLowerInvariant().Replace("%", "")]; var palette = palettes[parts[0].Trim().ToLowerInvariant().Replace("%", "")];
if (parts.Length > 1) palette.Comment = parts[1].Trim(); if (parts.Length > 1) palette.Comment = parts[1].Trim();
return palette;
} }
private static void SetInitialPositions(ConfigurationDto dto, string positions) private static void SetInitialPositions(Configuration dto, string positions)
{ {
var sets = positions.Split('$', StringSplitOptions.RemoveEmptyEntries); var sets = positions.Split('$', StringSplitOptions.RemoveEmptyEntries);
foreach (var set in sets) foreach (var set in sets)
+54 -129
View File
@@ -1,161 +1,98 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data;
using System.IO; using System.IO;
using System.IO.IsolatedStorage; using System.IO.IsolatedStorage;
using System.Linq; using System.Linq;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Dapper;
using fxl.codes.kisekae.Entities; using fxl.codes.kisekae.Entities;
using fxl.codes.kisekae.Extensions;
using fxl.codes.kisekae.Models;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Npgsql;
namespace fxl.codes.kisekae.Services namespace fxl.codes.kisekae.Services
{ {
public class DatabaseService public class DatabaseService
{ {
private const string ResolutionRegexPattern = @"\((?<Width>[0-9]*).(?<Height>[0-9]*)\)";
private readonly ConfigurationReaderService _configurationReaderService; private readonly ConfigurationReaderService _configurationReaderService;
private readonly IDbContextFactory<KisekaeContext> _contextFactory;
private readonly string _connectionString;
private readonly FileParserService _fileParserService; private readonly FileParserService _fileParserService;
private readonly ILogger<DatabaseService> _logger; private readonly ILogger<DatabaseService> _logger;
private readonly IsolatedStorageFile _storage; private readonly IsolatedStorageFile _storage;
public DatabaseService(ILogger<DatabaseService> logger, public DatabaseService(ILogger<DatabaseService> logger,
IConfiguration configuration,
ConfigurationReaderService configurationReaderService, ConfigurationReaderService configurationReaderService,
FileParserService fileParserService) FileParserService fileParserService,
IDbContextFactory<KisekaeContext> contextFactory)
{ {
_logger = logger; _logger = logger;
_configurationReaderService = configurationReaderService; _configurationReaderService = configurationReaderService;
_fileParserService = fileParserService; _fileParserService = fileParserService;
_connectionString = configuration.GetConnectionString("kisekae"); _contextFactory = contextFactory;
_storage = IsolatedStorageFile.GetUserStoreForApplication(); _storage = IsolatedStorageFile.GetUserStoreForApplication();
} }
public async Task<IEnumerable<KisekaeDto>> GetAll() public IEnumerable<Kisekae> GetAll()
{ {
await using var connection = new NpgsqlConnection(_connectionString); using var context = _contextFactory.CreateDbContext();
await connection.OpenAsync(); return context.KisekaeSets
.Include(x => x.Configurations)
.ToArray();
}
using var multi = await connection.QueryMultipleAsync("select * from kisekae; select * from configuration"); public Configuration GetConfig(int id)
var files = multi.Read<KisekaeDto>(); {
var configs = multi.Read<ConfigurationDto>(); using var context = _contextFactory.CreateDbContext();
var dictionary = configs.ToLookup(x => x.KisekaeId); return context.Configurations
await connection.CloseAsync(); .Include(x => x.Cels).ThenInclude(x => x.Cel)
.Include(x => x.Kisekae).ThenInclude(x => x.Palettes).ThenInclude(x => x.Colors)
foreach (var kiss in files) kiss.Configurations = dictionary[kiss.Id]; .FirstOrDefault(x => x.Id == id);
return files;
} }
public async void StoreToDatabase(IFormFile file) public async void StoreToDatabase(IFormFile file)
{ {
var memoryStream = await GetAsMemoryStream(file); var memoryStream = await GetAsMemoryStream(file);
var checksum = Convert.ToBase64String(await new SHA256Managed().ComputeHashAsync(memoryStream)); var checksum = Convert.ToBase64String(await SHA256.Create().ComputeHashAsync(memoryStream));
memoryStream.Position = 0; // Reset for re-read memoryStream.Position = 0; // Reset for re-read
await using var connection = new NpgsqlConnection(_connectionString); await using var context = await _contextFactory.CreateDbContextAsync();
await connection.OpenAsync(); var existing = await context.KisekaeSets
var transaction = await connection.BeginTransactionAsync(); .FirstOrDefaultAsync(x => string.Equals(x.FileName, file.FileName)
|| string.Equals(x.CheckSum, checksum));
if (existing != null) return;
try _fileParserService.UnzipLzh(file, memoryStream);
var directory = Path.GetFileNameWithoutExtension(file.FileName);
var kisekae = new Kisekae
{ {
var existing = GetExisting(connection, file.FileName, checksum); FileName = file.FileName,
if (existing != null) return; CheckSum = checksum
};
_fileParserService.UnzipLzh(file, memoryStream); var filenames = _storage.GetFileNames($"{Path.Combine(directory, "*")}");
var directory = Path.GetFileNameWithoutExtension(file.FileName); await SetInnerFiles(kisekae, directory, filenames);
var kisekae = new KisekaeDto
{
Filename = file.FileName,
Name = directory,
Checksum = checksum
};
kisekae.Id = await connection.InsertAsync(kisekae); foreach (var config in kisekae.Configurations)
_configurationReaderService.ReadConfigurationToDto(config,
kisekae.Cels.ToDictionary(x => x.FileName.ToLowerInvariant()),
kisekae.Palettes.ToDictionary(x => x.FileName.ToLowerInvariant()));
var filenames = _storage.GetFileNames($"{Path.Combine(directory, "*")}"); SetPaletteColors(kisekae.Palettes);
await SetInnerFiles(connection, directory, filenames, kisekae.Id);
using var saved = await connection.QueryMultipleAsync( foreach (var celConfig in kisekae.Configurations.SelectMany(config => config.Cels))
"select * from configuration where kisekae_id = @id; select * from cel where kisekae_id = @id; select * from palette where kisekae_id = @id",
new { id = kisekae.Id });
var configs = saved.Read<ConfigurationDto>().ToList();
var cels = saved.Read<CelDto>().ToDictionary(x => x.Filename.ToLowerInvariant());
var palettes = saved.Read<PaletteDto>().ToDictionary(x => x.Filename.ToLowerInvariant());
foreach (var config in configs)
{
_configurationReaderService.ReadConfigurationToDto(config, cels, palettes);
await connection.InsertAsync<CelConfigDto>(config.Cels);
await connection.UpdateAsync<PaletteDto>(config.Palettes);
await connection.UpdateAsync(config);
}
var paletteColors = SetPaletteColors(palettes.Values);
await connection.InsertAsync<PaletteColorDto>(paletteColors);
await transaction.CommitAsync();
}
catch (Exception e)
{ {
await transaction.RollbackAsync(); _fileParserService.RenderCel(celConfig);
_logger.LogError(e, $"Error saving file {file.FileName}");
} }
await connection.CloseAsync(); await context.AddAsync(kisekae);
await context.SaveChangesAsync();
} }
public async Task<PlaysetModel> LoadConfig(int configId) private async Task SetInnerFiles(Kisekae kisekae, string directory, IEnumerable<string> filenames)
{ {
await using var connection = new NpgsqlConnection(_connectionString);
await connection.OpenAsync();
var config = await connection.QuerySingleAsync<ConfigurationDto>("select * from configuration where id = @configId", new { configId });
var celIds = await connection.QueryAsync<int>("select cel_id from cel_config where config_id = @configId", new { configId });
var renders = await connection.QueryAsync<CelRenderDto>($"select * from cel_render where cel_id in ({string.Join(",", celIds)})");
if (!renders.Any())
{
using var reader = await connection.QueryMultipleAsync($"select * from cel where id in ({string.Join(",", celIds)});"
+ "select * from palette where kisekae_id = @kisekaeId", new { kisekaeId = config.KisekaeId });
var cels = reader.Read<CelDto>();
var palettes = reader.Read<PaletteDto>().ToDictionary(x => x.Id);
}
await connection.CloseAsync();
return null;
}
private KisekaeDto GetExisting(IDbConnection connection, string filename, string checksum)
{
var existing = connection.QuerySingleOrDefault<KisekaeDto>("select * from kisekae where kisekae.filename = @Filename", new { Filename = filename });
if (existing != null)
{
_logger.LogInformation($"Already existing upload {filename} under id {existing.Id}");
return existing;
}
existing = connection.QuerySingleOrDefault<KisekaeDto>("select * from kisekae where kisekae.checksum = @Checksum", new { Checksum = checksum });
if (existing == null) return null;
_logger.LogInformation($"Already existing upload (checksum: {checksum}) under id {existing.Id} and filename {existing.Filename}");
return existing;
}
private async Task SetInnerFiles(IDbConnection connection, string directory, IEnumerable<string> filenames, int id)
{
var files = new List<IKisekaeFile>();
foreach (var filename in filenames) foreach (var filename in filenames)
{ {
await using var reader = _storage.OpenFile(Path.Combine(directory, filename), FileMode.Open); await using var reader = _storage.OpenFile(Path.Combine(directory, filename), FileMode.Open);
@@ -167,40 +104,32 @@ namespace fxl.codes.kisekae.Services
switch (Path.GetExtension(filename).ToLower()) switch (Path.GetExtension(filename).ToLower())
{ {
case ".cel": case ".cel":
files.Add(new CelDto kisekae.Cels.Add(new Cel
{ {
Filename = filename, FileName = filename,
Data = bytes, Data = bytes
KisekaeId = id
}); });
break; break;
case ".cnf": case ".cnf":
files.Add(new ConfigurationDto kisekae.Configurations.Add(new Configuration
{ {
Filename = filename, Name = filename,
Data = Encoding.ASCII.GetString(bytes), Data = Encoding.ASCII.GetString(bytes)
KisekaeId = id
}); });
break; break;
case ".kcf": case ".kcf":
files.Add(new PaletteDto kisekae.Palettes.Add(new Palette
{ {
Filename = filename, FileName = filename,
Data = bytes, Data = bytes
KisekaeId = id
}); });
break; break;
} }
} }
await connection.InsertAsync(files.OfType<CelDto>());
await connection.InsertAsync(files.OfType<ConfigurationDto>());
await connection.InsertAsync(files.OfType<PaletteDto>());
} }
private List<PaletteColorDto> SetPaletteColors(IEnumerable<PaletteDto> palettes) private void SetPaletteColors(IEnumerable<Palette> palettes)
{ {
var paletteColors = new List<PaletteColorDto>();
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);
@@ -209,23 +138,19 @@ namespace fxl.codes.kisekae.Services
for (var colorIndex = 0; colorIndex < colorsPerGroup; colorIndex++) for (var colorIndex = 0; colorIndex < colorsPerGroup; colorIndex++)
{ {
var color = colors[groupIndex * colorsPerGroup + colorIndex]; var color = colors[groupIndex * colorsPerGroup + colorIndex];
paletteColors.Add(new PaletteColorDto palette.Colors.Add(new PaletteColor
{ {
Group = groupIndex, Group = groupIndex,
PaletteId = palette.Id,
Hex = color.ToHex() Hex = color.ToHex()
}); });
} }
} }
return paletteColors;
} }
private static async Task<MemoryStream> GetAsMemoryStream(IFormFile file) private static async Task<MemoryStream> GetAsMemoryStream(IFormFile file)
{ {
var stream = new MemoryStream(); var stream = new MemoryStream();
await file.CopyToAsync(stream); await file.CopyToAsync(stream);
return stream; return stream;
} }
} }
+40 -53
View File
@@ -7,7 +7,6 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using fxl.codes.kisekae.Entities; using fxl.codes.kisekae.Entities;
using fxl.codes.kisekae.Models;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using SixLabors.ImageSharp; using SixLabors.ImageSharp;
@@ -79,16 +78,16 @@ namespace fxl.codes.kisekae.Services
_storage.DeleteFile(file.FileName); _storage.DeleteFile(file.FileName);
} }
public Color[] ParsePalette(PaletteDto palette, out int groups, out int colorsPerGroup) public Color[] ParsePalette(Palette palette, out int groups, out int colorsPerGroup)
{ {
groups = 0; groups = 0;
colorsPerGroup = 0; colorsPerGroup = 0;
if (palette.Data.Length == 0) return null; if (palette.Data.Length == 0) return null;
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($"{palette.FileName} is not a valid palette file");
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);
@@ -97,16 +96,16 @@ namespace fxl.codes.kisekae.Services
return GetColors(palette.Data[32..], colorDepth, colorsPerGroup, groups); return GetColors(palette.Data[32..], colorDepth, colorsPerGroup, groups);
} }
public void ParseCel(string directory, CelModel cel, IEnumerable<PaletteModel> palettes) public void RenderCel(CelConfig celConfig)
{ {
_logger.LogTrace($"Reading cel {cel.FileName} from {directory}"); _logger.LogTrace($"Reading cel {celConfig.Cel.FileName}");
var buffer = ReadToBuffer(directory, cel.FileName); var buffer = celConfig.Cel?.Data?.ToArray();
if (buffer.Length == 0) return; if (buffer == null || 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($"{cel.FileName} is not a valid cel file"); if (buffer[4] != 32) _logger.LogError($"{celConfig.Cel.FileName} is not a valid cel file");
var pixelBits = Convert.ToInt32(buffer[5]); var pixelBits = Convert.ToInt32(buffer[5]);
var width = BitConverter.ToInt16(buffer, 8); var width = BitConverter.ToInt16(buffer, 8);
@@ -114,33 +113,24 @@ namespace fxl.codes.kisekae.Services
var xOffset = BitConverter.ToInt16(buffer, 12); var xOffset = BitConverter.ToInt16(buffer, 12);
var yOffset = BitConverter.ToInt16(buffer, 14); var yOffset = BitConverter.ToInt16(buffer, 14);
cel.ImageByPalette = GetCelImages(buffer[32..], palettes.ToArray(), width, height, pixelBits); celConfig.Cel.OffsetX = xOffset;
cel.Offset = new Coordinate(xOffset, yOffset); celConfig.Cel.OffsetY = yOffset;
cel.Height = height; celConfig.Cel.Height = height;
cel.Width = width; celConfig.Cel.Width = width;
celConfig.Render = GetCelImage(buffer[32..], celConfig.Palette, width, height, pixelBits);
} }
else else
{ {
var width = BitConverter.ToInt16(buffer, 0); var width = BitConverter.ToInt16(buffer, 0);
var height = BitConverter.ToInt16(buffer, 2); var height = BitConverter.ToInt16(buffer, 2);
cel.ImageByPalette = GetCelImages(buffer[4..], palettes.ToArray(), width, height); celConfig.Cel.Height = height;
cel.Height = height; celConfig.Cel.Width = width;
cel.Width = width; celConfig.Render = GetCelImage(buffer[4..], celConfig.Palette, width, height);
} }
} }
private byte[] ReadToBuffer(string directory, string filename)
{
using var stream = _storage.OpenFile(Path.Combine(directory, filename), FileMode.Open);
if (!stream.CanRead) throw new InvalidDataException();
var buffer = new byte[stream.Length];
stream.Read(buffer, 0, buffer.Length);
return buffer;
}
private Color[] GetColors(IReadOnlyCollection<byte> bytes, int depth = 12, int colorsPerGroup = 16, int groups = 10) private Color[] 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");
@@ -163,41 +153,38 @@ namespace fxl.codes.kisekae.Services
return colors; return colors;
} }
private Dictionary<int, string> GetCelImages(IReadOnlyCollection<byte> bytes, private Render GetCelImage(IReadOnlyCollection<byte> bytes,
IReadOnlyList<PaletteModel> palettes, Palette palette,
int width, int width,
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 dictionary = new Dictionary<int, string>();
var values = GetValues(bytes, pixelBits); var values = GetValues(bytes, pixelBits);
for (var paletteIndex = 0; paletteIndex < palettes.Count; paletteIndex++) using var bitmap = new Image<Rgba32>(width, height);
var index = 0;
for (var row = 0; row < height; row++)
{ {
var palette = palettes[paletteIndex]; var span = bitmap.GetPixelRowSpan(row);
using var bitmap = new Image<Rgba32>(width, height); for (var column = 0; column < width; column++)
var index = 0;
for (var row = 0; row < height; row++)
{ {
var span = bitmap.GetPixelRowSpan(row); var value = values[index];
for (var column = 0; column < width; column++) span[column] = value == 0 || value >= palette.Colors.Count ? Transparent : Color.ParseHex(palette.Colors[value].Hex);
{ index++;
var value = values[index];
span[column] = value == 0 || value >= palette.Colors.Length ? Transparent : palette.Colors[value];
index++;
}
if (width % 2 != 0 && pixelBits == 4) index++;
} }
using var memory = new MemoryStream(); if (width % 2 != 0 && pixelBits == 4) index++;
bitmap.SaveAsGif(memory);
dictionary.Add(paletteIndex, Convert.ToBase64String(memory.ToArray()));
} }
return dictionary; using var memory = new MemoryStream();
bitmap.SaveAsGif(memory);
return new Render
{
Image = memory.ToArray()
};
} }
private static int[] GetValues(IReadOnlyCollection<byte> bytes, int bits = 4) private static int[] GetValues(IReadOnlyCollection<byte> bytes, int bits = 4)
+3 -3
View File
@@ -1,7 +1,7 @@
using Dapper;
using fxl.codes.kisekae.Services; using fxl.codes.kisekae.Services;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
@@ -24,6 +24,8 @@ namespace fxl.codes.kisekae
services.AddControllersWithViews() services.AddControllersWithViews()
.AddRazorRuntimeCompilation(); .AddRazorRuntimeCompilation();
services.AddDbContextFactory<KisekaeContext>(options => { options.UseNpgsql(Configuration.GetConnectionString("kisekae")); });
services.AddSingleton<ConfigurationReaderService>(); services.AddSingleton<ConfigurationReaderService>();
services.AddSingleton<FileParserService>(); services.AddSingleton<FileParserService>();
services.AddScoped<DatabaseService>(); services.AddScoped<DatabaseService>();
@@ -58,8 +60,6 @@ namespace fxl.codes.kisekae
"default", "default",
"{controller=Home}/{action=Index}/{id?}"); "{controller=Home}/{action=Index}/{id?}");
}); });
DefaultTypeMap.MatchNamesWithUnderscores = true;
} }
} }
} }
+2 -2
View File
@@ -1,4 +1,4 @@
@model IEnumerable<ConfigurationModel> @model IEnumerable<KisekaeModel>
@{ @{
ViewData["Title"] = "Select"; ViewData["Title"] = "Select";
@@ -32,7 +32,7 @@
@foreach (var (key, value) in kiss.Configurations) @foreach (var (key, value) in kiss.Configurations)
{ {
<li> <li>
<a asp-controller="Play" asp-action="Index" asp-route-id="@kiss.Id">@value</a> <a asp-controller="Play" asp-action="Index" asp-route-id="@key">@value</a>
</li> </li>
} }
</ul> </ul>
-36
View File
@@ -1,36 +0,0 @@
@model PlaysetModel
@{
ViewData["Title"] = $"Play with {Model.Name}";
}
<header id="play_menu">
<ul>
<li>
<button class="mdc-button mdc-button--icon-trailing" data-rel="reset">
<span class="mdc-button__ripple"></span>
<span class="mdc-button__label">Reset</span>
<i class="material-icons mdc-button__icon" aria-hidden="true">restart_alt</i>
</button>
</li>
<li class="mdc-typography--button">Sets</li>
</ul>
</header>
<article id="play_area" style="background-color: #@Model.BorderColor">
<div id="play_space" style="height: @(Model.Height)px; width: @(Model.Width)px">
@for (var index = 0; index < Model.Cels.Count; index++)
{
var cel = Model.Cels[index];
<div class="cel-image"
style="background-image: url('data:image/gif;base64,@cel.DefaultImage'); height: @(cel.Height)px; width: @(cel.Width)px; z-index: @cel.ZIndex; opacity: @cel.Opacity"
data-id="@cel.Id"
data-index="@index"></div>
}
</div>
</article>
@section Scripts
{
<script>
document.kisekae.load("play_space", "play_menu", @Json.Serialize(Model))
</script>
}
+3 -3
View File
@@ -18,12 +18,12 @@
</header> </header>
<article id="play_area" style="background-color: #@Model.BorderColor"> <article id="play_area" style="background-color: #@Model.BorderColor">
<div id="play_space" style="height: @(Model.Height)px; width: @(Model.Width)px"> <div id="play_space" style="height: @(Model.Height)px; width: @(Model.Width)px">
@for (var index = 0; index < Model.Cels.Count; index++) @for (var index = 0; index < Model.Cels.Length; index++)
{ {
var cel = Model.Cels[index]; var cel = Model.Cels[index];
<div class="cel-image" <div class="cel-image"
style="background-image: url('data:image/gif;base64,@cel.DefaultImage'); height: @(cel.Height)px; width: @(cel.Width)px; z-index: @cel.ZIndex; opacity: @cel.Opacity" style="background-image: url('data:image/gif;base64,@cel.Image');"
data-id="@cel.Id" data-id="@cel.Mark"
data-index="@index"></div> data-index="@index"></div>
} }
</div> </div>
+10 -4
View File
@@ -1,8 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<CopyRazorGenerateFilesToPublishDirectory>true</CopyRazorGenerateFilesToPublishDirectory> <CopyRazorGenerateFilesToPublishDirectory>true</CopyRazorGenerateFilesToPublishDirectory>
<LangVersion>latestmajor</LangVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -14,9 +15,14 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Dapper" Version="2.0.90" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="5.0.10" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.0" />
<PackageReference Include="Npgsql" Version="5.0.10" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Npgsql" Version="6.0.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.0" />
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.4" /> <PackageReference Include="SixLabors.ImageSharp" Version="1.0.4" />
</ItemGroup> </ItemGroup>
+7
View File
@@ -0,0 +1,7 @@
{
"sdk": {
"version": "6.0",
"rollForward": "latestMajor",
"allowPrerelease": true
}
}