using System.Collections.Generic; using DB; using MAI2.Util; using Manager; using Rizu.Core.Models; namespace Rizu.Core; public static class ScoreConversion { private static readonly string[] Difficulties = ["Basic", "Advanced", "Expert", "Master", "Re:Master"]; private static readonly Dictionary DanIDToName = new() { { 1, "DAN_1" }, { 2, "DAN_2" }, { 3, "DAN_3" }, { 4, "DAN_4" }, { 5, "DAN_5" }, { 6, "DAN_6" }, { 7, "DAN_7" }, { 8, "DAN_8" }, { 9, "DAN_9" }, { 10, "DAN_10" }, { 12, "SHINDAN_1" }, { 13, "SHINDAN_2" }, { 14, "SHINDAN_3" }, { 15, "SHINDAN_4" }, { 16, "SHINDAN_5" }, { 17, "SHINDAN_6" }, { 18, "SHINDAN_7" }, { 19, "SHINDAN_8" }, { 20, "SHINDAN_9" }, { 21, "SHINDAN_10" }, { 22, "SHINKAIDEN" }, { 23, "URAKAIDEN" }, }; private const int KIRISAGI_STATION_MUSIC_ID = 11422; private const int LINK_ORIGINAL_MUSIC_ID = 131; public static string CreateScoreBatchManual(GameScoreList scoreList) { var music = Singleton.Instance.GetMusic(scoreList.SessionInfo.musicId); var score = new BatchManualScore { percent = (float)scoreList.Achivement, lamp = scoreList.ComboType switch { PlayComboflagID.AllPerfectPlus => "ALL PERFECT+", PlayComboflagID.AllPerfect => "ALL PERFECT", PlayComboflagID.Gold => "FULL COMBO+", PlayComboflagID.Silver => "FULL COMBO", _ => scoreList.IsClear ? "CLEAR" : "FAILED", }, identifier = music.name.str, difficulty = (scoreList.SessionInfo.musicId >= 10000 ? "DX " : "") + Difficulties[scoreList.SessionInfo.difficulty], timeAchieved = scoreList.UnixTime * 1000L, judgements = new BatchManualScoreJudgements { // .TrueCriticalNum stores the actual number of criticals, // even when critical judgements are hidden. pcrit = scoreList.TrueCriticalNum, perfect = scoreList.TruePerfectNum, great = scoreList.GreatNum, good = scoreList.GoodNum, miss = scoreList.MissNum, }, optional = new BatchManualOptional { fast = scoreList.Fast, slow = scoreList.Late, maxCombo = scoreList.MaxCombo, } }; // Kirasagi Station, title in-game is U+3000 but title in Tachi is empty if (scoreList.SessionInfo.musicId == KIRISAGI_STATION_MUSIC_ID) { score.identifier = ""; } // There are two songs named Link. if (score.identifier == "Link") { // IDs from https://github.com/TNG-dev/Tachi/blob/staging/database-seeds/collections/songs-maimaidx.json score.identifier = scoreList.SessionInfo.musicId == LINK_ORIGINAL_MUSIC_ID ? "68" : "244"; score.matchType = "tachiSongID"; } return JsonShim.Serialize(new BatchManual { meta = new BatchManualMeta(), scores = [score], classes = new BatchManualMatchingClass { matchingClass = scoreList.Dan.ToString().Replace("Class_", ""), }, }); } public static string CreateDanBatchManual(int rankID) { if (!DanIDToName.TryGetValue(rankID, out var dan)) { System.Console.WriteLine("[Rizu] Unknown course rank ID {0}", rankID); return null; } return JsonShim.Serialize(new BatchManualRankUp { meta = new BatchManualMeta(), scores = [], classes = new BatchManualDan { dan = dan }, }); } }