artum 3d043864f8
NomaiVR 2.0.0 (#440)
* Open virtual keyboard on focusing text fields

* Reopen keyboard if auto-closed and empty

* BepInEx version

* Fix storage

* BepInEx config

* Cleanup dependencies

* Unlock mouse

* Debug mode

* GetValue not needed I think

* Setting ranges

* Path fixes

* Update Readme with rollback info

* Fix empty patches

* Added support Unity project

* NomaiVR modifications to SteamVR plugin

* Add patch files for future SteamVR updates

* Assume Unity 2019.4 assemblies are present

* XRModule loading, testing automated unity build

* Should now deploy without issues

* Transition project to netstandard2.0

* Added enabler mod

* Full unity build only on release

* VR loading

* Some camera fixes

* Rotate camera

* Add comment

* Restore exception logs

* Add some inputs. MoveXZ and LookXZ not working.

* Patch move, look, roll

* Cleanup

* Revert restore logging

* Fix hands in menu, but still wrong position ingame

* Enable every module except controllerinput

* Updated fog fix

* Player rotation fix

* Some progress on shader issues

* Shadow fix fix

* Bye bye XR plugin

* Shadow fix fix, fix after removing the xr loader

* Re-enabled mostly working stuff

* Simulating input for landing camera

* Simulate flashlight input

* Cleanup

* Add binding for autopilot

* Add recenter input (oculus only)

* Act on recenter input

* Separate UI select action from jump action

* Remove redundant laser input simulation stuff

* Removed redundant patches

* Restore reference frame tracker patches

* Removed autopilot bindings

* Use interact button for EVERYTHING

* Add boost input

* Revert to old camera system

* Additional inputs, restored hand independent inputs

* Restored water effects in DLC areas

* Haptics and stationary tools test

* Additional input tweaks

* Cleanup inputs

* more cleanup

* Force gamepad mode

* Remove leftover log

* Add more menu inputs

* Fix holding items

* Add debug cheats

* Added proof of concept of image prompts for vr bindings

* Re-enable holding word stones, prevent HoldItem from fully crashing if one of them isn't found

* Change supported version

* Re-enable gesture prompts

* Add separate actions for UI, use triggers for subtabs

* oculus: right stick click to autopilot, chord to recenter

* Mouse pointer interactions for menus, dialogues and probably shiplog too

* Switched back to old stable VRToolSwapper

* Restored shiplog swap

* Re-enable signalscope zoom

* Fix null reference that could occur on final sequence of the game

* Prevent null reference in eye scene

* Imported poses playground in Unity project

* Fixed playground

* Added basic pose tutorial

* Formatting issues

* Spelling...

* Effect fixes for a certain item in the DLC

* Prevent too much UI rebuilding, add controls for DLC item, remove failed shiplog experiment

* Fix crashes during a certain transition

* Dynamic prompt icons (#437)

* Starting work on dynamic prompt icons

* Reading input icons from new structure

* new VRActionInputs

* Abstract and interaface for vractioninput

* Fixed vector2, cleanup

* Add more stuff to input mapo

* stationary actions

* Cleanup

* Cleanup

* Readd usable items check that disappeared from merge

* Fix map condition

* Cleanup

* Break lines

* Add patch to remove unused inputs

* Add menu entry for recentering

* Fix signalscope positioning when the suit is off

* Create proper SteamVR manifest for the mod

* Getting prompts from all input maps (#438)

* Small input fixes

* Fixed a DLC transition

* Trying out new ways of interacting with an item in the DLC

* Simulated inputs now need explicit values

* Attempt at fixing a 2d effect

* Fix poses on pause menu exit, changes to holdables to better detect equip/unequip

* Add cheats: wake up in dream, start mind projection

* Different attempt at mind projection

* Fix menu buttons not being visible to new profiles

* Interactable autopilot button in the ship

* Fixes to a certain shader used in the DLC

* Include SteamVR shaders in shader bundle

* Starting work on DLC hand poses

* More polish on some poses

* Fixed light sorce locations on DLC item

* Fixes to certain means of transport in the DLC

* Made previous fix head direction independent

* Fixes to a cool mechanic in the DLC

* Fixed stationary dpad not bound properly

* Added icons for each controller, thanks to NoChill for the index icons and WMR layout

* Official bindings for index

* Run draw on top patch only when needed

* Patcher default moddir, peephole fixes and removed unused code

* Restored not so unused code

* Fix another DLC item

* Solved performance issues during credits scene

* Avoid null reference exceptions during post credits scene

* Removed debug code

* Better mind projection shader reproduction

* Additional fixes to mind effect

* Add launch support as doorstop target for the vr patcher

* Support for OWML builds

* Hand poses for all DLC items

* Fixed typo

* Texture for empty actions, action part caching

* Cleanup old classes

* More fixes to prompt logic

* Properly change autopilot prompts during autopilot phases

* Added direction and click to prompts

* Avoid spamming haptics events

* Fix vive bindings, add trackpad hand

* Updated WMR bindings to use all the new actions

* Fixed prompts for CV1 controllers

* Test OWML external patcher

* Ignore files already copied

* Started to update readme for new release

* Disable debug cheats by default, cleaup old comments

* Ensure that one DLC effect doesn't persist when opening the pause menu

* Moved vrmanifest under StreaminAssets

* Removed physics override, use SteamVR refreshrate always

* Removed bepinex dependency from patcher, copy patcher in mod's postbuild events

* Changed full build order

* Separated secondary interact from grip action

* Added cleanup logic for previous versions to the patcher

* Updated readme to be more in line with the current build process

* Updated user settings file instructions

* Simplify build process

* Further details in readme for dev builds

* Support main hand swap for usable items

* Revert change that caused project initialization issues

* Fixed issues in project references

* Move fov management inside camera helper, disabled fov changes for a DLC effect

* Cleanup readme

* Improve oculus bindings

* Adjusted autopilot button color and text

* Removed unused asset bundles

* Make end scene follow snap to the front of the headset every 70 degrees

* Usable items now use the interact button and are droppable

* Fix oculus tool bindings

* Increased manifest version to force rebind

* Adjust prompts position

* Removed instructions to downgrade OWML

* Fix menu collider not aligning

* Fix typo in last change

* Cleanup force settings

* Don't change probe retrieve prompt

* Upgrade OWML

* Remove DLC info from warning

* Mods dir

* Cleanup readme

* More Readme cleanup

* Remove comfort section

* Fix setup link

* Fixed table of contents

* fixed toc again

* Add readme pointer to warning message

* Update readme and warning

* Autopilot and Recenter now marked as optional

* Add info about icons

Co-authored-by: Ricardo Lopes <raicuparta@gmail.com>
Co-authored-by: Raicuparta <Raicuparta@users.noreply.github.com>
2021-10-21 20:07:20 +02:00

470 lines
19 KiB
C#

#if (UNITY_EDITOR && UNITY_2019_1_OR_NEWER)
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Unity.XR.OpenVR.SimpleJSON;
using UnityEditor;
using UnityEditor.PackageManager;
using UnityEditor.PackageManager.Requests;
using UnityEditor.PackageManager.UI;
using UnityEngine;
using UnityEngine.Networking;
namespace Unity.XR.OpenVR
{
[InitializeOnLoad]
public class OpenVRPackageInstaller : ScriptableObject
{
private const string valveOpenVRPackageString = "com.valvesoftware.unity.openvr";
private static ListRequest listRequest;
private static AddRequest addRequest;
private static System.Diagnostics.Stopwatch packageTime = new System.Diagnostics.Stopwatch();
private const float estimatedTimeToInstall = 90; // in seconds
private const string updaterKeyTemplate = "com.valvesoftware.unity.openvr.updateState.{0}";
private static string updaterKey
{
get { return string.Format(updaterKeyTemplate, Application.productName); }
}
private static UpdateStates updateState
{
get { return _updateState; }
set
{
#if VALVE_DEBUG
Debug.Log("[DEBUG] Update State: " + value.ToString());
#endif
_updateState = value;
EditorPrefs.SetInt(updaterKey, (int)value);
}
}
private static UpdateStates _updateState = UpdateStates.Idle;
private static double runningSeconds
{
get
{
if (packageTime.IsRunning == false)
packageTime.Start();
return packageTime.Elapsed.TotalSeconds;
}
}
private static bool forced = false;
public static void Start(bool force = false)
{
EditorApplication.update -= Update;
EditorApplication.update += Update;
if (force)
{
RemoveScopedRegistry();
}
}
static OpenVRPackageInstaller()
{
#if OPENVR_XR_API //if we're updating, go ahead and just start
Start();
#endif
}
/// <summary>
/// State Machine
/// Idle: Start from last known state. If none is known, ask user if they want to install, if yes goto remove scoped registry step
/// WaitingOnExistingCheck:
/// RemoveScopedRegistry: Remove the scoped registry entry if it exists
/// WaitingForAdd: if the add request has been nulled or completed successfully, request a list of packages for confirmation
/// WaitingForAddConfirmation: enumerate the packages and verify the add succeeded. If it failed, try again.
/// If it succeeded request removal of this script
/// RemoveSelf: delete the key that we've been using to maintain state. Delete this script and the containing folder if it's empty.
/// </summary>
private static void Update()
{
switch (updateState)
{
case UpdateStates.Idle:
if (EditorPrefs.HasKey(updaterKey))
{
_updateState = (UpdateStates)EditorPrefs.GetInt(updaterKey);
packageTime.Start();
}
else
{
RequestExisting();
}
break;
case UpdateStates.WaitingOnExistingCheck:
if (listRequest == null)
{
//the list request got nulled for some reason. Request it again.
RequestExisting();
}
else if (listRequest != null && listRequest.IsCompleted)
{
if (listRequest.Error != null || listRequest.Status == UnityEditor.PackageManager.StatusCode.Failure)
{
DisplayErrorAndStop("Error while checking for an existing OpenVR package.", listRequest);
}
else
{
if (listRequest.Result.Any(package => package.name == valveOpenVRPackageString))
{
var existingPackage = listRequest.Result.FirstOrDefault(package => package.name == valveOpenVRPackageString);
string latestTarball = GetLatestTarballVersion();
if (latestTarball != null && latestTarball.CompareTo(existingPackage.version) == 1)
{
//we have a tarball higher than the currently installed version
string upgradeString = string.Format("This SteamVR Unity Plugin has a newer version of the Unity XR OpenVR package than you have installed. Would you like to upgrade?\n\nCurrent: {0}\nUpgrade: {1} (recommended)", existingPackage.version, latestTarball);
bool upgrade = UnityEditor.EditorUtility.DisplayDialog("OpenVR XR Updater", upgradeString, "Upgrade", "Cancel");
if (upgrade)
RemoveScopedRegistry();
else
{
bool delete = UnityEditor.EditorUtility.DisplayDialog("OpenVR XR Updater", "Would you like to remove this updater script so we don't ask again?", "Remove updater", "Keep");
if (delete)
{
Stop();
return;
}
else
{
GentleStop();
return;
}
}
}
}
else
{
#if UNITY_2020_1_OR_NEWER
RemoveScopedRegistry(); //just install if we're on 2020 and they don't have the package
return;
#else
//they don't have the package yet. Ask if they want to install (only for 2019)
bool blankInstall = UnityEditor.EditorUtility.DisplayDialog("OpenVR XR Installer", "The SteamVR Unity Plugin can be used with the legacy Unity VR API (Unity 5.4 - 2019) or with the Unity XR API (2019+). Would you like to install OpenVR for Unity XR?", "Install", "Cancel");
if (blankInstall)
RemoveScopedRegistry();
else
{
bool delete = UnityEditor.EditorUtility.DisplayDialog("OpenVR XR Installer", "Would you like to remove this installer script so we don't ask again?", "Remove installer", "Keep");
if (delete)
{
Stop();
return;
}
else
{
GentleStop();
return;
}
}
#endif
}
}
}
break;
case UpdateStates.WaitingForAdd:
if (addRequest == null)
{
//the add request got nulled for some reason. Request an add confirmation
RequestAddConfirmation();
}
else if (addRequest != null && addRequest.IsCompleted)
{
if (addRequest.Error != null || addRequest.Status == UnityEditor.PackageManager.StatusCode.Failure)
{
DisplayErrorAndStop("Error adding new version of OpenVR package.", addRequest);
}
else
{
//verify that the package has been added (then stop)
RequestAddConfirmation();
}
}
else
{
if (packageTime.Elapsed.TotalSeconds > estimatedTimeToInstall)
DisplayErrorAndStop("Error while trying to add package.", addRequest);
else
DisplayProgressBar();
}
break;
case UpdateStates.WaitingForAddConfirmation:
if (listRequest == null)
{
//the list request got nulled for some reason. Request it again.
RequestAddConfirmation();
}
else if (listRequest != null && listRequest.IsCompleted)
{
if (listRequest.Error != null || listRequest.Status == UnityEditor.PackageManager.StatusCode.Failure)
{
DisplayErrorAndStop("Error while confirming the OpenVR package has been added.", listRequest);
}
else
{
if (listRequest.Result.Any(package => package.name == valveOpenVRPackageString))
{
updateState = UpdateStates.RemoveSelf;
UnityEditor.EditorUtility.DisplayDialog("OpenVR Unity XR Installer", "OpenVR Unity XR successfully installed.\n\nA restart of the Unity Editor may be necessary.", "Ok");
}
else
{
//try to add again if it's not there and we don't know why
RequestAdd();
}
}
}
else
{
if (runningSeconds > estimatedTimeToInstall)
{
DisplayErrorAndStop("Error while confirming the OpenVR package has been added.", listRequest);
}
else
DisplayProgressBar();
}
break;
case UpdateStates.RemoveSelf:
EditorPrefs.DeleteKey(updaterKey);
EditorUtility.ClearProgressBar();
EditorApplication.update -= Update;
#if VALVE_SKIP_DELETE
Debug.Log("[DEBUG] skipping script deletion. Complete.");
return;
#endif
var script = MonoScript.FromScriptableObject(OpenVRPackageInstaller.CreateInstance<OpenVRPackageInstaller>());
var path = AssetDatabase.GetAssetPath(script);
FileInfo updaterScript = new FileInfo(path); updaterScript.IsReadOnly = false;
FileInfo updaterScriptMeta = new FileInfo(path + ".meta");
FileInfo simpleJSONScript = new FileInfo(Path.Combine(updaterScript.Directory.FullName, "OpenVRSimpleJSON.cs"));
FileInfo simpleJSONScriptMeta = new FileInfo(Path.Combine(updaterScript.Directory.FullName, "OpenVRSimpleJSON.cs.meta"));
updaterScript.IsReadOnly = false;
updaterScriptMeta.IsReadOnly = false;
simpleJSONScript.IsReadOnly = false;
simpleJSONScriptMeta.IsReadOnly = false;
updaterScriptMeta.Delete();
if (updaterScriptMeta.Exists)
{
DisplayErrorAndStop("Error while removing package installer script. Please delete manually.", listRequest);
return;
}
simpleJSONScript.Delete();
simpleJSONScriptMeta.Delete();
updaterScript.Delete();
AssetDatabase.Refresh();
break;
}
}
private static string GetLatestTarballVersion()
{
FileInfo[] files;
FileInfo latest = GetAvailableTarballs(out files);
if (latest == null)
return null;
return GetTarballVersion(latest);
}
private static FileInfo GetAvailableTarballs(out FileInfo[] packages)
{
var installerScript = MonoScript.FromScriptableObject(OpenVRPackageInstaller.CreateInstance<OpenVRPackageInstaller>());
var scriptPath = AssetDatabase.GetAssetPath(installerScript);
FileInfo thisScript = new FileInfo(scriptPath);
packages = thisScript.Directory.GetFiles("*.tgz");
if (packages.Length > 0)
{
if (packages.Length > 1)
{
var descending = packages.OrderByDescending(file => file.Name);
var latest = descending.First();
packages = descending.Where(file => file != latest).ToArray();
return latest;
}
var onlyPackage = packages[0];
packages = new FileInfo[0];
return onlyPackage;
}
else
return null;
}
private static string GetTarballVersion(FileInfo file)
{
int startIndex = file.Name.IndexOf('-') + 1;
int endIndex = file.Name.IndexOf(".tgz");
int len = endIndex - startIndex;
return file.Name.Substring(startIndex, len);
}
private const string packageManifestPath = "Packages/manifest.json";
private const string scopedRegistryKey = "scopedRegistries";
private const string npmRegistryName = "Valve";
//load packages.json
//check for existing scoped registries
//check for our scoped registry
//if no to either then add it
//save file
//reload
private static void RemoveScopedRegistry()
{
updateState = UpdateStates.RemoveOldRegistry;
packageTime.Start();
if (File.Exists(packageManifestPath) == false)
{
Debug.LogWarning("[OpenVR Installer] Could not find package manifest at: " + packageManifestPath);
RequestAdd();
return;
}
string jsonText = File.ReadAllText(packageManifestPath);
JSONNode manifest = JSON.Parse(jsonText);
if (manifest.HasKey(scopedRegistryKey) == true)
{
if (manifest[scopedRegistryKey].HasKey(npmRegistryName))
{
manifest[scopedRegistryKey].Remove(npmRegistryName);
File.WriteAllText(packageManifestPath, manifest.ToString(2));
Debug.Log("[OpenVR Installer] Removed Valve entry from scoped registry.");
}
}
RequestAdd();
}
private static void RequestAdd()
{
updateState = UpdateStates.WaitingForAdd;
FileInfo[] oldFiles;
FileInfo latest = GetAvailableTarballs(out oldFiles);
if (latest != null)
{
if (oldFiles.Length > 0)
{
var oldFilesNames = oldFiles.Select(file => file.Name);
string oldFilesString = string.Join("\n", oldFilesNames);
bool delete = UnityEditor.EditorUtility.DisplayDialog("OpenVR XR Installer", "Would you like to delete the old OpenVR packages?\n\n" + oldFilesString, "Delete old files", "Keep");
if (delete)
{
foreach (FileInfo file in oldFiles)
{
FileInfo meta = new FileInfo(file.FullName + ".meta");
if (meta.Exists)
{
meta.IsReadOnly = false;
meta.Delete();
}
if (file.Exists)
{
file.IsReadOnly = false;
file.Delete();
}
}
}
}
string packagePath = latest.FullName;
if (packagePath != null)
{
string packageAbsolute = packagePath.Replace("\\", "/");
string packageRelative = packageAbsolute.Substring(packageAbsolute.IndexOf("/Assets/"));
string packageURI = System.Uri.EscapeUriString(packageRelative);
addRequest = UnityEditor.PackageManager.Client.Add("file:.." + packageURI);
}
else
{
updateState = UpdateStates.RemoveSelf;
}
}
}
private static void RequestAddConfirmation()
{
updateState = UpdateStates.WaitingForAddConfirmation;
listRequest = Client.List(true, true);
}
private static void RequestExisting()
{
updateState = UpdateStates.WaitingOnExistingCheck;
listRequest = Client.List(true, true);
}
private static string dialogText = "Installing OpenVR Unity XR package from local storage using Unity Package Manager...";
private static void DisplayProgressBar()
{
bool cancel = UnityEditor.EditorUtility.DisplayCancelableProgressBar("SteamVR", dialogText, (float)packageTime.Elapsed.TotalSeconds / estimatedTimeToInstall);
if (cancel)
Stop();
}
private static void DisplayErrorAndStop(string stepInfo, Request request)
{
string error = "";
if (request != null)
error = request.Error.message;
string errorMessage = string.Format("{0}:\n\t{1}\n\nPlease manually reinstall the package through the package manager.", stepInfo, error);
UnityEngine.Debug.LogError(errorMessage);
Stop();
UnityEditor.EditorUtility.DisplayDialog("OpenVR Error", errorMessage, "Ok");
}
private static void Stop()
{
updateState = UpdateStates.RemoveSelf;
}
private static void GentleStop()
{
EditorApplication.update -= Update;
}
private enum UpdateStates
{
Idle,
WaitingOnExistingCheck,
RemoveOldRegistry,
WaitingForAdd,
WaitingForAddConfirmation,
RemoveSelf,
}
}
}
#endif