1
0
mirror of synced 2024-11-30 18:24:32 +01:00

Add ability to import ScoreIni files (debug only, for now) (#647)

This commit is contained in:
DragonRatTiger / リュウコ 2024-07-09 04:50:27 -05:00 committed by GitHub
parent c9603742b7
commit 332d187af1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 292 additions and 4 deletions

View File

@ -187,13 +187,13 @@ namespace TJAPlayer3
} }
else if (roundedDifficulty == (int)Difficulty.Tower) else if (roundedDifficulty == (int)Difficulty.Tower)
{ {
Int64 roundedClearStatus = Math.Max((int)ETowerClearStatus.NONE, Math.Min((int)ETowerClearStatus.TOTAL, record.ClearStatus + 1)); Int64 roundedClearStatus = Math.Clamp(record.ClearStatus + 1, (int)ETowerClearStatus.NONE, (int)ETowerClearStatus.TOTAL);
stats.ClearStatuses[roundedDifficulty][roundedClearStatus]++; stats.ClearStatuses[roundedDifficulty][roundedClearStatus]++;
} }
else if (roundedDifficulty == (int)Difficulty.Dan) else if (roundedDifficulty == (int)Difficulty.Dan)
{ {
Int64 roundedClearStatus = Math.Max((int)EDanClearStatus.NONE, Math.Min((int)EDanClearStatus.TOTAL, record.ClearStatus + 1)); Int64 roundedClearStatus = Math.Clamp(record.ClearStatus + 1, (int)EDanClearStatus.NONE, (int)EDanClearStatus.TOTAL);
stats.ClearStatuses[roundedDifficulty][roundedClearStatus]++; stats.ClearStatuses[roundedDifficulty][roundedClearStatus]++;
} }

View File

