<>
{l10n
- .getString('settings-osc-vrchat-description-v1')
+ .getString('settings-osc-vrchat-description-v2')
.split('\n')
+ .concat(
+ l10n
+ .getString('settings-osc-vrchat-description-guide')
+ .split('\n')
+ )
.map((line, i) => (
{line}
diff --git a/gui/src/components/tracker/TrackerCard.tsx b/gui/src/components/tracker/TrackerCard.tsx
index b8350f4763..38a4c7f6c0 100644
--- a/gui/src/components/tracker/TrackerCard.tsx
+++ b/gui/src/components/tracker/TrackerCard.tsx
@@ -45,6 +45,7 @@ function TrackerBig({
<>
{device.hardwareStatus.batteryPctEstimate && (
@@ -93,6 +94,7 @@ function TrackerSmol({
{device.hardwareStatus.batteryPctEstimate && (
diff --git a/gui/src/index.scss b/gui/src/index.scss
index 6bbdd88762..88b094d10f 100644
--- a/gui/src/index.scss
+++ b/gui/src/index.scss
@@ -17,6 +17,12 @@ body {
}
@media (-webkit-animation) {
+ img.uncrisp {
+ // Webkit moment https://stackoverflow.com/questions/7908168/image-resize-gives-slight-brief-pixelation-in-webkit-browsers
+ // doesn't happen in newer versions, weird.
+ -webkit-transform: translate3d(0, 0, 0);
+ }
+
body {
font-family: var(--font-name), 'Noto Sans CJK', sans-serif, 'Twemoji Webkit',
emoji;
diff --git a/gui/src/utils/tauri.ts b/gui/src/utils/tauri.ts
index ab9905ed01..9028a3e289 100644
--- a/gui/src/utils/tauri.ts
+++ b/gui/src/utils/tauri.ts
@@ -14,6 +14,7 @@ export async function fetchResourceUrl(url: string) {
// FIXME: For some fucking reason, you can't top-level await on a react component file
// on Chromium on developments builds specifically -Uriel
export const AUTOBONE_VIDEO = await fetchResourceUrl('/videos/autobone.webm');
+export const VRCHAT_OSC_VIDEO = await fetchResourceUrl('/videos/vrchatosc.webm');
export const isTrayAvailable =
isTauri() && (await invoke('is_tray_available'));
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 6162293dfb..786a9a5635 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -228,6 +228,9 @@ importers:
tailwindcss:
specifier: ^3.4.13
version: 3.4.14(ts-node@9.1.1(typescript@5.6.3))
+ ts-xor:
+ specifier: ^1.3.0
+ version: 1.3.0
typescript-eslint:
specifier: ^8.8.0
version: 8.8.0(eslint@8.57.1)(typescript@5.6.3)
@@ -2052,27 +2055,6 @@ packages:
eslint-import-resolver-webpack:
optional: true
- eslint-module-utils@2.8.1:
- resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==}
- engines: {node: '>=4'}
- peerDependencies:
- '@typescript-eslint/parser': '*'
- eslint: '*'
- eslint-import-resolver-node: '*'
- eslint-import-resolver-typescript: '*'
- eslint-import-resolver-webpack: '*'
- peerDependenciesMeta:
- '@typescript-eslint/parser':
- optional: true
- eslint:
- optional: true
- eslint-import-resolver-node:
- optional: true
- eslint-import-resolver-typescript:
- optional: true
- eslint-import-resolver-webpack:
- optional: true
-
eslint-plugin-import@2.31.0:
resolution: {integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==}
engines: {node: '>=4'}
@@ -3965,6 +3947,9 @@ packages:
ts-pattern@5.5.0:
resolution: {integrity: sha512-jqbIpTsa/KKTJYWgPNsFNbLVpwCgzXfFJ1ukNn4I8hMwyQzHMJnk/BqWzggB0xpkILuKzaO/aMYhS0SkaJyKXg==}
+ ts-xor@1.3.0:
+ resolution: {integrity: sha512-RLXVjliCzc1gfKQFLRpfeD0rrWmjnSTgj7+RFhoq3KRkUYa8LE/TIidYOzM5h+IdFBDSjjSgk9Lto9sdMfDFEA==}
+
tsconfig-paths@3.15.0:
resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==}
@@ -6229,7 +6214,7 @@ snapshots:
debug: 4.3.5
enhanced-resolve: 5.17.0
eslint: 8.57.1
- eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
+ eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
fast-glob: 3.3.2
get-tsconfig: 4.7.5
is-bun-module: 1.2.1
@@ -6253,16 +6238,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- eslint-module-utils@2.8.1(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1):
- dependencies:
- debug: 3.2.7
- optionalDependencies:
- '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.6.3)
- eslint: 8.57.1
- eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1)
- transitivePeerDependencies:
- - supports-color
-
eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1):
dependencies:
'@rtsao/scc': 1.1.0
@@ -8558,6 +8533,8 @@ snapshots:
ts-pattern@5.5.0: {}
+ ts-xor@1.3.0: {}
+
tsconfig-paths@3.15.0:
dependencies:
'@types/json5': 0.0.29
diff --git a/server/core/src/main/java/dev/slimevr/status/StatusSystem.kt b/server/core/src/main/java/dev/slimevr/status/StatusSystem.kt
index d7723a4500..fe590b6be8 100644
--- a/server/core/src/main/java/dev/slimevr/status/StatusSystem.kt
+++ b/server/core/src/main/java/dev/slimevr/status/StatusSystem.kt
@@ -2,13 +2,14 @@ package dev.slimevr.status
import solarxr_protocol.rpc.StatusDataUnion
import solarxr_protocol.rpc.StatusMessageT
+import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.atomic.AtomicInteger
class StatusSystem {
private val listeners: MutableList = CopyOnWriteArrayList()
- private val statuses: MutableMap = HashMap()
- private val prioritizedStatuses: MutableSet = HashSet()
+ private val statuses: MutableMap = ConcurrentHashMap()
+ private val prioritizedStatuses: MutableSet = ConcurrentHashMap.newKeySet()
private val idCounter = AtomicInteger(1)
fun addListener(listener: StatusListener) {