using System.Globalization; using CsvHelper; using CsvHelper.Configuration; using SVSim.Database.Common; using Microsoft.EntityFrameworkCore; using SVSim.Database.Models; namespace SVSim.Database.DataSeeders; /// /// Loads base data aside from cards into the DB. Cards excluded due to how many of them there are. /// public class BaseDataSeeder : IDataSeeder { private static string DataPath(string fileName) => Path.Combine(AppContext.BaseDirectory, "Data", fileName); private static List ReadCsv(string fileName) where TMap : ClassMap, new() { using StreamReader reader = new(DataPath(fileName)); using CsvReader csv = new(reader, CultureInfo.InvariantCulture); csv.Context.RegisterClassMap(); return csv.GetRecords().ToList(); } private class ClassEntryMap : ClassMap { public ClassEntryMap() { Map(m => m.Id).Name("id"); Map(m => m.Name).Name("name"); Map(m => m.DefaultLeaderSkin).Ignore(); } } private class LeaderSkinEntryMap : ClassMap { public LeaderSkinEntryMap() { Map(m => m.Id).Name("class_chara_id"); Map(m => m.Name).Name("class_chara_name"); Map(m => m.ClassId).Name("clan"); Map(m => m.Class).Ignore(); Map(m => m.Viewers).Ignore(); Map(m => m.EmoteId).Ignore(); } } private class EmblemEntryMap : ClassMap { public EmblemEntryMap() { Map(m => m.Id).Name("emblem_id"); } } private class SleeveEntryMap : ClassMap { public SleeveEntryMap() { Map(m => m.Id).Name("sleeve_id"); } } private class DegreeEntryMap : ClassMap { public DegreeEntryMap() { Map(m => m.Id).Name("degree_id"); } } private class BattlefieldEntryMap : ClassMap { public BattlefieldEntryMap() { Map(m => m.Id).Name("value"); Map(m => m.IsOpen).Name("is_open"); } } private class MyPageBackgroundEntryMap : ClassMap { public MyPageBackgroundEntryMap() { Map(m => m.Id).Name("id"); } } private class ClassExpEntryMap : ClassMap { public ClassExpEntryMap() { Map(m => m.Id).Name("level"); Map(m => m.NecessaryExp).Name("necessary_exp"); } } private class RankInfoEntryMap : ClassMap { public RankInfoEntryMap() { Map(m => m.Id).Name("rank_id"); Map(m => m.Name).Name("rank_name"); Map(m => m.NecessaryPoint).Name("necessary_point"); Map(m => m.AccumulatePoint).Name("accumulate_point"); Map(m => m.LowerLimitPoint).Name("lower_limit_point"); Map(m => m.BaseAddBp).Name("base_add_bp"); Map(m => m.BaseDropBp).Name("base_drop_bp"); Map(m => m.StreakBonusPt).Name("streak_bonus_pt"); Map(m => m.WinBonus).Name("win_bonus"); Map(m => m.LoseBonus).Name("lose_bonus"); Map(m => m.MaxWinBonus).Name("max_win_bonus"); Map(m => m.MaxLoseBonus).Name("max_lose_bonus"); Map(m => m.IsPromotionWar).Name("is_promotion_war"); Map(m => m.MatchCount).Name("match_count"); Map(m => m.NecessaryWin).Name("necessary_win"); Map(m => m.ResetLose).Name("reset_lose"); Map(m => m.AccumulateMasterPoint).Name("accumulate_master_point"); } } private class CardCosmeticRewardMap : ClassMap { public CardCosmeticRewardMap() { Map(m => m.CardId).Name("card_id"); Map(m => m.Type).Name("type"); Map(m => m.CosmeticId).Name("cosmetic_id"); Map(m => m.Quantity).Name("quantity").Default(1); Map(m => m.Card).Ignore(); } } public void Seed(ModelBuilder builder) { // Migrations bake the HasData rows into InsertData calls — once the migration is // generated, runtime model-creation no longer needs the CSVs. Tools that only query // an already-migrated DB (e.g. SVSim.CardImport) don't ship the Data folder; skip // gracefully so DbContext construction succeeds for them. if (!File.Exists(DataPath("classes.csv"))) { Console.Error.WriteLine($"[BaseDataSeeder] Skipping seed: Data folder not found at {DataPath("")}"); return; } List classes = ReadCsv("classes.csv"); List leaderSkins = ReadCsv("leaderskins.csv"); leaderSkins.ForEach(skin => { if (skin.ClassId == 0) { skin.ClassId = null; } }); List emblems = ReadCsv("emblems.csv"); List degrees = ReadCsv("degrees.csv"); List sleeves = ReadCsv("sleeves.csv"); List battlefields = ReadCsv("battlefields.csv"); List myPageBackgrounds = ReadCsv("mypagebackgrounds.csv"); List rankinfos = ReadCsv("ranks.csv"); List classexp = ReadCsv("classexp.csv"); List cardCosmeticRewards = ReadCsv("card_cosmetic_rewards.csv"); builder.Entity().HasData(classes); builder.Entity().HasData(leaderSkins); builder.Entity().HasData(emblems); builder.Entity().HasData(sleeves); builder.Entity().HasData(degrees); builder.Entity().HasData(battlefields); builder.Entity().HasData(myPageBackgrounds); builder.Entity().HasData(rankinfos); builder.Entity().HasData(classexp); builder.Entity().HasData(cardCosmeticRewards); } }