@ -0,0 +1,281 @@
using Microsoft.Data.Sqlite;
using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
namespace TJAPlayer3
{
static class CScoreIni_Importer
{
public static string Status { get; private set; } = "";
private static readonly string langSUBTITLE = "SUBTITLE" + CLangManager.LangInstance.Id.ToUpper();
public static void ImportScoreInisToSavesDb3()
{
Trace.TraceInformation("Importing score.ini files to Saves.db3 database!");
Status = "Establishing connection to database...";
SqliteConnection? connection = DBSaves.GetSavesDBConnection();
if (connection == null)
{
Trace.TraceError("Could not establish a connection to Saves.db3 database. Aborting score import.");
return;
}
Status = "Searching for scores...";
string[] _scoreFiles = Directory.GetFiles(TJAPlayer3.ConfigIni.strSongsPath, "*.score.ini", SearchOption.AllDirectories);
Trace.TraceInformation($"{_scoreFiles.Length} score.ini files have been found. Beginning import.");
int importcount = 0;
Status = "Importing scores...";
foreach (string _score in _scoreFiles)
{
try
{
string directory = Path.GetDirectoryName(_score);
DirectoryInfo dir_parent = Directory.GetParent(directory);
string[] TJAData = Array.Empty<string>();
if (File.Exists(GetTJAFile(_score)))
TJAData = File.ReadAllLines(GetTJAFile(_score));
string[] Difficulties = TJAData.Where(str => str.StartsWith("COURSE:")).ToArray();
string[] Levels = TJAData.Where(str => str.StartsWith("LEVEL:")).ToArray();
string[] ScoreData = File.ReadAllLines(_score);
CSongUniqueID UniqueId = new CSongUniqueID(Path.Combine(directory, "uniqueID.json"));
CBoxDef boxdef = new CBoxDef();
if (File.Exists(Path.Combine(dir_parent.FullName, "box.def")))
boxdef = new CBoxDef(Path.Combine(dir_parent.FullName, "box.def"));
//string Charter = "";
string[] Charters = new string[8] { "", "", "", "", "", "", "", "" };
string Artist = "";
int[] Level = { -1, -1, -1, -1, -1, -1, -1 };
int[] Clear = { -1, -1, -1, -1, -1, -1, -1 };
int[] Rank = { -1, -1, -1, -1, -1, -1, -1 };
int[] HighScore = { 0, 0, 0, 0, 0, 0, 0 };
foreach (string data in TJAData)
{
string[] split = data.Split(":", 2);
switch (split[0])
{
case "SUBTITLE":
Artist = split[1].StartsWith("--") || split[1].StartsWith("++") ? split[1].Substring(2) : split[1];
break;
case "MAKER":
Charters[0] = split[1];
break;
case "NOTESDESIGNER0":
Charters[1] = split[1];
break;
case "NOTESDESIGNER1":
Charters[2] = split[1];
break;
case "NOTESDESIGNER2":
Charters[3] = split[1];
break;
case "NOTESDESIGNER3":
Charters[4] = split[1];
break;
case "NOTESDESIGNER4":
Charters[5] = split[1];
break;
case "NOTESDESIGNER5":
Charters[6] = split[1];
break;
case "NOTESDESIGNER6":
Charters[7] = split[1];
break;
default:
if (split[0] == langSUBTITLE)
Artist = split[1];
break;
}
}
// Tower/Dan score data is saved in index 0 (Easy).
for (int i = 0; i < Difficulties.Length; i++)
{
int diff_index = Difficulties[i].IndexOf(':') + 1;
int lvl_index = Levels[i].IndexOf(":") + 1;
int level = int.TryParse(Levels[i].Substring(lvl_index), out int result) ? result : -1;
switch (Difficulties[i].Substring(diff_index).ToLower())
{
case "0":
case "easy":
Level[0] = level;
break;
case "1":
case "normal":
Level[1] = level;
break;
case "2":
case "hard":
Level[2] = level;
break;
case "3":
case "oni":
Level[3] = level;
break;
case "4":
case "edit":
Level[4] = level;
break;
case "5":
case "tower":
Level[5] = level;
break;
case "6":
case "dan":
Level[6] = level;
break;
}
}
foreach (string data in ScoreData)
{
string[] split = data.Split('=', 2);
int num = 0;
if (split.Length == 2) num = int.TryParse(split[1], out int result) ? result : 0;
switch (split[0])
{
case "HiScore1":
HighScore[0] = num;
HighScore[5] = num;
HighScore[6] = num;
break;
case "HiScore2":
HighScore[1] = num;
break;
case "HiScore3":
HighScore[2] = num;
break;
case "HiScore4":
HighScore[3] = num;
break;
case "HiScore5":
HighScore[4] = num;
break;
case "Clear0":
Clear[0] = num == 0 ? -1 : num;
Clear[5] = num == 0 ? -1 : num;
Clear[6] = num == 0 ? -1 : num;
break;
case "Clear1":
Clear[1] = num == 0 ? -1 : num;
break;
case "Clear2":
Clear[2] = num == 0 ? -1 : num;
break;
case "Clear3":
Clear[3] = num == 0 ? -1 : num;
break;
case "Clear4":
Clear[4] = num == 0 ? -1 : num;
break;
case "ScoreRank0":
Rank[0] = num - 1;
Rank[5] = num - 1;
Rank[6] = num - 1;
break;
case "ScoreRank1":
Rank[1] = num - 1;
break;
case "ScoreRank2":
Rank[2] = num - 1;
break;
case "ScoreRank3":
Rank[3] = num - 1;
break;
case "ScoreRank4":
Rank[4] = num - 1;
break;
}
}
for (int i = 0; i < Level.Length; i++)
{
int score_index = i < 5 ? i : 0;
if (Level[i] != -1 && HighScore[score_index] > 0)
{
SqliteCommand cmd = connection.CreateCommand();
cmd.CommandText = $@"
INSERT INTO best_plays(ChartUniqueId,ChartGenre,Charter,Artist,PlayMods,ChartDifficulty,ChartLevel,ClearStatus,ScoreRank,HighScore,SaveId,TowerBestFloor,DanExam1,DanExam2,DanExam3,DanExam4,DanExam5,DanExam6,DanExam7,PlayCount,HighScoreGoodCount,HighScoreOkCount,HighScoreBadCount,HighScoreMaxCombo,HighScoreRollCount,HighScoreADLibCount,HighScoreBoomCount)
VALUES(
'{UniqueId.data.id.Replace(@"'", @"''")}',
'{boxdef.Title.Replace(@"'", @"''")}',
'{(!string.IsNullOrEmpty(Charters[i + 1]) ? Charters[i + 1] : Charters[0]).Replace(@"'", @"''")}',
'{Artist.Replace(@"'", @"''")}',
8925478921,
{i},
{Level[i]},
{Clear[i] + (i == 6 && Clear[i] > -1 ? 1 : 0)},
{(i != 5 ? Rank[i] : -1)},
{HighScore[score_index]},
{GetPlayerId(_score)},
{(i == 5 ? Rank[i]+1 : 0)},
'[-1]',
'[-1]',
'[-1]',
'[-1]',
'[-1]',
'[-1]',
'[-1]',
1,
0,
0,
0,
0,
0,
0,
0
)
ON CONFLICT(ChartUniqueId,ChartDifficulty,PlayMods) DO NOTHING
";
if (cmd.ExecuteNonQuery() > 0)
importcount++;
}
}
}
catch (Exception ex)
{
Trace.TraceWarning($"Failed to import {_score} into new database. More details:\n{ex}");
}
}
Trace.TraceInformation($"Imported {importcount} of {_scoreFiles.Length} scores from score.ini files.");
Status = "";
}
private static string GetTJAFile(string path)
{
FileInfo info = new FileInfo(path);
if (info.FullName.EndsWith("1P.score.ini")) return info.FullName.Replace("1P.score.ini", "");
if (info.FullName.EndsWith("2P.score.ini")) return info.FullName.Replace("2P.score.ini", "");
if (info.FullName.EndsWith("3P.score.ini")) return info.FullName.Replace("3P.score.ini", "");
if (info.FullName.EndsWith("4P.score.ini")) return info.FullName.Replace("4P.score.ini", "");
if (info.FullName.EndsWith("5P.score.ini")) return info.FullName.Replace("5P.score.ini", "");
return info.FullName.Replace(".score.ini", "");
}
private static int GetPlayerId(string path)
{
FileInfo info = new FileInfo(path);
if (info.Name.EndsWith("1P.score.ini")) return 0;
if (info.Name.EndsWith("2P.score.ini")) return 1;
if (info.Name.EndsWith("3P.score.ini")) return 2;
if (info.Name.EndsWith("4P.score.ini")) return 3;
if (info.Name.EndsWith("5P.score.ini")) return 4;
return 0;
}
}
}

