├── .github ├── ISSUE_TEMPLATE │ └── bug_report.md ├── stale.yml └── workflows │ ├── build.yml │ └── set_up_env.ps1 ├── .gitignore ├── Documentation └── Images │ ├── beat-saber-bindings.png │ ├── binding-possibilities.png │ ├── bindings.png │ ├── controller-official-bindings.png │ ├── controller-settings.png │ ├── create-binding.png │ ├── current-binding-official.png │ ├── done.png │ ├── dynamicopenvr-logo-wide.png │ ├── edit-existing-binding.png │ ├── enable-advanced-settings.png │ ├── enable-debug-input.png │ ├── export-binding-file.png │ ├── files.png │ ├── go-back.png │ ├── haptics.png │ ├── manage-bindings-advanced.png │ ├── manage-bindings-default.png │ ├── manage-controller-bindings.png │ ├── missing.png │ ├── official-bindings.png │ ├── plus.png │ ├── poses.png │ ├── press-choose-another.png │ ├── pull.png │ ├── save.png │ ├── select-different-controller.png │ ├── select-game.png │ ├── select-official-binding.png │ ├── select-right-controller.png │ ├── use-input-as.png │ ├── vector1-actions.png │ ├── verify-buttons.png │ ├── vrsettings-after.png │ ├── vrsettings-before.png │ └── vrsettings.png ├── LICENSE ├── Libraries ├── Il2CppInterop │ ├── BepInEx.Core.dll │ ├── BepInEx.NET.Common.dll │ ├── BepInEx.Unity.Common.dll │ ├── BepInEx.Unity.IL2CPP.dll │ ├── Il2CppInterop.Common.dll │ ├── Il2CppInterop.Runtime.dll │ ├── Il2Cppmscorlib.dll │ ├── Newtonsoft.Json.dll │ ├── SteamVR.dll │ ├── UnityEngine.CoreModule.dll │ ├── UnityEngine.VRModule.dll │ ├── UnityEngine.XRModule.dll │ └── UnityEngine.dll └── Mono │ ├── 0Harmony.dll │ ├── IPA.Injector.dll │ ├── IPA.Loader.dll │ ├── Newtonsoft.Json.dll │ ├── UnityEngine.CoreModule.dll │ ├── UnityEngine.VRModule.dll │ ├── UnityEngine.XRModule.dll │ └── UnityEngine.dll ├── Packaging ├── DynamicOpenVR.BeatSaber │ ├── Beat Saber_Data │ │ ├── Managed │ │ │ └── Unity.XR.OpenVR.dll │ │ ├── Plugins │ │ │ └── x86_64 │ │ │ │ ├── XRSDKOpenVR.dll │ │ │ │ ├── openvr_api.dll │ │ │ │ └── ucrtbased.dll │ │ ├── StreamingAssets │ │ │ └── SteamVR │ │ │ │ └── OpenVRSettings.asset │ │ └── UnitySubsystems │ │ │ └── XRSDKOpenVR │ │ │ └── UnitySubsystemsManifest.json │ └── DynamicOpenVR │ │ ├── Actions │ │ └── beatsaber.json │ │ └── Bindings │ │ ├── beatsaber_holographic_controller.json │ │ ├── beatsaber_holographic_hmd.json │ │ ├── beatsaber_hpmotioncontroller.json │ │ ├── beatsaber_hypereal_controller.json │ │ ├── beatsaber_index_hmd.json │ │ ├── beatsaber_knuckles.json │ │ ├── beatsaber_oculus_touch.json │ │ ├── beatsaber_rift_hmd.json │ │ ├── beatsaber_vive_controller.json │ │ └── beatsaber_vive_hmd.json └── DynamicOpenVR │ └── Plugins │ └── DynamicOpenVR.manifest ├── README.md ├── Source ├── .editorconfig ├── DynamicOpenVR.BeatSaber │ ├── AppConfigConfirmationModal.cs │ ├── DynamicOpenVR.BeatSaber.csproj │ ├── HarmonyPatches │ │ ├── Input.cs │ │ ├── InputDevices.cs │ │ ├── InputTracking.cs │ │ ├── MainSystemInit.cs │ │ └── UnityXRHapticsHandler.cs │ ├── IPALogHandler.cs │ ├── InputCollections │ │ ├── BeatSaberActions.cs │ │ ├── UnityXRActions.cs │ │ └── UnityXRActionsHand.cs │ ├── NativeMethods.cs │ ├── OpenVRHelper.cs │ ├── Plugin.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Resources │ │ └── icon.png │ ├── SteamUtilities.cs │ ├── manifest.json │ └── stylecop.json ├── DynamicOpenVR.IL2CPP │ ├── DynamicOpenVR.IL2CPP.csproj │ └── stylecop.json ├── DynamicOpenVR.UntilYouFall │ ├── DynamicOpenVR.UntilYouFall.csproj │ ├── Plugin.cs │ └── Properties │ │ └── launchSettings.json ├── DynamicOpenVR.sln └── DynamicOpenVR │ ├── Common.props │ ├── DynamicOpenVR.csproj │ ├── Exceptions │ ├── OpenVRInitException.cs │ └── OpenVRInputException.cs │ ├── HmdMatrix34Extensions.cs │ ├── IO │ ├── AnalogInput.cs │ ├── BooleanInput.cs │ ├── HapticVibrationOutput.cs │ ├── OVRAction.cs │ ├── OVRInput.cs │ ├── PoseInput.cs │ ├── SkeletalInput.cs │ ├── SkeletalSummaryData.cs │ ├── Vector2Input.cs │ ├── Vector3Input.cs │ └── VectorInput.cs │ ├── Logging │ ├── ILogHandler.cs │ ├── Logger.cs │ └── UnityDebugLogHandler.cs │ ├── OpenVRActionManager.cs │ ├── OpenVREventHandler.cs │ ├── OpenVRFacade.cs │ ├── OpenVRUtilities.cs │ ├── SteamVR │ ├── Actions │ │ ├── ActionManifest.cs │ │ ├── BindingCollection.cs │ │ ├── DefaultBinding.cs │ │ ├── ManifestAction.cs │ │ ├── ManifestActionSet.cs │ │ └── ManifestDefaultBinding.cs │ ├── AppConfig.cs │ └── VRManifest │ │ ├── DefaultBinding.cs │ │ ├── VRApplication.cs │ │ └── VRApplicationManifest.cs │ ├── openvr_api.cs │ └── stylecop.json └── TROUBLESHOOTING.md /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Something isn't working! 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Before doing anything else, please attach your latest *full* log to this issue. It should be located at `Logs\_latest.log` (not the one inside `Logs\DynamicOpenVR`, the one directly under `Logs`) in your Beat Saber installation's folder.** 11 | 12 | **Desktop (please complete the following information):** 13 | - Operating system: [e.g. Windows 10, Ubuntu 18.04] 14 | - Headset and controllers: [e.g. Oculus Rift, HTC Vive, Valve Index] 15 | 16 | **Describe the bug** 17 | A clear and concise description of what the bug is. If your issue occurs with a particular avatar, please add a link to where you found it or attach it; **please do not attach the avatar file to this issue if you did not create it**. 18 | 19 | **Steps to reproduce** 20 | Steps to reproduce the behavior: 21 | 1. Go to '...' 22 | 2. Click on '...' 23 | 3. Scroll down to '...' 24 | 4. See error 25 | 26 | **Expected behavior** 27 | A clear and concise description of what you expected to happen. 28 | 29 | **Screenshots** 30 | If applicable, add screenshots to help explain your problem. 31 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Configuration for probot-stale - https://github.com/probot/stale 2 | 3 | # Number of days of inactivity before an Issue or Pull Request becomes stale 4 | daysUntilStale: 7 5 | 6 | # Number of days of inactivity before an Issue or Pull Request with the stale label is closed. 7 | # Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. 8 | daysUntilClose: 7 9 | 10 | # Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable 11 | exemptLabels: 12 | - backlog 13 | 14 | # Label to use when marking as stale 15 | staleLabel: stale 16 | 17 | # Comment to post when marking as stale. Set to `false` to disable 18 | markComment: > 19 | This issue has been automatically marked as stale because it has not had 20 | recent activity. It will be closed if no further activity occurs. 21 | 22 | # Comment to post when closing a stale Issue or Pull Request. 23 | closeComment: > 24 | This issue has been automatically closed because it has not had 25 | recent activity. If the problem persists, feel free to reopen this 26 | issue or create a new one. 27 | 28 | # Limit to only `issues` or `pulls` 29 | only: issues 30 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | push: 5 | paths: 6 | - .github/workflows/build.yml 7 | - Libraries/** 8 | - Packaging/** 9 | - Source/** 10 | 11 | jobs: 12 | build: 13 | name: Build DynamicOpenVR 14 | runs-on: windows-latest 15 | steps: 16 | - name: Check out 17 | uses: actions/checkout@v3 18 | 19 | - name: Set up environment 20 | run: ${{ github.workspace }}\.github\workflows\set_up_env.ps1 "${{ github.workspace }}\Packaging\DynamicOpenVR\Plugins\DynamicOpenVR.manifest" 21 | 22 | - name: Build Debug 23 | run: dotnet publish Source\DynamicOpenVR\DynamicOpenVR.csproj -c Debug 24 | 25 | - name: Upload Debug 26 | uses: actions/upload-artifact@v3 27 | with: 28 | name: DynamicOpenVR-${{ env.ZIP_VERSION }}-DEBUG 29 | path: Source\DynamicOpenVR\bin\Debug\netstandard2.0\publish 30 | 31 | - name: Build Release 32 | run: dotnet publish Source\DynamicOpenVR\DynamicOpenVR.csproj -c Release 33 | 34 | - name: Upload Release 35 | uses: actions/upload-artifact@v3 36 | with: 37 | name: DynamicOpenVR-${{ env.ZIP_VERSION }}-RELEASE 38 | path: Source\DynamicOpenVR\bin\Release\netstandard2.0\publish 39 | build-beat-saber: 40 | name: Build DynamicOpenVR.BeatSaber 41 | runs-on: windows-latest 42 | steps: 43 | - name: Check out 44 | uses: actions/checkout@v3 45 | 46 | - name: Set up environment 47 | run: ${{ github.workspace }}\.github\workflows\set_up_env.ps1 "${{ github.workspace }}\Source\DynamicOpenVR.BeatSaber\manifest.json" 48 | 49 | - name: Fetch Beat Saber Bindings 50 | run: git clone https://${{ github.actor }}:${{ secrets.PRIVATE_GITHUB_TOKEN }}@github.com/nicoco007/BeatSaberBindings --branch v${{ env.GAME_VERSION }} --single-branch '${{ runner.temp }}\BeatSaberBindings\Beat Saber_Data\Managed' 51 | 52 | - name: Add NuGet source 53 | run: dotnet nuget add source --username ${{ github.actor }} --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text "https://nuget.pkg.github.com/nicoco007/index.json" 54 | 55 | - name: Download dependencies 56 | uses: nicoco007/download-beatmods-deps@main 57 | with: 58 | manifest: ${{ github.workspace }}\Source\DynamicOpenVR.BeatSaber\manifest.json 59 | path: ${{ runner.temp }}\BeatSaberBindings 60 | 61 | - name: Build Debug 62 | run: dotnet publish Source\DynamicOpenVR.BeatSaber\DynamicOpenVR.BeatSaber.csproj -c Debug -p:BeatSaberDir=${{ runner.temp }}\BeatSaberBindings 63 | 64 | - name: Upload Debug 65 | uses: actions/upload-artifact@v3 66 | with: 67 | name: DynamicOpenVR.BeatSaber-${{ env.ZIP_VERSION }}-DEBUG 68 | path: Source\DynamicOpenVR.BeatSaber\bin\Debug\net472\publish 69 | 70 | - name: Build Release 71 | run: dotnet publish Source\DynamicOpenVR.BeatSaber\DynamicOpenVR.BeatSaber.csproj -c Release -p:BeatSaberDir=${{ runner.temp }}\BeatSaberBindings 72 | 73 | - name: Upload Release 74 | uses: actions/upload-artifact@v3 75 | with: 76 | name: DynamicOpenVR.BeatSaber-${{ env.ZIP_VERSION }}-RELEASE 77 | path: Source\DynamicOpenVR.BeatSaber\bin\Release\net472\publish 78 | build-il2cpp: 79 | name: Build DynamicOpenVR.IL2CPP 80 | runs-on: windows-latest 81 | steps: 82 | - name: Check out 83 | uses: actions/checkout@v3 84 | 85 | - name: Set up environment 86 | run: ${{ github.workspace }}\.github\workflows\set_up_env.ps1 "${{ github.workspace }}\Packaging\DynamicOpenVR\Plugins\DynamicOpenVR.manifest" 87 | 88 | - name: Build Debug 89 | run: dotnet publish Source\DynamicOpenVR.IL2CPP\DynamicOpenVR.IL2CPP.csproj -c Debug 90 | 91 | - name: Upload Debug 92 | uses: actions/upload-artifact@v3 93 | with: 94 | name: DynamicOpenVR.IL2CPP-${{ env.ZIP_VERSION }}-DEBUG 95 | path: Source\DynamicOpenVR.IL2CPP\bin\Debug\net6.0\publish 96 | 97 | - name: Build Release 98 | run: dotnet publish Source\DynamicOpenVR.IL2CPP\DynamicOpenVR.IL2CPP.csproj -c Release 99 | 100 | - name: Upload Release 101 | uses: actions/upload-artifact@v3 102 | with: 103 | name: DynamicOpenVR.IL2CPP-${{ env.ZIP_VERSION }}-RELEASE 104 | path: Source\DynamicOpenVR.IL2CPP\bin\Release\net6.0\publish 105 | -------------------------------------------------------------------------------- /.github/workflows/set_up_env.ps1: -------------------------------------------------------------------------------- 1 | $ErrorActionPreference = "Stop" 2 | 3 | $check = [char]0x2713 4 | $cross = [char]0x2717 5 | 6 | if ($args.Length -ne 1) { 7 | Write-Host "Invalid number of arguments" -ForegroundColor Red 8 | exit(-1) 9 | } 10 | 11 | if ($args[0] -eq "" -or !(Test-Path $args[0])) { 12 | Write-Host "File '$($args[0])' does not exist" -ForegroundColor Red 13 | exit(-1) 14 | } 15 | 16 | $manifest_content = Get-Content $args[0] | ConvertFrom-Json 17 | 18 | $manifest_version_str = $manifest_content.version 19 | $semver = [regex]::Match($manifest_version_str, '^(?(?(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*))(?:-(?:(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?)(?:\+(?:[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$') 20 | 21 | $version_with_prerelease = $semver.groups['prerelease'].value 22 | 23 | $git_hash = (git log -n 1 --pretty=%h).Trim() 24 | $git_tag = git tag -l --points-at HEAD 25 | 26 | if ($git_tag -ne "" -and $git_tag.Length -gt 0) { 27 | if ($git_tag -ne "v$version_with_prerelease") { 28 | Write-Host "$cross Git tag '$git_tag' does not match manifest version '$version_with_prerelease'" -ForegroundColor Red 29 | exit(-1) 30 | } 31 | 32 | Write-Host "$check Using Git tag '$git_tag'" -ForegroundColor Green 33 | $manifest_content.version = $version_with_prerelease 34 | $zip_version = "v$version_with_prerelease" 35 | } elseif ($git_hash -ne "" -and $git_hash.Length -gt 0) { 36 | Write-Host "$check Using Git hash '$git_hash'" -ForegroundColor Green 37 | $manifest_content.version = "$version_with_prerelease+git.$git_hash" 38 | $zip_version = $git_hash 39 | } else { 40 | Write-Host "$cross Could not find Git tag or hash" -ForegroundColor Red 41 | exit(-1) 42 | } 43 | 44 | Add-Content "$env:GITHUB_ENV" "ZIP_VERSION=$zip_version" 45 | Add-Content "$env:GITHUB_ENV" "GAME_VERSION=$($manifest_content.gameVersion)" 46 | 47 | $manifest_content | ConvertTo-Json | Set-Content $args[0] 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Aa][Rr][Mm]/ 27 | [Aa][Rr][Mm]64/ 28 | bld/ 29 | [Bb]in/ 30 | [Oo]bj/ 31 | [Ll]og/ 32 | [Ll]ogs/ 33 | 34 | # Visual Studio 2015/2017 cache/options directory 35 | .vs/ 36 | # Uncomment if you have tasks that create the project's static files in wwwroot 37 | #wwwroot/ 38 | 39 | # Visual Studio 2017 auto generated files 40 | Generated\ Files/ 41 | 42 | # MSTest test Results 43 | [Tt]est[Rr]esult*/ 44 | [Bb]uild[Ll]og.* 45 | 46 | # NUnit 47 | *.VisualState.xml 48 | TestResult.xml 49 | nunit-*.xml 50 | 51 | # Build Results of an ATL Project 52 | [Dd]ebugPS/ 53 | [Rr]eleasePS/ 54 | dlldata.c 55 | 56 | # Benchmark Results 57 | BenchmarkDotNet.Artifacts/ 58 | 59 | # .NET Core 60 | project.lock.json 61 | project.fragment.lock.json 62 | artifacts/ 63 | 64 | # StyleCop 65 | StyleCopReport.xml 66 | 67 | # Files built by Visual Studio 68 | *_i.c 69 | *_p.c 70 | *_h.h 71 | *.ilk 72 | *.meta 73 | *.obj 74 | *.iobj 75 | *.pch 76 | *.pdb 77 | *.ipdb 78 | *.pgc 79 | *.pgd 80 | *.rsp 81 | *.sbr 82 | *.tlb 83 | *.tli 84 | *.tlh 85 | *.tmp 86 | *.tmp_proj 87 | *_wpftmp.csproj 88 | *.log 89 | *.vspscc 90 | *.vssscc 91 | .builds 92 | *.pidb 93 | *.svclog 94 | *.scc 95 | 96 | # Chutzpah Test files 97 | _Chutzpah* 98 | 99 | # Visual C++ cache files 100 | ipch/ 101 | *.aps 102 | *.ncb 103 | *.opendb 104 | *.opensdf 105 | *.sdf 106 | *.cachefile 107 | *.VC.db 108 | *.VC.VC.opendb 109 | 110 | # Visual Studio profiler 111 | *.psess 112 | *.vsp 113 | *.vspx 114 | *.sap 115 | 116 | # Visual Studio Trace Files 117 | *.e2e 118 | 119 | # TFS 2012 Local Workspace 120 | $tf/ 121 | 122 | # Guidance Automation Toolkit 123 | *.gpState 124 | 125 | # ReSharper is a .NET coding add-in 126 | _ReSharper*/ 127 | *.[Rr]e[Ss]harper 128 | *.DotSettings.user 129 | 130 | # JustCode is a .NET coding add-in 131 | .JustCode 132 | 133 | # TeamCity is a build add-in 134 | _TeamCity* 135 | 136 | # DotCover is a Code Coverage Tool 137 | *.dotCover 138 | 139 | # AxoCover is a Code Coverage Tool 140 | .axoCover/* 141 | !.axoCover/settings.json 142 | 143 | # Visual Studio code coverage results 144 | *.coverage 145 | *.coveragexml 146 | 147 | # NCrunch 148 | _NCrunch_* 149 | .*crunch*.local.xml 150 | nCrunchTemp_* 151 | 152 | # MightyMoose 153 | *.mm.* 154 | AutoTest.Net/ 155 | 156 | # Web workbench (sass) 157 | .sass-cache/ 158 | 159 | # Installshield output folder 160 | [Ee]xpress/ 161 | 162 | # DocProject is a documentation generator add-in 163 | DocProject/buildhelp/ 164 | DocProject/Help/*.HxT 165 | DocProject/Help/*.HxC 166 | DocProject/Help/*.hhc 167 | DocProject/Help/*.hhk 168 | DocProject/Help/*.hhp 169 | DocProject/Help/Html2 170 | DocProject/Help/html 171 | 172 | # Click-Once directory 173 | publish/ 174 | 175 | # Publish Web Output 176 | *.[Pp]ublish.xml 177 | *.azurePubxml 178 | # Note: Comment the next line if you want to checkin your web deploy settings, 179 | # but database connection strings (with potential passwords) will be unencrypted 180 | *.pubxml 181 | *.publishproj 182 | 183 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 184 | # checkin your Azure Web App publish settings, but sensitive information contained 185 | # in these scripts will be unencrypted 186 | PublishScripts/ 187 | 188 | # NuGet Packages 189 | *.nupkg 190 | # NuGet Symbol Packages 191 | *.snupkg 192 | # The packages folder can be ignored because of Package Restore 193 | **/[Pp]ackages/* 194 | # except build/, which is used as an MSBuild target. 195 | !**/[Pp]ackages/build/ 196 | # Uncomment if necessary however generally it will be regenerated when needed 197 | #!**/[Pp]ackages/repositories.config 198 | # NuGet v3's project.json files produces more ignorable files 199 | *.nuget.props 200 | *.nuget.targets 201 | 202 | # Microsoft Azure Build Output 203 | csx/ 204 | *.build.csdef 205 | 206 | # Microsoft Azure Emulator 207 | ecf/ 208 | rcf/ 209 | 210 | # Windows Store app package directories and files 211 | AppPackages/ 212 | BundleArtifacts/ 213 | Package.StoreAssociation.xml 214 | _pkginfo.txt 215 | *.appx 216 | *.appxbundle 217 | *.appxupload 218 | 219 | # Visual Studio cache files 220 | # files ending in .cache can be ignored 221 | *.[Cc]ache 222 | # but keep track of directories ending in .cache 223 | !?*.[Cc]ache/ 224 | 225 | # Others 226 | ClientBin/ 227 | ~$* 228 | *~ 229 | *.dbmdl 230 | *.dbproj.schemaview 231 | *.jfm 232 | *.pfx 233 | *.publishsettings 234 | orleans.codegen.cs 235 | 236 | # Including strong name files can present a security risk 237 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 238 | #*.snk 239 | 240 | # Since there are multiple workflows, uncomment next line to ignore bower_components 241 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 242 | #bower_components/ 243 | 244 | # RIA/Silverlight projects 245 | Generated_Code/ 246 | 247 | # Backup & report files from converting an old project file 248 | # to a newer Visual Studio version. Backup files are not needed, 249 | # because we have git ;-) 250 | _UpgradeReport_Files/ 251 | Backup*/ 252 | UpgradeLog*.XML 253 | UpgradeLog*.htm 254 | ServiceFabricBackup/ 255 | *.rptproj.bak 256 | 257 | # SQL Server files 258 | *.mdf 259 | *.ldf 260 | *.ndf 261 | 262 | # Business Intelligence projects 263 | *.rdl.data 264 | *.bim.layout 265 | *.bim_*.settings 266 | *.rptproj.rsuser 267 | *- [Bb]ackup.rdl 268 | *- [Bb]ackup ([0-9]).rdl 269 | *- [Bb]ackup ([0-9][0-9]).rdl 270 | 271 | # Microsoft Fakes 272 | FakesAssemblies/ 273 | 274 | # GhostDoc plugin setting file 275 | *.GhostDoc.xml 276 | 277 | # Node.js Tools for Visual Studio 278 | .ntvs_analysis.dat 279 | node_modules/ 280 | 281 | # Visual Studio 6 build log 282 | *.plg 283 | 284 | # Visual Studio 6 workspace options file 285 | *.opt 286 | 287 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 288 | *.vbw 289 | 290 | # Visual Studio LightSwitch build output 291 | **/*.HTMLClient/GeneratedArtifacts 292 | **/*.DesktopClient/GeneratedArtifacts 293 | **/*.DesktopClient/ModelManifest.xml 294 | **/*.Server/GeneratedArtifacts 295 | **/*.Server/ModelManifest.xml 296 | _Pvt_Extensions 297 | 298 | # Paket dependency manager 299 | .paket/paket.exe 300 | paket-files/ 301 | 302 | # FAKE - F# Make 303 | .fake/ 304 | 305 | # CodeRush personal settings 306 | .cr/personal 307 | 308 | # Python Tools for Visual Studio (PTVS) 309 | __pycache__/ 310 | *.pyc 311 | 312 | # Cake - Uncomment if you are using it 313 | # tools/** 314 | # !tools/packages.config 315 | 316 | # Tabs Studio 317 | *.tss 318 | 319 | # Telerik's JustMock configuration file 320 | *.jmconfig 321 | 322 | # BizTalk build output 323 | *.btp.cs 324 | *.btm.cs 325 | *.odx.cs 326 | *.xsd.cs 327 | 328 | # OpenCover UI analysis results 329 | OpenCover/ 330 | 331 | # Azure Stream Analytics local run output 332 | ASALocalRun/ 333 | 334 | # MSBuild Binary and Structured Log 335 | *.binlog 336 | 337 | # NVidia Nsight GPU debugger configuration file 338 | *.nvuser 339 | 340 | # MFractors (Xamarin productivity tool) working folder 341 | .mfractor/ 342 | 343 | # Local History for Visual Studio 344 | .localhistory/ 345 | 346 | # BeatPulse healthcheck temp database 347 | healthchecksdb 348 | 349 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 350 | MigrationBackup/ 351 | 352 | # Ionide (cross platform F# VS Code tools) working folder 353 | .ionide/ -------------------------------------------------------------------------------- /Documentation/Images/beat-saber-bindings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/beat-saber-bindings.png -------------------------------------------------------------------------------- /Documentation/Images/binding-possibilities.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/binding-possibilities.png -------------------------------------------------------------------------------- /Documentation/Images/bindings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/bindings.png -------------------------------------------------------------------------------- /Documentation/Images/controller-official-bindings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/controller-official-bindings.png -------------------------------------------------------------------------------- /Documentation/Images/controller-settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/controller-settings.png -------------------------------------------------------------------------------- /Documentation/Images/create-binding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/create-binding.png -------------------------------------------------------------------------------- /Documentation/Images/current-binding-official.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/current-binding-official.png -------------------------------------------------------------------------------- /Documentation/Images/done.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/done.png -------------------------------------------------------------------------------- /Documentation/Images/dynamicopenvr-logo-wide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/dynamicopenvr-logo-wide.png -------------------------------------------------------------------------------- /Documentation/Images/edit-existing-binding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/edit-existing-binding.png -------------------------------------------------------------------------------- /Documentation/Images/enable-advanced-settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/enable-advanced-settings.png -------------------------------------------------------------------------------- /Documentation/Images/enable-debug-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/enable-debug-input.png -------------------------------------------------------------------------------- /Documentation/Images/export-binding-file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/export-binding-file.png -------------------------------------------------------------------------------- /Documentation/Images/files.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/files.png -------------------------------------------------------------------------------- /Documentation/Images/go-back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/go-back.png -------------------------------------------------------------------------------- /Documentation/Images/haptics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/haptics.png -------------------------------------------------------------------------------- /Documentation/Images/manage-bindings-advanced.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/manage-bindings-advanced.png -------------------------------------------------------------------------------- /Documentation/Images/manage-bindings-default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/manage-bindings-default.png -------------------------------------------------------------------------------- /Documentation/Images/manage-controller-bindings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/manage-controller-bindings.png -------------------------------------------------------------------------------- /Documentation/Images/missing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/missing.png -------------------------------------------------------------------------------- /Documentation/Images/official-bindings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/official-bindings.png -------------------------------------------------------------------------------- /Documentation/Images/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/plus.png -------------------------------------------------------------------------------- /Documentation/Images/poses.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/poses.png -------------------------------------------------------------------------------- /Documentation/Images/press-choose-another.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/press-choose-another.png -------------------------------------------------------------------------------- /Documentation/Images/pull.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/pull.png -------------------------------------------------------------------------------- /Documentation/Images/save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/save.png -------------------------------------------------------------------------------- /Documentation/Images/select-different-controller.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/select-different-controller.png -------------------------------------------------------------------------------- /Documentation/Images/select-game.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/select-game.png -------------------------------------------------------------------------------- /Documentation/Images/select-official-binding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/select-official-binding.png -------------------------------------------------------------------------------- /Documentation/Images/select-right-controller.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/select-right-controller.png -------------------------------------------------------------------------------- /Documentation/Images/use-input-as.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/use-input-as.png -------------------------------------------------------------------------------- /Documentation/Images/vector1-actions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/vector1-actions.png -------------------------------------------------------------------------------- /Documentation/Images/verify-buttons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/verify-buttons.png -------------------------------------------------------------------------------- /Documentation/Images/vrsettings-after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/vrsettings-after.png -------------------------------------------------------------------------------- /Documentation/Images/vrsettings-before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/vrsettings-before.png -------------------------------------------------------------------------------- /Documentation/Images/vrsettings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Documentation/Images/vrsettings.png -------------------------------------------------------------------------------- /Libraries/Il2CppInterop/BepInEx.Core.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Libraries/Il2CppInterop/BepInEx.Core.dll -------------------------------------------------------------------------------- /Libraries/Il2CppInterop/BepInEx.NET.Common.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Libraries/Il2CppInterop/BepInEx.NET.Common.dll -------------------------------------------------------------------------------- /Libraries/Il2CppInterop/BepInEx.Unity.Common.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Libraries/Il2CppInterop/BepInEx.Unity.Common.dll -------------------------------------------------------------------------------- /Libraries/Il2CppInterop/BepInEx.Unity.IL2CPP.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Libraries/Il2CppInterop/BepInEx.Unity.IL2CPP.dll -------------------------------------------------------------------------------- /Libraries/Il2CppInterop/Il2CppInterop.Common.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Libraries/Il2CppInterop/Il2CppInterop.Common.dll -------------------------------------------------------------------------------- /Libraries/Il2CppInterop/Il2CppInterop.Runtime.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Libraries/Il2CppInterop/Il2CppInterop.Runtime.dll -------------------------------------------------------------------------------- /Libraries/Il2CppInterop/Il2Cppmscorlib.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Libraries/Il2CppInterop/Il2Cppmscorlib.dll -------------------------------------------------------------------------------- /Libraries/Il2CppInterop/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Libraries/Il2CppInterop/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /Libraries/Il2CppInterop/SteamVR.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Libraries/Il2CppInterop/SteamVR.dll -------------------------------------------------------------------------------- /Libraries/Il2CppInterop/UnityEngine.CoreModule.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Libraries/Il2CppInterop/UnityEngine.CoreModule.dll -------------------------------------------------------------------------------- /Libraries/Il2CppInterop/UnityEngine.VRModule.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Libraries/Il2CppInterop/UnityEngine.VRModule.dll -------------------------------------------------------------------------------- /Libraries/Il2CppInterop/UnityEngine.XRModule.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Libraries/Il2CppInterop/UnityEngine.XRModule.dll -------------------------------------------------------------------------------- /Libraries/Il2CppInterop/UnityEngine.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Libraries/Il2CppInterop/UnityEngine.dll -------------------------------------------------------------------------------- /Libraries/Mono/0Harmony.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Libraries/Mono/0Harmony.dll -------------------------------------------------------------------------------- /Libraries/Mono/IPA.Injector.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Libraries/Mono/IPA.Injector.dll -------------------------------------------------------------------------------- /Libraries/Mono/IPA.Loader.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Libraries/Mono/IPA.Loader.dll -------------------------------------------------------------------------------- /Libraries/Mono/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Libraries/Mono/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /Libraries/Mono/UnityEngine.CoreModule.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Libraries/Mono/UnityEngine.CoreModule.dll -------------------------------------------------------------------------------- /Libraries/Mono/UnityEngine.VRModule.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Libraries/Mono/UnityEngine.VRModule.dll -------------------------------------------------------------------------------- /Libraries/Mono/UnityEngine.XRModule.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Libraries/Mono/UnityEngine.XRModule.dll -------------------------------------------------------------------------------- /Libraries/Mono/UnityEngine.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Libraries/Mono/UnityEngine.dll -------------------------------------------------------------------------------- /Packaging/DynamicOpenVR.BeatSaber/Beat Saber_Data/Managed/Unity.XR.OpenVR.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Packaging/DynamicOpenVR.BeatSaber/Beat Saber_Data/Managed/Unity.XR.OpenVR.dll -------------------------------------------------------------------------------- /Packaging/DynamicOpenVR.BeatSaber/Beat Saber_Data/Plugins/x86_64/XRSDKOpenVR.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Packaging/DynamicOpenVR.BeatSaber/Beat Saber_Data/Plugins/x86_64/XRSDKOpenVR.dll -------------------------------------------------------------------------------- /Packaging/DynamicOpenVR.BeatSaber/Beat Saber_Data/Plugins/x86_64/openvr_api.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Packaging/DynamicOpenVR.BeatSaber/Beat Saber_Data/Plugins/x86_64/openvr_api.dll -------------------------------------------------------------------------------- /Packaging/DynamicOpenVR.BeatSaber/Beat Saber_Data/Plugins/x86_64/ucrtbased.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoco007/DynamicOpenVR/807a8c7a966f7124a3e2038f614287273b9710b1/Packaging/DynamicOpenVR.BeatSaber/Beat Saber_Data/Plugins/x86_64/ucrtbased.dll -------------------------------------------------------------------------------- /Packaging/DynamicOpenVR.BeatSaber/Beat Saber_Data/StreamingAssets/SteamVR/OpenVRSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &11400000 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_GameObject: {fileID: 0} 10 | m_Enabled: 1 11 | m_EditorHideFlags: 0 12 | m_Script: {fileID: 11500000, guid: 7a32bfe54d957ec4581fa4a630f1647a, type: 3} 13 | m_Name: Open VR Settings 14 | m_EditorClassIdentifier: 15 | StereoRenderingMode: 1 16 | InitializationType: 1 17 | MirrorView: 1 18 | HasCopiedDefaults: 0 19 | -------------------------------------------------------------------------------- /Packaging/DynamicOpenVR.BeatSaber/Beat Saber_Data/UnitySubsystems/XRSDKOpenVR/UnitySubsystemsManifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "XRSDKOpenVR", 3 | "version": "1.0.0-preview.1", 4 | "libraryName": "XRSDKOpenVR", 5 | "displays": [ 6 | { 7 | "id": "OpenVR Display" 8 | } 9 | ], 10 | "inputs": [ 11 | { 12 | "id": "OpenVR Input", 13 | "disablesLegacyInput": true, 14 | "disablesLegacyVr": true 15 | } 16 | ] 17 | } -------------------------------------------------------------------------------- /Packaging/DynamicOpenVR.BeatSaber/DynamicOpenVR/Actions/beatsaber.json: -------------------------------------------------------------------------------- 1 | { 2 | "actions": [ 3 | { 4 | "name": "/actions/main/in/left_trigger", 5 | "requirement": "mandatory", 6 | "type": "vector1" 7 | }, 8 | { 9 | "name": "/actions/main/in/right_trigger", 10 | "requirement": "mandatory", 11 | "type": "vector1" 12 | }, 13 | { 14 | "name": "/actions/main/in/left_menu_button", 15 | "requirement": "mandatory", 16 | "type": "boolean" 17 | }, 18 | { 19 | "name": "/actions/main/in/right_menu_button", 20 | "requirement": "mandatory", 21 | "type": "boolean" 22 | }, 23 | { 24 | "name": "/actions/main/out/left_hand_haptics", 25 | "requirement": "suggested", 26 | "type": "vibration" 27 | }, 28 | { 29 | "name": "/actions/main/out/right_hand_haptics", 30 | "requirement": "suggested", 31 | "type": "vibration" 32 | }, 33 | { 34 | "name": "/actions/main/in/left_hand_pose", 35 | "requirement": "mandatory", 36 | "type": "pose" 37 | }, 38 | { 39 | "name": "/actions/main/in/right_hand_pose", 40 | "requirement": "mandatory", 41 | "type": "pose" 42 | }, 43 | { 44 | "name": "/actions/main/in/left_thumbstick", 45 | "requirement": "suggested", 46 | "type": "vector2" 47 | }, 48 | { 49 | "name": "/actions/main/in/right_thumbstick", 50 | "requirement": "suggested", 51 | "type": "vector2" 52 | }, 53 | { 54 | "name": "/actions/main/in/headset_on_head", 55 | "requirement": "optional", 56 | "type": "boolean" 57 | }, 58 | { 59 | "name": "/actions/unity/in/left_pose", 60 | "requirement": "suggested", 61 | "type": "pose" 62 | }, 63 | { 64 | "name": "/actions/unity/in/left_primary_button", 65 | "requirement": "optional", 66 | "type": "boolean" 67 | }, 68 | { 69 | "name": "/actions/unity/in/left_primary_touch", 70 | "requirement": "optional", 71 | "type": "boolean" 72 | }, 73 | { 74 | "name": "/actions/unity/in/left_secondary_button", 75 | "requirement": "optional", 76 | "type": "boolean" 77 | }, 78 | { 79 | "name": "/actions/unity/in/left_secondary_touch", 80 | "requirement": "optional", 81 | "type": "boolean" 82 | }, 83 | { 84 | "name": "/actions/unity/in/left_grip", 85 | "requirement": "optional", 86 | "type": "vector1" 87 | }, 88 | { 89 | "name": "/actions/unity/in/left_grip_button", 90 | "requirement": "suggested", 91 | "type": "boolean" 92 | }, 93 | { 94 | "name": "/actions/unity/in/left_trigger", 95 | "requirement": "suggested", 96 | "type": "vector1" 97 | }, 98 | { 99 | "name": "/actions/unity/in/left_trigger_button", 100 | "requirement": "suggested", 101 | "type": "boolean" 102 | }, 103 | { 104 | "name": "/actions/unity/in/left_menu_button", 105 | "requirement": "optional", 106 | "type": "boolean" 107 | }, 108 | { 109 | "name": "/actions/unity/in/left_primary_2d_axis", 110 | "requirement": "suggested", 111 | "type": "vector2" 112 | }, 113 | { 114 | "name": "/actions/unity/in/left_primary_2d_axis_click", 115 | "requirement": "suggested", 116 | "type": "boolean" 117 | }, 118 | { 119 | "name": "/actions/unity/in/left_primary_2d_axis_touch", 120 | "requirement": "optional", 121 | "type": "boolean" 122 | }, 123 | { 124 | "name": "/actions/unity/out/left_haptics", 125 | "requirement": "suggested", 126 | "type": "vibration" 127 | }, 128 | { 129 | "name": "/actions/unity/in/right_pose", 130 | "requirement": "suggested", 131 | "type": "pose" 132 | }, 133 | { 134 | "name": "/actions/unity/in/right_primary_button", 135 | "requirement": "optional", 136 | "type": "boolean" 137 | }, 138 | { 139 | "name": "/actions/unity/in/right_primary_touch", 140 | "requirement": "optional", 141 | "type": "boolean" 142 | }, 143 | { 144 | "name": "/actions/unity/in/right_secondary_button", 145 | "requirement": "optional", 146 | "type": "boolean" 147 | }, 148 | { 149 | "name": "/actions/unity/in/right_secondary_touch", 150 | "requirement": "optional", 151 | "type": "boolean" 152 | }, 153 | { 154 | "name": "/actions/unity/in/right_grip", 155 | "requirement": "optional", 156 | "type": "vector1" 157 | }, 158 | { 159 | "name": "/actions/unity/in/right_grip_button", 160 | "requirement": "suggested", 161 | "type": "boolean" 162 | }, 163 | { 164 | "name": "/actions/unity/in/right_trigger", 165 | "requirement": "suggested", 166 | "type": "vector1" 167 | }, 168 | { 169 | "name": "/actions/unity/in/right_trigger_button", 170 | "requirement": "suggested", 171 | "type": "boolean" 172 | }, 173 | { 174 | "name": "/actions/unity/in/right_menu_button", 175 | "requirement": "optional", 176 | "type": "boolean" 177 | }, 178 | { 179 | "name": "/actions/unity/in/right_primary_2d_axis", 180 | "requirement": "suggested", 181 | "type": "vector2" 182 | }, 183 | { 184 | "name": "/actions/unity/in/right_primary_2d_axis_click", 185 | "requirement": "suggested", 186 | "type": "boolean" 187 | }, 188 | { 189 | "name": "/actions/unity/in/right_primary_2d_axis_touch", 190 | "requirement": "optional", 191 | "type": "boolean" 192 | }, 193 | { 194 | "name": "/actions/unity/out/right_haptics", 195 | "requirement": "suggested", 196 | "type": "vibration" 197 | } 198 | ], 199 | "action_sets": [ 200 | { 201 | "name": "/actions/main", 202 | "usage": "leftright" 203 | }, 204 | { 205 | "name": "/actions/unity", 206 | "usage": "leftright" 207 | } 208 | ], 209 | "localization": [ 210 | { 211 | "language_tag": "en_us", 212 | "/actions/main": "Beat Saber", 213 | "/actions/main/in/left_trigger": "Left Trigger Pull", 214 | "/actions/main/in/right_trigger": "Right Trigger Pull", 215 | "/actions/main/in/left_menu_button": "Left Menu Button", 216 | "/actions/main/in/right_menu_button": "Right Menu Button", 217 | "/actions/main/out/left_hand_haptics": "Left Hand Haptic Vibration", 218 | "/actions/main/out/right_hand_haptics": "Right Hand Haptic Vibration", 219 | "/actions/main/in/left_hand_pose": "Left Hand Pose", 220 | "/actions/main/in/right_hand_pose": "Right Hand Pose", 221 | "/actions/main/in/left_thumbstick": "Left Joystick Position", 222 | "/actions/main/in/right_thumbstick": "Right Joystick Position", 223 | "/actions/main/in/headset_on_head": "Headset on head (proximity sensor)", 224 | "/actions/unity": "Unity XR Input", 225 | "/actions/unity/in/left_pose": "Left Controller Pose", 226 | "/actions/unity/in/left_primary_button": "Left Primary Button", 227 | "/actions/unity/in/left_primary_touch": "Left Primary Touch", 228 | "/actions/unity/in/left_secondary_button": "Left Secondary Button", 229 | "/actions/unity/in/left_secondary_touch": "Left Secondary Touch", 230 | "/actions/unity/in/left_grip": "Left Grip", 231 | "/actions/unity/in/left_grip_button": "Left Grip Button", 232 | "/actions/unity/in/left_trigger": "Left Trigger", 233 | "/actions/unity/in/left_trigger_button": "Left Trigger Button", 234 | "/actions/unity/in/left_menu_button": "Left Menu Button", 235 | "/actions/unity/in/left_primary_2d_axis": "Left Primary 2D Axis", 236 | "/actions/unity/in/left_primary_2d_axis_click": "Left Primary 2D Axis Click", 237 | "/actions/unity/in/left_primary_2d_axis_touch": "Left Primary 2D Axis Touch", 238 | "/actions/unity/out/left_haptics": "Left Haptic Vibration", 239 | "/actions/unity/in/right_pose": "Right Controller Pose", 240 | "/actions/unity/in/right_primary_button": "Right Primary Button", 241 | "/actions/unity/in/right_primary_touch": "Right Primary Touch", 242 | "/actions/unity/in/right_secondary_button": "Right Secondary Button", 243 | "/actions/unity/in/right_secondary_touch": "Right Secondary Touch", 244 | "/actions/unity/in/right_grip": "Right Grip", 245 | "/actions/unity/in/right_grip_button": "Right Grip Button", 246 | "/actions/unity/in/right_trigger": "Right Trigger", 247 | "/actions/unity/in/right_trigger_button": "Right Trigger Button", 248 | "/actions/unity/in/right_menu_button": "Right Menu Button", 249 | "/actions/unity/in/right_primary_2d_axis": "Right Primary 2D Axis", 250 | "/actions/unity/in/right_primary_2d_axis_click": "Right Primary 2D Axis Click", 251 | "/actions/unity/in/right_primary_2d_axis_touch": "Right Primary 2D Axis Touch", 252 | "/actions/unity/out/right_haptics": "Right Haptic Vibration" 253 | } 254 | ] 255 | } -------------------------------------------------------------------------------- /Packaging/DynamicOpenVR.BeatSaber/DynamicOpenVR/Bindings/beatsaber_holographic_controller.json: -------------------------------------------------------------------------------- 1 | { 2 | "bindings": { 3 | "/actions/main": { 4 | "haptics": [ 5 | { 6 | "output": "/actions/main/out/right_hand_haptics", 7 | "path": "/user/hand/right/output/haptic" 8 | }, 9 | { 10 | "output": "/actions/main/out/left_hand_haptics", 11 | "path": "/user/hand/left/output/haptic" 12 | } 13 | ], 14 | "poses": [ 15 | { 16 | "output": "/actions/main/in/left_hand_pose", 17 | "path": "/user/hand/left/pose/grip" 18 | }, 19 | { 20 | "output": "/actions/main/in/right_hand_pose", 21 | "path": "/user/hand/right/pose/grip" 22 | } 23 | ], 24 | "sources": [ 25 | { 26 | "inputs": { 27 | "pull": { 28 | "output": "/actions/main/in/left_trigger" 29 | } 30 | }, 31 | "mode": "trigger", 32 | "path": "/user/hand/left/input/trigger" 33 | }, 34 | { 35 | "inputs": { 36 | "pull": { 37 | "output": "/actions/main/in/right_trigger" 38 | } 39 | }, 40 | "mode": "trigger", 41 | "path": "/user/hand/right/input/trigger" 42 | }, 43 | { 44 | "inputs": { 45 | "click": { 46 | "output": "/actions/main/in/right_menu_button" 47 | } 48 | }, 49 | "mode": "button", 50 | "path": "/user/hand/right/input/application_menu" 51 | }, 52 | { 53 | "inputs": { 54 | "click": { 55 | "output": "/actions/main/in/left_menu_button" 56 | } 57 | }, 58 | "mode": "button", 59 | "path": "/user/hand/left/input/application_menu" 60 | }, 61 | { 62 | "inputs": { 63 | "position": { 64 | "output": "/actions/main/in/left_thumbstick" 65 | } 66 | }, 67 | "mode": "joystick", 68 | "path": "/user/hand/left/input/joystick" 69 | }, 70 | { 71 | "inputs": { 72 | "position": { 73 | "output": "/actions/main/in/right_thumbstick" 74 | } 75 | }, 76 | "mode": "joystick", 77 | "path": "/user/hand/right/input/joystick" 78 | } 79 | ] 80 | }, 81 | "/actions/unity": { 82 | "haptics": [ 83 | { 84 | "output": "/actions/unity/out/left_haptics", 85 | "path": "/user/hand/left/output/haptic" 86 | }, 87 | { 88 | "output": "/actions/unity/out/right_haptics", 89 | "path": "/user/hand/right/output/haptic" 90 | } 91 | ], 92 | "poses": [ 93 | { 94 | "output": "/actions/unity/in/left_pose", 95 | "path": "/user/hand/left/pose/grip" 96 | }, 97 | { 98 | "output": "/actions/unity/in/right_pose", 99 | "path": "/user/hand/right/pose/grip" 100 | } 101 | ], 102 | "sources": [ 103 | { 104 | "inputs": { 105 | "pull": { 106 | "output": "/actions/unity/in/left_trigger" 107 | } 108 | }, 109 | "mode": "trigger", 110 | "path": "/user/hand/left/input/trigger" 111 | }, 112 | { 113 | "inputs": { 114 | "click": { 115 | "output": "/actions/unity/in/left_trigger_button" 116 | } 117 | }, 118 | "mode": "button", 119 | "path": "/user/hand/left/input/trigger" 120 | }, 121 | { 122 | "inputs": { 123 | "click": { 124 | "output": "/actions/unity/in/left_primary_2d_axis_click" 125 | }, 126 | "position": { 127 | "output": "/actions/unity/in/left_primary_2d_axis" 128 | } 129 | }, 130 | "mode": "joystick", 131 | "path": "/user/hand/left/input/joystick" 132 | }, 133 | { 134 | "inputs": { 135 | "click": { 136 | "output": "/actions/unity/in/left_menu_button" 137 | } 138 | }, 139 | "mode": "button", 140 | "path": "/user/hand/left/input/application_menu" 141 | }, 142 | { 143 | "inputs": { 144 | "click": { 145 | "output": "/actions/unity/in/left_grip_button" 146 | } 147 | }, 148 | "mode": "button", 149 | "path": "/user/hand/left/input/grip" 150 | }, 151 | { 152 | "inputs": { 153 | "pull": { 154 | "output": "/actions/unity/in/right_trigger" 155 | } 156 | }, 157 | "mode": "trigger", 158 | "path": "/user/hand/right/input/trigger" 159 | }, 160 | { 161 | "inputs": { 162 | "click": { 163 | "output": "/actions/unity/in/right_trigger_button" 164 | } 165 | }, 166 | "mode": "button", 167 | "path": "/user/hand/right/input/trigger" 168 | }, 169 | { 170 | "inputs": { 171 | "click": { 172 | "output": "/actions/unity/in/right_grip_button" 173 | } 174 | }, 175 | "mode": "button", 176 | "path": "/user/hand/right/input/grip" 177 | }, 178 | { 179 | "inputs": { 180 | "click": { 181 | "output": "/actions/unity/in/right_menu_button" 182 | } 183 | }, 184 | "mode": "button", 185 | "path": "/user/hand/right/input/application_menu" 186 | }, 187 | { 188 | "inputs": { 189 | "click": { 190 | "output": "/actions/unity/in/right_primary_2d_axis_click" 191 | }, 192 | "position": { 193 | "output": "/actions/unity/in/right_primary_2d_axis" 194 | } 195 | }, 196 | "mode": "joystick", 197 | "path": "/user/hand/right/input/joystick" 198 | } 199 | ] 200 | } 201 | }, 202 | "controller_type": "holographic_controller" 203 | } -------------------------------------------------------------------------------- /Packaging/DynamicOpenVR.BeatSaber/DynamicOpenVR/Bindings/beatsaber_holographic_hmd.json: -------------------------------------------------------------------------------- 1 | { 2 | "bindings" : { 3 | "/actions/main" : { 4 | "sources" : [ 5 | { 6 | "inputs" : { 7 | "click" : { 8 | "output" : "/actions/main/in/headset_on_head" 9 | } 10 | }, 11 | "mode" : "button", 12 | "path" : "/user/head/proximity" 13 | } 14 | ] 15 | } 16 | }, 17 | "controller_type" : "holographic_hmd" 18 | } 19 | -------------------------------------------------------------------------------- /Packaging/DynamicOpenVR.BeatSaber/DynamicOpenVR/Bindings/beatsaber_hpmotioncontroller.json: -------------------------------------------------------------------------------- 1 | { 2 | "bindings": { 3 | "/actions/customavatars": { 4 | "skeleton": [ 5 | { 6 | "output": "/actions/customavatars/in/lefthandanim", 7 | "path": "/user/hand/left/input/skeleton/left" 8 | }, 9 | { 10 | "output": "/actions/customavatars/in/righthandanim", 11 | "path": "/user/hand/right/input/skeleton/right" 12 | } 13 | ], 14 | "sources": [] 15 | }, 16 | "/actions/main": { 17 | "chords": [], 18 | "haptics": [ 19 | { 20 | "output": "/actions/main/out/left_hand_haptics", 21 | "path": "/user/hand/left/output/haptic" 22 | }, 23 | { 24 | "output": "/actions/main/out/right_hand_haptics", 25 | "path": "/user/hand/right/output/haptic" 26 | } 27 | ], 28 | "poses": [ 29 | { 30 | "output": "/actions/main/in/left_hand_pose", 31 | "path": "/user/hand/left/pose/grip" 32 | }, 33 | { 34 | "output": "/actions/main/in/right_hand_pose", 35 | "path": "/user/hand/right/pose/grip" 36 | } 37 | ], 38 | "skeleton": [], 39 | "sources": [ 40 | { 41 | "inputs": { 42 | "pull": { 43 | "output": "/actions/main/in/left_trigger" 44 | } 45 | }, 46 | "mode": "trigger", 47 | "path": "/user/hand/left/input/trigger" 48 | }, 49 | { 50 | "inputs": { 51 | "pull": { 52 | "output": "/actions/main/in/right_trigger" 53 | } 54 | }, 55 | "mode": "trigger", 56 | "path": "/user/hand/right/input/trigger" 57 | }, 58 | { 59 | "inputs": { 60 | "click": { 61 | "output": "/actions/main/in/right_menu_button" 62 | } 63 | }, 64 | "mode": "button", 65 | "path": "/user/hand/right/input/b" 66 | }, 67 | { 68 | "inputs": { 69 | "click": { 70 | "output": "/actions/main/in/left_menu_button" 71 | } 72 | }, 73 | "mode": "button", 74 | "path": "/user/hand/left/input/y" 75 | }, 76 | { 77 | "inputs": { 78 | "position": { 79 | "output": "/actions/main/in/left_thumbstick" 80 | } 81 | }, 82 | "mode": "joystick", 83 | "path": "/user/hand/left/input/joystick" 84 | }, 85 | { 86 | "inputs": { 87 | "position": { 88 | "output": "/actions/main/in/right_thumbstick" 89 | } 90 | }, 91 | "mode": "joystick", 92 | "path": "/user/hand/right/input/joystick" 93 | } 94 | ] 95 | }, 96 | "/actions/unity": { 97 | "chords": [], 98 | "haptics": [ 99 | { 100 | "output": "/actions/unity/out/left_haptics", 101 | "path": "/user/hand/left/output/haptic" 102 | }, 103 | { 104 | "output": "/actions/unity/out/right_haptics", 105 | "path": "/user/hand/right/output/haptic" 106 | } 107 | ], 108 | "poses": [ 109 | { 110 | "output": "/actions/unity/in/left_pose", 111 | "path": "/user/hand/left/pose/grip" 112 | }, 113 | { 114 | "output": "/actions/unity/in/right_pose", 115 | "path": "/user/hand/right/pose/grip" 116 | } 117 | ], 118 | "skeleton": [], 119 | "sources": [ 120 | { 121 | "inputs": { 122 | "click": { 123 | "output": "/actions/unity/in/left_primary_button" 124 | }, 125 | "touch": { 126 | "output": "/actions/unity/in/left_primary_touch" 127 | } 128 | }, 129 | "mode": "button", 130 | "path": "/user/hand/left/input/x" 131 | }, 132 | { 133 | "inputs": { 134 | "click": { 135 | "output": "/actions/unity/in/left_trigger_button" 136 | }, 137 | "pull": { 138 | "output": "/actions/unity/in/left_trigger" 139 | } 140 | }, 141 | "mode": "trigger", 142 | "path": "/user/hand/left/input/trigger" 143 | }, 144 | { 145 | "inputs": { 146 | "click": { 147 | "output": "/actions/unity/in/left_primary_2d_axis_click" 148 | }, 149 | "position": { 150 | "output": "/actions/unity/in/left_primary_2d_axis" 151 | }, 152 | "touch": { 153 | "output": "/actions/unity/in/left_primary_2d_axis_touch" 154 | } 155 | }, 156 | "mode": "joystick", 157 | "path": "/user/hand/left/input/joystick" 158 | }, 159 | { 160 | "inputs": { 161 | "click": { 162 | "output": "/actions/unity/in/left_grip_button" 163 | }, 164 | "pull": { 165 | "output": "/actions/unity/in/left_grip" 166 | } 167 | }, 168 | "mode": "trigger", 169 | "path": "/user/hand/left/input/grip" 170 | }, 171 | { 172 | "inputs": { 173 | "click": { 174 | "output": "/actions/unity/in/left_secondary_button" 175 | }, 176 | "touch": { 177 | "output": "/actions/unity/in/left_secondary_touch" 178 | } 179 | }, 180 | "mode": "button", 181 | "path": "/user/hand/left/input/y" 182 | }, 183 | { 184 | "inputs": { 185 | "click": { 186 | "output": "/actions/unity/in/right_trigger_button" 187 | }, 188 | "pull": { 189 | "output": "/actions/unity/in/right_trigger" 190 | } 191 | }, 192 | "mode": "trigger", 193 | "path": "/user/hand/right/input/trigger" 194 | }, 195 | { 196 | "inputs": { 197 | "click": { 198 | "output": "/actions/unity/in/right_primary_2d_axis_click" 199 | }, 200 | "position": { 201 | "output": "/actions/unity/in/right_primary_2d_axis" 202 | }, 203 | "touch": { 204 | "output": "/actions/unity/in/right_primary_2d_axis_touch" 205 | } 206 | }, 207 | "mode": "joystick", 208 | "path": "/user/hand/right/input/joystick" 209 | }, 210 | { 211 | "inputs": { 212 | "click": { 213 | "output": "/actions/unity/in/right_grip_button" 214 | }, 215 | "pull": { 216 | "output": "/actions/unity/in/right_grip" 217 | } 218 | }, 219 | "mode": "trigger", 220 | "path": "/user/hand/right/input/grip" 221 | }, 222 | { 223 | "inputs": { 224 | "click": { 225 | "output": "/actions/unity/in/right_primary_button" 226 | }, 227 | "touch": { 228 | "output": "/actions/unity/in/right_primary_touch" 229 | } 230 | }, 231 | "mode": "button", 232 | "path": "/user/hand/right/input/a" 233 | }, 234 | { 235 | "inputs": { 236 | "click": { 237 | "output": "/actions/unity/in/right_secondary_button" 238 | }, 239 | "touch": { 240 | "output": "/actions/unity/in/right_secondary_touch" 241 | } 242 | }, 243 | "mode": "button", 244 | "path": "/user/hand/right/input/b" 245 | }, 246 | { 247 | "inputs": { 248 | "click": { 249 | "output": "/actions/unity/in/left_menu_button" 250 | } 251 | }, 252 | "mode": "button", 253 | "path": "/user/hand/left/input/application_menu" 254 | }, 255 | { 256 | "inputs": { 257 | "click": { 258 | "output": "/actions/unity/in/right_menu_button" 259 | } 260 | }, 261 | "mode": "button", 262 | "path": "/user/hand/right/input/application_menu" 263 | } 264 | ] 265 | } 266 | }, 267 | "controller_type": "hpmotioncontroller" 268 | } -------------------------------------------------------------------------------- /Packaging/DynamicOpenVR.BeatSaber/DynamicOpenVR/Bindings/beatsaber_hypereal_controller.json: -------------------------------------------------------------------------------- 1 | { 2 | "bindings": { 3 | "/actions/main": { 4 | "haptics": [ 5 | { 6 | "output": "/actions/main/out/left_hand_haptics", 7 | "path": "/user/hand/left/output/haptic" 8 | }, 9 | { 10 | "output": "/actions/main/out/right_hand_haptics", 11 | "path": "/user/hand/right/output/haptic" 12 | } 13 | ], 14 | "poses": [ 15 | { 16 | "output": "/actions/main/in/left_hand_pose", 17 | "path": "/user/hand/left/pose/grip" 18 | }, 19 | { 20 | "output": "/actions/main/in/right_hand_pose", 21 | "path": "/user/hand/right/pose/grip" 22 | } 23 | ], 24 | "sources": [ 25 | { 26 | "inputs": { 27 | "pull": { 28 | "output": "/actions/main/in/left_trigger" 29 | } 30 | }, 31 | "mode": "trigger", 32 | "path": "/user/hand/left/input/trigger" 33 | }, 34 | { 35 | "inputs": { 36 | "pull": { 37 | "output": "/actions/main/in/right_trigger" 38 | } 39 | }, 40 | "mode": "trigger", 41 | "path": "/user/hand/right/input/trigger" 42 | }, 43 | { 44 | "inputs": { 45 | "click": { 46 | "output": "/actions/main/in/left_menu_button" 47 | } 48 | }, 49 | "mode": "button", 50 | "path": "/user/hand/left/input/application_menu" 51 | }, 52 | { 53 | "inputs": { 54 | "click": { 55 | "output": "/actions/main/in/right_menu_button" 56 | } 57 | }, 58 | "mode": "button", 59 | "path": "/user/hand/right/input/application_menu" 60 | } 61 | ] 62 | } 63 | }, 64 | "controller_type": "hyperealvr_controller" 65 | } -------------------------------------------------------------------------------- /Packaging/DynamicOpenVR.BeatSaber/DynamicOpenVR/Bindings/beatsaber_index_hmd.json: -------------------------------------------------------------------------------- 1 | { 2 | "bindings" : { 3 | "/actions/main" : { 4 | "sources" : [ 5 | { 6 | "inputs" : { 7 | "click" : { 8 | "output" : "/actions/main/in/headset_on_head" 9 | } 10 | }, 11 | "mode" : "button", 12 | "path" : "/user/head/proximity" 13 | } 14 | ] 15 | } 16 | }, 17 | "controller_type" : "indexhmd" 18 | } 19 | -------------------------------------------------------------------------------- /Packaging/DynamicOpenVR.BeatSaber/DynamicOpenVR/Bindings/beatsaber_knuckles.json: -------------------------------------------------------------------------------- 1 | { 2 | "bindings": { 3 | "/actions/main": { 4 | "haptics": [ 5 | { 6 | "output": "/actions/main/out/left_hand_haptics", 7 | "path": "/user/hand/left/output/haptic" 8 | }, 9 | { 10 | "output": "/actions/main/out/right_hand_haptics", 11 | "path": "/user/hand/right/output/haptic" 12 | } 13 | ], 14 | "poses": [ 15 | { 16 | "output": "/actions/main/in/left_hand_pose", 17 | "path": "/user/hand/left/pose/grip" 18 | }, 19 | { 20 | "output": "/actions/main/in/right_hand_pose", 21 | "path": "/user/hand/right/pose/grip" 22 | } 23 | ], 24 | "sources": [ 25 | { 26 | "inputs": { 27 | "pull": { 28 | "output": "/actions/main/in/left_trigger" 29 | } 30 | }, 31 | "mode": "trigger", 32 | "path": "/user/hand/left/input/trigger" 33 | }, 34 | { 35 | "inputs": { 36 | "pull": { 37 | "output": "/actions/main/in/right_trigger" 38 | } 39 | }, 40 | "mode": "trigger", 41 | "path": "/user/hand/right/input/trigger" 42 | }, 43 | { 44 | "inputs": { 45 | "click": { 46 | "output": "/actions/main/in/left_menu_button" 47 | } 48 | }, 49 | "mode": "button", 50 | "path": "/user/hand/left/input/b" 51 | }, 52 | { 53 | "inputs": { 54 | "click": { 55 | "output": "/actions/main/in/right_menu_button" 56 | } 57 | }, 58 | "mode": "button", 59 | "path": "/user/hand/right/input/b" 60 | }, 61 | { 62 | "inputs": { 63 | "position": { 64 | "output": "/actions/main/in/left_thumbstick" 65 | } 66 | }, 67 | "mode": "joystick", 68 | "path": "/user/hand/left/input/thumbstick" 69 | }, 70 | { 71 | "inputs": { 72 | "position": { 73 | "output": "/actions/main/in/right_thumbstick" 74 | } 75 | }, 76 | "mode": "joystick", 77 | "path": "/user/hand/right/input/thumbstick" 78 | } 79 | ] 80 | }, 81 | "/actions/unity": { 82 | "haptics": [ 83 | { 84 | "output": "/actions/unity/out/left_haptics", 85 | "path": "/user/hand/left/output/haptic" 86 | }, 87 | { 88 | "output": "/actions/unity/out/right_haptics", 89 | "path": "/user/hand/right/output/haptic" 90 | } 91 | ], 92 | "poses": [ 93 | { 94 | "output": "/actions/unity/in/left_pose", 95 | "path": "/user/hand/left/pose/grip" 96 | }, 97 | { 98 | "output": "/actions/unity/in/right_pose", 99 | "path": "/user/hand/right/pose/grip" 100 | } 101 | ], 102 | "sources": [ 103 | { 104 | "inputs": { 105 | "click": { 106 | "output": "/actions/unity/in/left_trigger_button" 107 | }, 108 | "pull": { 109 | "output": "/actions/unity/in/left_trigger" 110 | } 111 | }, 112 | "mode": "trigger", 113 | "path": "/user/hand/left/input/trigger" 114 | }, 115 | { 116 | "inputs": { 117 | "click": { 118 | "output": "/actions/unity/in/right_trigger_button" 119 | }, 120 | "pull": { 121 | "output": "/actions/unity/in/right_trigger" 122 | } 123 | }, 124 | "mode": "trigger", 125 | "path": "/user/hand/right/input/trigger" 126 | }, 127 | { 128 | "inputs": { 129 | "click": { 130 | "output": "/actions/unity/in/left_primary_2d_axis_click" 131 | }, 132 | "position": { 133 | "output": "/actions/unity/in/left_primary_2d_axis" 134 | }, 135 | "touch": { 136 | "output": "/actions/unity/in/left_primary_2d_axis_touch" 137 | } 138 | }, 139 | "mode": "joystick", 140 | "path": "/user/hand/left/input/thumbstick" 141 | }, 142 | { 143 | "inputs": { 144 | "click": { 145 | "output": "/actions/unity/in/right_primary_2d_axis_click" 146 | }, 147 | "position": { 148 | "output": "/actions/unity/in/right_primary_2d_axis" 149 | }, 150 | "touch": { 151 | "output": "/actions/unity/in/right_primary_2d_axis_touch" 152 | } 153 | }, 154 | "mode": "joystick", 155 | "path": "/user/hand/right/input/thumbstick" 156 | }, 157 | { 158 | "inputs": { 159 | "click": { 160 | "output": "/actions/unity/in/left_secondary_button" 161 | }, 162 | "touch": { 163 | "output": "/actions/unity/in/left_secondary_touch" 164 | } 165 | }, 166 | "mode": "button", 167 | "path": "/user/hand/left/input/a" 168 | }, 169 | { 170 | "inputs": { 171 | "click": { 172 | "output": "/actions/unity/in/right_secondary_button" 173 | }, 174 | "touch": { 175 | "output": "/actions/unity/in/right_secondary_touch" 176 | } 177 | }, 178 | "mode": "button", 179 | "path": "/user/hand/right/input/a" 180 | }, 181 | { 182 | "inputs": { 183 | "click": { 184 | "output": "/actions/unity/in/left_primary_button" 185 | }, 186 | "touch": { 187 | "output": "/actions/unity/in/left_primary_touch" 188 | } 189 | }, 190 | "mode": "button", 191 | "path": "/user/hand/left/input/b" 192 | }, 193 | { 194 | "inputs": { 195 | "click": { 196 | "output": "/actions/unity/in/right_primary_button" 197 | }, 198 | "touch": { 199 | "output": "/actions/unity/in/right_primary_touch" 200 | } 201 | }, 202 | "mode": "button", 203 | "path": "/user/hand/right/input/b" 204 | }, 205 | { 206 | "inputs": { 207 | "pull": { 208 | "output": "/actions/unity/in/left_grip" 209 | } 210 | }, 211 | "mode": "trigger", 212 | "path": "/user/hand/left/input/grip" 213 | }, 214 | { 215 | "inputs": { 216 | "pull": { 217 | "output": "/actions/unity/in/right_grip" 218 | } 219 | }, 220 | "mode": "trigger", 221 | "path": "/user/hand/right/input/grip" 222 | }, 223 | { 224 | "inputs": { 225 | "click": { 226 | "output": "/actions/unity/in/left_grip_button" 227 | } 228 | }, 229 | "mode": "button", 230 | "path": "/user/hand/left/input/grip" 231 | }, 232 | { 233 | "inputs": { 234 | "click": { 235 | "output": "/actions/unity/in/right_grip_button" 236 | } 237 | }, 238 | "mode": "button", 239 | "path": "/user/hand/right/input/grip" 240 | } 241 | ] 242 | } 243 | }, 244 | "controller_type": "knuckles" 245 | } -------------------------------------------------------------------------------- /Packaging/DynamicOpenVR.BeatSaber/DynamicOpenVR/Bindings/beatsaber_oculus_touch.json: -------------------------------------------------------------------------------- 1 | { 2 | "bindings": { 3 | "/actions/main": { 4 | "haptics": [ 5 | { 6 | "output": "/actions/main/out/left_hand_haptics", 7 | "path": "/user/hand/left/output/haptic" 8 | }, 9 | { 10 | "output": "/actions/main/out/right_hand_haptics", 11 | "path": "/user/hand/right/output/haptic" 12 | } 13 | ], 14 | "poses": [ 15 | { 16 | "output": "/actions/main/in/left_hand_pose", 17 | "path": "/user/hand/left/pose/grip" 18 | }, 19 | { 20 | "output": "/actions/main/in/right_hand_pose", 21 | "path": "/user/hand/right/pose/grip" 22 | } 23 | ], 24 | "sources": [ 25 | { 26 | "inputs": { 27 | "pull": { 28 | "output": "/actions/main/in/left_trigger" 29 | } 30 | }, 31 | "mode": "trigger", 32 | "path": "/user/hand/left/input/trigger" 33 | }, 34 | { 35 | "inputs": { 36 | "pull": { 37 | "output": "/actions/main/in/right_trigger" 38 | } 39 | }, 40 | "mode": "trigger", 41 | "path": "/user/hand/right/input/trigger" 42 | }, 43 | { 44 | "inputs": { 45 | "click": { 46 | "output": "/actions/main/in/right_menu_button" 47 | } 48 | }, 49 | "mode": "button", 50 | "path": "/user/hand/right/input/b" 51 | }, 52 | { 53 | "inputs": { 54 | "click": { 55 | "output": "/actions/main/in/left_menu_button" 56 | } 57 | }, 58 | "mode": "button", 59 | "path": "/user/hand/left/input/y" 60 | }, 61 | { 62 | "inputs": { 63 | "position": { 64 | "output": "/actions/main/in/left_thumbstick" 65 | } 66 | }, 67 | "mode": "joystick", 68 | "path": "/user/hand/left/input/joystick" 69 | }, 70 | { 71 | "inputs": { 72 | "position": { 73 | "output": "/actions/main/in/right_thumbstick" 74 | } 75 | }, 76 | "mode": "joystick", 77 | "path": "/user/hand/right/input/joystick" 78 | } 79 | ] 80 | }, 81 | "/actions/unity": { 82 | "haptics": [ 83 | { 84 | "output": "/actions/unity/out/left_haptics", 85 | "path": "/user/hand/left/output/haptic" 86 | }, 87 | { 88 | "output": "/actions/unity/out/right_haptics", 89 | "path": "/user/hand/right/output/haptic" 90 | } 91 | ], 92 | "poses": [ 93 | { 94 | "output": "/actions/unity/in/left_pose", 95 | "path": "/user/hand/left/pose/grip" 96 | }, 97 | { 98 | "output": "/actions/unity/in/right_pose", 99 | "path": "/user/hand/right/pose/grip" 100 | } 101 | ], 102 | "sources": [ 103 | { 104 | "inputs": { 105 | "click": { 106 | "output": "/actions/unity/in/left_primary_button" 107 | }, 108 | "touch": { 109 | "output": "/actions/unity/in/left_primary_touch" 110 | } 111 | }, 112 | "mode": "button", 113 | "path": "/user/hand/left/input/x" 114 | }, 115 | { 116 | "inputs": { 117 | "click": { 118 | "output": "/actions/unity/in/left_menu_button" 119 | } 120 | }, 121 | "mode": "button", 122 | "path": "/user/hand/left/input/system" 123 | }, 124 | { 125 | "inputs": { 126 | "click": { 127 | "output": "/actions/unity/in/left_trigger_button" 128 | }, 129 | "pull": { 130 | "output": "/actions/unity/in/left_trigger" 131 | } 132 | }, 133 | "mode": "trigger", 134 | "path": "/user/hand/left/input/trigger" 135 | }, 136 | { 137 | "inputs": { 138 | "click": { 139 | "output": "/actions/unity/in/left_primary_2d_axis_click" 140 | }, 141 | "position": { 142 | "output": "/actions/unity/in/left_primary_2d_axis" 143 | }, 144 | "touch": { 145 | "output": "/actions/unity/in/left_primary_2d_axis_touch" 146 | } 147 | }, 148 | "mode": "joystick", 149 | "path": "/user/hand/left/input/joystick" 150 | }, 151 | { 152 | "inputs": { 153 | "click": { 154 | "output": "/actions/unity/in/left_grip_button" 155 | }, 156 | "pull": { 157 | "output": "/actions/unity/in/left_grip" 158 | } 159 | }, 160 | "mode": "trigger", 161 | "path": "/user/hand/left/input/grip" 162 | }, 163 | { 164 | "inputs": { 165 | "click": { 166 | "output": "/actions/unity/in/left_secondary_button" 167 | }, 168 | "touch": { 169 | "output": "/actions/unity/in/left_secondary_touch" 170 | } 171 | }, 172 | "mode": "button", 173 | "path": "/user/hand/left/input/y" 174 | }, 175 | { 176 | "inputs": { 177 | "click": { 178 | "output": "/actions/unity/in/right_trigger_button" 179 | }, 180 | "pull": { 181 | "output": "/actions/unity/in/right_trigger" 182 | } 183 | }, 184 | "mode": "trigger", 185 | "path": "/user/hand/right/input/trigger" 186 | }, 187 | { 188 | "inputs": { 189 | "click": { 190 | "output": "/actions/unity/in/right_primary_2d_axis_click" 191 | }, 192 | "position": { 193 | "output": "/actions/unity/in/right_primary_2d_axis" 194 | }, 195 | "touch": { 196 | "output": "/actions/unity/in/right_primary_2d_axis_touch" 197 | } 198 | }, 199 | "mode": "joystick", 200 | "path": "/user/hand/right/input/joystick" 201 | }, 202 | { 203 | "inputs": { 204 | "click": { 205 | "output": "/actions/unity/in/right_grip_button" 206 | }, 207 | "pull": { 208 | "output": "/actions/unity/in/right_grip" 209 | } 210 | }, 211 | "mode": "trigger", 212 | "path": "/user/hand/right/input/grip" 213 | }, 214 | { 215 | "inputs": { 216 | "click": { 217 | "output": "/actions/unity/in/right_primary_button" 218 | }, 219 | "touch": { 220 | "output": "/actions/unity/in/right_primary_touch" 221 | } 222 | }, 223 | "mode": "button", 224 | "path": "/user/hand/right/input/a" 225 | }, 226 | { 227 | "inputs": { 228 | "click": { 229 | "output": "/actions/unity/in/right_secondary_button" 230 | }, 231 | "touch": { 232 | "output": "/actions/unity/in/right_secondary_touch" 233 | } 234 | }, 235 | "mode": "button", 236 | "path": "/user/hand/right/input/b" 237 | } 238 | ] 239 | } 240 | }, 241 | "controller_type": "oculus_touch" 242 | } -------------------------------------------------------------------------------- /Packaging/DynamicOpenVR.BeatSaber/DynamicOpenVR/Bindings/beatsaber_rift_hmd.json: -------------------------------------------------------------------------------- 1 | { 2 | "bindings" : { 3 | "/actions/main" : { 4 | "sources" : [ 5 | { 6 | "inputs" : { 7 | "click" : { 8 | "output" : "/actions/main/in/headset_on_head" 9 | } 10 | }, 11 | "mode" : "button", 12 | "path" : "/user/head/proximity" 13 | } 14 | ] 15 | } 16 | }, 17 | "controller_type" : "rift" 18 | } 19 | -------------------------------------------------------------------------------- /Packaging/DynamicOpenVR.BeatSaber/DynamicOpenVR/Bindings/beatsaber_vive_controller.json: -------------------------------------------------------------------------------- 1 | { 2 | "bindings": { 3 | "/actions/main": { 4 | "haptics": [ 5 | { 6 | "output": "/actions/main/out/left_hand_haptics", 7 | "path": "/user/hand/left/output/haptic" 8 | }, 9 | { 10 | "output": "/actions/main/out/right_hand_haptics", 11 | "path": "/user/hand/right/output/haptic" 12 | } 13 | ], 14 | "poses": [ 15 | { 16 | "output": "/actions/main/in/left_hand_pose", 17 | "path": "/user/hand/left/pose/grip" 18 | }, 19 | { 20 | "output": "/actions/main/in/right_hand_pose", 21 | "path": "/user/hand/right/pose/grip" 22 | } 23 | ], 24 | "sources": [ 25 | { 26 | "inputs": { 27 | "pull": { 28 | "output": "/actions/main/in/left_trigger" 29 | } 30 | }, 31 | "mode": "trigger", 32 | "path": "/user/hand/left/input/trigger" 33 | }, 34 | { 35 | "inputs": { 36 | "pull": { 37 | "output": "/actions/main/in/right_trigger" 38 | } 39 | }, 40 | "mode": "trigger", 41 | "path": "/user/hand/right/input/trigger" 42 | }, 43 | { 44 | "inputs": { 45 | "click": { 46 | "output": "/actions/main/in/left_menu_button" 47 | } 48 | }, 49 | "mode": "button", 50 | "path": "/user/hand/left/input/application_menu" 51 | }, 52 | { 53 | "inputs": { 54 | "click": { 55 | "output": "/actions/main/in/right_menu_button" 56 | } 57 | }, 58 | "mode": "button", 59 | "path": "/user/hand/right/input/application_menu" 60 | }, 61 | { 62 | "inputs": { 63 | "position": { 64 | "output": "/actions/main/in/left_thumbstick" 65 | } 66 | }, 67 | "mode": "trackpad", 68 | "path": "/user/hand/left/input/trackpad" 69 | }, 70 | { 71 | "inputs": { 72 | "position": { 73 | "output": "/actions/main/in/right_thumbstick" 74 | } 75 | }, 76 | "mode": "trackpad", 77 | "path": "/user/hand/right/input/trackpad" 78 | } 79 | ] 80 | }, 81 | "/actions/unity": { 82 | "haptics": [ 83 | { 84 | "output": "/actions/unity/out/left_haptics", 85 | "path": "/user/hand/left/output/haptic" 86 | }, 87 | { 88 | "output": "/actions/unity/out/right_haptics", 89 | "path": "/user/hand/right/output/haptic" 90 | } 91 | ], 92 | "poses": [ 93 | { 94 | "output": "/actions/unity/in/left_pose", 95 | "path": "/user/hand/left/pose/grip" 96 | }, 97 | { 98 | "output": "/actions/unity/in/right_pose", 99 | "path": "/user/hand/right/pose/grip" 100 | } 101 | ], 102 | "sources": [ 103 | { 104 | "inputs": { 105 | "click": { 106 | "output": "/actions/unity/in/left_grip_button" 107 | } 108 | }, 109 | "mode": "button", 110 | "path": "/user/hand/left/input/grip" 111 | }, 112 | { 113 | "inputs": { 114 | "click": { 115 | "output": "/actions/unity/in/left_primary_button" 116 | } 117 | }, 118 | "mode": "button", 119 | "path": "/user/hand/left/input/application_menu" 120 | }, 121 | { 122 | "inputs": { 123 | "click": { 124 | "output": "/actions/unity/in/left_trigger_button" 125 | }, 126 | "pull": { 127 | "output": "/actions/unity/in/left_trigger" 128 | } 129 | }, 130 | "mode": "trigger", 131 | "path": "/user/hand/left/input/trigger" 132 | }, 133 | { 134 | "inputs": { 135 | "click": { 136 | "output": "/actions/unity/in/left_primary_2d_axis_click" 137 | }, 138 | "position": { 139 | "output": "/actions/unity/in/left_primary_2d_axis" 140 | }, 141 | "touch": { 142 | "output": "/actions/unity/in/left_primary_2d_axis_touch" 143 | } 144 | }, 145 | "mode": "trackpad", 146 | "path": "/user/hand/left/input/trackpad" 147 | }, 148 | { 149 | "inputs": { 150 | "click": { 151 | "output": "/actions/unity/in/right_primary_button" 152 | } 153 | }, 154 | "mode": "button", 155 | "path": "/user/hand/right/input/application_menu" 156 | }, 157 | { 158 | "inputs": { 159 | "click": { 160 | "output": "/actions/unity/in/right_grip_button" 161 | } 162 | }, 163 | "mode": "button", 164 | "path": "/user/hand/right/input/grip" 165 | }, 166 | { 167 | "inputs": { 168 | "click": { 169 | "output": "/actions/unity/in/right_trigger_button" 170 | }, 171 | "pull": { 172 | "output": "/actions/unity/in/right_trigger" 173 | } 174 | }, 175 | "mode": "trigger", 176 | "path": "/user/hand/right/input/trigger" 177 | }, 178 | { 179 | "inputs": { 180 | "click": { 181 | "output": "/actions/unity/in/right_primary_2d_axis_click" 182 | }, 183 | "position": { 184 | "output": "/actions/unity/in/right_primary_2d_axis" 185 | }, 186 | "touch": { 187 | "output": "/actions/unity/in/right_primary_2d_axis_touch" 188 | } 189 | }, 190 | "mode": "trackpad", 191 | "path": "/user/hand/right/input/trackpad" 192 | } 193 | ] 194 | } 195 | }, 196 | "controller_type": "vive_controller" 197 | } -------------------------------------------------------------------------------- /Packaging/DynamicOpenVR.BeatSaber/DynamicOpenVR/Bindings/beatsaber_vive_hmd.json: -------------------------------------------------------------------------------- 1 | { 2 | "bindings" : { 3 | "/actions/main" : { 4 | "sources" : [ 5 | { 6 | "inputs" : { 7 | "click" : { 8 | "output" : "/actions/main/in/headset_on_head" 9 | } 10 | }, 11 | "mode" : "button", 12 | "path" : "/user/head/proximity" 13 | } 14 | ] 15 | } 16 | }, 17 | "controller_type" : "vive" 18 | } 19 | -------------------------------------------------------------------------------- /Packaging/DynamicOpenVR/Plugins/DynamicOpenVR.manifest: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/beat-saber-modding-group/BSIPA-MetadataFileSchema/master/Schema.json", 3 | "author": "Nicolas Gnyra", 4 | "description": "Unity scripts to allow dynamic creation of OpenVR actions at runtime.", 5 | "gameVersion": "1.30.0", 6 | "id": "DynamicOpenVR", 7 | "name": "DynamicOpenVR", 8 | "version": "0.5.0+dev", 9 | "files": [ 10 | "Libs\\DynamicOpenVR.dll" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![DynamicOpenVR Logo](Documentation/Images/dynamicopenvr-logo-wide.png) 2 | 3 | [![Build Status](https://img.shields.io/github/actions/workflow/status/nicoco007/DynamicOpenVR/build.yml?style=flat-square)](https://github.com/nicoco007/DynamicOpenVR/actions) 4 | [![Latest Version](https://img.shields.io/github/v/release/nicoco007/DynamicOpenVR?include_prereleases&style=flat-square)](https://github.com/nicoco007/DynamicOpenVR/releases) 5 | [![License](https://img.shields.io/github/license/nicoco007/DynamicOpenVR?style=flat-square)](https://github.com/nicoco007/DynamicOpenVR/blob/master/LICENSE) 6 | 7 | ## What is DynamicOpenVR? 8 | 9 | DynamicOpenVR is a set of Unity scripts that enables legacy games to use the new SteamVR action-based input system and allows multiple 3rd party developers to add new action-based inputs and outputs to a game without interfering with each other. It is built to seamlessly integrate with existing games that use either the legacy input system or the new action-based one. 10 | 11 | ### Why should I care? 12 | 13 | DynamicOpenVR makes it easier for developers to add inputs to a game while allowing the user to customize how to trigger those inputs via SteamVR's powerful binding system. This removes the need for an additional layer of configuration and helps avoid hardcoding inputs to specific buttons. 14 | 15 | ## Installing 16 | Download the latest release from [the releases page](https://github.com/nicoco007/DynamicOpenVR/releases) and extract **the entire contents** of the ZIP file into your Beat Saber folder (for Steam, this is usually `C:\Program Files (x86)\Steam\steamapps\common\Beat Saber`), **overwriting any existing files**. 17 | 18 | ## Troubleshooting 19 | See [the troubleshooting guide](TROUBLESHOOTING.md). 20 | 21 | ## Using DynamicOpenVR in your game/mod 22 | While there are currently no official instructions, you can take a look at the DynamicOpenVR.BeatSaber project in this repository for an implementation of DynamicOpenVR for Beat Saber (which uses the legacy input system, so lots of Unity XR input methods are being patched) and the [Beat Saber Custom Avatars](https://github.com/nicoco007/BeatSaberCustomAvatars) mod which uses finger tracking inputs. 23 | 24 | ## Contributing 25 | To automatically copy the compiled DLLs into Beat Saber's installation directory, create a file called DynamicOpenVR.BeatSaber.csproj.user next to DynamicOpenVR.BeatSaber\DynamicOpenVR.BeatSaber.csproj and paste in the following: 26 | 27 | ```xml 28 | 29 | 30 | 31 | 32 | C:\Program Files (x86)\Steam\steamapps\common\Beat Saber 33 | 34 | 35 | ``` 36 | -------------------------------------------------------------------------------- /Source/DynamicOpenVR.BeatSaber/AppConfigConfirmationModal.cs: -------------------------------------------------------------------------------- 1 | // 2 | // DynamicOpenVR.BeatSaber - An implementation of DynamicOpenVR as a Beat Saber plugin. 3 | // Copyright © 2019-2023 Nicolas Gnyra 4 | // 5 | // This program is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU Affero General Public License as published 7 | // by the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU Affero General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU Affero General Public License 16 | // along with this program. If not, see http://www.gnu.org/licenses/. 17 | // 18 | 19 | using System; 20 | using System.Collections.Generic; 21 | using System.Globalization; 22 | using System.IO; 23 | using System.Linq; 24 | using DynamicOpenVR.SteamVR; 25 | using HMUI; 26 | using Newtonsoft.Json; 27 | using UnityEngine; 28 | using UnityEngine.UI; 29 | using Zenject; 30 | 31 | namespace DynamicOpenVR.BeatSaber 32 | { 33 | internal class AppConfigConfirmationModal : MonoBehaviour 34 | { 35 | private ModalView _modalView; 36 | private MainMenuViewController _mainMenuViewController; 37 | private AppConfig _appConfig; 38 | 39 | public static AppConfigConfirmationModal Create(DiContainer container, AppConfig updatedAppConfig) 40 | { 41 | GameObject modalViewObject = container.InstantiatePrefab(container.Resolve().transform.Find("OtherSettings/Content/LanguageDropdown/SimpleTextDropDown/DropdownTableView").gameObject); 42 | modalViewObject.name = "DynamicOpenVR Modal"; 43 | 44 | DestroyImmediate(modalViewObject.GetComponent()); 45 | DestroyImmediate(modalViewObject.GetComponent("ScrollRect")); 46 | DestroyImmediate(modalViewObject.GetComponent()); 47 | DestroyImmediate(modalViewObject.GetComponent()); 48 | 49 | foreach (RectTransform child in modalViewObject.transform) 50 | { 51 | if (child.name == "BG") 52 | { 53 | child.anchoredPosition = Vector2.zero; 54 | child.sizeDelta = Vector2.zero; 55 | } 56 | else 57 | { 58 | Destroy(child.gameObject); 59 | } 60 | } 61 | 62 | MainMenuViewController mainMenuViewController = container.Resolve(); 63 | Transform mainMenuViewControllerTransform = mainMenuViewController.transform; 64 | 65 | var rectTransform = (RectTransform)modalViewObject.transform; 66 | rectTransform.anchorMin = Vector2.one * 0.5f; 67 | rectTransform.anchorMax = Vector2.one * 0.5f; 68 | rectTransform.offsetMin = Vector2.zero; 69 | rectTransform.offsetMax = Vector2.zero; 70 | rectTransform.sizeDelta = new Vector2(110, 65); 71 | rectTransform.SetParent(mainMenuViewControllerTransform, false); 72 | 73 | Material fontMaterial = mainMenuViewControllerTransform.Find("MainContent/SoloButton/Text").GetComponent().fontMaterial; 74 | var textObject = new GameObject("Text"); 75 | CurvedTextMeshPro text = textObject.AddComponent(); 76 | text.text = "DynamicOpenVR.BeatSaber has created file called beatsaber.vrmanifest in your game's folder and would like to permanently register it" + 77 | $"with SteamVR by adding it to the global SteamVR app configuration at {GetExactPath(Plugin.kAppConfigPath)}.\n\n" + 78 | "Doing this allows SteamVR to properly recognize that the game is now using the new input system when the game is not running. " + 79 | "However, since DynamicOpenVR can in rare instances cause input to completely stop working, you can opt to skip this temporarily and" + 80 | "run the game as-is to confirm that everything works as expected and you will be prompted with this message again the next time you start the game.\n\n" + 81 | "Can DynamicOpenVR.BeatSaber proceed with the changes?"; 82 | 83 | text.fontMaterial = fontMaterial; 84 | text.fontSize = 3; 85 | text.alignment = TMPro.TextAlignmentOptions.Left; 86 | text.overflowMode = TMPro.TextOverflowModes.Truncate; 87 | textObject.transform.SetParent(rectTransform, false); 88 | 89 | var textTransform = (RectTransform)textObject.transform; 90 | textTransform.sizeDelta = new Vector2(100, 50); 91 | textTransform.anchoredPosition = new Vector2(0, 5); 92 | 93 | Transform settingsNavigationControllerTransform = container.Resolve().transform; 94 | Button noButton = CreateButton(settingsNavigationControllerTransform.Find("BottomPanel/CancelButton"), "NoButton", "No", new Vector2(-20, 8), rectTransform); 95 | Button yesButton = CreateButton(settingsNavigationControllerTransform.Find("BottomPanel/OkButton"), "YesButton", "Yes", new Vector2(20, 8), rectTransform); 96 | 97 | AppConfigConfirmationModal modal = modalViewObject.AddComponent(); 98 | modal._modalView = modalViewObject.GetComponent(); 99 | modal._mainMenuViewController = mainMenuViewController; 100 | modal._appConfig = updatedAppConfig; 101 | noButton.onClick.AddListener(modal.OnNoButtonClicked); 102 | yesButton.onClick.AddListener(modal.OnYesButtonClicked); 103 | mainMenuViewController.didActivateEvent += modal.OnMainMenuViewControllerActivated; 104 | 105 | return modal; 106 | } 107 | 108 | /// 109 | /// Gets the exact case used on the file system for an existing file or directory. 110 | /// Adapted from https://stackoverflow.com/a/29578292/3133529. 111 | /// 112 | /// A relative or absolute path. 113 | /// True if the exact path was found. False otherwise. 114 | /// 115 | /// This supports drive-lettered paths and UNC paths, but a UNC root 116 | /// will be returned in title case (e.g., \\Server\Share). 117 | /// 118 | private static string GetExactPath(string path) 119 | { 120 | // DirectoryInfo accepts either a file path or a directory path, and most of its properties work for either. 121 | // However, its Exists property only works for a directory path. 122 | var directory = new DirectoryInfo(path); 123 | if (File.Exists(path) || directory.Exists) 124 | { 125 | var parts = new List(); 126 | 127 | DirectoryInfo parentDirectory = directory.Parent; 128 | while (parentDirectory != null) 129 | { 130 | FileSystemInfo entry = parentDirectory.EnumerateFileSystemInfos(directory.Name).First(); 131 | parts.Add(entry.Name); 132 | 133 | directory = parentDirectory; 134 | parentDirectory = directory.Parent; 135 | } 136 | 137 | // Handle the root part (i.e., drive letter or UNC \\server\share). 138 | string root = directory.FullName; 139 | if (root.Contains(':')) 140 | { 141 | root = root.ToUpper(); 142 | } 143 | else 144 | { 145 | string[] rootParts = root.Split('\\'); 146 | root = string.Join("\\", rootParts.Select(part => CultureInfo.CurrentCulture.TextInfo.ToTitleCase(part))); 147 | } 148 | 149 | parts.Add(root); 150 | parts.Reverse(); 151 | path = Path.Combine(parts.ToArray()); 152 | } 153 | 154 | return path; 155 | } 156 | 157 | private static Button CreateButton(Transform template, string name, string text, Vector2 position, Transform parent) 158 | { 159 | var transform = (RectTransform)Instantiate(template); 160 | transform.name = name; 161 | transform.anchorMin = new Vector2(0.5f, 0); 162 | transform.anchorMax = new Vector2(0.5f, 0); 163 | transform.anchoredPosition = position; 164 | transform.SetParent(parent, false); 165 | 166 | Button button = transform.GetComponent