diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index fce1ec1..d23abcf 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -1,29 +1,29 @@ -# This workflow will build a .NET project -# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net +# # This workflow will build a .NET project +# # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net -name: .NET +# name: .NET -on: - pull_request: - branches: [ "master" ] - workflow_dispatch: +# on: +# pull_request: +# branches: [ "master" ] +# workflow_dispatch: -jobs: - build: - name: Multi-build - runs-on: ubuntu-latest, macos-latest, windows-latest +# jobs: +# build: +# name: Multi-build +# runs-on: ubuntu-latest, macos-latest, windows-latest - steps: - - uses: actions/checkout@v3 - - name: Setup .NET - uses: actions/setup-dotnet@v3 - with: - dotnet-version: 8.0.x - - name: Restore dependencies - run: dotnet restore - # -name: Update MaiLib - # run: git submodule update --init --remote --recursive - - name: Build - run: dotnet build --no-restore - # - name: Test - # run: dotnet test --no-build --verbosity normal +# steps: +# - uses: actions/checkout@v3 +# - name: Setup .NET +# uses: actions/setup-dotnet@v3 +# with: +# dotnet-version: 8.0.x +# - name: Restore dependencies +# run: dotnet restore +# # -name: Update MaiLib +# # run: git submodule update --init --remote --recursive +# - name: Build +# run: dotnet build --no-restore +# # - name: Test +# # run: dotnet test --no-build --verbosity normal diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 2156a09..9e01bdd 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -39,4 +39,4 @@ "problemMatcher": "$msCompile" } ] -} \ No newline at end of file +} diff --git a/Commands/CompileDatabase.cs b/Commands/CompileDatabase.cs index fc4a165..34d5da6 100644 --- a/Commands/CompileDatabase.cs +++ b/Commands/CompileDatabase.cs @@ -34,23 +34,11 @@ public class CompileDatabase : ConsoleCommand /// public string? Difficulty { get; set; } - /// - /// Categorize Index - /// - private int categorizeIndex = 0; /// /// Categorize Index outer shell /// - public int? CategorizeIndex - { - get - { return categorizeIndex; } - set - { - if (value != null) categorizeIndex = (int)value; - else categorizeIndex = 0; - } - } + public int CategorizeIndex { get; set; } + /// /// Destination of output /// @@ -96,7 +84,7 @@ public CompileDatabase() //FileLocation = GlobalPaths[0]; //HasOption("a|a000=", "Folder of A000 to override - end with a path separator", path => FileLocation = path); HasOption("f|format=", "The target format - Simai, SimaiFes, Ma2_103, Ma2_104", format => TargetFormat = format); - HasOption("g|genre=", "The preferred categorizing scheme, includes:\n" + CategorizeMethods, genre => Int32.TryParse(genre, out categorizeIndex)); + HasOption("g|genre=", "The preferred categorizing scheme, includes:\n" + CategorizeMethods, genre => CategorizeIndex = Int32.Parse(genre)); HasOption("r|rotate=", "Rotating method to rotate a chart: Clockwise90/180, Counterclockwise90/180, UpsideDown, LeftToRight", rotate => Rotate = rotate); HasOption("s|shift=", "Overall shift to the chart in unit of tick", tick => ShiftTick = int.Parse(tick)); HasOption("v|video=", "Folder of Video to override - end with a path separator", vPath => VideoLocation = vPath); @@ -114,7 +102,6 @@ public override int Run(string[] remainingArguments) try { // Console.ReadKey(); - string sep = Program.GlobalSep; bool exportBGA = true; bool exportImage = true; bool exportAudio = true; @@ -129,7 +116,7 @@ public override int Run(string[] remainingArguments) a000Location = Program.GlobalPaths[0]; } - string musicLocation = a000Location + @"music" + sep; + string musicLocation = $"{a000Location}/music/"; string? audioLocation = BGMLocation; // if (remainingArguments.Length == 0) // { @@ -173,16 +160,16 @@ public override int Run(string[] remainingArguments) try { - if (0 <= categorizeIndex && categorizeIndex < Program.TrackCategorizeMethodSet.Length) + if (0 <= CategorizeIndex && CategorizeIndex < Program.TrackCategorizeMethodSet.Length) { - Program.GlobalTrackCategorizeMethod = Program.TrackCategorizeMethodSet[categorizeIndex]; + Program.GlobalTrackCategorizeMethod = Program.TrackCategorizeMethodSet[(int)CategorizeIndex]; } } catch (Exception e) { Console.WriteLine(e.Message + " The program will use Genre as default method. Press any key to continue."); Program.GlobalTrackCategorizeMethod = Program.TrackCategorizeMethodSet[0]; - categorizeIndex = 0; + CategorizeIndex = 0; Console.ReadKey(); } @@ -214,70 +201,71 @@ public override int Run(string[] remainingArguments) foreach (string track in musicFolders) { Console.WriteLine("Iterating on folder {0}", track); - if (File.Exists(track + sep + "Music.xml")) + if (File.Exists($"{track}/Music.xml")) { - TrackInformation trackInfo = new XmlInformation(track + sep + ""); - Console.WriteLine("There is Music.xml in " + track); + TrackInformation trackInfo = new XmlInformation($"{track}/"); + Console.WriteLine("There is Music.xml in {0}",track); string shortID = Program.CompensateZero(trackInfo.TrackID).Substring(2); - Console.WriteLine("Name: " + trackInfo.TrackName); - Console.WriteLine("ID:" + trackInfo.TrackID); - Console.WriteLine("Genre: " + trackInfo.TrackGenre); - string[] categorizeScheme = { trackInfo.TrackGenre, trackInfo.TrackSymbolicLevel, trackInfo.TrackVersion, trackInfo.TrackComposer, trackInfo.TrackBPM, trackInfo.StandardDeluxePrefix, "" }; - string defaultCategorizedPath = outputLocation + categorizeScheme[categorizeIndex]; + Console.WriteLine($"Name: {trackInfo.TrackName}"); + Console.WriteLine($"ID: {trackInfo.TrackID}"); + Console.WriteLine($"Genre: {trackInfo.TrackGenre}"); + string[] categorizeScheme = [trackInfo.TrackGenre, trackInfo.TrackSymbolicLevel, trackInfo.TrackVersion, trackInfo.TrackComposer, trackInfo.TrackBPM, trackInfo.StandardDeluxePrefix, "" + ]; + string defaultCategorizedPath = $"{outputLocation}/{categorizeScheme[CategorizeIndex]}"; //Cross out if not creating update packs // defaultCategorizedPath += sep + categorizeScheme[0]; //Deal with special characters in path - string trackNameSubstitute = trackInfo.TrackSortName.Replace("" + sep + "", "of"); - trackNameSubstitute = trackInfo.TrackSortName.Replace("/", "of"); - trackNameSubstitute = trackInfo.TrackID + "_" + trackNameSubstitute; + string trackNameSubstitute = $"{trackInfo.TrackID}_{trackInfo.TrackSortName}"; if (!Directory.Exists(defaultCategorizedPath)) { Directory.CreateDirectory(defaultCategorizedPath); - Console.WriteLine("Created folder: " + defaultCategorizedPath); + Console.WriteLine("Created folder: {0}", defaultCategorizedPath); } else { - Console.WriteLine("Already exist folder: " + defaultCategorizedPath); + Console.WriteLine("Already exist folder: {0}", defaultCategorizedPath); } - if (!Directory.Exists(defaultCategorizedPath + sep + trackNameSubstitute + trackInfo.DXChartTrackPathSuffix)) + + string trackPath = + $"{defaultCategorizedPath}/{trackNameSubstitute}{trackInfo.DXChartTrackPathSuffix}"; + if (!Directory.Exists(trackPath)) { - Directory.CreateDirectory(defaultCategorizedPath + sep + trackNameSubstitute + trackInfo.DXChartTrackPathSuffix); - Console.WriteLine("Created song folder: " + defaultCategorizedPath + sep + trackNameSubstitute + trackInfo.DXChartTrackPathSuffix); + Directory.CreateDirectory(trackPath); + Console.WriteLine("Created song folder: {0}",trackPath); } else { - Console.WriteLine("Already exist song folder: " + defaultCategorizedPath + sep + trackNameSubstitute + trackInfo.DXChartTrackPathSuffix); + Console.WriteLine("Already exist song folder: {0}", trackPath); } SimaiCompiler compiler; if (trackInfo.Information["Utage"] != "") { - compiler = new SimaiCompiler(StrictDecimal, track + sep + "", defaultCategorizedPath + sep + trackNameSubstitute + "_Utage", true); - compiler.WriteOut(defaultCategorizedPath + sep + trackNameSubstitute + trackInfo.DXChartTrackPathSuffix, true); + compiler = new SimaiCompiler(StrictDecimal, $"{track}/", $"{defaultCategorizedPath}/{trackNameSubstitute}_Utage", true); + compiler.WriteOut(trackPath, true); Program.CompiledChart.Add(compiler.GenerateOneLineSummary()); } else { - compiler = new SimaiCompiler(StrictDecimal, track + sep + "", defaultCategorizedPath + sep + trackNameSubstitute + trackInfo.DXChartTrackPathSuffix); - compiler.WriteOut(defaultCategorizedPath + sep + trackNameSubstitute + trackInfo.DXChartTrackPathSuffix, true); + compiler = new SimaiCompiler(StrictDecimal, $"{track}/", trackPath); + compiler.WriteOut(trackPath, true); Program.CompiledChart.Add(compiler.GenerateOneLineSummary()); } - Console.WriteLine("Finished compiling maidata " + trackInfo.TrackName + " to: " + defaultCategorizedPath + sep + trackNameSubstitute + trackInfo.DXChartTrackPathSuffix + sep + "maidata.txt"); + Console.WriteLine("Finished compiling maidata {0} to: {1}", trackInfo.TrackName, $"{trackPath}/maidata.txt"); if (exportAudio) { - string originalMusicLocation = audioLocation ?? throw new NullReferenceException("AUDIO FOLDER NOT SPECIFIED BUT AUDIO LOCATION IS NULL"); - originalMusicLocation += "music00" + shortID + ".mp3"; - string newMusicLocation = defaultCategorizedPath + sep + trackNameSubstitute + trackInfo.DXChartTrackPathSuffix + sep + "track.mp3"; + string originalMusicLocation = $"{audioLocation}/music00{shortID}.mp3" ?? throw new NullReferenceException("AUDIO FOLDER NOT SPECIFIED BUT AUDIO LOCATION IS NULL"); + string newMusicLocation = $"{trackPath}/track.mp3"; if (!File.Exists(newMusicLocation)) { File.Copy(originalMusicLocation, newMusicLocation); - Console.WriteLine("Exported music to: " + newMusicLocation); + Console.WriteLine("Exported music to: {0}", newMusicLocation); } else { - Console.WriteLine("Audio already found in: " + newMusicLocation); + Console.WriteLine("Audio already found in: {0}", newMusicLocation); } //See if image is existing if (exportAudio && !File.Exists(newMusicLocation)) @@ -289,39 +277,40 @@ public override int Run(string[] remainingArguments) if (exportImage) { - string originalImageLocation = imageLocation ?? throw new NullReferenceException("IMAGE FOLDER NOT SPECIFIED BUT AUDIO LOCATION IS NULL"); - originalImageLocation += "UI_Jacket_00" + shortID + ".png"; - string newImageLocation = defaultCategorizedPath + sep + trackNameSubstitute + trackInfo.DXChartTrackPathSuffix + sep + "bg.png"; + string originalImageLocation = $"{imageLocation}/UI_Jacket_00{shortID}.png" ?? throw new NullReferenceException("IMAGE FOLDER NOT SPECIFIED BUT AUDIO LOCATION IS NULL"); + string newImageLocation = $"{trackPath}/bg.png"; if (!File.Exists(newImageLocation)) { File.Copy(originalImageLocation, newImageLocation); - Console.WriteLine("Image exported to: " + newImageLocation); + Console.WriteLine("Image exported to: {0}", newImageLocation); } else { - Console.WriteLine("Image already found in: " + newImageLocation); + Console.WriteLine("Image already found in: {0}", newImageLocation); } //Check if Image exists if (exportImage && !File.Exists(newImageLocation)) { - Console.WriteLine("Image exists at " + originalImageLocation + ": " + File.Exists(originalImageLocation)); + Console.WriteLine("Image exists at {0}: {1}", originalImageLocation, File.Exists(originalImageLocation)); throw new FileNotFoundException("IMAGE NOT FOUND IN: " + newImageLocation); } } // Console.WriteLine("Exported to: " + outputLocation + trackInfo.TrackGenre + sep + trackNameSubstitute + trackInfo.DXChart); - string? originalBGALocation = ""; - bool bgaExists = bgaMap.TryGetValue(Program.CompensateZero(trackInfo.TrackID), out originalBGALocation); + bool bgaExists = bgaMap.TryGetValue(Program.CompensateZero(trackInfo.TrackID), out var originalBGALocation); if (!bgaExists) { + // Compensate on DX Utage if (trackInfo.TrackID.Length == 6) { bgaExists = bgaMap.TryGetValue(trackInfo.TrackID.Substring(2, 4), out originalBGALocation); } + // Compensate on DX Standard else if (trackInfo.TrackID.Length == 5) { bgaExists = bgaMap.TryGetValue(trackInfo.TrackID.Substring(1, 4), out originalBGALocation); } + // Compensate on Standard else if (trackInfo.TrackID.Length == 3) { bgaExists = bgaMap.TryGetValue(Program.CompensateShortZero(trackInfo.TrackID), out originalBGALocation); @@ -337,22 +326,22 @@ public override int Run(string[] remainingArguments) } if (exportBGA) { - string? newBGALocation = defaultCategorizedPath + sep + trackNameSubstitute + trackInfo.DXChartTrackPathSuffix + sep + "pv.mp4"; + string? newBGALocation = $"{trackPath}/pv.mp4"; if (bgaExists && !File.Exists(newBGALocation)) { - Console.WriteLine("A BGA file was found in " + originalBGALocation); - var originalBGALocationCandidate = originalBGALocation ?? throw new NullReferenceException(); + Console.WriteLine("A BGA file was found in {0}", originalBGALocation); + string originalBGALocationCandidate = originalBGALocation ?? throw new NullReferenceException(); File.Copy(originalBGALocationCandidate, newBGALocation); - Console.WriteLine("Exported BGA file to: " + newBGALocation); + Console.WriteLine("Exported BGA file to: {0}", newBGALocation); } else if (bgaExists && File.Exists(newBGALocation)) { - Console.WriteLine("BGA already found in " + newBGALocation); + Console.WriteLine("BGA already found in {0}", newBGALocation); } //Check if BGA exists if (exportBGA && bgaExists && !File.Exists(newBGALocation)) { - Console.WriteLine("BGA exists at " + originalBGALocation + ": " + File.Exists(originalBGALocation)); + Console.WriteLine("BGA exists at {0}: {1}", originalBGALocation, File.Exists(originalBGALocation)); throw new FileNotFoundException("BGA NOT FOUND IN: " + newBGALocation); } } @@ -363,19 +352,19 @@ public override int Run(string[] remainingArguments) string[] compiledTrackDetail = { trackInfo.TrackName, trackInfo.TrackGenre, trackInfo.TrackVersion, trackInfo.TrackVersionNumber }; Program.CompiledTrackDetailSet.Add(trackInfo.TrackName + trackInfo.TrackID, compiledTrackDetail); // Program.CompiledChart.Add(trackInfo.TrackName + compiler.GenerateOneLineSummary()); - Console.WriteLine("Exported to: " + defaultCategorizedPath + sep + trackNameSubstitute + trackInfo.DXChartTrackPathSuffix); + Console.WriteLine("Exported to: {0}", trackPath); Console.WriteLine(); } else { - Console.WriteLine("There is no Music.xml in folder " + track); + Console.WriteLine("There is no Music.xml in folder {0}", track); } } - Console.WriteLine("Total music compiled: " + Program.NumberTotalTrackCompiled); + Console.WriteLine("Total music compiled: {0}", Program.NumberTotalTrackCompiled); int index = 1; foreach (KeyValuePair pair in Program.CompiledTracks) { - Console.WriteLine("[" + index + "]: " + pair.Key + " " + pair.Value); + Console.WriteLine($"[{index}]: {pair.Key} {pair.Value}"); index++; } Program.Log(outputLocation); @@ -383,7 +372,7 @@ public override int Run(string[] remainingArguments) } catch (Exception ex) { - Console.WriteLine("Program cannot proceed becasue of following error returned: \n{0}", ex.GetType()); + Console.WriteLine("Program cannot proceed because of following error returned: \n{0}", ex.GetType()); Console.Error.WriteLine(ex.Message); Console.Error.WriteLine(ex.StackTrace); Console.ReadKey(); diff --git a/Commands/CompileMa2.cs b/Commands/CompileMa2.cs index b670160..2dc3645 100644 --- a/Commands/CompileMa2.cs +++ b/Commands/CompileMa2.cs @@ -90,18 +90,23 @@ public override int Run(string[] remainingArguments) { case null: case "simai": + case "Simai": + case "SimaiFes": Simai resultChart = new Simai(candidate); + resultChart.Update(); result = resultChart.Compose(); if (Destination != null && !Destination.Equals("")) { - StreamWriter sw = new StreamWriter(Destination + Program.GlobalSep + "maidata.txt", false); + string targetMaidataLocation = $"{Destination}/maidata.txt"; + if (!Directory.Exists(Destination)) Directory.CreateDirectory(Destination); + StreamWriter sw = new StreamWriter(targetMaidataLocation, false); { sw.WriteLine(result); } sw.Close(); - if (File.Exists(Destination + Program.GlobalSep + "maidata.txt")) + if (File.Exists(targetMaidataLocation)) { - Console.WriteLine("Successfully compiled at: " + Destination + Program.GlobalSep + "result.ma2"); + Console.WriteLine("Successfully compiled at: {0}", targetMaidataLocation); } else { @@ -111,51 +116,27 @@ public override int Run(string[] remainingArguments) else Console.WriteLine(result); break; case "ma2": - case "MA2": case "Ma2": + case "MA2": case "Ma2_103": - if (result.Equals("")) - { - Ma2 defaultChart = new Ma2(candidate); - result = defaultChart.Compose(); - } - if (Destination != null && !Destination.Equals("")) - { - StreamWriter sw = new StreamWriter(Destination + Program.GlobalSep + "result.ma2", false); - { - sw.WriteLine(result); - } - sw.Close(); - if (File.Exists(Destination + Program.GlobalSep + "result.ma2")) - { - Console.WriteLine("Successfully compiled at: " + Destination + Program.GlobalSep + "result.ma2"); - } - else - { - throw new FileNotFoundException("THE FILE IS NOT SUCCESSFULLY COMPILED."); - } - } - else Console.WriteLine(result); - break; case "Ma2_104": if (result.Equals("")) { - Ma2 defaultChart = new Ma2(candidate) - { - ChartVersion = ChartEnum.ChartVersion.Ma2_104 - }; + Ma2 defaultChart = TargetFormat.Equals("Ma2_104")? new Ma2(candidate){ChartVersion = ChartEnum.ChartVersion.Ma2_104} : new Ma2(candidate); result = defaultChart.Compose(); } if (Destination != null && !Destination.Equals("")) { - StreamWriter sw = new StreamWriter(Destination + Program.GlobalSep + "result.ma2", false); + string targetMaidataLocation = $"{Destination}/result.ma2"; + if (!Directory.Exists(Destination)) Directory.CreateDirectory(Destination); + StreamWriter sw = new StreamWriter(targetMaidataLocation, false); { sw.WriteLine(result); } sw.Close(); - if (File.Exists(Destination + Program.GlobalSep + "result.ma2")) + if (File.Exists(targetMaidataLocation)) { - Console.WriteLine("Successfully compiled at: " + Destination + Program.GlobalSep + "result.ma2"); + Console.WriteLine("Successfully compiled at: {0}", targetMaidataLocation); } else { diff --git a/Commands/CompileMa2ID.cs b/Commands/CompileMa2ID.cs index ad0f414..db0141d 100644 --- a/Commands/CompileMa2ID.cs +++ b/Commands/CompileMa2ID.cs @@ -12,6 +12,7 @@ public class CompileMa2ID : ConsoleCommand /// Return when command successfully executed /// private const int Success = 0; + /// /// Return when command failed to execute /// @@ -21,27 +22,33 @@ public class CompileMa2ID : ConsoleCommand /// Source file path /// public string? FileLocation { get; set; } + /// /// Difficulty /// public string? Difficulty { get; set; } + /// /// ID /// public string? ID { get; set; } + /// /// Destination of output /// public string? Destination { get; set; } + /// /// Target Format of the file /// public string? TargetFormat { get; set; } + /// /// Rotation option for charts /// /// Clockwise90/180, Counterclockwise90/180, UpsideDown, LeftToRight public string? Rotate { get; set; } + /// /// OverallTick Shift for the chart: if the shift tick exceeds the 0 Bar 0 Tick, any note before 0 bar 0 tick will be discarded. /// @@ -54,14 +61,20 @@ public class CompileMa2ID : ConsoleCommand public CompileMa2ID() { IsCommand("CompileMa2ID", "Compile assigned Ma2 chart to assigned format"); - HasLongDescription("This function enables user to compile ma2 chart specified to the format they want. By default is simai for ma2."); - HasRequiredOption("d|difficulty=", "REQUIRED: The number representing the difficulty of chart -- 0-4 for Basic to Re:Master", diff => Difficulty = diff); + HasLongDescription( + "This function enables user to compile ma2 chart specified to the format they want. By default is simai for ma2."); + HasRequiredOption("d|difficulty=", + "REQUIRED: The number representing the difficulty of chart -- 0-4 for Basic to Re:Master", + diff => Difficulty = diff); HasRequiredOption("i|id=", "REQUIRED: The id of the ma2", id => ID = id); - HasRequiredOption("p|path=", "REQUIRED: Folder of A000 to override - end with a path separator", path => FileLocation = path); + HasRequiredOption("p|path=", "REQUIRED: Folder of A000 to override - end with a path separator", + path => FileLocation = path); //FileLocation = GlobalPaths[0]; //HasOption("a|a000=", "Folder of A000 to override - end with a path separator", path => FileLocation = path); HasOption("f|format=", "The target format - simai or ma2", format => TargetFormat = format); - HasOption("r|rotate=", "Rotating method to rotate a chart: Clockwise90/180, Counterclockwise90/180, UpsideDown, LeftToRight", rotate => Rotate = rotate); + HasOption("r|rotate=", + "Rotating method to rotate a chart: Clockwise90/180, Counterclockwise90/180, UpsideDown, LeftToRight", + rotate => Rotate = rotate); HasOption("s|shift=", "Overall shift to the chart in unit of tick", tick => ShiftTick = int.Parse(tick)); HasOption("o|output=", "Export compiled chart to location specified", dest => Destination = dest); } @@ -80,34 +93,45 @@ public override int Run(string[] remainingArguments) Ma2Parser parser = new Ma2Parser(); //Chart good = new Ma2(@"/Users/neskol/MaiAnalysis/A000/music/music" + musicID + "/" + musicID + "_0" + difficulty + ".ma2"); string tokenLocation = FileLocation ?? throw new FileNotFoundException(); - Chart candidate = parser.ChartOfToken(tokenizer.Tokens(tokenLocation + "music" + Program.GlobalSep + "music" + Program.CompensateZero(ID ?? throw new NullReferenceException("ID shall not be null")) + Program.GlobalSep + Program.CompensateZero(ID ?? throw new NullReferenceException("ID shall not be null")) + "_0" + Difficulty + ".ma2")); + string compensatedId = + Program.CompensateZero(ID ?? throw new NullReferenceException("ID shall not be null")); + Chart candidate = parser.ChartOfToken(tokenizer.Tokens( + $"{tokenLocation}/music/music{compensatedId}/{compensatedId}_0{Difficulty}.ma2")); if (Rotate != null) { bool rotationIsValid = Enum.TryParse(Rotate, out NoteEnum.FlipMethod rotateMethod); if (!rotationIsValid) throw new Exception("Given rotation method is not valid. Given: " + Rotate); candidate.RotateNotes(rotateMethod); } + if (ShiftTick != null && ShiftTick != 0) { candidate.ShiftByOffset((int)ShiftTick); } + string result = ""; switch (TargetFormat) { case null: + case "": case "simai": + case "Simai": + case "SimaiFes": Simai resultChart = new Simai(candidate); + // resultChart.Update(); result = resultChart.Compose(); if (Destination != null && !Destination.Equals("")) { - StreamWriter sw = new StreamWriter(Destination + Program.GlobalSep + "maidata.txt", false); + string targetMaidataLocation = $"{Destination}/maidata.txt"; + if (!Directory.Exists(Destination)) Directory.CreateDirectory(Destination); + StreamWriter sw = new StreamWriter(targetMaidataLocation, false); { sw.WriteLine(result); } sw.Close(); - if (File.Exists(Destination + Program.GlobalSep + "maidata.txt")) + if (File.Exists(targetMaidataLocation)) { - Console.WriteLine("Successfully compiled at: " + Destination + Program.GlobalSep + "result.ma2"); + Console.WriteLine("Successfully compiled at: {0}", targetMaidataLocation); } else { @@ -115,23 +139,33 @@ public override int Run(string[] remainingArguments) } } else Console.WriteLine(result); + break; case "ma2": + case "Ma2": + case "MA2": + case "Ma2_103": + case "Ma2_104": if (result.Equals("")) { - Ma2 defaultChart = new Ma2(candidate); + Ma2 defaultChart = TargetFormat.Equals("Ma2_104") + ? new Ma2(candidate) { ChartVersion = ChartEnum.ChartVersion.Ma2_104 } + : new Ma2(candidate); result = defaultChart.Compose(); } + if (Destination != null && !Destination.Equals("")) { - StreamWriter sw = new StreamWriter(Destination + Program.GlobalSep + "result.ma2", false); + string targetMaidataLocation = $"{Destination}/result.ma2"; + if (!Directory.Exists(Destination)) Directory.CreateDirectory(Destination); + StreamWriter sw = new StreamWriter(targetMaidataLocation, false); { sw.WriteLine(result); } sw.Close(); - if (File.Exists(Destination + Program.GlobalSep + "result.ma2")) + if (File.Exists(targetMaidataLocation)) { - Console.WriteLine("Successfully compiled at: " + Destination + Program.GlobalSep + "result.ma2"); + Console.WriteLine("Successfully compiled at: {0}", targetMaidataLocation); } else { @@ -154,5 +188,4 @@ public override int Run(string[] remainingArguments) } } } - } diff --git a/Commands/CompileUtageDatabase.cs b/Commands/CompileUtageDatabase.cs deleted file mode 100644 index bbbaad5..0000000 --- a/Commands/CompileUtageDatabase.cs +++ /dev/null @@ -1,364 +0,0 @@ -using ManyConsole; -using MaiLib; - -namespace MaichartConverter -{ - - /// - /// Compile Ma2 Command - /// - public class CompileUtageDatabase : ConsoleCommand - { - /// - /// Return when command successfully executed - /// - private const int Success = 0; - /// - /// Return when command failed to execute - /// - private const int Failed = 2; - - /// - /// Source file path - /// - public string? A000Location { get; set; } - /// - /// Image file path - /// - public string? ImageLocation { get; set; } - /// - /// Music file path - /// - public string? BGMLocation { get; set; } - /// - /// Video file path - /// - public string? VideoLocation { get; set; } - /// - /// Difficulty - /// - public string? Difficulty { get; set; } - - /// - /// Categorize Index - /// - private int categorizeIndex = 0; - /// - /// Categorize Index outer shell - /// - public int? CategorizeIndex - { - get - { return categorizeIndex; } - set - { - if (value != null) categorizeIndex = (int)value; - else categorizeIndex = 0; - } - } - /// - /// Destination of output - /// - public string? Destination { get; set; } - /// - /// Target Format of the file - /// - public string? TargetFormat { get; set; } - - /// - /// Stores categorize method for easier access - /// - public string CategorizeMethods { get; set; } - /// - /// Rotation option for charts - /// - /// Clockwise90/180, Counterclockwise90/180, UpsideDown, LeftToRight - public string? Rotate { get; set; } - /// - /// OverallTick Shift for the chart: if the shift tick exceeds the 0 Bar 0 Tick, any note before 0 bar 0 tick will be discarded. - /// - /// Tick, 384 tick = 1 bar - public int? ShiftTick { get; set; } - - /// - /// Construct Command - /// - public CompileUtageDatabase() - { - CategorizeMethods = ""; - for (int i = 0; i < Program.TrackCategorizeMethodSet.Length; i++) - { - CategorizeMethods += "[" + i + "] " + Program.TrackCategorizeMethodSet[i] + "\n"; - } - IsCommand("CompileUtageDatabase", "Compile whole utage database to format assigned"); - HasLongDescription("This function enables user to compile whole database to the format they want. By default is simai for ma2."); - HasRequiredOption("p|path=", "REQUIRED: Folder of A000 to override - end with a path separator", aPath => A000Location = aPath); - HasRequiredOption("o|output=", "REQUIRED: Export compiled chart to location specified", dest => Destination = dest); - HasOption("m|music=", "Folder of Music files to override - end with a path separator", mPath => BGMLocation = mPath); - HasOption("c|cover=", "Folder of Cover Image to override - end with a path separator", iPath => ImageLocation = iPath); - //FileLocation = GlobalPaths[0]; - //HasOption("a|a000=", "Folder of A000 to override - end with a path separator", path => FileLocation = path); - HasOption("f|format=", "The target format - simai or ma2", format => TargetFormat = format); - HasOption("g|genre=", "The preferred categorizing scheme, includes:\n" + CategorizeMethods, genre => Int32.TryParse(genre, out categorizeIndex)); - HasOption("r|rotate=", "Rotating method to rotate a chart: Clockwise90/180, Counterclockwise90/180, UpsideDown, LeftToRight", rotate => Rotate = rotate); - HasOption("s|shift=", "Overall shift to the chart in unit of tick", tick => ShiftTick = int.Parse(tick)); - HasOption("v|video=", "Folder of Video to override - end with a path separator", vPath => VideoLocation = vPath); - } - - /// - /// Execute the command - /// - /// Rest of the arguments - /// Code of execution indicates if the commands is successfully executed - /// Raised when the file is not found - public override int Run(string[] remainingArguments) - { - try - { - string sep = Program.GlobalSep; - bool exportBGA = true; - bool exportImage = true; - bool exportAudio = true; - string a000Location = A000Location ?? throw new FileNotFoundException("A000 location was not specified"); - if (a000Location == null || a000Location.Equals("")) - { - a000Location = Program.GlobalPaths[0]; - } - - string musicLocation = a000Location + @"music" + sep; - string? audioLocation = BGMLocation; - if (BGMLocation == null) - { - exportAudio = false; - } - else if (BGMLocation.Equals("")) - { - audioLocation = Program.GlobalPaths[1]; - } - - string? imageLocation = ImageLocation; - if (ImageLocation == null) - { - exportImage = false; - } - else if (ImageLocation.Equals("")) - { - imageLocation = Program.GlobalPaths[2]; - } - - string? bgaLocation = VideoLocation; - if (VideoLocation == null) - { - exportBGA = false; - } - else if (VideoLocation.Equals("")) - { - bgaLocation = Program.GlobalPaths[3]; - } - - string outputLocation = Destination ?? throw new NullReferenceException("Destination not specified"); - if (outputLocation.Equals("")) - { - outputLocation = Program.GlobalPaths[4]; - } - - try - { - if (0 <= categorizeIndex && categorizeIndex < Program.TrackCategorizeMethodSet.Length) - { - Program.GlobalTrackCategorizeMethod = Program.TrackCategorizeMethodSet[categorizeIndex]; - } - } - catch (Exception e) - { - Console.WriteLine(e.Message + " The program will use Genre as default method. Press any key to continue."); - Program.GlobalTrackCategorizeMethod = Program.TrackCategorizeMethodSet[0]; - categorizeIndex = 0; - Console.ReadKey(); - } - - Dictionary bgaMap = new Dictionary(); - if (exportBGA && bgaLocation != null) - { - string[] bgaFiles = Directory.GetFiles(bgaLocation, "*.mp4"); - Array.Sort(bgaFiles); - - foreach (string bgaFile in bgaFiles) - { - string musicID = bgaFile.Substring(bgaLocation.Length).Substring(0, 6).Substring(2, 4); - bgaMap.Add(Program.CompensateZero(musicID), bgaFile); - bgaMap.Add("01" + musicID, bgaFile); - } - } - else if (exportBGA) throw new NullReferenceException("BGA LOCATION IS NOT SPECIFIED BUT BGA OPTION IS ENABLED"); - string[] musicFolders = Directory.GetDirectories(musicLocation); - - //Create output directory - DirectoryInfo output = new DirectoryInfo(outputLocation); - - Program.NumberTotalTrackCompiled = 0; - Program.CompiledTracks = new Dictionary(); - //Iterate music folders - foreach (string track in musicFolders) - { - if (File.Exists(track + sep + "Music.xml")) - { - TrackInformation trackInfo = new XmlInformation(track + sep + ""); - Console.WriteLine("There is Music.xml in " + track); - string shortID = Program.CompensateZero(trackInfo.TrackID).Substring(2); - Console.WriteLine("Name: " + trackInfo.TrackName); - Console.WriteLine("ID:" + trackInfo.TrackID); - Console.WriteLine("Genre: " + trackInfo.TrackGenre); - string[] categorizeScheme = { trackInfo.TrackGenre, trackInfo.TrackSymbolicLevel, trackInfo.TrackVersion, trackInfo.TrackComposer, trackInfo.TrackBPM, trackInfo.StandardDeluxePrefix, "" }; - string defaultCategorizedPath = outputLocation + categorizeScheme[categorizeIndex]; - - //Cross out if not creating update packs - // defaultCategorizedPath += sep + categorizeScheme[0]; - - //Deal with special characters in path - string trackNameSubstitute = trackInfo.TrackSortName.Replace("" + sep + "", "of"); - trackNameSubstitute = trackInfo.TrackSortName.Replace("/", "of"); - trackNameSubstitute = trackInfo.TrackID + "_" + trackNameSubstitute; - if (!Directory.Exists(defaultCategorizedPath)) - { - Directory.CreateDirectory(defaultCategorizedPath); - Console.WriteLine("Created folder: " + defaultCategorizedPath); - } - else - { - Console.WriteLine("Already exist folder: " + defaultCategorizedPath); - } - if (!Directory.Exists(defaultCategorizedPath + sep + trackNameSubstitute + "_Utage")) - { - Directory.CreateDirectory(defaultCategorizedPath + sep + trackNameSubstitute + "_Utage"); - Console.WriteLine("Created song folder: " + defaultCategorizedPath + sep + trackNameSubstitute + "_Utage"); - } - else - { - Console.WriteLine("Already exist song folder: " + defaultCategorizedPath + sep + trackNameSubstitute + "_Utage"); - } - SimaiCompiler compiler = new SimaiCompiler(false, track + sep + "", defaultCategorizedPath + sep + trackNameSubstitute + "_Utage", true); - compiler.WriteOut(defaultCategorizedPath + sep + trackNameSubstitute + "_Utage", false); - Console.WriteLine("Finished compiling maidata " + trackInfo.TrackName + " to: " + defaultCategorizedPath + sep + trackNameSubstitute + "_Utage" + sep + "maidata.txt"); - if (exportAudio) - { - string originalMusicLocation = audioLocation ?? throw new NullReferenceException("AUDIO FOLDER NOT SPECIFIED BUT AUDIO LOCATION IS NULL"); - originalMusicLocation += "music00" + shortID + ".mp3"; - string newMusicLocation = defaultCategorizedPath + sep + trackNameSubstitute + "_Utage" + sep + "track.mp3"; - if (!File.Exists(newMusicLocation)) - { - File.Copy(originalMusicLocation, newMusicLocation); - Console.WriteLine("Exported music to: " + newMusicLocation); - } - else - { - Console.WriteLine("Audio already found in: " + newMusicLocation); - } - //See if image is existing - if (exportAudio && !File.Exists(newMusicLocation)) - { - Console.WriteLine("Audio exists at " + originalMusicLocation + ": " + File.Exists(originalMusicLocation)); - throw new FileNotFoundException("MUSIC NOT FOUND IN:" + newMusicLocation); - } - } - - if (exportImage) - { - string originalImageLocation = imageLocation ?? throw new NullReferenceException("IMAGE SPECIFIED BUT IMAGE LOCATION IS NULL"); - originalImageLocation += "UI_Jacket_00" + shortID + ".png"; - string newImageLocation = defaultCategorizedPath + sep + trackNameSubstitute + "_Utage" + sep + "bg.png"; - if (!File.Exists(newImageLocation) && File.Exists(originalImageLocation)) - { - File.Copy(originalImageLocation, newImageLocation); - Console.WriteLine("Image exported to: " + newImageLocation); - } - else - { - Console.WriteLine("Image already found in: " + newImageLocation); - } - //Check if Image exists - if (exportImage && !File.Exists(newImageLocation)) - { - Program.ErrorMessage.Add("Image exists at " + originalImageLocation + ": " + File.Exists(originalImageLocation) + "BUT NOT FOUND AT " + newImageLocation); - } - } - // Console.WriteLine("Exported to: " + outputLocation + trackInfo.TrackGenre + sep + trackNameSubstitute + trackInfo.DXChart); - - string? originalBGALocation = ""; - bool bgaExists = bgaMap.TryGetValue(Program.CompensateZero(trackInfo.TrackID), out originalBGALocation); - if (!bgaExists) - { - if (trackInfo.TrackID.Length == 5) - { - bgaExists = bgaMap.TryGetValue(trackInfo.TrackID.Substring(1, 4), out originalBGALocation); - } - else if (trackInfo.TrackID.Length == 3) - { - bgaExists = bgaMap.TryGetValue(Program.CompensateShortZero(trackInfo.TrackID), out originalBGALocation); - } - } - if (exportBGA && !bgaExists) - { - Console.WriteLine("BGA NOT FOUND"); - Console.WriteLine(trackInfo.TrackID); - Console.WriteLine(Program.CompensateZero(trackInfo.TrackID)); - Console.WriteLine(originalBGALocation); - Program.ErrorMessage.Add(trackInfo.TrackID + "BGA Not Found in " + originalBGALocation); - } - if (exportBGA) - { - string? newBGALocation = defaultCategorizedPath + sep + trackNameSubstitute + "_Utage" + sep + "pv.mp4"; - if (bgaExists && !File.Exists(newBGALocation)) - { - Console.WriteLine("A BGA file was found in " + originalBGALocation); - var originalBGALocationCandidate = originalBGALocation ?? throw new NullReferenceException("EXPORT AUDIO BUT AUDIO NOT FOUND"); - File.Copy(originalBGALocationCandidate, newBGALocation); - Console.WriteLine("Exported BGA file to: " + newBGALocation); - } - else if (bgaExists && File.Exists(newBGALocation)) - { - Console.WriteLine("BGA already found in " + newBGALocation); - } - //Check if BGA exists - if (exportBGA && bgaExists && !File.Exists(newBGALocation)) - { - Program.ErrorMessage.Add("BGA exists at " + originalBGALocation + ": " + File.Exists(originalBGALocation) + " BUT BGA NOT FOUND IN: " + newBGALocation); - } - } - Program.NumberTotalTrackCompiled++; - Program.CompiledTracks.Add(int.Parse(trackInfo.TrackID), trackInfo.TrackName); - // Program.AppendBPM(trackInfo.TrackID, trackInfo.TrackBPM); - // AppendDebugInformation(trackInfo.TrackID, compiler.SymbolicBPMTable(), compiler.SymbolicFirstNote(false)); - string[] compiledTrackDetail = { trackInfo.TrackName, trackInfo.TrackGenre, trackInfo.TrackVersion, trackInfo.TrackVersionNumber }; - Program.CompiledTrackDetailSet.Add(trackInfo.TrackName + trackInfo.TrackID, compiledTrackDetail); - Program.CompiledChart.Add(trackInfo.TrackID + trackInfo.TrackName + compiler.GenerateOneLineSummary()); - Console.WriteLine("Exported to: " + defaultCategorizedPath + sep + trackNameSubstitute + "_Utage"); - Console.WriteLine(); - } - else - { - Console.WriteLine("There is no Music.xml in folder " + track); - } - } - Console.WriteLine("Total music compiled: " + Program.NumberTotalTrackCompiled); - int index = 1; - foreach (KeyValuePair pair in Program.CompiledTracks) - { - Console.WriteLine("[" + index + "]: " + pair.Key + " " + pair.Value); - index++; - } - Program.Log(outputLocation); - return Success; - } - catch (Exception ex) - { - Console.WriteLine("Program cannot proceed becasue of following error returned: \n{0}", ex.GetType()); - Console.Error.WriteLine(ex.Message); - Console.Error.WriteLine(ex.StackTrace); - Console.ReadKey(); - return Failed; - } - } - } - -} diff --git a/Commands/ComposeSimai.cs b/Commands/ComposeSimai.cs index 22639c6..ae50801 100644 --- a/Commands/ComposeSimai.cs +++ b/Commands/ComposeSimai.cs @@ -92,23 +92,25 @@ public override int Run(string[] remainingArguments) { candidate.ShiftByOffset((int)ShiftTick); } - SimaiCompiler compiler = new SimaiCompiler(); string result = ""; switch (TargetFormat) { case "Simai": + case "SimaiFes": Simai resultChart = new Simai(candidate); result = resultChart.Compose(); if (Destination is not null && !Destination.Equals("")) { - StreamWriter sw = new StreamWriter(Destination + Program.GlobalSep + "maidata.txt", false); + string targetMaidataLocation = $"{Destination}/maidata.txt"; + if (!Directory.Exists(Destination)) Directory.CreateDirectory(Destination); + StreamWriter sw = new StreamWriter(targetMaidataLocation, false); { sw.WriteLine(result); } sw.Close(); - if (File.Exists(Destination + Program.GlobalSep + "maidata.txt")) + if (File.Exists(targetMaidataLocation)) { - Console.WriteLine("Successfully compiled at: " + Destination + Program.GlobalSep + "maidata.txt"); + Console.WriteLine("Successfully compiled at: {0}", targetMaidataLocation); } else { @@ -120,48 +122,27 @@ public override int Run(string[] remainingArguments) case null: case "": case "Ma2": - if (result.Equals("")) - { - Ma2 defaultChart = new Ma2(candidate); - result = defaultChart.Compose(); - } - if (Destination != null && !Destination.Equals("")) - { - StreamWriter sw = new StreamWriter(Destination + Program.GlobalSep + "result.ma2", false); - { - sw.WriteLine(result); - } - sw.Close(); - if (File.Exists(Destination + Program.GlobalSep + "result.ma2")) - { - Console.WriteLine("Successfully compiled at: " + Destination + Program.GlobalSep + "result.ma2"); - } - else - { - throw new FileNotFoundException("THE FILE IS NOT SUCCESSFULLY COMPILED."); - } - } - else Console.WriteLine(result); - break; + case "ma2": + case "MA2": + case "Ma2_103": case "Ma2_104": if (result.Equals("")) { - Ma2 defaultChart = new Ma2(candidate) - { - ChartVersion = ChartEnum.ChartVersion.Ma2_104 - }; + Ma2 defaultChart = TargetFormat is "Ma2_104"? new Ma2(candidate){ChartVersion = ChartEnum.ChartVersion.Ma2_104} : new Ma2(candidate); result = defaultChart.Compose(); } if (Destination != null && !Destination.Equals("")) { - StreamWriter sw = new StreamWriter(Destination + Program.GlobalSep + "result.ma2", false); + string targetMaidataLocation = $"{Destination}/result.ma2"; + if (!Directory.Exists(Destination)) Directory.CreateDirectory(Destination); + StreamWriter sw = new StreamWriter(targetMaidataLocation, false); { sw.WriteLine(result); } sw.Close(); - if (File.Exists(Destination + Program.GlobalSep + "result.ma2")) + if (File.Exists(targetMaidataLocation)) { - Console.WriteLine("Successfully compiled at: " + Destination + Program.GlobalSep + "result.ma2"); + Console.WriteLine("Successfully compiled at: {0}", targetMaidataLocation); } else { @@ -178,7 +159,7 @@ public override int Run(string[] remainingArguments) } catch (Exception ex) { - Console.WriteLine("Program cannot proceed becasue of following error returned: \n{0}", ex.GetType()); + Console.WriteLine("Program cannot proceed because of following error returned: \n{0}", ex.GetType()); Console.Error.WriteLine(ex.Message); Console.Error.WriteLine(ex.StackTrace); Console.ReadKey(); diff --git a/Commands/Manuals/CompileDatabase.md b/Commands/Manuals/CompileDatabase.md new file mode 100644 index 0000000..1bdca52 --- /dev/null +++ b/Commands/Manuals/CompileDatabase.md @@ -0,0 +1,25 @@ +# Manual for `CompileDatabase` command +### Compile whole ma2 database to simai +## Basic usage + MaichartConverter CompileDatabase --params +## Example usage + MaichartConverter CompileDatabase -p "/Users/Neskol/MaiAnalysis/A000/" -c "/Users/Neskol/MaiAnalysis/Image/Texture2D/" -v "/Users/Neskol/MaiAnalysis/DXBGA_HEVC/" -m "/Users/Neskol/MaiAnalysis/Sound/" -o "/Users/Neskol/MaiAnalysis/Output_HEVC_By_Cab/" -g 2 -d +## Available Params +### Required Params: +> Unless otherwise specified, `XXXXXX` here stands for musicID. +- `-p | --path `: Path to `A000` Folder. Expects file structure of `A000/music/musicXXXXXX/Music.xml` +- `-o | --output `: Path to output folder. Program will try to write to this path and create new folder when necessary so make sure you have write permission of the given folder. + +### Optional Params: +- `-m | --music `: Path to MP3 files. Expected naming scheme is `musicXXXXXX.mp3`. +- `-c | --cover `: Path to track pictures. Expected naming scheme is `UI_Jacket_XXXXXX.png`. +- `-v | --video `: Path to background videos. Expected naming scheme is `musicXXXXXX.mp4` +- `-g | --genre `: Preferred categorizing scheme. +`0 = Genre, 1 = Level, 2 = Cabinet, 3 = Composer, 4 = BPM, 5 - SD/DX Chart, 6 = No subfolders` +- `-d | --decimal`: Option to force levels to be displayed in decimals (e.g. `14+ => 14.7`). + +### Depreciated/Under development params: +> These parameters are not tested. Feel free to test and report issues! +- `-f | --format `: Forces program to compile carts in given format (within composed `maidata`.txt). Available format: `Simai, SimaiFes, Ma2, Ma2_104`. +- `-r | --rotate `: Forces program to rotate all charts in given method. Available rotations: `Clockwise90, Clockwise180, CounterClockwise90, CounterClockwise180, UpsideDown, LeftToRight`. +- `-s | --shift `: Shifts notes in all charts front or back by given ticks. diff --git a/Commands/Manuals/CompileMa2.md b/Commands/Manuals/CompileMa2.md new file mode 100644 index 0000000..a40825e --- /dev/null +++ b/Commands/Manuals/CompileMa2.md @@ -0,0 +1,16 @@ +# Manual for `ComposeMa2` command +### Compile assigned Ma2 chart to assigned format +## Basic usage + MaichartConverter ComposeMa2 --params +## Example usage + MaichartConverter ComposeMa2 -p "/Users/Neskol/MaiAnalysis/A000/music/music000363/000363_03.ma2" -f Ma2_104 +### Required Params: +> Unless otherwise specified, `XXXXXX` here stands for musicID. +- `-p | --path `: Path to .ma2 file to be converted. + +### Optional Params: +> Program will print result in the terminal if `-o | --output` parameter is not provided. +- `-f | --format `: Forces program to compile carts in given format (within composed `maidata`.txt). Available format: `Simai, SimaiFes, Ma2, Ma2_104`. Note: Festival features requires `SimaiFes` or `Ma2_104` parameter. +- `-r | --rotate `: Forces program to rotate all charts in given method. Available rotations: `Clockwise90, Clockwise180, CounterClockwise90, CounterClockwise180, UpsideDown, LeftToRight`. +- `-s | --shift `: Shifts notes in all charts front or back by given ticks. +- `-o | --output `: Path to output folder. Program will try to write to this path and create new folder when necessary so make sure you have write permission of the given folder. \ No newline at end of file diff --git a/Commands/Manuals/CompileMa2ID.md b/Commands/Manuals/CompileMa2ID.md new file mode 100644 index 0000000..3cf0f15 --- /dev/null +++ b/Commands/Manuals/CompileMa2ID.md @@ -0,0 +1,19 @@ +# Manual for `ComposeMa2ID` command +### Compile assigned Ma2 chart indexed by ID to assigned format +## Basic usage + MaichartConverter ComposeMa2ID --params +## Example usage + MaichartConverter ComposeMa2ID -p "/Users/Neskol/MaiAnalysis/A000" -i 363 -d 3 -f Ma2_104 +## Available Params +### Required Params: +> Unless otherwise specified, `XXXXXX` here stands for musicID. +- `-p | --path `: Path to `A000` Folder. Expects file structure of `A000/music/musicXXXXXX/Music.xml` +- `-i | --id `: Index of the track. Program will compensate 0s at the front. +- `-d | --difficulty <0-4>`: Difficulty to be specified. 0-4 for Basic to Re:Master. + +### Optional Params: +> Program will print result in the terminal if `-o | --output` parameter is not provided. +- `-f | --format `: Forces program to compile carts in given format (within composed `maidata`.txt). Available format: `Simai, SimaiFes, Ma2, Ma2_104`. Note: Festival features requires `SimaiFes` or `Ma2_104` parameter. +- `-r | --rotate `: Forces program to rotate all charts in given method. Available rotations: `Clockwise90, Clockwise180, CounterClockwise90, CounterClockwise180, UpsideDown, LeftToRight`. +- `-s | --shift `: Shifts notes in all charts front or back by given ticks. +- `-o | --output `: Path to output folder. Program will try to write to this path and create new folder when necessary so make sure you have write permission of the given folder. \ No newline at end of file diff --git a/Commands/Manuals/CompileSimai.md b/Commands/Manuals/CompileSimai.md new file mode 100644 index 0000000..8d6cd2b --- /dev/null +++ b/Commands/Manuals/CompileSimai.md @@ -0,0 +1,18 @@ +# Manual for `ComposeSimai` command +### Compile assigned simai chart to assigned format +#### _NOTE: This command converts complete Simai file (at least start with `&inote_X=`)._ +## Basic usage + MaichartConverter ComposeSimai --params +## Example usage + MaichartConverter ComposeSimai -p "/Users/Neskol/MaiAnalysis/Output_NoBGA/maimai/363_OSHAMASCRAMBLE/maidata.txt" -f Ma2_104 +### Required Params: +> Unless otherwise specified, `XXXXXX` here stands for musicID. +- `-p | --path `: Path to Simai file to be converted. + +### Optional Params: +> Program will print result in the terminal if `-o | --output` parameter is not provided. +- `-d | --difficulty `: Difficulty to be specified. 1-6 for `Easy` to `Re:Master`. Program will find for the first chart to compose if not specified. 7 for `Original` only if file contains. +- `-f | --format `: Forces program to compile carts in given format (within composed `maidata`.txt). Available format: `Simai, SimaiFes, Ma2, Ma2_104`. Note: Festival features requires `SimaiFes` or `Ma2_104` parameter. +- `-r | --rotate `: Forces program to rotate all charts in given method. Available rotations: `Clockwise90, Clockwise180, CounterClockwise90, CounterClockwise180, UpsideDown, LeftToRight`. +- `-s | --shift `: Shifts notes in all charts front or back by given ticks. +- `-o | --output `: Path to output folder. Program will try to write to this path and create new folder when necessary so make sure you have write permission of the given folder. \ No newline at end of file diff --git a/Commands/Manuals/ReverseMa2FromSimaiDatabase.md b/Commands/Manuals/ReverseMa2FromSimaiDatabase.md new file mode 100644 index 0000000..58db61d --- /dev/null +++ b/Commands/Manuals/ReverseMa2FromSimaiDatabase.md @@ -0,0 +1,13 @@ +# Manual for `ReverseMa2FromSimaiDatabase` command +### Reverse Simai Database from given folder to MaiAnalysis folder for compilation +## Basic usage + MaichartConverter ReverseMa2FromSimaiDatabase --params +## Example usage + MaichartConverter ReverseMa2FromSimaiDatabase -p "/Users/Neskol/MaiAnalysis/Output_NoBGA“ +## Available Params +### Optional Params: +> - If you run this program directly from the folder which contains required assets, you do not have to provide `path` param, but the file structure must be the same with specifications below. +> - If you want this program to create a `MaiAnalysis` folder in the current folder, you do not have to provide `output` param. +> - Unless otherwise specified, `XXXXXX` here stands for musicID. +- `-p | --path `: Path to input folder. Expects chart folder to be named as `XXX_TrackName...`. +- `-o | --output `: Path to output folder. diff --git a/MaiLib b/MaiLib index d1644a1..fdf5c44 160000 --- a/MaiLib +++ b/MaiLib @@ -1 +1 @@ -Subproject commit d1644a15a91b84430520ea3bfb7cca935c1808fe +Subproject commit fdf5c443e05c2eed9e64b306cb5984758bf24423 diff --git a/MaichartConverter.csproj b/MaichartConverter.csproj index 2b5396d..6c01f15 100644 --- a/MaichartConverter.csproj +++ b/MaichartConverter.csproj @@ -5,7 +5,7 @@ net8.0 enable enable - 1.0.6.1 + 1.0.6.2 AnyCPU;ARM64 True README.md diff --git a/Program.cs b/Program.cs index 3904a8c..0473b7e 100644 --- a/Program.cs +++ b/Program.cs @@ -11,33 +11,23 @@ namespace MaichartConverter /// class Program { - /// - /// Defines Windows path separator - /// - public static string WindowsPathSep = "\\"; - - /// - /// Defines MacOS path separator - /// - public static string MacPathSep = "/"; - - - public static string[] WinPaths = { @"C:\Users\Neskol\MaiAnalysis\A000\", + public static string[] WinPaths = + [ + @"C:\Users\Neskol\MaiAnalysis\A000\", @"C:\Users\Neskol\MaiAnalysis\Sound\", @"C:\Users\Neskol\MaiAnalysis\Image\Texture2D\", @"C:\Users\Neskol\MaiAnalysis\DXBGA_HEVC\", - @"C:\Users\Neskol\MaiAnalysis\Output\"}; + @"C:\Users\Neskol\MaiAnalysis\Output\" + ]; - public static string[] MacPaths = { @"/Users/neskol/MaiAnalysis/A000/", + public static string[] MacPaths = + [ + @"/Users/neskol/MaiAnalysis/A000/", @"/Users/neskol/MaiAnalysis/Sound/", @"/Users/neskol/MaiAnalysis/Image/Texture2D/", @"/Users/neskol/MaiAnalysis/DXBGA_HEVC/", - @"/Users/neskol/MaiAnalysis/Output/"}; - - /// - /// Defines which separator is using in programs - /// - public static string GlobalSep = MacPathSep; + @"/Users/neskol/MaiAnalysis/Output/" + ]; /// /// Defines which path is using in programs @@ -48,7 +38,7 @@ class Program /// Defines possible sorting scheme /// /// Sorting scheme - public static readonly string[] TrackCategorizeMethodSet = { "Genre", "Level", "Cabinet", "Composer", "BPM", "SD//DX Chart", "No Separate Folder" }; + public static readonly string[] TrackCategorizeMethodSet = ["Genre", "Level", "Cabinet", "Composer", "BPM", "SD/DX Chart", "No Separate Folder"]; /// /// Program will sort output according to this @@ -60,9 +50,9 @@ class Program /// public static int NumberTotalTrackCompiled; public static Dictionary CompiledTracks = new(); - public static List CompiledChart = new(); + public static List CompiledChart = []; - public static List ErrorMessage = new(); + public static List ErrorMessage = []; public static Dictionary CompiledTrackDetailSet = new Dictionary(); public static XmlDocument BPMCollection = new XmlDocument(); @@ -74,16 +64,16 @@ class Program /// Parameters to take in public static int Main(string[] args) { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - GlobalPaths = WinPaths; - GlobalSep = WindowsPathSep; - } - else - { - GlobalPaths = MacPaths; - GlobalSep = MacPathSep; - } + // if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + // { + // GlobalPaths = WinPaths; + // GlobalSep = WindowsPathSep; + // } + // else + // { + // GlobalPaths = MacPaths; + // GlobalSep = MacPathSep; + // } Console.WriteLine(ComposeHeader()); @@ -206,7 +196,7 @@ public static void Log(string outputLocation) index++; } sw.WriteLine(); - if (ErrorMessage.Count()>0) + if (ErrorMessage.Count>0) { sw.WriteLine("Warnings:"); foreach (string error in ErrorMessage) diff --git a/README.md b/README.md index 2e582a1..cebda41 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,13 @@ git clone git submodule update --init --recursive dotnet build -### Usage -> Type 'MaichartConverter help' for manual +### Usage & Available Commands +> Type 'MaichartConverter help' for detailed manual for each command. +- [`CompileDatabase`](./Commands/Manuals/CompileDatabase.md): Compose whole ma2 database to simai +- [`CompileMa2`](./Commands/Manuals/CompileMa2.md): Compile assigned Ma2 chart to assigned format +- [`CompileMa2ID`](./Commands/Manuals/CompileMa2ID.md): Compile assigned Ma2 chart indexed by ID to assigned format +- [`CompileSimai`](./Commands/Manuals/CompileSimai.md): Compile assigned simai chart to assigned format +- [`ReverseMa2FromSimaiDatabase`](./Commands/Manuals/ReverseMa2FromSimaiDatabase.md): Reverse Simai Database from given folder to MaiAnalysis folder for compilation ### Parameters notice - music files should be named musicxxxxxx.mp3 which xxxxxx matches the music id specified in music.xml in each a000 folder, and compensate 0s at the front to 6 digits