Skip to content

Commit 7ef7286

Browse files
authored
Merge pull request #21 from MDMods/development
v4.1.7: Inject custom IData into the DataHelper.highest list
2 parents 1d560d9 + 579aa5b commit 7ef7286

18 files changed

+364
-121
lines changed

Data/Album.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ public class Album
1010
{
1111
private static readonly Logger Logger = new(nameof(Album));
1212

13-
public Album(string path, int index)
13+
public Album(string path, int index, string packName = null)
1414
{
15-
if (Directory.Exists(path))
15+
// If packName is not null then it's a file path, not a folder chart
16+
if (Directory.Exists(path) && packName == null)
1617
{
1718
// Load album from directory
1819
if (!File.Exists($"{path}\\info.json"))
@@ -27,6 +28,7 @@ public Album(string path, int index)
2728
else if (File.Exists(path))
2829
{
2930
// Load album from package
31+
PackName = packName;
3032
using var zip = ZipFile.OpenRead(path);
3133
var info = zip.GetEntry("info.json");
3234
if (info == null)
@@ -38,6 +40,9 @@ public Album(string path, int index)
3840
using var stream = info.Open();
3941
Info = Json.Deserialize<AlbumInfo>(stream);
4042
IsPackaged = true;
43+
44+
// CurrentPack will always be null if album is not in a pack
45+
IsPack = AlbumManager.CurrentPack != null;
4146
}
4247
else
4348
{
@@ -54,14 +59,18 @@ public Album(string path, int index)
5459
public int Index { get; }
5560
public string Path { get; }
5661
public bool IsPackaged { get; }
62+
public bool IsPack { get; }
63+
public string PackName { get; }
5764
public AlbumInfo Info { get; }
5865
public Sprite Cover => this.GetCover();
5966
public AnimatedCover AnimatedCover => this.GetAnimatedCover();
6067
public AudioClip Music => this.GetAudio();
6168
public AudioClip Demo => this.GetAudio("demo");
6269
public Dictionary<int, Sheet> Sheets { get; } = new();
6370
public string AlbumName =>
64-
IsPackaged ? $"album_{System.IO.Path.GetFileNameWithoutExtension(Path)}" : $"album_{System.IO.Path.GetFileName(Path)}_folder";
71+
IsPackaged ?
72+
$"album_{System.IO.Path.GetFileNameWithoutExtension(Path)}{(PackName != null ? $"_{PackName}" : string.Empty)}"
73+
: $"album_{System.IO.Path.GetFileName(Path)}_folder";
6574
public string Uid => $"{AlbumManager.Uid}-{Index}";
6675

6776
public bool HasFile(string name)

Data/Pack.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using CustomAlbums.Managers;
2+
3+
namespace CustomAlbums.Data
4+
{
5+
public class Pack
6+
{
7+
public string Title { get; set; } = AlbumManager.GetCustomAlbumsTitle();
8+
public string TitleColorHex { get; set; } = "#ffffff";
9+
public bool LongTextScroll { get; set; } = false;
10+
11+
internal int StartIndex;
12+
internal int Length;
13+
}
14+
}

Data/SceneEggs.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ public enum SceneEggs
1111
Touhou = 3,
1212
Arknights = 4,
1313
Miku = 5,
14-
RinLen = 6,
14+
RinLen = 6,
15+
BlueArchive = 7,
1516
BadApple = 129,
1617
Christmas = 999
1718
}

Data/Setlist.cs

Lines changed: 0 additions & 13 deletions
This file was deleted.

Main.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public class Main : MelonMod
1212

1313
public const string MelonName = "CustomAlbums";
1414
public const string MelonAuthor = "Two Fellas";
15-
public const string MelonVersion = "4.1.6";
15+
public const string MelonVersion = "4.1.7";
1616

1717
public override void OnInitializeMelon()
1818
{

Managers/AlbumManager.cs

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using CustomAlbums.Data;
22
using CustomAlbums.ModExtensions;
33
using CustomAlbums.Utilities;
4+
using Il2CppAssets.Scripts.PeroTools.Commons;
5+
using Il2CppAssets.Scripts.PeroTools.GeneralLocalization;
46
using Il2CppPeroTools2.Resources;
57
using UnityEngine;
68
using Logger = CustomAlbums.Utilities.Logger;
@@ -29,20 +31,55 @@ public static class AlbumManager
2931
internal static Events.LoadAlbumEvent OnAlbumLoaded;
3032

3133
private static int MaxCount { get; set; }
34+
internal static string CurrentPack { get; set; } = null;
3235
public static Dictionary<string, Album> LoadedAlbums { get; } = new();
3336

37+
38+
public static void LoadMany(string directory)
39+
{
40+
// Get the files from the directory
41+
var files = Directory.EnumerateFiles(directory);
42+
43+
// Filter for .mdm files and find the pack.json file
44+
var mdms = files.Where(file => Path.GetExtension(file).EqualsCaseInsensitive(".mdm")).ToList();
45+
var json = files.FirstOrDefault(file => Path.GetFileName(file).EqualsCaseInsensitive("pack.json"));
46+
47+
// Initialize pack and variables
48+
var pack = PackManager.CreatePack(json);
49+
CurrentPack = pack.Title;
50+
pack.StartIndex = MaxCount;
51+
52+
// Count successfully loaded .mdm files
53+
pack.Length = mdms.Count(file => LoadOne(file) != null);
54+
55+
// Set the current pack to null and add the pack to the pack list
56+
CurrentPack = null;
57+
PackManager.AddPack(pack);
58+
}
59+
3460
public static Album LoadOne(string path)
3561
{
3662
MaxCount = Math.Max(LoadedAlbums.Count, MaxCount);
37-
var fileName = File.GetAttributes(path).HasFlag(FileAttributes.Directory) ? Path.GetFileName(path) : Path.GetFileNameWithoutExtension(path);
63+
var isDirectory = File.GetAttributes(path).HasFlag(FileAttributes.Directory);
64+
var fileName = isDirectory ? Path.GetFileName(path) : Path.GetFileNameWithoutExtension(path);
65+
3866
if (LoadedAlbums.ContainsKey(fileName)) return null;
39-
67+
4068
try
4169
{
42-
var album = new Album(path, MaxCount);
70+
if (isDirectory && Directory.EnumerateFiles(path)
71+
.Any(file => Path.GetFileName(file)
72+
.EqualsCaseInsensitive("pack.json")))
73+
{
74+
LoadMany(path);
75+
return null;
76+
}
77+
78+
var album = new Album(path, MaxCount, CurrentPack);
4379
if (album.Info is null) return null;
4480

4581
var albumName = album.AlbumName;
82+
4683
LoadedAlbums.Add(albumName, album);
4784

4885
if (album.HasFile("cover.png") || album.HasFile("cover.gif"))
@@ -94,5 +131,17 @@ public static IEnumerable<string> GetAlbumUidsFromNames(this IEnumerable<string>
94131
return albumNames.Where(name => LoadedAlbums.ContainsKey(name))
95132
.Select(name => $"{Uid}-{LoadedAlbums[name].Index}");
96133
}
134+
135+
/// <summary>
136+
/// Gets the current "Custom Albums" title based on language.
137+
/// </summary>
138+
/// <returns>The current "Custom Albums" title based on language.</returns>
139+
public static string GetCustomAlbumsTitle()
140+
{
141+
return Languages.GetValueOrDefault(
142+
SingletonScriptableObject<LocalizationSettings>
143+
.instance?
144+
.GetActiveOption("Language") ?? "English");
145+
}
97146
}
98147
}

Managers/PackManager.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using CustomAlbums.Data;
2+
using CustomAlbums.Utilities;
3+
4+
namespace CustomAlbums.Managers
5+
{
6+
internal class PackManager
7+
{
8+
private static readonly List<Pack> Packs = new();
9+
internal static Pack GetPackFromUid(string uid)
10+
{
11+
// If the uid is not custom or parsing the index fails
12+
if (!uid.StartsWith($"{AlbumManager.Uid}-") ||
13+
!uid[4..].TryParseAsInt(out var uidIndex)) return null;
14+
15+
// Retrieve the pack that the uid belongs to
16+
var pack = Packs.FirstOrDefault(pack =>
17+
uidIndex >= pack.StartIndex && uidIndex < pack.StartIndex + pack.Length);
18+
19+
// If the pack has no albums in it return null, otherwise return pack (will be null if it doesn't exist)
20+
return pack?.Length == 0 ? null : pack;
21+
}
22+
23+
internal static Pack CreatePack(string file)
24+
{
25+
return Json.Deserialize<Pack>(File.OpenRead(file));
26+
}
27+
28+
internal static void AddPack(Pack pack)
29+
{
30+
Packs.Add(pack);
31+
}
32+
}
33+
}

Managers/SaveManager.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using CustomAlbums.Data;
44
using CustomAlbums.Utilities;
55
using System.IO.Compression;
6+
using CustomAlbums.Patches;
67

78
namespace CustomAlbums.Managers
89
{
@@ -216,9 +217,19 @@ internal static void SaveScore(string uid, int musicDifficulty, int score, float
216217
if (musicDifficulty is 2 && AlbumManager.LoadedAlbums[albumName].HasDifficulty(3) && newScore.Evaluate >= 4)
217218
SaveData.UnlockedMasters.Add(albumName);
218219

219-
if (miss != 0) return;
220+
// Update the IData for the played chart
221+
var dataIndex = DataInjectPatch.DataList.GetIndexByUid(album.Uid, musicDifficulty);
222+
if (dataIndex != -1)
223+
{
224+
DataInjectPatch.DataList.RemoveAt(dataIndex);
225+
}
226+
227+
var newIData = DataInjectPatch.CreateIData(album, musicDifficulty, newScore);
228+
DataInjectPatch.DataList.Add(newIData);
220229

221230
// If there were no misses then add the chart/difficulty to the FullCombo list
231+
if (miss != 0) return;
232+
222233
SaveData.FullCombo.TryAdd(albumName, new List<int>());
223234

224235
if (!SaveData.FullCombo[albumName].Contains(musicDifficulty))

Patches/AssetPatch.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ internal class AssetPatch
3939
/// </summary>
4040
/// <param name="oldAssetName">The old assetName.</param>
4141
/// <param name="newAssetName">The new assetName where the value should be bound.</param>
42-
/// <returns>true if the key was successfully bound; otherwise, false.</returns>
42+
/// <returns><see langword="true"/> if the key was successfully bound; otherwise, <see langword="false"/>.</returns>
4343
internal static bool ModifyCacheKey(string oldAssetName, string newAssetName)
4444
{
4545
var success = AssetCache.Remove(oldAssetName, out var asset);
@@ -50,7 +50,7 @@ internal static bool ModifyCacheKey(string oldAssetName, string newAssetName)
5050
/// Removes a KeyValuePair from the asset cache.
5151
/// </summary>
5252
/// <param name="key">The key corresponding to the value to be removed.</param>
53-
/// <returns>true if the entry was successfully removed; otherwise, false.</returns>
53+
/// <returns><see langword="true"/> if the entry was successfully removed; otherwise, <see langword="false"/>.</returns>
5454
internal static bool RemoveFromCache(string key)
5555
{
5656
return AssetCache.Remove(key);
@@ -240,8 +240,8 @@ internal static void InitializeHandler()
240240
}
241241

242242
/// <summary>
243-
/// Gets <c>LoadFromName&lt;TextAsset&gt;</c> and detours it using a
244-
/// <c>NativeHook&lt;LoadFromNameDelegate&gt;</c> to <c>LoadFromNamePatch</c>.
243+
/// Gets <see cref="ResourcesManager.LoadFromName{}"/> where T : <see cref="TextAsset"/> and detours it using a
244+
/// <see cref="NativeHook{}"/> where T : <see cref="LoadFromNameDelegate"/> to <c>LoadFromNamePatch</c>.
245245
/// </summary>
246246
internal static unsafe void AttachHook()
247247
{
@@ -277,11 +277,11 @@ internal static unsafe void AttachHook()
277277
/// Modifies certain game data as it get loaded.
278278
/// The game data that is modified directly adds support for custom albums.
279279
/// </summary>
280-
/// <param name="instance">The instance of ResourceManager calling LoadFromName.</param>
280+
/// <param name="instance">The instance of <c>ResourceManager</c> calling <c>LoadFromName</c>.</param>
281281
/// <param name="assetNamePtr">The pointer to the string assetName.</param>
282282
/// <param name="nativeMethodInfo">Method info used by the original method.</param>
283283
/// <returns>
284-
/// A pointer of either a newly created asset if it exists or the original asset pointer if a new one was not
284+
/// An <see cref="IntPtr"/> of either a newly created asset if it exists or the original asset <see cref="IntPtr"/> if a new one was not
285285
/// created.
286286
/// </returns>
287287
[UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) })]
@@ -348,7 +348,7 @@ private static IntPtr LoadFromNamePatch(IntPtr instance, IntPtr assetNamePtr, In
348348
/// </summary>
349349
/// <param name="name"></param>
350350
/// <param name="text"></param>
351-
/// <returns>A new TextAsset initialized with the parameters.</returns>
351+
/// <returns>A new <see cref="TextAsset"/> initialized with the parameters.</returns>
352352
private static TextAsset CreateTextAsset(string name, string text)
353353
{
354354
return new TextAsset(text)

0 commit comments

Comments
 (0)