Compare commits

...

81 Commits

Author SHA1 Message Date
MathieuG-P 909b42f0b9 bumb to 1.4.1 2023-12-05 20:45:37 +01:00
MathieuG-P d48203cb26 update oculus binary id 2023-12-05 18:09:09 +01:00
MathieuG-P bfbd72cabf add 1.34.0 2023-12-05 18:04:19 +01:00
MathieuG-P 2da1c568c3 Add supporter 2023-12-04 18:32:02 +01:00
MathieuG-P 0cee42be6f Merge pull request #369 from Zagrios/bugfix/dont-download-maps-alredy-installed-when-installing-playlist
[bugfix] Don't download map already installed when installing a playlist
2023-12-04 17:44:16 +01:00
MathieuG-P 0f33fda360 [bugfix] Don't download map already installed when installing a playlist 2023-12-04 17:43:39 +01:00
MathieuG-P 6a4206271b Merge pull request #368 from Zagrios/bugfix/error-notification-if-version-dont-have-maps-folder
[bugfix] Versions that doesn't have "CustomLevels" folder causes error when installing a playlist
2023-12-04 16:28:47 +01:00
MathieuG-P e9b4ef39a3 [bugfix] Versions that doesn't have "CustomLevels" folder causes error when installing a playlist 2023-12-04 16:26:37 +01:00
MathieuG-P 8dc4b8ffbe Merge pull request #367 from Zagrios/bugfix/text-overflow-spanish-translation
[bugfix] Fix text overflow with spanish translation
2023-12-03 22:18:06 +01:00
MathieuG-P 7d225a3a1c [bugfix] Fix text overflow with spanish translation 2023-12-03 22:17:00 +01:00
MathieuG-P 7ff0fe5677 Merge pull request #365 from emesan22/master
[feature] Japanese translation
2023-12-02 01:22:07 +01:00
MathieuG-P 653d53e122 useless 2023-12-01 02:30:50 +01:00
MathieuG-P c1334af3f0 Merge pull request #366 from Zagrios/bugfix/error-on-closing-oneclick-window-when-downloading
[bugfix] Error when closing oneclick download window while still downloading
2023-12-01 02:20:57 +01:00
MathieuG-P 1850947a17 [bugfix] Error when closing oneclick download window while still downloading
stop send data after the window is destroyed + unsubscribe observable when the window closes
2023-12-01 02:16:31 +01:00
emesan c58fb4ad91 pritterが作動してコードが変更していたところを修正 2023-12-01 07:21:43 +09:00
emesan 5b77f1677c Revert "add"
This reverts commit 15c049530a.
2023-12-01 07:15:59 +09:00
emesan a069142992 どうやら修正していたらしい 2023-11-30 21:49:46 +09:00
emesan b635c05524 add Japanese in Chinese 2023-11-30 21:46:08 +09:00
emesan bb8ee97933 Merge branch 'Zagrios-master' 2023-11-30 21:32:07 +09:00
emesan 15c049530a add 2023-11-30 21:31:43 +09:00
emesan 0ca2d0b081 Merge branch 'master' of https://github.com/Zagrios/bs-manager into Zagrios-master 2023-11-30 21:30:57 +09:00
emesan 1932758f23 Japanese support 2023-11-30 21:14:35 +09:00
Shidorien 3949cfb54c Merge pull request #362 from Zagrios/feature/update-readme
Feature/update readme
2023-11-29 15:17:24 +01:00
Shidorien e22f692e50 Update README.md 2023-11-29 01:06:26 +01:00
Shidorien bd5edf1aaa Update README.md 2023-11-29 01:01:35 +01:00
Shidorien d5f3145230 Update README.md 2023-11-29 01:00:54 +01:00
Shidorien 8a63be3781 Update README.md 2023-11-29 01:00:16 +01:00
Shidorien 0d37a4c084 Update README.md 2023-11-29 00:48:36 +01:00
Shidorien a4a721c8da Update README.md 2023-11-28 22:01:38 +01:00
Shidorien 72f03d36e5 Update README.md 2023-11-28 21:57:03 +01:00
Shidorien c0e67505e5 Update README.md 2023-11-28 21:32:45 +01:00
Shidorien fa44259229 Update README.md 2023-11-28 21:27:01 +01:00
Shidorien 1e349c0142 Update README.md 2023-11-28 21:22:02 +01:00
MathieuG-P 3a9e77de24 bumb to 1.4.0 2023-11-28 13:31:25 +01:00
MathieuG-P 83b2d30b66 Wrong boolean 2023-11-26 16:23:09 +01:00
MathieuG-P 6e9e60cd08 Fix "Download .NET" translation broken 2023-11-26 16:04:28 +01:00
MathieuG-P bf6e9cc95d Fix break line issues with Chinese translation 2023-11-26 16:00:50 +01:00
MathieuG-P 0a10f9d1d5 Change chinese flag 2023-11-26 15:41:40 +01:00
MathieuG-P 72329b6ae4 Merge pull request #359 from ktKongTong/master
[feature] Chinese i18n support
2023-11-26 15:37:47 +01:00
ktKongTong 5e388b801a i18n chinese support 2023-11-26 00:05:37 +08:00
MathieuG-P 64858a3d2c Merge pull request #358 from Zagrios/bugfix/import-version-progression-was-wrong
[bugfix] Import version progression was wrong if symlinks present in the folder
2023-11-22 00:02:25 +01:00
MathieuG-P c4c77bbd7b [bugfix] Import version progression was wrong if symlinks present in the folder 2023-11-21 23:56:56 +01:00
Shidorien 14fe5073a7 Update README.md 2023-11-20 15:56:05 +01:00
Shidorien 59b5023f07 Update README.md 2023-11-20 15:46:27 +01:00
Shidorien ceceff4937 Update README.md 2023-11-20 14:17:39 +01:00
GaetanGrd 21a6007d22 Update logo file path in README.md 2023-11-20 14:07:06 +01:00
GaetanGrd b1d2e806fb Merge branch 'master' into feature/update-readme 2023-11-20 13:58:51 +01:00
MathieuG-P f2f087e6be update patreons 2023-11-20 11:40:43 +01:00
MathieuG-P 7806dfb3b9 bumb to 1.4.0-alpha.2 2023-11-18 13:21:03 +01:00
MathieuG-P d7eb9807f3 nothing 2023-11-18 13:18:56 +01:00
MathieuG-P 713b50a49d Merge pull request #357 from Zagrios/bugfix/unable-to-start-oculus-version-after-moving-installation-path
[bugfix] Unable to start Oculus version after moving installation directory
2023-11-18 12:57:16 +01:00
MathieuG-P d74008b109 [bugfix] Unable to start Oculus version after moving installation path 2023-11-18 12:51:49 +01:00
MathieuG-P a837310518 [chore] add bunch of logs for mods installation 2023-11-18 00:15:55 +01:00
MathieuG-P 2b35226f07 Merge pull request #354 from Zagrios/feature/recommended-banner-best-moddable-version
[feature] Added "recommended" banner on the best modable version
2023-11-17 23:34:45 +01:00
MathieuG-P 8986b5fed9 [feature] thicken "recommended" banner 2023-11-17 23:30:42 +01:00
MathieuG-P 01d07db991 Merge pull request #356 from Zagrios/bugfix/unable-to-launch-oculus-version-after-staying-in-the-version-page-while-downloading
[bugfix] BS version page being downloaded was always recognized as a Steam version, preventing launching if it was an Oculus version
2023-11-17 23:26:54 +01:00
MathieuG-P 9948e9b073 [bugfix] BS version page being downloaded was always recognized as a Steam version, preventing launching if it was an Oculus version 2023-11-17 23:21:28 +01:00
MathieuG-P 77aaeb14c8 Merge pull request #355 from Zagrios/bugfix/prevent-being-able-to-launch-currently-downloading-version
Bugfix/prevent being able to launch currently downloading version
2023-11-17 21:56:32 +01:00
MathieuG-P 3db58391ad [bugfix] Prevent being able to launch downloading BS version 2023-11-17 21:52:36 +01:00
MathieuG-P 0fa298bc09 [chore] add logs for installed versions detection 2023-11-17 21:02:55 +01:00
MathieuG-P 8421288322 [feature] Added "recommended" banner on the best modable version 2023-11-17 20:25:42 +01:00
MathieuG-P 46ee9d33e6 Merge pull request #353 from Zagrios/bugfix/prioritise-ipv4-to-avoid-ipv6-issues
[bugfix] prioritise ipv4 to avoid ipv6 issues
2023-11-15 18:02:55 +01:00
MathieuG-P 811d7a9f5a Merge branch 'master' into bugfix/prioritise-ipv4-to-avoid-ipv6-issues 2023-11-15 17:59:06 +01:00
MathieuG-P 1a5507249b bumb to 1.4.0-alpha.1 2023-11-15 13:24:20 +01:00
GaetanGrd d607458924 fix separator 2023-10-12 04:19:59 +02:00
GaetanGrd 86180ced4e fix separator 2023-10-12 04:19:32 +02:00
GaetanGrd ff781be2d5 move roadmap section 2023-10-12 04:19:17 +02:00
GaetanGrd cd03da7a1c add roadmap section 2023-10-12 04:18:42 +02:00
GaetanGrd 9b514339b3 add links 2023-10-12 04:11:13 +02:00
GaetanGrd 22a7333dbc add links 2023-10-12 04:04:22 +02:00
GaetanGrd a03f50eac3 add others sections 2023-10-12 03:51:22 +02:00
GaetanGrd 363816fc3f Add Version management 2023-10-12 03:36:36 +02:00
Gaëtan Gerard 91f2739262 attempted resolution 06 - use YT video on github readme 2023-10-10 21:14:26 +02:00
GaetanGrd 5836a0a7d1 attempted resolution 05 - use YT video on github readme 2023-10-09 20:23:27 +02:00
GaetanGrd 52d973c189 attempted resolution 04 - use YT video on github readme 2023-10-09 20:22:24 +02:00
GaetanGrd c8da0f4a46 attempted resolution 03 - use YT video on github readme 2023-10-09 20:01:24 +02:00
GaetanGrd bf9c12c027 attempted resolution 02 - use YT video on github readme 2023-10-09 19:55:08 +02:00
GaetanGrd bfbf669c09 attempted resolution 01 - use YT video on github readme 2023-10-09 19:51:58 +02:00
GaetanGrd 141d9aaf1d adding "BSManager: Your Beat Saber Assistant" 2023-10-09 19:37:19 +02:00
MathieuG-P 819409bce1 [bugfix] fix wrong configuration https 2023-10-05 16:36:25 +02:00
MathieuG-P 788d1087ba [bugfix] use ipv4 agent to perform requests 2023-10-04 15:24:41 +02:00
46 changed files with 2910 additions and 457 deletions
+509 -175
View File
@@ -9,242 +9,576 @@
*** https://www.markdownguide.org/basic-syntax/#reference-style-links
-->
<!-- TITLE -->
<!--
----------------------------------------
BSManager
----------------------------------------
-->
<div align="center">
<a href="https://github.com/Zagrios/bs-manager">
<img src="resources/readme/icon.svg" alt="Logo" width="250" height="250">
</a>
<br><br>
<h2><b>BSManager</b></h2>
<i>(Beat Saber Manager)</i>
<br><br>
<span>
Download, manage and customize your versions of Beat Saber with a simple click!
</span>
<br>
<span>
<a href="https://github.com/Zagrios/bs-manager/issues/new?assignees=Zagrios&labels=bug&template=-bug--bug-report.md&title=%5BBUG%5D+%3A+">Report Bug</a>
·
<a href="https://github.com/Zagrios/bs-manager/issues/new?assignees=Zagrios&labels=enhancement&template=-feat---feature-request.md&title=%5BFEAT.%5D+%3A+">Request Feature</a>
·
<a href="https://github.com/Zagrios/bs-manager/security/policy">Report a security vulnerability</a>
</span>
<a href="https://github.com/Zagrios/bs-manager">
<img src="resources/readme/SVG/icon.svg" alt="Logo" width="250" height="250">
</a>
<h1><b>BSManager</b></h1>
<p>
Download, manage and customize your versions of <a href="https://beatsaber.com/">Beat Saber</a> with a simple click!
</p>
<p>
<a
href="https://github.com/Zagrios/bs-manager/issues/new?assignees=Zagrios&labels=bug&template=-bug--bug-report.md&title=%5BBUG%5D+%3A+">Report
Bug</a>
·
<a
href="https://github.com/Zagrios/bs-manager/issues/new?assignees=Zagrios&labels=enhancement&template=-feat---feature-request.md&title=%5BFEAT.%5D+%3A+">Request
Feature</a>
·
<a href="https://github.com/Zagrios/bs-manager/security/policy">Report a security vulnerability</a>
</p>
<hr>
</div>
## <!-- BADGES -->
<br>
<div align="center" >
<a href="https://github.com/Zagrios/bs-manager/stargazers"><img src ="https://img.shields.io/github/stars/Zagrios/bs-manager?style=for-the-badge" alt="Stargazers"/></a>
<a href="https://github.com/Zagrios/bs-manager/network/members"><img src ="https://img.shields.io/github/forks/Zagrios/bs-manager?style=for-the-badge" alt="Forks"/></a>
<a href="https://github.com/Zagrios/bs-manager/blob/master/LICENSE"><img src ="https://img.shields.io/github/license/Zagrios/bs-manager?style=for-the-badge" alt="License"/></a>
<a href="https://github.com/Zagrios/bs-manager/graphs/contributors"><img src ="https://img.shields.io/github/contributors/Zagrios/bs-manager?style=for-the-badge" alt="Contributors"/></a>
<a href="https://github.com/Zagrios/bs-manager/issues"><img alt="GitHub issues" src="https://img.shields.io/github/issues/Zagrios/bs-manager?style=for-the-badge"></a>
<br>
<a href="https://discord.gg/uSqbHVpKdV"><img src ="https://img.shields.io/badge/-DISCORD-5865f2?style=for-the-badge&logo=discord&logoColor=ffffff" alt="discord"/></a>
<a href="https://www.patreon.com/bsmanager"><img src ="https://img.shields.io/badge/-🥰%20Support%20BSM-EC4546?style=for-the-badge" alt="Donation"/></a>
<a href="https://twitter.com/BSManager_"><img src ="https://img.shields.io/badge/-Twitter-F5F8FA?style=for-the-badge&logo=Twitter" alt="Twitter"/></a>
<br>
<!--
----------------------------------------
BADGES
----------------------------------------
-->
<div align="center">
<a href="https://github.com/Zagrios/bs-manager/stargazers"><img
src="https://img.shields.io/github/stars/Zagrios/bs-manager?style=for-the-badge" alt="Stargazers" /></a>
<a href="https://github.com/Zagrios/bs-manager/network/members"><img
src="https://img.shields.io/github/forks/Zagrios/bs-manager?style=for-the-badge" alt="Forks" /></a>
<a href="https://github.com/Zagrios/bs-manager/blob/master/LICENSE"><img
src="https://img.shields.io/github/license/Zagrios/bs-manager?style=for-the-badge" alt="License" /></a>
<a href="https://github.com/Zagrios/bs-manager/graphs/contributors"><img
src="https://img.shields.io/github/contributors/Zagrios/bs-manager?style=for-the-badge" alt="Contributors" /></a>
<a href="https://github.com/Zagrios/bs-manager/issues"><img alt="GitHub issues"
src="https://img.shields.io/github/issues/Zagrios/bs-manager?style=for-the-badge"></a>
<br>
<a href="https://discord.gg/uSqbHVpKdV"><img
src="https://img.shields.io/badge/-DISCORD-5865f2?style=for-the-badge&logo=discord&logoColor=ffffff"
alt="discord" /></a>
<a href="https://www.patreon.com/bsmanager"><img
src="https://img.shields.io/badge/-🥰%20Support%20BSM-EC4546?style=for-the-badge" alt="Donation" /></a>
<a href="https://twitter.com/BSManager_"><img
src="https://img.shields.io/badge/-Twitter-F5F8FA?style=for-the-badge&logo=Twitter" alt="Twitter" /></a>
</div>
<!--
----------------------------------------
TABLE OF CONTENTS
----------------------------------------
-->
<div>
<hr>
<details open>
<summary><b>Table of Contents</b></summary>
<ul>
<li>
<details>
<summary><a href="#bsmanager-your-beat-saber-assistant">BSManager: Your Beat Saber Assistant</a></summary>
<ul>
<li><a href="#what-is-it">What is it?</a></li>
<li><a href="#why-use-it">Why use it?</a></li>
<li><a href="#built-with">Built with</a></li>
<li><a href="#how-to-install">How to install</a></li>
</ul>
</details>
</li>
<li>
<details>
<summary><a href="#version-management">Version Management</a></summary>
<ul>
<li>
<details>
<summary><a href="#downloading-multiple-versions">Downloading multiple versions</a></summary>
<ul>
<li>via Steam account</li>
<li>via Oculus (PCVR) account</li>
</ul>
</details>
</li>
<li><a href="#multi-version-sharing">Multi-version Sharing</a></li>
<li><a href="#importing-an-existing-version-of-beat-saber">Importing an existing version of Beat Saber</a>
</li>
<li><a href="#launch-arguments">Launch arguments</a></li>
<li><a href="#shortcut-creation">Shortcut creation</a></li>
</ul>
</details>
</li>
<li>
<details>
<summary><a href="#download-and-installation">Download and Installation</a></summary>
<ul>
<li><a href="#maps">Maps</a></li>
<li><a href="#playlists">Playlists</a></li>
<li><a href="#mods">Mods</a></li>
<li><a href="#models">Models</a></li>
</ul>
</details>
</li>
<li>
<details>
<summary><a href="#customization">Customization</a></summary>
<ul>
<li><a href="#tool">Tool</a></li>
<li><a href="#beat-saber-instance">Beat Saber Instance</a></li>
</ul>
</details>
</li>
<li>
<details>
<summary><a href="#more-information">More Information</a></summary>
<ul>
<li><a href="#support">Support</a></li>
<li><a href="#credits">Credits</a></li>
<li><a href="#Contributing">Contributing</a></li>
</ul>
</details>
</li>
</ul>
</details>
<div align="right">
[<a href="#readme-bot">Go to bottom</a>]
</div>
</div>
---
<!-- TABLE OF CONTENTS -->
<!--
----------------------------------------
BSMANAGER: YOUR BEAT SABER ASSISTANT
----------------------------------------
-->
<div align="center">
<hr>
<h1><b>BSManager: Your Beat Saber Assistant</b></h1>
</div>
<b>Table of Contents</b>
<ul>
<!--
WHAT IS IT?
----------------------------------------
-->
<div>
<h2>What is it?</h2>
<p><a href="https://github.com/Zagrios/bs-manager">BSManager</a> simplifies your <a href="https://beatsaber.com/">Beat
Saber</a> experience by centralizing the management of mods, maps, and game versions in one place.</p>
</div>
<!--
WHY USE IT?
----------------------------------------
-->
<div>
<h2>Why use it?</h2>
<ul>
<li><strong>Easy</strong>: Manage and switch between different instances of <a href="https://beatsaber.com/">Beat
Saber</a> simply.</li>
<li><strong>Accessibility</strong>: Access a multitude of content with just a few clicks.</li>
<li><strong>Customization</strong>: Adapt <a href="https://github.com/Zagrios/bs-manager">BSManager</a> to your
tastes without technical hassles.</li>
</ul>
<b>Start your enhanced experience with <a href="https://beatsaber.com/">Beat Saber</a> and explore all the features
offered by <a href="https://github.com/Zagrios/bs-manager">BSManager</a>!</b>
</div>
<div align="center">
<br>
<video src="https://github.com/Zagrios/bs-manager/assets/40648115/012b0196-74ef-4ee5-86a4-49e835612f96"/>
</div>
<!--
BUILT WITH
----------------------------------------
-->
<div>
<h2><b>Built With</b></h2>
<ul>
<li>
<a href="#about-the-project">About The Project</a>
<ul>
<li><a href="#built-with">Built With</a></li>
</ul>
<a href="https://electron-react-boilerplate.js.org/"><img
src="https://img.shields.io/badge/-Electron%20React%20Boilerplate-black?style=for-the-badge&logo=Electron"
alt="Electron React Boilerplate"></a>
</li>
<li><a href="#usage">Usage</a></li>
<ul>
<li><a href="#how-to-install">How to install?</a></li>
<li><a href="#manage-versions">Manage Versions</a></li>
<li><a href="#customize-your-versions">Customize your versions</a></li>
<li><a href="#install-mods">Install Mods</a></li>
<li><a href="#install-maps">Install Maps</a></li>
<li><a href="#one-click">One Click</a></li>
<li><a href="#having-problems">Having problems?</a></li>
</ul>
<li><a href="#credits">Credits</a></li>
<li><a href="#contributing">Contributing</a></li>
</ul>
<li>
<a href="https://github.com/SteamRE/DepotDownloader"><img
src="https://img.shields.io/badge/-Depot%20Downloader-2a475e?style=for-the-badge&logo=steam"
alt="Depot Downloader"></a>
</li>
<li>
<a href="https://rxjs.dev/"><img
src="https://img.shields.io/badge/-RxJs-purple?style=for-the-badge&logo=ReactiveX" alt="RxJs"></a>
</li>
<li>
<a href="https://tailwindcss.com/"><img
src="https://img.shields.io/badge/-Tailwind%20CSS-white?style=for-the-badge&logo=Tailwind%20CSS"
alt="TailWind CSS"></a>
</li>
</ul>
</div>
<!--
HOW TO INSTALL
----------------------------------------
-->
<div>
<h2><b>How to install?</b></h2>
<ul>
<li>Download the <a href="https://github.com/Zagrios/bs-manager/releases/latest">latest release</a> from <a
href="https://github.com/Zagrios/bs-manager/releases">Releases</a>.</li>
<li>Execute the installer and <a href="https://github.com/Zagrios/bs-manager">BSManager</a> will start itself.</li>
<li>Once it's done, if you want to download a version, select a version and download it! </li>
<li>From the version page you can choose options, launch the version, and more!</li>
</ul>
</div>
<!-- ABOUT THE PROJECT -->
<div align="center">
<h1> </h1>
<h1><b>About The Project</b></h1>
<video src="https://github.com/Zagrios/bs-manager/assets/40648115/4215384e-eb68-40da-884c-f21df491ef75" />
</div>
<div>
<a href="https://github.com/Zagrios/bs-manager">BSManager</a> was created to unify and improve the two most used Apps in the community (<a href="https://github.com/RiskiVR/BSLegacyLauncher">BS legacy launcher</a> and <a href="https://github.com/Assistant/ModAssistant">Mod Assistant</a>).
<br><br>
<h4><a href="https://github.com/Zagrios/bs-manager">BSManager</a> will allow you to:</h4>
<ul>
<li><b>Manage multiple BeatSaber versions</b>, designed for people who need to play on different versions or have multiple profiles for the same version.</li>
<li><b>Download your maps in the same way</b>, in addition to that, depending on your choice, maps are not version dependent. so you will be able to find your maps whatever version you are using without having to transfer them.</li>
<li><b>Install your mods in one click</b>, just like <a href="https://github.com/Assistant/ModAssistant">Mod Assistant</a>, <a href="https://github.com/Zagrios/bs-manager">BSManager</a> will allow you to install your mods quickly and securely depending on the version you choose.</li>
<li><b>Customize your interface</b>, we know that some of you like to customize your interfaces to the maximum. That's why <a href="https://github.com/Zagrios/bs-manager">BSManager</a> brings you peace of mind on this point, you can change the name of the versions, their color, and you can even change the color of the logo! Of course, a dark theme has been added to protect your eyes at night.</li>
</ul>
</div>
<br>
<!--
----------------------------------------
VERSION MANAGEMENT
----------------------------------------
-->
<div align="center">
<img src="resources/readme/preview.png" alt="preview">
<hr>
<h1><b>Version management</b></h1>
</div>
<br>
<!--BUILT WITH-->
<div>
<h2><b>Built With</b></h2>
<ul>
<li>
<a href="https://electron-react-boilerplate.js.org/"><img src="https://img.shields.io/badge/-Electron%20React%20Boilerplate-black?style=for-the-badge&logo=Electron" alt="Electron React Boilerplate"></a>
</li>
<li>
<a href="https://github.com/SteamRE/DepotDownloader"><img src="https://img.shields.io/badge/-Depot%20Downloader-2a475e?style=for-the-badge&logo=steam" alt="Depot Downloader"></a>
</li>
<li>
<a href="https://rxjs.dev/"><img src="https://img.shields.io/badge/-RxJs-purple?style=for-the-badge&logo=ReactiveX" alt="RxJs"></a>
</li>
<li>
<a href="https://tailwindcss.com/"><img src="https://img.shields.io/badge/-Tailwind%20CSS-white?style=for-the-badge&logo=Tailwind%20CSS" alt="TailWind CSS"></a>
</li>
</ul>
<p>With <a href="https://github.com/Zagrios/bs-manager">BSManager</a>, manage your <a
href="https://beatsaber.com/">Beat Saber</a> versions with ease, allowing the download of new versions and
preserving
existing ones, provided that you own the game on a Steam or Oculus (PC) account.</p>
</div>
<!--
DOWNLOADING MULTIPLE VERSIONS
----------------------------------------
-->
<div>
<h2>Downloading Multiple Versions</h2>
<p><a href="https://github.com/Zagrios/bs-manager">BSManager</a> provides two authentication methods to access your
Steam account, ensuring safe and flexible access to
different game versions:</p>
</div>
<br>
<!--USAGE-->
<div align="center">
<h1> </h1>
<h1><b>Usage</b></h1>
<img src="https://github.com/Zagrios/bs-manager/assets/40648115/09d579de-8b8e-45d3-8829-21a25cc7daf8"/>
</div>
<!--HOW TO INSTALL?-->
<div>
<h2><b>How to install?</b></h2>
<ul>
<li>Download the <a href="https://github.com/Zagrios/bs-manager/releases/latest">latest release</a> from <a href="https://github.com/Zagrios/bs-manager/releases">Releases</a>.</li>
<li>Execute the installer and <a href="../..">BSManager</a> will start itself.</li>
<li>Once its done if you want to download a version, select a version and download it! </li>
<li>From the version page you can choose options, launch the version, and more!</li>
<ul>
<li><strong>via Steam</strong>: Use either your credentials, which will not be stored by <a
href="https://github.com/Zagrios/bs-manager">BSManager</a> or
<a href="https://github.com/SteamRE/DepotDownloader">DepotDownloader</a>, or opt for a quick and secure
authentication via QR with the Steam Guard app.</li>
</ul>
</div>
<br>
<!--MANAGE VERSIONS-->
<div>
<h2><b>Manage Versions</b></h2>
<span>
<a href="https://github.com/Zagrios/bs-manager">BSManager</a> allows you to manage your versions of Beat Saber. It gives you the ability to download any version of Beat Saber as long as you have a Steam account that already owns the game. Using <a href="https://github.com/Zagrios/bs-manager">BSManager</a>, you can easily manage and update your collection of Beat Saber versions.
</span>
</div>
<br>
<div align="center">
https://user-images.githubusercontent.com/40648115/213008824-25cfdda3-6350-42dc-aa53-2132b4b8e838.mov
<img src="https://github.com/Zagrios/bs-manager/assets/40648115/26da3a19-a936-4e6b-b79b-a139d7bd55de" />
</div>
<!--CUSTOM UR VERSIONS-->
<div>
<h2><b>Customize your versions</b></h2>
<span>
<a href="https://github.com/Zagrios/bs-manager">BSManager</a> will allow you to completely customize each of your downloaded versions, you can change the color of the icon, choose a name for the version and finally install your mods,maps and other contents according to the Beat Saber version!
</span>
<ul>
<li><strong>via Oculus</strong>: For Oculus users, <a href="https://github.com/Zagrios/bs-manager">BSManager</a>
uses authentication directly via the <a href="https://about.meta.com/fr/">META</a> website
to retrieve the connection token, ensuring reliable and secure access to your account data.</li>
</ul>
</div>
<br>
<div align="center">
https://user-images.githubusercontent.com/40648115/213296794-74a1e20b-12dc-44ec-a67f-e25d7010bd3d.mov
<img height=450 src="https://github.com/Zagrios/bs-manager/assets/40648115/1e4a2f98-af16-45aa-821d-0c4e90e1e54b" />
<img height=450 src="https://github.com/Zagrios/bs-manager/assets/40648115/3674e629-542d-4de3-b8db-b248f25126d7" />
</div>
<!--INSTALL MODS-->
<!--
MULTI-VERSION SHARING
----------------------------------------
-->
<div>
<h2><b>Install Mods</b></h2>
<span>
<a href="https://github.com/Zagrios/bs-manager">BSManager</a> allows you to manage Beat Saber mods in a quick and easy way. It uses the <a href="https://beatmods.com/#/">BeatMod API</a> to allow you to install, update or uninstall mods for each version of your collection. So the app can help you manage them efficiently.
</span>
<h2>Multi-Version Sharing</h2>
<p><a href="https://github.com/Zagrios/bs-manager">BSManager</a> facilitates the sharing of your maps, models, and
custom files between different versions of <a
href="https://beatsaber.com/">Beat Saber</a>. Thanks to an intuitive user interface, you can easily share
your files from one version to another, ensuring a consistent and continuous gaming experience across all your
installations.</p>
</div>
<br>
<div align="center">
https://user-images.githubusercontent.com/40648115/213296816-bdaafc90-da76-4835-8d83-9ac6a4e1c549.mov
<video src = "https://github.com/Zagrios/bs-manager/assets/40648115/5e0d1503-7a58-4134-878b-a2b31a8936df" />
</div>
<!--INSTALL MAPS-->
<!--
IMPORTING AN EXISTING VERSION OF BEAT SABER
----------------------------------------
-->
<div>
<h2><b>Install Maps</b></h2>
<span>
In addition to managing mods, <a href="https://github.com/Zagrios/bs-manager">BSManager</a> allows you to manage and organize custom beatmaps existing on <a href="https://beatsaver.com">Beat Saver</a>, a popular site for sharing custom beatmaps for beat Saber. Moreover the app allow you to share your maps across all your versions.
</span>
<h2>Importing an Existing Version of Beat Saber</h2>
<p><a href="https://github.com/Zagrios/bs-manager">BSManager</a> allows easy importing and organizing of your existing
versions of <a href="https://beatsaber.com/">Beat Saber</a>, enabling you to retain
all your previously downloaded or created data while taking advantage of <a
href="https://github.com/Zagrios/bs-manager">BSManager</a>'s management features.</p>
</div>
<br>
<div align="center">
https://user-images.githubusercontent.com/40648115/213296838-f775fe83-866d-4764-a7d0-648dbb8ec983.mov
<video src="https://github.com/Zagrios/bs-manager/assets/40648115/cdedb951-d97a-474d-a217-2422be3919f7"/>
</div>
<!--ONE CLICK-->
<!--
LAUNCH ARGUMENTS
----------------------------------------
-->
<div>
<h2><b>One Click</b></h2>
<span>
The "One-Click" feature of <a href="https://github.com/Zagrios/bs-manager">BSManager</a> is an incredibly convenient feature for Beat Saber users. It allows easy and quick installation of models, maps and playlists for all versions of Beat Saber you own.
</span>
<h2>Launch Arguments</h2>
<p><a href="https://github.com/Zagrios/bs-manager">BSManager</a> provides efficient management of <a
href="https://beatsaber.com/">Beat Saber</a> launch arguments, including three predefined ones to
enhance your gaming experience:</p>
<ul>
<li><strong>Oculus Mode</strong>: Launches the game directly in Oculus mode, avoiding the use of STEAM VR.</li>
<li><strong>FPFC Mode</strong>: Enables "FPFC" mode, allowing you to control the game without using a VR
headset.</li>
<li><strong>Debug Mode</strong>: Activates debugging mode, generating Windows log outputs for IPA.</li>
</ul>
<p>You also have the freedom to add your own custom launch arguments by inserting them into "Advanced Launch" and
separating them with a semicolon (;).</p>
</div>
<br>
<div align="center">
https://user-images.githubusercontent.com/40648115/213435051-7feb815d-f32b-4135-b095-ef49726a836c.mov
<img src="https://github.com/Zagrios/bs-manager/assets/40648115/1244d49f-20e1-400c-9818-528f05cfadf5" />
</div>
<!--HAVING PROBLEMS?-->
<!--
SHORTCUT CREATION
----------------------------------------
-->
<div>
<h2><b>Having problems?</b></h2>
<span>
See the <a href="https://github.com/Zagrios/bs-manager/issues">open issues</a> to show the list of known issues, from there you can create a new issue for your problem!
</span>
<h2>Shortcut Creation</h2>
<p>Create shortcuts to easily access your different versions of <a href="https://beatsaber.com/">Beat Saber</a> with
<a href="https://github.com/Zagrios/bs-manager">BSManager</a>. After selecting your
version, go to the version settings, click on "Create a Shortcut", and then select your launch options. Thus,
you can quickly and easily launch your preferred version of <a href="https://beatsaber.com/">Beat Saber</a> with the
desired settings.</p>
</div>
<br><br><br>
<div align="center">
<video src="https://github.com/Zagrios/bs-manager/assets/40648115/bfa1e97d-6392-4dec-a1fc-bb05048cf6d2" />
</div>
<!-- Credits -->
<!--
----------------------------------------
DOWNLOAD AND INSTALLATION
----------------------------------------
-->
<div align="center">
<hr>
<h1><b>Download and Installation</b></h1>
</div>
<div>
<h1><b>Credits</b></h1>
<ul>
<li><a href="https://github.com/Zagrios">Zagrios</a> - Founder & Lead Developer</li>
<li><a href="https://github.com/Iluhadesu">Iluhadesu</a> - Project Team & Developpement help</li>
<li><a href="https://github.com/GaetanGrd">GaetanGrd</a> - Project Team & Developpement help</li>
<li><a href="https://github.com/cheddZy">cheddZy</a> - Icon creator</li>
</ul>
<p><a href="https://github.com/Zagrios/bs-manager">BSManager</a> provides centralized and organized management of
beatmaps, mods, and models, integrating download features and sharing between <a href="https://beatsaber.com/">Beat
Saber</a> versions.</p>
</div>
<!-- Contributing -->
<br>
<!--CONTRIBUTING-->
<!--
MAPS
----------------------------------------
-->
<div>
<h1><b>Contributing</b></h1>
<p>
If you'd like to contribute, check out the <a href="https://github.com/Zagrios/bs-manager/blob/master/CONTRIBUTING.md">contributing guide</a>
</p>
<p>Thank you to all the people who already contributed to BSManager!</p>
<div>
<a href="https://github.com/Zagrios/bs-manager/graphs/contributors">
<img src="https://contrib.rocks/image?repo=Zagrios/bs-manager" />
</a>
</div>
<h2>Maps</h2>
<p><a href="https://github.com/Zagrios/bs-manager">BSManager</a> integrates the <a href="https://beatsaver.com">Beat
Saver</a> API to provide you with a comprehensive list of maps downloadable directly from its interface. Moreover,
the OneClick feature allows you to download maps with one click from various sources such as <a
href="https://beatsaver.com">Beat Saver</a>, <a href="https://bsaber.com">BeastSaber</a>, <a
href="https://scoresaber.com">ScoreSaber</a>, and <a href="https://www.beatleader.xyz">Beat Leader</a>. To add
maps, simply select the desired version or the "shared" tab, then click "ADD".</p>
</div>
<br>
<div align="center">
<video src="https://github.com/Zagrios/bs-manager/assets/40648115/3f9f9968-ac55-465e-bc28-17aebfc787ea"/>
</div>
<!--
PLAYLISTS
----------------------------------------
-->
<div>
<h2>Playlists</h2>
<p>Although the playlist management interface is not yet developed, <a
href="https://github.com/Zagrios/bs-manager">BSManager</a> offers a OneClick feature for playlists from <a
href="https://beatsaver.com">Beat Saver</a>.</p>
</div>
<div align="center">
<video src="https://github.com/Zagrios/bs-manager/assets/40648115/c2765468-e203-4989-85f8-2c3e54d8aba4" />
</div>
<!--
MODS
----------------------------------------
-->
<div>
<h2>Mods</h2>
<p>Manage your mods easily with <a href="https://github.com/Zagrios/bs-manager">BSManager</a>. After downloading a
version, navigate to the "Mods" tab of the selected version to manage and install mods. <a
href="https://github.com/Zagrios/bs-manager">BSManager</a> operates similarly to Mod Assistant and offers the same
mods as this tool.</p>
</div>
<div align="center">
<video src="https://github.com/Zagrios/bs-manager/assets/40648115/ca8f0727-b2dd-41f3-bbea-9bcaf61a89f1"/>
</div>
<!--
MODELS
----------------------------------------
-->
<div>
<h2>Models</h2>
<p>Add and manage models simply via the corresponding tab on the desired version or by going to the "shared" tab. The
<a href="https://modelsaber.com">Model Saber</a> API is integrated to provide easy and direct access to models
available for <a href="https://beatsaber.com/">Beat Saber</a>.</p>
</div>
<div align="center">
<video src="https://github.com/Zagrios/bs-manager/assets/40648115/d983b34b-9f4c-4274-aee4-4c1c03dd90d0"/>
</div>
<!--
----------------------------------------
CUSTOMIZATION
----------------------------------------
-->
<div align="center">
<hr>
<h1><b>Customization</b></h1>
</div>
<div>
<p><a href="https://github.com/Zagrios/bs-manager">BSManager</a> offers various options to customize both the tool
itself and your <a href="https://beatsaber.com/">Beat Saber</a> instances, allowing you to create a user experience
that is uniquely yours.</p>
</div>
<!--
TOOL
----------------------------------------
-->
<div>
<h2>Tool</h2>
<p>Adjust the appearance of <a href="https://github.com/Zagrios/bs-manager">BSManager</a> to your preferences with a
variety of customization options available in the tool's settings:</p>
<ul>
<li><strong>Theme</strong>: Choose between a light or dark theme, or follow the system settings for seamless integration into your work environment.</li>
<li><strong>Color</strong>: Select your preferred primary and secondary colors using hexadecimal codes, allowing you
to customize the visual appearance of the tool to your liking.</li>
</ul>
</div>
<div align="center">
<video src = "https://github.com/Zagrios/bs-manager/assets/40648115/d2c1b0ec-a2f5-41b5-99d5-c4c2cd34cbd4" />
</div>
<!--
BEAT SABER INSTANCE
----------------------------------------
-->
<div>
<h2>Beat Saber Instance</h2>
<p>For each <a href="https://beatsaber.com/">Beat Saber</a> instance, <a
href="https://github.com/Zagrios/bs-manager">BSManager</a> offers customization options accessible via the version
settings and by clicking on "Edit":</p>
<ul>
<li><strong>Name</strong>: Name your instances in a way that distinguishes and identifies them easily when switching
from one to another.</li>
<li><strong>Color</strong>: Customize the appearance of your instances by choosing a specific color for each of
them.</li>
</ul>
</div>
<div align="center">
<video src="https://github.com/Zagrios/bs-manager/assets/40648115/f66a2c99-770e-42ca-9a71-b1806946ad0c" />
</div>
<!--
----------------------------------------
MORE INFORMATION
----------------------------------------
-->
<div align="center">
<hr>
<h1><b>More Information</b></h1>
</div>
<div>
<p><a href="https://github.com/Zagrios/bs-manager">BSManager</a> has an active community and a support team ready to
assist you with any questions or issues you may encounter.</p>
</div>
<!--
SUPPORT
----------------------------------------
-->
<div>
<h2>Support</h2>
<p>For quick and interactive support, it is recommended to join our <a href="https://discord.gg/uSqbHVpKdV">Discord
server</a>. For bugs or more complex issues, you can also submit an <a href="https://github.com/Zagrios/bs-manager/issues">issue on
GitHub</a>.</p>
</div>
<!--
CREDITS
----------------------------------------
-->
<div>
<h2>Credits</h2>
<ul>
<li><a href="https://github.com/Zagrios">Zagrios</a> - Lead Developer & Founder.</li>
<li><a href="https://github.com/Iluhadesu">Iluhadesu</a> - Co-Developer & Co-Founder, Discord Bot Developer.</li>
<li><a href="https://github.com/GaetanGrd">GaetanGrd</a> - Co-Developer & Co-Founder, Documentation Lead.</li>
<li><a href="https://github.com/cheddZy">cheddZy</a> - Icon Creator.</li>
</ul>
</div>
<!--
CONTRIBUTING
----------------------------------------
-->
<div>
<h2>Contributing</h2>
<p>If you'd like to contribute, check out the <a
href="https://github.com/Zagrios/bs-manager/blob/master/CONTRIBUTING.md">contributing guide</a>.</p>
<p>Thank you to all the people who already contributed to <a
href="https://github.com/Zagrios/bs-manager">BSManager</a>!</p>
<div align="center">
<a href="https://github.com/Zagrios/bs-manager/graphs/contributors">
<img src="https://contrib.rocks/image?repo=Zagrios/bs-manager" />
</a>
</div>
</div>
<!--
----------------------------------------
Others
----------------------------------------
-->
<div align="right">
[<a href="#readme-top">Return to top</a>]
[<a href="#readme-top">Return to top</a>]
<hr>
</div>
<h1> </h1>
<a name="readme-bot"></a>
+84 -74
View File
@@ -2,7 +2,7 @@
{
"BSVersion": "0.10.1",
"BSManifest": "6316038906315325420",
"OculusBinaryId": "1392433784189730",
"OculusBinaryId": "1392433784189730",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/1662268711472777795",
"ReleaseImg": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/clans/32055887/a6d2b9ce074e71458499defdb5ef83bc4b9b56bb.png",
"ReleaseDate": "1525201860",
@@ -11,7 +11,7 @@
{
"BSVersion": "0.10.2",
"BSManifest": "2542095265882143144",
"OculusBinaryId": "1401326316633810",
"OculusBinaryId": "1401326316633810",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3199123443061240805",
"ReleaseDate": "1526065860",
"year": "2018"
@@ -19,7 +19,7 @@
{
"BSVersion": "0.10.2p1",
"BSManifest": "5611588554149133260",
"OculusBinaryId": "1408948315871610",
"OculusBinaryId": "1408948315871610",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/1660018815112331498",
"ReleaseDate": "1526843460",
"year": "2018"
@@ -33,7 +33,7 @@
{
"BSVersion": "0.11.0",
"BSManifest": "8700049030626148111",
"OculusBinaryId": "1480180522081722",
"OculusBinaryId": "1480180522081722",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/1675787121569907303",
"ReleaseDate": "1532027460",
"year": "2018"
@@ -41,7 +41,7 @@
{
"BSVersion": "0.11.1",
"BSManifest": "6574193224879562324",
"OculusBinaryId": "1481807568585684",
"OculusBinaryId": "1481807568585684",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/1675787121577641471",
"ReleaseDate": "1532113860",
"year": "2018"
@@ -49,7 +49,7 @@
{
"BSVersion": "0.11.2",
"BSManifest": "2707973953401625222",
"OculusBinaryId": "1529600877139686",
"OculusBinaryId": "1529600877139686",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/1700559455389069835",
"ReleaseDate": "1534792260",
"year": "2018"
@@ -57,7 +57,7 @@
{
"BSVersion": "0.12.0",
"BSManifest": "6094599000655593822",
"OculusBinaryId": "1645858012180638",
"OculusBinaryId": "1645858012180638",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/1708449632708343984",
"ReleaseDate": "1543349460",
"year": "2018"
@@ -65,7 +65,7 @@
{
"BSVersion": "0.12.0p1",
"BSManifest": "2068421223689664394",
"OculusBinaryId": "1648187958614310",
"OculusBinaryId": "1648187958614310",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/1708450266986928520",
"ReleaseDate": "1543435860",
"year": "2018"
@@ -73,7 +73,7 @@
{
"BSVersion": "0.12.1",
"BSManifest": "2472041066434647526",
"OculusBinaryId": "1668279893271783",
"OculusBinaryId": "1668279893271783",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3142848113551335636",
"ReleaseImg": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/clans/32055887/9b4b1890f39a682c6f4a06f12a56965b7aee0b6c.jpg",
"ReleaseDate": "1544818260",
@@ -82,7 +82,7 @@
{
"BSVersion": "0.12.2",
"BSManifest": "5325635033564462932",
"OculusBinaryId": "1676445885788517",
"OculusBinaryId": "1676445885788517",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/1708452169977638962",
"ReleaseImg": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/clans/32055887/82e2ce43df0e59337a79341c54ac2e5e12a5e7bc.jpg",
"ReleaseDate": "1545423060",
@@ -91,7 +91,7 @@
{
"BSVersion": "0.13.0",
"BSManifest": "3102409495238838111",
"OculusBinaryId": "1796264627139975",
"OculusBinaryId": "1796264627139975",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/1809790777736470809",
"ReleaseImg": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/clans/32055887/8f2128973e6d221b4f00aedb5194417eadad9920.jpg",
"ReleaseDate": "1552594260",
@@ -107,7 +107,7 @@
{
"BSVersion": "0.13.1",
"BSManifest": "6033025349617217666",
"OculusBinaryId": "1823415097758261",
"OculusBinaryId": "1823415097758261",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/1735482645687974657",
"ReleaseDate": "1554145860",
"year": "2019"
@@ -115,7 +115,7 @@
{
"BSVersion": "0.13.2",
"BSManifest": "6839388023573913446",
"OculusBinaryId": "1827595530673551",
"OculusBinaryId": "1827595530673551",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/1779393376014546213",
"ReleaseDate": "1554405060",
"year": "2019"
@@ -123,7 +123,7 @@
{
"BSVersion": "1.0.0",
"BSManifest": "152937782137361764",
"OculusBinaryId": "1901720436594393",
"OculusBinaryId": "1901720436594393",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/2655347409592352590",
"ReleaseImg": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/clans/32055887/023ab2b6a2f811e2beea327ae3875da643101694.jpg",
"ReleaseDate": "1558465860",
@@ -132,7 +132,7 @@
{
"BSVersion": "1.0.1",
"BSManifest": "7950322551526208347",
"OculusBinaryId": "1910612422371861",
"OculusBinaryId": "1910612422371861",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/1617268229025488499",
"ReleaseDate": "1558984260",
"year": "2019"
@@ -140,7 +140,7 @@
{
"BSVersion": "1.1.0",
"BSManifest": "1400454104881094752",
"OculusBinaryId": "1929327700500333",
"OculusBinaryId": "1929327700500333",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/1606010497768610092",
"ReleaseDate": "1560193860",
"year": "2019"
@@ -155,7 +155,7 @@
{
"BSVersion": "1.2.0",
"BSManifest": "3820905673516362176",
"OculusBinaryId": "2007606406005795",
"OculusBinaryId": "2007606406005795",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3266717385279679846",
"ReleaseImg": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/clans/32055887/cd96e7e784bb8761ba8e8609285baa5e1aec0d85.jpg",
"ReleaseDate": "1564081860",
@@ -164,7 +164,7 @@
{
"BSVersion": "1.3.0",
"BSManifest": "2440312204809283162",
"OculusBinaryId": "2063391663760602",
"OculusBinaryId": "2063391663760602",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/1602640407719691235",
"ReleaseImg": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/clans/32055887/7aec534fb70fafa582addd6cd52998ccc31adf57.jpg",
"ReleaseDate": "1567105860",
@@ -173,7 +173,7 @@
{
"BSVersion": "1.4.0",
"BSManifest": "3532596684905902618",
"OculusBinaryId": "2126093504157084",
"OculusBinaryId": "2126093504157084",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/1595888090489865366",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/2998e47ebbc57552718bb95e233a3a43d598630f.png",
"ReleaseDate": "1567105860",
@@ -182,7 +182,7 @@
{
"BSVersion": "1.4.2",
"BSManifest": "1199049250928380207",
"OculusBinaryId": "2136904763075958",
"OculusBinaryId": "2136904763075958",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3172148783714663931",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/b35d93fe817cea38c92c266579395c1fcd275af2.jpg",
"ReleaseDate": "1570821060",
@@ -191,7 +191,7 @@
{
"BSVersion": "1.5.0",
"BSManifest": "2831333980042022356",
"OculusBinaryId": "2179706668795767",
"OculusBinaryId": "2179706668795767",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/1604898551795379829",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/56dbb4a14b764ccea1de93625225b83de1636aee_400x225.jpg",
"ReleaseDate": "1573157460",
@@ -200,7 +200,7 @@
{
"BSVersion": "1.6.0",
"BSManifest": "1869974316274529288",
"OculusBinaryId": "2264419510324482",
"OculusBinaryId": "2264419510324482",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3462636667924814182",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/99a5ad752c76859e8697d75a140500195969fb2d.jpg",
"ReleaseDate": "1576267860",
@@ -209,7 +209,7 @@
{
"BSVersion": "1.6.1",
"BSManifest": "6122319670026856947",
"OculusBinaryId": "2313973998702366",
"OculusBinaryId": "2313973998702366",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/1702855647517326143",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/5e54a041cc52674f03a4d7c5406f2bb42d1f379b_400x225.jpg",
"ReleaseDate": "1578427860",
@@ -218,7 +218,7 @@
{
"BSVersion": "1.6.2",
"BSManifest": "4932559146183937357",
"OculusBinaryId": "2319779251455174",
"OculusBinaryId": "2319779251455174",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/1702857555888635029",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/5e54a041cc52674f03a4d7c5406f2bb42d1f379b_400x225.jpg",
"ReleaseDate": "1578600660",
@@ -227,7 +227,7 @@
{
"BSVersion": "1.7.0",
"BSManifest": "3516084911940449222",
"OculusBinaryId": "2355681587864940",
"OculusBinaryId": "2355681587864940",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/1708488968117071534",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/ddf8c11e64231bf86ff18f5bb7d81f7dec7bc655_400x225.png",
"ReleaseDate": "1580328660",
@@ -236,7 +236,7 @@
{
"BSVersion": "1.8.0",
"BSManifest": "3177969677109016846",
"OculusBinaryId": "2483396065093491",
"OculusBinaryId": "2483396065093491",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/2080040995048021450",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/ef301c5813a7f029156da357a997f17f80564a17_400x225.png",
"ReleaseDate": "1585253460",
@@ -245,7 +245,7 @@
{
"BSVersion": "1.9.0",
"BSManifest": "7885463693258878294",
"OculusBinaryId": "2509250149174749",
"OculusBinaryId": "2509250149174749",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/2194884053816491058",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/8b365e3fdd9e8494987ea92543114404f20db891.png",
"ReleaseDate": "1586459460",
@@ -254,7 +254,7 @@
{
"BSVersion": "1.9.1",
"BSManifest": "6222769774084748916",
"OculusBinaryId": "2555492557883841",
"OculusBinaryId": "2555492557883841",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/2196011856188103369",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/144427845aef04dbe4aa9dee62818f2d637e1f42_400x225.png",
"ReleaseDate": "1588705860",
@@ -263,7 +263,7 @@
{
"BSVersion": "1.10.0",
"BSManifest": "6711131863503994755",
"OculusBinaryId": "2611337982299298",
"OculusBinaryId": "2611337982299298",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/2179125258536373088",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/3a13e1c04c4f91a16c53fdb3a7662bcae60f48fa.png",
"ReleaseDate": "1590433860",
@@ -272,7 +272,7 @@
{
"BSVersion": "1.11.0",
"BSManifest": "1919603726987963829",
"OculusBinaryId": "2827873783979049",
"OculusBinaryId": "2827873783979049",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3961432516746159538",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/afba23a3fcc80b6d2c40d2acd9ab9a51be9d3eee.png",
"ReleaseDate": "1597691460",
@@ -281,14 +281,14 @@
{
"BSVersion": "1.11.1",
"BSManifest": "3268824881806146387",
"OculusBinaryId": "2844730055626755",
"OculusBinaryId": "2844730055626755",
"ReleaseDate": "1597950660",
"year": "2020"
},
{
"BSVersion": "1.12.1",
"BSManifest": "2928416283534881313",
"OculusBinaryId": "3002627316503694",
"OculusBinaryId": "3002627316503694",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/2889580787311737971",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/cb8f24404f10a177e0ff60473f9293c8fb9b5496.png",
"ReleaseDate": "1602616260",
@@ -297,7 +297,7 @@
{
"BSVersion": "1.12.2",
"BSManifest": "543439039654962432",
"OculusBinaryId": "3027756187324140",
"OculusBinaryId": "3027756187324140",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/5096345334644252275",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/56d1d6b2a2687530a5db221241cc4d7e4feefb4d.png",
"ReleaseDate": "1603134660",
@@ -306,7 +306,7 @@
{
"BSVersion": "1.13.0",
"BSManifest": "4635119747389290346",
"OculusBinaryId": "3087480618018363",
"OculusBinaryId": "3087480618018363",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/2903094755791760339",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/4ae946eda7c0bc9421c2afb7b33e965103924cb9.png",
"ReleaseDate": "1605211860",
@@ -315,7 +315,7 @@
{
"BSVersion": "1.13.2",
"BSManifest": "8571679771389514488",
"OculusBinaryId": "3259559474143809",
"OculusBinaryId": "3259559474143809",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3025824186763919109",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/70f13d02f95c7fadae92305474ae16ce1b99162e.jpg",
"ReleaseDate": "1611259860",
@@ -324,7 +324,7 @@
{
"BSVersion": "1.13.4",
"BSManifest": "1257277263145069282",
"OculusBinaryId": "3377183652381390",
"OculusBinaryId": "3377183652381390",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3020198491530803202",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/78643cb3c68591da1e69550300a6452390c3e797.png",
"ReleaseDate": "1615320660",
@@ -333,7 +333,7 @@
{
"BSVersion": "1.13.5",
"BSManifest": "7007516983116400336",
"OculusBinaryId": "3391815807584841",
"OculusBinaryId": "3391815807584841",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3021325027071201045",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/2611baaea1f0e49be4f611fed4a3cb5d155c8eb5.png",
"ReleaseDate": "1615579860",
@@ -342,7 +342,7 @@
{
"BSVersion": "1.14.0",
"BSManifest": "9218225910501819399",
"OculusBinaryId": "3405570192876069",
"OculusBinaryId": "3405570192876069",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3012318462417082617",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/51750f9885b9fe51df5820ba0e7f36c9b2154d22.png",
"ReleaseDate": "1616098260",
@@ -351,7 +351,7 @@
{
"BSVersion": "1.15.0",
"BSManifest": "7624554893344753887",
"OculusBinaryId": "3512427425523678",
"OculusBinaryId": "3512427425523678",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3041595663499101523",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/e8de2954a115e1961bdbfa3abab546d43dd653a4.png",
"ReleaseDate": "1619723460",
@@ -360,7 +360,7 @@
{
"BSVersion": "1.16.0",
"BSManifest": "3667184295685865706",
"OculusBinaryId": "3602735303159556",
"OculusBinaryId": "3602735303159556",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3001065803744427929",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/0ad20c1cf3d4e78aa8f28fd136f89f3683df2fb6.png",
"ReleaseDate": "1622142660",
@@ -369,7 +369,7 @@
{
"BSVersion": "1.16.1",
"BSManifest": "9201874499606445062",
"OculusBinaryId": "3608513445915075",
"OculusBinaryId": "3608513445915075",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3001065803748822093",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/522ca68fe0c4576f57189afdbb8107226cdcc819.png",
"ReleaseDate": "1622229060",
@@ -378,7 +378,7 @@
{
"BSVersion": "1.16.2",
"BSManifest": "3692829915208062825",
"OculusBinaryId": "3631747100258376",
"OculusBinaryId": "3631747100258376",
"ReleaseURL": "http://steamcommunity.com/games/620980/announcements/detail/3024710972645830369",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/7e81895079a84f1b85ddcee330aec7e5626fd2c6.png",
"ReleaseDate": "1623352260",
@@ -387,7 +387,7 @@
{
"BSVersion": "1.16.3",
"BSManifest": "6392596175313869009",
"OculusBinaryId": "3737896816310070",
"OculusBinaryId": "3737896816310070",
"ReleaseURL": "http://steamcommunity.com/games/620980/announcements/detail/5293402556388135977",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/34340f96abfa0203931ca312302ee0c19dc336c2.png",
"ReleaseDate": "1626808260",
@@ -396,7 +396,7 @@
{
"BSVersion": "1.16.4",
"BSManifest": "8820433629543698585",
"OculusBinaryId": "3759730617460023",
"OculusBinaryId": "3759730617460023",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/2965042081090310028",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/22b48a8e92eed7c4e471692124724a2f3ebc3f18.png",
"ReleaseDate": "1627326660",
@@ -405,7 +405,7 @@
{
"BSVersion": "1.17.0",
"BSManifest": "7826684224434229804",
"OculusBinaryId": "3858475637585520",
"OculusBinaryId": "3858475637585520",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/2945905042782366475",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/a789a030122442308376887039c244222b92c768.png",
"ReleaseDate": "1630437060",
@@ -414,7 +414,7 @@
{
"BSVersion": "1.17.1",
"BSManifest": "4668547658954826996",
"OculusBinaryId": "3894496013983482",
"OculusBinaryId": "3894496013983482",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/2947032120578243378",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/51561161026afcf3482bcbe2ea62a6d56e03a8d0.png",
"ReleaseDate": "1631214660",
@@ -423,7 +423,7 @@
{
"BSVersion": "1.18.0",
"BSManifest": "5599254819160454367",
"OculusBinaryId": "3926417640791319",
"OculusBinaryId": "3926417640791319",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/5570379635768010184",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/89a693714b3ee32d84d05bf62caca6f651a1dbec.png",
"ReleaseDate": "1632251460",
@@ -432,7 +432,7 @@
{
"BSVersion": "1.18.1",
"BSManifest": "8961661233382948062",
"OculusBinaryId": "3968051796627903",
"OculusBinaryId": "3968051796627903",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/2994322456166449763",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/a3a4511beadf811a56742fc234724ad14ab34749.png",
"ReleaseDate": "1633547460",
@@ -441,7 +441,7 @@
{
"BSVersion": "1.18.2",
"BSManifest": "6835596583028648427",
"OculusBinaryId": "4024867594279656",
"OculusBinaryId": "4024867594279656",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3026974832179662032",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/71994e941f3d2a8fbbe335fc717c136b5dc9f823.png",
"ReleaseDate": "1635189060",
@@ -450,7 +450,7 @@
{
"BSVersion": "1.18.3",
"BSManifest": "6558821762131072991",
"OculusBinaryId": "4042806399152442",
"OculusBinaryId": "4042806399152442",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3067508483705433949",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/7d79335af5e8ca560198e6a850e339bd7b430d9f.png",
"ReleaseDate": "1636056660",
@@ -459,7 +459,7 @@
{
"BSVersion": "1.19.0",
"BSManifest": "8948172000430595334",
"OculusBinaryId": "4132873813479033",
"OculusBinaryId": "4132873813479033",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3105792342251200877",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/537cf297a6f90b8bbe7baae92b6885f8fbf98d8c.png",
"ReleaseDate": "1639167060",
@@ -468,7 +468,7 @@
{
"BSVersion": "1.19.1",
"BSManifest": "1175216641760077721",
"OculusBinaryId": "4409301142502964",
"OculusBinaryId": "4409301142502964",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/5771929045825669047",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/908d3ebdf273ca6573c3c95898be22ff052ea014.png",
"ReleaseDate": "1644869460",
@@ -477,7 +477,7 @@
{
"BSVersion": "1.20.0",
"BSManifest": "4202491068770948196",
"OculusBinaryId": "4473099549456456",
"OculusBinaryId": "4473099549456456",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3096792662638975765",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/8dfcc668bc78674d7c1d010cee2a8153e0c0c2aa.png",
"ReleaseDate": "1646770260",
@@ -486,7 +486,7 @@
{
"BSVersion": "1.21.0",
"BSManifest": "3648558848715327622",
"OculusBinaryId": "4527595284006882",
"OculusBinaryId": "4527595284006882",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3180111792066790947",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/d854a4cc83b282acc191227a7759b4f5e6c6b085.png",
"ReleaseDate": "1648753860",
@@ -495,7 +495,7 @@
{
"BSVersion": "1.22.0",
"BSManifest": "4038188869828689801",
"OculusBinaryId": "4634406099992466",
"OculusBinaryId": "4634406099992466",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3181240878804806326",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/8486ec6eb3b6e28eaac59d414dd20bd18eed36d8.png",
"ReleaseDate": "1651777860",
@@ -504,7 +504,7 @@
{
"BSVersion": "1.22.1",
"BSManifest": "3771211058784167267",
"OculusBinaryId": "4660898857343190",
"OculusBinaryId": "4660898857343190",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3185745740381652029",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/bc9fea661f7f18616b6b2feb267cc3af0ea679c5.png",
"ReleaseDate": "1652987460",
@@ -513,7 +513,7 @@
{
"BSVersion": "1.23.0",
"BSManifest": "8051970117665729770",
"OculusBinaryId": "4681198518646557",
"OculusBinaryId": "4681198518646557",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3346751320551809488",
"ReleaseImg": "https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/clans//32055887/1623b6e0b864fdad8be08275c3bb126868eafe9b.png",
"ReleaseDate": "1655218980",
@@ -522,7 +522,7 @@
{
"BSVersion": "1.24.0",
"BSManifest": "649695825989344999",
"OculusBinaryId": "4793158617450546",
"OculusBinaryId": "4793158617450546",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/4719226562388423388",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans//32055887/82c29d674bc57596102a6b815f66e956f217e658.png",
"ReleaseDate": "1657810920",
@@ -531,7 +531,7 @@
{
"BSVersion": "1.24.1",
"BSManifest": "3141359577983993890",
"OculusBinaryId": "4962706317162441",
"OculusBinaryId": "4962706317162441",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/4719226562388423388",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans//32055887/82c29d674bc57596102a6b815f66e956f217e658.png",
"ReleaseDate": "1661864214",
@@ -540,7 +540,7 @@
{
"BSVersion": "1.25.0",
"BSManifest": "4529582051007915041",
"OculusBinaryId": "4996170620482677",
"OculusBinaryId": "4996170620482677",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3312985013538143172",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans//32055887/54ac649877eca25a2a6449662337e2c63c51bbcf.png",
"ReleaseDate": "1665068529",
@@ -549,7 +549,7 @@
{
"BSVersion": "1.25.1",
"BSManifest": "7372469314660649150",
"OculusBinaryId": "5074476459318759",
"OculusBinaryId": "5074476459318759",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/5346361068670142187",
"ReleaseImg": "https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/clans//32055887/52cbd15b5e226f509e051565f6e4935eb0e44e2c.png",
"ReleaseDate": "1665673269",
@@ -558,7 +558,7 @@
{
"BSVersion": "1.26.0",
"BSManifest": "3634450655207470002",
"OculusBinaryId": "5116093325157072",
"OculusBinaryId": "5116093325157072",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3414318646334948892",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans//32055887/d18ad9d7f45a5cc2a467d75f0bdf9d32b9141b14.png",
"ReleaseDate": "1667923560",
@@ -567,7 +567,7 @@
{
"BSVersion": "1.27.0",
"BSManifest": "3485516174915301618",
"OculusBinaryId": "5232077970225273",
"OculusBinaryId": "5232077970225273",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3629368753553708497",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans//32055887/d9ed8771498be7fc83721aaaaa5b15a08fbeadb1.png",
"ReleaseDate": "1670943003",
@@ -576,7 +576,7 @@
{
"BSVersion": "1.28.0",
"BSManifest": "7463243155526905423",
"OculusBinaryId": "5425534454212956",
"OculusBinaryId": "5425534454212956",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3666530358620442392",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans//32055887/8f978bbf292810004bca12523e76be8a7eec8c4e.png",
"ReleaseDate": "1677593822",
@@ -585,7 +585,7 @@
{
"BSVersion": "1.29.0",
"BSManifest": "3341527958186345367",
"OculusBinaryId": "5550538398379227",
"OculusBinaryId": "5550538398379227",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/6169409105082976092",
"ReleaseImg": "https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/clans//32055887/255fd49cd96042b97089f754609be291293e783f.png",
"ReleaseDate": "1680188760",
@@ -594,16 +594,17 @@
{
"BSVersion": "1.29.1",
"BSManifest": "886973241045584398",
"OculusBinaryId": "5581819385251128",
"OculusBinaryId": "5581819385251128",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/6169409105101272202",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/c328e407367e9914abaf92f609501877ee5abb63.png",
"ReleaseDate": "1680623885",
"year": "2023"
"year": "2023",
"recommended": true
},
{
"BSVersion": "1.29.4",
"BSManifest": "6291266771922375922",
"OculusBinaryId": "5659705544129178",
"OculusBinaryId": "5659705544129178",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3708194993422325380",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/9c3d476c03e4a2ac72ca5df016b7c94d242b41cb.png",
"ReleaseDate": "1683644991",
@@ -612,7 +613,7 @@
{
"BSVersion": "1.30.0",
"BSManifest": "7304715857122259127",
"OculusBinaryId": "5699848430114889",
"OculusBinaryId": "5699848430114889",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3725085394628677636",
"ReleaseImg": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/32055887/cd56688ad716b544af14a61b2fbace9088478887.png",
"ReleaseDate": "1684965390",
@@ -621,7 +622,7 @@
{
"BSVersion": "1.30.2",
"BSManifest": "8042804988990059618",
"OculusBinaryId": "5770096269756771",
"OculusBinaryId": "5770096269756771",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3655280868312846230",
"ReleaseImg": "https://clan.akamai.steamstatic.com/images/32055887/6d78e092c54f411b36f2c0577d62eb1b25f91aa3.png",
"ReleaseDate": "1686668364",
@@ -630,7 +631,7 @@
{
"BSVersion": "1.31.0",
"BSManifest": "676582354127623831",
"OculusBinaryId": "5824747874291610",
"OculusBinaryId": "5824747874291610",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3674423070127121445",
"ReleaseImg": "https://clan.cloudflare.steamstatic.com/images/32055887/28993aecc56a75c52295fa07620f58cb0e4b09e8.png",
"ReleaseDate": "1688050646",
@@ -639,7 +640,7 @@
{
"BSVersion": "1.31.1",
"BSManifest": "5239818041644201119",
"OculusBinaryId": "6044391715660557",
"OculusBinaryId": "6044391715660557",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3664295677895178184",
"ReleaseImg": "https://clan.akamai.steamstatic.com/images/32055887/58621b3cb8bf42fcfbf3b97fe47aa91b290eea04.png",
"ReleaseDate": "1693824747",
@@ -648,7 +649,7 @@
{
"BSVersion": "1.32.0",
"BSManifest": "1660149393914874041",
"OculusBinaryId": "6168675063232221",
"OculusBinaryId": "6168675063232221",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3723971545002767483",
"ReleaseImg": "https://clan.cloudflare.steamstatic.com/images/32055887/02284793f06188caf740da66939679afc25415e4.png",
"ReleaseDate": "1696517680",
@@ -657,10 +658,19 @@
{
"BSVersion": "1.33.0",
"BSManifest": "706865160400890715",
"OculusBinaryId": "6255299197903140",
"OculusBinaryId": "6255299197903140",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3744239644488431243",
"ReleaseImg": "https://clan.akamai.steamstatic.com/images/32055887/cac079717d62489822af3a6e90679a570842f4ca.png",
"ReleaseDate": "1698678611",
"year": "2023"
},
{
"BSVersion": "1.34.0",
"BSManifest": "3651119791147907495",
"OculusBinaryId": "6373048192794906",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3744239644488431243",
"ReleaseImg": "https://clan.cloudflare.steamstatic.com/images/32055887/1ef505a26d6eb8d7d8c132df54bd57918339cb2c.png",
"ReleaseDate": "1701795528",
"year": "2023"
}
]
+4 -8
View File
@@ -6,19 +6,15 @@
{"username": "Naysy"},
{"username": "Falmil"},
{"username": "K1Lc4m"},
{"username": "Adam"},
{"username": "Cabalia"},
{"username": "Anonymously42", "type": "diamond", "link": "https://www.twitch.tv/anonymously42tv"},
{"username": "En4Yuz"},
{"username": "AndyIsHereBoi", "type": "gold"},
{"username": "grtroadrunner"},
{"username": "Burt", "type": "gold"},
{"username": "Ilnahro"},
{"username": "T3chLog"},
{"username": "Phil", "type": "gold"},
{"username": "Protocrush", "type": "gold"},
{"username": "ServerMensch", "type": "gold"},
{"username": "policepigou"},
{"username": "Karlito", "type": "gold"},
{"username": "Cathery", "type": "gold"},
{"username": ".sharkey"}
{"username": ".sharkey"},
{"username": "Z3t4"},
{"username": "blot455", "type": "diamond"}
]
+15 -9
View File
@@ -108,7 +108,9 @@
"dropdown": {
"refresh": "Aktualisieren Sie die Versionen",
"import-version": "Importiere eine Version"
}
},
"recommended": "empfohlen",
"recommended-tooltip": "Am modbarsten Version"
},
"settings": {
"steam-and-oculus": {
@@ -154,13 +156,17 @@
"es-ES": "Español",
"de-DE": "Deutsch",
"ru-RU": "Русский",
"zh-CN": "简体中文",
"ja-JP": "日本語",
"translated": {
"en-EN": "Englisch, Vereinigtes Königreich",
"en-US": "Englisch, USA",
"fr-FR": "Französisch",
"es-ES": "Spanisch",
"de-DE": "Deutsch",
"ru-RU": "Russisch"
"ru-RU": "Russisch",
"zh-CN": "Vereinfachtes Chinesisch",
"ja-JP": "Japanisch"
}
}
},
@@ -523,10 +529,10 @@
"placeholder": "Geben Sie Ihr Passwort ein",
"max-length-warning": "Das Passwort überschreitet 64 Zeichen! Wenn das Passwort ungültig ist, versuchen Sie nur seine ersten 64 Zeichen einzugeben."
},
"qr":{
"qr": {
"label": "Oder mit einem QR-Code",
"note":{
"use-the":"Anmelden Sie sich über die ",
"note": {
"use-the": "Anmelden Sie sich über die ",
"steam-mobile-app": "Steam-Mobile-App",
"to-connect-with-qr": " per QR-Code an."
}
@@ -539,7 +545,7 @@
"submit": "Anmelden"
}
},
"steam-auth-approve":{
"steam-auth-approve": {
"title": "Warten auf Bestätigung",
"protected-by-mobile-auth": "Konto durch mobile Authentifizierung geschützt.",
"use-steam-app-to-approve": "Verwenden Sie die Steam Mobile-App, um die Verbindung zu bestätigen...",
@@ -676,15 +682,15 @@
"advanced-launch": "Erweiterte Start",
"valid-btn": "Verknüpfung erstellen"
},
"connect-to-meta":{
"connect-to-meta": {
"title": "Mit Meta verbinden",
"body":{
"body": {
"token-needed": "Dein Meta-Verbindungstoken wird benötigt, um Beat Saber herunterzuladen.",
"need-cookie-enabled": "Beim Einloggen in Meta wird ein Anmeldefenster geöffnet und du kannst dann den Anmeldevorgang beginnen. Bitte stelle sicher, dass Cookies akzeptiert werden, sonst könnten wir deinen Token zum Starten des Downloads nicht abrufen.",
"enter-token-manually": "Mein Anmelde-Token manuell eingeben",
"enter-token-manually-tooltip": "Dies ermöglicht es Ihnen, Ihren Anmelde-Token einzugeben, ohne sich über Meta anzumelden."
},
"stay":"Angemeldet bleiben",
"stay": "Angemeldet bleiben",
"connect-to-meta": "Mit Meta verbinden"
},
"original-version-backup-oculus": {
+15 -9
View File
@@ -108,7 +108,9 @@
"dropdown": {
"refresh": "Refresh versions",
"import-version": "Import a version"
}
},
"recommended": "recommended",
"recommended-tooltip": "Most modable version"
},
"settings": {
"steam-and-oculus": {
@@ -154,13 +156,17 @@
"es-ES": "Español",
"de-DE": "Deutsch",
"ru-RU": "Русский",
"zh-CN": "简体中文",
"ja-JP": "日本語",
"translated": {
"en-EN": "English, United Kingdom",
"en-US": "English, USA",
"fr-FR": "French",
"es-ES": "Spanish",
"de-DE": "German",
"ru-RU": "Russian"
"ru-RU": "Russian",
"zh-CN": "Chinese (Simplified)",
"ja-JP": "Japanese"
}
}
},
@@ -523,10 +529,10 @@
"placeholder": "Enter your password",
"max-length-warning": "The password exceeds 64 characters! If the password is invalid, try to enter only its first 64 characters."
},
"qr":{
"qr": {
"label": "Or with a QR code",
"note":{
"use-the":"Use the ",
"note": {
"use-the": "Use the ",
"steam-mobile-app": "Steam Mobile App",
"to-connect-with-qr": "to sign in via QR code."
}
@@ -539,7 +545,7 @@
"submit": "Sign in"
}
},
"steam-auth-approve":{
"steam-auth-approve": {
"title": "Waiting for confirmation",
"protected-by-mobile-auth": "Account protected by mobile authenticator.",
"use-steam-app-to-approve": "Use the Steam mobile app to confirm the connection...",
@@ -676,15 +682,15 @@
"advanced-launch": "Advanced launch",
"valid-btn": "Create the shortcut"
},
"connect-to-meta":{
"connect-to-meta": {
"title": "Connect to Meta",
"body":{
"body": {
"token-needed": "Your Meta connection token is required to download Beat Saber.",
"need-cookie-enabled": "By logging into Meta, a login window will open and you can then start the login process. Please ensure to accept cookies, otherwise, we might not be able to retrieve your token to start the download.",
"enter-token-manually": "Enter my login token manually",
"enter-token-manually-tooltip": "This will allow you to enter your login token without going through Meta login."
},
"stay":"Remember me",
"stay": "Remember me",
"connect-to-meta": "Connect to Meta"
},
"original-version-backup-oculus": {
+15 -9
View File
@@ -107,7 +107,9 @@
"dropdown": {
"refresh": "Actualizar las versiones",
"import-version": "Importar una versión"
}
},
"recommended": "recomendada",
"recommended-tooltip": "Versión más modable"
},
"settings": {
"steam-and-oculus": {
@@ -153,13 +155,17 @@
"es-ES": "Español",
"de-DE": "Deutsch",
"ru-RU": "Русский",
"zh-CN": "简体中文",
"ja-JP": "日本語",
"translated": {
"en-EN": "Inglés, Reino Unido",
"en-US": "Inglés, Estados Unidos",
"fr-FR": "Francés",
"es-ES": "Español",
"de-DE": "Alemán",
"ru-RU": "Ruso"
"ru-RU": "Ruso",
"zh-CN": "Chino simplificado",
"ja-JP": "Japonés"
}
}
},
@@ -522,10 +528,10 @@
"placeholder": "Introduce tu contraseña",
"max-length-warning": "¡La contraseña supera los 64 caracteres! Si la contraseña es inválida, intenta ingresar solo sus primeros 64 caracteres."
},
"qr":{
"qr": {
"label": "O con un código QR",
"note":{
"use-the":"Usa la ",
"note": {
"use-the": "Usa la ",
"steam-mobile-app": "aplicación Steam Mobile",
"to-connect-with-qr": "para conectarte con un código QR."
}
@@ -538,7 +544,7 @@
"submit": "Iniciar sesión"
}
},
"steam-auth-approve":{
"steam-auth-approve": {
"title": "Esperando confirmación",
"protected-by-mobile-auth": "Cuenta protegida por el autenticador móvil.",
"use-steam-app-to-approve": "Use la aplicación móvil de Steam para confirmar la conexión...",
@@ -675,15 +681,15 @@
"advanced-launch": "Lanzamiento avanzado",
"valid-btn": "Crear el atajo"
},
"connect-to-meta":{
"connect-to-meta": {
"title": "Conexión a Meta",
"body":{
"body": {
"token-needed": "Tu token de conexión a Meta es necesario para descargar Beat Saber.",
"need-cookie-enabled": "Al conectarte a Meta, se abrirá una ventana de inicio de sesión y entonces podrás empezar el proceso de conexión. Asegúrate de aceptar las cookies, de lo contrario, podríamos no poder recuperar tu token para iniciar la descarga.",
"enter-token-manually": "Ingresar mi token de inicio de sesión manualmente",
"enter-token-manually-tooltip": "Esto te permitirá ingresar tu token de inicio de sesión sin pasar por el inicio de sesión de Meta."
},
"stay":"Recuérdame",
"stay": "Recuérdame",
"connect-to-meta": "Conectarse a Meta"
},
"original-version-backup-oculus": {
+15 -9
View File
@@ -107,7 +107,9 @@
"dropdown": {
"refresh": "Actualiser les versions",
"import-version": "Importer une version"
}
},
"recommended": "recommandée",
"recommended-tooltip": "Version la plus modable"
},
"settings": {
"steam-and-oculus": {
@@ -153,13 +155,17 @@
"es-ES": "Español",
"de-DE": "Deutsch",
"ru-RU": "Русский",
"zh-CN": "简体中文",
"ja-JP": "日本語",
"translated": {
"en-EN": "Anglais, Royaume-Uni",
"en-US": "Anglais, États-Unis",
"fr-FR": "Français",
"es-ES": "Espagnol",
"de-DE": "Allemand",
"ru-RU": "Russe"
"ru-RU": "Russe",
"zh-CN": "Chinois simplifié",
"ja-JP": "Japonais"
}
}
},
@@ -519,10 +525,10 @@
"placeholder": "Entre ton mot de passe",
"max-length-warning": "Le mot de passe dépasse 64 caractères ! Si le mot de passe est invalide, tente d'entrer seulement ses 64 premiers caractères."
},
"qr":{
"qr": {
"label": "Ou avec un QR code",
"note":{
"use-the":"Utilisez l'",
"note": {
"use-the": "Utilisez l'",
"steam-mobile-app": "application mobile Steam",
"to-connect-with-qr": "pour vous connecter avec un QR code."
}
@@ -535,7 +541,7 @@
"submit": "Se connecter"
}
},
"steam-auth-approve":{
"steam-auth-approve": {
"title": "Attente de confirmation",
"protected-by-mobile-auth": "Compte protégé par l'authentificateur mobile.",
"use-steam-app-to-approve": "Utilisez l'application mobile Steam pour confirmer la connexion...",
@@ -672,15 +678,15 @@
"advanced-launch": "Lancement avancé",
"valid-btn": "Créer le raccourci"
},
"connect-to-meta":{
"connect-to-meta": {
"title": "Connexion à Meta",
"body":{
"body": {
"token-needed": "Votre token de connexion à Meta est nécessaire pour télécharger Beat Saber.",
"need-cookie-enabled": "En vous connectant à Meta, une fenêtre de connexion s'ouvrira et vous pourrez alors débuter le processus de connexion. Veillez à bien accepter les cookies sinon quoi, il se pourrait que l'on n'arrive pas à récupérer votre token pour démarrer le téléchargement.",
"enter-token-manually": "Entrer mon token de connexion manuellement",
"enter-token-manually-tooltip": "Cela vous permettra d'entrer votre token de connexion sans passer par la connexion Meta."
},
"stay":"Se souvenir de moi",
"stay": "Se souvenir de moi",
"connect-to-meta": "Se connecter à Meta"
},
"original-version-backup-oculus": {
+985
View File
@@ -0,0 +1,985 @@
{
"misc": {
"download": "ダウンロード",
"add": "追加 ",
"verify": "認証済み",
"launch": "起動",
"mods": "Mod",
"maps": "マップ",
"playlists": "プレイリスト",
"models": "モデル",
"cancel": "キャンセル",
"delete": "削除",
"accept": "同意する",
"refuse": "拒否する",
"apply": "適用",
"copy": "コピー",
"copied": "コピー済み!"
},
"nav-bar": {
"add-version": "バージョンを追加",
"settings": "設定",
"shared": {
"text": "共有",
"tooltip": "共有コンテンツ"
}
},
"pages": {
"shared-maps": {
"title": "共有マップ"
},
"version-viewer": {
"launch-mods": {
"oculus": "Oculusモード",
"oculus-description": "Steam経由でBeat Saberを使用している場合、SteamVRをバイパスしてOculusのVRコンポーザーを使用できるため、パフォーマンスが向上する可能性があります。これはOculusヘッドセットを使用するために必要なものではありません。",
"desktop": "FPFCモード",
"desktop-description": "ファーストパーソン・フライング・コントローラー・モードでは、WASDとマウスを使ってゲーム内のメニューを操作できます。ヘッドセットを装着する必要がないので、テストがより簡単になります!",
"debug": "デバックモード",
"debug-description": "IPAの出力ログウィンドウを有効にします。これはMODのデバッグコンソールを表示します。",
"advanced-launch": {
"button": "高度な起動",
"placeholder": "追加引数 例:--revert; --nowait"
}
},
"maps": {
"title": "共有マップ",
"search-bar": {
"search-placeholder": "マップを検索",
"filters-btn": "絞り込み",
"dropdown": {
"export-maps": "マップをエクスポート",
"delete-maps": "マップを削除"
}
},
"tabs": {
"maps": {
"actions": {
"add-maps": {
"text": "追加"
},
"link-maps": {
"tooltips": {
"link": "マップリンク",
"unlink": "マップリンク解除"
}
}
},
"empty-maps": {
"text": "マップがありません",
"button": "マップをダウンロードする"
}
}
}
},
"mods": {
"loading-mods": "Modを読み込み中...",
"no-internet": "インターネット接続がありません!",
"mods-not-available": "このバージョンで使用できるMODはまだありません。",
"buttons": {
"more-infos": "詳細情報",
"install-or-update": "インストールとアップデート"
},
"mods-grid": {
"header-bar": {
"name": "名前",
"installed": "インストール済み",
"latest": "最新",
"description": "說明",
"dropdown": {
"uninstall-all": "全てアンインストールする"
}
}
}
},
"dropdown": {
"open-folder": "フォルダーを開く",
"verify-files": "ファイルの検証",
"clone": "クローン",
"edit": "編集",
"uninstall": "アンインストール",
"create-shortcut": "ショートカットを作成",
"shared-folders": "共有フォルダー",
"restore-oculus-folder": "フォルダーの復元"
}
},
"available-versions": {
"title": "バージョンを選択",
"steam-release": "リリースページ",
"dropdown": {
"refresh": "バージョンの更新",
"import-version": "バージョンをインポート"
},
"recommended": "おすすめ",
"recommended-tooltip": "最もModがあるバージョン"
},
"settings": {
"steam-and-oculus": {
"title": "Steam & Oculus",
"description": "ログアウトすると、次のBeat Saberダウンロード時にアカウントを切り替えることができます。",
"logout": "ログアウト",
"download-platform": {
"title": "デフォルトプラットフォーム",
"desc": "Beat Saberのダウンロードに使用するデフォルトのプラットフォームを選択します。",
"always-ask": "常に尋ねる"
}
},
"appearance": {
"title": "外観",
"description": "BSManagerの2つのメインカラーを選択",
"reset": "リセット",
"sub-title": "テーマ",
"themes": {
"dark": "ダーク",
"light": "ライト",
"os": "コンピューターと同期する"
}
},
"installation-folder": {
"title": "インストールフォルダー",
"description": "BeatSaberのバージョンとその他の今後の機能を入れるフォルダを変更します。",
"choose-folder": "フォルダーを選択"
},
"additional-content": {
"title": "追加コンテンツ",
"description": "Beat Saberをカスタマイズできる追加コンテンツ!",
"deep-links": {
"sub-title": "OneClickインストール"
}
},
"language": {
"title": "言語",
"description": "言語を選択",
"languages": {
"en-EN": "English, UK",
"en-US": "English, US",
"fr-FR": "Français",
"es-ES": "Español",
"de-DE": "Deutsch",
"ru-RU": "Русский",
"zh-CN": "简体中文",
"ja-JP": "日本語",
"translated": {
"en-EN": "イギリス英語",
"en-US": "アメリカ英語",
"fr-FR": "フランス語",
"es-ES": "スペイン語",
"de-DE": "ドイツ語",
"ru-RU": "ロシア語",
"zh-CN": "簡体字中国",
"ja-JP": "日本語"
}
}
},
"patreon": {
"title": "BSManagerをサポートする 💖",
"description": "プロジェクトをサポートし、BSManagerの継続的な応援にご協力ください!",
"buttons": {
"support": "BSManagerをサポート 🥰",
"supporters": "サポーターの皆様 👀"
},
"view": {
"no-supporters": "サポーターはまだいません...",
"sponsors": "スポンサー",
"supporters": "サポーターの皆様"
}
},
"discord": {
"description": "BSManagerコミュニティーのソーシャルメディアに参加してください"
},
"contribution": {
"description": "BSManagerを改善するために、新機能を提案したり、バグを報告してください!",
"buttons": {
"request-features": "新機能を提案",
"report-bug": "バグを報告",
"open-logs": "ログを表示"
}
}
}
},
"notifications": {
"types": {
"error": "🚨 エラー",
"warning": "⚠️ 警告",
"success": "🎉 成功"
},
"common": {
"msg": {
"error-occurred": "エラーが発生しました"
}
},
"shared": {
"errors": {
"titles": {
"operation-running": "稼働中",
"no-internet": "インターネット接続がありません"
},
"msg": {
"operation-running": "現在の処理が終了するのを待ってから、もう一度試してください。",
"no-internet": "インターネット接続を確認し、もう一度お試しください。"
}
}
},
"bs-download": {
"success": {
"titles": {
"download-success": "ダウンロード完了",
"verification-finished": "検証完了"
}
},
"steam-download": {
"warnings": {
"msg": {
"ManifestChecksum": "以前にダウンロードしたマニフェストと新しいマニフェストが一致しないようです 🤔",
"ConnectionTimeout": "インターネット接続が不安定なようです 🥶",
"ConnectionLost": "接続が切られました。もう一度お試しください...",
"ConnectionError": "Steamに接続できません。もう一度お試しください...",
"Unknown": "何か変なことが起きたようだ。🤔 おそらく接続が不安定でしょう。"
}
},
"errors": {
"titles": {
"dotnet-required": ".NET 6が必要です!"
},
"msg": {
"401": "SteamがBeat Saberのダウンロードを許可してくれないようだ。😢",
"404": "Steamサーバーに接続できません。",
"Password": "パスワードが不正です。",
"InvalidCredentials": "無効なログイン認証情報、許可されていない接続、またはログイン試行回数が多すぎます。",
"NoManifest": "マニフェストは見つかりませんでした",
"DirectoryCreate": "必要なフォルダをインストールできません。",
"NotAvailableApp": "お持ちでないのにBeat Saberをダウンロードしようとしていませんか 🤣",
"DepotNotFound": "Beat Saberがダウンロードできませんでした 😥 もう一度お試しください 😕",
"NotCompleted": "ダウンロードができませんでした。(´・ω・`)",
"InvalidManifest": "Beat Saberがダウンロードできませんでした 😥 もう一度お試しください 😕",
"NoValidKey": "Beat Saberがダウンロードできませんでした 😥 もう一度お試しください 😕",
"NoManifestCode": "Beat Saberがダウンロードできませんでした 😥 もう一度お試しください 😕",
"Unknown": "不明なエラーが発生しました (´・ω・`)",
"NoServer": "Steamサーバーに接続できません。",
"NotAllowed": "どうやらBeat Saberのダウンロードは許可されていないようだ。🥱",
"ConnectionTimeout": "Steamに接続できません 😕",
"SteamLib": "このエラーが発生した場合は、ログを添えてGitHubにバグを報告してください。",
"ConnectionError": "10回試してもSteamに接続できませんでした 🤯",
"LicenceError": "ライセンスリストを取得できません。",
"RateLimitExceeded": "何度も試しているのでしばらくたって、もう一度お試しください。",
"TokenRejected": "ログイントークンが拒否されました 😕 もう一度お試しください。",
"AccessDenied": "Steamへのアクセスが拒否されました。",
"dotnet-required": "Beat Saberをダウンロードするには、.NET 6 Runtimeがインストールされている必要があります。下のボタンをクリックしてダウンロードしてください。"
},
"actions": {
"download-dotnet": ".NET 6をダウンロード"
}
}
},
"oculus-download": {
"errors": {
"msg": {
"DOWNLOAD_MANIFEST_FAILED": "このバージョンのマニフェストをダウンロードできません。ログイントークンが無効な可能性があります。",
"MANIFEST_FILE_NOT_FOUND": "このバージョンのマニフェストが見つかりません。",
"PARSE_MANIFEST_FILE_FAILED": "マニフェストの読み取り中にエラーが発生しました。",
"ALREADY_DOWNLOADING": "バージョンはすでにダウンロードされています。",
"UNABLE_TO_GET_MANIFEST": "ダウンロードに必要なマニフェストを取得できません。",
"VERIFY_INTEGRITY_FAILED": "ファイルの検証中にエラーが発生しました。",
"SOME_FILES_FAILED_TO_DOWNLOAD": "一部のファイルのダウンロードに失敗しました。",
"OCULUS_LOGIN_TIMED_OUT": "ログイントークンの取得に時間がかかりすぎました。",
"OCULUS_LOGIN_WINDOW_CLOSED_BY_USER": "メタ・ログイン・ウィンドウが閉じられた。",
"NO_META_AUTH_TOKEN": "ダウンロードに必要な Meta ログイン トークンを取得できません。",
"UNKNOWN_ERROR": "不明なエラーが発生しました。"
}
}
}
},
"bs-import-version": {
"success": {
"start-import": {
"title": "インポート中 👌",
"desc": "設定によっては、インポートに数分かかる場合があります。"
},
"imported": {
"title": "インポート完了 🎉"
}
},
"errors": {
"import-error": {
"desc": "選択したフォルダがBeat Saberのインストールフォルダであることを確認してください。"
}
}
},
"settings": {
"move-folder": {
"success": {
"titles": {
"transfer-started": "転送中",
"transfer-finished": "転送完了"
},
"descs": {
"transfer-started": "転送を開始しました。設定によっては数分かかる場合があります。"
}
},
"errors": {
"titles": {
"transfer-failed": "転送失敗 😕"
},
"descs": {
"COPY_TO_SUBPATH": "コピー先フォルダーは、コピー元フォルダーの下のフォルダーにはできません。",
"restore-linked-folders": "共有フォルダのリストア中にエラーが発生しました。バージョンページの「共有フォルダ」メニューから手動で復元できます。"
}
}
},
"steam": {
"success": {
"titles": {
"logout": "Steamから切断されました。"
}
}
},
"additional-content": {
"deep-link": {
"select-all": "すべて選択",
"activation": {
"success": {
"title": "OneClickが有効になりました!",
"description": "OneClickでのインストールが有効になりました。"
},
"error": {
"description": "OneClickのインストールを有効にできません。"
}
},
"deactivation": {
"success": {
"title": "OneClickが無効になりました!",
"description": "OneClickでのインストールは無効になります。"
},
"error": {
"description": "不明なエラーが発生しました。"
}
},
"check-all-enabled": {
"title": "OneClickが無効",
"description": "1つ以上のOneClickインストールが無効になっています。設定から有効にしてください。",
"actions": {
"settings": "設定に移動",
"not-remind": "二度と表示しないで"
}
}
}
}
},
"bs-launch": {
"success": {
"titles": {
"BS_LAUNCHING": "起動中...🚀",
"STEAM_LAUNCHING": "Steamの起動を確認しました!"
},
"msg": {
"BS_LAUNCHING": "ウォームアップを忘れずに 😉",
"STEAM_LAUNCHING": "Beat SaberはSteamの起動後に自動的に起動します。"
}
},
"errors": {
"titles": {
"UNKNOWN_ERROR": "起動不可",
"STEAM_NOT_RUNNING": "Steamが起動していません",
"OCULUS_NOT_RUNNING": "Oculusが起動していません",
"BS_ALREADY_RUNNING": "Beat Saberはすでに起動しています",
"EXE_NOT_FINDED": "ファイルが見つかりません",
"EXIT": "緊急停止",
"OCULUS_LIB_NOT_FOUND": "Oculusライブラリが見つかりません"
},
"msg": {
"UNKNOWN_ERROR": "不明なエラーが発生しました。",
"STEAM_NOT_RUNNING": "BeatSaberを起動するには、Steamが起動している必要があります。",
"OCULUS_NOT_RUNNING": "BeatSaberを起動するには、Oculusが起動している必要があります。",
"BS_ALREADY_RUNNING": "再度起動する前にBeatSaberを閉じてください。",
"EXE_NOT_FINDED": "いくつかのファイルが見つからないようです。",
"EXIT": "BeatSaberが緊急停止したため、ファイルをチェックします。",
"OCULUS_LIB_NOT_FOUND": "Oculusアプリケーションが正しくインストールしていることと、Oculusライブラリが正しく定義されていることを確認してください。"
},
"actions": {
"STEAM_NOT_RUNNING": "Steamを起動"
}
}
},
"steam": {
"steam-launching": {
"title": "Steamを起動!",
"description": "Beat SaberはSteamの起動後に自動的に起動します。"
}
},
"custom-version": {
"errors": {
"titles": {
"CantEditSteam": "編集不可",
"CantRename": "改名不可能",
"VersionAlreadExist": "このバージョンは既に存在しています!",
"CantClone": "クローン作成不可"
},
"msg": {
"CantEditSteam": "Steam版は編集できませんがクローンを作ることは可能です。"
}
},
"success": {
"titles": {
"CloningFinished": "クローンが完了しました 🎉"
}
}
},
"mods": {
"install-mods": {
"titles": {
"success": "Modをインストールしました 🎉",
"warning": "Modをインストールしました 🤔"
},
"msg": {
"success": "すべてのMODがインストールした。",
"warning": "1つ以上のMODがインストールできませんでした。",
"errors": {
"no-mods": "インストールするMODがありません。",
"cannot-install-bsipa": "BSIPAをインストールすることが出来ませんでした 😨"
}
}
},
"uninstall-mod": {
"titles": {
"success": "Modのアンインストール完了 🎉"
},
"msg": {
"errors": {
"no-mods": "Modはインストールされていません 😑"
}
}
},
"uninstall-all-mods": {
"titles": {
"success": "Modのアンインストール完了 🎉"
},
"msg": {
"success": "すべてのModをアンインストールしました。",
"errors": {
"no-mods": "このバージョンのModはインストールされていません 😑"
}
}
}
},
"maps": {
"one-click-install": {
"success": "マップのインストール完了",
"error": "マップのインストール中にエラーが発生しました"
}
},
"playlists": {
"one-click-install": {
"success": "プレイリストのインストール完了",
"error": "プレイリストのインストール中にエラーが発生しました。"
}
},
"models": {
"one-click-install": {
"success": "モデルのインストール完了",
"error": "モデルのインストール中にエラーが発生しました。"
}
},
"shared-folder": {
"info": {
"userdata-backup-created": {
"title": "バックアップを作成しました",
"msg": "'UserData'フォルダを共有するとエラーが発生する可能性があります。問題が発生した場合は、フォルダをリンク解除してバックアップを復元してください。"
}
}
},
"create-launch-shortcut": {
"success": {
"title": "ショートカットを作成しました",
"msg": "デスクトップにショートカットを作成されました。"
},
"error": {
"msg": "ショートカットの作成中にエラーが発生しました。"
}
}
},
"modals": {
"misc": {
"remember-my-choice": "この選択を記憶する"
},
"choose-store": {
"title": "どのプラットフォーム?",
"body": "Beat Saberをダウンロードするプラットフォームを選択してください。",
"set-in-settings": "設定からデフォルトのプラットフォームを設定する"
},
"guard": {
"title": "Steamガード",
"inputs": {
"guard-code": {
"label": "ガードコード",
"placeholder": "ガードコードを入力"
}
},
"buttons": {
"submit": "ログイン"
}
},
"steam-login": {
"title": "Steamにログイン",
"inputs": {
"username": {
"label": "アカウント名でサインイン",
"placeholder": "アカウント名を入力"
},
"password": {
"label": "パスワード",
"placeholder": "パスワードを入力",
"max-length-warning": "パスワードが64文字を超えています!最初の64文字だけを入力してみてください。"
},
"qr": {
"label": "もしくはQRコード",
"note": {
"use-the": "",
"steam-mobile-app": "Steam Mobile App",
"to-connect-with-qr": "でQRコードからサインインする。"
}
},
"stay": "記憶する"
},
"why-credentials": "なぜアカウントが必要なのですか?",
"need-help-to-connect": "自分のアカウントにアクセスする方法を教えてほしい!",
"buttons": {
"submit": "サインイン"
}
},
"steam-auth-approve": {
"title": "確認待ち",
"protected-by-mobile-auth": "モバイル認証で保護されたアカウント。",
"use-steam-app-to-approve": "Steamモバイルアプリを使用して、接続を確認してください...",
"not-access-to-steam-app": "Steamモバイルアプリにアクセスできません。"
},
"steam-credentials": {
"title": "Steamアカウント情報",
"p-1": "なぜなら、Steamはダウンロードを許可するために、あなたがゲームを支払ったことを確認する必要があるからです。アカウント情報は保存されず、直接DepotDownloaderに渡されます。アカウント情報を入力したくない場合は、このチュートリアルに従うことができます:",
"p-2": "右上の歯車アイコンをクリックし、\"バージョンをインポート\"を選択し、beat saberがダウンロードされたフォルダを選択します。"
},
"bs-import-version": {
"title": "バージョンをインポート",
"description": "BSManagerで使用するBeat Saberのバージョンをインポートします。選択したBeat SaberのインストールフォルダをBSManager versionsフォルダにコピーします。",
"oculus-version": "Oculusバージョン",
"oculus-version-tooltip": "Oculusバージョンかどうかを確認する",
"buttons": {
"submit": "バージョンをインポートする"
}
},
"bs-uninstall": {
"title": "アンインストール",
"description": "本当にバージョン{version}のBeat Saberをアンインストールしますか?プレイするには再度ダウンロードする必要があります。",
"buttons": {
"submit": "アンインストール"
}
},
"install-folder": {
"title": "インストールフォルダー",
"description": "デフォルトのインストールフォルダを変更すると、インストールされているすべてのデータが新しいフォルダに移動します。",
"buttons": {
"submit": "フォルダーを選択"
}
},
"edit-version": {
"title": "名前を変更",
"buttons": {
"submit": "保存"
}
},
"clone-version": {
"title": "バージョンをクローン",
"description": "バージョンのクローンを作成することで、ビートセイバーの追加コンテンツを2つのバージョンに分けることができます。",
"inputs": {
"name": {
"label": "名前",
"placeholder": "バージョンの名前"
},
"color": {
"label": "カラー"
}
},
"buttons": {
"submit": "クローン"
}
},
"uninstall-mod": {
"title": "アンインストール",
"description": "本当にこの{mod}をアンインストールしますか? インストールされている他のMODの誤作動を引き起こす可能性があります。",
"description-bsipa": "本当にBSIPAをアンインストールしますか?その後、すべてのインストールされたMODは動作しなくなります。"
},
"uninstall-all-mods": {
"title": "Modのアンインストール",
"description": "バージョン{version}のMODをすべてアンインストールしてもよろしいですか?この操作は元に戻せません。"
},
"maps-actions": {
"delete-maps": {
"title": {
"single": "このマップを削除しますか?",
"multiple": "いくつかのマップを削除しますか?"
},
"desc": {
"single": "本当にマップ{name}を削除しますか?",
"multiple": "本当に{nb}個のマップを削除しますか?"
},
"info": {
"desc": {
"single": "このマップは共有マップの一部です。",
"multiple": "これらのマップは共有マップの一部です。"
},
"title": {
"single": "このマップは、共有マップを使用しているバージョンからも削除されます。",
"multiple": "これらのマップは、共有マップを使用しているバージョンからも削除されます。"
}
}
},
"link-maps": {
"title": "マップをリンク",
"desc": "マップをリンクすると、この機能が有効になっているすべてのバージョン間でマップを共有できます。リンクされると、このバージョンは共有マップの恩恵を受けることができます。",
"info": "マップの追加と削除も共有されます。",
"keep-maps": {
"label": "マップを保持",
"title": "マップを保持すると現在のバージョンのすべてのマップを共有マップフォルダーにコピーします。有効していない場合はこのバージョンのマップは保持されず、失われます。"
},
"valid-btn": "マップをリンク"
},
"unlink-maps": {
"title": "マップのリンクを解除",
"desc": "マップのリンクを解除すると、このバージョンでは共有マップを使用できなくなります。",
"keep-maps": {
"label": "マップを保持",
"title": "マップを保持は、リンクを解除した後、共有フォルダから現在のバージョンにすべてのマップをコピーします。これを無効をしても共有マップは失われません。"
},
"valid-btn": "マップのリンクを解除"
}
},
"download-maps": {
"search-btn": "検索 ",
"loading-maps": "マップを読込中...",
"no-maps-found": "マップが見つかりませんでした",
"no-internet": "インターネット接続無し"
},
"mods-disclaimer": {
"title": "免責事項",
"p-1": "Modの使用を選択することで、あなたは以下のことを同意することになります:",
"li-1": "バニラゲームには存在しない問題が発生するかもしれません。バグ、クラッシュ、ラグの99.9%はModによるものです。",
"li-2": "MODはアップデートによって壊されることがありますが、それは普通のことです。MOD製作者は実生活を持つボランティアなので、そのようなことが起きても忍耐強く、敬意を払ってください。",
"li-3": "Beat Gamesは意図的にMODを壊そうとしているわけではありません。彼らはコードベースに取り組みたいと願っており、そのためにMODが壊れることはありますが、MODを殺そうとしているわけではありません。",
"p-2": "MODに関する問題でゲーム開発者を攻撃したり、その逆をしたりしないでください。MOD開発者とゲーム開発者は別のグループです。"
},
"shared-folders": {
"title": "共有フォルダー",
"description": "Beat Saberのフォルダをリンクして、他のバージョンの共有フォルダとコンテンツを同期します。なお、コンテンツを削除したら共有済みのバージョンも同様に削除されます。",
"buttons": {
"add-folder": "フォルダーを追加",
"link-folder": "フォルダーをリンク",
"unlink-folder": "フォルダーのリンクを解除",
"link-all": "すべてリンク"
}
},
"create-launch-shortcut": {
"title": "ショートカットを作成",
"desc": "ショートカットを作成すると、BSManagerを起動せずに、直接Beat Saberを起動できます。",
"launch-options": "起動オプション",
"advanced-launch": "高度な起動",
"valid-btn": "ショートカットを作成"
},
"connect-to-meta": {
"title": "Metaに接続する",
"body": {
"token-needed": "Beat SaberのダウンロードにはMetaのログイントークンが必要です。",
"need-cookie-enabled": "Metaにログインするとログインウィンドウが開き、ログインプロセスを開始することができます。Cookieを受け入れるようにしてください。そうしないとダウンロードを開始するためのトークンを取得できない場合があります。",
"enter-token-manually": "ログイントークンを手動で入力する",
"enter-token-manually-tooltip": "これにより、Metaログインを経由せずにログイントークンを入力できるようになります。"
},
"stay": "記憶する",
"connect-to-meta": "Metaに接続する"
},
"original-version-backup-oculus": {
"title": "注意",
"body": {
"must-be-installed-once": "少なくとも一度はOculus StoreからBeat Saberをインストールしている必要があります。そうしないとBeat Saberは起動後に自動的に終了する可能性があります。",
"need-backup": "このバージョンを起動するには、OculusライブラリにあるBeat Saberインストールフォルダの名前を変更します。",
"can-restore-later": "必要であれば、BSManagerから元のOculusバージョンのオプションに行き、'フォルダを復元'をクリックして復元することができます。",
"tips-launch-oculus": "ヒント: 元のバージョンが復元されない限り、Oculusから直接このバージョンを起動することができます。"
},
"not-remind-me": "二度と表示しないでください",
"understood": "分かった"
},
"enter-meta-token": {
"title": "Metaトークン",
"body": {
"need-token": "Beat Saberをダウンロードするには、Metaのログイントークンが必要です。",
"how-obtain-token": "Metaトークンはどうやって入手すればいいですか?",
"input-label": "Metaトークン",
"token-is-invalid": "トークンが無効です。"
},
"valid-btn": "検証"
}
},
"maps": {
"map-filter-panel": {
"duration": "尺",
"tags": "タグ",
"specificities": "一般",
"requirements": "要Mod"
},
"map-types": {
"accuracy": "正確",
"balanced": "バランス",
"challenge": "挑戦",
"dancestyle": "ダンス",
"fitness": "フットネス",
"speed": "スピード",
"tech": "技術的"
},
"map-styles": {
"dance": "ダンス",
"swing": "スウィング",
"nightcore": "ナイトコア",
"folk": "フォーク",
"family": "ファミリー",
"ambient": "アンビエント",
"funk": "ファンク",
"jazz": "ジャズ",
"soul": "ソウル",
"speedcore": "スピードコア ",
"punk": "パンク",
"rb": "r&b",
"holiday": "休日",
"vocaloid": "ボーカロイド",
"jrock": "j-rock",
"trance": "トランス",
"drumbass": "ドラムンベース",
"comedy": "コメディ",
"instrumental": "器楽",
"hardcore": "ハードコア",
"kpop": "k-pop",
"indie": "インディー",
"techno": "テクノ",
"house": "家",
"game": "ビデオゲーム",
"film": "映画音楽",
"alt": "オルタナティヴ",
"dubstep": "ダブステップ",
"metal": "メタル",
"anime": "アニメ",
"hiphop": "ヒップポップ",
"jpop": "j-pop",
"rock": "ロック",
"pop": "ポップ",
"electronic": "エレクトロニック",
"classical-orchestral": "Classical & Orchestral"
},
"map-specificities": {
"automapper": "AI",
"ranked": "ランク入賞",
"curated": "厳選済み",
"verified": "認証済み",
"fullSpread": "フルスプレッド"
},
"difficulties": {
"Easy": "easy",
"Normal": "normal",
"Hard": "hard",
"Expert": "expert",
"ExpertPlus": "expert+"
},
"map-item": {
"by": "By {songAutor}",
"mapped-by": "作成者 "
}
},
"models": {
"types": {
"singular": {
"avatar": "アバター",
"saber": "セイバー",
"platform": "プラットフォーム",
"bloq": "ノーツ"
},
"plural": {
"avatar": "アバター",
"saber": "セイバー",
"platform": "プラットフォーム",
"bloq": "ノーツ"
}
},
"sorts": {
"name": "名前",
"date": "最近",
"author": "作成者"
},
"panel": {
"actions": {
"search": "モデルを検索",
"drop-down": {
"delete": "モデルを削除",
"export": "モデルをエクスポート"
},
"link-models": "モデルをリンク",
"unlink-models": "モデルのリンクを解除"
},
"grid": {
"loading": "モデルの読み込み中...",
"no-models": "モデルがありません",
"download-models": "モデルをダウンロードする"
}
},
"modals": {
"delete-model": {
"title": "モデルを削除",
"desc": "本当にモデル {modelName} を削除しますか?",
"linked-annotation": "このモデルはすべてのリンク済みのバージョンから削除されます。"
},
"delete-models": {
"title": "モデルを削除",
"desc": "本当に{nb}個のモデルを削除しますか?",
"linked-annotation": "このモデルはすべてのリンク済みのバージョンから削除されます。"
},
"download-models": {
"search-btn": "検索 ",
"search-placeholder": "モデルを検索する",
"search-tips": {
"header": {
"tag": "タグ",
"desc": "說明"
},
"author-desc": "指定した作者のモデルのみを表示",
"hash-desc": "指定したハッシュを持つモデルのみを表示",
"tag-desc": "指定したタグを持つモデルのみを表示",
"name-desc": "指定した名前のモデルのみを表示",
"discordid-desc": "指定したDiscordユーザーからのモデルのみを表示",
"status-desc": "指定されたステータスのモデルのみを表示 (プロフィールのみ、作者のみ)"
},
"no-models": "モデルは見つかりませんでした。",
"no-internet": "インターネットに接続できませんでした。",
"error-occured": "エラーが発生しました。もう一度お試しください."
},
"link-models": {
"avatar": {
"title": "アバターをリンク",
"desc": "アバターをリンクすると、この機能が有効になっているすべてのバージョン間でアバターを共有できます。また、リンクすることでこのバージョンは共有アバターの恩恵を受けることができます。",
"info": "アバターの追加と削除も共有されます",
"keep-models": {
"label": "アバターを保持",
"title": "アバターを保持すると、現在のバージョンからすべてのアバターが共有アバターフォルダーにコピーされます。有効していない場合はこのバージョンのアバターは保持されず、それらは失われます。"
},
"valid-btn": "アバターをリンク"
},
"saber": {
"title": "セーバーをリンク",
"desc": "セーバーをリンクすると、この機能が有効になっているすべてのバージョン間でセーバーを共有できます。また、リンクすることでこのバージョンは共有セーバーの恩恵を受けることができます。",
"info": "セーバーの追加と削除も共有されます",
"keep-models": {
"label": "セーバーを保持",
"title": "セーバーを保持すると、現在のバージョンからすべてのセーバーが共有vフォルダーにコピーされます。有効していない場合はこのバージョンのセーバーは保持されず、それらは失われます。"
},
"valid-btn": "セーバーをリンク"
},
"platform": {
"title": "プラットフォームをリンク",
"desc": "プラットフォームをリンクすると、この機能が有効になっているすべてのバージョン間でプラットフォームを共有できます。また、リンクすることでこのバージョンは共有プラットフォームの恩恵を受けることができます。",
"info": "プラットフォームの追加と削除も共有されます",
"keep-models": {
"label": "プラットフォームを保持",
"title": "プラットフォームを保持すると、現在のバージョンからすべてのプラットフォームが共有プラットフォームフォルダーにコピーされます。有効していない場合はこのバージョンのプラットフォームは保持されず、それらは失われます。"
},
"valid-btn": "プラットフォームをリンク"
},
"bloq": {
"title": "ノーツをリンク",
"desc": "ノーツをリンクすると、この機能が有効になっているすべてのバージョン間でノーツを共有できます。また、リンクすることでこのバージョンは共有ノーツの恩恵を受けることができます。",
"info": "ノーツの追加と削除も共有されます",
"keep-models": {
"label": "ノーツを保持",
"title": "ノーツを保持すると、現在のバージョンからすべてのノーツが共有ノーツフォルダーにコピーされます。有効していない場合はこのバージョンのノーツは保持されず、それらは失われます。"
},
"valid-btn": "ノーツをリンク"
}
},
"unlink-models": {
"avatar": {
"title": "アバターのリンクを解除",
"desc": "アバターのリンクを解除すると、このバージョンでは共有アバターが使用できなくなります。",
"keep-models": {
"label": "アバターを保持する",
"title": "アバターを保持すると、リンクを解除した後、共有フォルダにあるすべてのアバターが現在のバージョンにコピーされます。これが無効にしても共有アバターは失われません。"
},
"valid-btn": "アバターのリンクを解除"
},
"saber": {
"title": "セーバーのリンクを解除",
"desc": "セーバーのリンクを解除すると、このバージョンでは共有セーバーが使用できなくなります。",
"keep-models": {
"label": "セーバーを保持する",
"title": "セーバーを保持すると、リンクを解除した後、共有フォルダにあるすべてのセーバーが現在のバージョンにコピーされます。これが無効にしても共有セーバーは失われません。"
},
"valid-btn": "セーバーのリンクを解除"
},
"platform": {
"title": "プラットフォームのリンクを解除",
"desc": "プラットフォームのリンクを解除すると、このバージョンでは共有プラットフォームが使用できなくなります。",
"keep-models": {
"label": "プラットフォームを保持する",
"title": "プラットフォームを保持すると、リンクを解除した後、共有フォルダにあるすべてのプラットフォームが現在のバージョンにコピーされます。これが無効にしても共有プラットフォームは失われません。"
},
"valid-btn": "プラットフォームのリンクを解除"
},
"bloq": {
"title": "ノーツのリンクを解除",
"desc": "ノーツのリンクを解除すると、このバージョンでは共有ノーツが使用できなくなります。",
"keep-models": {
"label": "ノーツを保持する",
"title": "ノーツを保持すると、リンクを解除した後、共有フォルダにあるすべてのノーツが現在のバージョンにコピーされます。これが無効にしても共有ノーツは失われません。"
},
"valid-btn": "ノーツのリンクを解除"
}
}
},
"notifications": {
"prevent-for-mods": {
"title": "Modが必要です!",
"desc": "Beat Saberでモデルを使用するためには必要なMODをインストールし、確認してください",
"go-to-mods": "Modインストーラーに移動",
"not-remind": "二度と表示しないで"
},
"prevent-for-models-breaks": {
"title": "モデルが壊れています!",
"desc": "Beat Saberエンジンのアップデートしたため、このバージョンではモデルが機能しなくなりました。"
},
"export-success": {
"title": "エクスポート完了🎉"
}
}
},
"beat-saver": {
"maps-sorts": {
"Latest": "最新",
"Relevance": "関連性",
"Rating": "レーティング",
"Curated": "厳選"
}
},
"auto-update": {
"checking": "アップデートを確認中",
"downloading": "アップデート中"
},
"bs-shortcut-launch": {
"beat-saber-launching": "",
"launching": "起動中",
"open-bsmanager": "BSManagerを開く",
"status-text": {
"init": "初期化中...",
"success": {
"BS_LAUNCHING": "Beat Saberを起動中...",
"STEAM_LAUNCHING": "Steamを起動中...",
"STEAM_LAUNCHED": "Steamの起動が完了しました!",
"UNABLE_TO_LAUNCH_STEAM": "Steamを起動できませんでした、Beat Saberを強制的に起動します..."
}
}
},
"dateformat": {
"dayNames": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
"monthNames": ["Jan", "Feb", "Mar", "Apr", "May", "June", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
"timeNames": ["a", "p", "am", "pm", "A", "P", "AM", "PM"]
}
}
+15 -9
View File
@@ -108,7 +108,9 @@
"dropdown": {
"refresh": "Обновить версии",
"import-version": "Импорт версии"
}
},
"recommended": "рекомендуемая",
"recommended-tooltip": "самая модифицируемая версия"
},
"settings": {
"steam-and-oculus": {
@@ -154,13 +156,17 @@
"es-ES": "Español",
"de-DE": "Deutsch",
"ru-RU": "Русский",
"zh-CN": "简体中文",
"ja-JP": "日本語",
"translated": {
"en-EN": "Английский, Великобритания",
"en-US": "Английский, США",
"fr-FR": "Французский",
"es-ES": "Испанский",
"de-DE": "Немецкий",
"ru-RU": "Русский"
"ru-RU": "Русский",
"zh-CN": "Китайский (упрощенный)",
"ja-JP": "Японский"
}
}
},
@@ -523,10 +529,10 @@
"placeholder": "Введите ваш пароль",
"max-length-warning": "Пароль превышает 64 символа! Если пароль недействителен, попробуйте ввести только его первые 64 символа."
},
"qr":{
"qr": {
"label": "Или с QR-кодом",
"note":{
"use-the":"Используйте ",
"note": {
"use-the": "Используйте ",
"steam-mobile-app": "мобильное приложение Steam",
"to-connect-with-qr": "для входа с QR-кодом."
}
@@ -539,7 +545,7 @@
"submit": "Войти"
}
},
"steam-auth-approve":{
"steam-auth-approve": {
"title": "Ожидание подтверждения",
"protected-by-mobile-auth": "Учетная запись защищена мобильным аутентификатором.",
"use-steam-app-to-approve": "Используйте мобильное приложение Steam для подтверждения подключения...",
@@ -676,15 +682,15 @@
"advanced-launch": "Расширенный запуск",
"valid-btn": "Создать ярлык"
},
"connect-to-meta":{
"connect-to-meta": {
"title": "Подключение к Meta",
"body":{
"body": {
"token-needed": "Для скачивания Beat Saber необходим ваш токен подключения к Meta.",
"need-cookie-enabled": "При входе в Meta откроется окно входа, и вы сможете начать процесс входа. Пожалуйста, убедитесь, что вы приняли cookies, иначе мы можем не суметь получить ваш токен для начала загрузки.",
"enter-token-manually": "Ввести мой токен входа вручную",
"enter-token-manually-tooltip": "Это позволит вам ввести ваш токен входа без прохождения через вход в Meta."
},
"stay":"Запомнить меня",
"stay": "Запомнить меня",
"connect-to-meta": "Подключиться к Meta"
},
"original-version-backup-oculus": {
+986
View File
@@ -0,0 +1,986 @@
{
"misc": {
"download": "下载",
"add": "添加",
"verify": "验证",
"launch": "启动",
"mods": "Mod",
"maps": "谱面",
"playlists": "歌单",
"models": "模型",
"cancel": "取消",
"delete": "删除",
"accept": "接受",
"refuse": "拒绝",
"apply": "应用",
"copy": "复制",
"copied": "已复制!"
},
"nav-bar": {
"add-version": "添加版本",
"settings": "设置",
"shared": {
"text": "共享",
"tooltip": "共享内容"
}
},
"pages": {
"shared-maps": {
"title": "共享谱面"
},
"version-viewer": {
"launch-mods": {
"oculus": "Oculus 模式",
"oculus-description": "若使用 Steam 版 BeatSaber,这允许你在绕过 SteamVR 的同时使用 Oculus 的 VR comsposer,可能会有性能提升。(不只是 Oculus 头显)",
"desktop": "FPFC 模式",
"desktop-description": "第一人称飞控模式允许你使用键盘 WASD 和鼠标在游戏中进行导航。你无需带上头显即可进行测试!",
"debug": "Debug 模式",
"debug-description": "为 IPA 启用输出日志窗口。 会显示所用 Mod 的 debug 输出",
"advanced-launch": {
"button": "高级启动",
"placeholder": "额外启动参数,例如: --revert; --nowait"
}
},
"maps": {
"title": "Shared maps",
"search-bar": {
"search-placeholder": "谱面搜索",
"filters-btn": "筛选",
"dropdown": {
"export-maps": "导出谱面",
"delete-maps": "删除谱面"
}
},
"tabs": {
"maps": {
"actions": {
"add-maps": {
"text": "添加"
},
"link-maps": {
"tooltips": {
"link": "Link maps",
"unlink": "Unlink maps"
}
}
},
"empty-maps": {
"text": "无谱面",
"button": "下载谱面"
}
}
}
},
"mods": {
"loading-mods": "Mod 加载中...",
"no-internet": "无网络",
"mods-not-available": "该版本 BeatSaber 暂无可用 Mod",
"buttons": {
"more-infos": "更多信息",
"install-or-update": "安装或更新"
},
"mods-grid": {
"header-bar": {
"name": "名称",
"installed": "已安装",
"latest": "最新",
"description": "描述",
"dropdown": {
"uninstall-all": "全部卸载"
}
}
}
},
"dropdown": {
"open-folder": "打开文件夹",
"verify-files": "验证文件",
"clone": "Clone",
"edit": "编辑",
"uninstall": "卸载",
"create-shortcut": "创建快捷方式",
"shared-folders": "Shared Folders",
"restore-oculus-folder": "Restore the folder"
}
},
"available-versions": {
"title": "选择版本",
"steam-release": "发布页面",
"dropdown": {
"refresh": "刷新版本",
"import-version": "导入版本"
},
"recommended": "推荐",
"recommended-tooltip": "多 Mod 版本"
},
"settings": {
"steam-and-oculus": {
"title": "Steam & Oculus",
"description": "登出后,您可以在下一次下载 Beat Saber 时切换帐户。",
"logout": "登出",
"download-platform": {
"title": ",默认平台",
"desc": "选择要下载 BeatSaber 的默认平台。",
"always-ask": "总是询问"
}
},
"appearance": {
"title": "外观",
"description": "选择 BSManager 的两种主题色",
"reset": "重置",
"sub-title": "主题",
"themes": {
"dark": "Dark",
"light": "Light",
"os": "与系统保持同步"
}
},
"installation-folder": {
"title": "安装文件夹",
"description": "为 BeatSaber 不同版本及未来其他特性修改默认文件夹",
"choose-folder": "选择文件夹"
},
"additional-content": {
"title": "附加内容",
"description": "允许你自定义 BeatSaber 的附加内容!",
"deep-links": {
"sub-title": "一键安装"
}
},
"language": {
"title": "语言",
"description": "选择语言",
"languages": {
"en-EN": "English, UK",
"en-US": "English, US",
"fr-FR": "Français",
"es-ES": "Español",
"de-DE": "Deutsch",
"ru-RU": "Русский",
"zh-CN": "简体中文",
"ja-JP": "日本語",
"translated": {
"en-EN": "英式英语",
"en-US": "美式英语",
"fr-FR": "法语",
"es-ES": "西班牙语",
"de-DE": "德语",
"ru-RU": "俄语",
"zh-CN": "简体中文",
"ja-JP": "日语"
}
}
},
"patreon": {
"title": "支持 BSManager 💖",
"description": "支持该项目并帮助我们持续改进 BSManager。",
"buttons": {
"support": "支持 BSManager 🥰",
"supporters": "支持者 👀"
},
"view": {
"no-supporters": "暂无支持者",
"sponsors": "赞助者",
"supporters": "支持者"
}
},
"discord": {
"description": "在社交媒体上关注我们,加入 BSManager 社区!"
},
"contribution": {
"description": "建议新功能或报告错误以帮助改进 BSManager",
"buttons": {
"request-features": "请求新功能",
"report-bug": "报告 bug",
"open-logs": "打开日志"
}
}
}
},
"notifications": {
"types": {
"error": "🚨 错误",
"warning": "⚠️ 警告",
"success": "🎉 成功"
},
"common": {
"msg": {
"error-occurred": "发生了一个错误"
}
},
"shared": {
"errors": {
"titles": {
"operation-running": "操作进行中",
"no-internet": "无网络"
},
"msg": {
"operation-running": "等待当前操作完成,然后重试。",
"no-internet": "检查你的连接并重试。"
}
}
},
"bs-download": {
"success": {
"titles": {
"download-success": "下载完成",
"verification-finished": "验证完成"
}
},
"steam-download": {
"warnings": {
"msg": {
"ManifestChecksum": "之前下载的清单与新的清单不匹配 🤔",
"ConnectionTimeout": "你的网络连接似乎不稳定 🥶",
"ConnectionLost": "连接已丢失,请重试...",
"ConnectionError": "无法连接到 Steam,请重试...",
"Unknown": "发生了奇怪的事情 🤔 你的连接可能不稳定。"
}
},
"errors": {
"titles": {
"dotnet-required": "需要 .NET 6"
},
"msg": {
"401": "Steam 似乎不想让我们下载 Beat Saber😢",
"404": "无法联系 Steam 服务器。",
"Password": "密码无效",
"InvalidCredentials": "登录凭据无效、连接未经批准或登录尝试次数过多。",
"NoManifest": "未找到清单",
"DirectoryCreate": "无法安装必要的文件夹。",
"NotAvailableApp": "您是否在没有安装 BeatSaber 的情况下尝试下载?🤣",
"DepotNotFound": "无法下载 Beat Saber 😥 稍后重试 😕",
"NotCompleted": "下载无法完成 ¯\\_(ツ)_/¯",
"InvalidManifest": "无法下载 Beat Saber 😥 稍后重试 😕",
"NoValidKey": "无法下载 Beat Saber 😥 稍后重试 😕",
"NoManifestCode": "无法下载 Beat Saber 😥 稍后重试 😕",
"Unknown": "发生了一个错误 ¯\\_(ツ)_/¯",
"NoServer": "U无法联系 Steam 服务器。",
"NotAllowed": "显然你没有下载 Beat Saber 的许可 🥱",
"ConnectionTimeout": "无法连接到 Steam 😕",
"SteamLib": "如果你遇到此错误,请在 GitHub 上报告该错误并附上日志。",
"ConnectionError": "尝试 10 次后仍无法连接到 Steam🤯",
"LicenceError": "无法获取许可证列表。",
"RateLimitExceeded": "你已经尝试了太多次,请稍等片刻,稍后再试。",
"TokenRejected": "你的登录令牌已被拒绝 😕 请重试。",
"AccessDenied": "访问 Steam 被拒绝。",
"dotnet-required": "必须安装 .NET 6 Runtime 才能下载 Beat Saber 版本。单击下面的按钮下载它。"
},
"actions": {
"download-dotnet": "下载 .NET 6"
}
}
},
"oculus-download": {
"errors": {
"msg": {
"DOWNLOAD_MANIFEST_FAILED": "无法下载此版本的清单;你的登录令牌可能无效。",
"MANIFEST_FILE_NOT_FOUND": "找不到此版本的清单。",
"PARSE_MANIFEST_FILE_FAILED": "读取清单时发生错误。",
"ALREADY_DOWNLOADING": "已经有一个版本在下载中。",
"UNABLE_TO_GET_MANIFEST": "无法获取下载所需的清单。",
"VERIFY_INTEGRITY_FAILED": "文件验证过程中发生错误。",
"SOME_FILES_FAILED_TO_DOWNLOAD": "一些文件下载失败。",
"OCULUS_LOGIN_TIMED_OUT": "获取登录令牌用时过长。",
"OCULUS_LOGIN_WINDOW_CLOSED_BY_USER": "Meta 登录窗口被关闭。",
"NO_META_AUTH_TOKEN": "无法获取下载所需的 Meta 登录令牌。",
"UNKNOWN_ERROR": "发生未知错误。"
}
}
}
},
"bs-import-version": {
"success": {
"start-import": {
"title": "正在导入 👌",
"desc": "导入可能需要几分钟时间(依赖于你如何配置)。"
},
"imported": {
"title": "已导入版本 🎉"
}
},
"errors": {
"import-error": {
"desc": "检查所选文件夹是否为 Beat Saber 的安装内容。"
}
}
},
"settings": {
"move-folder": {
"success": {
"titles": {
"transfer-started": "正在传输",
"transfer-finished": "传输完成"
},
"descs": {
"transfer-started": "传输已开始,可能需要几分钟时间(依赖于你如何配置)。"
}
},
"errors": {
"titles": {
"transfer-failed": "传输失败 😕"
},
"descs": {
"COPY_TO_SUBPATH": "目标文件夹不能是源文件夹的子文件夹。",
"restore-linked-folders": "恢复共享文件夹时发生错误。你仍然可以通过版本页面上的'共享文件夹'菜单手动恢复它们。"
}
}
},
"steam": {
"success": {
"titles": {
"logout": "断开与 Steam 的连接"
}
}
},
"additional-content": {
"deep-link": {
"select-all": "全选",
"activation": {
"success": {
"title": "一键安装激活成功!",
"description": "一键安装已被激活。"
},
"error": {
"description": "无法激活一键安装。"
}
},
"deactivation": {
"success": {
"title": "一键安装已停用!",
"description": "一键安装安装已被停用。"
},
"error": {
"description": "发生未知错误。"
}
},
"check-all-enabled": {
"title": "一键安装已禁用",
"description": "一个或多个一键安装被禁用。前往设置以启用它们。",
"actions": {
"settings": "设置",
"not-remind": "不再提醒"
}
}
}
}
},
"bs-launch": {
"success": {
"titles": {
"BS_LAUNCHING": "启动中...🚀",
"STEAM_LAUNCHING": "Steam 正在启动!"
},
"msg": {
"BS_LAUNCHING": "别忘了热身哦 😉",
"STEAM_LAUNCHING": "Beat Saber 会在 Steam 启动后自动启动。"
}
},
"errors": {
"titles": {
"UNKNOWN_ERROR": "无法启动",
"STEAM_NOT_RUNNING": "Steam 未运行",
"OCULUS_NOT_RUNNING": "Oculus 未运行",
"BS_ALREADY_RUNNING": "Beat Saber 已在运行",
"EXE_NOT_FINDED": "缺少文件",
"EXIT": "突然停止",
"OCULUS_LIB_NOT_FOUND": "未找到 Oculus 库"
},
"msg": {
"UNKNOWN_ERROR": "发生未知错误。",
"STEAM_NOT_RUNNING": "启动 BeatSaber 前必须运行 Steam。",
"OCULUS_NOT_RUNNING": "启动 BeatSaber 前必须运行 Oculus。",
"BS_ALREADY_RUNNING": "再次启动前请关闭 BeatSaber。",
"EXE_NOT_FINDED": "某些文件似乎丢失了,尝试验证文件。",
"EXIT": "BeatSaber 突然停止,请检查文件。",
"OCULUS_LIB_NOT_FOUND": "检查 Oculus 应用是否正确安装,以及库是否在 Oculus 中正确定义。"
},
"actions": {
"STEAM_NOT_RUNNING": "启动 Steam"
}
}
},
"steam": {
"steam-launching": {
"title": "Steam 正在启动!",
"description": "Beat Saber 会在 Steam 启动后自动启动。"
}
},
"custom-version": {
"errors": {
"titles": {
"CantEditSteam": "无法编辑",
"CantRename": "无法重命名",
"VersionAlreadExist": "该版本已存在",
"CantClone": "无法克隆"
},
"msg": {
"CantEditSteam": "你不能编辑 Steam 版本。不过你可以克隆它。"
}
},
"success": {
"titles": {
"CloningFinished": "克隆完成 🎉"
}
}
},
"mods": {
"install-mods": {
"titles": {
"success": "Mod 已安装 🎉",
"warning": "Mod 已安装 🤔"
},
"msg": {
"success": "所有 Mod 已被安装。",
"warning": "一个或多个 Mod 无法安装。",
"errors": {
"no-mods": "没有 Mod 可安装。",
"cannot-install-bsipa": "BSIPA安装失败 😨"
}
}
},
"uninstall-mod": {
"titles": {
"success": "Mod 已卸载 🎉"
},
"msg": {
"errors": {
"no-mods": "该 Mod 未安装 😑"
}
}
},
"uninstall-all-mods": {
"titles": {
"success": "所有 Mod 已卸载 🎉"
},
"msg": {
"success": "所有 Mod 已被卸载。",
"errors": {
"no-mods": "该版本中没有安装 Mod 😑"
}
}
}
},
"maps": {
"one-click-install": {
"success": "谱面安装完成",
"error": "安装谱面时发生错误"
}
},
"playlists": {
"one-click-install": {
"success": "歌单安装完成",
"error": "歌单安装时发生错误"
}
},
"models": {
"one-click-install": {
"success": "模型安装完成",
"error": "模型安装时发生错误"
}
},
"shared-folder": {
"info": {
"userdata-backup-created": {
"title": "备份已创建",
"msg": "共享 “UserData” 文件夹可能会产生错误,如果出现问题,请取消关联该文件夹以恢复备份"
}
}
},
"create-launch-shortcut": {
"success": {
"title": "快捷方式已创建",
"msg": "快捷方式已在桌面上创建"
},
"error": {
"msg": "创建快捷方式时发生错误"
}
}
},
"modals": {
"misc": {
"remember-my-choice": "记住我的选择"
},
"choose-store": {
"title": "选择哪个平台?",
"body": "选择你希望为其下载 BeatSaber 的平台。",
"set-in-settings": "在设置中设定默认平台"
},
"guard": {
"title": "Steam Guard",
"inputs": {
"guard-code": {
"label": "Guard Code",
"placeholder": "输入你的 Guard Code"
}
},
"buttons": {
"submit": "登录"
}
},
"steam-login": {
"title": "Steam登录",
"inputs": {
"username": {
"label": "使用账户名登录",
"placeholder": "输入你的账户名"
},
"password": {
"label": "密码",
"placeholder": "输入你的密码",
"max-length-warning": "密码超过64个字符!如果密码无效,请尝试只输入前64个字符。"
},
"qr": {
"label": "或使用二维码",
"note": {
"use-the": "使用",
"steam-mobile-app": "Steam 移动应用",
"to-connect-with-qr": "通过二维码登录。"
}
},
"stay": "记住我"
},
"why-credentials": "为什么需要我的凭证?",
"need-help-to-connect": "我需要帮助以访问我的账户!",
"buttons": {
"submit": "登录"
}
},
"steam-auth-approve": {
"title": "等待确认",
"protected-by-mobile-auth": "账户受移动认证器保护。",
"use-steam-app-to-approve": "使用 Steam 移动应用程序确认连接...",
"not-access-to-steam-app": "我无法访问 Steam 移动应用程序"
},
"steam-credentials": {
"title": "Steam 凭证",
"p-1": "凭证仅用于下载游戏,因为 Steam 需要验证你是否已经购买了游戏,以便允许你下载它。它们不会被保存,而是直接传递给 DepotDownloader。如果你不想输入你的凭证,你可以按照此教程操作:",
"p-2": "然后点击右上角的齿轮图标,选择“导入版本”,选择 Beat Saber 已下载的文件夹(如果你按照上面的教程,你应该会得到正确的位置)"
},
"bs-import-version": {
"title": "导入版本",
"description": "导入 Beat Saber 版本以与 BSManager 一起使用。这将把所选的 Beat Saber 安装文件夹复制到 BSManager 版本文件夹。",
"oculus-version": "Oculus 版本",
"oculus-version-tooltip": "检查是否为 Oculus 版本",
"buttons": {
"submit": "导入版本"
}
},
"bs-uninstall": {
"title": "卸载",
"description": "你确定要卸载 Beat Saber {version} 吗?你将不得不重新下载它才能游玩。",
"buttons": {
"submit": "卸载"
}
},
"install-folder": {
"title": "安装文件夹",
"description": "更改默认安装文件夹将导致所有已安装数据移动到新文件夹。",
"buttons": {
"submit": "选择文件夹"
}
},
"edit-version": {
"title": "编辑版本",
"buttons": {
"submit": "编辑"
}
},
"clone-version": {
"title": "克隆版本",
"description": "克隆版本可以让你在两个版本之间分离附加的 BeatSaber 内容。",
"inputs": {
"name": {
"label": "名称",
"placeholder": "版本名称"
},
"color": {
"label": "颜色"
}
},
"buttons": {
"submit": "克隆"
}
},
"uninstall-mod": {
"title": "卸载",
"description": "你确定要卸载 {mod} 吗?这可能会导致其他已安装的 Mod 失效。",
"description-bsipa": "你确定要卸载 BSIPA 吗?之后所有已安装的 Mod 将不再起作用。"
},
"uninstall-all-mods": {
"title": "Mod 卸载中",
"description": "你确定要卸载 {version} 版本的所有 Mod 卸载吗?该操作无法回退。"
},
"maps-actions": {
"delete-maps": {
"title": {
"single": "删除该谱面?",
"multiple": "删除谱面?"
},
"desc": {
"single": "你确定要删除谱面 {name} 吗?",
"multiple": "你确定要删除全部 {nb} 个谱面吗?"
},
"info": {
"desc": {
"single": "该谱面是共享谱面的一部分",
"multiple": "这些谱面是共享谱面的一部分"
},
"title": {
"single": "该谱面也将从使用共享谱面的版本中移除",
"multiple": "这些谱面也将从使用共享谱面的版本中移除"
}
}
},
"link-maps": {
"title": "关联谱面",
"desc": "关联谱面可以在所有启用此功能的版本之间共享谱面。一旦关联,该版本将受益于共享谱面。",
"info": "添加和删除的谱面也将被共享",
"keep-maps": {
"label": "保留谱面",
"title": "保留谱面将会把当前版本的所有谱面复制到共享谱面文件夹。否则,该版本的谱面将不会被保留,它们将丢失。"
},
"valid-btn": "关联谱面"
},
"unlink-maps": {
"title": "取消关联谱面",
"desc": "请注意,取消关联谱面后该版本将无法使用共享谱面,直到重新启用。",
"keep-maps": {
"label": "保留谱面",
"title": "保留谱面将会在取消关联后把共享文件夹的所有谱面复制到当前版本。如果此项被禁用,谱面也不会丢失。"
},
"valid-btn": "取消关联谱面"
}
},
"download-maps": {
"search-btn": "搜索",
"loading-maps": "谱面加载中...",
"no-maps-found": "未找到谱面",
"no-internet": "无网络"
},
"mods-disclaimer": {
"title": "免责声明",
"p-1": "选择使用 Mod,你需要理解:",
"li-1": "你可能会遇到原版游戏中不存在的问题。99.9%的bug、崩溃和延迟都是由 Mod 引起的。",
"li-2": "模组可能会因更新而失效,这是正常的——当这种情况发生时,请保持耐心和尊重,因为模组制作者都是有真实生活的志愿者。",
"li-3": "Beat Games并不是故意想要破坏 Mod。他们希望能够修改代码库,有时这会破坏 Mod,但他们并不是想要消灭 Mod。",
"p-2": "不要因为与 Mod 相关的问题攻击游戏开发者,反之亦然——Mod 制作者和游戏开发者是两个不同的群体。总之,不要做个 SB。"
},
"shared-folders": {
"title": "共享文件夹",
"description": "关联 Beat Saber 文件夹,以便与其他版本中的共享文件夹同步其内容。请注意,删除操作也会被共享。",
"buttons": {
"add-folder": "添加文件夹",
"link-folder": "关联文件夹",
"unlink-folder": "取消关联文件夹",
"link-all": "关联所有"
}
},
"create-launch-shortcut": {
"title": "创建快捷方式",
"desc": "创建快捷方式使得你可以在不通过 BSManager 的情况下以特定选项启动 BeatSaber",
"launch-options": "启动选项",
"advanced-launch": "高级启动",
"valid-btn": "创建快捷方式"
},
"connect-to-meta": {
"title": "连接到 Meta",
"body": {
"token-needed": "需要 Meta 登录令牌用于下载 Beat Saber。",
"need-cookie-enabled": "通过登录 Meta,将打开一个登录窗口,然后你可以开始登录过程。请确保接受 cookie,否则我们可能无法检索你的令牌以开始下载。",
"enter-token-manually": "手动输入我的登录令牌",
"enter-token-manually-tooltip": "这将允许你在不通过 Meta 登录的情况下输入你的登录令牌。"
},
"stay": "记住我",
"connect-to-meta": "连接到 Meta"
},
"original-version-backup-oculus": {
"title": "警告",
"body": {
"must-be-installed-once": "你必须至少从 Oculus 商店安装过一次 BeatSaber,否则 BeatSaber 可能会在启动后自动关闭。",
"need-backup": "要启动该版本,位于你的 Oculus 库中的 BeatSaber 安装文件夹将被重命名。",
"can-restore-later": "如果需要,你可以通过前往 BSManager 的原始 Oculus 版本选项并点击'恢复文件夹'来恢复它。",
"tips-launch-oculus": "提示:只要原始版本没有被恢复,你就可以直接从 Oculus 启动该版本。"
},
"not-remind-me": "不再提醒我",
"understood": "明白了"
},
"enter-meta-token": {
"title": "Meta 令牌",
"body": {
"need-token": "要下载 BeatSaber,需要你的 Meta 登录令牌。",
"how-obtain-token": "如何获取我的 Meta 令牌?",
"input-label": "Meta 令牌",
"token-is-invalid": "令牌无效。"
},
"valid-btn": "验证"
}
},
"maps": {
"map-filter-panel": {
"duration": "时长",
"tags": "标签",
"specificities": "general",
"requirements": "要求"
},
"map-types": {
"accuracy": "精确度",
"balanced": "平衡",
"challenge": "挑战",
"dancestyle": "舞蹈",
"fitness": "健身",
"speed": "速度",
"tech": "技术"
},
"map-styles": {
"dance": "dance",
"swing": "swing",
"nightcore": "nightcore",
"folk": "folk",
"family": "family",
"ambient": "ambient",
"funk": "funk",
"jazz": "jazz",
"soul": "soul",
"speedcore": "speedcore",
"punk": "punk",
"rb": "r&b",
"holiday": "holiday",
"vocaloid": "vocaloid",
"jrock": "j-rock",
"trance": "trance",
"drumbass": "drum & bass",
"comedy": "comedy",
"instrumental": "instrumental",
"hardcore": "hardcore",
"kpop": "k-pop",
"indie": "indie",
"techno": "techno",
"house": "house",
"game": "video game",
"film": "film",
"alt": "alternative",
"dubstep": "dubstep",
"metal": "metal",
"anime": "anime",
"hiphop": "hiphop",
"jpop": "j-pop",
"rock": "rock",
"pop": "pop",
"electronic": "electronic",
"classical-orchestral": "Classical & Orchestral"
},
"map-specificities": {
"automapper": "AI",
"ranked": "ranked",
"curated": "curated",
"verified": "verified",
"fullSpread": "full spread"
},
"difficulties": {
"Easy": "easy",
"Normal": "normal",
"Hard": "hard",
"Expert": "expert",
"ExpertPlus": "expert+"
},
"map-item": {
"by": "By {songAutor}",
"mapped-by": "mapped by"
}
},
"models": {
"types": {
"singular": {
"avatar": "avatar",
"saber": "光剑",
"platform": "平台",
"bloq": "方块"
},
"plural": {
"avatar": "avatars",
"saber": "光剑",
"platform": "平台",
"bloq": "方块"
}
},
"sorts": {
"name": "名称",
"date": "日期",
"author": "作者"
},
"panel": {
"actions": {
"search": "搜索模型",
"drop-down": {
"delete": "删除模型",
"export": "导出模型"
},
"link-models": "关联模型",
"unlink-models": "取消关联模型"
},
"grid": {
"loading": "模型加载中...",
"no-models": "无模型",
"download-models": "下载模型"
}
},
"modals": {
"delete-model": {
"title": "删除该模型",
"desc": "确定要删除模型 {modelName} 吗?",
"linked-annotation": "该模型将从所有关联版本中移除。"
},
"delete-models": {
"title": "删除模型",
"desc": "确定要删除 {nb} 个模型吗?",
"linked-annotation": "这些模型将从所有关联版本中移除。"
},
"download-models": {
"search-btn": "搜索",
"search-placeholder": "搜索模型",
"search-tips": {
"header": {
"tag": "Tag",
"desc": "描述"
},
"author-desc": "仅显示指定作者的模型。",
"hash-desc": "仅显示具有指定哈希值的模型。",
"tag-desc": "仅显示具有指定 tag 的模型。",
"name-desc": "仅显示具有指定名称的模型。",
"discordid-desc": "仅显示来自指定 Discord 用户的模型。",
"status-desc": "仅显示具有指定状态的模型。(仅限个人资料,且仅限作者)"
},
"no-models": "未找到模型",
"no-internet": "无网络连接",
"error-occured": "发生了一个错误,稍后重试。"
},
"link-models": {
"avatar": {
"title": "关联 Avatar",
"desc": "关联 Avatar 允许在所有启用此功能的版本之间共享 Avatar。一旦关联,该版本将受益于共享 Avatar。",
"info": "对 Avatar 的添加和删除也将被共享",
"keep-models": {
"label": "保留 Avatar",
"title": "保留 Avatar 将会把当前版本的所有 Avatar复制到共享 Avatar文件夹。否则,该版本的 Avatar将不会被保留,它们将丢失。"
},
"valid-btn": "关联 Avatar "
},
"saber": {
"title": "关联光剑",
"desc": "关联光剑允许在所有启用此功能的版本之间共享光剑。一旦关联,该版本将受益于共享光剑。",
"info": "对光剑的添加和删除也将被共享",
"keep-models": {
"label": "保留光剑",
"title": "保留光剑将会把当前版本的所有光剑复制到共享光剑文件夹。否则,该版本的光剑将不会被保留,它们将丢失。"
},
"valid-btn": "关联光剑"
},
"platform": {
"title": "关联平台",
"desc": "关联平台允许在所有启用此功能的版本之间共享平台。一旦关联,该版本将受益于共享平台。",
"info": "对平台的添加和删除也将被共享",
"keep-models": {
"label": "保留平台",
"title": "保留平台将会把当前版本的所有平台复制到共享平台文件夹。否则,该版本的平台将不会被保留,它们将丢失。"
},
"valid-btn": "关联平台"
},
"bloq": {
"title": "关联方块",
"desc": "关联方块允许在所有启用此功能的版本之间共享方块。一旦关联,该版本将受益于共享方块。",
"info": "对方块的添加和删除也将被共享",
"keep-models": {
"label": "保留方块",
"title": "保留方块将会把当前版本的所有方块复制到共享方块文件夹。否则,该版本的方块将不会被保留,它们将丢失。"
},
"valid-btn": "关联方块"
}
},
"unlink-models": {
"avatar": {
"title": "取消关联 Avatar",
"desc": "请注意,取消关联 Avatar 将禁用该版本的共享 Avatar 使用,直到重新启用。",
"keep-models": {
"label": "保留 Avatar",
"title": "保留 Avatar 将会在取消关联后把共享文件夹的所有 Avatar 复制到当前版本。如果此项被禁用,Avatar 将不会丢失。"
},
"valid-btn": "取消关联 Avatar"
},
"saber": {
"title": "取消关联光剑",
"desc": "请注意,取消关联光剑将禁用该版本的共享光剑使用,直到重新启用。",
"keep-models": {
"label": "保留光剑",
"title": "保留光剑将会在取消关联后把共享文件夹的所有光剑复制到当前版本。如果此项被禁用,光剑将不会丢失。"
},
"valid-btn": "取消关联光剑"
},
"platform": {
"title": "取消关联平台",
"desc": "请注意,取消关联平台将禁用该版本的共享平台使用,直到重新启用。",
"keep-models": {
"label": "保留平台",
"title": "保留平台将会在取消关联后把共享文件夹的所有平台复制到当前版本。如果此项被禁用,平台将不会丢失。"
},
"valid-btn": "取消关联平台"
},
"bloq": {
"title": "取消关联方块",
"desc": "请注意,取消关联方块将禁用该版本的共享方块使用,直到重新启用。",
"keep-models": {
"label": "保留方块",
"title": "保留方块将会在取消关联后把共享文件夹的所有方块复制到当前版本。如果此项被禁用,方块将不会丢失。"
},
"valid-btn": "取消关联方块"
}
}
},
"notifications": {
"prevent-for-mods": {
"title": "需要的 Mod",
"desc": "确保你已经安装了在 BeatSaber 中使用模型所需的 Mod",
"go-to-mods": "前往 Mod 页",
"not-remind": "不再提醒我"
},
"prevent-for-models-breaks": {
"title": "已损坏的模型",
"desc": "因 BeatSaber 引擎更新,这些模型在该版本中不再可用。"
},
"export-success": {
"title": "导出成功 🎉"
}
}
},
"beat-saver": {
"maps-sorts": {
"Latest": "最新",
"Relevance": "相关",
"Rating": "评分",
"Curated": "Curated"
}
},
"auto-update": {
"checking": "检查更新中",
"downloading": "下载更新中"
},
"bs-shortcut-launch": {
"beat-saber-launching": "启动 Beat Saber",
"launching": "启动中",
"open-bsmanager": "打开 BSManager",
"status-text": {
"init": "正在初始化...",
"success": {
"BS_LAUNCHING": "Beat Saber 启动中...",
"STEAM_LAUNCHING": "Steam 启动中...",
"STEAM_LAUNCHED": "Steam 成功启动!",
"UNABLE_TO_LAUNCH_STEAM": "无法启动 Steam, 强制启动 Beat Saber ..."
}
}
},
"dateformat": {
"dayNames": ["周日", "周一", "周二", "周三", "周四", "周五", "周六", "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"],
"monthNames": ["1 月", "2 月", "3 月", "4 月", "5 月", "6 月", "7 月", "8 月", "9 月", "10 月", "11 月", "12 月", "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
"timeNames": ["上午", "下午", "上午", "下午", "上午", "下午", "上午", "下午"]
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "bs-manager",
"version": "1.3.2",
"version": "1.4.1",
"description": "BSManager",
"main": "./dist/main/main.js",
"author": {

Before

Width:  |  Height:  |  Size: 260 KiB

After

Width:  |  Height:  |  Size: 260 KiB

Before

Width:  |  Height:  |  Size: 188 KiB

After

Width:  |  Height:  |  Size: 188 KiB

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Before

Width:  |  Height:  |  Size: 965 KiB

After

Width:  |  Height:  |  Size: 965 KiB

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

+19 -9
View File
@@ -1,4 +1,4 @@
import { CopyOptions, copy, createReadStream, ensureDir, move, stat, symlink } from "fs-extra";
import { CopyOptions, copy, createReadStream, ensureDir, move, realpath, stat, symlink } from "fs-extra";
import { access, mkdir, rm, readdir, unlink, lstat, readlink } from "fs/promises";
import path from "path";
import { Observable, concatMap, from } from "rxjs";
@@ -165,16 +165,20 @@ export function hashFile(filePath: string, algorithm = "sha256"): Promise<string
}
export async function dirSize(dirPath: string): Promise<number>{
const files = await readdir(dirPath, { withFileTypes: true });
const paths = files.map(async file => {
const fullPath = path.join(dirPath, file.name);
const entries = await readdir(dirPath);
if (file.isDirectory()) return dirSize(fullPath);
const paths = entries.map(async entry => {
const fullPath = path.join(dirPath, entry);
const realPath = await realpath(fullPath);
const stat = await lstat(realPath);
if (file.isFile()) {
const { size } = await stat( fullPath );
return size;
if (stat.isDirectory()) {
return dirSize(fullPath);
}
if (stat.isFile()) {
return stat.size;
}
return 0;
@@ -185,9 +189,15 @@ export async function dirSize(dirPath: string): Promise<number>{
export function rxCopy(src: string, dest: string, option?: CopyOptions): Observable<Progression> {
return from(dirSize(src)).pipe(
const dirSizePromise = dirSize(src).catch(err => {
log.error("dirSizePromise", err);
return 0;
});
return from(dirSizePromise).pipe(
concatMap(totalSize => {
const progress: Progression = { current: 0, total: totalSize };
return new Observable<Progression>(sub => {
sub.next(progress);
copy(src, dest, {...option, filter: (src) => {
@@ -252,17 +252,24 @@ export class LocalMapsManagerService {
}
const zipUrl = map.versions.at(0).downloadURL;
const mapFolderName = sanitize(`${map.id}-${map.name}`);
const mapsFolder = await this.getMapsFolderPath(version);
const installedMap = await this.loadMapInfoFromPath(path.join(mapsFolder, mapFolderName)).catch(e => {
log.error("loadMapInfoFromPath", e);
return null;
});
if(map.versions.every(version => version.hash === installedMap?.hash)) {
return installedMap;
}
const { zip, zipPath } = await this.downloadMapZip(zipUrl);
if (!zip) {
throw `Cannot download ${zipUrl}`;
}
const mapFolderName = sanitize(`${map.id}-${map.name}`);
const mapPath = path.join(mapsFolder, mapFolderName);
await ensureFolderExist(mapPath);
@@ -159,7 +159,10 @@ export class LocalPlaylistsManagerService {
await this.installBPListFile(playlistPath, version);
const versionMapsFolder = await this.maps.getMapsFolderPath(version);
const realDestMapsFolder = await realpath(versionMapsFolder);
const realDestMapsFolder = await realpath(versionMapsFolder).catch(e => {
log.error(e);
return versionMapsFolder;
});
if(realSourceMapsFolder === realDestMapsFolder) { continue; }
@@ -2,6 +2,7 @@ import { LaunchOption } from "shared/models/bs-launch";
import { BSLocalVersionService } from "../bs-local-version.service";
import { ChildProcessWithoutNullStreams, SpawnOptionsWithoutStdio, spawn } from "child_process";
import path from "path";
import log from "electron-log";
export abstract class AbstractLauncherService {
@@ -39,6 +40,8 @@ export abstract class AbstractLauncherService {
spawnOptions.windowsVerbatimArguments = true;
}
log.info(`Launch BS exe at ${bsExePath} with args ${args?.join(" ")}`);
return spawn(bsExePath, args, spawnOptions);
}
@@ -51,28 +51,33 @@ export class OculusLauncherService extends AbstractLauncherService implements St
throw new Error("Oculus library not found, deleteBsSymlinks");
}
const libContents = await readdir(oculusLibPath, { withFileTypes: true});
const symlinks = (await Promise.all(libContents.map(async dirent => {
return (await lstat(path.join(oculusLibPath, dirent.name))).isSymbolicLink() ? dirent : null;
const libContents = await readdir(oculusLibPath);
const symlinks = (await Promise.all(libContents.map(async dir => {
return (await lstat(path.join(oculusLibPath, dir))).isSymbolicLink() ? dir : null;
}))).filter(Boolean);
const bsSymlinks = symlinks.filter(dirent => dirent.name.startsWith(OCULUS_BS_DIR));
const versionsFolderPath = await this.pathsService.versionsDirectory();
log.info("Symlinks found in Oculus library", symlinks);
const bsSymlinks = symlinks.filter(dirent => dirent.startsWith(OCULUS_BS_DIR));
// get only symlinks created by BSM (with metadata.config)
const bsmSymlinks = (await Promise.all(bsSymlinks.map(async symlink => {
const symlinkPath = path.join(oculusLibPath, symlink.name);
const targetPath = await readlink(symlinkPath).catch(err => { log.error(err); return undefined; });
const symlinkPath = path.join(oculusLibPath, symlink);
const targetPath = await readlink(symlinkPath).catch(err => log.error(err));
log.info("Oculus Symlink", symlink, "target", targetPath);
if(!targetPath){ return null; }
if(!targetPath.startsWith(versionsFolderPath)){ return null; }
const bsmVersionsDir = path.join(this.pathsService.INSTALLATION_FOLDER, this.pathsService.VERSIONS_FOLDER);
if(!targetPath.includes(bsmVersionsDir)){ return null; }
return symlink;
}))).filter(Boolean);
await Promise.all(bsmSymlinks.map(symlink => {
log.info("Deleting symlink", symlink.name);
return unlink(path.join(oculusLibPath, symlink.name));
log.info("Delete symlink", symlink);
return unlink(path.join(oculusLibPath, symlink));
}));
}
+32 -16
View File
@@ -11,9 +11,9 @@ import log from "electron-log";
import { OculusService } from "./oculus.service";
import { DownloadLinkType } from "shared/models/mods";
import sanitize from "sanitize-filename";
import { Progression, copyDirectoryWithJunctions, deleteFolder, ensurePathNotAlreadyExist, getFoldersInFolder, pathExist, rxCopy } from "../helpers/fs.helpers";
import { Progression, copyDirectoryWithJunctions, deleteFolder, ensurePathNotAlreadyExist, getFoldersInFolder, rxCopy } from "../helpers/fs.helpers";
import { FolderLinkerService } from "./folder-linker.service";
import { ReadStream, createReadStream, readFile, writeFile } from "fs-extra";
import { ReadStream, createReadStream, pathExists, readFile, writeFile } from "fs-extra";
import readline from "readline";
import { Observable, Subject, catchError, finalize, from, map, switchMap, throwError } from "rxjs";
import { BsStore } from "../../shared/models/bs-store.enum";
@@ -53,7 +53,10 @@ export class BSLocalVersionService {
private async getVersionFromGlobalGameManagerFile(versionFilePath: string): Promise<BSVersion> {
if(!(await pathExist(versionFilePath))){ return null; }
if(!(await pathExists(versionFilePath))){
log.info("globalgamemanagers file not found", versionFilePath);
return null;
}
const versionsDict = await this.remoteVersionService.getAvailableVersions();
@@ -81,6 +84,8 @@ export class BSLocalVersionService {
stream?.close();
}
log.info("unable to get version from globalgamemanagers file", versionFilePath);
return null;
}
@@ -92,6 +97,8 @@ export class BSLocalVersionService {
}
): Promise<BSVersion>{
log.info("getVersionOfBSFolder", bsPath, options);
if(!bsPath){ return null; }
const versionFilePath = path.join(bsPath, 'Beat Saber_Data', 'globalgamemanagers');
@@ -129,7 +136,7 @@ export class BSLocalVersionService {
const contents = await readFile(path.join(versionPath, this.METADATA_FILE), "utf-8");
return JSON.parse(contents);
})().catch(e => {
log.warn(e);
log.warn("Not a critical error", e);
return {};
}).then(metadata => ({...defaultMetadata, ...metadata}));
}
@@ -139,7 +146,7 @@ export class BSLocalVersionService {
const metadata = await this.getAllVersionMetadata(version);
return metadata?.[key];
})().catch(e => {
log.warn(e);
log.warn("Not a critical error", e);
return null;
}).then(value => (value ?? defaultValue) as T);
}
@@ -196,7 +203,7 @@ export class BSLocalVersionService {
*/
public async getInstalledVersionPath(version: BSVersion): Promise<string>{
const versionPath = await this.getVersionPath(version);
if(await pathExist(versionPath)){ return versionPath; }
if(await pathExists(versionPath)){ return versionPath; }
const versionFolders = await getFoldersInFolder(await this.installLocationService.versionsDirectory());
@@ -227,7 +234,7 @@ export class BSLocalVersionService {
private async getSteamVersion(): Promise<BSVersion> {
const steamBsFolder = await this.steamService.getGameFolder(BS_APP_ID, "Beat Saber");
if (!steamBsFolder || !(await pathExist(steamBsFolder))) {
if (!steamBsFolder || !(await pathExists(steamBsFolder))) {
return null;
}
@@ -247,26 +254,35 @@ export class BSLocalVersionService {
public async getInstalledVersions(): Promise<BSVersion[]> {
const versions: BSVersion[] = [];
const steamVersion = await this.getSteamVersion();
const steamVersion = await this.getSteamVersion().catch(e => {
log.error("unable to get original Steam version", e);
});
if (steamVersion) {
versions.push(steamVersion);
}
const oculusVersion = await this.getOculusVersion();
const oculusVersion = await this.getOculusVersion().catch(e => {
log.error("unable to get original Oculus version", e);
});
if (oculusVersion) {
versions.push(oculusVersion);
}
if (!(await pathExist(await this.installLocationService.versionsDirectory()))) {
if (!(await pathExists(await this.installLocationService.versionsDirectory()))) {
return versions;
}
const folderInInstallation = await getFoldersInFolder(await this.installLocationService.versionsDirectory());
for (const f of folderInInstallation) {
log.info("try get version from folder", f);
log.info("Finded versions folders", folderInInstallation);
const version = await this.getVersionOfBSFolder(f);
for (const f of folderInInstallation) {
const version = await this.getVersionOfBSFolder(f).catch(e => {
log.error("unable to get version of folder", f, e);
});
if(!version){ continue; }
@@ -283,7 +299,7 @@ export class BSLocalVersionService {
public async deleteVersion(version: BSVersion): Promise<boolean>{
if(version.steam || version.oculus){ return false; }
const versionFolder = await this.getVersionPath(version);
if(!(await pathExist(versionFolder))){ return true; }
if(!(await pathExists(versionFolder))){ return true; }
return deleteFolder(versionFolder)
.then(() => { return true; })
@@ -304,7 +320,7 @@ export class BSLocalVersionService {
return editedVersion;
}
if((await pathExist(newPath)) && newPath === oldPath){ throw {title: "VersionAlreadExist"} as BsmException; }
if((await pathExists(newPath)) && newPath === oldPath){ throw {title: "VersionAlreadExist"} as BsmException; }
return rename(oldPath, newPath).then(() => {
this.deleteCustomVersion(version);
@@ -328,7 +344,7 @@ export class BSLocalVersionService {
this.addCustomVersion(cloneVersion);
}
if(await pathExist(newPath)){ throw {title: "VersionAlreadExist"} as BsmException; }
if(await pathExists(newPath)){ throw {title: "VersionAlreadExist"} as BsmException; }
return copyDirectoryWithJunctions(originPath, newPath).then(() => {
this.addCustomVersion(cloneVersion);
@@ -108,7 +108,11 @@ export class BsOculusDownloaderService {
private async createDownloadVersion(version: BSVersion): Promise<{version: BSVersion, dest: string}>{
const dest = await ensurePathNotAlreadyExist(await this.versions.getVersionPath(version));
return {
version: {...version, ...(path.basename(dest) !== version.BSVersion && { name: path.basename(dest) })},
version: {
...version,
...(path.basename(dest) !== version.BSVersion && { name: path.basename(dest) }),
metadata: { store: BsStore.OCULUS }
},
dest
};
}
@@ -64,7 +64,11 @@ export class BsSteamDownloaderService {
const versionPath = await this.localVersionService.getVersionPath(downloadInfos.bsVersion);
const dest = downloadInfos.isVerification ? versionPath : await ensurePathNotAlreadyExist(versionPath);
const downloadVersion: BSVersion = { ...downloadInfos.bsVersion, ...(path.basename(dest) !== downloadInfos.bsVersion.BSVersion && { name: path.basename(dest) }) };
const downloadVersion: BSVersion = {
...downloadInfos.bsVersion,
...(path.basename(dest) !== downloadInfos.bsVersion.BSVersion && { name: path.basename(dest) }),
metadata: { store: BsStore.STEAM }
};
const depotDownloaderOptions: DepotDownloaderArgsOptions = {
app: BS_APP_ID,
@@ -13,8 +13,8 @@ export class InstallationLocationService {
return InstallationLocationService.instance;
}
private readonly INSTALLATION_FOLDER = "BSManager";
private readonly VERSIONS_FOLDER = "BSInstances";
public readonly INSTALLATION_FOLDER = "BSManager";
public readonly VERSIONS_FOLDER = "BSInstances";
private readonly SHARED_CONTENT_FOLDER = "SharedContent";
+2
View File
@@ -39,6 +39,7 @@ export class IpcService {
}
public send<T>(channel: string, window: BrowserWindow, response?: T | Error): void {
if(window.webContents?.isDestroyed()){ return; }
window.webContents?.send(channel, response);
}
@@ -53,6 +54,7 @@ export class IpcService {
complete: () => this.send(this.getCompleteChannel(channel), window)
})
window.webContents.once("destroyed", () => sub.unsubscribe());
window.webContents.ipc.once(this.getTearDownChannel(channel), () => sub.unsubscribe());
sub.add(() => {
@@ -9,11 +9,13 @@ import { RequestService } from "../request.service";
import { spawn } from "child_process";
import { BS_EXECUTABLE } from "../../constants";
import log from "electron-log";
import { deleteFolder, pathExist, unlinkPath, ensureFolderExist } from "../../helpers/fs.helpers";
import { deleteFolder, pathExist, unlinkPath } from "../../helpers/fs.helpers";
import { lastValueFrom } from "rxjs";
import JSZip from "jszip";
import { extractZip } from "../../helpers/zip.helpers";
import recursiveReadDir from "recursive-readdir";
import { minToMs } from "../../../shared/helpers/time.helpers";
import { ensureDir } from "fs-extra";
export class BsModsManagerService {
private static instance: BsModsManagerService;
@@ -121,6 +123,8 @@ export class BsModsManagerService {
private async downloadZip(zipUrl: string): Promise<JSZip> {
zipUrl = path.join(this.beatModsApi.BEAT_MODS_URL, zipUrl);
log.info("Download mod zip", zipUrl);
const buffer = await lastValueFrom(this.requestService.downloadBuffer(zipUrl))
.then(progress => progress.data)
.catch(e => {
@@ -139,24 +143,33 @@ export class BsModsManagerService {
}
private async executeBSIPA(version: BSVersion, args: string[]): Promise<boolean> {
log.info("executeBSIPA", version?.BSVersion, args);
const versionPath = await this.bsLocalService.getVersionPath(version);
const ipaPath = path.join(versionPath, "IPA.exe");
const bsExePath = path.join(versionPath, BS_EXECUTABLE);
if (!(await pathExist(ipaPath)) || !(await pathExist(bsExePath))) {
log.error("IPA.exe or Beat Saber.exe not found");
return false;
}
return new Promise<boolean>(resolve => {
log.info("START IPA PROCESS", `start /wait /min "" "${ipaPath}" ${args.join(" ")}`);
const processIPA = spawn(`start /wait /min "" "${ipaPath}" ${args.join(" ")}`, { cwd: versionPath, detached: true, shell: true });
processIPA.once("exit", code => {
if (code === 0) {
log.info("Ipa process exist with code 0");
return resolve(true);
}
log.error("IPA PROCESS", "exit code", code);
log.error("Ipa process exist with non 0 code", code);
resolve(false);
});
setTimeout(() => resolve(false), 1 * 60 * 1000); // timeout 1min
setTimeout(() => {
log.info("Ipa process timeout");
resolve(false)
}, minToMs(1));
});
}
@@ -168,6 +181,7 @@ export class BsModsManagerService {
}
private async installMod(mod: Mod, version: BSVersion): Promise<boolean> {
log.info("INSTALL MOD", mod.name, "for version", `${version.BSVersion} - ${version.name}`);
this.utilsService.ipcSend<ModInstallProgression>("mod-installed", { success: true, data: { name: mod.name, progression: ((this.nbInstalledMods + 1) / this.nbModsToInstall) * 100 } });
const download = this.getModDownload(mod, version);
@@ -176,7 +190,9 @@ export class BsModsManagerService {
return false;
}
log.info("Start download mod zip", mod.name, download.url);
const zip = await this.downloadZip(download.url);
log.info("Mod zip download end", mod.name, download.url, !!zip);
if (!zip) {
return false;
@@ -192,7 +208,10 @@ export class BsModsManagerService {
const entryMd5 = crypto.createHash("md5").update(data).digest("hex");
return download.hashMd5.some(md5 => md5.hash === entryMd5) ? entry : undefined;
})
)
).catch(e => {
log.error("Error while checking mod zip entries", mod.name, e);
throw e;
})
).filter(entry => !!entry);
if (checkedEntries.length !== download.hashMd5.length) {
@@ -203,13 +222,16 @@ export class BsModsManagerService {
const isBSIPA = mod.name.toLowerCase() === "bsipa";
const destDir = isBSIPA ? verionPath : path.join(verionPath, ModsInstallFolder.PENDING);
await ensureFolderExist(destDir);
await ensureDir(destDir);
log.info("Start extracting mod zip", mod.name, "to", destDir);
const extracted = await extractZip(zip, destDir)
.then(() => true)
.catch(e => {
log.error("EXTRACT MOD ZIP", e);
log.error("Error while extracting mod zip", e);
return false;
});
log.info("Mod zip extraction end", mod.name, "to", destDir, "success:", extracted);
const res = isBSIPA
? extracted &&
+10 -5
View File
@@ -1,4 +1,4 @@
import { get } from "https";
import { Agent, get } from "https";
import { createWriteStream, unlink } from "fs";
import { Progression } from "main/helpers/fs.helpers";
import { Observable, shareReplay, tap } from "rxjs";
@@ -17,12 +17,17 @@ export class RequestService {
private constructor() {}
private get ipv4Agent(){
return new Agent({ family: 4 });
}
public async getJSON<T = unknown>(url: RequestInfo, options?: RequestInit): Promise<T> {
try {
const response = await fetch(url, options);
const response = await fetch(url, {...options, agent: this.ipv4Agent});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status} ${response}`);
throw new Error(`HTTP error! status: ${response.status} ${url}`);
}
return await response.json();
@@ -45,7 +50,7 @@ export class RequestService {
});
file.on("error", err => unlink(dest, () => subscriber.error(err)));
const req = get(url, res => {
const req = get(url, { agent: this.ipv4Agent }, res => {
progress.total = parseInt(res.headers?.["content-length"] || "0", 10);
res.on("data", chunk => {
@@ -72,7 +77,7 @@ export class RequestService {
const allChunks: Buffer[] = [];
const req = get(url, res => {
const req = get(url, { agent: this.ipv4Agent }, res => {
progress.total = parseInt(res.headers?.["content-length"] || "0", 10);
res.on("data", chunk => {
@@ -1,7 +1,6 @@
import { ApiResult } from "renderer/models/api/api.model";
import { BsvMapDetail } from "shared/models/maps";
import { BsvPlaylist, BsvPlaylistPage, MapFilter, SearchParams, SearchResponse } from "shared/models/maps/beat-saver.model";
import fetch from "node-fetch";
import { RequestService } from "../../request.service";
export class BeatSaverApiService {
private static instance: BeatSaverApiService;
@@ -13,9 +12,13 @@ export class BeatSaverApiService {
return BeatSaverApiService.instance;
}
private readonly request: RequestService;
private readonly bsaverApiUrl = "https://beatsaver.com/api";
private constructor() {}
private constructor() {
this.request = RequestService.getInstance();
}
private mapFilterToUrlParams(filter: MapFilter): URLSearchParams {
if (!filter) {
@@ -68,15 +71,13 @@ export class BeatSaverApiService {
});
}
public async getMapsDetailsByHashs<T extends string>(hashs: T[]): Promise<ApiResult<Record<Lowercase<T>, BsvMapDetail>>> {
public async getMapsDetailsByHashs<T extends string>(hashs: T[]): Promise<Record<Lowercase<T>, BsvMapDetail>> {
if (hashs.length > 50) {
throw "too musch map hashs";
}
const paramsHashs = hashs.join(",");
const resp = await fetch(`${this.bsaverApiUrl}/maps/hash/${paramsHashs}`);
const data = (await resp.json()) as Record<Lowercase<T>, BsvMapDetail> | BsvMapDetail;
const data = await this.request.getJSON<Record<Lowercase<T>, BsvMapDetail> | BsvMapDetail>(`${this.bsaverApiUrl}/maps/hash/${paramsHashs}`);
if ((data as BsvMapDetail).id) {
const key = (data as BsvMapDetail).versions.at(0).hash.toLowerCase();
@@ -84,41 +85,24 @@ export class BeatSaverApiService {
[key]: data as BsvMapDetail,
} as Record<Lowercase<T>, BsvMapDetail>;
return { status: resp.status, data: parsedData };
return parsedData
}
return { status: resp.status, data: data as Record<Lowercase<T>, BsvMapDetail> };
return data as Record<Lowercase<T>, BsvMapDetail>;
}
public async getMapDetailsById(id: string): Promise<ApiResult<BsvMapDetail>> {
const res = await fetch(`${this.bsaverApiUrl}/maps/id/${id}`);
const data = (await res.json()) as BsvMapDetail;
return { status: res.status, data };
public async getMapDetailsById(id: string): Promise<BsvMapDetail> {
return this.request.getJSON<BsvMapDetail>(`${this.bsaverApiUrl}/maps/id/${id}`);
}
public async searchMaps(search: SearchParams): Promise<ApiResult<SearchResponse>> {
public async searchMaps(search: SearchParams): Promise<SearchResponse> {
const url = new URL(`${this.bsaverApiUrl}/search/text/${search?.page ?? 0}`);
url.search = this.searchParamsToUrlParams(search).toString();
const res = await fetch(url.toString());
if (!res.ok) {
return { status: res.status, data: null };
}
const data = await res.json();
return { status: res.status, data };
return this.request.getJSON<SearchResponse>(url.toString());
}
public async getPlaylistDetails(id: string): Promise<ApiResult<BsvPlaylist>> {
const res = await fetch(`${this.bsaverApiUrl}/playlists/id/${id}/0`);
const data = (await res.json()) as BsvPlaylistPage;
return { status: res.status, data: data.playlist };
public async getPlaylistDetails(id: string): Promise<BsvPlaylist> {
const res = await this.request.getJSON<BsvPlaylistPage>(`${this.bsaverApiUrl}/playlists/id/${id}/0`);
return res.playlist;
}
}
@@ -2,6 +2,7 @@ import { splitIntoChunk } from "../../../../shared/helpers/array.helpers";
import { BsvMapDetail } from "shared/models/maps";
import { BsvPlaylist, SearchParams } from "shared/models/maps/beat-saver.model";
import { BeatSaverApiService } from "./beat-saver-api.service";
import log from "electron-log";
export class BeatSaverService {
private static instance: BeatSaverService;
@@ -36,12 +37,10 @@ export class BeatSaverService {
chunkHash.map(async hashs => {
const res = await this.bsaverApi.getMapsDetailsByHashs(hashs);
if (res.status === 200) {
mapDetails.push(...Object.values<BsvMapDetail>(res.data).filter(detail => !!detail));
mapDetails.forEach(detail => {
this.cachedMapsDetails.set(detail.versions.at(0).hash.toLowerCase(), detail);
});
}
mapDetails.push(...Object.values<BsvMapDetail>(res).filter(detail => !!detail));
mapDetails.forEach(detail => {
this.cachedMapsDetails.set(detail.versions.at(0).hash.toLowerCase(), detail);
});
})
);
@@ -49,23 +48,22 @@ export class BeatSaverService {
}
public async getMapDetailsById(id: string): Promise<BsvMapDetail> {
const res = await this.bsaverApi.getMapDetailsById(id);
return res.data;
return this.bsaverApi.getMapDetailsById(id);
}
public searchMaps(search: SearchParams): Promise<BsvMapDetail[]> {
return this.bsaverApi
.searchMaps(search)
.then(res => {
return res.status === 200 ? res.data.docs : [];
return res.docs;
})
.catch(() => {
.catch(e => {
log.error(e);
return [];
});
}
public async getPlaylistPage(id: string): Promise<BsvPlaylist> {
const res = await this.bsaverApi.getPlaylistDetails(id);
return res.data;
return this.bsaverApi.getPlaylistDetails(id);
}
}
@@ -1,8 +1,8 @@
import fetch from "node-fetch";
import { ApiResult } from "renderer/models/api/api.model";
import { MSGetQuery, MSGetQueryFilter, MSGetResponse } from "../../../../shared/models/models/model-saber.model";
import { RequestService } from "../../request.service";
export class ModelSaberApiService {
private static instance: ModelSaberApiService;
public static getInstance(): ModelSaberApiService {
@@ -15,7 +15,11 @@ export class ModelSaberApiService {
private readonly API_URL = "https://modelsaber.com/api/v2/";
private readonly ENDPOINTS = { get: "get.php", types: "types.php" };
private constructor() {}
private readonly request: RequestService;
private constructor() {
this.request = RequestService.getInstance();
}
private parseFilters(filters: MSGetQueryFilter[]): string {
if (!filters) {
@@ -50,19 +54,10 @@ export class ModelSaberApiService {
return new URLSearchParams(searchParams);
}
public async searchModel(query: MSGetQuery): Promise<ApiResult<MSGetResponse>> {
public async searchModel(query: MSGetQuery): Promise<MSGetResponse> {
const url = new URL(this.ENDPOINTS.get, this.API_URL);
url.search = this.buildUrlQuery(query).toString();
const res = await fetch(url.toString());
if (!res.ok) {
return { data: null, status: res.status };
}
const data = (await res.json()) as MSGetResponse;
return { data, status: res.status };
return this.request.getJSON<MSGetResponse>(url.toString());
}
}
@@ -33,15 +33,11 @@ export class ModelSaberService {
try {
const res = await this.modelSaberApi.searchModel(query);
if (res.status !== 200) {
if (Object.keys(res).length === 0) {
return null;
}
if (Object.keys(res.data).length === 0) {
return null;
}
return res.data[`${id}`];
return res[`${id}`];
} catch (e) {
log.error(e);
return null;
@@ -63,15 +59,11 @@ export class ModelSaberService {
try {
const res = await this.modelSaberApi.searchModel(query);
if (res.status !== 200) {
if (Object.keys(res).length === 0) {
return null;
}
if (Object.keys(res.data).length === 0) {
return null;
}
const model = Array.from(Object.values(res.data)).at(0);
const model = Array.from(Object.values(res)).at(0);
model.name = striptags(model.name ?? "");
model.author = striptags(model.author ?? "");
@@ -89,11 +81,9 @@ export class ModelSaberService {
return new Observable<MSModel[]>(observer => {
(async () => {
const res = await this.modelSaberApi.searchModel(query);
if (res.status !== 200) {
observer.error(res.status);
}
observer.next(
Object.values(res.data).map(model => {
Object.values(res).map(model => {
if (!model?.name) {
return null;
}
@@ -8,6 +8,7 @@ import { motion } from "framer-motion";
import { GlowEffect } from "../shared/glow-effect.component";
import equal from "fast-deep-equal";
import { SteamIcon } from "../svgs/icons/steam-icon.component";
import { useConstant } from "renderer/hooks/use-constant.hook";
type Props = {
version: BSVersion;
@@ -17,15 +18,17 @@ type Props = {
export const AvailableVersionItem = memo(function AvailableVersionItem({version, selected, onClick}: Props) {
const [hovered, setHovered] = useState(false);
const t = useTranslation();
const formatedDate = (() => dateFormat(+version.ReleaseDate * 1000, "ddd. d mmm yyyy"))();
const [hovered, setHovered] = useState(false);
const formatedDate = useConstant(() => dateFormat(+version.ReleaseDate * 1000, "ddd. d mmm yyyy"));
return (
<motion.li className="group relative w-72 h-60 transition-transform active:scale-[.98]" onClick={onClick} onHoverStart={() => setHovered(true)} onHoverEnd={() => setHovered(false)}>
<motion.li className="group relative w-72 h-60 active:scale-[.98]" onClick={onClick} onHoverStart={() => setHovered(true)} onHoverEnd={() => setHovered(false)}>
<GlowEffect visible={hovered || selected} className="absolute" />
<div className={`relative flex flex-col overflow-hidden rounded-md w-72 h-60 cursor-pointer group-hover:shadow-none duration-300 bg-light-main-color-2 dark:bg-main-color-2 ${!selected && "shadow-lg shadow-gray-900"}`}>
{version.recommended && (
<span className="uppercase absolute -rotate-45 top-9 -left-[6.2rem] font-bold text-white bg-red-600 w-full text-center text-xs z-[1] shadow-sm shadow-black py-0.5" title={t("pages.available-versions.recommended-tooltip")}>{t("pages.available-versions.recommended")}</span>
)}
<BsmImage image={version.ReleaseImg ? version.ReleaseImg : defaultImage} errorImage={defaultImage} placeholder={defaultImage} className="absolute top-0 right-0 w-full h-full opacity-40 blur-xl object-cover" loading="lazy" />
<BsmImage image={version.ReleaseImg ? version.ReleaseImg : defaultImage} errorImage={defaultImage} placeholder={defaultImage} className="bg-black w-full h-3/4 object-cover" loading="lazy" />
<div className="z-[1] p-2 w-full flex items-center justify-between grow">
@@ -34,11 +37,7 @@ export const AvailableVersionItem = memo(function AvailableVersionItem({version,
<span className="text-sm text-gray-700 dark:text-gray-400">{formatedDate}</span>
</div>
{version.ReleaseURL && (
<a
href={version.ReleaseURL}
target="_blank"
className="flex flex-row justify-between items-center rounded-full bg-black bg-opacity-30 text-white pb-px hover:bg-opacity-50"
>
<a href={version.ReleaseURL} target="_blank" className="flex flex-row justify-between items-center rounded-full bg-black bg-opacity-30 text-white pb-px overflow-hidden hover:bg-opacity-50">
<SteamIcon className="w-[25px] h-[25px] transition-transform group-hover:rotate-[-360deg] duration-300" />
<span className="relative -left-px text-sm w-fit max-w-0 text-center overflow-hidden h-full whitespace-nowrap pb-[3px] transition-all group-hover:max-w-[200px] group-hover:px-1 duration-300">{t("pages.available-versions.steam-release")}</span>
</a>
@@ -84,7 +84,7 @@ export function FilterPanel({ className, ref, playlist = false, filter, onChange
};
const renderLabel = (text: string | number, isMax: boolean): JSX.Element => {
return <span className={`bg-inherit absolute top-[calc(100%+4px)] h-5 font-bold rounded-md shadow-center shadow-black px-1 flex items-center ${isMax ? "text-lg" : "text-sm"}`}>{text}</span>;
return <span className={`bg-inherit absolute top-[calc(100%+4px)] whitespace-nowrap h-5 font-bold rounded-md shadow-center shadow-black px-1 flex items-center ${isMax ? "text-lg" : "text-sm"}`}>{text}</span>;
};
const onNpssChange = ([min, max]: number[]) => {
@@ -153,7 +153,7 @@ export function MapsPlaylistsPanel({ version, isActive }: Props) {
<div className="h-full rounded-full bg-light-main-color-2 dark:bg-main-color-2 grow p-[6px]">
<input type="text" className="h-full w-full bg-light-main-color-1 dark:bg-main-color-1 rounded-full px-2" placeholder={t("pages.version-viewer.maps.search-bar.search-placeholder")} value={tabIndex === 0 ? mapSearch : playlistSearch} onChange={e => handleSearch(e.target.value)} tabIndex={-1} />
</div>
<BsmDropdownButton className="h-full relative z-[1] flex justify-center" buttonClassName="flex items-center justify-center h-full rounded-full px-2 py-1" icon="filter" text="pages.version-viewer.maps.search-bar.filters-btn" withBar={false}>
<BsmDropdownButton className="h-full relative z-[1] flex justify-center" buttonClassName="flex items-center justify-center h-full rounded-full px-2 py-1" icon="filter" text="pages.version-viewer.maps.search-bar.filters-btn" textClassName="whitespace-nowrap" withBar={false}>
<FilterPanel className="absolute top-[calc(100%+3px)] origin-top w-[500px] h-fit p-2 rounded-md shadow-md shadow-black" filter={mapFilter} onChange={setMapFilter} />
</BsmDropdownButton>
<BsmDropdownButton className="h-full flex aspect-square relative rounded-full z-[1] bg-light-main-color-1 dark:bg-main-color-3" buttonClassName="rounded-full h-full w-full p-[6px]" icon="three-dots" withBar={false} items={dropDownItems} menuTranslationY="6px" align="center" />
@@ -1,7 +1,7 @@
import { BSVersion } from "shared/bs-version.interface";
import { Link, useLocation } from "react-router-dom";
import { useState } from "react";
import { distinctUntilChanged, lastValueFrom, map, of, Subscription, switchMap } from "rxjs";
import { distinctUntilChanged, lastValueFrom, map, of, Subscription, switchMap, take } from "rxjs";
import { BSLauncherService, LaunchMods } from "renderer/services/bs-launcher.service";
import { ConfigurationService } from "renderer/services/configuration.service";
import { BSUninstallerService } from "renderer/services/bs-uninstaller.service";
@@ -55,7 +55,9 @@ export function BsVersionItem(props: { version: BSVersion }) {
return props.version?.BSVersion === state?.BSVersion && props?.version.steam === state?.steam && props?.version.oculus === state?.oculus && props?.version.name === state?.name;
};
const handleDoubleClick = () => {
const handleDoubleClick = async () => {
const downloadingVersion = await lastValueFrom(bsDownloader.downloadingVersion$.pipe(take(1)));
if(equal(downloadingVersion, props.version)){ return; }
const launch$ = launcherService.launch({
version: state,
oculus: !!configService.get<boolean>(LaunchMods.OCULUS_MOD),
@@ -38,7 +38,7 @@ export function NavBar() {
return (
<nav id="nav-bar" className="z-10 flex flex-col h-full max-h-full items-center p-1">
<BsManagerIcon className="relative aspect-square w-16 h-16 mb-3" />
<ol id="versions" className="w-fit max-w-[120px] relative left-[2px] grow overflow-y-hidden scrollbar-track-transparent scrollbar-thin scrollbar-thumb-rounded-full scrollbar-thumb-neutral-900 hover:overflow-y-scroll">
<ol id="versions" className="w-fit max-w-[150px] relative left-[2px] grow overflow-y-hidden scrollbar-track-transparent scrollbar-thin scrollbar-thumb-rounded-full scrollbar-thumb-neutral-900 hover:overflow-y-scroll">
<SharedNavBarItem />
<NavBarSpliter />
{listVersions().map(version => (
@@ -21,9 +21,10 @@ type Props = {
menuTranslationY?: string | number;
children?: JSX.Element;
text?: string;
textClassName?: string;
};
export const BsmDropdownButton = forwardRef(({ className, items, align, withBar = true, icon = "settings", buttonClassName, menuTranslationY, children, text }: Props, fowardRed) => {
export const BsmDropdownButton = forwardRef(({ className, items, align, withBar = true, icon = "settings", buttonClassName, menuTranslationY, children, text, textClassName }: Props, fowardRed) => {
const [expanded, setExpanded] = useState(false);
const t = useTranslation();
const ref = useRef(fowardRed);
@@ -63,7 +64,7 @@ export const BsmDropdownButton = forwardRef(({ className, items, align, withBar
return (
<div ref={ref as unknown as React.LegacyRef<HTMLDivElement>} className={className}>
<BsmButton onClick={() => setExpanded(!expanded)} className={buttonClassName ?? defaultButtonClassName} icon={icon} active={expanded} onClickOutside={handleClickOutside} withBar={withBar} text={text} />
<BsmButton onClick={() => setExpanded(!expanded)} className={buttonClassName ?? defaultButtonClassName} icon={icon} active={expanded} textClassName={textClassName} onClickOutside={handleClickOutside} withBar={withBar} text={text} />
<div className={`py-1 w-fit absolute cursor-pointer top-[calc(100%-4px)] rounded-md bg-inherit text-sm text-gray-800 dark:text-gray-200 shadow-md shadow-black transition-[scale] ease-in-out ${alignClass}`} style={{ scale: expanded ? "1" : "0", translate: `0 ${menuTranslationY}` }}>
{items?.map(
i =>
@@ -53,6 +53,8 @@ import { VolumeOffIcon } from "./icons/volume-off-icon.component";
import { VolumeDownIcon } from "./icons/volume-down-icon.component";
import { GermanIcon } from "./flags/german-icon.component";
import { RussianIcon } from "./flags/russian-icon.component";
import { ChineseIcon } from "./flags/chinese-icon.component";
import { JapanIcon } from "./flags/japan-icon.component";
import { MSModelType } from "shared/models/models/model-saber.model";
import { ModelTypeAvatarIcon } from "./icons/model-type-avatar-icon.component";
import { ModelTypeSaberIcon } from "./icons/model-type-saber-icon.component";
@@ -63,7 +65,7 @@ import { EyeCrossIcon } from "./icons/eye-cross-icon.component";
import { ShortcutIcon } from "./icons/shortcut-icon.component";
import { BackupRestoreIcon } from "./icons/backup-restore-icon.component";
export type BsmIconType = BsvMapCharacteristic | MSModelType | ("settings" | "trash" | "favorite" | "folder" | "bsNote" | "check" | "three-dots" | "twitch" | "eye" | "play" | "checkCircleIcon" | "discord" | "info" | "eye-cross" | "terminal" | "desktop" | "oculus" | "add" | "cross" | "task" | "github" | "close" | "thumbUpFill" | "timerFill" | "pause" | "twitter" | "sync" | "chevron-top" | "copy" | "steam" | "edit" | "export" | "patreon" | "search" | "bsMapDifficulty" | "link" | "unlink" | "download" | "filter" | "mee6" | "volume-up" | "volume-off" | "volume-down" | "shortcut" | "backup-restore" | "fr-FR-flag" | "es-ES-flag" | "en-US-flag" | "en-EN-flag" | "de-DE-flag" | "ru-RU-flag");
export type BsmIconType = BsvMapCharacteristic | MSModelType | ("settings" | "trash" | "favorite" | "folder" | "bsNote" | "check" | "three-dots" | "twitch" | "eye" | "play" | "checkCircleIcon" | "discord" | "info" | "eye-cross" | "terminal" | "desktop" | "oculus" | "add" | "cross" | "task" | "github" | "close" | "thumbUpFill" | "timerFill" | "pause" | "twitter" | "sync" | "chevron-top" | "copy" | "steam" | "edit" | "export" | "patreon" | "search" | "bsMapDifficulty" | "link" | "unlink" | "download" | "filter" | "mee6" | "volume-up" | "volume-off" | "volume-down" | "shortcut" | "backup-restore" | "fr-FR-flag" | "es-ES-flag" | "en-US-flag" | "en-EN-flag" | "de-DE-flag" | "ru-RU-flag" | "zh-CN-flag" | "ja-JP-flag");
export const BsmIcon = memo(({ className, icon, style }: { className?: string; icon: BsmIconType; style?: CSSProperties }) => {
// TODO : Very ugly very messy, need to find a better way to do this
@@ -117,6 +119,12 @@ export const BsmIcon = memo(({ className, icon, style }: { className?: string; i
if (icon === "ru-RU-flag") {
return <RussianIcon className={className} style={style} />;
}
if (icon === "zh-CN-flag") {
return <ChineseIcon className={className} style={style} />;
}
if (icon === "ja-JP-flag") {
return <JapanIcon className={className} style={style} />;
}
if (icon === "task") {
return <TaskIcon className={className} style={style} />;
}
@@ -0,0 +1,21 @@
import { CSSProperties } from "react";
export function ChineseIcon(props: { className?: string; style?: CSSProperties }) {
return (
<svg width="71px" height="48px" viewBox="0 0 71 48" version="1.1" xmlns="http://www.w3.org/2000/svg" className={props.className} style={props.style}>
<defs />
<g id="Flags" stroke="none" strokeWidth="1" fill="none" fillRule="evenodd" transform="translate(-70.000000, -498.000000)">
<g transform="translate(70.000000, 70.000000)" fillRule="nonzero" id="China">
<g transform="translate(0.000000, 428.000000)">
<rect id="Rounded_Rectangle_7_copy-5" fill="#ED5565" x="0.28" y="0.98" width="70" height="47" rx="6.36" />
<path d="M12.23,26.34 C11.41,26.93 10.93,26.6 11.16,25.61 L12.05,21.93 C12.2430284,20.8254147 11.8671738,19.6978512 11.05,18.93 L8.36,16.6 C7.59,15.94 7.79,15.37 8.8,15.34 L12.57,15.23 C13.6782653,15.1750168 14.6410409,14.4499636 15,13.4 L16.18,9.4 C16.47,8.4 16.98,8.4 17.32,9.4 L18.74,13.4 C19.1553515,14.4093082 20.1106424,15.0927684 21.2,15.16 L25.04,15.16 C26.04,15.16 26.25,15.73 25.49,16.39 L22.56,18.95 C21.7650096,19.7288598 21.4350484,20.866657 21.69,21.95 L22.62,25.19 C22.9,26.19 22.43,26.53 21.57,26 L18.42,24 C17.4584774,23.4711751 16.2849442,23.5095258 15.36,24.1 L12.23,26.34 Z" id="Shape_2_copy_9" fill="#F6D660"/>
<path d="M29.37,10.78 C29.09,10.98 28.93,10.87 29.01,10.52 L29.31,9.24 C29.3656763,8.87495864 29.2472583,8.50490228 28.99,8.24 L28.08,7.43 C27.82,7.2 27.89,7 28.23,6.99 L29.5,6.99 C29.8717689,6.9586152 30.1877729,6.70581199 30.3,6.35 L30.7,4.95 C30.8,4.61 30.97,4.61 31.09,4.95 L31.57,6.33 C31.7126147,6.67114428 32.031835,6.90575195 32.4,6.94 L33.7,6.94 C34.04,6.94 34.11,7.14 33.85,7.37 L32.85,8.26 C32.5912527,8.52348971 32.4790218,8.89759264 32.55,9.26 L32.87,10.39 C32.97,10.73 32.81,10.86 32.52,10.67 L31.46,10 C31.1505989,9.82136721 30.7694011,9.82136721 30.46,10 L29.37,10.78 Z" id="Shape_2_copy_10" fill="#F6D660"/>
<path d="M29.37,30.53 C29.09,30.73 28.93,30.62 29.01,30.27 L29.31,28.99 C29.3656763,28.6249586 29.2472583,28.2549023 28.99,27.99 L28.08,27.18 C27.82,26.95 27.89,26.75 28.23,26.74 L29.5,26.74 C29.8691682,26.7101752 30.1844554,26.4618866 30.3,26.11 L30.7,24.71 C30.8,24.37 30.97,24.37 31.09,24.71 L31.57,26.09 C31.7126147,26.4311443 32.031835,26.6657519 32.4,26.7 L33.7,26.7 C34.04,26.7 34.11,26.9 33.85,27.13 L32.85,28.02 C32.5912527,28.2834897 32.4790218,28.6575926 32.55,29.02 L32.87,30.15 C32.97,30.49 32.81,30.62 32.52,30.43 L31.47,29.76 C31.1605989,29.5813672 30.7794011,29.5813672 30.47,29.76 L29.37,30.53 Z" id="Shape_2_copy_11" fill="#F6D660"/>
<path d="M36.3,25.23 C36.02,25.43 35.86,25.32 35.94,24.98 L36.24,23.7 C36.2956763,23.3349586 36.1772583,22.9649023 35.92,22.7 L35.01,21.89 C34.75,21.66 34.82,21.46 35.16,21.45 L36.43,21.45 C36.7991682,21.4201752 37.1144554,21.1718866 37.23,20.82 L37.63,19.42 C37.73,19.08 37.9,19.08 38.02,19.42 L38.5,20.8 C38.6426147,21.1411443 38.961835,21.3757519 39.33,21.41 L40.63,21.41 C40.97,21.41 41.04,21.61 40.78,21.84 L39.78,22.73 C39.5248508,22.9954093 39.4164332,23.369263 39.49,23.73 L39.81,24.86 C39.91,25.2 39.74,25.33 39.46,25.14 L38.41,24.47 C38.1005989,24.2913672 37.7194011,24.2913672 37.41,24.47 L36.3,25.23 Z" id="Shape_2_copy_12" fill="#F6D660"/>
<path d="M36.3,16.09 C36.02,16.29 35.86,16.18 35.94,15.83 L36.24,14.55 C36.2956763,14.1849586 36.1772583,13.8149023 35.92,13.55 L35,12.7 C34.74,12.47 34.81,12.27 35.15,12.26 L36.42,12.26 C36.7891682,12.2301752 37.1044554,11.9818866 37.22,11.63 L37.62,10.23 C37.72,9.89 37.89,9.89 38.01,10.23 L38.49,11.61 C38.6326147,11.9511443 38.951835,12.1857519 39.32,12.22 L40.62,12.22 C40.96,12.22 41.03,12.42 40.77,12.65 L39.77,13.54 C39.5163739,13.8062871 39.4081897,14.1793363 39.48,14.54 L39.8,15.67 C39.9,16.01 39.73,16.14 39.45,15.95 L38.4,15.28 C38.0905989,15.1013672 37.7094011,15.1013672 37.4,15.28 L36.3,16.09 Z" id="Shape_2_copy_13" fill="#F6D660"/>
</g>
</g>
</g>
</svg>
);
}
@@ -0,0 +1,22 @@
import { CSSProperties } from "react";
export function JapanIcon(props: { className?: string; style?: CSSProperties }) {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="71px" height="48px" viewBox="0 0 71 48" version="1.1" className={props.className} style={props.style}>
<defs />
<g id="Flags" stroke="none" strokeWidth="1" fill="none" fillRule="evenodd" transform="translate(-239,-805)">
<g transform="translate(70,70)" fillRule="nonzero" id="Russian">
<g transform="translate(169,735)">
<g id="Bolivia-9">
<path d="M 0.5 7 L 0.5 41 L 70.5 41 L 70.5 7 C 70.5 3.3 67.5 0.4 63.9 0.4 L 7.2 0.4 C 5.4 0.4 3.7 1.1 2.5 2.3 C 1.2 3.5 0.5 5.2 0.5 7 Z" id="Shape" fill="#ffffff" /> <polygon id="Shape" fill="#fff" points="0.5,33.0 70.5,33.0 70.5,15.0 0.5,15.0" />
<path d="M 0.5 40.8 C 0.5 44.4 3.5 47.4 7.2 47.4 L 63.9 47.4 C 67.5 47.4 70.5 44.4 70.5 40.8 L 70.5 31.8 L 0.5 31.8 L 0.5 40.8 Z" id="Shape" fill="#ffffff" />
<circle cx="35.5" cy="24" r="15" fill="#ec5565" />
</g>
</g>
</g>
</g>
</svg>
);
}
export default JapanIcon;
@@ -12,6 +12,8 @@ import { BsmImage } from "renderer/components/shared/bsm-image.component";
import { useService } from "renderer/hooks/use-service.hook";
import { BsStore } from "shared/models/bs-store.enum";
import { lastValueFrom } from "rxjs";
import { BsDownloaderService } from "renderer/services/bs-version-download/bs-downloader.service";
import equal from "fast-deep-equal";
type Props = { version: BSVersion };
@@ -20,12 +22,14 @@ export function LaunchSlide({ version }: Props) {
const configService = useService(ConfigurationService);
const bsLauncherService = useService(BSLauncherService);
const bsDownloader = useService(BsDownloaderService);
const [oculusMode, setOculusMode] = useState(!!configService.get<boolean>(LaunchMods.OCULUS_MOD));
const [desktopMode, setDesktopMode] = useState(!!configService.get<boolean>(LaunchMods.DESKTOP_MOD));
const [debugMode, setDebugMode] = useState(!!configService.get<boolean>(LaunchMods.DEBUG_MOD));
const [advancedLaunch, setAdvancedLaunch] = useState(false);
const [additionalArgsString, setAdditionalArgsString] = useState<string>(configService.get<string>("additionnal-args") || "");
const versionDownloading = useObservable(bsDownloader.downloadingVersion$);
const versionRunning = useObservable(bsLauncherService.versionRunning$);
@@ -96,7 +100,13 @@ export function LaunchSlide({ version }: Props) {
</motion.div>
</div>
<div className='grow flex justify-center items-center'>
<BsmButton onClick={launch} active={JSON.stringify(version) === JSON.stringify(versionRunning)} className='relative -translate-y-1/2 text-5xl text-gray-800 dark:text-gray-200 font-bold tracking-wide pt-1 pb-3 px-7 rounded-lg shadow-md italic shadow-black active:scale-90 transition-transform' text="misc.launch"/>
<BsmButton
onClick={launch}
active={JSON.stringify(version) === JSON.stringify(versionRunning)}
className='relative -translate-y-1/2 text-5xl text-gray-800 dark:text-gray-200 font-bold tracking-wide pt-1 pb-3 px-7 rounded-lg shadow-md italic shadow-black active:scale-90 transition-transform'
text="misc.launch"
disabled={equal(version, versionDownloading)}
/>
</div>
</div>
);
@@ -65,10 +65,10 @@ export function ModsGrid({ modsMap, installed, modsSelected, onModChange, moreIn
<span className="z-10 sticky flex items-center justify-end top-0 bg-inherit border-b-2 border-main-color-1">
<BsmButton className="rounded-full h-6 w-6 p-[2px]" withBar={false} icon="search" onClick={handleToogleFilter} />
</span>
<span className="z-10 sticky top-0 flex items-center bg-inherit border-main-color-1 border-b-2 h-8 px-1">{filterEnabled ? <motion.input autoFocus className="bg-main-color-1 rounded-md h-6 px-2" initial={{ width: 0 }} animate={{ width: "250px" }} transition={{ ease: "easeInOut", duration: 0.15 }} onChange={e => handleInput(e.target.value)} /> : <span className="w-full text-center">{t("pages.version-viewer.mods.mods-grid.header-bar.name")}</span>}</span>
<span className="z-10 sticky flex items-center justify-center top-0 bg-inherit border-b-2 border-main-color-1 h-8 px-2">{t("pages.version-viewer.mods.mods-grid.header-bar.installed")}</span>
<span className="z-10 sticky flex items-center justify-center top-0 bg-inherit border-b-2 border-main-color-1 h-8 px-2">{t("pages.version-viewer.mods.mods-grid.header-bar.latest")}</span>
<span className="z-10 sticky flex items-center justify-center top-0 bg-inherit border-b-2 border-main-color-1 h-8">{t("pages.version-viewer.mods.mods-grid.header-bar.description")}</span>
<span className="z-10 sticky top-0 flex items-center bg-inherit border-main-color-1 border-b-2 h-8 px-1 whitespace-nowrap">{filterEnabled ? <motion.input autoFocus className="bg-main-color-1 rounded-md h-6 px-2" initial={{ width: 0 }} animate={{ width: "250px" }} transition={{ ease: "easeInOut", duration: 0.15 }} onChange={e => handleInput(e.target.value)} /> : <span className="w-full text-center">{t("pages.version-viewer.mods.mods-grid.header-bar.name")}</span>}</span>
<span className="z-10 sticky flex items-center justify-center top-0 bg-inherit border-b-2 border-main-color-1 h-8 px-2 whitespace-nowrap">{t("pages.version-viewer.mods.mods-grid.header-bar.installed")}</span>
<span className="z-10 sticky flex items-center justify-center top-0 bg-inherit border-b-2 border-main-color-1 h-8 px-2 whitespace-nowrap">{t("pages.version-viewer.mods.mods-grid.header-bar.latest")}</span>
<span className="z-10 sticky flex items-center justify-center top-0 bg-inherit border-b-2 border-main-color-1 h-8 whitespace-nowrap">{t("pages.version-viewer.mods.mods-grid.header-bar.description")}</span>
<span className="z-10 sticky top-0 bg-inherit border-b-2 border-main-color-1 h-8 flex justify-start items-center py-1 pl-[3px] min-w-[50px]">
<BsmDropdownButton className="h-full aspect-square relative rounded-full bg-light-main-color-1 dark:bg-main-color-3" withBar={false} icon="three-dots" buttonClassName="!rounded-full !p-[2px] !bg-light-main-color-2 dark:!bg-main-color-2 hover:!bg-light-main-color-1 dark:hover:!bg-main-color-3" menuTranslationY="5px" items={[{ text: "pages.version-viewer.mods.mods-grid.header-bar.dropdown.uninstall-all", icon: "trash", onClick: handleUninstallAll }]} />
</span>
@@ -3,7 +3,7 @@ export const defaultConfiguration: { [key in DefaultConfigKey]: any } = {
"second-color": "#ff4444",
theme: "os",
language: window.navigator.language.length <= 2 ? `${window.navigator.language}-${window.navigator.language.toLocaleUpperCase()}` : window.navigator.language,
supported_languages: ["en-US", "en-EN", "fr-FR", "es-ES", "de-DE", "ru-RU"],
supported_languages: ["en-US", "en-EN", "fr-FR", "es-ES", "de-DE", "ru-RU", "zh-CN", "ja-JP"],
default_mods: ["SongCore", "WhyIsThereNoLeaderboard", "BeatSaverDownloader", "BeatSaverVoting", "PlaylistManager"],
"default-shared-folders": [
window.electron.path.join("Beat Saber_Data", "CustomLevels"),
@@ -58,7 +58,7 @@ export class SteamDownloaderService extends AbstractBsDownloaderService implemen
duration: 11_000,
title: "notifications.bs-download.steam-download.errors.titles.dotnet-required",
desc: "notifications.bs-download.steam-download.errors.msg.dotnet-required",
actions: [{ id: "0", title: "notifications.bs-download..errors.actions.download-dotnet" }],
actions: [{ id: "0", title: "notifications.bs-download.steam-download.errors.actions.download-dotnet" }],
});
if (choice === "0") {
+1
View File
@@ -17,6 +17,7 @@ export interface BSVersion extends PartialBSVersion {
color?: string; // TODO : Should be in metadata
OculusBinaryId?: string;
metadata?: BSVersionMetadata;
recommended?: boolean;
}
export interface BSVersionMetadata {