From e95b7c6aa633b7046bd856faf2e165568f19795f Mon Sep 17 00:00:00 2001 From: Fluto Date: Fri, 4 Feb 2022 17:21:30 +1100 Subject: [PATCH] Added TJA support + other things --- .idea/.idea.TaikoMods.dir/.idea/.name | 1 - .../.idea/projectSettingsUpdater.xml | 6 + .idea/.idea.TaikoMods.dir/.idea/workspace.xml | 63 + Folder.DotSettings.user | 5 + MusicPatch.cs | 1137 ---------- README.md | 122 +- TaikoMods.csproj | 38 - .gitignore => TakoTako/.gitignore | 0 .../.idea.TakoTako.dir}/.idea/.gitignore | 2 +- .../.idea.TakoTako.dir}/.idea/encodings.xml | 0 .../.idea.TakoTako.dir}/.idea/indexLayout.xml | 0 .../.idea/.idea.TakoTako.dir}/.idea/vcs.xml | 2 +- .../DisableScreenChangeOnFocus.cs | 2 +- TakoTako/Executables/tja2bin.exe | Bin 0 -> 95232 bytes TakoTako/FodyWeavers.xml | 8 + TakoTako/FodyWeavers.xsd | 141 ++ .../Folder.DotSettings | 1 + TakoTako/MusicPatch.cs | 1953 +++++++++++++++++ NuGet.Config => TakoTako/NuGet.Config | 0 Plugin.cs => TakoTako/Plugin.cs | 86 +- TakoTako/References/Newtonsoft.Json.dll | Bin 0 -> 254464 bytes SignInPatch.cs => TakoTako/SignInPatch.cs | 12 +- .../SkipSplashScreen.cs | 2 +- TakoTako/TakoTako.csproj | 72 + TakoTakoScripts/.gitignore | 35 + .../.idea.TakoTakoScripts/.idea/.gitignore | 13 + .../.idea.TakoTakoScripts/.idea/encodings.xml | 4 + .../.idea/indexLayout.xml | 8 + .../.idea/.idea.TakoTakoScripts/.idea/vcs.xml | 6 + TakoTakoScripts/TJAConvert/Files.cs | 133 ++ TakoTakoScripts/TJAConvert/FodyWeavers.xml | 3 + TakoTakoScripts/TJAConvert/FodyWeavers.xsd | 141 ++ TakoTakoScripts/TJAConvert/Program.cs | 1141 ++++++++++ .../TJAConvert/References/SonicAudioLib.dll | Bin 0 -> 70656 bytes TakoTakoScripts/TJAConvert/TJAConvert.csproj | 44 + TakoTakoScripts/TJAConvert/TJAMetaData.cs | 415 ++++ TakoTakoScripts/TakoTako.Common/CustomSong.cs | 204 ++ .../TakoTako.Common/TakoTako.Common.csproj | 16 + .../TakoTakoScripts.Common.csproj | 16 + TakoTakoScripts/TakoTakoScripts.sln | 22 + .../TakoTakoScripts.sln.DotSettings | 7 + TakoTakoScripts/global.json | 7 + readme-image-0.png | Bin 0 -> 33572 bytes readme-image-1.png | Bin 0 -> 121621 bytes readme-image-2.png | Bin 0 -> 7334 bytes 45 files changed, 4616 insertions(+), 1252 deletions(-) delete mode 100644 .idea/.idea.TaikoMods.dir/.idea/.name create mode 100644 .idea/.idea.TaikoMods.dir/.idea/projectSettingsUpdater.xml create mode 100644 .idea/.idea.TaikoMods.dir/.idea/workspace.xml create mode 100644 Folder.DotSettings.user delete mode 100644 MusicPatch.cs delete mode 100644 TaikoMods.csproj rename .gitignore => TakoTako/.gitignore (100%) rename {.idea/.idea.TaikoMods.dir => TakoTako/.idea/.idea.TakoTako.dir}/.idea/.gitignore (92%) rename {.idea/.idea.TaikoMods.dir => TakoTako/.idea/.idea.TakoTako.dir}/.idea/encodings.xml (100%) rename {.idea/.idea.TaikoMods.dir => TakoTako/.idea/.idea.TakoTako.dir}/.idea/indexLayout.xml (100%) rename {.idea/.idea.TaikoMods.dir => TakoTako/.idea/.idea.TakoTako.dir}/.idea/vcs.xml (69%) rename DisableScreenChangeOnFocus.cs => TakoTako/DisableScreenChangeOnFocus.cs (95%) create mode 100644 TakoTako/Executables/tja2bin.exe create mode 100644 TakoTako/FodyWeavers.xml create mode 100644 TakoTako/FodyWeavers.xsd rename Folder.DotSettings => TakoTako/Folder.DotSettings (86%) create mode 100644 TakoTako/MusicPatch.cs rename NuGet.Config => TakoTako/NuGet.Config (100%) rename Plugin.cs => TakoTako/Plugin.cs (62%) create mode 100644 TakoTako/References/Newtonsoft.Json.dll rename SignInPatch.cs => TakoTako/SignInPatch.cs (80%) rename SkipSplashScreen.cs => TakoTako/SkipSplashScreen.cs (96%) create mode 100644 TakoTako/TakoTako.csproj create mode 100644 TakoTakoScripts/.gitignore create mode 100644 TakoTakoScripts/.idea/.idea.TakoTakoScripts/.idea/.gitignore create mode 100644 TakoTakoScripts/.idea/.idea.TakoTakoScripts/.idea/encodings.xml create mode 100644 TakoTakoScripts/.idea/.idea.TakoTakoScripts/.idea/indexLayout.xml create mode 100644 TakoTakoScripts/.idea/.idea.TakoTakoScripts/.idea/vcs.xml create mode 100644 TakoTakoScripts/TJAConvert/Files.cs create mode 100644 TakoTakoScripts/TJAConvert/FodyWeavers.xml create mode 100644 TakoTakoScripts/TJAConvert/FodyWeavers.xsd create mode 100644 TakoTakoScripts/TJAConvert/Program.cs create mode 100644 TakoTakoScripts/TJAConvert/References/SonicAudioLib.dll create mode 100644 TakoTakoScripts/TJAConvert/TJAConvert.csproj create mode 100644 TakoTakoScripts/TJAConvert/TJAMetaData.cs create mode 100644 TakoTakoScripts/TakoTako.Common/CustomSong.cs create mode 100644 TakoTakoScripts/TakoTako.Common/TakoTako.Common.csproj create mode 100644 TakoTakoScripts/TakoTakoScripts.Common/TakoTakoScripts.Common.csproj create mode 100644 TakoTakoScripts/TakoTakoScripts.sln create mode 100644 TakoTakoScripts/TakoTakoScripts.sln.DotSettings create mode 100644 TakoTakoScripts/global.json create mode 100644 readme-image-0.png create mode 100644 readme-image-1.png create mode 100644 readme-image-2.png diff --git a/.idea/.idea.TaikoMods.dir/.idea/.name b/.idea/.idea.TaikoMods.dir/.idea/.name deleted file mode 100644 index 8dafd9f..0000000 --- a/.idea/.idea.TaikoMods.dir/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -TaikoMods \ No newline at end of file diff --git a/.idea/.idea.TaikoMods.dir/.idea/projectSettingsUpdater.xml b/.idea/.idea.TaikoMods.dir/.idea/projectSettingsUpdater.xml new file mode 100644 index 0000000..4bb9f4d --- /dev/null +++ b/.idea/.idea.TaikoMods.dir/.idea/projectSettingsUpdater.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/.idea.TaikoMods.dir/.idea/workspace.xml b/.idea/.idea.TaikoMods.dir/.idea/workspace.xml new file mode 100644 index 0000000..7d16c69 --- /dev/null +++ b/.idea/.idea.TaikoMods.dir/.idea/workspace.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1643955770420 + + + + + + + + + + \ No newline at end of file diff --git a/Folder.DotSettings.user b/Folder.DotSettings.user new file mode 100644 index 0000000..806e514 --- /dev/null +++ b/Folder.DotSettings.user @@ -0,0 +1,5 @@ + + True + <AssemblyExplorer> + <Assembly Path="C:\git\public-git\taiko-mods\Taiko-Mod\bin\Debug\net48\Assembly-CSharp-firstpass.dll" /> +</AssemblyExplorer> \ No newline at end of file diff --git a/MusicPatch.cs b/MusicPatch.cs deleted file mode 100644 index bbe2f1a..0000000 --- a/MusicPatch.cs +++ /dev/null @@ -1,1137 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Json; -using System.Text.RegularExpressions; -using BepInEx.Logging; -using HarmonyLib; -using Unity.Collections; -using Unity.Collections.LowLevel.Unsafe; -using UnityEngine; - -namespace TaikoMods; - -/// -/// This will allow custom songs to be read in -/// -[HarmonyPatch] -[SuppressMessage("ReSharper", "InconsistentNaming")] -public class MusicPatch -{ - public static int SaveDataMax => DataConst.MusicMax; - - public static string MusicTrackDirectory => Plugin.Instance.ConfigSongDirectory.Value; - public static string SaveFilePath => $"{Plugin.Instance.ConfigSaveDirectory.Value}/save.json"; - private const string SongDataFileName = "data.json"; - - public static ManualLogSource Log => Plugin.Log; - - public static void Setup(Harmony harmony) - { - CreateDirectoryIfNotExist(Path.GetDirectoryName(SaveFilePath)); - CreateDirectoryIfNotExist(MusicTrackDirectory); - - PatchManual(harmony); - - void CreateDirectoryIfNotExist(string path) - { - path = Path.GetFullPath(path); - if (!Directory.Exists(path)) - { - Log.LogInfo($"Creating path at {path}"); - Directory.CreateDirectory(path); - } - } - } - - private static void PatchManual(Harmony harmony) - { - var original = typeof(FumenLoader).GetNestedType("PlayerData", BindingFlags.NonPublic).GetMethod("Read"); - var prefix = typeof(MusicPatch).GetMethod(nameof(Read_Prefix), BindingFlags.Static | BindingFlags.NonPublic); - - harmony.Patch(original, new HarmonyMethod(prefix)); - } - - #region Custom Save Data - - private static CustomMusicSaveDataBody _customSaveData; - private static readonly DataContractJsonSerializer saveDataSerializer = new(typeof(CustomMusicSaveDataBody)); - - private static CustomMusicSaveDataBody GetCustomSaveData() - { - if (_customSaveData != null) - return _customSaveData; - - Log.LogInfo("Loading custom save data"); - var savePath = SaveFilePath; - try - { - CustomMusicSaveDataBody data; - if (!File.Exists(savePath)) - { - data = new CustomMusicSaveDataBody(); - using var fileStream = File.OpenWrite(savePath); - saveDataSerializer.WriteObject(fileStream, data); - } - else - { - using var fileStream = File.OpenRead(savePath); - data = (CustomMusicSaveDataBody) saveDataSerializer.ReadObject(fileStream); - - data.CustomTrackToEnsoRecordInfo ??= new Dictionary(); - data.CustomTrackToMusicInfoEx ??= new Dictionary(); - } - - _customSaveData = data; - return data; - } - catch (Exception e) - { - Log.LogError($"Could not load custom data, creating a fresh one\n {e}"); - } - - try - { - var data = new CustomMusicSaveDataBody(); - using var fileStream = File.OpenWrite(savePath); - saveDataSerializer.WriteObject(fileStream, data); - } - catch (Exception e) - { - Log.LogError($"Cannot save data at path {savePath}\n {e}"); - } - - return new CustomMusicSaveDataBody(); - } - - private static void SaveCustomData() - { - if (_customSaveData == null) - return; - - Log.LogInfo("Saving custom save data"); - try - { - var data = GetCustomSaveData(); - var savePath = SaveFilePath; - using var fileStream = File.OpenWrite(savePath); - saveDataSerializer.WriteObject(fileStream, data); - } - catch (Exception e) - { - Log.LogError($"Could not save custom data \n {e}"); - } - } - - #endregion - - #region Load Custom Songs - - private static readonly DataContractJsonSerializer customSongSerializer = new(typeof(CustomSong)); - private static List customSongsList; - private static readonly Dictionary idToSong = new Dictionary(); - private static readonly Dictionary uniqueIdToSong = new Dictionary(); - - public static List GetCustomSongs() - { - if (customSongsList != null) - return customSongsList; - - if (!Directory.Exists(MusicTrackDirectory)) - { - Log.LogError($"Cannot find {MusicTrackDirectory}"); - customSongsList = new List(); - return customSongsList; - } - - customSongsList = new List(); - - foreach (var musicDirectory in Directory.GetDirectories(MusicTrackDirectory)) - { - var files = Directory.GetFiles(musicDirectory); - var customSongPath = files.FirstOrDefault(x => Path.GetFileName(x) == SongDataFileName); - if (string.IsNullOrWhiteSpace(customSongPath)) - continue; - - using var fileStream = File.OpenRead(customSongPath); - var song = (CustomSong) customSongSerializer.ReadObject(fileStream); - if (song == null) - { - Log.LogError($"Cannot read {customSongPath}"); - continue; - } - - if (idToSong.ContainsKey(song.id)) - { - Log.LogError($"Cannot load song {song.songName.text} with ID {song.uniqueId} as it clashes with another, skipping it..."); - continue; - } - - if (uniqueIdToSong.ContainsKey(song.uniqueId)) - { - var uniqueIdTest = song.id.GetHashCode(); - while (uniqueIdToSong.ContainsKey(uniqueIdTest)) - uniqueIdTest++; - - Log.LogWarning($"Found song {song.songName.text} with an existing ID {song.uniqueId}, changing it to {uniqueIdTest}"); - song.uniqueId = uniqueIdTest; - } - - customSongsList.Add(song); - idToSong[song.id] = song; - uniqueIdToSong[song.uniqueId] = song; - Log.LogInfo($"Added Song {song.songName.text}:{song.id}:{song.uniqueId}"); - } - - if (customSongsList.Count == 0) - Log.LogInfo($"No tracks found"); - - return customSongsList; - } - - #endregion - - #region Loading and Initializing Data - - /// - /// This will handle loading the meta data of tracks - /// - [HarmonyPatch(typeof(MusicDataInterface))] - [HarmonyPatch(MethodType.Constructor)] - [HarmonyPatch(new[] {typeof(string)})] - [HarmonyPostfix] - private static void MusicDataInterface_Postfix(MusicDataInterface __instance, string path) - { - // This is where the metadata for tracks are read in our attempt to allow custom tracks will be to add additional metadata to the list that is created - Log.LogInfo("Injecting custom songs"); - - var customSongs = GetCustomSongs(); - - if (customSongs.Count == 0) - return; - // now that we have loaded this json, inject it into the existing `musicInfoAccessers` - var musicInfoAccessors = __instance.musicInfoAccessers; - - #region Logic from the original constructor - - for (int i = 0; i < customSongs.Count; i++) - { - musicInfoAccessors.Add(new MusicDataInterface.MusicInfoAccesser(customSongs[i].uniqueId, customSongs[i].id, $"song_{customSongs[i].id}", customSongs[i].order, customSongs[i].genreNo, - true, false, 0, false, 0, new bool[5] - { - customSongs[i].branchEasy, - customSongs[i].branchNormal, - customSongs[i].branchHard, - customSongs[i].branchMania, - customSongs[i].branchUra - }, new int[5] - { - customSongs[i].starEasy, - customSongs[i].starNormal, - customSongs[i].starHard, - customSongs[i].starMania, - customSongs[i].starUra - }, new int[5] - { - customSongs[i].shinutiEasy, - customSongs[i].shinutiNormal, - customSongs[i].shinutiHard, - customSongs[i].shinutiMania, - customSongs[i].shinutiUra - }, new int[5] - { - customSongs[i].shinutiEasyDuet, - customSongs[i].shinutiNormalDuet, - customSongs[i].shinutiHardDuet, - customSongs[i].shinutiManiaDuet, - customSongs[i].shinutiUraDuet - }, new int[5] - { - customSongs[i].scoreEasy, - customSongs[i].scoreNormal, - customSongs[i].scoreHard, - customSongs[i].scoreMania, - customSongs[i].scoreUra - })); - } - - #endregion - - // sort this - musicInfoAccessors.Sort((MusicDataInterface.MusicInfoAccesser a, MusicDataInterface.MusicInfoAccesser b) => a.Order - b.Order); - } - - - /// - /// This will handle loading the preview data of tracks - /// - [HarmonyPatch(typeof(SongDataInterface))] - [HarmonyPatch(MethodType.Constructor)] - [HarmonyPatch(new[] {typeof(string)})] - [HarmonyPostfix] - private static void SongDataInterface_Postfix(SongDataInterface __instance, string path) - { - // This is where the metadata for tracks are read in our attempt to allow custom tracks will be to add additional metadata to the list that is created - Log.LogInfo("Injecting custom song preview data"); - var customSongs = GetCustomSongs(); - - if (customSongs.Count == 0) - return; - - // now that we have loaded this json, inject it into the existing `songInfoAccessers` - var musicInfoAccessors = __instance.songInfoAccessers; - - foreach (var customTrack in customSongs) - { - musicInfoAccessors.Add(new SongDataInterface.SongInfoAccesser(customTrack.id, customTrack.previewPos, customTrack.fumenOffsetPos)); - } - } - - - /// - /// This will handle loading the localisation of tracks - /// - [HarmonyPatch(typeof(WordDataInterface))] - [HarmonyPatch(MethodType.Constructor)] - [HarmonyPatch(new[] {typeof(string), typeof(string)})] - [HarmonyPostfix] - private static void WordDataInterface_Postfix(WordDataInterface __instance, string path, string language) - { - // This is where the metadata for tracks are read in our attempt to allow custom tracks will be to add additional metadata to the list that is created - var customSongs = GetCustomSongs(); - - if (customSongs.Count == 0) - return; - - // now that we have loaded this json, inject it into the existing `songInfoAccessers` - var musicInfoAccessors = __instance.wordListInfoAccessers; - - foreach (var customTrack in customSongs) - { - musicInfoAccessors.Add(new WordDataInterface.WordListInfoAccesser($"song_{customTrack.id}", customTrack.songName.text, customTrack.songName.font)); - musicInfoAccessors.Add(new WordDataInterface.WordListInfoAccesser($"song_sub_{customTrack.id}", customTrack.songSubtitle.text, customTrack.songSubtitle.font)); - musicInfoAccessors.Add(new WordDataInterface.WordListInfoAccesser($"song_detail_{customTrack.id}", customTrack.songDetail.text, customTrack.songDetail.font)); - } - } - - #endregion - - #region Loading / Save Custom Save Data - - /// - /// When loading, make sure to ignore custom tracks, as their IDs will be different - /// - [HarmonyPatch(typeof(SongSelectManager), "LoadSongList")] - [HarmonyPrefix] - private static bool LoadSongList_Prefix(SongSelectManager __instance) - { - #region Edited Code - - Log.LogInfo("Loading custom save"); - var customData = GetCustomSaveData(); - - #endregion - - #region Setup instanced variables / methods - - var playDataMgr = (PlayDataManager) typeof(SongSelectManager).GetField("playDataMgr", BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(__instance); - var musicInfoAccess = (MusicDataInterface.MusicInfoAccesser[]) typeof(SongSelectManager).GetField("musicInfoAccess", BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(__instance); - var enableKakuninSong = (bool) (typeof(SongSelectManager).GetField("enableKakuninSong", BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(__instance) ?? false); - - var getLocalizedTextMethodInfo = typeof(SongSelectManager).GetMethod("GetLocalizedText", BindingFlags.NonPublic | BindingFlags.Instance); - var getLocalizedText = (string x) => (string) getLocalizedTextMethodInfo?.Invoke(__instance, new object[] {x, string.Empty}); - - var updateSortCategoryInfoMethodInfo = typeof(SongSelectManager).GetMethod("UpdateSortCategoryInfo", BindingFlags.NonPublic | BindingFlags.Instance); - var updateSortCategoryInfo = (DataConst.SongSortType x) => updateSortCategoryInfoMethodInfo?.Invoke(__instance, new object[] {x}); - - #endregion - - if (playDataMgr == null) - { - Log.LogError("Could not find playDataMgr"); - return true; - } - - __instance.UnsortedSongList.Clear(); - playDataMgr.GetMusicInfoExAll(0, out var dst); - playDataMgr.GetPlayerInfo(0, out var _); - _ = TaikoSingletonMonoBehaviour.Instance.newFriends.Count; - for (int i = 0; i < 8; i++) - { - for (int j = 0; j < musicInfoAccess.Length; j++) - { - bool flag = false; - playDataMgr.GetUnlockInfo(0, DataConst.ItemType.Music, musicInfoAccess[j].UniqueId, out var dst3); - if (!dst3.isUnlock && musicInfoAccess[j].Price != 0) - { - flag = true; - } - - if (!enableKakuninSong && musicInfoAccess[j].IsKakuninSong()) - { - flag = true; - } - - if (flag || musicInfoAccess[j].GenreNo != i) - { - continue; - } - - SongSelectManager.Song song2 = new SongSelectManager.Song(); - song2.PreviewIndex = j; - song2.Id = musicInfoAccess[j].Id; - song2.TitleKey = "song_" + musicInfoAccess[j].Id; - song2.SubKey = "song_sub_" + musicInfoAccess[j].Id; - song2.RubyKey = "song_detail_" + musicInfoAccess[j].Id; - song2.UniqueId = musicInfoAccess[j].UniqueId; - song2.SongGenre = musicInfoAccess[j].GenreNo; - song2.ListGenre = i; - song2.Order = musicInfoAccess[j].Order; - song2.TitleText = getLocalizedText("song_" + song2.Id); - song2.SubText = getLocalizedText("song_sub_" + song2.Id); - song2.DetailText = getLocalizedText("song_detail_" + song2.Id); - song2.Stars = musicInfoAccess[j].Stars; - song2.Branches = musicInfoAccess[j].Branches; - song2.HighScores = new SongSelectManager.Score[5]; - song2.HighScores2P = new SongSelectManager.Score[5]; - song2.DLC = musicInfoAccess[j].IsDLC; - song2.Price = musicInfoAccess[j].Price; - song2.IsCap = musicInfoAccess[j].IsCap; - if (TaikoSingletonMonoBehaviour.Instance.MyDataManager.SongData.GetInfo(song2.Id) != null) - { - song2.AudioStartMS = TaikoSingletonMonoBehaviour.Instance.MyDataManager.SongData.GetInfo(song2.Id).PreviewPos; - } - else - { - song2.AudioStartMS = 0; - } - - if (dst != null) - { - #region Edited Code - - MusicInfoEx data; - - if (musicInfoAccess[j].UniqueId >= SaveDataMax) - customData.CustomTrackToMusicInfoEx.TryGetValue(musicInfoAccess[j].UniqueId, out data); - else - data = dst[musicInfoAccess[j].UniqueId]; - song2.Favorite = data.favorite; - song2.NotPlayed = new bool[5]; - song2.NotCleared = new bool[5]; - song2.NotFullCombo = new bool[5]; - song2.NotDondaFullCombo = new bool[5]; - song2.NotPlayed2P = new bool[5]; - song2.NotCleared2P = new bool[5]; - song2.NotFullCombo2P = new bool[5]; - song2.NotDondaFullCombo2P = new bool[5]; - bool isNew = data.isNew; - - #endregion - - for (int k = 0; k < 5; k++) - { - playDataMgr.GetPlayerRecordInfo(0, musicInfoAccess[j].UniqueId, (EnsoData.EnsoLevelType) k, out var dst4); - song2.NotPlayed[k] = dst4.playCount <= 0; - song2.NotCleared[k] = dst4.crown < DataConst.CrownType.Silver; - song2.NotFullCombo[k] = dst4.crown < DataConst.CrownType.Gold; - song2.NotDondaFullCombo[k] = dst4.crown < DataConst.CrownType.Rainbow; - song2.HighScores[k].hiScoreRecordInfos = dst4.normalHiScore; - song2.HighScores[k].crown = dst4.crown; - playDataMgr.GetPlayerRecordInfo(1, musicInfoAccess[j].UniqueId, (EnsoData.EnsoLevelType) k, out var dst5); - song2.NotPlayed2P[k] = dst5.playCount <= 0; - song2.NotCleared2P[k] = dst4.crown < DataConst.CrownType.Silver; - song2.NotFullCombo2P[k] = dst5.crown < DataConst.CrownType.Gold; - song2.NotDondaFullCombo2P[k] = dst5.crown < DataConst.CrownType.Rainbow; - song2.HighScores2P[k].hiScoreRecordInfos = dst5.normalHiScore; - song2.HighScores2P[k].crown = dst5.crown; - } - - song2.NewSong = isNew && (song2.DLC || song2.Price > 0); - } - - __instance.UnsortedSongList.Add(song2); - } - } - - var unsortedSongList = (from song in __instance.UnsortedSongList - orderby song.SongGenre, song.Order - select song).ToList(); - typeof(SongSelectManager).GetProperty(nameof(SongSelectManager.UnsortedSongList), BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance)?.SetValue(__instance, unsortedSongList); - - var songList = new List(__instance.UnsortedSongList); - typeof(SongSelectManager).GetProperty(nameof(SongSelectManager.SongList), BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance)?.SetValue(__instance, songList); - - updateSortCategoryInfo(DataConst.SongSortType.Genre); - return false; - } - - /// - /// When saving favourite tracks, save the custom ones too - /// - [HarmonyPatch(typeof(SongSelectManager), "SaveFavotiteSongs")] - [HarmonyPrefix] - private static bool SaveFavotiteSongs_Prefix(SongSelectManager __instance) - { - var playDataMgr = (PlayDataManager) typeof(SongSelectManager).GetField("playDataMgr", BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(__instance); - - playDataMgr.GetMusicInfoExAll(0, out var dst); - var customSaveData = GetCustomSaveData(); - - bool saveCustomData = false; - int num = 0; - foreach (SongSelectManager.Song unsortedSong in __instance.UnsortedSongList) - { - num++; - if (unsortedSong.UniqueId < SaveDataMax) - { - dst[unsortedSong.UniqueId].favorite = unsortedSong.Favorite; - playDataMgr.SetMusicInfoEx(0, unsortedSong.UniqueId, ref dst[unsortedSong.UniqueId], num >= __instance.UnsortedSongList.Count); - } - else - { - customSaveData.CustomTrackToMusicInfoEx.TryGetValue(unsortedSong.UniqueId, out var data); - saveCustomData |= data.favorite != unsortedSong.Favorite; - data.favorite = unsortedSong.Favorite; - customSaveData.CustomTrackToMusicInfoEx[unsortedSong.UniqueId] = data; - } - } - - if (saveCustomData) - SaveCustomData(); - - return false; - } - - /// - /// When loading the song, mark the custom song as not new - /// - [HarmonyPatch(typeof(CourseSelect), "EnsoConfigSubmit")] - [HarmonyPrefix] - private static bool EnsoConfigSubmit_Prefix(CourseSelect __instance) - { - var songInfoType = typeof(CourseSelect).GetNestedType("SongInfo", BindingFlags.NonPublic); - var scoreType = typeof(CourseSelect).GetNestedType("Score", BindingFlags.NonPublic); - var playerTypeEnumType = typeof(CourseSelect).GetNestedType("PlayerType", BindingFlags.NonPublic); - - var settings = (EnsoData.Settings) typeof(CourseSelect).GetField("settings", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); - var playDataManager = (PlayDataManager) typeof(CourseSelect).GetField("playDataManager", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); - var ensoDataManager = (EnsoDataManager) typeof(CourseSelect).GetField("ensoDataManager", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); - - var selectedSongInfo = typeof(CourseSelect).GetField("selectedSongInfo", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); - var ensoMode = (EnsoMode) typeof(CourseSelect).GetField("ensoMode", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); - var ensoMode2P = (EnsoMode) typeof(CourseSelect).GetField("ensoMode2P", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); - var selectedCourse = (int) typeof(CourseSelect).GetField("selectedCourse", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); - var selectedCourse2P = (int) typeof(CourseSelect).GetField("selectedCourse2P", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); - var status = (SongSelectStatus) typeof(CourseSelect).GetField("status", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); - - var SetSaveDataEnsoModeMethodInfo = typeof(CourseSelect).GetMethod("SetSaveDataEnsoMode", BindingFlags.NonPublic | BindingFlags.Instance); - var SetSaveDataEnsoMode = (object x) => (string) SetSaveDataEnsoModeMethodInfo?.Invoke(__instance, new object[] {x}); - - var songUniqueId = (int) songInfoType.GetField("UniqueId").GetValue(selectedSongInfo); - - void SetSettings() => typeof(CourseSelect).GetField("settings", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(__instance, settings); - - settings.ensoType = EnsoData.EnsoType.Normal; - settings.rankMatchType = EnsoData.RankMatchType.None; - settings.musicuid = (string) songInfoType.GetField("Id").GetValue(selectedSongInfo); - settings.musicUniqueId = songUniqueId; - settings.genre = (EnsoData.SongGenre) songInfoType.GetField("SongGenre").GetValue(selectedSongInfo); - settings.playerNum = 1; - settings.ensoPlayerSettings[0].neiroId = ensoMode.neiro; - settings.ensoPlayerSettings[0].courseType = (EnsoData.EnsoLevelType) selectedCourse; - settings.ensoPlayerSettings[0].speed = ensoMode.speed; - settings.ensoPlayerSettings[0].dron = ensoMode.dron; - settings.ensoPlayerSettings[0].reverse = ensoMode.reverse; - settings.ensoPlayerSettings[0].randomlv = ensoMode.randomlv; - settings.ensoPlayerSettings[0].special = ensoMode.special; - - var array = (Array) songInfoType.GetField("HighScores").GetValue(selectedSongInfo); - settings.ensoPlayerSettings[0].hiScore = ((HiScoreRecordInfo) scoreType.GetField("hiScoreRecordInfos").GetValue(array.GetValue(selectedCourse))).score; - - SetSettings(); - if (status.Is2PActive) - { - settings.ensoPlayerSettings[1].neiroId = ensoMode2P.neiro; - settings.ensoPlayerSettings[1].courseType = (EnsoData.EnsoLevelType) selectedCourse2P; - settings.ensoPlayerSettings[1].speed = ensoMode2P.speed; - settings.ensoPlayerSettings[1].dron = ensoMode2P.dron; - settings.ensoPlayerSettings[1].reverse = ensoMode2P.reverse; - settings.ensoPlayerSettings[1].randomlv = ensoMode2P.randomlv; - settings.ensoPlayerSettings[1].special = ensoMode2P.special; - TaikoSingletonMonoBehaviour.Instance.MyDataManager.PlayData.GetPlayerRecordInfo(1, songUniqueId, (EnsoData.EnsoLevelType) selectedCourse2P, out var dst); - settings.ensoPlayerSettings[1].hiScore = dst.normalHiScore.score; - settings.playerNum = 2; - } - - settings.debugSettings.isTestMenu = false; - settings.rankMatchType = EnsoData.RankMatchType.None; - settings.isRandomSelect = (bool) songInfoType.GetField("IsRandomSelect").GetValue(selectedSongInfo); - settings.isDailyBonus = (bool) songInfoType.GetField("IsDailyBonus").GetValue(selectedSongInfo); - ensoMode.songUniqueId = settings.musicUniqueId; - ensoMode.level = (EnsoData.EnsoLevelType) selectedCourse; - - SetSettings(); - typeof(CourseSelect).GetField("ensoMode", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(__instance, ensoMode); - SetSaveDataEnsoMode(Enum.Parse(playerTypeEnumType, "Player1")); - ensoMode2P.songUniqueId = settings.musicUniqueId; - ensoMode2P.level = (EnsoData.EnsoLevelType) selectedCourse2P; - typeof(CourseSelect).GetField("ensoMode2P", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(__instance, ensoMode2P); - SetSaveDataEnsoMode(Enum.Parse(playerTypeEnumType, "Player2")); - playDataManager.GetSystemOption(out var dst2); - int deviceTypeIndex = EnsoDataManager.GetDeviceTypeIndex(settings.ensoPlayerSettings[0].inputDevice); - settings.noteDispOffset = dst2.onpuDispLevels[deviceTypeIndex]; - settings.noteDelay = dst2.onpuHitLevels[deviceTypeIndex]; - settings.songVolume = TaikoSingletonMonoBehaviour.Instance.MySoundManager.GetVolume(SoundManager.SoundType.InGameSong); - settings.seVolume = TaikoSingletonMonoBehaviour.Instance.MySoundManager.GetVolume(SoundManager.SoundType.Se); - settings.voiceVolume = TaikoSingletonMonoBehaviour.Instance.MySoundManager.GetVolume(SoundManager.SoundType.Voice); - settings.bgmVolume = TaikoSingletonMonoBehaviour.Instance.MySoundManager.GetVolume(SoundManager.SoundType.Bgm); - settings.neiroVolume = TaikoSingletonMonoBehaviour.Instance.MySoundManager.GetVolume(SoundManager.SoundType.InGameNeiro); - settings.effectLevel = (EnsoData.EffectLevel) dst2.qualityLevel; - SetSettings(); - ensoDataManager.SetSettings(ref settings); - ensoDataManager.DecideSetting(); - if (status.Is2PActive) - { - dst2.controlType[1] = dst2.controlType[0]; - playDataManager.SetSystemOption(ref dst2); - } - - var customSaveData = GetCustomSaveData(); - - if (songUniqueId < SaveDataMax) - { - playDataManager.GetMusicInfoExAll(0, out var dst3); - dst3[songUniqueId].isNew = false; - playDataManager.SetMusicInfoEx(0, songUniqueId, ref dst3[songUniqueId]); - } - else - { - customSaveData.CustomTrackToMusicInfoEx.TryGetValue(songUniqueId, out var data); - data.isNew = false; - customSaveData.CustomTrackToMusicInfoEx[songUniqueId] = data; - SaveCustomData(); - } - - UnityEngine.Debug.Log($"p1 is {ensoMode}"); - return false; - } - - /// - /// When loading the song obtain isfavourite correctly - /// - [HarmonyPatch(typeof(KpiListCommon.MusicKpiInfo), "GetEnsoSettings")] - [HarmonyPrefix] - private static bool GetEnsoSettings_Prefix(KpiListCommon.MusicKpiInfo __instance) - { - TaikoSingletonMonoBehaviour.Instance.MyDataManager.EnsoData.CopySettings(out var dst); - __instance.music_id = dst.musicuid; - __instance.genre = (int) dst.genre; - __instance.course_type = (int) dst.ensoPlayerSettings[0].courseType; - __instance.neiro_id = dst.ensoPlayerSettings[0].neiroId; - __instance.speed = (int) dst.ensoPlayerSettings[0].speed; - __instance.dron = (int) dst.ensoPlayerSettings[0].dron; - __instance.reverse = (int) dst.ensoPlayerSettings[0].reverse; - __instance.randomlv = (int) dst.ensoPlayerSettings[0].randomlv; - __instance.special = (int) dst.ensoPlayerSettings[0].special; - PlayDataManager playData = TaikoSingletonMonoBehaviour.Instance.MyDataManager.PlayData; - playData.GetEnsoMode(out var dst2); - __instance.sort_course = (int) dst2.songSortCourse; - __instance.sort_type = (int) dst2.songSortType; - __instance.sort_filter = (int) dst2.songFilterType; - __instance.sort_favorite = (int) dst2.songFilterTypeFavorite; - MusicDataInterface.MusicInfoAccesser[] array = TaikoSingletonMonoBehaviour.Instance.MyDataManager.MusicData.musicInfoAccessers.ToArray(); - playData.GetMusicInfoExAll(0, out var dst3); - - #region edited code - - for (int i = 0; i < array.Length; i++) - { - var id = array[i].UniqueId; - if (id == dst.musicUniqueId && dst3 != null) - { - if (id < SaveDataMax) - { - __instance.is_favorite = dst3[id].favorite; - } - else - { - GetCustomSaveData().CustomTrackToMusicInfoEx.TryGetValue(id, out var data); - __instance.is_favorite = data.favorite; - } - } - } - - #endregion - - playData.GetPlayerInfo(0, out var dst4); - __instance.current_coins_num = dst4.donCoin; - __instance.total_coins_num = dst4.getCoinsInTotal; - playData.GetRankMatchSeasonRecordInfo(0, 0, out var dst5); - __instance.rank_point = dst5.rankPointMax; - - return false; - } - - /// - /// Load scores from custom save data - /// - [HarmonyPatch(typeof(PlayDataManager), "GetPlayerRecordInfo")] - [HarmonyPrefix] - public static bool GetPlayerRecordInfo_Prefix(int playerId, int uniqueId, EnsoData.EnsoLevelType levelType, out EnsoRecordInfo dst, PlayDataManager __instance) - { - if (uniqueId < SaveDataMax) - { - dst = new EnsoRecordInfo(); - return true; - } - - int num = (int) levelType; - if (num is < 0 or >= 5) - num = 0; - - // load our custom save, this will combine the scores of player1 and player2 - var saveData = GetCustomSaveData().CustomTrackToEnsoRecordInfo; - if (!saveData.TryGetValue(uniqueId, out var ensoData)) - { - ensoData = new EnsoRecordInfo[(int) EnsoData.EnsoLevelType.Num]; - saveData[uniqueId] = ensoData; - } - - dst = ensoData[num]; - return false; - } - - /// - /// Save scores to custom save data - /// - [HarmonyPatch(typeof(PlayDataManager), "UpdatePlayerScoreRecordInfo", - new Type[] {typeof(int), typeof(int), typeof(int), typeof(EnsoData.EnsoLevelType), typeof(bool), typeof(DataConst.SpecialTypes), typeof(HiScoreRecordInfo), typeof(DataConst.ResultType), typeof(bool), typeof(DataConst.CrownType)})] - [HarmonyPrefix] - public static bool UpdatePlayerScoreRecordInfo(PlayDataManager __instance, int playerId, int charaIndex, int uniqueId, EnsoData.EnsoLevelType levelType, bool isSinuchi, DataConst.SpecialTypes spTypes, HiScoreRecordInfo record, - DataConst.ResultType resultType, bool savemode, DataConst.CrownType crownType) - { - if (uniqueId < SaveDataMax) - return true; - - int num = (int) levelType; - if (num is < 0 or >= 5) - num = 0; - - var saveData = GetCustomSaveData().CustomTrackToEnsoRecordInfo; - if (!saveData.TryGetValue(uniqueId, out var ensoData)) - { - ensoData = new EnsoRecordInfo[(int) EnsoData.EnsoLevelType.Num]; - saveData[uniqueId] = ensoData; - } - - EnsoRecordInfo ensoRecordInfo = ensoData[(int) levelType]; -#pragma warning disable Harmony003 - if (ensoRecordInfo.normalHiScore.score <= record.score) - { - ensoRecordInfo.normalHiScore.score = record.score; - ensoRecordInfo.normalHiScore.combo = record.combo; - ensoRecordInfo.normalHiScore.excellent = record.excellent; - ensoRecordInfo.normalHiScore.good = record.good; - ensoRecordInfo.normalHiScore.bad = record.bad; - ensoRecordInfo.normalHiScore.renda = record.renda; - } -#pragma warning restore Harmony003 - - if (crownType != DataConst.CrownType.Off) - { - if (IsValueInRange((int) crownType, 0, 5) && ensoRecordInfo.crown <= crownType) - { - ensoRecordInfo.crown = crownType; - ensoRecordInfo.cleared = crownType >= DataConst.CrownType.Silver; - } - } - - ensoData[(int) levelType] = ensoRecordInfo; - - if (savemode && playerId == 0) - SaveCustomData(); - - return false; - - bool IsValueInRange(int myValue, int minValue, int maxValue) - { - if (myValue >= minValue && myValue < maxValue) - return true; - return false; - } - } - - /// - /// Allow for a song id > 400 - /// - [HarmonyPatch(typeof(EnsoMode), "IsValid")] - [HarmonyPrefix] - public static bool IsValid_Prefix(ref bool __result, EnsoMode __instance) - { -#pragma warning disable Harmony003 - __result = Validate(); - return false; - bool Validate() - { - // commented out this code - // if (songUniqueId < DataConst.InvalidId || songUniqueId > DataConst.MusicMax) - // { - // return false; - // } - if (!Enum.IsDefined(typeof(EnsoData.SongGenre), __instance.listGenre)) - { - return false; - } - if (__instance.neiro < 0 || __instance.neiro > DataConst.NeiroMax) - { - return false; - } - if (!Enum.IsDefined(typeof(EnsoData.EnsoLevelType), __instance.level)) - { - return false; - } - if (!Enum.IsDefined(typeof(DataConst.SpeedTypes), __instance.speed)) - { - return false; - } - if (!Enum.IsDefined(typeof(DataConst.OptionOnOff), __instance.dron)) - { - return false; - } - if (!Enum.IsDefined(typeof(DataConst.OptionOnOff), __instance.reverse)) - { - return false; - } - if (!Enum.IsDefined(typeof(DataConst.RandomLevel), __instance.randomlv)) - { - return false; - } - if (!Enum.IsDefined(typeof(DataConst.SpecialTypes), __instance.special)) - { - return false; - } - if (!Enum.IsDefined(typeof(DataConst.SongSortType), __instance.songSortType)) - { - return false; - } - if (!Enum.IsDefined(typeof(DataConst.SongSortCourse), __instance.songSortCourse)) - { - return false; - } - if (!Enum.IsDefined(typeof(DataConst.SongFilterType), __instance.songFilterType)) - { - return false; - } - if (!Enum.IsDefined(typeof(DataConst.SongFilterTypeFavorite), __instance.songFilterTypeFavorite)) - { - return false; - } - return true; - } -#pragma warning restore Harmony003 - } - - #endregion - - #region Read Fumen - - private static readonly Regex fumenFilePathRegex = new Regex("(?.*?)_(?[ehmnx])(?_[12])?.bin"); - - private static readonly Dictionary playerToFumenData = new Dictionary(); - - /// - /// Read unencrypted Fumen files, save them to - /// todo dispose old fumens? - /// - /// - private static unsafe bool Read_Prefix(string filePath, ref bool __result, object __instance) - { - var type = typeof(FumenLoader).GetNestedType("PlayerData", BindingFlags.NonPublic); - - if (File.Exists(filePath)) - return true; - - // if the file doesn't exist, perhaps it's a custom song? - var fileName = Path.GetFileName(filePath); - var match = fumenFilePathRegex.Match(fileName); - if (!match.Success) - { - Log.LogError($"Cannot interpret {fileName}"); - return true; - } - - // get song id - var songId = match.Groups["songID"]; - var difficulty = match.Groups["difficulty"]; - var songIndex = match.Groups["songIndex"]; - - var newPath = Path.Combine(MusicTrackDirectory, $"{songId}\\{fileName}"); - Log.LogInfo($"Redirecting file from {filePath} to {newPath}"); - - type.GetMethod("Dispose").Invoke(__instance, new object[] { }); - type.GetField("fumenPath").SetValue(__instance, newPath); - - byte[] array = File.ReadAllBytes(newPath); - var fumenSize = array.Length; - type.GetField("fumenSize").SetValue(__instance, fumenSize); - - var fumenData = UnsafeUtility.Malloc(fumenSize, 16, Allocator.Persistent); - type.GetField("fumenData").SetValue(__instance, (IntPtr) fumenData); - - Marshal.Copy(array, 0, (IntPtr) fumenData, fumenSize); - - type.GetField("isReadEnd").SetValue(__instance, true); - type.GetField("isReadSucceed").SetValue(__instance, true); - __result = true; - - playerToFumenData[__instance] = (IntPtr) fumenData; - return false; - } - - /// - /// When asking to get a Fumen, used the ones we stored above - /// - [HarmonyPatch(typeof(FumenLoader), "GetFumenData")] - [HarmonyPrefix] - public static unsafe bool GetFumenData_Prefix(int player, ref void* __result, FumenLoader __instance) - { - var settings = (EnsoData.Settings) typeof(FumenLoader).GetField("settings", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); - var playerData = (Array) typeof(FumenLoader).GetField("playerData", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); - - if (player >= 0 && player < settings.playerNum) - { - if (playerToFumenData.TryGetValue(playerData.GetValue(player), out var data)) - { - __result = (void*) data; - return false; - } - } - - // try loading the actual data - return true; - } - - #endregion - - #region Read Song - - private static readonly Regex musicFilePathRegex = new Regex("^song_(?.*?)$"); - - /// - /// Read an unencrypted song "asynchronously" (it does it instantly, we should have fast enough PCs right?) - /// - /// - [HarmonyPatch(typeof(CriPlayer), "LoadAsync")] - [HarmonyPostfix] - public static void LoadAsync_Postfix(CriPlayer __instance) - { - // Run this on the next frame - Plugin.Instance.StartCustomCoroutine(LoadAsync()); - - IEnumerator LoadAsync() - { - yield return null; - var sheetName = __instance.CueSheetName; - var path = Application.streamingAssetsPath + "/sound/" + sheetName + ".bin"; - - if (File.Exists(path)) - yield break; - - typeof(CriPlayer).GetField("isLoadingAsync", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(__instance, true); - typeof(CriPlayer).GetField("isCancelLoadingAsync", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(__instance, false); - typeof(CriPlayer).GetProperty("IsPrepared").SetValue(__instance, false); - typeof(CriPlayer).GetProperty("IsLoadSucceed").SetValue(__instance, false); - typeof(CriPlayer).GetProperty("LoadingState").SetValue(__instance, CriPlayer.LoadingStates.Loading); - typeof(CriPlayer).GetProperty("LoadTime").SetValue(__instance, -1f); - typeof(CriPlayer).GetField("loadStartTime", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(__instance, Time.time); - - var match = musicFilePathRegex.Match(sheetName); - if (!match.Success) - { - Log.LogError($"Cannot interpret {sheetName}"); - yield break; - } - - var songName = match.Groups["songName"]; - var newPath = Path.Combine(MusicTrackDirectory, $"{songName}\\{sheetName}.bin"); - Log.LogInfo($"Redirecting file from {path} to {newPath}"); - - var cueSheet = CriAtom.AddCueSheetAsync(sheetName, File.ReadAllBytes(newPath), null); - typeof(CriPlayer).GetProperty("CueSheet").SetValue(__instance, cueSheet); - - if (cueSheet != null) - { - typeof(CriPlayer).GetField("isLoadingAsync", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(__instance, false); - typeof(CriPlayer).GetProperty("IsLoadSucceed").SetValue(__instance, true); - - typeof(CriPlayer).GetProperty("LoadingState").SetValue(__instance, CriPlayer.LoadingStates.Finished); - typeof(CriPlayer).GetProperty("LoadTime").SetValue(__instance, 0); - yield break; - } - - Log.LogError($"Could not load music"); - typeof(CriPlayer).GetProperty("LoadingState").SetValue(__instance, CriPlayer.LoadingStates.Finished); - typeof(CriPlayer).GetField("isLoadingAsync", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(__instance, false); - } - } - - /// - /// Read an unencrypted song - /// - [HarmonyPatch(typeof(CriPlayer), "Load")] - [HarmonyPrefix] - private static bool Load_Prefix(ref bool __result, CriPlayer __instance) - { - var sheetName = __instance.CueSheetName; - var path = Application.streamingAssetsPath + "/sound/" + sheetName + ".bin"; - - if (File.Exists(path)) - return true; - - var match = musicFilePathRegex.Match(sheetName); - if (!match.Success) - { - Log.LogError($"Cannot interpret {sheetName}"); - return true; - } - - var songName = match.Groups["songName"]; - - var newPath = Path.Combine(MusicTrackDirectory, $"{songName}\\{sheetName}.bin"); - Log.LogInfo($"Redirecting file from {path} to {newPath}"); - - // load custom song - typeof(CriPlayer).GetProperty("IsPrepared").SetValue(__instance, false); - typeof(CriPlayer).GetProperty("LoadingState").SetValue(__instance, CriPlayer.LoadingStates.Loading); - typeof(CriPlayer).GetProperty("IsLoadSucceed").SetValue(__instance, false); - typeof(CriPlayer).GetProperty("LoadTime").SetValue(__instance, -1f); - typeof(CriPlayer).GetField("loadStartTime", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(__instance, Time.time); - - if (sheetName == "") - { - typeof(CriPlayer).GetProperty("LoadingState").SetValue(__instance, CriPlayer.LoadingStates.Finished); - __result = false; - return false; - } - - // - var cueSheet = CriAtom.AddCueSheetAsync(sheetName, File.ReadAllBytes(newPath), null); - typeof(CriPlayer).GetProperty("CueSheet").SetValue(__instance, cueSheet); - - if (cueSheet != null) - { - __result = true; - return false; - } - - typeof(CriPlayer).GetProperty("LoadingState").SetValue(__instance, CriPlayer.LoadingStates.Finished); - __result = false; - return false; - } - - #endregion - - #region Data Structures - - [Serializable] - [DataContract(Name = "CustomSaveData")] - public class CustomMusicSaveDataBody - { - [DataMember] public Dictionary CustomTrackToMusicInfoEx = new(); - - [DataMember] public Dictionary CustomTrackToEnsoRecordInfo = new(); - } - - // ReSharper disable once ClassNeverInstantiated.Global - [DataContract(Name = "CustomSong")] - [Serializable] - public class CustomSong - { - // Song Details - [DataMember] public int uniqueId; - [DataMember] public string id; - [DataMember] public int order; - [DataMember] public int genreNo; - [DataMember] public bool branchEasy; - [DataMember] public bool branchNormal; - [DataMember] public bool branchHard; - [DataMember] public bool branchMania; - [DataMember] public bool branchUra; - [DataMember] public int starEasy; - [DataMember] public int starNormal; - [DataMember] public int starHard; - [DataMember] public int starMania; - [DataMember] public int starUra; - [DataMember] public int shinutiEasy; - [DataMember] public int shinutiNormal; - [DataMember] public int shinutiHard; - [DataMember] public int shinutiMania; - [DataMember] public int shinutiUra; - [DataMember] public int shinutiEasyDuet; - [DataMember] public int shinutiNormalDuet; - [DataMember] public int shinutiHardDuet; - [DataMember] public int shinutiManiaDuet; - [DataMember] public int shinutiUraDuet; - [DataMember] public int scoreEasy; - [DataMember] public int scoreNormal; - [DataMember] public int scoreHard; - [DataMember] public int scoreMania; - [DataMember] public int scoreUra; - - // Preview Details - [DataMember] public int previewPos; - [DataMember] public int fumenOffsetPos; - - // LocalisationDetails - /// - /// Song Title - /// - /// A Cruel Angel's Thesis - /// - /// - [DataMember] public TextEntry songName; - - /// - /// Origin of the song - /// - /// From \" Neon Genesis EVANGELION \" - /// - /// - [DataMember] public TextEntry songSubtitle; - - /// - /// Extra details for the track, sometimes used to say it's Japanese name - /// - /// 残酷な天使のテーゼ - /// - /// - [DataMember] public TextEntry songDetail; - } - - [Serializable] - public class TextEntry - { - /// - /// The text to display - /// - public string text; - - /// - /// 0 == Japanese - /// 1 == English - /// 2 == Traditional Chinese - /// 3 == Simplified Chinese - /// 4 == Korean - /// - public int font; - } - - #endregion -} \ No newline at end of file diff --git a/README.md b/README.md index 1422b3f..47407b5 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,52 @@ -# Taiko no Tatsujin: The Drum Master - Mods +# TakoTako -Hey this modifies version 1.1.0.0 of Taiko no Tatsujin: The Drum Master +Hey this is a mod for Taiko no Tatsujin: The Drum Master Currently has the features: -- Fixes sign in screen +- Fixes sign in screen for version 1.1.0.0 - Skips splash screen -- Disable fullscreen on application focus -- Allows custom tracks to be loaded into the game +- Disable fullscreen on application focus (worked when in windowed mode) +- Allows custom official tracks or TJAs to be loaded into the game +- Override songs names to a certain language than the default one ---- ## Installation -1. Download ![BepInEx](https://github.com/BepInEx/BepInEx/releases) `BepInEx_x64_XXXXX.zip`, as of writing the latest version is 5.4.18. This is a mod to patch Unity Games -2. Find your game's installation directiory, yours might be under `C:\Program Files\ModifiableWindowsApps\Taiko no Tatsujin\` -3. Paste all of the files from the .zip from step 1 into this folder -(It will look something like this, my directory is different because I installed it to a different folder)\ -![](https://github.com/Fluto/Taiko-no-Tatsujin-The-Drum-Master-Patch/blob/main/3.png) -4. Run Taiko no Tatusjin The Drum Master once, then close it -5. ![Download my patch](https://github.com/Fluto/TaikoMods/releases) -6. Look in your game's folder again, new files will have been generated under `.\BepInEx\plugins` -7. Paste the .DLL from step 4 into this folder\ -![](https://github.com/Fluto/Taiko-no-Tatsujin-The-Drum-Master-Patch/blob/main/4.png) -8. And you're done! +To install mods is a bit tricky this time around as we have to take a few more steps to be able to inject files into the game. !(Swigs did a quick video on it here)[https://youtu.be/WDsWDVbtbbI] but if you want to follow along in text read on ahead. + +1. Become an Xbox Insider, to do this open the `Xbox Insider Hub` which you can get from the Microsoft Store if you don't already have it installed. Go to Previews > Windows Gaming, and join it. There should be an update ready for you for the Xbox app, so go ahead and update and relaunch it +2. In the Xbox App go to Settings > General and enable `Use advanced installation and management features`. Feel free to change your installation directory +3. If the game is already installed uninstall it, and reinstall it +4. Download ![BepInEx](https://github.com/BepInEx/BepInEx/releases) `BepInEx_x64_XXXXX.zip`, as of writing the latest version is 5.4.18. This is a mod to patch Unity Games +5. Go to where you installed your game, for example `C:\XboxGames\T Tablet\Content` +6. Paste all of the files from the .zip from step 5 into this folder +(It will look something like this)\ +![](https://github.com/Fluto/TakoTako/blob/main/readme-image-0.png) +7. We now need to give special permissions to the `BepInEx` folder. To do this, right click it, click on `Properties`, go to the `Security` tab, Click on the `Advanced` button, Click Change at the top, Under `Enter the object name to select` field type in your username and click `Check Names`. If the text doesn't become underscored that means you have entered the incorrect username. Then press `Ok` on that window to dismiss it. Going back to the `Advanced Security Settings Window` tick `Replace owner on subcontainers and objects` then finally press Apply. +![](https://github.com/Fluto/TakoTako/blob/main/readme-image-1.png) +8. Run Taiko no Tatusjin The Drum Master once, then close it. This will generate some files +9. Look in your game's folder again, new files will have been generated under `.\BepInEx\plugins` +10. ![Download my patch](https://github.com/Fluto/TaikoMods/releases) +11. Paste the .DLL from step 4 into this folder\ +![](https://github.com/Fluto/TakoTako/blob/main/readme-image-2.png) +12. And you're done! ## Configuration -After installing the mod, and running the game it will generate files in `.\BepInEx\config`. Open `com.fluto.taikomods.cfg` to configure this mod +After installing the mod, and running the game it will generate files in `.\BepInEx\config`. Open `com.fluto.takotako.cfg` to configure this mod Here you can enable each individual feature or redirect where custom songs will be loaded from ## Custom Songs With this feature you can inject custom songs into the game! -To begin place custom songs in `SongDirectory` specified in your configuration file, by default this is `%userprofile%/Documents/TaikoTheDrumMasterMods/customSongs` -Each song must have it's own directory with a unique name. The folder must have this structure +To begin place custom songs in `SongDirectory` specified in your configuration file, by default this is `%userprofile%/Documents/TakoTako/customSongs` +Each song must have it's own directory with a unique name. +These songs can be nested within folders. + +The folder must have this structure: ``` -CustomSongs +Offical Songs -- [MUSIC_ID] ---- data.json (this contains the metadata for the track) ---- song_[MUSIC_ID].bin (this is a raw .acb music file, this is a CRIWARE format) @@ -54,8 +65,20 @@ CustomSongs ---- [MUSIC_ID]_x.bin ---- [MUSIC_ID]_x_1.bin ---- [MUSIC_ID]_x_2.bin + +TJA +-- [MUSIC_ID] +---- [MUSIC_ID].tja +---- song_[MUSIC_ID].ogg or .wav + +Genre override +e.g. this will override the songs to pop +-- 01 Pop +---- [MUSIC_ID] +------ [MUSIC_ID].tja +------ song_[MUSIC_ID].ogg or .wav ``` -This format will be updated in the future to remove redundantancy + ``` data.json Format { @@ -95,22 +118,53 @@ data.json Format int fumenOffsetPos; // Text Info - TextEntry songName (Song Title - e.g. A Cruel Angel's Thesis) - { - string text; - int font; (0 == Japanese, 1 == English, 2 == Traditional Chinese, 3 == Simplified Chinese, 4 == Korean) - } + TextEntry songName; (Song Title - e.g. A Cruel Angel's Thesis) - TextEntry songSubtitle (Origin of the song - e.g. From \" Neon Genesis EVANGELION \") - { - string text; - int font; (0 == Japanese, 1 == English, 2 == Traditional Chinese, 3 == Simplified Chinese, 4 == Korean) - } + TextEntry songSubtitle; (Origin of the song - e.g. From \" Neon Genesis EVANGELION \") + + TextEntry songDetail; (Extra details for the track, sometimes used to say it's Japanese name - e.g. 残酷な天使のテーゼ) +} + +TextEntry { - TextEntry songDetail (Extra details for the track, sometimes used to say it's Japanese name - e.g. 残酷な天使のテーゼ) - { string text; int font; (0 == Japanese, 1 == English, 2 == Traditional Chinese, 3 == Simplified Chinese, 4 == Korean) - } + + // Langauge overrides + string jpText; (langauge override for 日本語 text) + int jpFont; (langauge override for 日本語 text) + string enText; (langauge override for English text) + int enFont; (langauge override for English text) + string frText; (langauge override for Français text) + int frFont; (langauge override for Français text) + string itText; (langauge override for Italiano text) + int itFont; (langauge override for Italiano text) + string deText; (langauge override for Deutsch text) + int deFont; (langauge override for Deutsch text) + string esText; (langauge override for Español text) + int esFont; (langauge override for Español text) + string tcText; (langauge override for 繁體中文 text) + int tcFont; (langauge override for 繁體中文 text) + string scText; (langauge override for 简体中文 text) + int scFont; (langauge override for 简体中文 text) + string krText; (langauge override for 영어 text) + int krFont; (langauge override for 영어 text) } ``` +--- +## Supported Versions +
+Supported Versions +- 1.1.0.0 +- 1.2.2.0 +
+ +--- +## Contributers +(to add!) + +--- +## Credits +- !(SuperSonicAudio)[https://github.com/blueskythlikesclouds/SonicAudioTools] +- !(VGAudio)[https://github.com/Thealexbarney/VGAudio] +- Pulsar#5356 for the TJA2BIN.exe \ No newline at end of file diff --git a/TaikoMods.csproj b/TaikoMods.csproj deleted file mode 100644 index 4a3109a..0000000 --- a/TaikoMods.csproj +++ /dev/null @@ -1,38 +0,0 @@ - - - - net48 - com.fluto.taikomods - Fixes Taiko issues and allows custom songs - 0.0.1 - true - latest - TaikoMods - com.fluto.taikomods - 1.0.1 - - - - - - - - - - - - - - - - D:\XboxGames\T Tablet\Content\Taiko no Tatsujin_Data\Managed\Assembly-CSharp.dll - - - D:\XboxGames\T Tablet\Content\Taiko no Tatsujin_Data\Managed\Assembly-CSharp-firstpass.dll - - - - - - - diff --git a/.gitignore b/TakoTako/.gitignore similarity index 100% rename from .gitignore rename to TakoTako/.gitignore diff --git a/.idea/.idea.TaikoMods.dir/.idea/.gitignore b/TakoTako/.idea/.idea.TakoTako.dir/.idea/.gitignore similarity index 92% rename from .idea/.idea.TaikoMods.dir/.idea/.gitignore rename to TakoTako/.idea/.idea.TakoTako.dir/.idea/.gitignore index c23595d..30ccfec 100644 --- a/.idea/.idea.TaikoMods.dir/.idea/.gitignore +++ b/TakoTako/.idea/.idea.TakoTako.dir/.idea/.gitignore @@ -5,7 +5,7 @@ /contentModel.xml /modules.xml /projectSettingsUpdater.xml -/.idea.TaikoMods.iml +/.idea.TakoTako.iml # Editor-based HTTP Client requests /httpRequests/ # Datasource local storage ignored files diff --git a/.idea/.idea.TaikoMods.dir/.idea/encodings.xml b/TakoTako/.idea/.idea.TakoTako.dir/.idea/encodings.xml similarity index 100% rename from .idea/.idea.TaikoMods.dir/.idea/encodings.xml rename to TakoTako/.idea/.idea.TakoTako.dir/.idea/encodings.xml diff --git a/.idea/.idea.TaikoMods.dir/.idea/indexLayout.xml b/TakoTako/.idea/.idea.TakoTako.dir/.idea/indexLayout.xml similarity index 100% rename from .idea/.idea.TaikoMods.dir/.idea/indexLayout.xml rename to TakoTako/.idea/.idea.TakoTako.dir/.idea/indexLayout.xml diff --git a/.idea/.idea.TaikoMods.dir/.idea/vcs.xml b/TakoTako/.idea/.idea.TakoTako.dir/.idea/vcs.xml similarity index 69% rename from .idea/.idea.TaikoMods.dir/.idea/vcs.xml rename to TakoTako/.idea/.idea.TakoTako.dir/.idea/vcs.xml index 94a25f7..6c0b863 100644 --- a/.idea/.idea.TaikoMods.dir/.idea/vcs.xml +++ b/TakoTako/.idea/.idea.TakoTako.dir/.idea/vcs.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/DisableScreenChangeOnFocus.cs b/TakoTako/DisableScreenChangeOnFocus.cs similarity index 95% rename from DisableScreenChangeOnFocus.cs rename to TakoTako/DisableScreenChangeOnFocus.cs index 2634bc4..84cd4c4 100644 --- a/DisableScreenChangeOnFocus.cs +++ b/TakoTako/DisableScreenChangeOnFocus.cs @@ -1,6 +1,6 @@ using HarmonyLib; -namespace TaikoMods; +namespace TakoTako; [HarmonyPatch] public class DisableScreenChangeOnFocus diff --git a/TakoTako/Executables/tja2bin.exe b/TakoTako/Executables/tja2bin.exe new file mode 100644 index 0000000000000000000000000000000000000000..f47a6238e18a7ad5fd41b39cd65f7fa4493d8748 GIT binary patch literal 95232 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 literal 0 HcmV?d00001 diff --git a/TakoTako/FodyWeavers.xml b/TakoTako/FodyWeavers.xml new file mode 100644 index 0000000..8412ac5 --- /dev/null +++ b/TakoTako/FodyWeavers.xml @@ -0,0 +1,8 @@ + + + + TakoTako* + Newtonsoft.Json* + + + diff --git a/TakoTako/FodyWeavers.xsd b/TakoTako/FodyWeavers.xsd new file mode 100644 index 0000000..05e92c1 --- /dev/null +++ b/TakoTako/FodyWeavers.xsd @@ -0,0 +1,141 @@ + + + + + + + + + + + + A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks + + + + + A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks. + + + + + A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks + + + + + A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks. + + + + + A list of unmanaged 32 bit assembly names to include, delimited with line breaks. + + + + + A list of unmanaged 64 bit assembly names to include, delimited with line breaks. + + + + + The order of preloaded assemblies, delimited with line breaks. + + + + + + This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file. + + + + + Controls if .pdbs for reference assemblies are also embedded. + + + + + Controls if runtime assemblies are also embedded. + + + + + Controls whether the runtime assemblies are embedded with their full path or only with their assembly name. + + + + + Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option. + + + + + As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off. + + + + + Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code. + + + + + Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior. + + + + + A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with | + + + + + A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |. + + + + + A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with | + + + + + A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with |. + + + + + A list of unmanaged 32 bit assembly names to include, delimited with |. + + + + + A list of unmanaged 64 bit assembly names to include, delimited with |. + + + + + The order of preloaded assemblies, delimited with |. + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/Folder.DotSettings b/TakoTako/Folder.DotSettings similarity index 86% rename from Folder.DotSettings rename to TakoTako/Folder.DotSettings index 31b9bd1..2bc44b1 100644 --- a/Folder.DotSettings +++ b/TakoTako/Folder.DotSettings @@ -1,4 +1,5 @@  True True + True True \ No newline at end of file diff --git a/TakoTako/MusicPatch.cs b/TakoTako/MusicPatch.cs new file mode 100644 index 0000000..1b5e985 --- /dev/null +++ b/TakoTako/MusicPatch.cs @@ -0,0 +1,1953 @@ +using System; +using System.Collections; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.IO.Compression; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using BepInEx.Logging; +using HarmonyLib; +using Newtonsoft.Json; +using TakoTako.Common; +using Unity.Collections; +using Unity.Collections.LowLevel.Unsafe; +using UnityEngine; + +namespace TakoTako; + +/// +/// This will allow custom songs to be read in +/// +[HarmonyPatch] +[SuppressMessage("ReSharper", "InconsistentNaming")] +public class MusicPatch +{ + public static int SaveDataMax => DataConst.MusicMax; + + public static string MusicTrackDirectory => Plugin.Instance.ConfigSongDirectory.Value; + public static string SaveFilePath => $"{Plugin.Instance.ConfigSaveDirectory.Value}/save.json"; + private const string SongDataFileName = "data.json"; + + public static ManualLogSource Log => Plugin.Log; + + public static void Setup(Harmony harmony) + { + CreateDirectoryIfNotExist(Path.GetDirectoryName(SaveFilePath)); + CreateDirectoryIfNotExist(MusicTrackDirectory); + + PatchManual(harmony); + + void CreateDirectoryIfNotExist(string path) + { + path = Path.GetFullPath(path); + if (!Directory.Exists(path)) + { + Log.LogInfo($"Creating path at {path}"); + Directory.CreateDirectory(path); + } + } + } + + private static void PatchManual(Harmony harmony) + { + var original = typeof(FumenLoader).GetNestedType("PlayerData", BindingFlags.NonPublic).GetMethod("Read"); + var prefix = typeof(MusicPatch).GetMethod(nameof(Read_Prefix), BindingFlags.Static | BindingFlags.NonPublic); + + harmony.Patch(original, new HarmonyMethod(prefix)); + } + + #region Custom Save Data + + private static CustomMusicSaveDataBody _customSaveData; + + private static CustomMusicSaveDataBody GetCustomSaveData() + { + if (_customSaveData != null) + return _customSaveData; + + var savePath = SaveFilePath; + CustomMusicSaveDataBody data; + try + { + if (!File.Exists(savePath)) + { + data = new CustomMusicSaveDataBody(); + SaveCustomData(); + } + else + { + using var fileStream = File.OpenRead(savePath); + data = (CustomMusicSaveDataBody) JsonConvert.DeserializeObject(File.ReadAllText(savePath)); + data.CustomTrackToEnsoRecordInfo ??= new Dictionary(); + data.CustomTrackToMusicInfoEx ??= new Dictionary(); + } + + _customSaveData = data; + return data; + } + catch (Exception e) + { + Log.LogError($"Could not load custom data, creating a fresh one\n {e}"); + } + + data = new CustomMusicSaveDataBody(); + SaveCustomData(); + return data; + } + + private static int saveMutex = 0; + + private static void SaveCustomData() + { + if (!Plugin.Instance.ConfigSaveEnabled.Value) + return; + + if (_customSaveData == null) + return; + + saveMutex++; + if (saveMutex > 1) + return; + + SaveData(); + + async void SaveData() + { + while (saveMutex > 0) + { + saveMutex = 0; + Log.LogInfo("Saving custom data"); + try + { + var data = GetCustomSaveData(); + var savePath = SaveFilePath; + var json = JsonConvert.SerializeObject(data); + + using Stream fs = new FileStream(savePath, FileMode.Create, FileAccess.Write, FileShare.None, 4096, FileOptions.WriteThrough); + using StreamWriter streamWriter = new StreamWriter(fs); + await streamWriter.WriteAsync(json); + } + catch (Exception e) + { + Log.LogError($"Could not save custom data \n {e}"); + } + } + } + } + + #endregion + + #region Load Custom Songs + + private static ConcurrentBag customSongsList; + private static readonly ConcurrentDictionary idToSong = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary uniqueIdToSong = new ConcurrentDictionary(); + + public static ConcurrentBag GetCustomSongs() + { + if (customSongsList != null) + return customSongsList; + + customSongsList = new ConcurrentBag(); + if (!Directory.Exists(MusicTrackDirectory)) + { + Log.LogError($"Cannot find {MusicTrackDirectory}"); + return customSongsList; + } + + try + { + // add songs + var songPaths = Directory.GetFiles(MusicTrackDirectory, "song*.bin", SearchOption.AllDirectories).Select(Path.GetDirectoryName).Distinct().ToList(); + Parallel.ForEach(songPaths, musicDirectory => + { + try + { + var directory = musicDirectory; + + var isGenerated = musicDirectory.EndsWith("[GENERATED]"); + if (isGenerated) + return; + + SubmitDirectory(directory, false); + } + catch (Exception e) + { + Log.LogError(e); + } + }); + + var tjaPaths = Directory.GetFiles(MusicTrackDirectory, "*.tja", SearchOption.AllDirectories).Select(Path.GetDirectoryName).Distinct().ToList(); + // convert / add TJA songs + Parallel.ForEach(tjaPaths, new ParallelOptions() {MaxDegreeOfParallelism = 4}, musicDirectory => + { + try + { + if (IsTjaConverted(musicDirectory, out var conversionStatus) && conversionStatus != null) + { + foreach (var item in conversionStatus.Items.Where(item => item.Successful)) + SubmitDirectory(Path.Combine(musicDirectory, item.FolderName), true); + return; + } + + conversionStatus ??= new ConversionStatus(); + + if (conversionStatus.Items.Count > 0 && conversionStatus.Items.Any(x => !x.Successful && x.Attempts > ConversionStatus.ConversionItem.MaxAttempts)) + { + Log.LogWarning($"Ignoring {musicDirectory}"); + return; + } + + try + { + var pathName = Path.GetFileName(musicDirectory); + var pluginDirectory = @$"{Environment.CurrentDirectory}\BepInEx\plugins\{PluginInfo.PLUGIN_GUID}"; + var tjaConvertPath = @$"{pluginDirectory}\TJAConvert.exe"; + var tja2BinConvertPath = @$"{pluginDirectory}\tja2bin.exe"; + if (!File.Exists(tjaConvertPath) || !File.Exists(tja2BinConvertPath)) + throw new Exception("Cannot find .exes in plugin folder"); + + Log.LogInfo($"Converting {pathName}"); + var info = new ProcessStartInfo() + { + FileName = tjaConvertPath, + Arguments = $"\"{musicDirectory}\"", + CreateNoWindow = true, + WindowStyle = ProcessWindowStyle.Hidden, + UseShellExecute = false, + RedirectStandardOutput = true, + WorkingDirectory = pluginDirectory, + StandardOutputEncoding = Encoding.Unicode, + }; + + var process = new Process(); + process.StartInfo = info; + process.Start(); + var result = process.StandardOutput.ReadToEnd(); + var resultLines = result.Split(new[] {"\r\n", "\r", "\n"}, StringSplitOptions.RemoveEmptyEntries); + + foreach (var line in resultLines) + { + var match = ConversionStatus.ConversionResultRegex.Match(line); + if (!match.Success) + continue; + + var resultInt = int.Parse(match.Groups["ID"].Value); + var folderPath = match.Groups["PATH"].Value; + + folderPath = Path.GetFullPath(folderPath).Replace(Path.GetFullPath(musicDirectory), "."); + + var existingEntry = conversionStatus.Items.FirstOrDefault(x => x.FolderName == folderPath); + var asciiFolderPath = Regex.Replace(folderPath, @"[^\u0000-\u007F]+", string.Empty); + if (resultInt >= 0) + Log.LogInfo($"Converted {asciiFolderPath} successfully"); + else + Log.LogError($"Could not convert {asciiFolderPath}"); + + if (existingEntry == null) + { + conversionStatus.Items.Add(new ConversionStatus.ConversionItem() + { + Attempts = 1, + FolderName = folderPath, + Successful = resultInt >= 0, + }); + } + else + { + existingEntry.Attempts++; + existingEntry.Successful = resultInt >= 0; + } + } + + File.WriteAllText(Path.Combine(musicDirectory, "conversion.json"), JsonConvert.SerializeObject(conversionStatus), Encoding.Unicode); + } + catch (Exception e) + { + Log.LogError(e); + return; + } + + if (!IsTjaConverted(musicDirectory, out conversionStatus)) + return; + + // if the files are converted, let's gzip those .bins to save space... because they can add up + foreach (var item in conversionStatus.Items) + { + var directory = Path.Combine(musicDirectory, item.FolderName); + var dataPath = Path.Combine(directory, "data.json"); + if (!File.Exists(dataPath)) + { + Log.LogError($"Cannot find {dataPath}"); + return; + } + + var song = JsonConvert.DeserializeObject(File.ReadAllText(dataPath)); + if (song == null) + { + Log.LogError($"Cannot read {dataPath}"); + return; + } + + foreach (var filePath in Directory.EnumerateFiles(directory, "*.bin")) + { + using MemoryStream compressedMemoryStream = new MemoryStream(); + using (FileStream originalFileStream = File.Open(filePath, FileMode.Open)) + { + using var compressor = new GZipStream(compressedMemoryStream, CompressionMode.Compress); + originalFileStream.CopyTo(compressor); + } + + File.WriteAllBytes(filePath, compressedMemoryStream.ToArray()); + } + + song.AreFilesGZipped = true; + File.WriteAllText(dataPath, JsonConvert.SerializeObject(song)); + + SubmitDirectory(directory, true); + } + } + catch (Exception e) + { + Log.LogError(e); + } + }); + + if (customSongsList.Count == 0) + Log.LogInfo($"No tracks found"); + } + catch (Exception e) + { + Log.LogError(e); + } + + return customSongsList; + + void SubmitDirectory(string directory, bool isTjaSong) + { + var dataPath = Path.Combine(directory, "data.json"); + if (!File.Exists(dataPath)) + { + Log.LogError($"Cannot find {dataPath}"); + return; + } + + var song = JsonConvert.DeserializeObject(File.ReadAllText(dataPath)); + if (song == null) + { + Log.LogError($"Cannot read {dataPath}"); + return; + } + + if (Plugin.Instance.ConfigApplyGenreOverride.Value) + { + // if this directory has a genre then override it + var fullPath = Path.GetFullPath(directory); + fullPath = fullPath.Replace(Path.GetFullPath(Plugin.Instance.ConfigSongDirectory.Value), ""); + var directories = fullPath.Split('\\'); + if (directories.Any(x => x.Equals("01 Pop", StringComparison.InvariantCultureIgnoreCase))) + song.genreNo = 0; + if (directories.Any(x => x.Equals("02 Anime", StringComparison.InvariantCultureIgnoreCase))) + song.genreNo = 1; + if (directories.Any(x => x.Equals("03 Vocaloid", StringComparison.InvariantCultureIgnoreCase))) + song.genreNo = 2; + if (directories.Any(x => x.Equals("04 Children and Folk", StringComparison.InvariantCultureIgnoreCase))) + song.genreNo = 4; + if (directories.Any(x => x.Equals("05 Variety", StringComparison.InvariantCultureIgnoreCase))) + song.genreNo = 3; + if (directories.Any(x => x.Equals("06 Classical", StringComparison.InvariantCultureIgnoreCase))) + song.genreNo = 5; + if (directories.Any(x => x.Equals("07 Game Music", StringComparison.InvariantCultureIgnoreCase))) + song.genreNo = 6; + if (directories.Any(x => x.Equals("08 Live Festival Mode", StringComparison.InvariantCultureIgnoreCase))) + song.genreNo = 3; + if (directories.Any(x => x.Equals("08 Namco Original", StringComparison.InvariantCultureIgnoreCase))) + song.genreNo = 7; + } + + var instanceId = Guid.NewGuid().ToString(); + song.SongName = song.id; + song.FolderPath = directory; + song.id = instanceId; + + if (uniqueIdToSong.ContainsKey(song.uniqueId) || (song.uniqueId >= 0 && song.uniqueId <= SaveDataMax)) + { + var uniqueIdTest = unchecked(song.id.GetHashCode() + song.previewPos + song.fumenOffsetPos); + while (uniqueIdToSong.ContainsKey(uniqueIdTest) || (uniqueIdTest >= 0 && uniqueIdTest <= SaveDataMax)) + uniqueIdTest = unchecked((uniqueIdTest + 1) * (uniqueIdTest + 1)); + + song.uniqueId = uniqueIdTest; + } + + customSongsList.Add(song); + idToSong[song.id] = song; + uniqueIdToSong[song.uniqueId] = song; + Log.LogInfo($"Added {(isTjaSong ? "TJA" : "")} Song {song.songName.text}"); + } + } + + private static bool IsTjaConverted(string directory, out ConversionStatus conversionStatus) + { + conversionStatus = null; + if (!Directory.Exists(directory)) + return false; + + var conversionFile = Path.Combine(directory, "conversion.json"); + if (!File.Exists(conversionFile)) + return false; + + var json = File.ReadAllText(conversionFile, Encoding.Unicode); + try + { + conversionStatus = JsonConvert.DeserializeObject(json); + if (conversionStatus == null) + return false; + + return conversionStatus.Items.Count != 0 && conversionStatus.Items.All(x => x.Successful); + } + catch + { + return false; + } + } + + #endregion + + #region Loading and Initializing Data + + /// + /// This will handle loading the meta data of tracks + /// + [HarmonyPatch(typeof(MusicDataInterface))] + [HarmonyPatch(MethodType.Constructor)] + [HarmonyPatch(new[] {typeof(string)})] + [HarmonyPostfix] + private static void MusicDataInterface_Postfix(MusicDataInterface __instance, string path) + { + try + { + // This is where the metadata for tracks are read in our attempt to allow custom tracks will be to add additional metadata to the list that is created + Log.LogInfo("Injecting custom songs"); + + var customSongs = GetCustomSongs(); + if (customSongs.Count == 0) + return; + + // now that we have loaded this json, inject it into the existing `musicInfoAccessers` + var musicInfoAccessors = __instance.musicInfoAccessers; + + #region Logic from the original constructor + + foreach (var song in customSongs) + { + if (song == null) + continue; + + musicInfoAccessors.Add(new MusicDataInterface.MusicInfoAccesser( + song.uniqueId, + song.id, + $"song_{song.id}", + song.order, + song.genreNo, + !Plugin.Instance.ConfigDisableCustomDLCSongs.Value, + false, + 0, false, + 0, + new[] + { + song.branchEasy, + song.branchNormal, + song.branchHard, + song.branchMania, + song.branchUra + }, new[] + { + song.starEasy, + song.starNormal, + song.starHard, + song.starMania, + song.starUra + }, new[] + { + song.shinutiEasy, + song.shinutiNormal, + song.shinutiHard, + song.shinutiMania, + song.shinutiUra + }, new[] + { + song.shinutiEasyDuet, + song.shinutiNormalDuet, + song.shinutiHardDuet, + song.shinutiManiaDuet, + song.shinutiUraDuet + }, new[] + { + song.scoreEasy, + song.scoreNormal, + song.scoreHard, + song.scoreMania, + song.scoreUra + })); + } + + #endregion + + // sort this + musicInfoAccessors.Sort((a, b) => a.Order - b.Order); + } + catch (Exception e) + { + Log.LogError(e); + } + } + + + /// + /// This will handle loading the preview data of tracks + /// + [HarmonyPatch(typeof(SongDataInterface))] + [HarmonyPatch(MethodType.Constructor)] + [HarmonyPatch(new[] {typeof(string)})] + [HarmonyPostfix] + private static void SongDataInterface_Postfix(SongDataInterface __instance, string path) + { + // This is where the metadata for tracks are read in our attempt to allow custom tracks will be to add additional metadata to the list that is created + Log.LogInfo("Injecting custom song preview data"); + var customSongs = GetCustomSongs(); + + if (customSongs.Count == 0) + return; + + // now that we have loaded this json, inject it into the existing `songInfoAccessers` + var musicInfoAccessors = __instance.songInfoAccessers; + if (musicInfoAccessors == null) + return; + + foreach (var customTrack in customSongs) + { + if (customTrack == null) + continue; + + musicInfoAccessors.Add(new SongDataInterface.SongInfoAccesser(customTrack.id, customTrack.previewPos, customTrack.fumenOffsetPos)); + } + } + + + /// + /// This will handle loading the localisation of tracks + /// + [HarmonyPatch(typeof(WordDataInterface))] + [HarmonyPatch(MethodType.Constructor)] + [HarmonyPatch(new[] {typeof(string), typeof(string)})] + [HarmonyPostfix] + private static void WordDataInterface_Postfix(WordDataInterface __instance, string path, string language) + { + // This is where the metadata for tracks are read in our attempt to allow custom tracks will be to add additional metadata to the list that is created + var customSongs = GetCustomSongs(); + + if (customSongs.Count == 0) + return; + + var customLanguage = Plugin.Instance.ConfigOverrideDefaultSongLanguage.Value; + var languageValue = language; + if (customLanguage is "Japanese" or "English" or "French" or "Italian" or "German" or "Spanish" or "ChineseTraditional" or "ChineseSimplified" or "Korean") + languageValue = customLanguage; + + // now that we have loaded this json, inject it into the existing `songInfoAccessers` + var musicInfoAccessors = __instance.wordListInfoAccessers; + + // override the existing songs if we're using a custom language + if (languageValue != language) + { + var wordListInfoRead = (ReadData) typeof(WordDataInterface).GetField("wordListInfoRead", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); + var dictionary = wordListInfoRead.InfomationDatas.ToList(); + + for (int i = 0; i < musicInfoAccessors.Count; i++) + { + const string songDetailPrefix = "song_detail_"; + var entry = musicInfoAccessors[i]; + var index = entry.Key.IndexOf(songDetailPrefix, StringComparison.Ordinal); + if (index < 0) + continue; + + var songTitle = entry.Key.Substring(songDetailPrefix.Length); + if (string.IsNullOrWhiteSpace(songTitle)) + continue; + + var songKey = $"song_{songTitle}"; + var subtitleKey = $"song_sub_{songTitle}"; + var detailKey = $"song_detail_{songTitle}"; + + var songEntry = dictionary.Find(x => x.key == songKey); + var subtitleEntry = dictionary.Find(x => x.key == subtitleKey); + var detailEntry = dictionary.Find(x => x.key == detailKey); + + if (songEntry == null || subtitleEntry == null || detailEntry == null) + continue; + + musicInfoAccessors.RemoveAll(x => x.Key == songKey || x.Key == subtitleKey || x.Key == detailKey); + + var songValues = GetValuesWordList(songEntry); + var subtitleValues = GetValuesWordList(songEntry); + var detailValues = GetValuesWordList(songEntry); + + musicInfoAccessors.Insert(0, new WordDataInterface.WordListInfoAccesser(songKey, songValues.text, songValues.font)); + musicInfoAccessors.Insert(0, new WordDataInterface.WordListInfoAccesser(subtitleKey, subtitleValues.text, subtitleValues.font)); + musicInfoAccessors.Insert(0, new WordDataInterface.WordListInfoAccesser(detailKey, detailValues.text, detailValues.font)); + } + } + + foreach (var customTrack in customSongs) + { + Add($"song_{customTrack.id}", customTrack.songName); + Add($"song_sub_{customTrack.id}", customTrack.songSubtitle); + Add($"song_detail_{customTrack.id}", customTrack.songDetail); + + void Add(string key, TextEntry textEntry) + { + var (text, font) = GetValuesTextEntry(textEntry); + musicInfoAccessors.Add(new WordDataInterface.WordListInfoAccesser(key, text, font)); + } + } + + (string text, int font) GetValuesWordList(WordListInfo wordListInfo) + { + string text; + int font; + switch (languageValue) + { + case "Japanese": + text = wordListInfo.jpText; + font = wordListInfo.jpFontType; + break; + case "English": + text = wordListInfo.enText; + font = wordListInfo.enFontType; + break; + case "French": + text = wordListInfo.frText; + font = wordListInfo.frFontType; + break; + case "Italian": + text = wordListInfo.itText; + font = wordListInfo.itFontType; + break; + case "German": + text = wordListInfo.deText; + font = wordListInfo.deFontType; + break; + case "Spanish": + text = wordListInfo.esText; + font = wordListInfo.esFontType; + break; + case "Chinese": + case "ChineseT": + case "ChineseTraditional": + text = wordListInfo.tcText; + font = wordListInfo.tcFontType; + break; + case "ChineseSimplified": + case "ChineseS": + text = wordListInfo.scText; + font = wordListInfo.scFontType; + break; + case "Korean": + text = wordListInfo.krText; + font = wordListInfo.krFontType; + break; + default: + text = wordListInfo.enText; + font = wordListInfo.enFontType; + break; + } + + return (text, font); + } + + (string text, int font) GetValuesTextEntry(TextEntry textEntry) + { + string text; + int font; + switch (languageValue) + { + case "Japanese": + text = textEntry.jpText; + font = textEntry.jpFont; + break; + case "English": + text = textEntry.enText; + font = textEntry.enFont; + break; + case "French": + text = textEntry.frText; + font = textEntry.frFont; + break; + case "Italian": + text = textEntry.itText; + font = textEntry.itFont; + break; + case "German": + text = textEntry.deText; + font = textEntry.deFont; + break; + case "Spanish": + text = textEntry.esText; + font = textEntry.esFont; + break; + case "Chinese": + case "ChineseT": + case "ChineseTraditional": + text = textEntry.tcText; + font = textEntry.tcFont; + break; + case "ChineseSimplified": + case "ChineseS": + text = textEntry.scText; + font = textEntry.scFont; + break; + case "Korean": + text = textEntry.krText; + font = textEntry.krFont; + break; + default: + text = textEntry.enText; + font = textEntry.enFont; + break; + } + + if (!string.IsNullOrEmpty(text)) return (text, font); + text = textEntry.text; + font = textEntry.font; + + return (text, font); + } + } + + #endregion + + #region Loading / Save Custom Save Data + + /// + /// When loading, make sure to ignore custom tracks, as their IDs will be different + /// + [HarmonyPatch(typeof(SongSelectManager), "LoadSongList")] + [HarmonyPrefix] + private static bool LoadSongList_Prefix(SongSelectManager __instance) + { + #region Edited Code + + Log.LogInfo("Loading custom save"); + var customData = GetCustomSaveData(); + + #endregion + + #region Setup instanced variables / methods + + var playDataMgr = (PlayDataManager) typeof(SongSelectManager).GetField("playDataMgr", BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(__instance); + var musicInfoAccess = (MusicDataInterface.MusicInfoAccesser[]) typeof(SongSelectManager).GetField("musicInfoAccess", BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(__instance); + var enableKakuninSong = (bool) (typeof(SongSelectManager).GetField("enableKakuninSong", BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(__instance) ?? false); + + var getLocalizedTextMethodInfo = typeof(SongSelectManager).GetMethod("GetLocalizedText", BindingFlags.NonPublic | BindingFlags.Instance); + var getLocalizedText = (string x) => (string) getLocalizedTextMethodInfo?.Invoke(__instance, new object[] {x, string.Empty}); + + var updateSortCategoryInfoMethodInfo = typeof(SongSelectManager).GetMethod("UpdateSortCategoryInfo", BindingFlags.NonPublic | BindingFlags.Instance); + var updateSortCategoryInfo = (DataConst.SongSortType x) => updateSortCategoryInfoMethodInfo?.Invoke(__instance, new object[] {x}); + + #endregion + + if (playDataMgr == null) + { + Log.LogError("Could not find playDataMgr"); + return true; + } + + __instance.UnsortedSongList.Clear(); + playDataMgr.GetMusicInfoExAll(0, out var dst); + playDataMgr.GetPlayerInfo(0, out var _); + _ = TaikoSingletonMonoBehaviour.Instance.newFriends.Count; + for (int i = 0; i < 8; i++) + { + for (int j = 0; j < musicInfoAccess.Length; j++) + { + bool flag = false; + playDataMgr.GetUnlockInfo(0, DataConst.ItemType.Music, musicInfoAccess[j].UniqueId, out var dst3); + if (!dst3.isUnlock && musicInfoAccess[j].Price != 0) + { + flag = true; + } + + if (!enableKakuninSong && musicInfoAccess[j].IsKakuninSong()) + { + flag = true; + } + + if (flag || musicInfoAccess[j].GenreNo != i) + { + continue; + } + + SongSelectManager.Song song2 = new SongSelectManager.Song(); + song2.PreviewIndex = j; + song2.Id = musicInfoAccess[j].Id; + song2.TitleKey = "song_" + musicInfoAccess[j].Id; + song2.SubKey = "song_sub_" + musicInfoAccess[j].Id; + song2.RubyKey = "song_detail_" + musicInfoAccess[j].Id; + song2.UniqueId = musicInfoAccess[j].UniqueId; + song2.SongGenre = musicInfoAccess[j].GenreNo; + song2.ListGenre = i; + song2.Order = musicInfoAccess[j].Order; + song2.TitleText = getLocalizedText("song_" + song2.Id); + song2.SubText = getLocalizedText("song_sub_" + song2.Id); + song2.DetailText = getLocalizedText("song_detail_" + song2.Id); + song2.Stars = musicInfoAccess[j].Stars; + song2.Branches = musicInfoAccess[j].Branches; + song2.HighScores = new SongSelectManager.Score[5]; + song2.HighScores2P = new SongSelectManager.Score[5]; + song2.DLC = musicInfoAccess[j].IsDLC; + song2.Price = musicInfoAccess[j].Price; + song2.IsCap = musicInfoAccess[j].IsCap; + if (TaikoSingletonMonoBehaviour.Instance.MyDataManager.SongData.GetInfo(song2.Id) != null) + { + song2.AudioStartMS = TaikoSingletonMonoBehaviour.Instance.MyDataManager.SongData.GetInfo(song2.Id).PreviewPos; + } + else + { + song2.AudioStartMS = 0; + } + + if (dst != null) + { + #region Edited Code + + MusicInfoEx data; + if (uniqueIdToSong.ContainsKey(musicInfoAccess[j].UniqueId)) + { + customData.CustomTrackToMusicInfoEx.TryGetValue(musicInfoAccess[j].UniqueId, out var objectData); + data = objectData; + } + else + data = dst[musicInfoAccess[j].UniqueId]; + + song2.Favorite = data.favorite; + song2.NotPlayed = new bool[5]; + song2.NotCleared = new bool[5]; + song2.NotFullCombo = new bool[5]; + song2.NotDondaFullCombo = new bool[5]; + song2.NotPlayed2P = new bool[5]; + song2.NotCleared2P = new bool[5]; + song2.NotFullCombo2P = new bool[5]; + song2.NotDondaFullCombo2P = new bool[5]; + bool isNew = data.isNew; + + #endregion + + for (int k = 0; k < 5; k++) + { + playDataMgr.GetPlayerRecordInfo(0, musicInfoAccess[j].UniqueId, (EnsoData.EnsoLevelType) k, out var dst4); + song2.NotPlayed[k] = dst4.playCount <= 0; + song2.NotCleared[k] = dst4.crown < DataConst.CrownType.Silver; + song2.NotFullCombo[k] = dst4.crown < DataConst.CrownType.Gold; + song2.NotDondaFullCombo[k] = dst4.crown < DataConst.CrownType.Rainbow; + song2.HighScores[k].hiScoreRecordInfos = dst4.normalHiScore; + song2.HighScores[k].crown = dst4.crown; + playDataMgr.GetPlayerRecordInfo(1, musicInfoAccess[j].UniqueId, (EnsoData.EnsoLevelType) k, out var dst5); + song2.NotPlayed2P[k] = dst5.playCount <= 0; + song2.NotCleared2P[k] = dst4.crown < DataConst.CrownType.Silver; + song2.NotFullCombo2P[k] = dst5.crown < DataConst.CrownType.Gold; + song2.NotDondaFullCombo2P[k] = dst5.crown < DataConst.CrownType.Rainbow; + song2.HighScores2P[k].hiScoreRecordInfos = dst5.normalHiScore; + song2.HighScores2P[k].crown = dst5.crown; + } + + song2.NewSong = isNew && (song2.DLC || song2.Price > 0); + } + + __instance.UnsortedSongList.Add(song2); + } + } + + var unsortedSongList = (from song in __instance.UnsortedSongList + orderby song.SongGenre, song.Order + select song).ToList(); + typeof(SongSelectManager).GetProperty(nameof(SongSelectManager.UnsortedSongList), BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance)?.SetValue(__instance, unsortedSongList); + + var songList = new List(__instance.UnsortedSongList); + typeof(SongSelectManager).GetProperty(nameof(SongSelectManager.SongList), BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance)?.SetValue(__instance, songList); + + updateSortCategoryInfo(DataConst.SongSortType.Genre); + return false; + } + + /// + /// When saving favourite tracks, save the custom ones too + /// + [HarmonyPatch(typeof(SongSelectManager), "SaveFavotiteSongs")] + [HarmonyPrefix] + private static bool SaveFavotiteSongs_Prefix(SongSelectManager __instance) + { + var playDataMgr = (PlayDataManager) typeof(SongSelectManager).GetField("playDataMgr", BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(__instance); + + playDataMgr.GetMusicInfoExAll(0, out var dst); + var customSaveData = GetCustomSaveData(); + + bool saveCustomData = false; + int num = 0; + foreach (SongSelectManager.Song unsortedSong in __instance.UnsortedSongList) + { + num++; + if (uniqueIdToSong.ContainsKey(unsortedSong.UniqueId)) + { + customSaveData.CustomTrackToMusicInfoEx.TryGetValue(unsortedSong.UniqueId, out var data); + saveCustomData |= data.favorite != unsortedSong.Favorite; + data.favorite = unsortedSong.Favorite; + customSaveData.CustomTrackToMusicInfoEx[unsortedSong.UniqueId] = data; + } + else + { + dst[unsortedSong.UniqueId].favorite = unsortedSong.Favorite; + playDataMgr.SetMusicInfoEx(0, unsortedSong.UniqueId, ref dst[unsortedSong.UniqueId], num >= __instance.UnsortedSongList.Count); + } + } + + if (saveCustomData) + SaveCustomData(); + + return false; + } + + /// + /// When loading the song, mark the custom song as not new + /// + [HarmonyPatch(typeof(CourseSelect), "EnsoConfigSubmit")] + [HarmonyPrefix] + private static bool EnsoConfigSubmit_Prefix(CourseSelect __instance) + { + var songInfoType = typeof(CourseSelect).GetNestedType("SongInfo", BindingFlags.NonPublic); + var scoreType = typeof(CourseSelect).GetNestedType("Score", BindingFlags.NonPublic); + var playerTypeEnumType = typeof(CourseSelect).GetNestedType("PlayerType", BindingFlags.NonPublic); + + var settings = (EnsoData.Settings) typeof(CourseSelect).GetField("settings", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); + var playDataManager = (PlayDataManager) typeof(CourseSelect).GetField("playDataManager", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); + var ensoDataManager = (EnsoDataManager) typeof(CourseSelect).GetField("ensoDataManager", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); + + var selectedSongInfo = typeof(CourseSelect).GetField("selectedSongInfo", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); + var ensoMode = (EnsoMode) typeof(CourseSelect).GetField("ensoMode", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); + var ensoMode2P = (EnsoMode) typeof(CourseSelect).GetField("ensoMode2P", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); + var selectedCourse = (int) typeof(CourseSelect).GetField("selectedCourse", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); + var selectedCourse2P = (int) typeof(CourseSelect).GetField("selectedCourse2P", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); + var status = (SongSelectStatus) typeof(CourseSelect).GetField("status", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); + + var SetSaveDataEnsoModeMethodInfo = typeof(CourseSelect).GetMethod("SetSaveDataEnsoMode", BindingFlags.NonPublic | BindingFlags.Instance); + var SetSaveDataEnsoMode = (object x) => (string) SetSaveDataEnsoModeMethodInfo.Invoke(__instance, new object[] {x}); + + var songUniqueId = (int) songInfoType.GetField("UniqueId").GetValue(selectedSongInfo); + + void SetSettings() => typeof(CourseSelect).GetField("settings", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(__instance, settings); + + settings.ensoType = EnsoData.EnsoType.Normal; + settings.rankMatchType = EnsoData.RankMatchType.None; + settings.musicuid = (string) songInfoType.GetField("Id").GetValue(selectedSongInfo); + settings.musicUniqueId = songUniqueId; + settings.genre = (EnsoData.SongGenre) songInfoType.GetField("SongGenre").GetValue(selectedSongInfo); + settings.playerNum = 1; + settings.ensoPlayerSettings[0].neiroId = ensoMode.neiro; + settings.ensoPlayerSettings[0].courseType = (EnsoData.EnsoLevelType) selectedCourse; + settings.ensoPlayerSettings[0].speed = ensoMode.speed; + settings.ensoPlayerSettings[0].dron = ensoMode.dron; + settings.ensoPlayerSettings[0].reverse = ensoMode.reverse; + settings.ensoPlayerSettings[0].randomlv = ensoMode.randomlv; + settings.ensoPlayerSettings[0].special = ensoMode.special; + + var array = (Array) songInfoType.GetField("HighScores").GetValue(selectedSongInfo); + settings.ensoPlayerSettings[0].hiScore = ((HiScoreRecordInfo) scoreType.GetField("hiScoreRecordInfos").GetValue(array.GetValue(selectedCourse))).score; + + SetSettings(); + if (status.Is2PActive) + { + settings.ensoPlayerSettings[1].neiroId = ensoMode2P.neiro; + settings.ensoPlayerSettings[1].courseType = (EnsoData.EnsoLevelType) selectedCourse2P; + settings.ensoPlayerSettings[1].speed = ensoMode2P.speed; + settings.ensoPlayerSettings[1].dron = ensoMode2P.dron; + settings.ensoPlayerSettings[1].reverse = ensoMode2P.reverse; + settings.ensoPlayerSettings[1].randomlv = ensoMode2P.randomlv; + settings.ensoPlayerSettings[1].special = ensoMode2P.special; + TaikoSingletonMonoBehaviour.Instance.MyDataManager.PlayData.GetPlayerRecordInfo(1, songUniqueId, (EnsoData.EnsoLevelType) selectedCourse2P, out var dst); + settings.ensoPlayerSettings[1].hiScore = dst.normalHiScore.score; + settings.playerNum = 2; + } + + settings.debugSettings.isTestMenu = false; + settings.rankMatchType = EnsoData.RankMatchType.None; + settings.isRandomSelect = (bool) songInfoType.GetField("IsRandomSelect").GetValue(selectedSongInfo); + settings.isDailyBonus = (bool) songInfoType.GetField("IsDailyBonus").GetValue(selectedSongInfo); + ensoMode.songUniqueId = settings.musicUniqueId; + ensoMode.level = (EnsoData.EnsoLevelType) selectedCourse; + + SetSettings(); + typeof(CourseSelect).GetField("ensoMode", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(__instance, ensoMode); + SetSaveDataEnsoMode(Enum.Parse(playerTypeEnumType, "Player1")); + ensoMode2P.songUniqueId = settings.musicUniqueId; + ensoMode2P.level = (EnsoData.EnsoLevelType) selectedCourse2P; + typeof(CourseSelect).GetField("ensoMode2P", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(__instance, ensoMode2P); + SetSaveDataEnsoMode(Enum.Parse(playerTypeEnumType, "Player2")); + playDataManager.GetSystemOption(out var dst2); + int deviceTypeIndex = EnsoDataManager.GetDeviceTypeIndex(settings.ensoPlayerSettings[0].inputDevice); + settings.noteDispOffset = dst2.onpuDispLevels[deviceTypeIndex]; + settings.noteDelay = dst2.onpuHitLevels[deviceTypeIndex]; + settings.songVolume = TaikoSingletonMonoBehaviour.Instance.MySoundManager.GetVolume(SoundManager.SoundType.InGameSong); + settings.seVolume = TaikoSingletonMonoBehaviour.Instance.MySoundManager.GetVolume(SoundManager.SoundType.Se); + settings.voiceVolume = TaikoSingletonMonoBehaviour.Instance.MySoundManager.GetVolume(SoundManager.SoundType.Voice); + settings.bgmVolume = TaikoSingletonMonoBehaviour.Instance.MySoundManager.GetVolume(SoundManager.SoundType.Bgm); + settings.neiroVolume = TaikoSingletonMonoBehaviour.Instance.MySoundManager.GetVolume(SoundManager.SoundType.InGameNeiro); + settings.effectLevel = (EnsoData.EffectLevel) dst2.qualityLevel; + SetSettings(); + ensoDataManager.SetSettings(ref settings); + ensoDataManager.DecideSetting(); + if (status.Is2PActive) + { + dst2.controlType[1] = dst2.controlType[0]; + playDataManager.SetSystemOption(ref dst2); + } + + var customSaveData = GetCustomSaveData(); + + if (uniqueIdToSong.ContainsKey(songUniqueId)) + { + customSaveData.CustomTrackToMusicInfoEx.TryGetValue(songUniqueId, out var data); + data.isNew = false; + customSaveData.CustomTrackToMusicInfoEx[songUniqueId] = data; + SaveCustomData(); + } + else + { + playDataManager.GetMusicInfoExAll(0, out var dst3); + dst3[songUniqueId].isNew = false; + playDataManager.SetMusicInfoEx(0, songUniqueId, ref dst3[songUniqueId]); + } + + return false; + } + + /// + /// When loading the song obtain isfavourite correctly + /// + [HarmonyPatch(typeof(KpiListCommon.MusicKpiInfo), "GetEnsoSettings")] + [HarmonyPrefix] + private static bool GetEnsoSettings_Prefix(KpiListCommon.MusicKpiInfo __instance) + { + TaikoSingletonMonoBehaviour.Instance.MyDataManager.EnsoData.CopySettings(out var dst); + __instance.music_id = dst.musicuid; + __instance.genre = (int) dst.genre; + __instance.course_type = (int) dst.ensoPlayerSettings[0].courseType; + __instance.neiro_id = dst.ensoPlayerSettings[0].neiroId; + __instance.speed = (int) dst.ensoPlayerSettings[0].speed; + __instance.dron = (int) dst.ensoPlayerSettings[0].dron; + __instance.reverse = (int) dst.ensoPlayerSettings[0].reverse; + __instance.randomlv = (int) dst.ensoPlayerSettings[0].randomlv; + __instance.special = (int) dst.ensoPlayerSettings[0].special; + PlayDataManager playData = TaikoSingletonMonoBehaviour.Instance.MyDataManager.PlayData; + playData.GetEnsoMode(out var dst2); + __instance.sort_course = (int) dst2.songSortCourse; + __instance.sort_type = (int) dst2.songSortType; + __instance.sort_filter = (int) dst2.songFilterType; + __instance.sort_favorite = (int) dst2.songFilterTypeFavorite; + MusicDataInterface.MusicInfoAccesser[] array = TaikoSingletonMonoBehaviour.Instance.MyDataManager.MusicData.musicInfoAccessers.ToArray(); + playData.GetMusicInfoExAll(0, out var dst3); + + #region edited code + + for (int i = 0; i < array.Length; i++) + { + var id = array[i].UniqueId; + if (id == dst.musicUniqueId && dst3 != null) + { + if (uniqueIdToSong.ContainsKey(id)) + { + GetCustomSaveData().CustomTrackToMusicInfoEx.TryGetValue(id, out var data); + __instance.is_favorite = data.favorite; + } + else + { + __instance.is_favorite = dst3[id].favorite; + } + } + } + + #endregion + + playData.GetPlayerInfo(0, out var dst4); + __instance.current_coins_num = dst4.donCoin; + __instance.total_coins_num = dst4.getCoinsInTotal; + playData.GetRankMatchSeasonRecordInfo(0, 0, out var dst5); + __instance.rank_point = dst5.rankPointMax; + + return false; + } + + /// + /// Load scores from custom save data + /// + [HarmonyPatch(typeof(PlayDataManager), "GetPlayerRecordInfo")] + [HarmonyPrefix] + public static bool GetPlayerRecordInfo_Prefix(int playerId, int uniqueId, EnsoData.EnsoLevelType levelType, out EnsoRecordInfo dst, PlayDataManager __instance) + { + if (!uniqueIdToSong.ContainsKey(uniqueId)) + { + dst = new EnsoRecordInfo(); + return true; + } + + int num = (int) levelType; + if (num is < 0 or >= 5) + num = 0; + + // load our custom save, this will combine the scores of player1 and player2 + var saveData = GetCustomSaveData().CustomTrackToEnsoRecordInfo; + if (!saveData.TryGetValue(uniqueId, out var ensoData)) + { + ensoData = new EnsoRecordInfo[(int) EnsoData.EnsoLevelType.Num]; + saveData[uniqueId] = ensoData; + } + + dst = ensoData[num]; + return false; + } + + /// + /// Save scores to custom save data + /// + [HarmonyPatch(typeof(PlayDataManager), "UpdatePlayerScoreRecordInfo", + new Type[] {typeof(int), typeof(int), typeof(int), typeof(EnsoData.EnsoLevelType), typeof(bool), typeof(DataConst.SpecialTypes), typeof(HiScoreRecordInfo), typeof(DataConst.ResultType), typeof(bool), typeof(DataConst.CrownType)})] + [HarmonyPrefix] + public static bool UpdatePlayerScoreRecordInfo(PlayDataManager __instance, int playerId, int charaIndex, int uniqueId, EnsoData.EnsoLevelType levelType, bool isSinuchi, DataConst.SpecialTypes spTypes, HiScoreRecordInfo record, + DataConst.ResultType resultType, bool savemode, DataConst.CrownType crownType) + { + if (!uniqueIdToSong.ContainsKey(uniqueId)) + return true; + + int num = (int) levelType; + if (num is < 0 or >= 5) + num = 0; + + var saveData = GetCustomSaveData().CustomTrackToEnsoRecordInfo; + if (!saveData.TryGetValue(uniqueId, out var ensoData)) + { + ensoData = new EnsoRecordInfo[(int) EnsoData.EnsoLevelType.Num]; + saveData[uniqueId] = ensoData; + } + + EnsoRecordInfo ensoRecordInfo = ensoData[(int) levelType]; +#pragma warning disable Harmony003 + if (ensoRecordInfo.normalHiScore.score <= record.score) + { + ensoRecordInfo.normalHiScore.score = record.score; + ensoRecordInfo.normalHiScore.combo = record.combo; + ensoRecordInfo.normalHiScore.excellent = record.excellent; + ensoRecordInfo.normalHiScore.good = record.good; + ensoRecordInfo.normalHiScore.bad = record.bad; + ensoRecordInfo.normalHiScore.renda = record.renda; + } +#pragma warning restore Harmony003 + + if (crownType != DataConst.CrownType.Off) + { + if (IsValueInRange((int) crownType, 0, 5) && ensoRecordInfo.crown <= crownType) + { + ensoRecordInfo.crown = crownType; + ensoRecordInfo.cleared = crownType >= DataConst.CrownType.Silver; + } + } + + ensoData[(int) levelType] = ensoRecordInfo; + + if (savemode && playerId == 0) + SaveCustomData(); + + return false; + + bool IsValueInRange(int myValue, int minValue, int maxValue) + { + if (myValue >= minValue && myValue < maxValue) + return true; + return false; + } + } + + [HarmonyPatch(typeof(SongSelectManager), "Start")] + [HarmonyPostfix] + public static void Start_Postfix(SongSelectManager __instance) + { + Plugin.Instance.StartCustomCoroutine(SetSelectedSongAsync()); + + IEnumerator SetSelectedSongAsync() + { + while (__instance.SongList.Count == 0 || (bool) typeof(SongSelectManager).GetField("isAsyncLoading", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance)) + yield return null; + + // if the song id is < 0 then fix the selected song index + var ensoMode = (EnsoMode) typeof(SongSelectManager).GetField("ensoMode", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); + var lastPlaySongId = ensoMode.songUniqueId; + + var songIndex = __instance.SongList.IndexOf(__instance.SongList.FirstOrDefault(song => song.UniqueId == lastPlaySongId)); + if (songIndex < 0) + yield break; + + typeof(SongSelectManager).GetProperty("SelectedSongIndex").SetValue(__instance, songIndex); + __instance.SortSongList(ensoMode.songSortCourse, ensoMode.songSortType, ensoMode.songFilterType, ensoMode.songFilterTypeFavorite); + } + } + + /// + /// Allow for a song id > 400 + /// + [HarmonyPatch(typeof(EnsoMode), "IsValid")] + [HarmonyPrefix] + public static bool IsValid_Prefix(ref bool __result, EnsoMode __instance) + { +#pragma warning disable Harmony003 + __result = Validate(); + return false; + bool Validate() + { + // commented out this code + // if (songUniqueId < DataConst.InvalidId || songUniqueId > DataConst.MusicMax) + // { + // return false; + // } + if (!Enum.IsDefined(typeof(EnsoData.SongGenre), __instance.listGenre)) + { + return false; + } + + if (__instance.neiro < 0 || __instance.neiro > DataConst.NeiroMax) + { + return false; + } + + if (!Enum.IsDefined(typeof(EnsoData.EnsoLevelType), __instance.level)) + { + return false; + } + + if (!Enum.IsDefined(typeof(DataConst.SpeedTypes), __instance.speed)) + { + return false; + } + + if (!Enum.IsDefined(typeof(DataConst.OptionOnOff), __instance.dron)) + { + return false; + } + + if (!Enum.IsDefined(typeof(DataConst.OptionOnOff), __instance.reverse)) + { + return false; + } + + if (!Enum.IsDefined(typeof(DataConst.RandomLevel), __instance.randomlv)) + { + return false; + } + + if (!Enum.IsDefined(typeof(DataConst.SpecialTypes), __instance.special)) + { + return false; + } + + if (!Enum.IsDefined(typeof(DataConst.SongSortType), __instance.songSortType)) + { + return false; + } + + if (!Enum.IsDefined(typeof(DataConst.SongSortCourse), __instance.songSortCourse)) + { + return false; + } + + if (!Enum.IsDefined(typeof(DataConst.SongFilterType), __instance.songFilterType)) + { + return false; + } + + if (!Enum.IsDefined(typeof(DataConst.SongFilterTypeFavorite), __instance.songFilterTypeFavorite)) + { + return false; + } + + return true; + } +#pragma warning restore Harmony003 + } + + /// + /// Allow for a song id less than 0 + /// + [HarmonyPatch(typeof(EnsoDataManager), "DecideSetting")] + [HarmonyPrefix] + public static bool DecideSetting_Prefix(EnsoDataManager __instance) + { + var ensoSettings = (EnsoData.Settings) typeof(EnsoDataManager).GetField("ensoSettings", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); + // if (ensoSettings.musicuid.Length <= 0) + // { + // MusicDataInterface.MusicInfoAccesser infoByUniqueId = TaikoSingletonMonoBehaviour.Instance.MyDataManager.MusicData.GetInfoByUniqueId(ensoSettings.musicUniqueId); + // if (infoByUniqueId != null) + // { + // ensoSettings.musicuid = infoByUniqueId.Id; + // } + // } + // else if (ensoSettings.musicUniqueId <= DataConst.InvalidId) + // { + // MusicDataInterface.MusicInfoAccesser infoById = TaikoSingletonMonoBehaviour.Instance.MyDataManager.MusicData.GetInfoById(ensoSettings.musicuid); + // if (infoById != null) + // { + // ensoSettings.musicUniqueId = infoById.UniqueId; + // } + // } + if (ensoSettings.musicuid.Length <= 0 /* || ensoSettings.musicUniqueId <= DataConst.InvalidId*/) + { + List musicInfoAccessers = TaikoSingletonMonoBehaviour.Instance.MyDataManager.MusicData.musicInfoAccessers; + for (int i = 0; i < musicInfoAccessers.Count; i++) + { + if (!musicInfoAccessers[i].Debug) + { + ensoSettings.musicuid = musicInfoAccessers[i].Id; + ensoSettings.musicUniqueId = musicInfoAccessers[i].UniqueId; + } + } + } + + MusicDataInterface.MusicInfoAccesser infoByUniqueId2 = TaikoSingletonMonoBehaviour.Instance.MyDataManager.MusicData.GetInfoByUniqueId(ensoSettings.musicUniqueId); + if (infoByUniqueId2 != null) + { + ensoSettings.songFilePath = infoByUniqueId2.SongFileName; + } + + __instance.DecidePartsSetting(); + if (ensoSettings.ensoType == EnsoData.EnsoType.Normal) + { + int num = 0; + int dlcType = 2; + if (ensoSettings.rankMatchType == EnsoData.RankMatchType.None) + { + num = ((ensoSettings.playerNum != 1) ? 1 : 0); + } + else if (ensoSettings.rankMatchType == EnsoData.RankMatchType.RankMatch) + { + num = 2; + ensoSettings.isRandomSelect = false; + ensoSettings.isDailyBonus = false; + } + else + { + num = 3; + ensoSettings.isRandomSelect = false; + ensoSettings.isDailyBonus = false; + } + + TaikoSingletonMonoBehaviour.Instance.CosmosLib._kpiListCommon._musicKpiInfo.SetMusicSortSettings(num, dlcType, ensoSettings.isRandomSelect, ensoSettings.isDailyBonus); + } + else + { + ensoSettings.isRandomSelect = false; + ensoSettings.isDailyBonus = false; + } + + typeof(EnsoDataManager).GetField("ensoSettings", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(__instance, ensoSettings); + return false; + } + + #endregion + + #region Read Fumen + + private static readonly Regex fumenFilePathRegex = new Regex("(?.*?)_(?[ehmnx])(_(?[12]))?.bin"); + + private static readonly Dictionary playerToFumenData = new Dictionary(); + + /// + /// Read unencrypted Fumen files, save them to + /// + /// + private static unsafe bool Read_Prefix(string filePath, ref bool __result, object __instance) + { + var type = typeof(FumenLoader).GetNestedType("PlayerData", BindingFlags.NonPublic); + + if (File.Exists(filePath)) + return true; + + // if the file doesn't exist, perhaps it's a custom song? + var fileName = Path.GetFileName(filePath); + var match = fumenFilePathRegex.Match(fileName); + if (!match.Success) + { + Log.LogError($"Cannot interpret {fileName}"); + return true; + } + + // get song id + var songId = match.Groups["songID"].Value; + var difficulty = match.Groups["difficulty"].Value; + var songIndex = match.Groups["songIndex"].Value; + + if (!idToSong.TryGetValue(songId, out var songInstance)) + { + Log.LogError($"Cannot find song with id: {songId}"); + return true; + } + + var path = songInstance.FolderPath; + var songName = songInstance.SongName; + + var files = Directory.GetFiles(path, "*.bin"); + if (files.Length == 0) + { + Log.LogError($"Cannot find fumen at {path}"); + return true; + } + + var newPath = GetPathOfBestFumen(); + if (!File.Exists(newPath)) + { + Log.LogError($"Cannot find fumen for {newPath}"); + return true; + } + + type.GetMethod("Dispose").Invoke(__instance, new object[] { }); + type.GetField("fumenPath").SetValue(__instance, newPath); + + byte[] array = File.ReadAllBytes(newPath); + if (songInstance.AreFilesGZipped) + { + using var memoryStream = new MemoryStream(array); + using var destination = new MemoryStream(); + using var gzipStream = new GZipStream(memoryStream, CompressionMode.Decompress); + gzipStream.CopyTo(destination); + array = destination.ToArray(); + } + + var fumenSize = array.Length; + type.GetField("fumenSize").SetValue(__instance, fumenSize); + + var fumenData = UnsafeUtility.Malloc(fumenSize, 16, Allocator.Persistent); + type.GetField("fumenData").SetValue(__instance, (IntPtr) fumenData); + + Marshal.Copy(array, 0, (IntPtr) fumenData, fumenSize); + + type.GetField("isReadEnd").SetValue(__instance, true); + type.GetField("isReadSucceed").SetValue(__instance, true); + __result = true; + + playerToFumenData[__instance] = (IntPtr) fumenData; + return false; + + string GetPathOfBestFumen() + { + var baseSongPath = Path.Combine(path, $"{songName}"); + var withDifficulty = baseSongPath + $"_{difficulty}"; + var withSongIndex = withDifficulty + (string.IsNullOrWhiteSpace(songIndex) ? "" : $"_{songIndex}"); + + var testPath = withSongIndex + ".bin"; + if (File.Exists(testPath)) + return testPath; + + testPath = withDifficulty + ".bin"; + if (File.Exists(testPath)) + return testPath; + + // add every difficulty below this one + Difficulty difficultyEnum = (Difficulty) Enum.Parse(typeof(Difficulty), difficulty); + int difficultyInt = (int) difficultyEnum; + + var checkDifficulties = new List(); + + for (int i = 1; i < (int) Difficulty.Count; i++) + { + AddIfInRange(difficultyInt - i); + AddIfInRange(difficultyInt + i); + + void AddIfInRange(int checkDifficulty) + { + if (checkDifficulty is >= 0 and < (int) Difficulty.Count) + checkDifficulties.Add((Difficulty) checkDifficulty); + } + } + + foreach (var testDifficulty in checkDifficulties) + { + withDifficulty = baseSongPath + $"_{testDifficulty.ToString()}"; + testPath = withDifficulty + ".bin"; + if (File.Exists(testPath)) + return testPath; + testPath = withDifficulty + "_1.bin"; + if (File.Exists(testPath)) + return testPath; + testPath = withDifficulty + "_2.bin"; + if (File.Exists(testPath)) + return testPath; + } + + // uh... can't find it? + return string.Empty; + } + } + + private enum Difficulty + { + e, + h, + m, + n, + x, + Count, + } + + private static Difficulty[] AllDifficulties = (Difficulty[]) Enum.GetValues(typeof(Difficulty)); + + /// + /// When asking to get a Fumen, used the ones we stored above + /// + [HarmonyPatch(typeof(FumenLoader), "GetFumenData")] + [HarmonyPrefix] + public static unsafe bool GetFumenData_Prefix(int player, ref void* __result, FumenLoader __instance) + { + var settings = (EnsoData.Settings) typeof(FumenLoader).GetField("settings", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); + var playerData = (Array) typeof(FumenLoader).GetField("playerData", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); + + if (player >= 0 && player < settings.playerNum) + { + if (playerToFumenData.TryGetValue(playerData.GetValue(player), out var data)) + { + __result = (void*) data; + return false; + } + } + + // try loading the actual data + return true; + } + + #endregion + + #region Read Song + + private static readonly Regex musicFilePathRegex = new Regex("^song_(?.*?)$"); + + /// + /// Read an unencrypted song "asynchronously" (it does it instantly, we should have fast enough PCs right?) + /// + /// + [HarmonyPatch(typeof(CriPlayer), "LoadAsync")] + [HarmonyPostfix] + public static void LoadAsync_Postfix(CriPlayer __instance) + { + // Run this on the next frame + Plugin.Instance.StartCustomCoroutine(LoadAsync()); + + IEnumerator LoadAsync() + { + yield return null; + var sheetName = __instance.CueSheetName; + var path = Application.streamingAssetsPath + "/sound/" + sheetName + ".bin"; + + if (File.Exists(path)) + yield break; + + typeof(CriPlayer).GetField("isLoadingAsync", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(__instance, true); + typeof(CriPlayer).GetField("isCancelLoadingAsync", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(__instance, false); + typeof(CriPlayer).GetProperty("IsPrepared").SetValue(__instance, false); + typeof(CriPlayer).GetProperty("IsLoadSucceed").SetValue(__instance, false); + typeof(CriPlayer).GetProperty("LoadingState").SetValue(__instance, CriPlayer.LoadingStates.Loading); + typeof(CriPlayer).GetProperty("LoadTime").SetValue(__instance, -1f); + typeof(CriPlayer).GetField("loadStartTime", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(__instance, Time.time); + + var match = musicFilePathRegex.Match(sheetName); + if (!match.Success) + { + Log.LogError($"Cannot interpret {sheetName}"); + yield break; + } + + var songName = match.Groups["songName"].Value; + if (!idToSong.TryGetValue(songName, out var songInstance)) + { + Log.LogError($"Cannot find song : {songName}"); + yield break; + } + + var newPath = Path.Combine(songInstance.FolderPath, $"{sheetName.Replace(songName, songInstance.SongName)}.bin"); + + var bytes = File.ReadAllBytes(newPath); + if (songInstance.AreFilesGZipped) + { + using var memoryStream = new MemoryStream(bytes); + using var destination = new MemoryStream(); + using var gzipStream = new GZipStream(memoryStream, CompressionMode.Decompress); + gzipStream.CopyTo(destination); + bytes = destination.ToArray(); + } + + var cueSheet = CriAtom.AddCueSheetAsync(sheetName, bytes, null); + typeof(CriPlayer).GetProperty("CueSheet").SetValue(__instance, cueSheet); + + if (cueSheet != null) + { + typeof(CriPlayer).GetField("isLoadingAsync", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(__instance, false); + typeof(CriPlayer).GetProperty("IsLoadSucceed").SetValue(__instance, true); + + typeof(CriPlayer).GetProperty("LoadingState").SetValue(__instance, CriPlayer.LoadingStates.Finished); + typeof(CriPlayer).GetProperty("LoadTime").SetValue(__instance, 0); + yield break; + } + + Log.LogError($"Could not load music"); + typeof(CriPlayer).GetProperty("LoadingState").SetValue(__instance, CriPlayer.LoadingStates.Finished); + typeof(CriPlayer).GetField("isLoadingAsync", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(__instance, false); + } + } + + /// + /// Read an unencrypted song + /// + [HarmonyPatch(typeof(CriPlayer), "Load")] + [HarmonyPrefix] + private static bool Load_Prefix(ref bool __result, CriPlayer __instance) + { + var sheetName = __instance.CueSheetName; + var path = Application.streamingAssetsPath + "/sound/" + sheetName + ".bin"; + + if (File.Exists(path)) + return true; + + var match = musicFilePathRegex.Match(sheetName); + if (!match.Success) + { + Log.LogError($"Cannot interpret {sheetName}"); + return true; + } + + var songName = match.Groups["songName"].Value; + + if (!idToSong.TryGetValue(songName, out var songInstance)) + { + Log.LogError($"Cannot find song : {songName}"); + return true; + } + + var newPath = Path.Combine(songInstance.FolderPath, $"{sheetName.Replace(songName, songInstance.SongName)}.bin"); + + // load custom song + typeof(CriPlayer).GetProperty("IsPrepared").SetValue(__instance, false); + typeof(CriPlayer).GetProperty("LoadingState").SetValue(__instance, CriPlayer.LoadingStates.Loading); + typeof(CriPlayer).GetProperty("IsLoadSucceed").SetValue(__instance, false); + typeof(CriPlayer).GetProperty("LoadTime").SetValue(__instance, -1f); + typeof(CriPlayer).GetField("loadStartTime", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(__instance, Time.time); + + if (sheetName == "") + { + typeof(CriPlayer).GetProperty("LoadingState").SetValue(__instance, CriPlayer.LoadingStates.Finished); + __result = false; + return false; + } + + var bytes = File.ReadAllBytes(newPath); + if (songInstance.AreFilesGZipped) + { + using var memoryStream = new MemoryStream(bytes); + using var destination = new MemoryStream(); + using var gzipStream = new GZipStream(memoryStream, CompressionMode.Decompress); + gzipStream.CopyTo(destination); + bytes = destination.ToArray(); + } + + var cueSheet = CriAtom.AddCueSheetAsync(sheetName, bytes, null); + typeof(CriPlayer).GetProperty("CueSheet").SetValue(__instance, cueSheet); + + if (cueSheet != null) + { + __result = true; + return false; + } + + typeof(CriPlayer).GetProperty("LoadingState").SetValue(__instance, CriPlayer.LoadingStates.Finished); + __result = false; + return false; + } + + #endregion + + #region Data Structures + + [Serializable] + public class CustomMusicSaveDataBody + { + public Dictionary CustomTrackToMusicInfoEx = new(); + public Dictionary CustomTrackToEnsoRecordInfo = new(); + } + + /// + /// This acts as a wrapper for the taiko save data formatting to decrease file size + /// + [Serializable] + public class CustomMusicSaveDataBodySerializable + { + [JsonProperty("m")] public Dictionary CustomTrackToMusicInfoEx = new(); + [JsonProperty("r")] public Dictionary CustomTrackToEnsoRecordInfo = new(); + + + public static explicit operator CustomMusicSaveDataBodySerializable(CustomMusicSaveDataBody m) + { + var result = new CustomMusicSaveDataBodySerializable(); + foreach (var musicInfoEx in m.CustomTrackToMusicInfoEx) + result.CustomTrackToMusicInfoEx[musicInfoEx.Key] = musicInfoEx.Value; + foreach (var ensoRecord in m.CustomTrackToEnsoRecordInfo) + { + var array = new EnsoRecordInfoSerializable[ensoRecord.Value.Length]; + for (var i = 0; i < ensoRecord.Value.Length; i++) + array[i] = ensoRecord.Value[i]; + result.CustomTrackToEnsoRecordInfo[ensoRecord.Key] = array; + } + + return result; + } + + public static explicit operator CustomMusicSaveDataBody(CustomMusicSaveDataBodySerializable m) + { + var result = new CustomMusicSaveDataBody(); + foreach (var musicInfoEx in m.CustomTrackToMusicInfoEx) + result.CustomTrackToMusicInfoEx[musicInfoEx.Key] = musicInfoEx.Value; + foreach (var ensoRecord in m.CustomTrackToEnsoRecordInfo) + { + var array = new EnsoRecordInfo[ensoRecord.Value.Length]; + for (var i = 0; i < ensoRecord.Value.Length; i++) + array[i] = ensoRecord.Value[i]; + result.CustomTrackToEnsoRecordInfo[ensoRecord.Key] = array; + } + + return result; + } + + + [Serializable] + public class MusicInfoExSerializable + { + [JsonProperty("f", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool favorite; + + [JsonProperty("favorite")] + private bool favorite_v0 + { + set => favorite = value; + } + + [JsonProperty("n", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool isNew; + + [JsonProperty("isNew")] + private bool isNew_v0 + { + set => favorite = value; + } + + public static implicit operator MusicInfoEx(MusicInfoExSerializable m) => new() + { + favorite = m.favorite, + isNew = m.isNew, + }; + + public static implicit operator MusicInfoExSerializable(MusicInfoEx m) => new() + { + favorite = m.favorite, + isNew = m.isNew, + }; + } + + [Serializable] + public class EnsoRecordInfoSerializable + { + [JsonProperty("h", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public HiScoreRecordInfoSerializable normalHiScore; + + [JsonProperty("normalHiScore", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + private HiScoreRecordInfoSerializable normalHiScore_v0 + { + set => normalHiScore = value; + } + + [JsonProperty("c", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public DataConst.CrownType crown; + + [JsonProperty("crown", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + private DataConst.CrownType crown_v0 + { + set => crown = value; + } + + [JsonProperty("p", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public int playCount; + + [JsonProperty("playCount", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + private int playCount_v0 + { + set => playCount = value; + } + + [JsonProperty("l", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool cleared; + + [JsonProperty("cleared", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + private bool cleared_v0 + { + set => cleared = value; + } + + [JsonProperty("g", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool allGood; + + [JsonProperty("allGood", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + private bool allGood_v0 + { + set => allGood = value; + } + + public static implicit operator EnsoRecordInfo(EnsoRecordInfoSerializable e) => new() + { + normalHiScore = e.normalHiScore, + crown = e.crown, + playCount = e.playCount, + cleared = e.cleared, + allGood = e.allGood, + }; + + public static implicit operator EnsoRecordInfoSerializable(EnsoRecordInfo e) => new() + { + normalHiScore = e.normalHiScore, + crown = e.crown, + playCount = e.playCount, + cleared = e.cleared, + allGood = e.allGood, + }; + + [Serializable] + public struct HiScoreRecordInfoSerializable + { + [JsonProperty("s", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public int score; + + [JsonProperty("score", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public int score_v0 + { + set => score = value; + } + + [JsonProperty("e", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public short excellent; + + [JsonProperty("excellent", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public short excellent_v0 + { + set => excellent = value; + } + + [JsonProperty("g", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public short good; + + [JsonProperty("good", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public short good_v0 + { + set => good = value; + } + + [JsonProperty("b", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public short bad; + + [JsonProperty("bad", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public short bad_v0 + { + set => bad = value; + } + + [JsonProperty("c", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public short combo; + + [JsonProperty("combo", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public short combo_v0 + { + set => combo = value; + } + + [JsonProperty("r", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public short renda; + + [JsonProperty("renda", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public short renda_v0 + { + set => renda = value; + } + + public static implicit operator HiScoreRecordInfo(HiScoreRecordInfoSerializable h) => new() + { + score = h.score, + excellent = h.excellent, + good = h.good, + bad = h.bad, + combo = h.combo, + renda = h.renda, + }; + + public static implicit operator HiScoreRecordInfoSerializable(HiScoreRecordInfo h) => new() + { + score = h.score, + excellent = h.excellent, + good = h.good, + bad = h.bad, + combo = h.combo, + renda = h.renda, + }; + } + } + } + + #endregion + + private class ConversionStatus + { + public static Regex ConversionResultRegex = new("(?-?\\d*)\\:(?.*?)$"); + + [JsonProperty("i")] public List Items = new(); + + public override string ToString() + { + return $"{nameof(Items)}: {string.Join(",", Items)}"; + } + + public class ConversionItem + { + [JsonIgnore] public const int CurrentVersion = 1; + [JsonIgnore] public const int MaxAttempts = 3; + + [JsonProperty("f")] public string FolderName; + [JsonProperty("a")] public int Attempts; + [JsonProperty("s")] public bool Successful; + [JsonProperty("v")] public int Version = CurrentVersion; + + public override string ToString() + { + return $"{nameof(FolderName)}: {FolderName}, {nameof(Attempts)}: {Attempts}, {nameof(Successful)}: {Successful}, {nameof(Version)}: {Version}"; + } + } + } + + public class SongInstance : CustomSong + { + public string FolderPath; + public string SongName; + } +} diff --git a/NuGet.Config b/TakoTako/NuGet.Config similarity index 100% rename from NuGet.Config rename to TakoTako/NuGet.Config diff --git a/Plugin.cs b/TakoTako/Plugin.cs similarity index 62% rename from Plugin.cs rename to TakoTako/Plugin.cs index e43b8fe..04a3099 100644 --- a/Plugin.cs +++ b/TakoTako/Plugin.cs @@ -3,11 +3,11 @@ using System.Collections; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; -using FlutoTaikoMods; using HarmonyLib; using HarmonyLib.Tools; +using UnityEngine; -namespace TaikoMods +namespace TakoTako { [BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)] public class Plugin : BaseUnityPlugin @@ -16,60 +16,88 @@ namespace TaikoMods public ConfigEntry ConfigDisableScreenChangeOnFocus; public ConfigEntry ConfigFixSignInScreen; public ConfigEntry ConfigEnableCustomSongs; + public ConfigEntry ConfigSongDirectory; + public ConfigEntry ConfigSaveEnabled; public ConfigEntry ConfigSaveDirectory; - + public ConfigEntry ConfigDisableCustomDLCSongs; + public ConfigEntry ConfigOverrideDefaultSongLanguage; + public ConfigEntry ConfigApplyGenreOverride; + public static Plugin Instance; private Harmony _harmony; public static ManualLogSource Log; - + private void Awake() { Instance = this; Log = Logger; - + Logger.LogInfo($"Plugin {PluginInfo.PLUGIN_GUID} is loaded!"); - + SetupConfig(); - + SetupHarmony(); } private void SetupConfig() { var userFolder = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); - - ConfigFixSignInScreen = Config.Bind("General", - "FixSignInScreen", - true, - "When true this will apply the patch to fix signing into Xbox Live"); - - ConfigSkipSplashScreen = Config.Bind("General", - "SkipSplashScreen", - true, - "When true this will skip the intro"); - - ConfigDisableScreenChangeOnFocus = Config.Bind("General", - "DisableScreenChangeOnFocus", - false, - "When focusing this wont do anything jank, I thnk"); - + ConfigEnableCustomSongs = Config.Bind("CustomSongs", "EnableCustomSongs", true, "When true this will load custom mods"); - + ConfigSongDirectory = Config.Bind("CustomSongs", "SongDirectory", - $"{userFolder}/Documents/TaikoTheDrumMasterMods/customSongs", + $"{userFolder}/Documents/{typeof(Plugin).Namespace}/customSongs", "The directory where custom tracks are stored"); + ConfigSaveEnabled = Config.Bind("CustomSongs", + "SaveEnabled", + true, + "Should there be local saves? Disable this if you want to wipe modded saves with every load"); + ConfigSaveDirectory = Config.Bind("CustomSongs", "SaveDirectory", $"{userFolder}/Documents/TaikoTheDrumMasterMods/saves", "The directory where saves are stored"); + + ConfigDisableCustomDLCSongs = Config.Bind("CustomSongs", + "DisableCustomDLCSongs", + false, + "By default, DLC is enabled for custom songs, this is to reduce any hiccups when playing online with other people. " + + "Set this to true if you want DLC to be marked as false, be aware that the fact you're playing a custom song will be sent over the internet"); + + ConfigOverrideDefaultSongLanguage = Config.Bind("CustomSongs", + "ConfigOverrideDefaultSongLanguage", + string.Empty, + "Set this value to {Japanese, English, French, Italian, German, Spanish, ChineseTraditional, ChineseSimplified, Korean} " + + "to override all music tracks to a certain language, regardless of your applications language"); + + ConfigApplyGenreOverride = Config.Bind("CustomSongs", + "ConfigApplyGenreOverride", + true, + "Set this value to {01 Pop, 02 Anime, 03 Vocaloid, 04 Children and Folk, 05 Variety, 06 Classical, 07 Game Music, 08 Live Festival Mode, 08 Namco Original} " + + "to override all track's genre in a certain folder. This is useful for TJA files that do not have a genre"); + + ConfigFixSignInScreen = Config.Bind("General", + "FixSignInScreen", + true, + "When true this will apply the patch to fix signing into Xbox Live"); + + ConfigSkipSplashScreen = Config.Bind("General", + "SkipSplashScreen", + true, + "When true this will skip the intro"); + + ConfigDisableScreenChangeOnFocus = Config.Bind("General", + "DisableScreenChangeOnFocus", + false, + "When focusing this wont do anything jank, I thnk"); } - + private void SetupHarmony() { // Patch methods @@ -77,13 +105,13 @@ namespace TaikoMods if (ConfigSkipSplashScreen.Value) _harmony.PatchAll(typeof(SkipSplashScreen)); - + if (ConfigFixSignInScreen.Value) _harmony.PatchAll(typeof(SignInPatch)); - + if (ConfigDisableScreenChangeOnFocus.Value) _harmony.PatchAll(typeof(DisableScreenChangeOnFocus)); - + if (ConfigEnableCustomSongs.Value) { _harmony.PatchAll(typeof(MusicPatch)); diff --git a/TakoTako/References/Newtonsoft.Json.dll b/TakoTako/References/Newtonsoft.Json.dll new file mode 100644 index 0000000000000000000000000000000000000000..0657dba04c2af9987b19bf09d1dcd0a53a54fdaa GIT binary patch literal 254464 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 /// This patch will address the issue where signing with GDK is done correctly @@ -13,14 +11,10 @@ namespace FlutoTaikoMods; [HarmonyPatch("SignIn")] public static class SignInPatch { - + // ReSharper disable once InconsistentNaming private static bool Prefix(GdkHelpers __instance) { - // Only apply this patch if we're on version 1.0.0 - if (Application.version != "1.0.0") - return false; - Plugin.Log.LogInfo("Patching sign in to force the user to be prompted to sign in"); var methodInfo = typeof(GdkHelpers).GetMethod("SignInImpl", BindingFlags.NonPublic | BindingFlags.Instance); if (methodInfo == null) @@ -32,4 +26,4 @@ public static class SignInPatch methodInfo.Invoke(__instance, new object[] {true}); return false; } -} \ No newline at end of file +} diff --git a/SkipSplashScreen.cs b/TakoTako/SkipSplashScreen.cs similarity index 96% rename from SkipSplashScreen.cs rename to TakoTako/SkipSplashScreen.cs index 66eed61..d8d93f4 100644 --- a/SkipSplashScreen.cs +++ b/TakoTako/SkipSplashScreen.cs @@ -1,7 +1,7 @@ using System.Diagnostics.CodeAnalysis; using HarmonyLib; -namespace TaikoMods; +namespace TakoTako; [HarmonyPatch] [SuppressMessage("ReSharper", "InconsistentNaming")] diff --git a/TakoTako/TakoTako.csproj b/TakoTako/TakoTako.csproj new file mode 100644 index 0000000..8233088 --- /dev/null +++ b/TakoTako/TakoTako.csproj @@ -0,0 +1,72 @@ + + + + net48 + com.fluto.takotako + Fixes Taiko issues and allows custom songs + 0.0.1 + true + latest + TakoTako + com.fluto.takotako + 2.0.0 + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + D:\XboxGames\T Tablet\Content\Taiko no Tatsujin_Data\Managed\Assembly-CSharp.dll + True + + + D:\XboxGames\T Tablet\Content\Taiko no Tatsujin_Data\Managed\Assembly-CSharp-firstpass.dll + True + + + References\Newtonsoft.Json.dll + + + ..\TakoTakoScripts\TakoTako.Common\bin\Debug\net48\TakoTako.Common.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TakoTakoScripts/.gitignore b/TakoTakoScripts/.gitignore new file mode 100644 index 0000000..9d3e8b0 --- /dev/null +++ b/TakoTakoScripts/.gitignore @@ -0,0 +1,35 @@ +# Common IntelliJ Platform excludes + +# User specific +**/.idea/**/workspace.xml +**/.idea/**/tasks.xml +**/.idea/shelf/* +**/.idea/dictionaries +**/.idea/httpRequests/ + +# Sensitive or high-churn files +**/.idea/**/dataSources/ +**/.idea/**/dataSources.ids +**/.idea/**/dataSources.xml +**/.idea/**/dataSources.local.xml +**/.idea/**/sqlDataSources.xml +**/.idea/**/dynamic.xml + +# Rider +# Rider auto-generates .iml files, and contentModel.xml +**/.idea/**/*.iml +**/.idea/**/contentModel.xml +**/.idea/**/modules.xml + +*.suo +*.user +.vs/ +[Bb]in/ +[Oo]bj/ +_UpgradeReport_Files/ +[Pp]ackages/ + +Thumbs.db +Desktop.ini +.DS_Store +ShortcutFolder.lnk diff --git a/TakoTakoScripts/.idea/.idea.TakoTakoScripts/.idea/.gitignore b/TakoTakoScripts/.idea/.idea.TakoTakoScripts/.idea/.gitignore new file mode 100644 index 0000000..bd4c181 --- /dev/null +++ b/TakoTakoScripts/.idea/.idea.TakoTakoScripts/.idea/.gitignore @@ -0,0 +1,13 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/modules.xml +/.idea.TakoTakoScripts.iml +/projectSettingsUpdater.xml +/contentModel.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/TakoTakoScripts/.idea/.idea.TakoTakoScripts/.idea/encodings.xml b/TakoTakoScripts/.idea/.idea.TakoTakoScripts/.idea/encodings.xml new file mode 100644 index 0000000..df87cf9 --- /dev/null +++ b/TakoTakoScripts/.idea/.idea.TakoTakoScripts/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/TakoTakoScripts/.idea/.idea.TakoTakoScripts/.idea/indexLayout.xml b/TakoTakoScripts/.idea/.idea.TakoTakoScripts/.idea/indexLayout.xml new file mode 100644 index 0000000..7b08163 --- /dev/null +++ b/TakoTakoScripts/.idea/.idea.TakoTakoScripts/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/TakoTakoScripts/.idea/.idea.TakoTakoScripts/.idea/vcs.xml b/TakoTakoScripts/.idea/.idea.TakoTakoScripts/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/TakoTakoScripts/.idea/.idea.TakoTakoScripts/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/TakoTakoScripts/TJAConvert/Files.cs b/TakoTakoScripts/TJAConvert/Files.cs new file mode 100644 index 0000000..6a49f39 --- /dev/null +++ b/TakoTakoScripts/TJAConvert/Files.cs @@ -0,0 +1,133 @@ +namespace TJAConvert +{ + public class Files + { + public static byte[] TemplateACBData = + { + 0x1F, 0x8B, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xED, 0x58, 0x7D, 0x6C, 0x14, 0xC7, + 0x15, 0x7F, 0x7B, 0xE7, 0xE0, 0x60, 0xC0, 0x04, 0xDA, 0x40, 0x2A, 0x6A, 0x62, 0x92, 0x26, 0x10, + 0x04, 0xC4, 0x76, 0x02, 0x05, 0xDB, 0x15, 0x3E, 0xFC, 0x85, 0x8D, 0x4D, 0x4E, 0x77, 0xC6, 0x04, + 0x68, 0x80, 0xF5, 0xEE, 0xD8, 0xB7, 0x61, 0x6F, 0xF7, 0xBA, 0xBB, 0x67, 0xB8, 0x04, 0x52, 0x5A, + 0xB5, 0x46, 0x6D, 0x49, 0xA9, 0xA2, 0x82, 0xF2, 0x17, 0x41, 0x6A, 0x50, 0xDA, 0x24, 0x82, 0xA4, + 0x0D, 0x52, 0x93, 0xB4, 0xA5, 0x2D, 0x85, 0xAA, 0x1F, 0x81, 0xAA, 0x9F, 0x91, 0x50, 0x52, 0x50, + 0x2A, 0x25, 0x52, 0x55, 0x3E, 0xDA, 0x2A, 0x4A, 0x93, 0x34, 0xD7, 0xF7, 0x9B, 0xDD, 0xBB, 0x5B, + 0x9F, 0xCD, 0x91, 0x56, 0xEA, 0x3F, 0x55, 0x47, 0xBA, 0xDF, 0xBC, 0x99, 0x37, 0xF3, 0x66, 0xE6, + 0xBD, 0x37, 0xEF, 0xCD, 0x5E, 0xDB, 0x86, 0x81, 0x2E, 0xA2, 0xD9, 0xEF, 0x10, 0x29, 0xF7, 0x13, + 0x45, 0x4E, 0x13, 0x4D, 0xD9, 0x45, 0x28, 0x6D, 0x4A, 0x9A, 0x51, 0x19, 0x60, 0xA8, 0x06, 0xCC, + 0x01, 0xCC, 0x8B, 0x33, 0xDC, 0x0E, 0x58, 0xB4, 0x85, 0xE1, 0x6E, 0x50, 0xCD, 0xA0, 0xFA, 0x00, + 0x1B, 0x00, 0x43, 0x80, 0x0C, 0xE0, 0x61, 0xC0, 0x18, 0xE0, 0x08, 0xE0, 0x38, 0xE0, 0x25, 0xC0, + 0xCF, 0x01, 0xBF, 0x03, 0xBC, 0x01, 0xF8, 0x07, 0x83, 0x32, 0x03, 0xB0, 0x60, 0x33, 0xC3, 0x5D, + 0xA0, 0x3E, 0x99, 0x60, 0xE8, 0x01, 0x6C, 0x45, 0xD3, 0x05, 0x40, 0x9E, 0xF2, 0x25, 0xDE, 0xA5, + 0x72, 0x18, 0xD4, 0x37, 0x01, 0x2F, 0x02, 0x20, 0x4F, 0x79, 0x0D, 0x73, 0xDF, 0xE2, 0x0D, 0x29, + 0x7F, 0xE1, 0x66, 0x24, 0x0A, 0xA8, 0x05, 0xDC, 0x0A, 0x68, 0x04, 0xF4, 0x31, 0x37, 0xB2, 0x95, + 0x85, 0x46, 0x2C, 0x34, 0x1F, 0x02, 0xEC, 0x07, 0x40, 0x5E, 0xE4, 0x18, 0xE0, 0x0C, 0xE0, 0x02, + 0xE0, 0x5D, 0x1E, 0x1C, 0xAD, 0x05, 0xCC, 0x06, 0xDC, 0xCC, 0x7D, 0xD1, 0x5B, 0x40, 0xE1, 0xF8, + 0xD1, 0x3B, 0x01, 0x77, 0x01, 0x96, 0x00, 0xA0, 0x88, 0x68, 0x13, 0x60, 0x39, 0xC6, 0xAD, 0x04, + 0x74, 0x00, 0x36, 0x50, 0x50, 0x94, 0x26, 0x85, 0x8A, 0xE5, 0x26, 0x40, 0x3D, 0xFF, 0x2E, 0x30, + 0x03, 0x34, 0xEB, 0x56, 0xD9, 0xCE, 0xF5, 0x5B, 0x74, 0xDD, 0x12, 0xE1, 0x71, 0x4A, 0x8A, 0x45, + 0xF3, 0x5C, 0xE2, 0xBA, 0x0A, 0xED, 0x4F, 0x10, 0xDD, 0x70, 0x84, 0x6B, 0xF3, 0xDA, 0xF3, 0xAA, + 0x79, 0xBD, 0xE8, 0x62, 0xFE, 0x19, 0xE3, 0xFB, 0x6B, 0xB6, 0xFB, 0x1B, 0xAA, 0xD9, 0x5B, 0xD8, + 0x18, 0xCA, 0xEA, 0xE5, 0x3F, 0x3E, 0xC0, 0x7D, 0x47, 0x60, 0xDA, 0x6B, 0xCB, 0x8C, 0xEE, 0x9F, + 0xA4, 0x73, 0x1A, 0xE0, 0x0B, 0xE5, 0xBD, 0xF9, 0x71, 0x43, 0x20, 0x77, 0x2D, 0xD1, 0x74, 0xAA, + 0x2C, 0x3F, 0x54, 0xA6, 0x6F, 0x0F, 0x6F, 0xEF, 0x1A, 0x65, 0xAD, 0x50, 0x75, 0xE1, 0x50, 0x97, + 0x61, 0x8A, 0x1E, 0x5D, 0x58, 0x9E, 0x31, 0x6C, 0x70, 0x33, 0x69, 0x3C, 0x24, 0x68, 0x50, 0x38, + 0xAE, 0x61, 0x5B, 0x34, 0x90, 0xCB, 0x08, 0x1A, 0x50, 0x9D, 0x11, 0xE1, 0x51, 0x4C, 0x1B, 0xEE, + 0xD7, 0x97, 0xAF, 0x55, 0xDD, 0x14, 0xB5, 0xAB, 0x9E, 0x18, 0xB1, 0x9D, 0x5C, 0xE7, 0x2E, 0x4F, + 0x58, 0x72, 0x60, 0x7B, 0x56, 0x0C, 0xA8, 0x43, 0xA6, 0x00, 0xB1, 0x5E, 0x4D, 0x07, 0x8D, 0x8D, + 0xEA, 0xA8, 0x18, 0xB6, 0x9D, 0xB4, 0xDF, 0x8A, 0x19, 0xAE, 0xAA, 0xF9, 0x64, 0xB7, 0xA3, 0x66, + 0x52, 0x01, 0x69, 0xDA, 0x43, 0xAA, 0x29, 0x79, 0x09, 0x31, 0x2C, 0x1C, 0x61, 0x69, 0x22, 0x34, + 0xBE, 0x24, 0x2C, 0x99, 0xB3, 0xBC, 0x60, 0x4E, 0x52, 0x7C, 0xA6, 0xDD, 0x4E, 0xA7, 0x55, 0x4B, + 0xF7, 0xDB, 0x03, 0x8E, 0xAA, 0xED, 0x28, 0xB2, 0xB2, 0x65, 0x22, 0xDA, 0x6D, 0xCB, 0x73, 0x6C, + 0xB3, 0x24, 0x29, 0x96, 0xF5, 0xEC, 0x7E, 0x5B, 0xCF, 0x9A, 0xAA, 0xC7, 0x7B, 0x0F, 0xE6, 0x79, + 0x8E, 0x50, 0xD3, 0xB1, 0x9D, 0x43, 0x03, 0xB6, 0xB6, 0xD1, 0x76, 0x76, 0xDC, 0x67, 0xEA, 0xC4, + 0x2D, 0x28, 0xA7, 0xA0, 0x0D, 0x1E, 0x62, 0x58, 0x23, 0x38, 0x61, 0x9F, 0x91, 0x36, 0x3C, 0x8C, + 0xF2, 0xE7, 0xAE, 0xCF, 0xA6, 0x0B, 0x9D, 0x7D, 0x86, 0x2B, 0x19, 0x6E, 0xB8, 0x73, 0xBD, 0xAD, + 0x0B, 0xBF, 0x33, 0xA6, 0x0D, 0x75, 0x67, 0x0D, 0xBD, 0xB4, 0x9A, 0x54, 0x67, 0xF9, 0xDA, 0xDB, + 0xE4, 0xE2, 0xDA, 0xD0, 0xA0, 0x6D, 0x66, 0xD3, 0x72, 0x6B, 0xBC, 0xEE, 0xA0, 0x6A, 0x16, 0x74, + 0x7C, 0x5F, 0xD6, 0x73, 0x0D, 0x9D, 0x65, 0x5B, 0xC1, 0x06, 0xD6, 0x98, 0xB6, 0xB6, 0x63, 0xFC, + 0xC9, 0x65, 0x57, 0xB0, 0x3D, 0x3E, 0x38, 0xB5, 0xA7, 0x54, 0x56, 0x92, 0x27, 0x9C, 0x4E, 0x4B, + 0xB3, 0x75, 0x96, 0x27, 0x4D, 0xDB, 0x39, 0xCA, 0x76, 0x0F, 0x94, 0xA2, 0x49, 0x65, 0x94, 0x34, + 0xC9, 0xF6, 0x2E, 0x33, 0x48, 0xC1, 0x9C, 0x45, 0xB3, 0x77, 0xA8, 0x9E, 0x1A, 0x2C, 0x27, 0x54, + 0x8F, 0x0D, 0xA4, 0xF5, 0x58, 0xC3, 0x76, 0xD1, 0x11, 0xE2, 0x8E, 0x61, 0x3B, 0x86, 0x97, 0x93, + 0x4B, 0x85, 0xF4, 0xE1, 0xDB, 0x6B, 0x9C, 0x05, 0xA5, 0x71, 0x27, 0xDA, 0x34, 0xB4, 0x3F, 0x3E, + 0x5E, 0x9C, 0x8F, 0x90, 0x16, 0x7C, 0x86, 0xB8, 0x6A, 0x9A, 0xC2, 0x0B, 0x8D, 0x9B, 0x94, 0x23, + 0x65, 0x4E, 0xCE, 0xB1, 0xB3, 0x96, 0xDE, 0x2D, 0x2C, 0xE1, 0xA8, 0x9E, 0xED, 0xF8, 0x7D, 0x89, + 0xC6, 0x06, 0x4A, 0xAC, 0xA2, 0xC4, 0x4A, 0x8A, 0x3B, 0xF6, 0x83, 0x42, 0xF3, 0xD6, 0x89, 0x1C, + 0x25, 0x56, 0x50, 0x62, 0x39, 0x25, 0xEE, 0xA5, 0xC4, 0x3D, 0x94, 0x68, 0xE2, 0x31, 0x94, 0x68, + 0xA0, 0xB8, 0xAA, 0x43, 0x81, 0x31, 0x36, 0xDA, 0x04, 0xD3, 0x95, 0x3A, 0x62, 0xC3, 0x6E, 0x53, + 0x70, 0xC3, 0x6A, 0x62, 0xED, 0x6B, 0xEA, 0xBB, 0x58, 0x71, 0xAA, 0x77, 0x77, 0xBC, 0xBD, 0x9E, + 0xDD, 0x69, 0x59, 0xE3, 0xB2, 0x7B, 0x9A, 0x96, 0x35, 0x34, 0xD6, 0xAF, 0xC9, 0x1A, 0xA6, 0xDE, + 0x5C, 0x43, 0xAE, 0x6D, 0x8D, 0x6C, 0xF3, 0x44, 0x3A, 0xD3, 0x50, 0xF1, 0xCA, 0xEE, 0xE9, 0x58, + 0x73, 0xFB, 0xE3, 0x8F, 0x9E, 0x18, 0x7B, 0xF1, 0x58, 0xBA, 0xF9, 0xE2, 0x2F, 0xBC, 0xB1, 0x72, + 0x7E, 0x9B, 0xCC, 0x4F, 0xF4, 0x2A, 0xC7, 0xC9, 0x4E, 0xAE, 0x11, 0x05, 0x7E, 0x2F, 0x19, 0x53, + 0x69, 0x1E, 0x05, 0xF9, 0xA9, 0x0A, 0x69, 0xA8, 0x86, 0xE3, 0x3A, 0xDD, 0xC2, 0x49, 0x80, 0x16, + 0x82, 0x6A, 0x40, 0x66, 0x59, 0x05, 0x6E, 0x0F, 0xB8, 0x71, 0x80, 0x8E, 0x79, 0x51, 0x39, 0x3B, + 0x1B, 0x5A, 0xA2, 0xF5, 0x4F, 0x16, 0x29, 0x6C, 0x49, 0x18, 0xB8, 0x47, 0xA7, 0x92, 0x8B, 0xC0, + 0xC8, 0xC5, 0x56, 0x8F, 0xA5, 0x8B, 0x5D, 0xB4, 0xC1, 0x15, 0x0E, 0x7C, 0x84, 0xA4, 0xF7, 0x23, + 0xB0, 0x84, 0x2F, 0x64, 0xBF, 0x9A, 0xA1, 0x3E, 0x61, 0x8D, 0x78, 0x29, 0x38, 0x47, 0x19, 0xC7, + 0x0D, 0xC2, 0xD3, 0xA0, 0xE1, 0x1A, 0x43, 0x86, 0xC9, 0x5E, 0x14, 0x3A, 0x5F, 0x1F, 0x9F, 0xEF, + 0x36, 0xAE, 0x17, 0x51, 0x21, 0x20, 0x46, 0x68, 0x0A, 0xCE, 0x87, 0x03, 0xDD, 0x98, 0x08, 0x62, + 0xDF, 0xC7, 0xA8, 0x10, 0x8D, 0xC2, 0xB5, 0xBF, 0xB3, 0x6B, 0xE8, 0x3B, 0x90, 0x7F, 0x81, 0xE5, + 0xF7, 0x72, 0xFD, 0x69, 0xFE, 0xBD, 0x26, 0x19, 0x35, 0x34, 0x1B, 0xF2, 0x21, 0x7A, 0x2A, 0x94, + 0x73, 0x33, 0xA0, 0x1E, 0xB0, 0x18, 0xB0, 0x02, 0x8C, 0xD5, 0xD0, 0x5F, 0x1F, 0xA8, 0x8D, 0x00, + 0x91, 0xF0, 0x35, 0x17, 0xA1, 0x88, 0xF2, 0x6C, 0x07, 0xF4, 0x96, 0x97, 0xA5, 0x70, 0x8B, 0xA8, + 0x5F, 0xA4, 0x39, 0x86, 0xB2, 0xAB, 0xB0, 0x1A, 0xE5, 0xAD, 0xF4, 0x75, 0xE8, 0x7B, 0x10, 0x22, + 0x0D, 0xAE, 0x4C, 0x4A, 0xB5, 0x2C, 0x61, 0xBA, 0xD4, 0x67, 0xDB, 0x99, 0x2E, 0x53, 0x1D, 0xA1, + 0xA4, 0x9A, 0xCE, 0x98, 0xCC, 0x4D, 0x70, 0x0C, 0xC6, 0x08, 0xD9, 0x16, 0x2E, 0x8D, 0xBB, 0x94, + 0x25, 0x37, 0x8C, 0xDB, 0x0E, 0xC7, 0x9F, 0x52, 0xBB, 0x47, 0xAF, 0xE4, 0x5F, 0xFE, 0xF9, 0x39, + 0xB9, 0x2A, 0xB4, 0x89, 0x9B, 0xEC, 0x5F, 0xCA, 0x16, 0xC9, 0x98, 0x41, 0x4B, 0x71, 0x7E, 0x9C, + 0x75, 0x0A, 0x94, 0x3C, 0x0D, 0x87, 0xC3, 0x5B, 0x81, 0x96, 0x00, 0x5A, 0xD0, 0xEC, 0x06, 0x3C, + 0x00, 0xC8, 0x00, 0x3E, 0x07, 0xC6, 0x63, 0xA0, 0x0E, 0x03, 0x8E, 0x01, 0x7E, 0x02, 0x59, 0xBF, + 0x2D, 0x2E, 0x57, 0x55, 0x20, 0xF2, 0xE3, 0x12, 0x1E, 0xDA, 0xE8, 0x91, 0x17, 0xD8, 0xCF, 0x41, + 0x83, 0xB6, 0xA1, 0xF9, 0xC1, 0xA3, 0xDB, 0xB1, 0xB3, 0x19, 0xDF, 0x98, 0x7E, 0xB8, 0xF0, 0x0D, + 0x5A, 0xF2, 0x3C, 0xB6, 0x2A, 0xD4, 0xA5, 0x05, 0x49, 0xC5, 0x0D, 0x67, 0x98, 0xA4, 0xA7, 0x3A, + 0x9E, 0x3F, 0x21, 0xD4, 0xCB, 0x5A, 0xE4, 0xE9, 0x2E, 0x05, 0xDE, 0x07, 0x67, 0xC5, 0xE5, 0x6E, + 0x2C, 0xEF, 0x68, 0xF2, 0x83, 0x8D, 0x8C, 0xC4, 0x2E, 0x95, 0x45, 0x96, 0x70, 0x00, 0x0D, 0x2D, + 0x03, 0xCF, 0x2E, 0x31, 0x5C, 0x0A, 0x9E, 0x30, 0x15, 0xF5, 0x4F, 0xD0, 0x7F, 0x1D, 0xD7, 0x77, + 0xF0, 0xEF, 0x53, 0x92, 0xA1, 0xD0, 0x8D, 0x14, 0x18, 0xA3, 0x90, 0xD6, 0x17, 0x14, 0x02, 0x7E, + 0xA0, 0x87, 0x82, 0x3E, 0x88, 0x62, 0xBE, 0x5E, 0x37, 0x46, 0xF8, 0xA5, 0xD4, 0x51, 0xB5, 0x7A, + 0x2F, 0xD3, 0x9D, 0x55, 0xED, 0xEF, 0x72, 0x65, 0x33, 0x67, 0x61, 0x85, 0x77, 0x41, 0x60, 0xFF, + 0x8F, 0xF3, 0x7A, 0x70, 0xE6, 0x51, 0x49, 0xA3, 0x4C, 0x97, 0xF7, 0x4D, 0xFA, 0xFF, 0x14, 0xC0, + 0x2C, 0xEC, 0x64, 0x3E, 0xA8, 0xC5, 0x80, 0x36, 0x40, 0x12, 0xDE, 0xA1, 0xC1, 0x3B, 0x2C, 0x4C, + 0xCE, 0x81, 0xFA, 0x3C, 0xFA, 0xBE, 0x06, 0xEE, 0xA1, 0xB0, 0x95, 0x41, 0xF9, 0xAD, 0x27, 0x7D, + 0x53, 0xD3, 0x51, 0x6E, 0x4B, 0x15, 0xF9, 0x39, 0xC9, 0x57, 0xDE, 0x38, 0x0B, 0xFF, 0x47, 0x26, + 0x2D, 0x37, 0x92, 0xFF, 0x96, 0x09, 0x3D, 0x6B, 0xA4, 0x27, 0xF9, 0x24, 0x5F, 0x0D, 0x9F, 0xE0, + 0xD4, 0x2B, 0xBB, 0x93, 0x9A, 0x5D, 0x1C, 0x27, 0xF7, 0xC6, 0x17, 0xA9, 0x72, 0x09, 0xF4, 0xA7, + 0xB3, 0xFE, 0xB6, 0x72, 0xF3, 0x2B, 0x4C, 0x0F, 0x49, 0x46, 0xAD, 0x7F, 0x7F, 0x64, 0xFC, 0x00, + 0xCC, 0x85, 0xFE, 0x16, 0x80, 0x92, 0xF7, 0x67, 0x15, 0xA8, 0x4E, 0xC0, 0x16, 0x80, 0x05, 0x78, + 0x04, 0xF0, 0x75, 0x70, 0x9F, 0x84, 0x12, 0x9F, 0x43, 0xF3, 0x04, 0xE0, 0x0C, 0xE9, 0x45, 0x27, + 0x8A, 0x94, 0xD6, 0xF6, 0x75, 0x5A, 0x7E, 0x93, 0x8A, 0x0F, 0x22, 0x8A, 0x9B, 0x6A, 0x6E, 0x88, + 0x0F, 0x91, 0xC0, 0xAB, 0x07, 0x7E, 0x19, 0x78, 0xA4, 0xAC, 0xFE, 0x5B, 0xFA, 0xFE, 0x70, 0x97, + 0x22, 0x7C, 0xAD, 0xA4, 0x6D, 0xAE, 0x7F, 0x13, 0x27, 0x2F, 0xB1, 0xAE, 0x64, 0x93, 0x12, 0x89, + 0x48, 0xF5, 0xD4, 0xCB, 0x9E, 0x39, 0xB4, 0x38, 0x5A, 0xE2, 0xAF, 0x6D, 0x8F, 0x41, 0x65, 0xDB, + 0x87, 0xD3, 0x1E, 0xD7, 0x1C, 0x95, 0x71, 0xB3, 0xF6, 0x46, 0xF7, 0x68, 0x76, 0x3A, 0x13, 0x79, + 0x5A, 0x99, 0xC9, 0x8D, 0xBD, 0x18, 0xA7, 0x19, 0x19, 0xFE, 0x58, 0xC8, 0xA8, 0x15, 0x83, 0xE5, + 0x84, 0x32, 0xEB, 0x4C, 0x3E, 0x5F, 0x37, 0xF7, 0xA6, 0xEA, 0x5C, 0x6E, 0xF3, 0xE6, 0xD6, 0xF9, + 0x57, 0x5A, 0x0F, 0x44, 0x7F, 0x76, 0x65, 0xF7, 0x63, 0xA7, 0x4E, 0x1C, 0x3A, 0x78, 0x68, 0x57, + 0x2A, 0x65, 0xF4, 0xB6, 0x2C, 0xBD, 0xDA, 0x7A, 0x2E, 0xFA, 0xCB, 0x2B, 0xEF, 0xFF, 0xE8, 0x37, + 0x2F, 0x1C, 0x3D, 0x78, 0x68, 0x6C, 0x1F, 0xF7, 0xF5, 0xB6, 0xD4, 0x5D, 0x6D, 0xFD, 0x63, 0xF4, + 0x95, 0xDA, 0x25, 0x2D, 0xBD, 0x9B, 0x52, 0xA9, 0xD1, 0xB1, 0x2F, 0x1E, 0xFC, 0xC6, 0xB7, 0x7F, + 0x78, 0xB9, 0xFA, 0xEC, 0xD5, 0xDD, 0x17, 0x7F, 0x7D, 0xEA, 0x05, 0x1E, 0xF4, 0xDE, 0xC9, 0x4B, + 0xFF, 0x7C, 0xF5, 0xD2, 0xBC, 0xCF, 0xFE, 0xF9, 0xE4, 0x13, 0xDA, 0xAD, 0x17, 0x8F, 0xBF, 0x71, + 0xA9, 0xE5, 0x83, 0x7B, 0x2F, 0x3F, 0xF2, 0xDE, 0x5F, 0xDF, 0x7E, 0x34, 0xBF, 0xCF, 0x3D, 0xB7, + 0xD4, 0x3D, 0xB7, 0xEF, 0xFC, 0xCE, 0x57, 0xDE, 0xAE, 0xDB, 0x33, 0xFA, 0x87, 0x99, 0x9B, 0x9E, + 0x3F, 0xFF, 0xD5, 0x07, 0x2E, 0xBF, 0xFE, 0xFD, 0xFC, 0xD9, 0x87, 0xF3, 0x07, 0x5E, 0xFA, 0xDB, + 0xA9, 0x15, 0x3F, 0xF8, 0xEE, 0xF3, 0x3B, 0xCF, 0x3F, 0xF3, 0xD4, 0x49, 0xE7, 0xF4, 0xB1, 0xDD, + 0x0F, 0x9E, 0x7D, 0x79, 0x24, 0xFD, 0xFA, 0x71, 0x23, 0xBF, 0x70, 0xDB, 0xDF, 0xDF, 0xB9, 0x7A, + 0x72, 0xD1, 0xBF, 0x75, 0xB4, 0xFF, 0x97, 0xFF, 0xA9, 0xF2, 0x91, 0xFA, 0xC9, 0xFB, 0xEF, 0x3F, + 0xFB, 0x3D, 0xEF, 0xCD, 0xF7, 0x8F, 0xAE, 0x7B, 0xF6, 0x3B, 0x8F, 0xD7, 0x4E, 0xDD, 0xFF, 0xF4, + 0x87, 0xF8, 0xC0, 0x1E, 0x5F, 0x82, 0xFC, 0xD5, 0x11, 0xCA, 0x5F, 0x1D, 0x92, 0xA1, 0xC8, 0x5C, + 0x1F, 0x91, 0xEF, 0x33, 0xFE, 0x7D, 0x94, 0x7F, 0xF3, 0xFD, 0xEF, 0x1A, 0x37, 0xFC, 0x7D, 0x43, + 0xFD, 0xAA, 0xCB, 0xC1, 0x83, 0x3F, 0x70, 0x2A, 0xCA, 0xDF, 0xCD, 0xF2, 0xF0, 0x70, 0x5B, 0x27, + 0x69, 0x94, 0x2A, 0x7E, 0xE1, 0xF2, 0x6B, 0x15, 0x81, 0x72, 0x06, 0x16, 0x99, 0xDD, 0xCC, 0x30, + 0x97, 0x7F, 0x75, 0x48, 0x45, 0xF3, 0x11, 0x02, 0x16, 0x60, 0x1C, 0x46, 0xDD, 0x89, 0x28, 0x09, + 0xA2, 0x01, 0x44, 0xF8, 0x33, 0xC7, 0x0F, 0x3E, 0x32, 0xF6, 0x03, 0x38, 0xCA, 0x70, 0x4E, 0x48, + 0xF2, 0x53, 0xF1, 0x7A, 0xFB, 0x2A, 0xDB, 0x5F, 0x5B, 0xE8, 0xFC, 0xCD, 0xC1, 0xF9, 0x8B, 0xF9, + 0x7B, 0x46, 0x30, 0xF6, 0x86, 0xF0, 0x37, 0x4F, 0x29, 0x79, 0xDF, 0x16, 0xA1, 0xF2, 0x10, 0x5E, + 0x51, 0xBF, 0x2B, 0xCB, 0xE5, 0x4F, 0x0B, 0xC6, 0xD6, 0x94, 0xBE, 0xA0, 0x8A, 0xD2, 0xAB, 0x7F, + 0x55, 0x15, 0x4E, 0x19, 0x13, 0xCA, 0xE9, 0x2F, 0xCF, 0x9A, 0xF9, 0xC1, 0x9C, 0x37, 0x7B, 0x0F, + 0x7F, 0x6B, 0x5B, 0xF7, 0xCB, 0x3F, 0x7D, 0x62, 0xC2, 0xFF, 0x12, 0xFF, 0x02, 0x1E, 0x7A, 0xF5, + 0x14, 0x00, 0x13, 0x00, 0x00 + }; + } +} \ No newline at end of file diff --git a/TakoTakoScripts/TJAConvert/FodyWeavers.xml b/TakoTakoScripts/TJAConvert/FodyWeavers.xml new file mode 100644 index 0000000..5029e70 --- /dev/null +++ b/TakoTakoScripts/TJAConvert/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/TakoTakoScripts/TJAConvert/FodyWeavers.xsd b/TakoTakoScripts/TJAConvert/FodyWeavers.xsd new file mode 100644 index 0000000..05e92c1 --- /dev/null +++ b/TakoTakoScripts/TJAConvert/FodyWeavers.xsd @@ -0,0 +1,141 @@ + + + + + + + + + + + + A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks + + + + + A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks. + + + + + A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks + + + + + A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks. + + + + + A list of unmanaged 32 bit assembly names to include, delimited with line breaks. + + + + + A list of unmanaged 64 bit assembly names to include, delimited with line breaks. + + + + + The order of preloaded assemblies, delimited with line breaks. + + + + + + This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file. + + + + + Controls if .pdbs for reference assemblies are also embedded. + + + + + Controls if runtime assemblies are also embedded. + + + + + Controls whether the runtime assemblies are embedded with their full path or only with their assembly name. + + + + + Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option. + + + + + As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off. + + + + + Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code. + + + + + Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior. + + + + + A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with | + + + + + A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |. + + + + + A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with | + + + + + A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with |. + + + + + A list of unmanaged 32 bit assembly names to include, delimited with |. + + + + + A list of unmanaged 64 bit assembly names to include, delimited with |. + + + + + The order of preloaded assemblies, delimited with |. + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/TakoTakoScripts/TJAConvert/Program.cs b/TakoTakoScripts/TJAConvert/Program.cs new file mode 100644 index 0000000..4338f0d --- /dev/null +++ b/TakoTakoScripts/TJAConvert/Program.cs @@ -0,0 +1,1141 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.IO.Compression; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; +using NAudio.Vorbis; +using NAudio.Wave; +using NAudio.Wave.SampleProviders; +using Newtonsoft.Json; +using SonicAudioLib.Archives; +using SonicAudioLib.CriMw; +using TakoTako.Common; +using VGAudio.Containers.Hca; +using VGAudio.Containers.Wave; + +namespace TJAConvert +{ + public static class Program + { + public static async Task Main(string[] args) + { + if (args.Length != 1) + { + Console.WriteLine("Pass in a tja directory"); + return; + } + + var directory = args[0]; + if (!Directory.Exists(directory)) + { + Console.WriteLine("This is not a valid tja directory"); + return; + } + + + var result = await Run(directory); + Console.OutputEncoding = Encoding.Unicode; + Console.WriteLine(result); + } + + /// 0 if pass, -1 if failed unexpectedly, -2 if invalid tja, -3 Timeout + public static async Task Run(string directory) + { + StringBuilder result = new StringBuilder(); + foreach (var tjaPath in Directory.EnumerateFiles(directory, "*.tja")) + { + var fileName = Path.GetFileNameWithoutExtension(tjaPath); + var truncatedName = fileName.Substring(0, Math.Min(fileName.Length, 10)); + if (truncatedName.Length != fileName.Length) + fileName = truncatedName + "..."; + + string realDirectory; + int namingAttempts = 0; + do + { + if (namingAttempts == 0) + realDirectory = Path.Combine(directory, $"{fileName} [GENERATED]"); + else + realDirectory = Path.Combine(directory, $"{fileName} {namingAttempts}[GENERATED]"); + namingAttempts++; + } while (File.Exists(realDirectory)); + + int intResult = -1; + try + { + intResult = await RunConversion(); + } + catch + { + } + + result.AppendLine($"{intResult}:{realDirectory}"); + + async Task RunConversion() + { + TJAMetadata metadata; + try + { + metadata = new TJAMetadata(tjaPath); + } + catch + { + return -2; + } + + var originalAudioPath = $"{directory}/{metadata.AudioPath}"; + + if (!File.Exists(originalAudioPath)) + return -2; + + var newDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + var tempOutDirectory = Path.Combine(newDirectory, Guid.NewGuid().ToString()); + if (Directory.Exists(tempOutDirectory)) + Directory.Delete(tempOutDirectory, true); + Directory.CreateDirectory(tempOutDirectory); + + var passed = await TJAToFumens(metadata, tjaPath, tempOutDirectory); + + if (passed >= 0) passed = CreateMusicFile(metadata, tempOutDirectory) ? 0 : -1; + + var copyFilePath = Path.Combine(newDirectory, Path.GetFileName(originalAudioPath)); + File.Copy(originalAudioPath, copyFilePath); + + var audioExtension = Path.GetExtension(copyFilePath).TrimStart('.'); + switch (audioExtension.ToLowerInvariant()) + { + case "wav": + if (passed >= 0) passed = WavToACB(copyFilePath, tempOutDirectory) ? 0 : -1; + break; + case "ogg": + if (passed >= 0) passed = OGGToACB(copyFilePath, tempOutDirectory) ? 0 : -1; + break; + default: + Console.WriteLine($"Do not support {audioExtension} audio files"); + passed = -4; + break; + } + + if (passed >= 0) + { + if (Directory.Exists(realDirectory)) + Directory.Delete(realDirectory, true); + Directory.CreateDirectory(realDirectory); + foreach (var filePath in Directory.EnumerateFiles(tempOutDirectory)) + { + var extension = Path.GetExtension(filePath).Trim('.'); + if (extension != "bin" && extension != "json") + continue; + var copyFileName = Path.GetFileName(filePath); + File.Copy(filePath, Path.Combine(realDirectory, copyFileName)); + } + } + + if (Directory.Exists(tempOutDirectory)) + Directory.Delete(tempOutDirectory, true); + + return passed; + } + } + + return result.ToString(); + } + + private static void Pack(string path) + { + const int bufferSize = 4096; + string acbPath = path + ".acb"; + + if (!File.Exists(acbPath)) + throw new FileNotFoundException("Unable to locate the corresponding ACB file. Please ensure that it's in the same directory."); + + CriTable acbFile = new CriTable(); + acbFile.Load(acbPath, bufferSize); + + CriAfs2Archive afs2Archive = new CriAfs2Archive(); + + CriCpkArchive cpkArchive = new CriCpkArchive(); + CriCpkArchive extCpkArchive = new CriCpkArchive(); + cpkArchive.Mode = extCpkArchive.Mode = CriCpkMode.Id; + + using (CriTableReader reader = CriTableReader.Create((byte[]) acbFile.Rows[0]["WaveformTable"])) + { + while (reader.Read()) + { + ushort id = reader.ContainsField("MemoryAwbId") ? reader.GetUInt16("MemoryAwbId") : reader.GetUInt16("Id"); + + string inputName = id.ToString("D5"); + + inputName += ".hca"; + inputName = Path.Combine(path, inputName); + + if (!File.Exists(inputName)) + throw new FileNotFoundException($"Unable to locate {inputName}"); + + CriAfs2Entry entry = new CriAfs2Entry + { + FilePath = new FileInfo(inputName), + Id = id + }; + afs2Archive.Add(entry); + } + } + + acbFile.Rows[0]["AwbFile"] = null; + acbFile.Rows[0]["StreamAwbAfs2Header"] = null; + + if (afs2Archive.Count > 0 || cpkArchive.Count > 0) + acbFile.Rows[0]["AwbFile"] = afs2Archive.Save(); + + acbFile.WriterSettings = CriTableWriterSettings.Adx2Settings; + acbFile.Save(acbPath, bufferSize); + } + + private static bool CreateMusicFile(TJAMetadata metadata, string outputPath) + { + try + { + var musicInfo = new CustomSong + { + uniqueId = metadata.Title.GetHashCode(), + id = metadata.Id, + order = 0, + genreNo = (int) metadata.Genre, + branchEasy = false, + branchNormal = false, + branchHard = false, + branchMania = false, + branchUra = false, + previewPos = (int) (metadata.PreviewTime * 1000), + fumenOffsetPos = (int) (metadata.Offset * 10), + songName = new TextEntry() + { + text = metadata.Title, + font = GetFontForText(metadata.Title), + jpText = metadata.TitleJA, + jpFont = string.IsNullOrWhiteSpace(metadata.TitleJA) ? 0 : GetFontForText(metadata.TitleJA), + enText = metadata.TitleEN, + enFont = string.IsNullOrWhiteSpace(metadata.TitleEN) ? 0 : GetFontForText(metadata.TitleEN), + scText = metadata.TitleCN, + scFont = string.IsNullOrWhiteSpace(metadata.TitleCN) ? 0 : GetFontForText(metadata.TitleCN), + tcText = metadata.TitleTW, + tcFont = string.IsNullOrWhiteSpace(metadata.TitleTW) ? 0 : GetFontForText(metadata.TitleTW), + krText = metadata.TitleKO, + krFont = string.IsNullOrWhiteSpace(metadata.TitleKO) ? 0 : GetFontForText(metadata.TitleKO), + }, + songSubtitle = new TextEntry() + { + text = metadata.Subtitle, + font = GetFontForText(metadata.Subtitle), + jpText = metadata.SubtitleJA, + jpFont = string.IsNullOrWhiteSpace(metadata.SubtitleJA) ? 0 : GetFontForText(metadata.SubtitleJA), + enText = metadata.SubtitleEN, + enFont = string.IsNullOrWhiteSpace(metadata.SubtitleEN) ? 0 : GetFontForText(metadata.SubtitleEN), + scText = metadata.SubtitleCN, + scFont = string.IsNullOrWhiteSpace(metadata.SubtitleCN) ? 0 : GetFontForText(metadata.SubtitleCN), + tcText = metadata.SubtitleTW, + tcFont = string.IsNullOrWhiteSpace(metadata.SubtitleTW) ? 0 : GetFontForText(metadata.SubtitleTW), + krText = metadata.SubtitleKO, + krFont = string.IsNullOrWhiteSpace(metadata.SubtitleKO) ? 0 : GetFontForText(metadata.SubtitleKO), + }, + songDetail = new TextEntry() + { + text = metadata.Detail, + font = GetFontForText(metadata.Detail), + jpText = metadata.DetailJA, + jpFont = string.IsNullOrWhiteSpace(metadata.DetailJA) ? 0 : GetFontForText(metadata.DetailJA), + enText = metadata.DetailEN, + enFont = string.IsNullOrWhiteSpace(metadata.DetailEN) ? 0 : GetFontForText(metadata.DetailEN), + scText = metadata.DetailCN, + scFont = string.IsNullOrWhiteSpace(metadata.DetailCN) ? 0 : GetFontForText(metadata.DetailCN), + tcText = metadata.DetailTW, + tcFont = string.IsNullOrWhiteSpace(metadata.DetailTW) ? 0 : GetFontForText(metadata.DetailTW), + krText = metadata.DetailKO, + krFont = string.IsNullOrWhiteSpace(metadata.DetailKO) ? 0 : GetFontForText(metadata.DetailKO), + }, + }; + + foreach (var course in metadata.Courses) + { + //todo figure out the best score? + switch (course.CourseType) + { + case CourseType.Easy: + musicInfo.starEasy = course.Level; + musicInfo.shinutiEasy = 10170; + musicInfo.shinutiEasyDuet = 10170; + musicInfo.scoreEasy = 360090; + musicInfo.branchEasy = course.IsBranching; + break; + case CourseType.Normal: + musicInfo.starNormal = course.Level; + musicInfo.shinutiNormal = 6010; + musicInfo.shinutiNormalDuet = 6010; + musicInfo.scoreNormal = 650150; + musicInfo.branchNormal = course.IsBranching; + break; + case CourseType.Hard: + musicInfo.starHard = course.Level; + musicInfo.shinutiHard = 3010; + musicInfo.shinutiHardDuet = 3010; + musicInfo.scoreHard = 800210; + musicInfo.branchHard = course.IsBranching; + break; + case CourseType.Oni: + musicInfo.starMania = course.Level; + musicInfo.shinutiMania = 1000; + musicInfo.shinutiManiaDuet = 1000; + musicInfo.scoreMania = 10000; + musicInfo.branchMania = course.IsBranching; + break; + case CourseType.UraOni: + musicInfo.starUra = course.Level; + musicInfo.shinutiUra = 1000; + musicInfo.shinutiUraDuet = 1000; + musicInfo.scoreUra = 10000; + musicInfo.branchUra = course.IsBranching; + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + var json = JsonConvert.SerializeObject(musicInfo, Formatting.Indented); + File.WriteAllText($"{outputPath}/data.json", json); + return true; + } + catch (Exception e) + { + Console.WriteLine(e); + return false; + } + } + + private static async Task TJAToFumens(TJAMetadata metadata, string tjaPath, string outputPath) + { + var fileName = Path.GetFileName(tjaPath); + var newPath = Path.Combine(outputPath, fileName); + + // copy the file here in case we need to make any edits to it + if (File.Exists(newPath)) + File.Delete(newPath); + + File.Copy(tjaPath, newPath); + + int passed = 0; + // If this TJA has Ura Oni + if (metadata.Courses.Any(x => x.CourseType == CourseType.UraOni)) + { + // tja2bin doesn't support Ura Oni, so rip it out and change the course type to oni, then rename the final file + passed = await ConvertUraOni(metadata, newPath); + if (passed < 0) + return passed; + // for every .bin in this directory, we can now add the prefix _x + + foreach (var filePath in Directory.EnumerateFiles(outputPath, "*.bin")) + { + var binFileName = Path.GetFileName(filePath); + var binDirectory = Path.GetDirectoryName(filePath); + + binFileName = binFileName + .Replace("_m_1.bin", "_x_1_.bin") + .Replace("_m_2.bin", "_x_2_.bin") + .Replace("_m.bin", "_x.bin"); + + File.Move(filePath, $"{binDirectory}/{binFileName}"); + } + + try + { + metadata = new TJAMetadata(newPath); + } + catch + { + return -2; + } + } + + // If this TJA has doubles, then rip them out out + if (metadata.Courses.Any(x => x.PlayStyle == TJAMetadata.PlayStyle.Double)) + { + // will need to create additional files to splice them out + + passed = await SpliceDoubles(metadata, newPath); + if (passed < 0) + return passed; + + try + { + metadata = new TJAMetadata(newPath); + } + catch + { + return -2; + } + } + + if (metadata.Courses.All(x => x.PlayStyle != TJAMetadata.PlayStyle.Double)) + passed = await Convert(newPath, outputPath); + + if (passed < 0) + return passed; + + var fumenFiles = Directory.EnumerateFiles(outputPath, "*.bin").ToList().Where(x => !x.StartsWith("song_")).ToList(); + if (fumenFiles.Count == 0) + { + Console.WriteLine($"Failed to create Fumens for {fileName}"); + return -1; + } + + return passed; + } + + private static async Task ConvertUraOni(TJAMetadata metadata, string newPath) + { + var directory = Path.GetDirectoryName(newPath); + var fileName = Path.GetFileNameWithoutExtension(newPath); + var lines = File.ReadAllLines(newPath).ToList(); + + int courseStartIndex = lines.FindLastIndex(x => + { + var match = TJAMetadata.TJAKeyValueRegex.Match(x); + if (!match.Success) + return false; + + var type = match.Groups["KEY"].Value; + return TJAMetadata.MainMetadataKeys.Contains(type.ToUpperInvariant()); + }); + + var metaDataLines = lines.Take(courseStartIndex + 1).ToList(); + var courses = metadata.Courses.Where(x => x.CourseType == CourseType.UraOni).Reverse(); + + foreach (var course in courses) + { + if (course.PlayStyle == TJAMetadata.PlayStyle.Single) + { + var file = new List(metaDataLines); + file.Add(""); + file.AddRange(course.MetadataToTJA(courseTypeOverride: CourseType.Oni)); + file.Add(""); + file.AddRange(lines.GetRange(course.SongDataIndexStart, course.SongDataIndexEnd - course.SongDataIndexStart + 1)); + + var path = $"{directory}/{fileName}.tja"; + File.WriteAllLines(path, file); + + var passed = await Convert(path, directory); + if (passed < 0) + return passed; + + lines.RemoveRange(course.CourseDataIndexStart, course.SongDataIndexEnd - course.CourseDataIndexStart + 1); + } + else + { + var passed = await SplitP1P2(lines, course, directory, fileName, CourseType.Oni); + if (passed < 0) + return passed; + } + } + + File.WriteAllLines(newPath, lines); + + return 0; + } + + /// + /// This aims to separate P1 and P2 tracks for TJA2BIN to read + /// + private static async Task SpliceDoubles(TJAMetadata metadata, string newPath) + { + var directory = Path.GetDirectoryName(newPath); + var fileName = Path.GetFileNameWithoutExtension(newPath); + var lines = File.ReadAllLines(newPath).ToList(); + + // first thing to do is inject missing metadata + for (int i = metadata.Courses.Count - 1; i >= 0; i--) + { + var course = metadata.Courses[i]; + lines.RemoveRange(course.CourseDataIndexStart, course.CourseDataIndexEnd - course.CourseDataIndexStart); + lines.Insert(course.CourseDataIndexStart, ""); + var courseData = course.MetadataToTJA(); + lines.InsertRange(course.CourseDataIndexStart + 1, courseData); + lines.Insert(course.CourseDataIndexStart + 1 + courseData.Count, ""); + } + + File.WriteAllLines(newPath, lines); + + try + { + metadata = new TJAMetadata(newPath); + } + catch + { + return -2; + } + + var doubleCourses = metadata.Courses.Where(x => x.PlayStyle == TJAMetadata.PlayStyle.Double).Reverse(); + + // remove doubles section + foreach (var course in doubleCourses) + { + var passed = await SplitP1P2(lines, course, directory, fileName); + if (passed < 0) + return passed; + } + + File.WriteAllLines(newPath, lines); + return 0; + } + + private static async Task SplitP1P2(List lines, TJAMetadata.Course course, string directory, string fileName, CourseType? courseTypeOverride = null) + { + // metadata end + int courseStartIndex = lines.FindLastIndex(x => + { + var match = TJAMetadata.TJAKeyValueRegex.Match(x); + if (!match.Success) + return false; + + var type = match.Groups["KEY"].Value; + return TJAMetadata.MainMetadataKeys.Contains(type.ToUpperInvariant()); + }); + var metaDataLines = lines.Take(courseStartIndex + 1).ToList(); + + var startSongP1Index = lines.FindIndex(course.CourseDataIndexEnd, x => x.StartsWith("#START P1", StringComparison.InvariantCultureIgnoreCase)); + if (startSongP1Index < 0) + return -1; + var endP1Index = lines.FindIndex(startSongP1Index, x => x.StartsWith("#END", StringComparison.InvariantCultureIgnoreCase)); + if (endP1Index < 0) + return -1; + + var startSongP2Index = lines.FindIndex(endP1Index, x => x.StartsWith("#START P2", StringComparison.InvariantCultureIgnoreCase)); + if (startSongP2Index < 0) + return -1; + var endP2Index = lines.FindIndex(startSongP2Index, x => x.StartsWith("#END", StringComparison.InvariantCultureIgnoreCase)); + if (endP2Index < 0) + return -1; + + // otherwise create new files + var p1File = new List(metaDataLines); + p1File.AddRange(course.MetadataToTJA(TJAMetadata.PlayStyle.Single, courseTypeOverride)); + p1File.AddRange(lines.GetRange(startSongP1Index, endP1Index - startSongP1Index + 1)); + RemoveP1P2(p1File); + + var path = $"{directory}/{fileName}_1.tja"; + File.WriteAllLines(path, p1File); + + var passed = await Convert(path, directory); + if (passed < 0) + return passed; + + var p2File = new List(metaDataLines); + p2File.AddRange(course.MetadataToTJA(TJAMetadata.PlayStyle.Single, courseTypeOverride)); + p2File.AddRange(lines.GetRange(startSongP2Index, endP2Index - startSongP2Index + 1)); + RemoveP1P2(p2File); + + path = $"{directory}/{fileName}_2.tja"; + File.WriteAllLines(path, p2File); + + passed = await Convert(path, directory); + if (passed < 0) + return passed; + + lines.RemoveRange(course.CourseDataIndexStart, course.SongDataIndexEnd - course.CourseDataIndexStart + 1); + return 0; + } + + private static void RemoveP1P2(List playerLines) + { + for (var i = 0; i < playerLines.Count; i++) + { + var line = playerLines[i]; + if (line.StartsWith("#START", StringComparison.InvariantCultureIgnoreCase)) + playerLines[i] = "#START"; + } + } + + private static async Task Convert(string tjaPath, string outputPath) + { + var fileName = Path.GetFileNameWithoutExtension(tjaPath); + + TJAMetadata metadata; + try + { + metadata = new TJAMetadata(tjaPath); + } + catch + { + return -2; + } + + var newPath = $"{outputPath}\\{Path.GetFileName(tjaPath)}"; + if (metadata.Courses.Count == 1) + { + var coursePostfix = metadata.Courses[0].CourseType.ToShort(); + if (fileName.EndsWith("_1")) + newPath = $"{outputPath}\\{fileName.Substring(0, fileName.Length - 2)}_{coursePostfix}_1.tja"; + else if (fileName.EndsWith("_2")) + newPath = $"{outputPath}\\{fileName.Substring(0, fileName.Length - 2)}_{coursePostfix}_2.tja"; + else + newPath = $"{outputPath}\\{fileName}_{coursePostfix}.tja"; + } + + var lines = ApplyGeneralFixes(File.ReadAllLines(tjaPath).ToList()); + File.WriteAllLines(newPath, lines); + + var currentDirectory = Environment.CurrentDirectory; + var exePath = $"{currentDirectory}/tja2bin.exe"; + if (!File.Exists(exePath)) + { + Console.WriteLine($"Cannot find tja2bin at {exePath}"); + return -1; + } + + var timeStamp = Guid.NewGuid().ToString(); + bool isUsingTempFilePath = false; + try + { + int attempts = 30; + string result = string.Empty; + + do + { + ProcessStartInfo info = new ProcessStartInfo() + { + FileName = exePath, + Arguments = $"\"{newPath}\"", + CreateNoWindow = true, + WindowStyle = ProcessWindowStyle.Hidden, + UseShellExecute = false, + RedirectStandardOutput = true, + }; + + var process = new Process(); + process.StartInfo = info; + + CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); + var delayTask = Task.Delay(TimeSpan.FromSeconds(10), cancellationTokenSource.Token); + var runTask = RunProcess(); + + var taskResult = await Task.WhenAny(delayTask, runTask); + if (taskResult == delayTask) + { + // tja2bin can sometimes have memory leak + if (!process.HasExited) + { + process.Kill(); + return -3; + } + } + + attempts--; + + // todo: Not sure how to solve this, so ignore it for now + if (result.Contains("branches must have same measure count") || result.Contains("invalid #BRANCHSTART")) + return -2; + + async Task RunProcess() + { + process.Start(); + result = await process.StandardOutput.ReadToEndAsync(); + } + } while (FailedAndCanRetry(result) && attempts > 0); + + if (isUsingTempFilePath) + { + foreach (var file in Directory.EnumerateFiles(Path.GetDirectoryName(newPath))) + { + var tempFileName = Path.GetFileName(file); + var newName = $"{outputPath}\\{tempFileName}".Replace(timeStamp.ToString(), fileName); + if (File.Exists(newName)) + File.Delete(newName); + File.Move(file, newName); + } + + Directory.Delete(Path.GetDirectoryName(newPath)); + if (File.Exists($"{outputPath}\\{fileName}.tja")) + File.Delete($"{outputPath}\\{fileName}.tja"); + } + else + { + File.Delete(newPath); + } + + return 0; + } + catch (Exception e) + { + Console.WriteLine(e); + return -1; + } + + List ApplyGeneralFixes(List lines) + { + var noScoreInitRegex = new Regex("SCOREINIT:\\s*$", RegexOptions.CultureInvariant); + var noScoreDiffRegex = new Regex("SCOREDIFF:\\s*$", RegexOptions.CultureInvariant); + lines = lines + // get rid of comments + .Select(x => + { + x = x.Trim(); + var commentIndex = x.IndexOf("//", StringComparison.Ordinal); + if (commentIndex >= 0) + x = x.Substring(0, commentIndex); + + // remove unwanted characters in tracks + if (x.Trim().EndsWith(",")) + x = Regex.Replace(x, "[^\\d,ABF]", ""); + + // if there's no scores, give them an arbitrary score + if (noScoreInitRegex.IsMatch(x)) + return "SCOREINIT:440"; + if (noScoreDiffRegex.IsMatch(x)) + return "SCOREDIFF:113"; + + // I saw a few typos in a bunch of tjas, so I added a fix for it here, lol + return x.Replace("##", "#").Replace("#SCROOL", "#SCROLL").Replace("#SCROLLL", "#SCROLL").Replace("#SRCOLL", "#SCROLL").Replace("#MEAUSRE", "#MEASURE").Trim(); + }) + // remove lyrics, sections and delays as they are not supported by tja2bin + .Where(x => !( + x.StartsWith("#LYRIC", StringComparison.InvariantCultureIgnoreCase) + || x.StartsWith("#DELAY", StringComparison.InvariantCultureIgnoreCase) + || x.StartsWith("#MAKER", StringComparison.InvariantCultureIgnoreCase) + || x.StartsWith("#SECTION", StringComparison.InvariantCultureIgnoreCase))) + .ToList(); + return lines; + } + + bool FailedAndCanRetry(string result) + { + metadata = new TJAMetadata(newPath); + if (result.Contains("too many balloon notes")) + { + // one of the fumens does not have the correct amount of balloon amounts + var currentLines = File.ReadLines(newPath).ToList(); + var problematicCourse = GetCourseWithProblems(); + + // if there are two 9s close to each other, remove the second one + for (int i = problematicCourse.SongDataIndexStart; i < problematicCourse.SongDataIndexEnd; i++) + { + // if we find a 9 in a song, make sure there isn't another within this line or the next + var line = currentLines[i].Trim(); + if (line.EndsWith(",", StringComparison.InvariantCultureIgnoreCase)) + { + var index = line.IndexOf("9", StringComparison.Ordinal); + if (index < 0) continue; + + var nextIndex = line.IndexOf("9", index + 1, StringComparison.Ordinal); + if (nextIndex > 0) + { + TryReplace(line, i, nextIndex); + } + else + { + // check the next line + for (int j = 1; j <= 1; j++) + { + var lineAhead = currentLines[i + j]; + nextIndex = lineAhead.IndexOf("9", 0, StringComparison.Ordinal); + if (nextIndex < 0) + continue; + + TryReplace(lineAhead, i + j, nextIndex); + } + } + + void TryReplace(string currentLine, int linesIndex, int searchStartIndex) + { + currentLine = currentLine.Remove(searchStartIndex, 1); + currentLine = currentLine.Insert(searchStartIndex, "0"); + currentLines[linesIndex] = currentLine; + } + } + } + + var balloonLine = currentLines.FindIndex(problematicCourse.CourseDataIndexStart, x => x.StartsWith("balloon:", StringComparison.InvariantCultureIgnoreCase)); + if (balloonLine < 0) + { + // dunno stop here + return false; + } + + // check to see if the balloon count matches up with the amount of 7 + var balloonMatches = Regex.Matches(currentLines[balloonLine], "(\\d+)"); + + List currentNumbers = new List(); + foreach (Match match in balloonMatches) + currentNumbers.Add(int.Parse(match.Value)); + + int balloons8 = 0; + int balloons79 = 0; + // bug perhaps 7|9 instead of 8? + Regex balloonRegex = new Regex("^.*(7|8|9).*,.*$"); + for (int i = problematicCourse.SongDataIndexStart; i < problematicCourse.SongDataIndexEnd; i++) + { + var line = currentLines[i]; + if (balloonRegex.IsMatch(line)) + { + balloons8 += line.Count(x => x is '8'); + balloons79 += line.Count(x => x is '7' or '9'); + } + } + + var balloons = Math.Max(balloons8, balloons79); + + if (balloons > currentNumbers.Count) + { + // since we're patching this, do whatever we want + var finalBalloonText = "BALLOON:"; + if (balloons >= currentNumbers.Count) + { + for (int i = currentNumbers.Count; i < balloons; i++) + currentNumbers.Add(4); + } + + finalBalloonText += string.Join(",", currentNumbers); + currentLines[balloonLine] = finalBalloonText; + } + + File.WriteAllLines(newPath, currentLines); + return true; + } + + if (result.Contains("need a #BRANCHEND")) + { + var currentLines = File.ReadLines(newPath).ToList(); + var problematicCourse = GetCourseWithProblems(); + + currentLines.Insert(problematicCourse.SongDataIndexEnd, "#BRANCHEND"); + File.WriteAllLines(newPath, currentLines); + return true; + } + + if (result.Contains("#E must be after the #N branch") || result.Contains("#M must be after the #E branch")) + { + var currentLines = File.ReadLines(newPath).ToList(); + // var problematicCourse = GetCourseWithProblems(); + + string currentBranch = ""; + int startOfBranch = -1; + int endOfBranch = -1; + var branches = new List<(string branch, int start, int end)>(); + + for (int i = 0; i < currentLines.Count; i++) + { + var line = currentLines[i]; + bool isBranchStart = line.StartsWith("#BRANCHSTART", StringComparison.InvariantCultureIgnoreCase); + + if (line.StartsWith("#BRANCHEND", StringComparison.InvariantCultureIgnoreCase) || isBranchStart) + { + if (!string.IsNullOrWhiteSpace(currentBranch)) + EndBranch(); + + currentBranch = ""; + // Order is N E M + if (branches.Count > 1) + { + // try to sort the order of branches + var branchesSorted = new List<(string branch, int start, int end)>(branches); + branchesSorted.Sort((x, y) => GetSortOrder(x.branch) - GetSortOrder(y.branch)); + var branchesSortedValue = new List>(); + + foreach (var branch in branchesSorted) + { + var text = currentLines.GetRange(branch.start, branch.end - branch.start); + // does this text actually have any music? found a case where a branch was empty /shrug + if (!text.Any(x => x.Contains(","))) + continue; + + branchesSortedValue.Add(text); + } + + for (int j = 0; j < branches.Count; j++) + { + var branch = branchesSorted[branchesSorted.Count - 1 - j]; + currentLines.RemoveRange(branch.start, branch.end - branch.start); + if (j < 3) + currentLines.InsertRange(branch.start, branchesSortedValue[j]); + } + } + + branches.Clear(); + } + + else if (line.Trim().Equals("#M", StringComparison.InvariantCultureIgnoreCase)) + { + if (!string.IsNullOrWhiteSpace(currentBranch)) + EndBranch(); + + currentBranch = "m"; + startOfBranch = i; + } + else if (line.Trim().Equals("#N", StringComparison.InvariantCultureIgnoreCase)) + { + if (!string.IsNullOrWhiteSpace(currentBranch)) + EndBranch(); + + currentBranch = "n"; + startOfBranch = i; + } + else if (line.Trim().Equals("#E", StringComparison.InvariantCultureIgnoreCase)) + { + if (!string.IsNullOrWhiteSpace(currentBranch)) + EndBranch(); + + currentBranch = "e"; + startOfBranch = i; + } + + int GetSortOrder(string branch) + { + switch (branch) + { + case "n": + return 1; + case "e": + return 2; + case "m": + return 3; + } + + return 0; + } + + void EndBranch() + { + endOfBranch = i; + if (!string.IsNullOrEmpty(currentBranch)) + branches.Add((currentBranch, startOfBranch, endOfBranch)); + } + } + + File.WriteAllLines(newPath, currentLines); + return true; + } + + if (result.Contains("unexpected EOF") && !newPath.Contains(timeStamp.ToString())) + { + // perhaps the files name is weird? let's rename it, and move this to a new folder + var newDirectory = Path.GetTempPath() + "\\" + timeStamp; + var fileName = timeStamp + ".tja"; + var tempFilePath = Path.Combine(newDirectory, fileName); + Directory.CreateDirectory(newDirectory); + File.Copy(newPath, tempFilePath); + newPath = tempFilePath; + isUsingTempFilePath = true; + return true; + } + + if (result.Contains("missing score information")) + { + // Missing score! let's just to replace the existing one with whatever + for (int i = metadata.Courses.Count - 1; i >= 0; i--) + { + var course = metadata.Courses[i]; + + if (!string.IsNullOrWhiteSpace(course.Metadata.ScoreDiff) && !string.IsNullOrWhiteSpace(course.Metadata.ScoreInit)) + continue; + + course.Metadata.ScoreInit = "980"; + course.Metadata.ScoreDiff = "320"; + + lines.RemoveRange(course.CourseDataIndexStart, course.CourseDataIndexEnd - course.CourseDataIndexStart); + lines.Insert(course.CourseDataIndexStart, ""); + var newCourseData = course.MetadataToTJA(); + lines.InsertRange(course.CourseDataIndexStart + 1, newCourseData); + lines.Insert(course.CourseDataIndexStart + 1 + newCourseData.Count, ""); + File.WriteAllLines(newPath, lines); + } + + return true; + } + + return false; + + TJAMetadata.Course GetCourseWithProblems() + { + var courses = new List(metadata.Courses); + // step 1. find the troublesome course + var resultLines = result.Split(new[] {"\r\n", "\r", "\n"}, StringSplitOptions.RemoveEmptyEntries); + foreach (var line in resultLines) + { + if (line.Contains("_x.bin")) + courses.RemoveAll(x => x.CourseType == CourseType.UraOni); + if (line.Contains("_m.bin")) + courses.RemoveAll(x => x.CourseType == CourseType.Oni); + if (line.Contains("_h.bin")) + courses.RemoveAll(x => x.CourseType == CourseType.Hard); + if (line.Contains("_n.bin")) + courses.RemoveAll(x => x.CourseType == CourseType.Normal); + if (line.Contains("_e.bin")) + courses.RemoveAll(x => x.CourseType == CourseType.Easy); + } + + if (courses.Count == 0) + { + // dunno stop here + return null; + } + + return courses[0]; + } + } + } + + private static bool OGGToACB(string oggPath, string outDirectory) + { + try + { + var directory = Path.GetDirectoryName(oggPath); + var fileName = Path.GetFileNameWithoutExtension(oggPath); + var acbPath = $"{directory}/{Guid.NewGuid().ToString()}"; + Directory.CreateDirectory(acbPath); + + using MemoryStream stream = new MemoryStream(Files.TemplateACBData); + using var decompressor = new GZipStream(stream, CompressionMode.Decompress); + using (FileStream compressedFileStream = File.Create($"{acbPath}.acb")) + decompressor.CopyTo(compressedFileStream); + + var hca = OggToHca(oggPath); + if (hca == null) + return false; + + File.WriteAllBytes($"{acbPath}/00000.hca", hca); + Pack(acbPath); + if (File.Exists($"{outDirectory}/song_{fileName}.bin")) + File.Delete($"{outDirectory}/song_{fileName}.bin"); + + File.Move($"{acbPath}.acb", $"{outDirectory}/song_{fileName}.bin"); + Directory.Delete(acbPath, true); + return true; + } + catch (Exception e) + { + Console.WriteLine(e); + return false; + } + } + + private static bool WavToACB(string wavPath, string outDirectory, bool deleteWav = false) + { + try + { + var directory = Path.GetDirectoryName(wavPath); + var fileName = Path.GetFileNameWithoutExtension(wavPath); + var acbPath = $"{directory}/{Guid.NewGuid().ToString()}"; + Directory.CreateDirectory(acbPath); + + using MemoryStream stream = new MemoryStream(Files.TemplateACBData); + using var decompressor = new GZipStream(stream, CompressionMode.Decompress); + using (FileStream compressedFileStream = File.Create($"{acbPath}.acb")) + decompressor.CopyTo(compressedFileStream); + + var hca = WavToHca(wavPath); + File.WriteAllBytes($"{acbPath}/00000.hca", hca); + Pack(acbPath); + if (File.Exists($"{outDirectory}/song_{fileName}.bin")) + File.Delete($"{outDirectory}/song_{fileName}.bin"); + + File.Move($"{acbPath}.acb", $"{outDirectory}/song_{fileName}.bin"); + + if (deleteWav) + File.Delete(wavPath); + Directory.Delete(acbPath, true); + return true; + } + catch (Exception e) + { + Console.WriteLine(e); + return false; + } + } + + private static byte[] WavToHca(string path) + { + var hcaWriter = new HcaWriter(); + var waveReader = new WaveReader(); + var audioData = waveReader.Read(File.ReadAllBytes(path)); + return hcaWriter.GetFile(audioData); + } + + private static byte[] OggToHca(string inPath) + { + try + { + using FileStream fileIn = new FileStream(inPath, FileMode.Open); + var vorbis = new VorbisWaveReader(fileIn); + var memoryStream = new MemoryStream(); + WaveFileWriter.WriteWavFileToStream(memoryStream, new SampleToWaveProvider16(vorbis)); + + var hcaWriter = new HcaWriter(); + var waveReader = new WaveReader(); + var audioData = waveReader.Read(memoryStream.ToArray()); + return hcaWriter.GetFile(audioData); + } + catch (Exception e) + { + Console.WriteLine(e); + return null; + } + } + + private static bool OggToWav(string inPath, string outPath) + { + try + { + using FileStream fileIn = new FileStream(inPath, FileMode.Open); + var vorbis = new VorbisWaveReader(fileIn); + WaveFileWriter.CreateWaveFile16(outPath, vorbis); + return true; + } + catch (Exception e) + { + Console.WriteLine(e); + return false; + } + } + + private static IEnumerable GetCharsInRange(string text, int min, int max) + { + return text.Where(e => e >= min && e <= max); + } + + private static int GetFontForText(string keyword) + { + if (string.IsNullOrEmpty(keyword)) + return 1; + + var hiragana = GetCharsInRange(keyword, 0x3040, 0x309F).Any(); + var katakana = GetCharsInRange(keyword, 0x30A0, 0x30FF).Any(); + var kanji = GetCharsInRange(keyword, 0x4E00, 0x9FBF).Any(); + + if (hiragana || katakana || kanji) + return 0; + + var hangulJamo = GetCharsInRange(keyword, 0x1100, 0x11FF).Any(); + var hangulSyllables = GetCharsInRange(keyword, 0xAC00, 0xD7A3).Any(); + var hangulCompatibility = GetCharsInRange(keyword, 0x3130, 0x318F).Any(); + var hangulExtendedA = GetCharsInRange(keyword, 0xA960, 0xA97F).Any(); + var hangulExtendedB = GetCharsInRange(keyword, 0xD7B0, 0xD7FF).Any(); + + if (hangulJamo + || hangulSyllables + || hangulCompatibility + || hangulExtendedA + || hangulExtendedB) + return 4; + + var ascii = GetCharsInRange(keyword, 0x0041, 0x005A).Any(); + var ascii2 = GetCharsInRange(keyword, 0x0061, 0x007A).Any(); + if (ascii || ascii2) + return 1; + + // don't know how to distinguish between simplified and traditional chinese... sorry :( + return 3; + } + } +} diff --git a/TakoTakoScripts/TJAConvert/References/SonicAudioLib.dll b/TakoTakoScripts/TJAConvert/References/SonicAudioLib.dll new file mode 100644 index 0000000000000000000000000000000000000000..97b1b0a6eb93f0351c2bd3d63938982fe525d814 GIT binary patch literal 70656 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
#IYJerl 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 + + + Exe + net48 + default + true + win10-x64 + true + + + + + + + + + References\SonicAudioLib.dll + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + + diff --git a/TakoTakoScripts/TJAConvert/TJAMetaData.cs b/TakoTakoScripts/TJAConvert/TJAMetaData.cs new file mode 100644 index 0000000..6825afc --- /dev/null +++ b/TakoTakoScripts/TJAConvert/TJAMetaData.cs @@ -0,0 +1,415 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace TJAConvert; + +internal class TJAMetadata +{ + public string Id; + public string Title; + public string TitleJA; + public string TitleEN; + public string TitleCN; + public string TitleTW; + public string TitleKO; + + public string Detail; +// dunno what to put in here +#pragma warning disable CS0649 + public string DetailJA; + public string DetailEN; + public string DetailCN; + public string DetailTW; + public string DetailKO; +#pragma warning restore CS0649 + + public string Subtitle; + public string SubtitleJA; + public string SubtitleEN; + public string SubtitleCN; + public string SubtitleTW; + public string SubtitleKO; + + public string AudioPath; + public float Offset; + public float PreviewTime; + public SongGenre Genre; + + public List Courses = new(); + + public TJAMetadata(string tjaPath) + { + Id = Path.GetFileNameWithoutExtension(tjaPath); + + var lines = File.ReadLines(tjaPath).ToList(); + + Title = FindAndGetField("TITLE"); + TitleJA = FindAndGetField("TITLEJA"); + TitleEN = FindAndGetField("TITLEEN"); + TitleCN = FindAndGetField("TITLECN"); + TitleTW = FindAndGetField("TITLETW"); + TitleKO = FindAndGetField("TITLEKO"); + + Detail = FindAndGetField("MAKER"); + + ModifySubtitle("SUBTITLE", x => Subtitle = x); + ModifySubtitle("SUBTITLEJA", x => SubtitleJA = x); + ModifySubtitle("SUBTITLEEN", x => SubtitleEN = x); + ModifySubtitle("SUBTITLECN", x => SubtitleCN = x); + ModifySubtitle("SUBTITLETW", x => SubtitleTW = x); + ModifySubtitle("SUBTITLEKO", x => SubtitleKO = x); + + void ModifySubtitle(string key, Action setSubtitle) + { + var entry = FindAndGetField(key); + if (string.IsNullOrEmpty(entry)) + return; + + var subtitle = FindAndGetField(key).TrimStart('-', '+'); + setSubtitle(subtitle); + } + + AudioPath = FindAndGetField("WAVE"); + Offset = float.Parse(FindAndGetField("OFFSET")); + PreviewTime = float.Parse(FindAndGetField("DEMOSTART")); + + var genreEntry = FindAndGetField("GENRE"); + Genre = GetGenre(genreEntry); + + // start finding courses + Course currentCourse = new Course(); + // find the last metadata entry + int courseStartIndex = lines.FindLastIndex(x => + { + var match = TJAKeyValueRegex.Match(x); + if (!match.Success) + return false; + + var type = match.Groups["KEY"].Value; + return MainMetadataKeys.Contains(type.ToUpperInvariant()); + }); + // find where the track starts + int courseEndIndex = lines.FindIndex(courseStartIndex, x => x.StartsWith("#START", StringComparison.InvariantCultureIgnoreCase)); + + do + { + bool newContent = false; + for (int i = courseStartIndex + 1; i < courseEndIndex; i++) + { + var line = lines[i]; + var match = TJAKeyValueRegex.Match(line); + if (!match.Success) + continue; + + newContent = true; + var key = match.Groups["KEY"].Value.ToUpperInvariant().Trim(); + var value = match.Groups["VALUE"].Value.Trim(); + + switch (key) + { + case "COURSE": + { + currentCourse.CourseType = GetCourseType(value); + break; + } + case "LEVEL": + { + currentCourse.Level = int.Parse(value); + break; + } + case "STYLE": + { + currentCourse.PlayStyle = (PlayStyle) Enum.Parse(typeof(PlayStyle), value, true); + break; + } + } + + if (key.Equals(nameof(Course.OtherMetadata.Balloon).ToUpperInvariant())) currentCourse.Metadata.Balloon = value; + if (key.Equals(nameof(Course.OtherMetadata.ScoreInit).ToUpperInvariant())) currentCourse.Metadata.ScoreInit = value; + if (key.Equals(nameof(Course.OtherMetadata.ScoreDiff).ToUpperInvariant())) currentCourse.Metadata.ScoreDiff = value; + if (key.Equals(nameof(Course.OtherMetadata.BalloonNor).ToUpperInvariant())) currentCourse.Metadata.BalloonNor = value; + if (key.Equals(nameof(Course.OtherMetadata.BalloonExp).ToUpperInvariant())) currentCourse.Metadata.BalloonExp = value; + if (key.Equals(nameof(Course.OtherMetadata.BalloonMas).ToUpperInvariant())) currentCourse.Metadata.BalloonMas = value; + if (key.Equals(nameof(Course.OtherMetadata.Exam1).ToUpperInvariant())) currentCourse.Metadata.Exam1 = value; + if (key.Equals(nameof(Course.OtherMetadata.Exam2).ToUpperInvariant())) currentCourse.Metadata.Exam2 = value; + if (key.Equals(nameof(Course.OtherMetadata.Exam3).ToUpperInvariant())) currentCourse.Metadata.Exam3 = value; + if (key.Equals(nameof(Course.OtherMetadata.GaugeNcr).ToUpperInvariant())) currentCourse.Metadata.GaugeNcr = value; + if (key.Equals(nameof(Course.OtherMetadata.Total).ToUpperInvariant())) currentCourse.Metadata.Total = value; + if (key.Equals(nameof(Course.OtherMetadata.HiddenBranch).ToUpperInvariant())) currentCourse.Metadata.HiddenBranch = value; + } + + currentCourse.CourseDataIndexStart = courseStartIndex + 1; + currentCourse.CourseDataIndexEnd = courseEndIndex; + currentCourse.SongDataIndexStart = courseEndIndex; + + // find the next end + if (currentCourse.PlayStyle == PlayStyle.Double) + { + // go through p1 and p2 + var index = lines.FindIndex(courseEndIndex, x => x.StartsWith("#END", StringComparison.InvariantCultureIgnoreCase)); + courseStartIndex = lines.FindIndex(index + 1, x => x.StartsWith("#END", StringComparison.InvariantCultureIgnoreCase)); + } + else + { + courseStartIndex = lines.FindIndex(courseEndIndex, x => x.StartsWith("#END", StringComparison.InvariantCultureIgnoreCase)); + } + + currentCourse.SongDataIndexEnd = courseStartIndex; + + if (newContent) + Courses.Add(currentCourse); + + for (int i = currentCourse.SongDataIndexStart; i < currentCourse.SongDataIndexEnd; i++) + { + var line = lines[i]; + if (line.Contains("#BRANCH")) + { + currentCourse.IsBranching = true; + break; + } + } + + // duplicate the existing course + currentCourse = new Course(currentCourse); + // find the next start + courseEndIndex = lines.FindIndex(courseStartIndex, x => x.StartsWith("#START", StringComparison.InvariantCultureIgnoreCase)); + } while (courseEndIndex > 0); + + string FindAndGetField(string fieldName) + { + var tileRegex = new Regex(string.Format(TJAFieldRegexTemplate, fieldName), RegexOptions.IgnoreCase); + var index = lines.FindIndex(x => tileRegex.IsMatch(x)); + if (index < 0) + return null; + + return tileRegex.Match(lines[index]).Groups["VALUE"].Value; + } + + SongGenre GetGenre(string value) + { + if (string.IsNullOrWhiteSpace(value)) + return SongGenre.Variety; + + switch (value.ToUpperInvariant()) + { + case "アニメ": + return SongGenre.Anime; + case "J-POP": + return SongGenre.Pop; + case "どうよう": + return SongGenre.Children; + case "バラエティ": + return SongGenre.Variety; + case "ボーカロイド": + case "VOCALOID": + return SongGenre.Vocaloid; + case "クラシック": + return SongGenre.Classic; + case "ゲームミュージック": + return SongGenre.Game; + case "ナムコオリジナル": + return SongGenre.Namco; + } + + return SongGenre.Variety; + } + + CourseType GetCourseType(string value) + { + switch (value.ToUpperInvariant()) + { + case "EASY": + case "0": + return CourseType.Easy; + case "NORMAL": + case "1": + return CourseType.Normal; + case "HARD": + case "2": + return CourseType.Hard; + case "ONI": + case "3": + return CourseType.Oni; + case "Edit": + case "4": + return CourseType.UraOni; + } + + return CourseType.UraOni; + } + + + } + + public const string TJAFieldRegexTemplate = "^{0}:\\s*(?.*?)\\s*$"; + public static Regex TJAKeyValueRegex = new("^(?.*?):\\s*(?.*?)\\s*$", RegexOptions.IgnoreCase); + + public static HashSet MainMetadataKeys = new() + { + "TITLE", + "TITLEEN", + "SUBTITLE", + "SUBTITLEEN", + "BPM", + "WAVE", + "OFFSET", + "DEMOSTART", + "GENRE", + "SCOREMODE", + "MAKER", + "LYRICS", + "SONGVOL", + "SEVOL", + "SIDE", + "LIFE", + "GAME", + "HEADSCROLL", + "BGIMAGE", + "BGMOVIE", + "MOVIEOFFSET", + "TAIKOWEBSKIN", + }; + + + public class Course + { + public CourseType CourseType = CourseType.Oni; + public int Level = 5; + public PlayStyle PlayStyle = PlayStyle.Single; + public bool IsBranching = false; + + public OtherMetadata Metadata = new(); + + public int CourseDataIndexStart; + public int CourseDataIndexEnd; + + public int SongDataIndexStart; + public int SongDataIndexEnd; + + public Course() + { + } + + public Course(Course course) + { + CourseType = course.CourseType; + Level = course.Level; + // PlayStyle = course.PlayStyle; + Metadata = new OtherMetadata(course.Metadata); + } + + public class OtherMetadata + { + public string Balloon; + public string ScoreInit; + public string ScoreDiff; + public string BalloonNor; + public string BalloonExp; + public string BalloonMas; + public string Exam1; + public string Exam2; + public string Exam3; + public string GaugeNcr; + public string Total; + public string HiddenBranch; + + public OtherMetadata() + { + } + + public OtherMetadata(OtherMetadata metadata) + { + Balloon = metadata.Balloon; + ScoreInit = metadata.ScoreInit; + ScoreDiff = metadata.ScoreDiff; + BalloonNor = metadata.BalloonNor; + BalloonExp = metadata.BalloonExp; + BalloonMas = metadata.BalloonMas; + Exam1 = metadata.Exam1; + Exam2 = metadata.Exam2; + Exam3 = metadata.Exam3; + GaugeNcr = metadata.GaugeNcr; + Total = metadata.Total; + HiddenBranch = metadata.HiddenBranch; + } + } + + public List MetadataToTJA(PlayStyle? playStyleOverride = null, CourseType? courseTypeOverride = null) + { + List result = new List(); + result.Add($"COURSE:{(courseTypeOverride ?? CourseType).ToString()}"); + result.Add($"LEVEL:{Level.ToString()}"); + result.Add($"STYLE:{(playStyleOverride ?? PlayStyle).ToString()}"); + + AddIfNotNull(nameof(OtherMetadata.Balloon), Metadata.Balloon); + AddIfNotNull(nameof(OtherMetadata.ScoreInit), Metadata.ScoreInit); + AddIfNotNull(nameof(OtherMetadata.ScoreDiff), Metadata.ScoreDiff); + AddIfNotNull(nameof(OtherMetadata.BalloonNor), Metadata.BalloonNor); + AddIfNotNull(nameof(OtherMetadata.BalloonExp), Metadata.BalloonExp); + AddIfNotNull(nameof(OtherMetadata.BalloonMas), Metadata.BalloonMas); + AddIfNotNull(nameof(OtherMetadata.Exam1), Metadata.Exam1); + AddIfNotNull(nameof(OtherMetadata.Exam2), Metadata.Exam2); + AddIfNotNull(nameof(OtherMetadata.Exam3), Metadata.Exam3); + AddIfNotNull(nameof(OtherMetadata.GaugeNcr), Metadata.GaugeNcr); + AddIfNotNull(nameof(OtherMetadata.Total), Metadata.Total); + AddIfNotNull(nameof(OtherMetadata.HiddenBranch), Metadata.HiddenBranch); + + void AddIfNotNull(string name, string value) + { + if (!string.IsNullOrWhiteSpace(value)) + result.Add($"{name.ToUpperInvariant()}:{value}"); + } + + return result; + } + } + + public enum PlayStyle + { + None = 0, + Single = 1, + Double = 2, + } + + + public enum SongGenre + { + Pop, + Anime, + Vocaloid, + Variety, + Children, + Classic, + Game, + Namco, + } +} + +public enum CourseType +{ + Easy, + Normal, + Hard, + Oni, + UraOni +} + +public static class CourseTypeExtensions +{ + public static string ToShort(this CourseType courseType) + { + return courseType switch + { + CourseType.Easy => "e", + CourseType.Normal => "n", + CourseType.Hard => "h", + CourseType.Oni => "m", + CourseType.UraOni => "x", + _ => throw new ArgumentOutOfRangeException(nameof(courseType), courseType, null) + }; + } +} diff --git a/TakoTakoScripts/TakoTako.Common/CustomSong.cs b/TakoTakoScripts/TakoTako.Common/CustomSong.cs new file mode 100644 index 0000000..224f14b --- /dev/null +++ b/TakoTakoScripts/TakoTako.Common/CustomSong.cs @@ -0,0 +1,204 @@ +using System; +using System.Runtime.Serialization; +using Newtonsoft.Json; + +// ReSharper disable InconsistentNaming + +namespace TakoTako.Common +{ + [DataContract(Name = "CustomSong")] + [Serializable] + public class CustomSong + { + // Song Details + [DataMember] public int uniqueId; + [DataMember] public string id; + [DataMember] public int order; + [DataMember] public int genreNo; + [DataMember] public bool branchEasy; + [DataMember] public bool branchNormal; + [DataMember] public bool branchHard; + [DataMember] public bool branchMania; + [DataMember] public bool branchUra; + [DataMember] public int starEasy; + [DataMember] public int starNormal; + [DataMember] public int starHard; + [DataMember] public int starMania; + [DataMember] public int starUra; + [DataMember] public int shinutiEasy; + [DataMember] public int shinutiNormal; + [DataMember] public int shinutiHard; + [DataMember] public int shinutiMania; + [DataMember] public int shinutiUra; + [DataMember] public int shinutiEasyDuet; + [DataMember] public int shinutiNormalDuet; + [DataMember] public int shinutiHardDuet; + [DataMember] public int shinutiManiaDuet; + [DataMember] public int shinutiUraDuet; + [DataMember] public int scoreEasy; + [DataMember] public int scoreNormal; + [DataMember] public int scoreHard; + [DataMember] public int scoreMania; + [DataMember] public int scoreUra; + + // Preview Details + [DataMember] public int previewPos; + [DataMember] public int fumenOffsetPos; + + [DataMember] public bool AreFilesGZipped; + + // LocalisationDetails + /// + /// Song Title + /// + /// A Cruel Angel's Thesis + /// + /// + [DataMember] public TextEntry songName; + + /// + /// Origin of the song + /// + /// From \" Neon Genesis EVANGELION \" + /// + /// + [DataMember] public TextEntry songSubtitle; + + /// + /// Extra details for the track, sometimes used to say it's Japanese name + /// + /// 残酷な天使のテーゼ + /// + /// + [DataMember] public TextEntry songDetail; + } + + [Serializable] + public class TextEntry + { + /// + /// The text to display by default, if any override exist, the game will use that text + /// + [JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public string text; + + /// + /// font for the default text, if any override exist, the game will use that text + /// 0 == Japanese + /// 1 == English + /// 2 == Traditional Chinese + /// 3 == Simplified Chinese + /// 4 == Korean + /// + [JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public int font; + + /// + /// 日本語 Text + /// + [JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public string jpText; + + /// + /// 日本語 Font + /// + [JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public int jpFont; + + /// + /// English Text + /// + [JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public string enText; + + /// + /// English Font + /// + [JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public int enFont; + + /// + /// Français Text + /// + [JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public string frText; + + /// + /// Français Font + /// + [JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public int frFont; + + /// + /// Italiano Text + /// + [JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public string itText; + + /// + /// Italiano Font + /// + [JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public int itFont; + + /// + /// Deutsch Text + /// + [JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public string deText; + + /// + /// Deutsch Font + /// + [JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public int deFont; + + /// + /// Español Text + /// + [JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public string esText; + + /// + /// Español Font + /// + [JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public int esFont; + + /// + /// 繁體中文 Text + /// + [JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public string tcText; + + /// + /// 繁體中文 Font + /// + [JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public int tcFont; + + /// + /// 简体中文 Text + /// + [JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public string scText; + + /// + /// 简体中文 Font + /// + [JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public int scFont; + + /// + /// 영어 Text + /// + [JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public string krText; + + /// + /// 영어 Font + /// + [JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public int krFont; + } +} diff --git a/TakoTakoScripts/TakoTako.Common/TakoTako.Common.csproj b/TakoTakoScripts/TakoTako.Common/TakoTako.Common.csproj new file mode 100644 index 0000000..93116fc --- /dev/null +++ b/TakoTakoScripts/TakoTako.Common/TakoTako.Common.csproj @@ -0,0 +1,16 @@ + + + + net48 + TakoTako.Common + TakoTako.Common + latest + + + + + ..\..\TakoTako\References\Newtonsoft.Json.dll + + + + diff --git a/TakoTakoScripts/TakoTakoScripts.Common/TakoTakoScripts.Common.csproj b/TakoTakoScripts/TakoTakoScripts.Common/TakoTakoScripts.Common.csproj new file mode 100644 index 0000000..93116fc --- /dev/null +++ b/TakoTakoScripts/TakoTakoScripts.Common/TakoTakoScripts.Common.csproj @@ -0,0 +1,16 @@ + + + + net48 + TakoTako.Common + TakoTako.Common + latest + + + + + ..\..\TakoTako\References\Newtonsoft.Json.dll + + + + diff --git a/TakoTakoScripts/TakoTakoScripts.sln b/TakoTakoScripts/TakoTakoScripts.sln new file mode 100644 index 0000000..62daa78 --- /dev/null +++ b/TakoTakoScripts/TakoTakoScripts.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TakoTako.Common", "TakoTako.Common\TakoTako.Common.csproj", "{DDD2BC9B-15CB-47AE-A104-F45A3C65C7B1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TJAConvert", "TJAConvert\TJAConvert.csproj", "{9ED2476B-FB39-4BE9-8661-21311AD9A3E8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DDD2BC9B-15CB-47AE-A104-F45A3C65C7B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DDD2BC9B-15CB-47AE-A104-F45A3C65C7B1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DDD2BC9B-15CB-47AE-A104-F45A3C65C7B1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DDD2BC9B-15CB-47AE-A104-F45A3C65C7B1}.Release|Any CPU.Build.0 = Release|Any CPU + {9ED2476B-FB39-4BE9-8661-21311AD9A3E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9ED2476B-FB39-4BE9-8661-21311AD9A3E8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9ED2476B-FB39-4BE9-8661-21311AD9A3E8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9ED2476B-FB39-4BE9-8661-21311AD9A3E8}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/TakoTakoScripts/TakoTakoScripts.sln.DotSettings b/TakoTakoScripts/TakoTakoScripts.sln.DotSettings new file mode 100644 index 0000000..0b1fe32 --- /dev/null +++ b/TakoTakoScripts/TakoTakoScripts.sln.DotSettings @@ -0,0 +1,7 @@ + + ACB + OGG + TJA + True + True + True \ No newline at end of file diff --git a/TakoTakoScripts/global.json b/TakoTakoScripts/global.json new file mode 100644 index 0000000..e5674e1 --- /dev/null +++ b/TakoTakoScripts/global.json @@ -0,0 +1,7 @@ +{ + "sdk": { + "version": "5.0.0", + "rollForward": "latestMinor", + "allowPrerelease": false + } +} \ No newline at end of file diff --git a/readme-image-0.png b/readme-image-0.png new file mode 100644 index 0000000000000000000000000000000000000000..955a581c90c95b3eb9aca94abb608843051bad8b GIT binary patch literal 33572 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 z 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

hHPmbg&1)m>WqyHgD>3dMIEm03*54t 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

gr;-a|=sUyq-h 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 wN+(li!jtK({zmbA5if#N&o-= literal 0 HcmV?d00001 diff --git a/readme-image-2.png b/readme-image-2.png new file mode 100644 index 0000000000000000000000000000000000000000..aacf67ab6d66af9be30497eb2f26fe8700a2f193 GIT binary patch literal 7334 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 literal 0 HcmV?d00001