Compare commits

...

7 Commits

Author SHA1 Message Date
Uriel
a2bbe7097c Forgot the other task for git force (#861) 2023-09-29 22:56:41 +03:00
Uriel
415a07461e Force git tag fetching (#860) 2023-09-29 21:55:27 +03:00
Uriel
4bd31fb02f Only get first tag on build (#859) 2023-09-28 20:19:27 -04:00
Uriel
2bc50b2bc2 Add preload component (#854) 2023-09-26 07:42:34 -04:00
imgbot[bot]
e37b11844f [ImgBot] Optimize images (#838) 2023-09-25 18:39:08 -04:00
Butterscotch!
92f709e2f9 Track connection by socket address if HWID is unavailable (#851) 2023-09-25 00:45:29 -04:00
Butterscotch!
7fe3d82540 Fix NPE when tracking arms from controllers (#853) 2023-09-25 00:11:42 -04:00
16 changed files with 154 additions and 79 deletions

View File

@@ -23,7 +23,7 @@ jobs:
with:
submodules: recursive
- name: Get tags
run: git fetch --tags origin --recurse-submodules=no
run: git fetch --tags origin --recurse-submodules=no --force
- name: Set up JDK 17
uses: actions/setup-java@v3
@@ -52,7 +52,7 @@ jobs:
with:
submodules: recursive
- name: Get tags
run: git fetch --tags origin --recurse-submodules=no
run: git fetch --tags origin --recurse-submodules=no --force
- name: Set up JDK 17
uses: actions/setup-java@v3

View File

@@ -31,6 +31,7 @@
"react": "^18.0.0",
"react-dev-utils": "^12.0.0",
"react-dom": "^18.0.0",
"react-helmet": "^6.1.0",
"react-hook-form": "^7.29.0",
"react-modal": "3.15.1",
"react-responsive": "^9.0.2",
@@ -77,6 +78,7 @@
"@types/file-saver": "^2.0.5",
"@types/react": "18.0.25",
"@types/react-dom": "^18.0.5",
"@types/react-helmet": "^6.1.6",
"@types/react-modal": "3.13.1",
"@types/three": "^0.148.0",
"@typescript-eslint/eslint-plugin": "^5.60.1",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 218 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

@@ -1,5 +1 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg clip-rule="evenodd" fill-rule="evenodd" stroke-miterlimit="10" version="1.1" viewBox="0 0 380 380" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
<style>svg { background-color: #663499; }</style>
<rect id="bg" width="100%" height="100%" fill="#663499"/><g id="logo" fill="none" stroke="#fff"><path id="left" d="m72.867 191.74 37-39 39 36" stroke-width="13.62px"/><path id="right" d="m208.87 187.74 38-35 36 38" stroke-width="13.62px"/><path id="outer" d="m56.867 253.74s130.61-31.182 248 5c13.45 4.146 20.244 2.975 20-8s1.909-126.06-46-131" stroke-linecap="square" stroke-width="17px"/></g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" stroke-miterlimit="10" clip-rule="evenodd" version="1.1" viewBox="0 0 380 380" xml:space="preserve"><style>svg{background-color:#663499}</style><rect id="bg" width="100%" height="100%" fill="#663499"/><g id="logo" fill="none" stroke="#fff"><path id="left" stroke-width="13.62" d="m72.867 191.74 37-39 39 36"/><path id="right" stroke-width="13.62" d="m208.87 187.74 38-35 36 38"/><path id="outer" stroke-linecap="square" stroke-width="17" d="m56.867 253.74s130.61-31.182 248 5c13.45 4.146 20.244 2.975 20-8s1.909-126.06-46-131"/></g></svg>

Before

Width:  |  Height:  |  Size: 660 B

After

Width:  |  Height:  |  Size: 598 B

View File

@@ -52,6 +52,7 @@ import { VRModePage } from './components/vr-mode/VRModePage';
import { InterfaceSettings } from './components/settings/pages/InterfaceSettings';
import { error, log } from './utils/logging';
import { AppLayout } from './AppLayout';
import { Preload } from './components/Preload';
export const GH_REPO = 'SlimeVR/SlimeVR-Server';
export const VersionContext = createContext('');
@@ -252,6 +253,7 @@ export default function App() {
<StatusProvider>
<VersionContext.Provider value={updateFound}>
<div className="h-full w-full text-standard bg-background-80 text-background-10">
<Preload />
<div className="flex-col h-full">
{!websocketAPI.isConnected && (
<>

View File

@@ -0,0 +1,48 @@
import { Helmet } from 'react-helmet';
export function Preload() {
return (
<Helmet>
<link rel="preload" href="/images/front-standing-pose.webp" as="image" />
<link rel="preload" href="/images/slime-girl.webp" as="image" />
<link rel="preload" href="/images/mounting-reset-pose.webp" as="image" />
<link rel="preload" href="/images/reset-pose.webp" as="image" />
<link rel="preload" href="/images/slimes.webp" as="image" />
<link
rel="preload"
href="/sounds/quick-reset-started-sound.mp3"
as="audio"
/>
<link
rel="preload"
href="/sounds/full-reset-started-sound.mp3"
as="audio"
/>
<link
rel="preload"
href="/sounds/mounting-reset-started-sound.mp3"
as="audio"
/>
<link rel="preload" href="/sounds/first-tap.mp3" as="audio" />
<link rel="preload" href="/sounds/second-tap.mp3" as="audio" />
<link rel="preload" href="/sounds/third-tap.mp3" as="audio" />
<link rel="preload" href="/sounds/fourth-tap.mp3" as="audio" />
<link rel="preload" href="/sounds/fifth-tap.mp3" as="audio" />
<link rel="preload" href="/sounds/end-tap.mp3" as="audio" />
<link rel="preload" href="/sounds/tapextrasetup.mp3" as="audio" />
<link
rel="preload"
href="/models/tracker.gltf"
as="fetch"
crossOrigin="anonymous"
/>
<link
rel="preload"
href="/models/extension.gltf"
as="fetch"
crossOrigin="anonymous"
/>
</Helmet>
);
}

View File

@@ -15,24 +15,6 @@ const tapSetupSound5 = new Audio('/sounds/fifth-tap.mp3');
const tapSetupSoundEnd = new Audio('/sounds/end-tap.mp3');
const tapSetupExtraSound = new Audio('/sounds/tapextrasetup.mp3');
const sounds = [
quickResetStartedSound,
fullResetStartedSound,
mountingResetStartedSound,
tapSetupSound1,
tapSetupSound2,
tapSetupSound3,
tapSetupSound4,
tapSetupSound5,
tapSetupSoundEnd,
tapSetupExtraSound,
];
sounds.forEach((s) => {
s.play();
setTimeout(() => s.pause(), 10);
});
function restartAndPlay(audio: HTMLAudioElement, volume: number) {
audio.volume = Math.min(1, Math.pow(volume, Math.E) + 0.05);
if (audio.paused) {

View File

@@ -1,11 +1,14 @@
import react from '@vitejs/plugin-react';
import { defineConfig, PluginOption } from 'vite';
import { execSync } from 'child_process';
import path from 'path'
import path from 'path';
import { visualizer } from 'rollup-plugin-visualizer';
const commitHash = execSync('git rev-parse --verify --short HEAD').toString().trim();
const versionTag = execSync('git --no-pager tag --points-at HEAD').toString().trim();
const versionTag = execSync('git --no-pager tag --sort -taggerdate --points-at HEAD')
.toString()
.split('\n')[0]
.trim();
// If not empty then it's not clean
const gitClean = execSync('git status --porcelain').toString() ? false : true;
@@ -51,7 +54,7 @@ export default defineConfig({
},
resolve: {
alias: {
'@': path.resolve(__dirname, 'src')
}
}
'@': path.resolve(__dirname, 'src'),
},
},
});

38
package-lock.json generated
View File

@@ -48,6 +48,7 @@
"react": "^18.0.0",
"react-dev-utils": "^12.0.0",
"react-dom": "^18.0.0",
"react-helmet": "^6.1.0",
"react-hook-form": "^7.29.0",
"react-modal": "3.15.1",
"react-responsive": "^9.0.2",
@@ -65,6 +66,7 @@
"@types/file-saver": "^2.0.5",
"@types/react": "18.0.25",
"@types/react-dom": "^18.0.5",
"@types/react-helmet": "^6.1.6",
"@types/react-modal": "3.13.1",
"@types/three": "^0.148.0",
"@typescript-eslint/eslint-plugin": "^5.60.1",
@@ -3394,6 +3396,15 @@
"@types/react": "*"
}
},
"node_modules/@types/react-helmet": {
"version": "6.1.6",
"resolved": "https://registry.npmjs.org/@types/react-helmet/-/react-helmet-6.1.6.tgz",
"integrity": "sha512-ZKcoOdW/Tg+kiUbkFCBtvDw0k3nD4HJ/h/B9yWxN4uDO8OkRksWTO+EL+z/Qu3aHTeTll3Ro0Cc/8UhwBCMG5A==",
"dev": true,
"dependencies": {
"@types/react": "*"
}
},
"node_modules/@types/react-modal": {
"version": "3.13.1",
"resolved": "https://registry.npmjs.org/@types/react-modal/-/react-modal-3.13.1.tgz",
@@ -9333,6 +9344,25 @@
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",
"integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg=="
},
"node_modules/react-fast-compare": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
"integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ=="
},
"node_modules/react-helmet": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-6.1.0.tgz",
"integrity": "sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==",
"dependencies": {
"object-assign": "^4.1.1",
"prop-types": "^15.7.2",
"react-fast-compare": "^3.1.1",
"react-side-effect": "^2.1.0"
},
"peerDependencies": {
"react": ">=16.3.0"
}
},
"node_modules/react-hook-form": {
"version": "7.45.4",
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.45.4.tgz",
@@ -9446,6 +9476,14 @@
"react-dom": ">=16.8"
}
},
"node_modules/react-side-effect": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-2.1.2.tgz",
"integrity": "sha512-PVjOcvVOyIILrYoyGEpDN3vmYNLdy1CajSFNt4TDsVQC5KpTijDvWVoR+/7Rz2xT978D8/ZtFceXxzsPwZEDvw==",
"peerDependencies": {
"react": "^16.3.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/react-use-measure": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.1.tgz",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -1071,8 +1071,8 @@ class HumanSkeleton(
BoneType.RIGHT_FOOT_TRACKER -> trackerRightFootNode
BoneType.LEFT_SHOULDER -> leftShoulderTailNode
BoneType.RIGHT_SHOULDER -> rightShoulderTailNode
BoneType.LEFT_UPPER_ARM -> if (!isTrackingLeftArmFromController) leftElbowNode else null
BoneType.RIGHT_UPPER_ARM -> if (!isTrackingLeftArmFromController) rightElbowNode else null
BoneType.LEFT_UPPER_ARM -> leftElbowNode
BoneType.RIGHT_UPPER_ARM -> rightElbowNode
BoneType.LEFT_ELBOW_TRACKER -> trackerLeftElbowNode
BoneType.RIGHT_ELBOW_TRACKER -> trackerRightElbowNode
BoneType.LEFT_LOWER_ARM -> if (isTrackingLeftArmFromController) leftElbowNode else leftWristNode

View File

@@ -57,15 +57,19 @@ class TrackersUDPServer(private val port: Int, name: String, private val tracker
private fun setUpNewConnection(handshakePacket: DatagramPacket, handshake: UDPPacket3Handshake) {
LogManager.info("[TrackerServer] Handshake received from ${handshakePacket.address}:${handshakePacket.port}")
val addr = handshakePacket.address
val socketAddr = handshakePacket.socketAddress
// Get a connection either by an existing one, or by creating a new one
val connection: UDPDevice = synchronized(connections) {
connectionsByMAC[handshake.macString]?.apply {
// Look for an existing connection by the MAC address and update the
// connection information
connectionsByAddress.remove(address)
address = handshakePacket.socketAddress
address = socketAddr
lastPacketNumber = 0
ipAddress = addr
name = handshake.macString?.let { "udp://$it" }
descriptiveName = "udp:/${handshakePacket.address}"
descriptiveName = "udp:/$addr"
firmwareBuild = handshake.firmwareBuild
connectionsByAddress[address] = this
@@ -73,7 +77,28 @@ class TrackersUDPServer(private val port: Int, name: String, private val tracker
LogManager
.info(
"""
[TrackerServer] Tracker $i handed over to address ${handshakePacket.socketAddress}.
[TrackerServer] Tracker $i handed over to address $socketAddr.
Board type: ${handshake.boardType},
imu type: ${handshake.imuType},
firmware: ${handshake.firmware} ($firmwareBuild),
mac: ${handshake.macString},
name: $name
""".trimIndent()
)
} ?: connectionsByAddress[socketAddr]?.apply {
// Look for an existing connection by the socket address (IP and port)
// and update the connection information
lastPacketNumber = 0
ipAddress = addr
name = handshake.macString?.let { "udp://$it" }
?: "udp:/$addr"
descriptiveName = "udp:/$addr"
firmwareBuild = handshake.firmwareBuild
val i = connections.indexOf(this)
LogManager
.info(
"""
[TrackerServer] Tracker $i reconnected from address $socketAddr.
Board type: ${handshake.boardType},
imu type: ${handshake.imuType},
firmware: ${handshake.firmware} ($firmwareBuild),
@@ -83,8 +108,9 @@ class TrackersUDPServer(private val port: Int, name: String, private val tracker
)
}
} ?: run {
// No existing connection could be found, create a new one
val connection = UDPDevice(
handshakePacket.socketAddress,
socketAddr,
addr,
handshake.macString ?: addr.hostAddress,
handshake.boardType,
@@ -99,53 +125,31 @@ class TrackersUDPServer(private val port: Int, name: String, private val tracker
NetworkProtocol.SLIMEVR_RAW
}
connection.name = handshake.macString?.let { "udp://$it" }
?: "udp:/${handshakePacket.address}"
?: "udp:/$addr"
// TODO: The missing slash in udp:// was intended because InetAddress.toString()
// returns "hostname/address" but it wasn't known that if hostname is empty
// string it just looks like "/address" lol.
// Fixing this would break config!
connection.descriptiveName = "udp:/${handshakePacket.address}"
connection.descriptiveName = "udp:/$addr"
synchronized(connections) {
if (handshake.macString != null && connectionsByMAC.containsKey(handshake.macString)) {
val previousConnection = connectionsByMAC[handshake.macString]!!
val i = connections.indexOf(previousConnection)
connectionsByAddress.remove(previousConnection.address)
previousConnection.lastPacketNumber = 0
previousConnection.ipAddress = addr
previousConnection.address = handshakePacket.socketAddress
previousConnection.name = connection.name
previousConnection.descriptiveName = connection.descriptiveName
connectionsByAddress[handshakePacket.socketAddress] = previousConnection
LogManager
.info(
"""
[TrackerServer] Tracker $i handed over to address ${handshakePacket.socketAddress}.
Board type: ${handshake.boardType},
imu type: ${handshake.imuType},
firmware: ${handshake.firmware} (${connection.firmwareBuild}),
mac: ${handshake.macString},
name: ${previousConnection.name}
""".trimIndent()
)
} else {
val i = connections.size
connections.add(connection)
connectionsByAddress[handshakePacket.socketAddress] = connection
if (handshake.macString != null) {
connectionsByMAC[handshake.macString!!] = connection
}
LogManager
.info(
"""
[TrackerServer] Tracker $i handed over to address ${handshakePacket.socketAddress}.
Board type: ${handshake.boardType},
imu type: ${handshake.imuType},
firmware: ${handshake.firmware} (${connection.firmwareBuild}),
mac: ${handshake.macString},
name: ${connection.name}
""".trimIndent()
)
// Register the new connection
val i = connections.size
connections.add(connection)
connectionsByAddress[socketAddr] = connection
if (handshake.macString != null) {
connectionsByMAC[handshake.macString!!] = connection
}
LogManager
.info(
"""
[TrackerServer] Tracker $i connected from address $socketAddr.
Board type: ${handshake.boardType},
imu type: ${handshake.imuType},
firmware: ${handshake.firmware} (${connection.firmwareBuild}),
mac: ${handshake.macString},
name: ${connection.name}
""".trimIndent()
)
}
if (connection.protocol == NetworkProtocol.OWO_LEGACY || connection.firmwareBuild < 9) {
// Set up new sensor for older firmware.

View File

@@ -81,8 +81,8 @@ buildConfig {
packageName("dev.slimevr.desktop")
val gitVersionTag = providers.exec {
commandLine("git", "--no-pager", "tag", "--points-at", "HEAD")
}.standardOutput.asText.get()
commandLine("git", "--no-pager", "tag", "--sort", "-taggerdate", "--points-at", "HEAD")
}.standardOutput.asText.get().split('\n').first()
buildConfigField("String", "GIT_COMMIT_HASH", "\"${grgit.head().abbreviatedId}\"")
buildConfigField("String", "GIT_VERSION_TAG", "\"${gitVersionTag.trim()}\"")
buildConfigField("boolean", "GIT_CLEAN", grgit.status().isClean.toString())