Skip to content

Commit

Permalink
Implement copyToBase
Browse files Browse the repository at this point in the history
Replacement for copyToData; closes #22
  • Loading branch information
TrevTV committed Oct 23, 2024
1 parent f3042bc commit 785e727
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 0 deletions.
2 changes: 2 additions & 0 deletions MelonLoader/Core.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ internal static int Initialize()
APKAssetManager.Initialize();
MelonLogger.Msg("Initialized JNI");

APKAssetManager.CopyAdditionalData();

if (IsBad(MelonEnvironment.PackageName))
throw new Exception();

Expand Down
47 changes: 47 additions & 0 deletions MelonLoader/Utils/APKAssetManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,42 @@ public static void Initialize()
GetAndroidAssetManager();
}

public static void CopyAdditionalData()
{
SaveItemToDirectory("copyToBase/", MelonEnvironment.MelonBaseDirectory, false);
}

public static void SaveItemToDirectory(string itemPath, string copyBase, bool includeInitial = true)
{
string[] contents = GetDirectoryContents(itemPath);
if (contents.Length == 0)
{
string path = includeInitial ? itemPath : itemPath[(itemPath.IndexOf('/') + 1)..];
if (string.IsNullOrEmpty(path))
return;

string outPath = Path.Combine(copyBase, path);
string outDir = Path.GetDirectoryName(outPath);

if (!Directory.Exists(outDir))
Directory.CreateDirectory(outDir);

using FileStream fileStream = File.Open(outPath, FileMode.Create);
using Stream assetStream = GetAssetStream(itemPath);

byte[] buffer = new byte[assetStream.Length];
assetStream.Read(buffer, 0, buffer.Length);
fileStream.Write(buffer, 0, buffer.Length);

return;
}

foreach (string item in contents)
{
SaveItemToDirectory(Path.Combine(itemPath, item), copyBase, includeInitial);
}
}

public static byte[] GetAssetBytes(string path)
{
JString pathString = JNI.NewString(path);
Expand Down Expand Up @@ -53,6 +89,17 @@ public static Stream GetAssetStream(string path)
return new APKAssetStream(asset);
}

public static string[] GetDirectoryContents(string directory)
{
JString pathString = JNI.NewString(directory);
JObjectArray<JString> assets = JNI.CallObjectMethod<JObjectArray<JString>>(assetManager, JNI.GetMethodID(JNI.GetObjectClass(assetManager), "list", "(Ljava/lang/String;)[Ljava/lang/String;"), new JValue(pathString));

string[] cleanAssets = assets.Select(a => a.GetString()).ToArray();
HandleException();

return cleanAssets;
}

public static bool DoesAssetExist(string path)
{
// using `list` isn't as fast as just calling open, but this allows the function to not crash on debuggable builds of apps
Expand Down

0 comments on commit 785e727

Please sign in to comment.