175 lines
6.4 KiB
C#
175 lines
6.4 KiB
C#
using System.Globalization;
|
|
using CsvHelper;
|
|
using CsvHelper.Configuration;
|
|
using SVSim.Database.Common;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using SVSim.Database.Models;
|
|
|
|
namespace SVSim.Database.DataSeeders;
|
|
|
|
/// <summary>
|
|
/// Loads base data aside from cards into the DB. Cards excluded due to how many of them there are.
|
|
/// </summary>
|
|
public class BaseDataSeeder : IDataSeeder
|
|
{
|
|
private static string DataPath(string fileName) =>
|
|
Path.Combine(AppContext.BaseDirectory, "Data", fileName);
|
|
|
|
private static List<T> ReadCsv<T, TMap>(string fileName) where TMap : ClassMap<T>, new()
|
|
{
|
|
using StreamReader reader = new(DataPath(fileName));
|
|
using CsvReader csv = new(reader, CultureInfo.InvariantCulture);
|
|
csv.Context.RegisterClassMap<TMap>();
|
|
return csv.GetRecords<T>().ToList();
|
|
}
|
|
|
|
private class ClassEntryMap : ClassMap<ClassEntry>
|
|
{
|
|
public ClassEntryMap()
|
|
{
|
|
Map(m => m.Id).Name("id");
|
|
Map(m => m.Name).Name("name");
|
|
Map(m => m.DefaultLeaderSkin).Ignore();
|
|
}
|
|
}
|
|
private class LeaderSkinEntryMap : ClassMap<LeaderSkinEntry>
|
|
{
|
|
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<EmblemEntry>
|
|
{
|
|
public EmblemEntryMap()
|
|
{
|
|
Map(m => m.Id).Name("emblem_id");
|
|
}
|
|
}
|
|
private class SleeveEntryMap : ClassMap<SleeveEntry>
|
|
{
|
|
public SleeveEntryMap()
|
|
{
|
|
Map(m => m.Id).Name("sleeve_id");
|
|
}
|
|
}
|
|
|
|
private class DegreeEntryMap : ClassMap<DegreeEntry>
|
|
{
|
|
public DegreeEntryMap()
|
|
{
|
|
Map(m => m.Id).Name("degree_id");
|
|
}
|
|
}
|
|
|
|
private class BattlefieldEntryMap : ClassMap<BattlefieldEntry>
|
|
{
|
|
public BattlefieldEntryMap()
|
|
{
|
|
Map(m => m.Id).Name("value");
|
|
Map(m => m.IsOpen).Name("is_open");
|
|
}
|
|
}
|
|
|
|
private class MyPageBackgroundEntryMap : ClassMap<MyPageBackgroundEntry>
|
|
{
|
|
public MyPageBackgroundEntryMap()
|
|
{
|
|
Map(m => m.Id).Name("id");
|
|
}
|
|
}
|
|
|
|
private class ClassExpEntryMap : ClassMap<ClassExpEntry>
|
|
{
|
|
public ClassExpEntryMap()
|
|
{
|
|
Map(m => m.Id).Name("level");
|
|
Map(m => m.NecessaryExp).Name("necessary_exp");
|
|
}
|
|
}
|
|
|
|
private class RankInfoEntryMap : ClassMap<RankInfoEntry>
|
|
{
|
|
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<CardCosmeticReward>
|
|
{
|
|
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<ClassEntry> classes = ReadCsv<ClassEntry, ClassEntryMap>("classes.csv");
|
|
List<LeaderSkinEntry> leaderSkins = ReadCsv<LeaderSkinEntry, LeaderSkinEntryMap>("leaderskins.csv");
|
|
leaderSkins.ForEach(skin =>
|
|
{
|
|
if (skin.ClassId == 0)
|
|
{
|
|
skin.ClassId = null;
|
|
}
|
|
});
|
|
|
|
List<EmblemEntry> emblems = ReadCsv<EmblemEntry, EmblemEntryMap>("emblems.csv");
|
|
List<DegreeEntry> degrees = ReadCsv<DegreeEntry, DegreeEntryMap>("degrees.csv");
|
|
List<SleeveEntry> sleeves = ReadCsv<SleeveEntry, SleeveEntryMap>("sleeves.csv");
|
|
List<BattlefieldEntry> battlefields = ReadCsv<BattlefieldEntry, BattlefieldEntryMap>("battlefields.csv");
|
|
List<MyPageBackgroundEntry> myPageBackgrounds = ReadCsv<MyPageBackgroundEntry, MyPageBackgroundEntryMap>("mypagebackgrounds.csv");
|
|
List<RankInfoEntry> rankinfos = ReadCsv<RankInfoEntry, RankInfoEntryMap>("ranks.csv");
|
|
List<ClassExpEntry> classexp = ReadCsv<ClassExpEntry, ClassExpEntryMap>("classexp.csv");
|
|
List<CardCosmeticReward> cardCosmeticRewards = ReadCsv<CardCosmeticReward, CardCosmeticRewardMap>("card_cosmetic_rewards.csv");
|
|
|
|
builder.Entity<ClassEntry>().HasData(classes);
|
|
builder.Entity<LeaderSkinEntry>().HasData(leaderSkins);
|
|
builder.Entity<EmblemEntry>().HasData(emblems);
|
|
builder.Entity<SleeveEntry>().HasData(sleeves);
|
|
builder.Entity<DegreeEntry>().HasData(degrees);
|
|
builder.Entity<BattlefieldEntry>().HasData(battlefields);
|
|
builder.Entity<MyPageBackgroundEntry>().HasData(myPageBackgrounds);
|
|
builder.Entity<RankInfoEntry>().HasData(rankinfos);
|
|
builder.Entity<ClassExpEntry>().HasData(classexp);
|
|
builder.Entity<CardCosmeticReward>().HasData(cardCosmeticRewards);
|
|
}
|
|
}
|