1
0
mirror of synced 2024-11-27 15:30:49 +01:00

Loading custom songs shouldn't lag on the song select screen

This commit is contained in:
Fluto 2022-08-20 15:09:09 +10:00
parent fafe244e21
commit e38444ffb7
2 changed files with 34 additions and 103 deletions

View File

@ -10,7 +10,6 @@ using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using BepInEx.Logging; using BepInEx.Logging;
using Blittables;
using HarmonyLib; using HarmonyLib;
#if TAIKO_IL2CPP #if TAIKO_IL2CPP
using UnhollowerBaseLib; using UnhollowerBaseLib;
@ -553,6 +552,7 @@ public class CustomMusicLoaderPatch
); );
musicInfoAccessors.Add(musicInfo); musicInfoAccessors.Add(musicInfo);
} }
#endregion #endregion
BubbleSort(musicInfoAccessors, (a, b) => a.Order - b.Order); BubbleSort(musicInfoAccessors, (a, b) => a.Order - b.Order);
@ -710,7 +710,7 @@ public class CustomMusicLoaderPatch
wordDataInterface.wordListInfoAccessers = musicInfoAccessors; wordDataInterface.wordListInfoAccessers = musicInfoAccessors;
return wordDataInterface; return wordDataInterface;
(string text, int font) GetValuesWordList(WordListInfo wordListInfo) (string text, int font) GetValuesWordList(WordListInfo wordListInfo)
{ {
string text; string text;
@ -1018,7 +1018,6 @@ public class CustomMusicLoaderPatch
__instance.SongList.Clear(); __instance.SongList.Clear();
foreach (var song in unsortedSongList) foreach (var song in unsortedSongList)
__instance.SongList.Add(song); __instance.SongList.Add(song);
__instance.UnsortedSongList = unsortedSongList; __instance.UnsortedSongList = unsortedSongList;
@ -1663,13 +1662,13 @@ public class CustomMusicLoaderPatch
[HarmonyPatch(typeof(Cryptgraphy), nameof(Cryptgraphy.ReadAllAesAndGZipBytes))] [HarmonyPatch(typeof(Cryptgraphy), nameof(Cryptgraphy.ReadAllAesAndGZipBytes))]
[HarmonyPrefix] [HarmonyPrefix]
private static bool ReadAllAesAndGZipBytes_Prefix(string path, Cryptgraphy.AesKeyType type, private static bool ReadAllAesAndGZipBytes_Prefix(string path, Cryptgraphy.AesKeyType type,
#if TAIKO_IL2CPP #if TAIKO_IL2CPP
ref Il2CppStructArray<byte> __result ref Il2CppStructArray<byte> __result
#elif TAIKO_MONO #elif TAIKO_MONO
ref byte[] __result ref byte[] __result
#endif #endif
) )
{ {
if (pathToData.TryGetValue(path, out var data)) if (pathToData.TryGetValue(path, out var data))
{ {
@ -1812,114 +1811,46 @@ public class CustomMusicLoaderPatch
#region Read Song #region Read Song
private static readonly Regex musicFilePathRegex = new Regex("^song_(?<songName>.*?_custom_\\d*?)$"); private static readonly Regex sheetNameRegex = new Regex("^song_(?<songName>.*?_custom_\\d*?)$");
private static readonly Regex songFilePathRegex = new Regex("sound\\/(?<sheetName>.*?)\\.bin$");
/// <summary>
/// Read an unencrypted song "asynchronously" (it does it instantly, we should have fast enough PCs right?) [HarmonyPatch(typeof(Cryptgraphy), nameof(Cryptgraphy.ReadAllAesBytesAsyncInternal))]
/// </summary>
/// <param name="__instance"></param>
[HarmonyPatch(typeof(CriPlayer), nameof(CriPlayer.LoadAsync))]
[HarmonyPrefix] [HarmonyPrefix]
[HarmonyWrapSafe] [HarmonyWrapSafe]
public static bool LoadAsync_Postfix(CriPlayer __instance, public static bool ReadAllAesBytesAsyncInternal_Prefix(string path, Cryptgraphy.AesKeyType type, Cryptgraphy.Request request)
#if TAIKO_IL2CPP
ref Il2CppSystem.Collections.IEnumerator __result
#elif TAIKO_MONO
ref IEnumerator __result
#endif
)
{ {
var sheetName = __instance.CueSheetName; var pathMatch = songFilePathRegex.Match(path);
var path = UnityEngine.Application.streamingAssetsPath + "/sound/" + sheetName + ".bin"; if (!pathMatch.Success)
if (File.Exists(path))
return true; return true;
var match = musicFilePathRegex.Match(sheetName); var sheetName = pathMatch.Groups["sheetName"].Value;
if (!match.Success) var sheetNameMatch = sheetNameRegex.Match(sheetName);
{ if (!sheetNameMatch.Success)
Log.LogError($"Cannot interpret {sheetName}");
return true; return true;
}
var songName = match.Groups["songName"].Value; var songName = sheetNameMatch.Groups["songName"].Value;
if (!idToSong.TryGetValue(songName, out var songInstance)) if (!idToSong.TryGetValue(songName, out var songInstance))
{ {
Log.LogError($"Cannot find song : {songName}"); Log.LogError($"Cannot find song : {songName}");
return true; return true;
} }
__instance.isLoadingAsync = true;
__instance.isCancelLoadingAsync = false;
__instance.IsPrepared = false;
__instance.IsLoadSucceed = false;
__instance.LoadingState = CriPlayer.LoadingStates.Loading;
__instance.LoadTime = -1f;
__instance.loadStartTime = UnityEngine.Time.time;
// Run this on the next frame var newPath = Path.Combine(songInstance.FolderPath, $"{sheetName.Replace(songName, songInstance.SongName)}.bin");
#if TAIKO_IL2CPP
__result = LoadAsync().WrapToIl2Cpp(); var bytes = File.ReadAllBytes(newPath);
#elif TAIKO_MONO if (songInstance.areFilesGZipped)
__result = LoadAsync();
#endif
return false;
IEnumerator LoadAsync()
{ {
yield return null; using var memoryStream = new MemoryStream(bytes);
using var destination = new MemoryStream();
var newPath = Path.Combine(songInstance.FolderPath, $"{sheetName.Replace(songName, songInstance.SongName)}.bin"); using var gzipStream = new GZipStream(memoryStream, CompressionMode.Decompress);
var task = Task.Run(async () => gzipStream.CopyTo(destination);
{ bytes = destination.ToArray();
try
{
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);
await gzipStream.CopyToAsync(destination);
bytes = destination.ToArray();
}
return bytes;
}
catch (Exception e)
{
Log.LogError(e);
return null;
}
});
do
{
yield return null;
} while (!task.IsCompleted);
var bytes = task.Result;
var cueSheet = CriAtom.AddCueSheetAsync(sheetName, bytes, null);
__instance.CueSheet = cueSheet;
if (cueSheet != null)
{
while (cueSheet.IsLoading)
yield return null;
__instance.isLoadingAsync = false;
__instance.IsLoadSucceed = true;
__instance.LoadingState = CriPlayer.LoadingStates.Finished;
__instance.LoadTime = 0;
yield break;
}
Log.LogError($"Could not load music");
__instance.LoadingState = CriPlayer.LoadingStates.Finished;
__instance.isLoadingAsync = false;
} }
request.Bytes = bytes;
request.IsDone = true;
return false;
} }
/// <summary> /// <summary>
@ -1935,7 +1866,7 @@ public class CustomMusicLoaderPatch
if (File.Exists(path)) if (File.Exists(path))
return true; return true;
var match = musicFilePathRegex.Match(sheetName); var match = sheetNameRegex.Match(sheetName);
if (!match.Success) if (!match.Success)
{ {
Log.LogError($"Cannot interpret {sheetName}"); Log.LogError($"Cannot interpret {sheetName}");

View File

@ -110,8 +110,8 @@ namespace TakoTako
ConfigAutomaticallyStartGame = Config.Bind("General", ConfigAutomaticallyStartGame = Config.Bind("General",
"AutomaticallyStartGame", "AutomaticallyStartGame",
true, false,
"When true this will continue on the main menu"); "When true this will continue on the main menu ");
ConfigSkipDLCCheck = Config.Bind("General", ConfigSkipDLCCheck = Config.Bind("General",
"SkipDLCCheck", "SkipDLCCheck",