View File

@ -191,6 +191,12 @@ namespace TJAPlayer3
base.ePhaseID = CStage.EPhase.Common_FADEOUT; base.ePhaseID = CStage.EPhase.Common_FADEOUT;
} }
} }
#if DEBUG
if (TJAPlayer3.InputManager.Keyboard.KeyPressed((int)SlimDXKeys.Key.F8))
{
CScoreIni_Importer.ImportScoreInisToSavesDb3();
}
#endif
// Disable F1 keybind since menu is accessible from main menu // Disable F1 keybind since menu is accessible from main menu
@ -937,6 +943,7 @@ namespace TJAPlayer3
TJAPlayer3.actTextConsole.tPrint(4, (TJAPlayer3.Skin.Resolution[1] - 24), CTextConsole.EFontType.White, "TJAPlayer3 forked TJAPlayer2 forPC(kairera0467)"); TJAPlayer3.actTextConsole.tPrint(4, (TJAPlayer3.Skin.Resolution[1] - 24), CTextConsole.EFontType.White, "TJAPlayer3 forked TJAPlayer2 forPC(kairera0467)");
#endif #endif
//TJAPlayer3.actTextConsole.tPrint(4, 64, CTextConsole.EFontType.White, CScoreIni_Importer.Status);
#endregion #endregion
CStage.EPhase eフェーズid = base.ePhaseID; CStage.EPhase eフェーズid = base.ePhaseID;