373 lines
14 KiB
C#
373 lines
14 KiB
C#
/*
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
* All rights reserved.
|
|
*
|
|
* Licensed under the Oculus SDK License Agreement (the "License");
|
|
* you may not use the Oculus SDK except in compliance with the License,
|
|
* which is provided at the time of installation or download, or which
|
|
* otherwise accompanies this software in either electronic or hard copy form.
|
|
*
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* https://developer.oculus.com/licenses/oculussdk/
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Reflection;
|
|
using UnityEngine;
|
|
using UnityEditor;
|
|
|
|
using PackageInfo = UnityEditor.PackageManager.PackageInfo;
|
|
using Debug = UnityEngine.Debug;
|
|
using System.Diagnostics;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Oculus.Interaction
|
|
{
|
|
[InitializeOnLoad]
|
|
public class PluginUpdater
|
|
{
|
|
private static bool _isRestarting = false;
|
|
private static string _keyBase = "Oculus_Interaction_PluginUpdater";
|
|
private static string _keyDontAsk = _keyBase + "_DontAsk";
|
|
private static string _keyIsInstalling = _keyBase + "_IsRestarting";
|
|
private static BuildTarget[] buildTargets = { BuildTarget.Android, BuildTarget.StandaloneWindows, BuildTarget.StandaloneWindows64 };
|
|
private static string _baseDllName = "InteractionSdk";
|
|
|
|
static PluginUpdater()
|
|
{
|
|
EditorApplication.delayCall += HandleDelayCall;
|
|
}
|
|
|
|
[MenuItem("Meta/Interaction/Update Interaction SDK Plugin")]
|
|
public static void UpdatePlugin()
|
|
{
|
|
PerformUpdate(verbose: true);
|
|
}
|
|
|
|
private static string GetProjectPath()
|
|
{
|
|
string path = Application.dataPath;
|
|
string token = "/Assets";
|
|
if (path.EndsWith(token))
|
|
{
|
|
path = path.Substring(0, path.Length - token.Length);
|
|
}
|
|
|
|
return path;
|
|
}
|
|
|
|
public static void HandleDelayCall()
|
|
{
|
|
if (!EditorApplication.isPlaying && !_isRestarting)
|
|
{
|
|
// first off, check to see if there's NO current dll for the build targets, and if so just copy the new one over right now since there won't be a chance of write blocking
|
|
foreach (BuildTarget t in buildTargets)
|
|
{
|
|
if (IsNewLibraryPresent(t) && !IsCurrentLibraryPresent(t))
|
|
{
|
|
MoveNewLibary(t);
|
|
}
|
|
}
|
|
|
|
// only do the moving when not running and not called from command line in batch mode
|
|
if (!Application.isBatchMode)
|
|
{
|
|
// has an install been started and Unity just got restarted?
|
|
// If so, start moving the new libraries into the names where the old ones were located
|
|
if (PlayerPrefs.GetInt(_keyIsInstalling, 0) > 0)
|
|
{
|
|
foreach (BuildTarget t in buildTargets)
|
|
{
|
|
if (IsNewLibraryPresent(t))
|
|
{
|
|
MoveNewLibary(t);
|
|
}
|
|
}
|
|
|
|
// mark as done for next time Unity starts
|
|
PlayerPrefs.SetInt(_keyIsInstalling, 0);
|
|
}
|
|
else if (PlayerPrefs.GetInt(_keyDontAsk, 0) == 0)
|
|
{
|
|
// if user hasn't asked us to stop bugging them, go on and ask 'em
|
|
PerformUpdate(verbose: false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static string GetTargetFolderName(BuildTarget target)
|
|
{
|
|
switch (target)
|
|
{
|
|
case BuildTarget.Android:
|
|
return "Android";
|
|
case BuildTarget.StandaloneOSX:
|
|
return "OSX";
|
|
case BuildTarget.StandaloneWindows:
|
|
return "Win32";
|
|
case BuildTarget.StandaloneWindows64:
|
|
return "Win64";
|
|
default:
|
|
throw new ArgumentException("Attempted GetTargetFolderName() for unsupported BuildTarget: " + target);
|
|
}
|
|
}
|
|
|
|
private static string GetTargetDllSuffix(BuildTarget target)
|
|
{
|
|
switch (target)
|
|
{
|
|
case BuildTarget.Android:
|
|
return ".aar";
|
|
case BuildTarget.StandaloneOSX:
|
|
return ".bundle";
|
|
case BuildTarget.StandaloneWindows:
|
|
return ".dll";
|
|
case BuildTarget.StandaloneWindows64:
|
|
return ".dll";
|
|
default:
|
|
throw new ArgumentException("Attempted GetTargetDllSuffix() for unsupported BuildTarget: " + target);
|
|
}
|
|
}
|
|
|
|
private static string[] FindAllSdkDlls(BuildTarget target)
|
|
{
|
|
char[] slashes = new char[] { '/', '\\' };
|
|
|
|
List<string> dllPaths = new List<string>();
|
|
string[] dlls = AssetDatabase.FindAssets(_baseDllName);
|
|
string targetPath = GetTargetFolderName(target);
|
|
foreach (string dll in dlls)
|
|
{
|
|
string path = AssetDatabase.GUIDToAssetPath(dll);
|
|
string suffix = GetTargetDllSuffix(target);
|
|
|
|
if (path.Contains(_baseDllName + suffix) && !path.Contains(_baseDllName + suffix + ".disabled"))
|
|
{
|
|
// see if the path contains the build target name (e.g. Win64) we're looking for
|
|
string[] subPaths = path.Split(slashes);
|
|
foreach (string subpath in subPaths)
|
|
{
|
|
if (subpath == targetPath)
|
|
{
|
|
dllPaths.Add(path);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
return dllPaths.ToArray();
|
|
}
|
|
|
|
private static void PerformUpdate(bool verbose)
|
|
{
|
|
int newLibsFound = 0;
|
|
|
|
foreach (BuildTarget t in buildTargets)
|
|
{
|
|
if (IsNewLibraryPresent(t))
|
|
{
|
|
newLibsFound++;
|
|
}
|
|
}
|
|
|
|
if (newLibsFound > 0)
|
|
{
|
|
// the ordering of the dialog responses is to keep consistency with the OVRPluginUpdater dialog responses
|
|
int response = EditorUtility.DisplayDialogComplex("Update Interaction SDK libraries?", "New versions of Interaction SDK libraries were found, it is recommended you update them now.", "Ok", "No, Don't ask again", "Not right now");
|
|
switch (response)
|
|
{
|
|
case 0: // yes
|
|
if (MoveAllNewLibraries() > 0)
|
|
{
|
|
PlayerPrefs.SetInt(_keyIsInstalling, 1);
|
|
response = EditorUtility.DisplayDialogComplex("Restart Unity?", "Unity needs to be restarted in order for the Interaction SDK installation to complete", "Ok", "Not right now", "Cancel");
|
|
|
|
if (response == 0)
|
|
RestartUnity();
|
|
}
|
|
else
|
|
{
|
|
PlayerPrefs.SetInt(_keyIsInstalling, 0);
|
|
EditorUtility.DisplayDialog("Library update error", "There was an issue updating the new Interaction SDK libraries", "Ok");
|
|
return;
|
|
}
|
|
break;
|
|
|
|
case 1: // dont ask again
|
|
PlayerPrefs.SetInt(_keyDontAsk, 1);
|
|
break;
|
|
|
|
case 2: // no
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (verbose)
|
|
{
|
|
EditorUtility.DisplayDialog("Interaction SDK Plugin Updater", "No new libraries were found to update", "Ok");
|
|
}
|
|
}
|
|
}
|
|
|
|
private static int MoveAllNewLibraries()
|
|
{
|
|
int found = 0;
|
|
foreach (BuildTarget t in buildTargets)
|
|
{
|
|
if (IsNewLibraryPresent(t))
|
|
{
|
|
found++;
|
|
if (IsCurrentLibraryPresent(t))
|
|
{
|
|
MoveCurrentLibrary(t);
|
|
}
|
|
}
|
|
}
|
|
|
|
return found;
|
|
}
|
|
|
|
private static string GetCurrentLibraryAssetPath(BuildTarget target, bool newVersion)
|
|
{
|
|
string[] dlls = FindAllSdkDlls(target);
|
|
foreach (var dllName in dlls)
|
|
{
|
|
string suffix = GetTargetDllSuffix(target);
|
|
|
|
if (dllName.Contains(suffix))
|
|
{
|
|
bool isNew = dllName.Contains(suffix + ".new");
|
|
if (newVersion == isNew)
|
|
return dllName;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private static bool IsCurrentLibraryPresent(BuildTarget target)
|
|
{
|
|
return GetCurrentLibraryAssetPath(target, false) != null;
|
|
}
|
|
|
|
private static bool IsNewLibraryPresent(BuildTarget target)
|
|
{
|
|
return GetCurrentLibraryAssetPath(target, true) != null;
|
|
}
|
|
|
|
private static bool MoveCurrentLibrary(BuildTarget target)
|
|
{
|
|
string srcPath = GetCurrentLibraryAssetPath(target, false);
|
|
bool success = MoveAsset(srcPath, srcPath + ".disabled", true);
|
|
return success;
|
|
}
|
|
|
|
private static bool MoveNewLibary(BuildTarget target)
|
|
{
|
|
string src = GetCurrentLibraryAssetPath(target, true);
|
|
string dest = src;
|
|
if (dest.EndsWith(".new"))
|
|
{
|
|
dest = dest.Substring(0, dest.Length - 4);
|
|
}
|
|
bool success = MoveAsset(src, dest, false);
|
|
if (success)
|
|
{
|
|
PluginImporter pi = PluginImporter.GetAtPath(dest) as PluginImporter;
|
|
pi.SetCompatibleWithEditor(false);
|
|
pi.SetCompatibleWithAnyPlatform(false);
|
|
pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSX, false);
|
|
pi.SetCompatibleWithPlatform(BuildTarget.Android, false);
|
|
pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows, false);
|
|
pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows64, false);
|
|
pi.SetCompatibleWithPlatform(target, true);
|
|
pi.SetCompatibleWithEditor(true);
|
|
|
|
switch (target)
|
|
{
|
|
case BuildTarget.StandaloneOSX:
|
|
pi.SetCompatibleWithEditor(true);
|
|
pi.SetEditorData("CPU", "AnyCPU");
|
|
pi.SetEditorData("OS", "OSX");
|
|
pi.SetPlatformData("Editor", "CPU", "AnyCPU");
|
|
pi.SetPlatformData("Editor", "OS", "OSX");
|
|
break;
|
|
case BuildTarget.StandaloneWindows:
|
|
pi.SetEditorData("CPU", "X86");
|
|
pi.SetEditorData("OS", "Windows");
|
|
pi.SetPlatformData("Editor", "CPU", "X86");
|
|
pi.SetPlatformData("Editor", "OS", "Windows");
|
|
break;
|
|
case BuildTarget.Android:
|
|
break;
|
|
case BuildTarget.StandaloneWindows64:
|
|
pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows64, true);
|
|
pi.SetCompatibleWithEditor(true);
|
|
pi.SetEditorData("CPU", "X86_64");
|
|
pi.SetEditorData("OS", "Windows");
|
|
pi.SetPlatformData("Editor", "CPU", "X86_64");
|
|
pi.SetPlatformData("Editor", "OS", "Windows");
|
|
break;
|
|
}
|
|
|
|
ReimportAsset(dest);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogErrorFormat("ISDK PluginUpdater: Error copying {0} to {1}", src, dest);
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
private static void ReimportAsset(string path)
|
|
{
|
|
AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
|
|
AssetDatabase.Refresh();
|
|
AssetDatabase.SaveAssets();
|
|
}
|
|
|
|
private static bool MoveAsset(string srcPath, string destPath, bool reImport)
|
|
{
|
|
string fullDest = GetProjectPath() + "/" + destPath;
|
|
if (File.Exists(fullDest))
|
|
{
|
|
File.Delete(fullDest);
|
|
File.Delete(fullDest + ".meta");
|
|
}
|
|
|
|
string errMsg = AssetDatabase.MoveAsset(srcPath, destPath);
|
|
if (errMsg.Length > 0)
|
|
{
|
|
UnityEngine.Debug.LogError(errMsg);
|
|
return false;
|
|
}
|
|
|
|
if (reImport)
|
|
{
|
|
ReimportAsset(destPath);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private static void RestartUnity()
|
|
{
|
|
_isRestarting = true;
|
|
EditorApplication.OpenProject(GetProjectPath());
|
|
}
|
|
}
|
|
}
|