mirror of
https://git.743378673.xyz/MeloNX/MeloNX.git
synced 2025-07-30 05:17:10 +02:00
add dlc manager
This commit is contained in:
parent
fb562c8077
commit
7a85dc2e76
9 changed files with 642 additions and 113 deletions
|
@ -152,6 +152,22 @@ namespace LibRyujinx
|
|||
return LoadApplication(path);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_deviceGetDlcContentList")]
|
||||
public static JArrayLocalRef JniGetDlcContentListNative(JEnvRef jEnv, JObjectLocalRef jObj, JStringLocalRef pathPtr, JLong titleId)
|
||||
{
|
||||
var list = GetDlcContentList(GetString(jEnv, pathPtr), (ulong)(long)titleId);
|
||||
|
||||
debug_break(4);
|
||||
|
||||
return CreateStringArray(jEnv, list);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_deviceGetDlcTitleId")]
|
||||
public static JStringLocalRef JniGetDlcTitleIdNative(JEnvRef jEnv, JObjectLocalRef jObj, JStringLocalRef pathPtr, JStringLocalRef ncaPath)
|
||||
{
|
||||
return CreateString(jEnv, GetDlcTitleId(GetString(jEnv, pathPtr), GetString(jEnv, ncaPath)));
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_deviceSignalEmulationClose")]
|
||||
public static void JniSignalEmulationCloseNative(JEnvRef jEnv, JObjectLocalRef jObj)
|
||||
{
|
||||
|
@ -296,6 +312,27 @@ namespace LibRyujinx
|
|||
return InitializeGraphicsRenderer(GraphicsBackend.Vulkan, createSurfaceFunc, extensions.ToArray());
|
||||
}
|
||||
|
||||
private static JArrayLocalRef CreateStringArray(JEnvRef jEnv, List<string> strings)
|
||||
{
|
||||
JEnvValue value = jEnv.Environment;
|
||||
ref JNativeInterface jInterface = ref value.Functions;
|
||||
IntPtr newObjectArrayPtr = jInterface.NewObjectArrayPointer;
|
||||
IntPtr findClassPtr = jInterface.FindClassPointer;
|
||||
IntPtr setObjectArrayElementPtr = jInterface.SetObjectArrayElementPointer;
|
||||
|
||||
var newObjectArray = newObjectArrayPtr.GetUnsafeDelegate<NewObjectArrayDelegate>();
|
||||
var findClass = findClassPtr.GetUnsafeDelegate<FindClassDelegate>();
|
||||
var setObjectArrayElement = setObjectArrayElementPtr.GetUnsafeDelegate<SetObjectArrayElementDelegate>();
|
||||
var array = newObjectArray(jEnv, strings.Count, findClass(jEnv, GetCCharSequence("java/lang/String")), CreateString(jEnv, "")._value);
|
||||
|
||||
for (int i = 0; i < strings.Count; i++)
|
||||
{
|
||||
setObjectArrayElement(jEnv, array, i, CreateString(jEnv, strings[i])._value);
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_graphicsRendererSetSize")]
|
||||
public static void JniSetRendererSizeNative(JEnvRef jEnv, JObjectLocalRef jObj, JInt width, JInt height)
|
||||
{
|
||||
|
|
|
@ -31,6 +31,7 @@ using Ryujinx.Common.Utilities;
|
|||
using System.Globalization;
|
||||
using Ryujinx.Ui.Common.Configuration.System;
|
||||
using Ryujinx.Common.Logging.Targets;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace LibRyujinx
|
||||
{
|
||||
|
@ -545,6 +546,83 @@ namespace LibRyujinx
|
|||
|
||||
return gameInfo;
|
||||
}
|
||||
|
||||
public static string GetDlcTitleId(string path, string ncaPath)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
using FileStream containerFile = File.OpenRead(path);
|
||||
|
||||
PartitionFileSystem partitionFileSystem = new(containerFile.AsStorage());
|
||||
|
||||
SwitchDevice.VirtualFileSystem.ImportTickets(partitionFileSystem);
|
||||
|
||||
using UniqueRef<IFile> ncaFile = new();
|
||||
|
||||
partitionFileSystem.OpenFile(ref ncaFile.Ref, ncaPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
|
||||
|
||||
Nca nca = TryOpenNca(ncaFile.Get.AsStorage(), ncaPath);
|
||||
if (nca != null)
|
||||
{
|
||||
return nca.Header.TitleId.ToString("X16");
|
||||
}
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
|
||||
private static Nca TryOpenNca(IStorage ncaStorage, string containerPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new Nca(SwitchDevice.VirtualFileSystem.KeySet, ncaStorage);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<string> GetDlcContentList(string path, ulong titleId)
|
||||
{
|
||||
if(!File.Exists(path))
|
||||
return new List<string>();
|
||||
|
||||
using FileStream containerFile = File.OpenRead(path);
|
||||
|
||||
PartitionFileSystem partitionFileSystem = new(containerFile.AsStorage());
|
||||
bool containsDownloadableContent = false;
|
||||
|
||||
SwitchDevice.VirtualFileSystem.ImportTickets(partitionFileSystem);
|
||||
List<string> paths = new List<string>();
|
||||
|
||||
foreach (DirectoryEntryEx fileEntry in partitionFileSystem.EnumerateEntries("/", "*.nca"))
|
||||
{
|
||||
using var ncaFile = new UniqueRef<IFile>();
|
||||
|
||||
partitionFileSystem.OpenFile(ref ncaFile.Ref, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
|
||||
|
||||
Nca nca = TryOpenNca(ncaFile.Get.AsStorage(), path);
|
||||
if (nca == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nca.Header.ContentType == NcaContentType.PublicData)
|
||||
{
|
||||
if ((nca.Header.TitleId & 0xFFFFFFFFFFFFE000) != titleId)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
paths.Add(fileEntry.FullPath);
|
||||
}
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
}
|
||||
|
||||
public class SwitchDevice : IDisposable
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue