200 lines
6.5 KiB
C#
200 lines
6.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Threading.Tasks;
|
|
using Serilog;
|
|
using Serilog.Sinks.Unity3D;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using VRC.PackageManagement.Core;
|
|
using VRC.PackageManagement.Core.Types;
|
|
using VRC.PackageManagement.Core.Types.Packages;
|
|
using Version = VRC.PackageManagement.Core.Types.VPMVersion.Version;
|
|
|
|
namespace VRC.PackageManagement.Resolver
|
|
{
|
|
|
|
[InitializeOnLoad]
|
|
public class Resolver
|
|
{
|
|
private const string _projectLoadedKey = "PROJECT_LOADED";
|
|
|
|
private static string _projectDir;
|
|
public static string ProjectDir
|
|
{
|
|
get
|
|
{
|
|
if (_projectDir != null)
|
|
{
|
|
return _projectDir;
|
|
}
|
|
|
|
try
|
|
{
|
|
_projectDir = new DirectoryInfo(Assembly.GetExecutingAssembly().Location).Parent.Parent.Parent
|
|
.FullName;
|
|
return _projectDir;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
return "";
|
|
}
|
|
}
|
|
}
|
|
|
|
static Resolver()
|
|
{
|
|
SetupLogging();
|
|
if (!SessionState.GetBool(_projectLoadedKey, false))
|
|
{
|
|
#pragma warning disable 4014
|
|
CheckResolveNeeded();
|
|
#pragma warning restore 4014
|
|
}
|
|
}
|
|
|
|
private static void SetupLogging()
|
|
{
|
|
VRCLibLogger.SetLoggerDirectly(
|
|
new LoggerConfiguration()
|
|
.MinimumLevel.Information()
|
|
.WriteTo.Unity3D()
|
|
.CreateLogger()
|
|
);
|
|
}
|
|
|
|
private static async Task CheckResolveNeeded()
|
|
{
|
|
SessionState.SetBool(_projectLoadedKey, true);
|
|
|
|
//Wait for project to finish compiling
|
|
while (EditorApplication.isCompiling || EditorApplication.isUpdating)
|
|
{
|
|
await Task.Delay(250);
|
|
}
|
|
|
|
try
|
|
{
|
|
|
|
if (string.IsNullOrWhiteSpace(ProjectDir))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (VPMProjectManifest.ResolveIsNeeded(ProjectDir))
|
|
{
|
|
Debug.Log($"Resolve needed.");
|
|
var result = EditorUtility.DisplayDialog("VRChat Package Management",
|
|
$"This project requires some VRChat Packages which are not in the project yet.\n\nPress OK to download and install them.",
|
|
"OK", "Show Me What's Missing");
|
|
if (result)
|
|
{
|
|
ResolveStatic(ProjectDir);
|
|
}
|
|
else
|
|
{
|
|
ResolverWindow.ShowWindow();
|
|
}
|
|
}
|
|
}
|
|
catch (Exception)
|
|
{
|
|
// Unity says we can't open windows from this function so it throws an exception but also works fine.
|
|
}
|
|
}
|
|
|
|
public static bool VPMManifestExists()
|
|
{
|
|
return VPMProjectManifest.Exists(ProjectDir, out _);
|
|
}
|
|
|
|
public static void CreateManifest()
|
|
{
|
|
VPMProjectManifest.Load(ProjectDir);
|
|
ResolverWindow.Refresh();
|
|
}
|
|
|
|
public static void ResolveManifest()
|
|
{
|
|
ResolveStatic(ProjectDir);
|
|
}
|
|
|
|
public static void ResolveStatic(string dir)
|
|
{
|
|
// Todo: calculate and show actual progress
|
|
EditorUtility.DisplayProgressBar($"Getting all VRChat Packages", "Downloading and Installing...", 0.5f);
|
|
VPMProjectManifest.Resolve(ProjectDir);
|
|
EditorUtility.ClearProgressBar();
|
|
ForceRefresh();
|
|
}
|
|
|
|
public static List<string> GetAllVersionsOf(string id)
|
|
{
|
|
var project = new UnityProject(ProjectDir);
|
|
|
|
var versions = new List<string>();
|
|
foreach (var provider in Repos.GetAll)
|
|
{
|
|
var packagesWithVersions = provider.GetAllWithVersions();
|
|
|
|
foreach (var packageVersionList in packagesWithVersions)
|
|
{
|
|
foreach (var package in packageVersionList.Value.VersionsDescending)
|
|
{
|
|
if (package.Id != id)
|
|
continue;
|
|
if (Version.TryParse(package.Version, out var result))
|
|
{
|
|
if (!versions.Contains(package.Version))
|
|
versions.Add(package.Version);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Sort packages in project to the top
|
|
var sorted = from entry in versions orderby project.VPMProvider.HasPackage(entry) descending select entry;
|
|
|
|
return sorted.ToList<string>();
|
|
}
|
|
|
|
public static List<string> GetAffectedPackageList(IVRCPackage package)
|
|
{
|
|
List<string> list = new List<string>();
|
|
|
|
var project = new UnityProject(ProjectDir);
|
|
|
|
if (Repos.GetAllDependencies(package, out Dictionary<string, string> dependencies, null))
|
|
{
|
|
foreach (KeyValuePair<string, string> item in dependencies)
|
|
{
|
|
project.VPMProvider.Refresh();
|
|
if (project.VPMProvider.GetPackage(item.Key, item.Value) == null)
|
|
{
|
|
IVRCPackage d = Repos.GetPackageWithVersionMatch(item.Key, item.Value);
|
|
if (d != null)
|
|
{
|
|
list.Add(d.Id + " " + d.Version + "\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public static void ForceRefresh ()
|
|
{
|
|
MethodInfo method = typeof( UnityEditor.PackageManager.Client ).GetMethod( "Resolve", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.DeclaredOnly );
|
|
if( method != null )
|
|
method.Invoke( null, null );
|
|
|
|
AssetDatabase.Refresh();
|
|
}
|
|
|
|
}
|
|
} |