Add proper command line arguments
This commit is contained in:
parent
1632ceebf6
commit
18c9c3bea0
@ -6,6 +6,7 @@ namespace GameDatabase.Context
|
||||
{
|
||||
public partial class TaikoDbContext : DbContext
|
||||
{
|
||||
private string? dbFilePath;
|
||||
public TaikoDbContext()
|
||||
{
|
||||
}
|
||||
@ -15,6 +16,11 @@ namespace GameDatabase.Context
|
||||
{
|
||||
}
|
||||
|
||||
public TaikoDbContext(string dbFilePath)
|
||||
{
|
||||
this.dbFilePath = dbFilePath;
|
||||
}
|
||||
|
||||
public virtual DbSet<Card> Cards { get; set; } = null!;
|
||||
public virtual DbSet<SongBestDatum> SongBestData { get; set; } = null!;
|
||||
public virtual DbSet<SongPlayDatum> SongPlayData { get; set; } = null!;
|
||||
@ -28,6 +34,10 @@ namespace GameDatabase.Context
|
||||
}
|
||||
|
||||
var path = Path.Combine(PathHelper.GetRootPath(), "taiko.db3");
|
||||
if (dbFilePath is not null)
|
||||
{
|
||||
path = dbFilePath;
|
||||
}
|
||||
optionsBuilder.UseSqlite($"Data Source={path}");
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>1.0.0-beta1</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@ -15,6 +16,8 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="SharpZipLib" Version="1.4.0" />
|
||||
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -1,94 +1,166 @@
|
||||
// See https://aka.ms/new-console-template for more information
|
||||
|
||||
using System.CommandLine;
|
||||
using System.CommandLine.Parsing;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using GameDatabase.Context;
|
||||
using GameDatabase.Entities;
|
||||
using ICSharpCode.SharpZipLib.GZip;
|
||||
using JorgeSerrano.Json;
|
||||
using LocalSaveModScoreMigrator;
|
||||
using SharedProject.Enums;
|
||||
|
||||
using var db = new TaikoDbContext();
|
||||
var rootCommand = new RootCommand("Command-line tool to migrate saves from local save mod to local server database.");
|
||||
|
||||
var card = db.Cards.First();
|
||||
Console.WriteLine(card.Baid);
|
||||
Console.WriteLine(card.AccessCode);
|
||||
|
||||
var localSaveJson = File.ReadAllText("record_enso_p1.json");
|
||||
var options = new JsonSerializerOptions
|
||||
FileInfo? Parse(SymbolResult result, string defaultFileName)
|
||||
{
|
||||
PropertyNamingPolicy = new JsonSnakeCaseNamingPolicy()
|
||||
};
|
||||
options.Converters.Add(new DateTimeConverter());
|
||||
options.Converters.Add(new ScoreRankConverter());
|
||||
var playRecordJson = JsonSerializer.Deserialize<List<PlayRecordJson>>(localSaveJson, options);
|
||||
if (playRecordJson is null)
|
||||
{
|
||||
throw new ApplicationException("Play record json is null");
|
||||
}
|
||||
|
||||
Console.WriteLine(playRecordJson.First().SongId);
|
||||
|
||||
var musicInfoJson = File.ReadAllText("wwwroot/musicinfo.json");
|
||||
var musicInfo = JsonSerializer.Deserialize<MusicInfo>(musicInfoJson);
|
||||
|
||||
if (musicInfo is null)
|
||||
{
|
||||
throw new ApplicationException("Music info is null");
|
||||
}
|
||||
|
||||
var user = db.UserData.First();
|
||||
var musicInfoMap = musicInfo.Items.DistinctBy(entry => entry.Id).ToDictionary(entry => entry.Id, entry => entry.SongId);
|
||||
foreach (var playRecord in playRecordJson)
|
||||
{
|
||||
var songId = musicInfoMap[playRecord.SongId.Split("_")[1]];
|
||||
Console.WriteLine(songId);
|
||||
Console.WriteLine(playRecord.DateTime);
|
||||
var playLog = new SongPlayDatum
|
||||
if (result.Tokens.Count == 0)
|
||||
{
|
||||
Baid = user.Baid,
|
||||
Difficulty = playRecord.Difficulty,
|
||||
Crown = playRecord.Crown,
|
||||
Score = playRecord.Score,
|
||||
ScoreRank = playRecord.Scorerank,
|
||||
ComboCount = playRecord.Combo,
|
||||
DrumrollCount = playRecord.Drumroll,
|
||||
PlayTime = playRecord.DateTime,
|
||||
GoodCount = playRecord.Good,
|
||||
MissCount = playRecord.Bad,
|
||||
OkCount = playRecord.Ok,
|
||||
Skipped = false,
|
||||
SongNumber = 0,
|
||||
SongId = songId
|
||||
};
|
||||
db.SongPlayData.Add(playLog);
|
||||
|
||||
|
||||
var best = new SongBestDatum
|
||||
{
|
||||
Baid = user.Baid,
|
||||
Difficulty = playRecord.Difficulty,
|
||||
BestCrown = playRecord.Crown,
|
||||
BestScore = playRecord.Score,
|
||||
BestScoreRank = playRecord.Scorerank,
|
||||
SongId = songId
|
||||
};
|
||||
|
||||
var existing = db.SongBestData.FirstOrDefault(datum => datum.Baid == user.Baid &&
|
||||
datum.Difficulty == playLog.Difficulty &&
|
||||
datum.SongId == songId);
|
||||
|
||||
|
||||
if (existing is null)
|
||||
{
|
||||
db.SongBestData.Add(best);
|
||||
return new FileInfo(defaultFileName);
|
||||
}
|
||||
else
|
||||
|
||||
var filePath = result.Tokens.Single().Value;
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
existing.BestCrown = (CrownType)Math.Max((int)existing.BestCrown, (int)playRecord.Crown);
|
||||
existing.BestScoreRank = (ScoreRank)Math.Max((int)existing.BestScoreRank, (int)playRecord.Scorerank);
|
||||
existing.BestScore = Math.Max(existing.BestScore, playRecord.Score);
|
||||
db.SongBestData.Update(existing);
|
||||
return new FileInfo(filePath);
|
||||
}
|
||||
|
||||
result.ErrorMessage = $"File {filePath} does not exist";
|
||||
return null;
|
||||
}
|
||||
|
||||
db.SaveChanges();
|
||||
var saveFileArgument = new Argument<FileInfo?>(
|
||||
name: "--save-file",
|
||||
description: "Path to the save file from local save mod",
|
||||
isDefault: true,
|
||||
parse: result => Parse(result, "record_enso_p1.json")
|
||||
);
|
||||
|
||||
var dbFileArgument = new Argument<FileInfo?>(
|
||||
name: "--db-file-path",
|
||||
description: "Path to the database file for local server",
|
||||
isDefault: true,
|
||||
parse: result => Parse(result, "wwwroot/taiko.db3")
|
||||
);
|
||||
|
||||
var musicInfoArgument = new Argument<FileInfo?>(
|
||||
name: "--music-info-file",
|
||||
description: "Path to the music info json/bin file",
|
||||
isDefault: true,
|
||||
parse: result => Parse(result, "wwwroot/data/musicinfo.json")
|
||||
);
|
||||
rootCommand.Add(saveFileArgument);
|
||||
rootCommand.Add(dbFileArgument);
|
||||
rootCommand.Add(musicInfoArgument);
|
||||
|
||||
rootCommand.SetHandler((saveFile, dbFile, musicInfoFile) => Run(saveFile!, dbFile!, musicInfoFile!),
|
||||
saveFileArgument, dbFileArgument, musicInfoArgument);
|
||||
|
||||
await rootCommand.InvokeAsync(args);
|
||||
|
||||
void Run(FileSystemInfo saveFile, FileSystemInfo dbFile, FileSystemInfo musicInfoFile)
|
||||
{
|
||||
using var db = new TaikoDbContext(dbFile.FullName);
|
||||
var card = db.Cards.First();
|
||||
Console.WriteLine(card.Baid);
|
||||
Console.WriteLine(card.AccessCode);
|
||||
|
||||
var localSaveJson = File.ReadAllText(saveFile.FullName);
|
||||
var options = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = new JsonSnakeCaseNamingPolicy()
|
||||
};
|
||||
options.Converters.Add(new DateTimeConverter());
|
||||
options.Converters.Add(new ScoreRankConverter());
|
||||
var playRecordJson = JsonSerializer.Deserialize<List<PlayRecordJson>>(localSaveJson, options);
|
||||
if (playRecordJson is null)
|
||||
{
|
||||
throw new ApplicationException("Play record json is null");
|
||||
}
|
||||
|
||||
Console.WriteLine(playRecordJson.First().SongId);
|
||||
|
||||
var musicInfoJson = File.ReadAllText(musicInfoFile.FullName);
|
||||
if (musicInfoFile.FullName.EndsWith(".bin"))
|
||||
{
|
||||
var compressed = File.OpenRead(musicInfoFile.FullName);
|
||||
using var gZipInputStream = new GZipInputStream(compressed);
|
||||
using var decompressed = new MemoryStream();
|
||||
|
||||
// Decompress
|
||||
gZipInputStream.CopyTo(decompressed);
|
||||
|
||||
// Reset stream for reading
|
||||
decompressed.Position = 0;
|
||||
musicInfoJson = Encoding.UTF8.GetString(decompressed.ToArray());
|
||||
}
|
||||
var musicInfo = JsonSerializer.Deserialize<MusicInfo>(musicInfoJson);
|
||||
|
||||
if (musicInfo is null)
|
||||
{
|
||||
throw new ApplicationException("Music info is null");
|
||||
}
|
||||
|
||||
var user = db.UserData.First();
|
||||
var musicInfoMap = musicInfo.Items.DistinctBy(entry => entry.Id)
|
||||
.ToDictionary(entry => entry.Id, entry => entry.SongId);
|
||||
foreach (var playRecord in playRecordJson)
|
||||
{
|
||||
var key = playRecord.SongId.Split("_")[1];
|
||||
if (!musicInfoMap.ContainsKey(key))
|
||||
{
|
||||
Console.WriteLine($"Key {key} does not exist!!!");
|
||||
continue;
|
||||
}
|
||||
var songId = musicInfoMap[key];
|
||||
Console.WriteLine(songId);
|
||||
Console.WriteLine(playRecord.DateTime);
|
||||
var playLog = new SongPlayDatum
|
||||
{
|
||||
Baid = user.Baid,
|
||||
Difficulty = playRecord.Difficulty,
|
||||
Crown = playRecord.Crown,
|
||||
Score = playRecord.Score,
|
||||
ScoreRank = playRecord.Scorerank,
|
||||
ComboCount = playRecord.Combo,
|
||||
DrumrollCount = playRecord.Drumroll,
|
||||
PlayTime = playRecord.DateTime,
|
||||
GoodCount = playRecord.Good,
|
||||
MissCount = playRecord.Bad,
|
||||
OkCount = playRecord.Ok,
|
||||
Skipped = false,
|
||||
SongNumber = 0,
|
||||
SongId = songId
|
||||
};
|
||||
db.SongPlayData.Add(playLog);
|
||||
|
||||
|
||||
var best = new SongBestDatum
|
||||
{
|
||||
Baid = user.Baid,
|
||||
Difficulty = playRecord.Difficulty,
|
||||
BestCrown = playRecord.Crown,
|
||||
BestScore = playRecord.Score,
|
||||
BestScoreRank = playRecord.Scorerank,
|
||||
SongId = songId
|
||||
};
|
||||
|
||||
var existing = db.SongBestData.FirstOrDefault(datum => datum.Baid == user.Baid &&
|
||||
datum.Difficulty == playLog.Difficulty &&
|
||||
datum.SongId == songId);
|
||||
|
||||
|
||||
if (existing is null)
|
||||
{
|
||||
db.SongBestData.Add(best);
|
||||
}
|
||||
else
|
||||
{
|
||||
existing.BestCrown = (CrownType)Math.Max((int)existing.BestCrown, (int)playRecord.Crown);
|
||||
existing.BestScoreRank = (ScoreRank)Math.Max((int)existing.BestScoreRank, (int)playRecord.Scorerank);
|
||||
existing.BestScore = Math.Max(existing.BestScore, playRecord.Score);
|
||||
db.SongBestData.Update(existing);
|
||||
}
|
||||
}
|
||||
|
||||
db.SaveChanges();
|
||||
}
|
Loading…
Reference in New Issue
Block a user