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
+
+
+ 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