Cache downloaded base libraries in the unity-libs directory (#1213)

This commit is contained in:
ManlyMarco authored and GitHub committed 2025-11-16 19:49:19 +01:00
1 parent 88b4838fef
commit dd0655fe9d
1 file changed
+31 -17
@@ -58,9 +58,10 @@ internal static partial class Il2CppInteropManager
"IL2CPP", "UnityBaseLibrariesSource",
"https://unity.bepinex.dev/libraries/{VERSION}.zip",
new StringBuilder()
.AppendLine("URL to the ZIP of managed Unity base libraries.")
.AppendLine("The base libraries are used by Il2CppInterop to generate interop assemblies.")
.AppendLine("URL to a ZIP file with managed Unity base libraries. They are used by Il2CppInterop to generate interop assemblies.")
.AppendLine("The URL can include {VERSION} template which will be replaced with the game's Unity engine version.")
.AppendLine("If a .zip file with the same filename as the URL (after template replacement) already exists in unity-libs, it will be used instead of downloading a new copy.")
.AppendLine("If you want to ensure BepInEx doesn't try to connect to the internet, set this to only the .zip filename (without a URL) and manually place the file in the unity-libs directory.")
.ToString());
private static readonly ConfigEntry<string> ConfigUnhollowerDeobfuscationRegex = ConfigFile.CoreConfig.Bind(
@@ -288,25 +289,38 @@ internal static partial class Il2CppInteropManager
var source = UnityBaseLibrariesSource.Value.Replace("{VERSION}", version);
if (string.IsNullOrEmpty(source)) return;
var uri = new Uri(source);
string file = Path.GetFileName(uri.AbsolutePath);
var baseFolder = Directory.CreateDirectory(UnityBaseLibsDirectory);
baseFolder.EnumerateFiles("*.dll").Do(a=>a.Delete());
var target = baseFolder.GetFiles(file).FirstOrDefault();
if (target != null) {
Logger.LogMessage($"Reading unity base libraries from file {source}");
using var fStream = target.OpenRead();
using var zipArchive = new ZipArchive(fStream, ZipArchiveMode.Read);
zipArchive.ExtractToDirectory(UnityBaseLibsDirectory);
} else {
Logger.LogMessage($"Downloading unity base libraries {source}");
var uriIsValid = Uri.TryCreate(source, UriKind.Absolute, out var uri) && (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps);
var fileName = Path.GetFileName(uriIsValid ? uri.AbsolutePath : source);
var zipFilePath = Path.Combine(baseFolder.FullName, fileName);
if (!File.Exists(zipFilePath))
{
// Check if URI is valid before attempting download
if (!uriIsValid)
throw new ArgumentException($"Unity base libraries source \"{source}\" is not a valid URL and the .zip file does not exist locally. Either provide a valid HTTP/HTTPS URL, or place the .zip file in the unity-libs directory.");
Logger.LogMessage($"Downloading unity base libraries from {source}");
using var httpClient = new HttpClient();
using var zipStream = httpClient.GetStreamAsync(source).GetAwaiter().GetResult();
Logger.LogMessage("Extracting downloaded unity base libraries");
using var zipArchive = new ZipArchive(zipStream, ZipArchiveMode.Read);
zipArchive.ExtractToDirectory(UnityBaseLibsDirectory);
using var zipStream = httpClient.GetStreamAsync(uri).GetAwaiter().GetResult();
try
{
using var writeStream = new FileStream(zipFilePath, FileMode.Create, FileAccess.Write, FileShare.None);
zipStream.CopyTo(writeStream);
}
catch
{
// Delete the incomplete file to avoid issues on next startup
try { File.Delete(zipFilePath); } catch { }
throw;
}
}
Logger.LogMessage($"Extracting unity base libraries from {zipFilePath}");
using var readStream = File.OpenRead(zipFilePath);
using var zipArchive = new ZipArchive(readStream, ZipArchiveMode.Read);
zipArchive.ExtractToDirectory(UnityBaseLibsDirectory);
}
private static List<AsmResolver.DotNet.AssemblyDefinition> RunCpp2Il()