├── .github └── workflows │ └── release.yml ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── loader ├── Cargo.toml ├── README.md ├── VRC-OSC.ico ├── build.rs ├── lib.rs └── main.rs ├── plugin-chatbox ├── Cargo.toml ├── README.md └── lib.rs ├── plugin-clock ├── Cargo.toml ├── README.md └── lib.rs ├── plugin-control ├── Cargo.toml ├── README.md └── src │ ├── lib.rs │ ├── unix.rs │ └── windows.rs ├── plugin-debug ├── Cargo.toml ├── README.md └── lib.rs ├── plugin-lastfm ├── Cargo.toml ├── README.md └── src │ ├── lib.rs │ └── model.rs ├── plugin-spotify ├── Cargo.toml ├── README.md └── src │ ├── chatbox.rs │ ├── control.rs │ └── lib.rs ├── plugin-steamvr ├── Cargo.toml ├── README.md └── src │ ├── lib.rs │ └── openvr.rs ├── rust-toolchain.toml └── rustfmt.toml /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | on: 2 | release: 3 | types: [ created ] 4 | 5 | jobs: 6 | release: 7 | env: 8 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 9 | LASTFM_API_KEY: ${{ secrets.LASTFM_API_KEY }} 10 | LASTFM_USERNAME: ${{ secrets.LASTFM_USERNAME }} 11 | SPOTIFY_CALLBACK: ${{ secrets.SPOTIFY_CALLBACK }} 12 | SPOTIFY_CLIENT: ${{ secrets.SPOTIFY_CLIENT }} 13 | SPOTIFY_SECRET: ${{ secrets.SPOTIFY_SECRET }} 14 | 15 | strategy: 16 | fail-fast: false 17 | matrix: 18 | include: 19 | - name: Linux-x86_64 20 | target: x86_64-unknown-linux-gnu 21 | runner: ubuntu-latest 22 | zip: vrc-osc,libchatbox.so,libclock.so,libcontrol.so,libdebug.so,liblastfm.so,libspotify.so,libsteamvr.so 23 | 24 | - name: macOS-Apple 25 | target: aarch64-apple-darwin 26 | runner: macos-latest 27 | zip: vrc-osc,libchatbox.dylib,libclock.dylib,libcontrol.dylib,libdebug.dylib,liblastfm.dylib,libspotify.dylib 28 | 29 | - name: macOS-Intel 30 | target: x86_64-apple-darwin 31 | runner: macos-latest 32 | zip: vrc-osc,libchatbox.dylib,libclock.dylib,libcontrol.dylib,libdebug.dylib,liblastfm.dylib,libspotify.dylib 33 | 34 | - name: Windows 35 | target: x86_64-pc-windows-msvc 36 | runner: windows-latest 37 | zip: vrc-osc.exe,chatbox.dll,clock.dll,control.dll,debug.dll,lastfm.dll,spotify.dll,steamvr.dll 38 | 39 | name: ${{ matrix.name }} 40 | runs-on: ${{ matrix.runner }} 41 | steps: 42 | - name: Fetch Repository 43 | uses: actions/checkout@v3 44 | 45 | - name: Update and Install Dependencies (Linux) 46 | if: ${{ matrix.runner == 'ubuntu-latest' }} 47 | run: | 48 | sudo apt-get update 49 | sudo apt-get install -y libssl-dev libxdo-dev 50 | 51 | - name: Update Rust Toolchain 52 | run: rustup update stable 53 | 54 | - name: Add Rust Target 55 | run: rustup target add ${{ matrix.target }} 56 | 57 | - name: Build Release Binary (macOS) 58 | if: ${{ matrix.runner == 'macos-latest' }} 59 | run: cargo build --release --target ${{ matrix.target }} --workspace --exclude plugin-control --exclude plugin-steamvr 60 | 61 | - name: Build Release Binary (Other) 62 | if: ${{ matrix.runner != 'macos-latest' }} 63 | run: cargo build --release --target ${{ matrix.target }} 64 | 65 | - name: Create Zip Archive (Windows) 66 | if: ${{ matrix.runner == 'windows-latest' }} 67 | run: bash -c '7z a ${{ matrix.name }}.zip ./target/${{ matrix.target }}/release/{${{ matrix.zip }}}' 68 | 69 | - name: Create Zip Archive (Other) 70 | if: ${{ matrix.runner != 'windows-latest' }} 71 | run: zip -j ${{ matrix.name }}.zip target/${{ matrix.target }}/release/{${{ matrix.zip }}} 72 | 73 | - name: Upload Zip Archive 74 | run: gh release upload ${{ github.ref_name }} ${{ matrix.name }}.zip --clobber 75 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | .idea/ 3 | .vscode/ 4 | target/ -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.21.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler" 16 | version = "1.0.2" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 19 | 20 | [[package]] 21 | name = "aead" 22 | version = "0.5.2" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" 25 | dependencies = [ 26 | "crypto-common", 27 | "generic-array", 28 | ] 29 | 30 | [[package]] 31 | name = "aes" 32 | version = "0.8.4" 33 | source = "registry+https://github.com/rust-lang/crates.io-index" 34 | checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" 35 | dependencies = [ 36 | "cfg-if", 37 | "cipher", 38 | "cpufeatures", 39 | ] 40 | 41 | [[package]] 42 | name = "aes-gcm" 43 | version = "0.10.3" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" 46 | dependencies = [ 47 | "aead", 48 | "aes", 49 | "cipher", 50 | "ctr", 51 | "ghash", 52 | "subtle", 53 | ] 54 | 55 | [[package]] 56 | name = "ahash" 57 | version = "0.8.11" 58 | source = "registry+https://github.com/rust-lang/crates.io-index" 59 | checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" 60 | dependencies = [ 61 | "cfg-if", 62 | "once_cell", 63 | "version_check", 64 | "zerocopy", 65 | ] 66 | 67 | [[package]] 68 | name = "aho-corasick" 69 | version = "1.1.3" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 72 | dependencies = [ 73 | "memchr", 74 | ] 75 | 76 | [[package]] 77 | name = "allocator-api2" 78 | version = "0.2.18" 79 | source = "registry+https://github.com/rust-lang/crates.io-index" 80 | checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" 81 | 82 | [[package]] 83 | name = "android-tzdata" 84 | version = "0.1.1" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" 87 | 88 | [[package]] 89 | name = "android_system_properties" 90 | version = "0.1.5" 91 | source = "registry+https://github.com/rust-lang/crates.io-index" 92 | checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" 93 | dependencies = [ 94 | "libc", 95 | ] 96 | 97 | [[package]] 98 | name = "anstream" 99 | version = "0.6.13" 100 | source = "registry+https://github.com/rust-lang/crates.io-index" 101 | checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" 102 | dependencies = [ 103 | "anstyle", 104 | "anstyle-parse", 105 | "anstyle-query", 106 | "anstyle-wincon", 107 | "colorchoice", 108 | "utf8parse", 109 | ] 110 | 111 | [[package]] 112 | name = "anstyle" 113 | version = "1.0.6" 114 | source = "registry+https://github.com/rust-lang/crates.io-index" 115 | checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" 116 | 117 | [[package]] 118 | name = "anstyle-parse" 119 | version = "0.2.3" 120 | source = "registry+https://github.com/rust-lang/crates.io-index" 121 | checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" 122 | dependencies = [ 123 | "utf8parse", 124 | ] 125 | 126 | [[package]] 127 | name = "anstyle-query" 128 | version = "1.0.2" 129 | source = "registry+https://github.com/rust-lang/crates.io-index" 130 | checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" 131 | dependencies = [ 132 | "windows-sys 0.52.0", 133 | ] 134 | 135 | [[package]] 136 | name = "anstyle-wincon" 137 | version = "3.0.2" 138 | source = "registry+https://github.com/rust-lang/crates.io-index" 139 | checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" 140 | dependencies = [ 141 | "anstyle", 142 | "windows-sys 0.52.0", 143 | ] 144 | 145 | [[package]] 146 | name = "anyhow" 147 | version = "1.0.82" 148 | source = "registry+https://github.com/rust-lang/crates.io-index" 149 | checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" 150 | 151 | [[package]] 152 | name = "aquamarine" 153 | version = "0.1.12" 154 | source = "registry+https://github.com/rust-lang/crates.io-index" 155 | checksum = "a941c39708478e8eea39243b5983f1c42d2717b3620ee91f4a52115fd02ac43f" 156 | dependencies = [ 157 | "itertools 0.9.0", 158 | "proc-macro-error", 159 | "proc-macro2", 160 | "quote", 161 | "syn 1.0.109", 162 | ] 163 | 164 | [[package]] 165 | name = "ascii" 166 | version = "1.1.0" 167 | source = "registry+https://github.com/rust-lang/crates.io-index" 168 | checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16" 169 | 170 | [[package]] 171 | name = "async-broadcast" 172 | version = "0.5.1" 173 | source = "registry+https://github.com/rust-lang/crates.io-index" 174 | checksum = "7c48ccdbf6ca6b121e0f586cbc0e73ae440e56c67c30fa0873b4e110d9c26d2b" 175 | dependencies = [ 176 | "event-listener 2.5.3", 177 | "futures-core", 178 | ] 179 | 180 | [[package]] 181 | name = "async-channel" 182 | version = "2.2.0" 183 | source = "registry+https://github.com/rust-lang/crates.io-index" 184 | checksum = "f28243a43d821d11341ab73c80bed182dc015c514b951616cf79bd4af39af0c3" 185 | dependencies = [ 186 | "concurrent-queue", 187 | "event-listener 5.3.0", 188 | "event-listener-strategy 0.5.1", 189 | "futures-core", 190 | "pin-project-lite", 191 | ] 192 | 193 | [[package]] 194 | name = "async-executor" 195 | version = "1.10.0" 196 | source = "registry+https://github.com/rust-lang/crates.io-index" 197 | checksum = "5f98c37cf288e302c16ef6c8472aad1e034c6c84ce5ea7b8101c98eb4a802fee" 198 | dependencies = [ 199 | "async-lock 3.3.0", 200 | "async-task", 201 | "concurrent-queue", 202 | "fastrand 2.0.2", 203 | "futures-lite 2.3.0", 204 | "slab", 205 | ] 206 | 207 | [[package]] 208 | name = "async-ffi" 209 | version = "0.5.0" 210 | source = "registry+https://github.com/rust-lang/crates.io-index" 211 | checksum = "f4de21c0feef7e5a556e51af767c953f0501f7f300ba785cc99c47bdc8081a50" 212 | dependencies = [ 213 | "async-ffi-macros", 214 | ] 215 | 216 | [[package]] 217 | name = "async-ffi-macros" 218 | version = "0.5.0" 219 | source = "registry+https://github.com/rust-lang/crates.io-index" 220 | checksum = "cfca27fc54e6a22790dbc90b1ffe3c0cff0008976035bb4123408f862a452d29" 221 | dependencies = [ 222 | "proc-macro2", 223 | "quote", 224 | "syn 2.0.58", 225 | ] 226 | 227 | [[package]] 228 | name = "async-fs" 229 | version = "1.6.0" 230 | source = "registry+https://github.com/rust-lang/crates.io-index" 231 | checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" 232 | dependencies = [ 233 | "async-lock 2.8.0", 234 | "autocfg", 235 | "blocking", 236 | "futures-lite 1.13.0", 237 | ] 238 | 239 | [[package]] 240 | name = "async-io" 241 | version = "1.13.0" 242 | source = "registry+https://github.com/rust-lang/crates.io-index" 243 | checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" 244 | dependencies = [ 245 | "async-lock 2.8.0", 246 | "autocfg", 247 | "cfg-if", 248 | "concurrent-queue", 249 | "futures-lite 1.13.0", 250 | "log", 251 | "parking", 252 | "polling 2.8.0", 253 | "rustix 0.37.27", 254 | "slab", 255 | "socket2 0.4.10", 256 | "waker-fn", 257 | ] 258 | 259 | [[package]] 260 | name = "async-io" 261 | version = "2.3.2" 262 | source = "registry+https://github.com/rust-lang/crates.io-index" 263 | checksum = "dcccb0f599cfa2f8ace422d3555572f47424da5648a4382a9dd0310ff8210884" 264 | dependencies = [ 265 | "async-lock 3.3.0", 266 | "cfg-if", 267 | "concurrent-queue", 268 | "futures-io", 269 | "futures-lite 2.3.0", 270 | "parking", 271 | "polling 3.6.0", 272 | "rustix 0.38.32", 273 | "slab", 274 | "tracing", 275 | "windows-sys 0.52.0", 276 | ] 277 | 278 | [[package]] 279 | name = "async-lock" 280 | version = "2.8.0" 281 | source = "registry+https://github.com/rust-lang/crates.io-index" 282 | checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" 283 | dependencies = [ 284 | "event-listener 2.5.3", 285 | ] 286 | 287 | [[package]] 288 | name = "async-lock" 289 | version = "3.3.0" 290 | source = "registry+https://github.com/rust-lang/crates.io-index" 291 | checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" 292 | dependencies = [ 293 | "event-listener 4.0.3", 294 | "event-listener-strategy 0.4.0", 295 | "pin-project-lite", 296 | ] 297 | 298 | [[package]] 299 | name = "async-process" 300 | version = "1.8.1" 301 | source = "registry+https://github.com/rust-lang/crates.io-index" 302 | checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" 303 | dependencies = [ 304 | "async-io 1.13.0", 305 | "async-lock 2.8.0", 306 | "async-signal", 307 | "blocking", 308 | "cfg-if", 309 | "event-listener 3.1.0", 310 | "futures-lite 1.13.0", 311 | "rustix 0.38.32", 312 | "windows-sys 0.48.0", 313 | ] 314 | 315 | [[package]] 316 | name = "async-recursion" 317 | version = "1.1.0" 318 | source = "registry+https://github.com/rust-lang/crates.io-index" 319 | checksum = "30c5ef0ede93efbf733c1a727f3b6b5a1060bbedd5600183e66f6e4be4af0ec5" 320 | dependencies = [ 321 | "proc-macro2", 322 | "quote", 323 | "syn 2.0.58", 324 | ] 325 | 326 | [[package]] 327 | name = "async-signal" 328 | version = "0.2.5" 329 | source = "registry+https://github.com/rust-lang/crates.io-index" 330 | checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5" 331 | dependencies = [ 332 | "async-io 2.3.2", 333 | "async-lock 2.8.0", 334 | "atomic-waker", 335 | "cfg-if", 336 | "futures-core", 337 | "futures-io", 338 | "rustix 0.38.32", 339 | "signal-hook-registry", 340 | "slab", 341 | "windows-sys 0.48.0", 342 | ] 343 | 344 | [[package]] 345 | name = "async-task" 346 | version = "4.7.0" 347 | source = "registry+https://github.com/rust-lang/crates.io-index" 348 | checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799" 349 | 350 | [[package]] 351 | name = "async-trait" 352 | version = "0.1.80" 353 | source = "registry+https://github.com/rust-lang/crates.io-index" 354 | checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" 355 | dependencies = [ 356 | "proc-macro2", 357 | "quote", 358 | "syn 2.0.58", 359 | ] 360 | 361 | [[package]] 362 | name = "atomic-waker" 363 | version = "1.1.2" 364 | source = "registry+https://github.com/rust-lang/crates.io-index" 365 | checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" 366 | 367 | [[package]] 368 | name = "atty" 369 | version = "0.2.14" 370 | source = "registry+https://github.com/rust-lang/crates.io-index" 371 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 372 | dependencies = [ 373 | "hermit-abi 0.1.19", 374 | "libc", 375 | "winapi", 376 | ] 377 | 378 | [[package]] 379 | name = "autocfg" 380 | version = "1.2.0" 381 | source = "registry+https://github.com/rust-lang/crates.io-index" 382 | checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" 383 | 384 | [[package]] 385 | name = "autocxx" 386 | version = "0.26.0" 387 | source = "registry+https://github.com/rust-lang/crates.io-index" 388 | checksum = "1ba64dd33efd8f09724143d45ab91b48aebcee52f4fb11add3464c998fab47dc" 389 | dependencies = [ 390 | "aquamarine", 391 | "autocxx-macro", 392 | "cxx", 393 | "moveit", 394 | ] 395 | 396 | [[package]] 397 | name = "autocxx-bindgen" 398 | version = "0.65.1" 399 | source = "registry+https://github.com/rust-lang/crates.io-index" 400 | checksum = "6c9fb7b8dd83a582e12157367773d8d1195f2dea54d4250aaf3426abae3237aa" 401 | dependencies = [ 402 | "bitflags 1.3.2", 403 | "cexpr", 404 | "clang-sys", 405 | "itertools 0.10.5", 406 | "lazy_static", 407 | "lazycell", 408 | "log", 409 | "peeking_take_while", 410 | "prettyplease", 411 | "proc-macro2", 412 | "quote", 413 | "regex", 414 | "rustc-hash", 415 | "shlex", 416 | "syn 2.0.58", 417 | "which", 418 | ] 419 | 420 | [[package]] 421 | name = "autocxx-build" 422 | version = "0.26.0" 423 | source = "registry+https://github.com/rust-lang/crates.io-index" 424 | checksum = "955e602d2d68b79ca5d674984259234fad2c8d869ad99011699e0a3cd76f38cd" 425 | dependencies = [ 426 | "autocxx-engine", 427 | "env_logger", 428 | "indexmap 1.9.3", 429 | "syn 2.0.58", 430 | ] 431 | 432 | [[package]] 433 | name = "autocxx-engine" 434 | version = "0.26.0" 435 | source = "registry+https://github.com/rust-lang/crates.io-index" 436 | checksum = "5918896fc1d44a647345fd5e8c74208424e394a76bdd2942398f4aff81ec7ab1" 437 | dependencies = [ 438 | "aquamarine", 439 | "autocxx-bindgen", 440 | "autocxx-parser", 441 | "cc", 442 | "cxx-gen", 443 | "indexmap 1.9.3", 444 | "indoc", 445 | "itertools 0.10.5", 446 | "log", 447 | "miette", 448 | "once_cell", 449 | "prettyplease", 450 | "proc-macro2", 451 | "quote", 452 | "regex", 453 | "rustversion", 454 | "serde_json", 455 | "strum_macros", 456 | "syn 2.0.58", 457 | "tempfile", 458 | "thiserror", 459 | "version_check", 460 | ] 461 | 462 | [[package]] 463 | name = "autocxx-macro" 464 | version = "0.26.0" 465 | source = "registry+https://github.com/rust-lang/crates.io-index" 466 | checksum = "8e594e68d030b6eb1ce7e2b40958f4f4ae7150c588c76d76b9f8178d41c47d80" 467 | dependencies = [ 468 | "autocxx-parser", 469 | "proc-macro-error", 470 | "proc-macro2", 471 | "quote", 472 | "syn 2.0.58", 473 | ] 474 | 475 | [[package]] 476 | name = "autocxx-parser" 477 | version = "0.26.0" 478 | source = "registry+https://github.com/rust-lang/crates.io-index" 479 | checksum = "2ef00b2fc378804c31c4fbd693a7fea93f8a90467dce331dae1e4ce41e542953" 480 | dependencies = [ 481 | "indexmap 1.9.3", 482 | "itertools 0.10.5", 483 | "log", 484 | "once_cell", 485 | "proc-macro2", 486 | "quote", 487 | "serde", 488 | "serde_json", 489 | "syn 2.0.58", 490 | "thiserror", 491 | ] 492 | 493 | [[package]] 494 | name = "backtrace" 495 | version = "0.3.71" 496 | source = "registry+https://github.com/rust-lang/crates.io-index" 497 | checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" 498 | dependencies = [ 499 | "addr2line", 500 | "cc", 501 | "cfg-if", 502 | "libc", 503 | "miniz_oxide", 504 | "object", 505 | "rustc-demangle", 506 | ] 507 | 508 | [[package]] 509 | name = "base64" 510 | version = "0.21.7" 511 | source = "registry+https://github.com/rust-lang/crates.io-index" 512 | checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" 513 | 514 | [[package]] 515 | name = "base64" 516 | version = "0.22.0" 517 | source = "registry+https://github.com/rust-lang/crates.io-index" 518 | checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" 519 | 520 | [[package]] 521 | name = "bitflags" 522 | version = "1.3.2" 523 | source = "registry+https://github.com/rust-lang/crates.io-index" 524 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 525 | 526 | [[package]] 527 | name = "bitflags" 528 | version = "2.5.0" 529 | source = "registry+https://github.com/rust-lang/crates.io-index" 530 | checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" 531 | 532 | [[package]] 533 | name = "block-buffer" 534 | version = "0.10.4" 535 | source = "registry+https://github.com/rust-lang/crates.io-index" 536 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 537 | dependencies = [ 538 | "generic-array", 539 | ] 540 | 541 | [[package]] 542 | name = "block-padding" 543 | version = "0.3.3" 544 | source = "registry+https://github.com/rust-lang/crates.io-index" 545 | checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" 546 | dependencies = [ 547 | "generic-array", 548 | ] 549 | 550 | [[package]] 551 | name = "blocking" 552 | version = "1.5.1" 553 | source = "registry+https://github.com/rust-lang/crates.io-index" 554 | checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" 555 | dependencies = [ 556 | "async-channel", 557 | "async-lock 3.3.0", 558 | "async-task", 559 | "fastrand 2.0.2", 560 | "futures-io", 561 | "futures-lite 2.3.0", 562 | "piper", 563 | "tracing", 564 | ] 565 | 566 | [[package]] 567 | name = "bumpalo" 568 | version = "3.16.0" 569 | source = "registry+https://github.com/rust-lang/crates.io-index" 570 | checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" 571 | 572 | [[package]] 573 | name = "byteorder" 574 | version = "1.5.0" 575 | source = "registry+https://github.com/rust-lang/crates.io-index" 576 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 577 | 578 | [[package]] 579 | name = "bytes" 580 | version = "1.6.0" 581 | source = "registry+https://github.com/rust-lang/crates.io-index" 582 | checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" 583 | 584 | [[package]] 585 | name = "cbc" 586 | version = "0.1.2" 587 | source = "registry+https://github.com/rust-lang/crates.io-index" 588 | checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" 589 | dependencies = [ 590 | "cipher", 591 | ] 592 | 593 | [[package]] 594 | name = "cc" 595 | version = "1.0.92" 596 | source = "registry+https://github.com/rust-lang/crates.io-index" 597 | checksum = "2678b2e3449475e95b0aa6f9b506a28e61b3dc8996592b983695e8ebb58a8b41" 598 | dependencies = [ 599 | "jobserver", 600 | "libc", 601 | ] 602 | 603 | [[package]] 604 | name = "cesu8" 605 | version = "1.1.0" 606 | source = "registry+https://github.com/rust-lang/crates.io-index" 607 | checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" 608 | 609 | [[package]] 610 | name = "cexpr" 611 | version = "0.6.0" 612 | source = "registry+https://github.com/rust-lang/crates.io-index" 613 | checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" 614 | dependencies = [ 615 | "nom", 616 | ] 617 | 618 | [[package]] 619 | name = "cfg-if" 620 | version = "1.0.0" 621 | source = "registry+https://github.com/rust-lang/crates.io-index" 622 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 623 | 624 | [[package]] 625 | name = "chrono" 626 | version = "0.4.37" 627 | source = "registry+https://github.com/rust-lang/crates.io-index" 628 | checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" 629 | dependencies = [ 630 | "android-tzdata", 631 | "iana-time-zone", 632 | "num-traits", 633 | "serde", 634 | "windows-targets 0.52.4", 635 | ] 636 | 637 | [[package]] 638 | name = "chunked_transfer" 639 | version = "1.5.0" 640 | source = "registry+https://github.com/rust-lang/crates.io-index" 641 | checksum = "6e4de3bc4ea267985becf712dc6d9eed8b04c953b3fcfb339ebc87acd9804901" 642 | 643 | [[package]] 644 | name = "cipher" 645 | version = "0.4.4" 646 | source = "registry+https://github.com/rust-lang/crates.io-index" 647 | checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" 648 | dependencies = [ 649 | "crypto-common", 650 | "inout", 651 | ] 652 | 653 | [[package]] 654 | name = "clang-sys" 655 | version = "1.7.0" 656 | source = "registry+https://github.com/rust-lang/crates.io-index" 657 | checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" 658 | dependencies = [ 659 | "glob", 660 | "libc", 661 | "libloading", 662 | ] 663 | 664 | [[package]] 665 | name = "codespan-reporting" 666 | version = "0.11.1" 667 | source = "registry+https://github.com/rust-lang/crates.io-index" 668 | checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" 669 | dependencies = [ 670 | "termcolor", 671 | "unicode-width", 672 | ] 673 | 674 | [[package]] 675 | name = "colorchoice" 676 | version = "1.0.0" 677 | source = "registry+https://github.com/rust-lang/crates.io-index" 678 | checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" 679 | 680 | [[package]] 681 | name = "combine" 682 | version = "4.6.7" 683 | source = "registry+https://github.com/rust-lang/crates.io-index" 684 | checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" 685 | dependencies = [ 686 | "bytes", 687 | "memchr", 688 | ] 689 | 690 | [[package]] 691 | name = "concurrent-queue" 692 | version = "2.4.0" 693 | source = "registry+https://github.com/rust-lang/crates.io-index" 694 | checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" 695 | dependencies = [ 696 | "crossbeam-utils", 697 | ] 698 | 699 | [[package]] 700 | name = "const-random" 701 | version = "0.1.18" 702 | source = "registry+https://github.com/rust-lang/crates.io-index" 703 | checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" 704 | dependencies = [ 705 | "const-random-macro", 706 | ] 707 | 708 | [[package]] 709 | name = "const-random-macro" 710 | version = "0.1.16" 711 | source = "registry+https://github.com/rust-lang/crates.io-index" 712 | checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" 713 | dependencies = [ 714 | "getrandom", 715 | "once_cell", 716 | "tiny-keccak", 717 | ] 718 | 719 | [[package]] 720 | name = "const_format" 721 | version = "0.2.32" 722 | source = "registry+https://github.com/rust-lang/crates.io-index" 723 | checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" 724 | dependencies = [ 725 | "const_format_proc_macros", 726 | ] 727 | 728 | [[package]] 729 | name = "const_format_proc_macros" 730 | version = "0.2.32" 731 | source = "registry+https://github.com/rust-lang/crates.io-index" 732 | checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" 733 | dependencies = [ 734 | "proc-macro2", 735 | "quote", 736 | "unicode-xid", 737 | ] 738 | 739 | [[package]] 740 | name = "convert_case" 741 | version = "0.4.0" 742 | source = "registry+https://github.com/rust-lang/crates.io-index" 743 | checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" 744 | 745 | [[package]] 746 | name = "cookie" 747 | version = "0.17.0" 748 | source = "registry+https://github.com/rust-lang/crates.io-index" 749 | checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24" 750 | dependencies = [ 751 | "percent-encoding", 752 | "time", 753 | "version_check", 754 | ] 755 | 756 | [[package]] 757 | name = "cookie_store" 758 | version = "0.20.0" 759 | source = "registry+https://github.com/rust-lang/crates.io-index" 760 | checksum = "387461abbc748185c3a6e1673d826918b450b87ff22639429c694619a83b6cf6" 761 | dependencies = [ 762 | "cookie", 763 | "idna 0.3.0", 764 | "log", 765 | "publicsuffix", 766 | "serde", 767 | "serde_derive", 768 | "serde_json", 769 | "time", 770 | "url", 771 | ] 772 | 773 | [[package]] 774 | name = "core-foundation" 775 | version = "0.9.4" 776 | source = "registry+https://github.com/rust-lang/crates.io-index" 777 | checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" 778 | dependencies = [ 779 | "core-foundation-sys", 780 | "libc", 781 | ] 782 | 783 | [[package]] 784 | name = "core-foundation-sys" 785 | version = "0.8.6" 786 | source = "registry+https://github.com/rust-lang/crates.io-index" 787 | checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" 788 | 789 | [[package]] 790 | name = "core-graphics" 791 | version = "0.23.2" 792 | source = "registry+https://github.com/rust-lang/crates.io-index" 793 | checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" 794 | dependencies = [ 795 | "bitflags 1.3.2", 796 | "core-foundation", 797 | "core-graphics-types", 798 | "foreign-types", 799 | "libc", 800 | ] 801 | 802 | [[package]] 803 | name = "core-graphics-types" 804 | version = "0.1.3" 805 | source = "registry+https://github.com/rust-lang/crates.io-index" 806 | checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" 807 | dependencies = [ 808 | "bitflags 1.3.2", 809 | "core-foundation", 810 | "libc", 811 | ] 812 | 813 | [[package]] 814 | name = "cpufeatures" 815 | version = "0.2.12" 816 | source = "registry+https://github.com/rust-lang/crates.io-index" 817 | checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" 818 | dependencies = [ 819 | "libc", 820 | ] 821 | 822 | [[package]] 823 | name = "crc32fast" 824 | version = "1.4.0" 825 | source = "registry+https://github.com/rust-lang/crates.io-index" 826 | checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" 827 | dependencies = [ 828 | "cfg-if", 829 | ] 830 | 831 | [[package]] 832 | name = "crossbeam-utils" 833 | version = "0.8.19" 834 | source = "registry+https://github.com/rust-lang/crates.io-index" 835 | checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" 836 | 837 | [[package]] 838 | name = "crossterm" 839 | version = "0.25.0" 840 | source = "registry+https://github.com/rust-lang/crates.io-index" 841 | checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67" 842 | dependencies = [ 843 | "bitflags 1.3.2", 844 | "crossterm_winapi", 845 | "libc", 846 | "mio", 847 | "parking_lot", 848 | "signal-hook", 849 | "signal-hook-mio", 850 | "winapi", 851 | ] 852 | 853 | [[package]] 854 | name = "crossterm_winapi" 855 | version = "0.9.1" 856 | source = "registry+https://github.com/rust-lang/crates.io-index" 857 | checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" 858 | dependencies = [ 859 | "winapi", 860 | ] 861 | 862 | [[package]] 863 | name = "crunchy" 864 | version = "0.2.2" 865 | source = "registry+https://github.com/rust-lang/crates.io-index" 866 | checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" 867 | 868 | [[package]] 869 | name = "crypto-common" 870 | version = "0.1.6" 871 | source = "registry+https://github.com/rust-lang/crates.io-index" 872 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 873 | dependencies = [ 874 | "generic-array", 875 | "rand_core", 876 | "typenum", 877 | ] 878 | 879 | [[package]] 880 | name = "ctr" 881 | version = "0.9.2" 882 | source = "registry+https://github.com/rust-lang/crates.io-index" 883 | checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" 884 | dependencies = [ 885 | "cipher", 886 | ] 887 | 888 | [[package]] 889 | name = "cxx" 890 | version = "1.0.121" 891 | source = "registry+https://github.com/rust-lang/crates.io-index" 892 | checksum = "21db378d04296a84d8b7d047c36bb3954f0b46529db725d7e62fb02f9ba53ccc" 893 | dependencies = [ 894 | "cc", 895 | "cxxbridge-flags", 896 | "cxxbridge-macro", 897 | "link-cplusplus", 898 | ] 899 | 900 | [[package]] 901 | name = "cxx-gen" 902 | version = "0.7.121" 903 | source = "registry+https://github.com/rust-lang/crates.io-index" 904 | checksum = "383ecb9f96a536a1c7a2a61c5786f583da84f9240da149d78d005a4413c9a71e" 905 | dependencies = [ 906 | "codespan-reporting", 907 | "proc-macro2", 908 | "quote", 909 | "syn 2.0.58", 910 | ] 911 | 912 | [[package]] 913 | name = "cxxbridge-flags" 914 | version = "1.0.121" 915 | source = "registry+https://github.com/rust-lang/crates.io-index" 916 | checksum = "be8dcadd2e2fb4a501e1d9e93d6e88e6ea494306d8272069c92d5a9edf8855c0" 917 | 918 | [[package]] 919 | name = "cxxbridge-macro" 920 | version = "1.0.121" 921 | source = "registry+https://github.com/rust-lang/crates.io-index" 922 | checksum = "ad08a837629ad949b73d032c637653d069e909cffe4ee7870b02301939ce39cc" 923 | dependencies = [ 924 | "proc-macro2", 925 | "quote", 926 | "syn 2.0.58", 927 | ] 928 | 929 | [[package]] 930 | name = "darling" 931 | version = "0.20.8" 932 | source = "registry+https://github.com/rust-lang/crates.io-index" 933 | checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" 934 | dependencies = [ 935 | "darling_core", 936 | "darling_macro", 937 | ] 938 | 939 | [[package]] 940 | name = "darling_core" 941 | version = "0.20.8" 942 | source = "registry+https://github.com/rust-lang/crates.io-index" 943 | checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" 944 | dependencies = [ 945 | "fnv", 946 | "ident_case", 947 | "proc-macro2", 948 | "quote", 949 | "strsim", 950 | "syn 2.0.58", 951 | ] 952 | 953 | [[package]] 954 | name = "darling_macro" 955 | version = "0.20.8" 956 | source = "registry+https://github.com/rust-lang/crates.io-index" 957 | checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" 958 | dependencies = [ 959 | "darling_core", 960 | "quote", 961 | "syn 2.0.58", 962 | ] 963 | 964 | [[package]] 965 | name = "deranged" 966 | version = "0.3.11" 967 | source = "registry+https://github.com/rust-lang/crates.io-index" 968 | checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" 969 | dependencies = [ 970 | "powerfmt", 971 | "serde", 972 | ] 973 | 974 | [[package]] 975 | name = "derivative" 976 | version = "2.2.0" 977 | source = "registry+https://github.com/rust-lang/crates.io-index" 978 | checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" 979 | dependencies = [ 980 | "proc-macro2", 981 | "quote", 982 | "syn 1.0.109", 983 | ] 984 | 985 | [[package]] 986 | name = "derive-config" 987 | version = "2.1.1" 988 | source = "registry+https://github.com/rust-lang/crates.io-index" 989 | checksum = "6f03fa8c91a0b5875b8bc83b172cf2f19445c448803da991e116781b741bc0e2" 990 | dependencies = [ 991 | "derive-macros", 992 | "duplicate", 993 | "thiserror", 994 | "toml 0.8.12", 995 | ] 996 | 997 | [[package]] 998 | name = "derive-macros" 999 | version = "2.1.1" 1000 | source = "registry+https://github.com/rust-lang/crates.io-index" 1001 | checksum = "4424be643671411826060012a293916a971f80bcdb74a929b1f56645b11a4f85" 1002 | dependencies = [ 1003 | "quote", 1004 | "syn 2.0.58", 1005 | ] 1006 | 1007 | [[package]] 1008 | name = "derive_more" 1009 | version = "0.99.17" 1010 | source = "registry+https://github.com/rust-lang/crates.io-index" 1011 | checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" 1012 | dependencies = [ 1013 | "convert_case", 1014 | "proc-macro2", 1015 | "quote", 1016 | "rustc_version", 1017 | "syn 1.0.109", 1018 | ] 1019 | 1020 | [[package]] 1021 | name = "digest" 1022 | version = "0.10.7" 1023 | source = "registry+https://github.com/rust-lang/crates.io-index" 1024 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 1025 | dependencies = [ 1026 | "block-buffer", 1027 | "crypto-common", 1028 | "subtle", 1029 | ] 1030 | 1031 | [[package]] 1032 | name = "dlv-list" 1033 | version = "0.5.2" 1034 | source = "registry+https://github.com/rust-lang/crates.io-index" 1035 | checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f" 1036 | dependencies = [ 1037 | "const-random", 1038 | ] 1039 | 1040 | [[package]] 1041 | name = "dotenvy" 1042 | version = "0.15.7" 1043 | source = "registry+https://github.com/rust-lang/crates.io-index" 1044 | checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" 1045 | 1046 | [[package]] 1047 | name = "dotenvy_macro" 1048 | version = "0.15.7" 1049 | source = "registry+https://github.com/rust-lang/crates.io-index" 1050 | checksum = "cb0235d912a8c749f4e0c9f18ca253b4c28cfefc1d2518096016d6e3230b6424" 1051 | dependencies = [ 1052 | "dotenvy", 1053 | "proc-macro2", 1054 | "quote", 1055 | "syn 1.0.109", 1056 | ] 1057 | 1058 | [[package]] 1059 | name = "duplicate" 1060 | version = "1.0.0" 1061 | source = "registry+https://github.com/rust-lang/crates.io-index" 1062 | checksum = "de78e66ac9061e030587b2a2e75cc88f22304913c907b11307bca737141230cb" 1063 | dependencies = [ 1064 | "heck", 1065 | "proc-macro-error", 1066 | ] 1067 | 1068 | [[package]] 1069 | name = "dyn-clone" 1070 | version = "1.0.17" 1071 | source = "registry+https://github.com/rust-lang/crates.io-index" 1072 | checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" 1073 | 1074 | [[package]] 1075 | name = "either" 1076 | version = "1.10.0" 1077 | source = "registry+https://github.com/rust-lang/crates.io-index" 1078 | checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" 1079 | 1080 | [[package]] 1081 | name = "encoding_rs" 1082 | version = "0.8.34" 1083 | source = "registry+https://github.com/rust-lang/crates.io-index" 1084 | checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" 1085 | dependencies = [ 1086 | "cfg-if", 1087 | ] 1088 | 1089 | [[package]] 1090 | name = "enigo" 1091 | version = "0.1.3" 1092 | source = "registry+https://github.com/rust-lang/crates.io-index" 1093 | checksum = "802e4b2ae123615659085369b453cba87c5562e46ed8050a909fee18a9bc3157" 1094 | dependencies = [ 1095 | "core-graphics", 1096 | "libc", 1097 | "objc", 1098 | "pkg-config", 1099 | "windows 0.51.1", 1100 | ] 1101 | 1102 | [[package]] 1103 | name = "enumflags2" 1104 | version = "0.7.9" 1105 | source = "registry+https://github.com/rust-lang/crates.io-index" 1106 | checksum = "3278c9d5fb675e0a51dabcf4c0d355f692b064171535ba72361be1528a9d8e8d" 1107 | dependencies = [ 1108 | "enumflags2_derive", 1109 | "serde", 1110 | ] 1111 | 1112 | [[package]] 1113 | name = "enumflags2_derive" 1114 | version = "0.7.9" 1115 | source = "registry+https://github.com/rust-lang/crates.io-index" 1116 | checksum = "5c785274071b1b420972453b306eeca06acf4633829db4223b58a2a8c5953bc4" 1117 | dependencies = [ 1118 | "proc-macro2", 1119 | "quote", 1120 | "syn 2.0.58", 1121 | ] 1122 | 1123 | [[package]] 1124 | name = "enumset" 1125 | version = "1.1.3" 1126 | source = "registry+https://github.com/rust-lang/crates.io-index" 1127 | checksum = "226c0da7462c13fb57e5cc9e0dc8f0635e7d27f276a3a7fd30054647f669007d" 1128 | dependencies = [ 1129 | "enumset_derive", 1130 | ] 1131 | 1132 | [[package]] 1133 | name = "enumset_derive" 1134 | version = "0.8.1" 1135 | source = "registry+https://github.com/rust-lang/crates.io-index" 1136 | checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" 1137 | dependencies = [ 1138 | "darling", 1139 | "proc-macro2", 1140 | "quote", 1141 | "syn 2.0.58", 1142 | ] 1143 | 1144 | [[package]] 1145 | name = "env_logger" 1146 | version = "0.9.3" 1147 | source = "registry+https://github.com/rust-lang/crates.io-index" 1148 | checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" 1149 | dependencies = [ 1150 | "atty", 1151 | "humantime", 1152 | "log", 1153 | "regex", 1154 | "termcolor", 1155 | ] 1156 | 1157 | [[package]] 1158 | name = "equivalent" 1159 | version = "1.0.1" 1160 | source = "registry+https://github.com/rust-lang/crates.io-index" 1161 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 1162 | 1163 | [[package]] 1164 | name = "errno" 1165 | version = "0.3.8" 1166 | source = "registry+https://github.com/rust-lang/crates.io-index" 1167 | checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" 1168 | dependencies = [ 1169 | "libc", 1170 | "windows-sys 0.52.0", 1171 | ] 1172 | 1173 | [[package]] 1174 | name = "event-listener" 1175 | version = "2.5.3" 1176 | source = "registry+https://github.com/rust-lang/crates.io-index" 1177 | checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" 1178 | 1179 | [[package]] 1180 | name = "event-listener" 1181 | version = "3.1.0" 1182 | source = "registry+https://github.com/rust-lang/crates.io-index" 1183 | checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" 1184 | dependencies = [ 1185 | "concurrent-queue", 1186 | "parking", 1187 | "pin-project-lite", 1188 | ] 1189 | 1190 | [[package]] 1191 | name = "event-listener" 1192 | version = "4.0.3" 1193 | source = "registry+https://github.com/rust-lang/crates.io-index" 1194 | checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" 1195 | dependencies = [ 1196 | "concurrent-queue", 1197 | "parking", 1198 | "pin-project-lite", 1199 | ] 1200 | 1201 | [[package]] 1202 | name = "event-listener" 1203 | version = "5.3.0" 1204 | source = "registry+https://github.com/rust-lang/crates.io-index" 1205 | checksum = "6d9944b8ca13534cdfb2800775f8dd4902ff3fc75a50101466decadfdf322a24" 1206 | dependencies = [ 1207 | "concurrent-queue", 1208 | "parking", 1209 | "pin-project-lite", 1210 | ] 1211 | 1212 | [[package]] 1213 | name = "event-listener-strategy" 1214 | version = "0.4.0" 1215 | source = "registry+https://github.com/rust-lang/crates.io-index" 1216 | checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" 1217 | dependencies = [ 1218 | "event-listener 4.0.3", 1219 | "pin-project-lite", 1220 | ] 1221 | 1222 | [[package]] 1223 | name = "event-listener-strategy" 1224 | version = "0.5.1" 1225 | source = "registry+https://github.com/rust-lang/crates.io-index" 1226 | checksum = "332f51cb23d20b0de8458b86580878211da09bcd4503cb579c225b3d124cabb3" 1227 | dependencies = [ 1228 | "event-listener 5.3.0", 1229 | "pin-project-lite", 1230 | ] 1231 | 1232 | [[package]] 1233 | name = "fallible-iterator" 1234 | version = "0.3.0" 1235 | source = "registry+https://github.com/rust-lang/crates.io-index" 1236 | checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" 1237 | 1238 | [[package]] 1239 | name = "fallible-streaming-iterator" 1240 | version = "0.1.9" 1241 | source = "registry+https://github.com/rust-lang/crates.io-index" 1242 | checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" 1243 | 1244 | [[package]] 1245 | name = "fastrand" 1246 | version = "1.9.0" 1247 | source = "registry+https://github.com/rust-lang/crates.io-index" 1248 | checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" 1249 | dependencies = [ 1250 | "instant", 1251 | ] 1252 | 1253 | [[package]] 1254 | name = "fastrand" 1255 | version = "2.0.2" 1256 | source = "registry+https://github.com/rust-lang/crates.io-index" 1257 | checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" 1258 | 1259 | [[package]] 1260 | name = "ferrispot" 1261 | version = "0.4.1" 1262 | source = "git+https://github.com/Shays-Forks/Ferrispot.git#31e2d0dc478073791c6fc6fb078fdacbb426bf68" 1263 | dependencies = [ 1264 | "async-trait", 1265 | "base64 0.21.7", 1266 | "const_format", 1267 | "log", 1268 | "rand", 1269 | "reqwest 0.11.27", 1270 | "serde", 1271 | "sha2", 1272 | "thiserror", 1273 | ] 1274 | 1275 | [[package]] 1276 | name = "flate2" 1277 | version = "1.0.28" 1278 | source = "registry+https://github.com/rust-lang/crates.io-index" 1279 | checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" 1280 | dependencies = [ 1281 | "crc32fast", 1282 | "miniz_oxide", 1283 | ] 1284 | 1285 | [[package]] 1286 | name = "fnv" 1287 | version = "1.0.7" 1288 | source = "registry+https://github.com/rust-lang/crates.io-index" 1289 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 1290 | 1291 | [[package]] 1292 | name = "foreign-types" 1293 | version = "0.5.0" 1294 | source = "registry+https://github.com/rust-lang/crates.io-index" 1295 | checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" 1296 | dependencies = [ 1297 | "foreign-types-macros", 1298 | "foreign-types-shared", 1299 | ] 1300 | 1301 | [[package]] 1302 | name = "foreign-types-macros" 1303 | version = "0.2.3" 1304 | source = "registry+https://github.com/rust-lang/crates.io-index" 1305 | checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" 1306 | dependencies = [ 1307 | "proc-macro2", 1308 | "quote", 1309 | "syn 2.0.58", 1310 | ] 1311 | 1312 | [[package]] 1313 | name = "foreign-types-shared" 1314 | version = "0.3.1" 1315 | source = "registry+https://github.com/rust-lang/crates.io-index" 1316 | checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" 1317 | 1318 | [[package]] 1319 | name = "form_urlencoded" 1320 | version = "1.2.1" 1321 | source = "registry+https://github.com/rust-lang/crates.io-index" 1322 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 1323 | dependencies = [ 1324 | "percent-encoding", 1325 | ] 1326 | 1327 | [[package]] 1328 | name = "futures-channel" 1329 | version = "0.3.30" 1330 | source = "registry+https://github.com/rust-lang/crates.io-index" 1331 | checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" 1332 | dependencies = [ 1333 | "futures-core", 1334 | ] 1335 | 1336 | [[package]] 1337 | name = "futures-core" 1338 | version = "0.3.30" 1339 | source = "registry+https://github.com/rust-lang/crates.io-index" 1340 | checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" 1341 | 1342 | [[package]] 1343 | name = "futures-io" 1344 | version = "0.3.30" 1345 | source = "registry+https://github.com/rust-lang/crates.io-index" 1346 | checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" 1347 | 1348 | [[package]] 1349 | name = "futures-lite" 1350 | version = "1.13.0" 1351 | source = "registry+https://github.com/rust-lang/crates.io-index" 1352 | checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" 1353 | dependencies = [ 1354 | "fastrand 1.9.0", 1355 | "futures-core", 1356 | "futures-io", 1357 | "memchr", 1358 | "parking", 1359 | "pin-project-lite", 1360 | "waker-fn", 1361 | ] 1362 | 1363 | [[package]] 1364 | name = "futures-lite" 1365 | version = "2.3.0" 1366 | source = "registry+https://github.com/rust-lang/crates.io-index" 1367 | checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" 1368 | dependencies = [ 1369 | "fastrand 2.0.2", 1370 | "futures-core", 1371 | "futures-io", 1372 | "parking", 1373 | "pin-project-lite", 1374 | ] 1375 | 1376 | [[package]] 1377 | name = "futures-sink" 1378 | version = "0.3.30" 1379 | source = "registry+https://github.com/rust-lang/crates.io-index" 1380 | checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" 1381 | 1382 | [[package]] 1383 | name = "futures-task" 1384 | version = "0.3.30" 1385 | source = "registry+https://github.com/rust-lang/crates.io-index" 1386 | checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" 1387 | 1388 | [[package]] 1389 | name = "futures-util" 1390 | version = "0.3.30" 1391 | source = "registry+https://github.com/rust-lang/crates.io-index" 1392 | checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" 1393 | dependencies = [ 1394 | "futures-core", 1395 | "futures-io", 1396 | "futures-sink", 1397 | "futures-task", 1398 | "memchr", 1399 | "pin-project-lite", 1400 | "pin-utils", 1401 | "slab", 1402 | ] 1403 | 1404 | [[package]] 1405 | name = "fuzzy-matcher" 1406 | version = "0.3.7" 1407 | source = "registry+https://github.com/rust-lang/crates.io-index" 1408 | checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94" 1409 | dependencies = [ 1410 | "thread_local", 1411 | ] 1412 | 1413 | [[package]] 1414 | name = "fxhash" 1415 | version = "0.2.1" 1416 | source = "registry+https://github.com/rust-lang/crates.io-index" 1417 | checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" 1418 | dependencies = [ 1419 | "byteorder", 1420 | ] 1421 | 1422 | [[package]] 1423 | name = "generic-array" 1424 | version = "0.14.7" 1425 | source = "registry+https://github.com/rust-lang/crates.io-index" 1426 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 1427 | dependencies = [ 1428 | "typenum", 1429 | "version_check", 1430 | ] 1431 | 1432 | [[package]] 1433 | name = "getrandom" 1434 | version = "0.2.14" 1435 | source = "registry+https://github.com/rust-lang/crates.io-index" 1436 | checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" 1437 | dependencies = [ 1438 | "cfg-if", 1439 | "libc", 1440 | "wasi", 1441 | ] 1442 | 1443 | [[package]] 1444 | name = "ghash" 1445 | version = "0.5.1" 1446 | source = "registry+https://github.com/rust-lang/crates.io-index" 1447 | checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" 1448 | dependencies = [ 1449 | "opaque-debug", 1450 | "polyval", 1451 | ] 1452 | 1453 | [[package]] 1454 | name = "gimli" 1455 | version = "0.28.1" 1456 | source = "registry+https://github.com/rust-lang/crates.io-index" 1457 | checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" 1458 | 1459 | [[package]] 1460 | name = "glob" 1461 | version = "0.3.1" 1462 | source = "registry+https://github.com/rust-lang/crates.io-index" 1463 | checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" 1464 | 1465 | [[package]] 1466 | name = "h2" 1467 | version = "0.3.26" 1468 | source = "registry+https://github.com/rust-lang/crates.io-index" 1469 | checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" 1470 | dependencies = [ 1471 | "bytes", 1472 | "fnv", 1473 | "futures-core", 1474 | "futures-sink", 1475 | "futures-util", 1476 | "http 0.2.12", 1477 | "indexmap 2.2.6", 1478 | "slab", 1479 | "tokio", 1480 | "tokio-util", 1481 | "tracing", 1482 | ] 1483 | 1484 | [[package]] 1485 | name = "hashbrown" 1486 | version = "0.12.3" 1487 | source = "registry+https://github.com/rust-lang/crates.io-index" 1488 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 1489 | 1490 | [[package]] 1491 | name = "hashbrown" 1492 | version = "0.14.3" 1493 | source = "registry+https://github.com/rust-lang/crates.io-index" 1494 | checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" 1495 | dependencies = [ 1496 | "ahash", 1497 | "allocator-api2", 1498 | ] 1499 | 1500 | [[package]] 1501 | name = "hashlink" 1502 | version = "0.9.0" 1503 | source = "registry+https://github.com/rust-lang/crates.io-index" 1504 | checksum = "692eaaf7f7607518dd3cef090f1474b61edc5301d8012f09579920df68b725ee" 1505 | dependencies = [ 1506 | "hashbrown 0.14.3", 1507 | ] 1508 | 1509 | [[package]] 1510 | name = "heck" 1511 | version = "0.4.1" 1512 | source = "registry+https://github.com/rust-lang/crates.io-index" 1513 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 1514 | 1515 | [[package]] 1516 | name = "hermit-abi" 1517 | version = "0.1.19" 1518 | source = "registry+https://github.com/rust-lang/crates.io-index" 1519 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 1520 | dependencies = [ 1521 | "libc", 1522 | ] 1523 | 1524 | [[package]] 1525 | name = "hermit-abi" 1526 | version = "0.3.9" 1527 | source = "registry+https://github.com/rust-lang/crates.io-index" 1528 | checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" 1529 | 1530 | [[package]] 1531 | name = "hex" 1532 | version = "0.4.3" 1533 | source = "registry+https://github.com/rust-lang/crates.io-index" 1534 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 1535 | 1536 | [[package]] 1537 | name = "hmac" 1538 | version = "0.12.1" 1539 | source = "registry+https://github.com/rust-lang/crates.io-index" 1540 | checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" 1541 | dependencies = [ 1542 | "digest", 1543 | ] 1544 | 1545 | [[package]] 1546 | name = "home" 1547 | version = "0.5.9" 1548 | source = "registry+https://github.com/rust-lang/crates.io-index" 1549 | checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" 1550 | dependencies = [ 1551 | "windows-sys 0.52.0", 1552 | ] 1553 | 1554 | [[package]] 1555 | name = "http" 1556 | version = "0.2.12" 1557 | source = "registry+https://github.com/rust-lang/crates.io-index" 1558 | checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" 1559 | dependencies = [ 1560 | "bytes", 1561 | "fnv", 1562 | "itoa", 1563 | ] 1564 | 1565 | [[package]] 1566 | name = "http" 1567 | version = "1.1.0" 1568 | source = "registry+https://github.com/rust-lang/crates.io-index" 1569 | checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" 1570 | dependencies = [ 1571 | "bytes", 1572 | "fnv", 1573 | "itoa", 1574 | ] 1575 | 1576 | [[package]] 1577 | name = "http-body" 1578 | version = "0.4.6" 1579 | source = "registry+https://github.com/rust-lang/crates.io-index" 1580 | checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" 1581 | dependencies = [ 1582 | "bytes", 1583 | "http 0.2.12", 1584 | "pin-project-lite", 1585 | ] 1586 | 1587 | [[package]] 1588 | name = "http-body" 1589 | version = "1.0.0" 1590 | source = "registry+https://github.com/rust-lang/crates.io-index" 1591 | checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" 1592 | dependencies = [ 1593 | "bytes", 1594 | "http 1.1.0", 1595 | ] 1596 | 1597 | [[package]] 1598 | name = "http-body-util" 1599 | version = "0.1.1" 1600 | source = "registry+https://github.com/rust-lang/crates.io-index" 1601 | checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" 1602 | dependencies = [ 1603 | "bytes", 1604 | "futures-core", 1605 | "http 1.1.0", 1606 | "http-body 1.0.0", 1607 | "pin-project-lite", 1608 | ] 1609 | 1610 | [[package]] 1611 | name = "httparse" 1612 | version = "1.8.0" 1613 | source = "registry+https://github.com/rust-lang/crates.io-index" 1614 | checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" 1615 | 1616 | [[package]] 1617 | name = "httpdate" 1618 | version = "1.0.3" 1619 | source = "registry+https://github.com/rust-lang/crates.io-index" 1620 | checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" 1621 | 1622 | [[package]] 1623 | name = "human-panic" 1624 | version = "1.2.3" 1625 | source = "registry+https://github.com/rust-lang/crates.io-index" 1626 | checksum = "c4f016c89920bbb30951a8405ecacbb4540db5524313b9445736e7e1855cf370" 1627 | dependencies = [ 1628 | "anstream", 1629 | "anstyle", 1630 | "backtrace", 1631 | "os_info", 1632 | "serde", 1633 | "serde_derive", 1634 | "toml 0.8.12", 1635 | "uuid", 1636 | ] 1637 | 1638 | [[package]] 1639 | name = "humantime" 1640 | version = "2.1.0" 1641 | source = "registry+https://github.com/rust-lang/crates.io-index" 1642 | checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" 1643 | 1644 | [[package]] 1645 | name = "hyper" 1646 | version = "0.14.28" 1647 | source = "registry+https://github.com/rust-lang/crates.io-index" 1648 | checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" 1649 | dependencies = [ 1650 | "bytes", 1651 | "futures-channel", 1652 | "futures-core", 1653 | "futures-util", 1654 | "h2", 1655 | "http 0.2.12", 1656 | "http-body 0.4.6", 1657 | "httparse", 1658 | "httpdate", 1659 | "itoa", 1660 | "pin-project-lite", 1661 | "socket2 0.5.6", 1662 | "tokio", 1663 | "tower-service", 1664 | "tracing", 1665 | "want", 1666 | ] 1667 | 1668 | [[package]] 1669 | name = "hyper" 1670 | version = "1.2.0" 1671 | source = "registry+https://github.com/rust-lang/crates.io-index" 1672 | checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a" 1673 | dependencies = [ 1674 | "bytes", 1675 | "futures-channel", 1676 | "futures-util", 1677 | "http 1.1.0", 1678 | "http-body 1.0.0", 1679 | "httparse", 1680 | "itoa", 1681 | "pin-project-lite", 1682 | "smallvec", 1683 | "tokio", 1684 | "want", 1685 | ] 1686 | 1687 | [[package]] 1688 | name = "hyper-rustls" 1689 | version = "0.24.2" 1690 | source = "registry+https://github.com/rust-lang/crates.io-index" 1691 | checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" 1692 | dependencies = [ 1693 | "futures-util", 1694 | "http 0.2.12", 1695 | "hyper 0.14.28", 1696 | "rustls 0.21.10", 1697 | "tokio", 1698 | "tokio-rustls 0.24.1", 1699 | ] 1700 | 1701 | [[package]] 1702 | name = "hyper-rustls" 1703 | version = "0.26.0" 1704 | source = "registry+https://github.com/rust-lang/crates.io-index" 1705 | checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" 1706 | dependencies = [ 1707 | "futures-util", 1708 | "http 1.1.0", 1709 | "hyper 1.2.0", 1710 | "hyper-util", 1711 | "rustls 0.22.3", 1712 | "rustls-pki-types", 1713 | "tokio", 1714 | "tokio-rustls 0.25.0", 1715 | "tower-service", 1716 | ] 1717 | 1718 | [[package]] 1719 | name = "hyper-util" 1720 | version = "0.1.3" 1721 | source = "registry+https://github.com/rust-lang/crates.io-index" 1722 | checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" 1723 | dependencies = [ 1724 | "bytes", 1725 | "futures-channel", 1726 | "futures-util", 1727 | "http 1.1.0", 1728 | "http-body 1.0.0", 1729 | "hyper 1.2.0", 1730 | "pin-project-lite", 1731 | "socket2 0.5.6", 1732 | "tokio", 1733 | "tower", 1734 | "tower-service", 1735 | "tracing", 1736 | ] 1737 | 1738 | [[package]] 1739 | name = "iana-time-zone" 1740 | version = "0.1.60" 1741 | source = "registry+https://github.com/rust-lang/crates.io-index" 1742 | checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" 1743 | dependencies = [ 1744 | "android_system_properties", 1745 | "core-foundation-sys", 1746 | "iana-time-zone-haiku", 1747 | "js-sys", 1748 | "wasm-bindgen", 1749 | "windows-core 0.52.0", 1750 | ] 1751 | 1752 | [[package]] 1753 | name = "iana-time-zone-haiku" 1754 | version = "0.1.2" 1755 | source = "registry+https://github.com/rust-lang/crates.io-index" 1756 | checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" 1757 | dependencies = [ 1758 | "cc", 1759 | ] 1760 | 1761 | [[package]] 1762 | name = "ident_case" 1763 | version = "1.0.1" 1764 | source = "registry+https://github.com/rust-lang/crates.io-index" 1765 | checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 1766 | 1767 | [[package]] 1768 | name = "idna" 1769 | version = "0.3.0" 1770 | source = "registry+https://github.com/rust-lang/crates.io-index" 1771 | checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" 1772 | dependencies = [ 1773 | "unicode-bidi", 1774 | "unicode-normalization", 1775 | ] 1776 | 1777 | [[package]] 1778 | name = "idna" 1779 | version = "0.5.0" 1780 | source = "registry+https://github.com/rust-lang/crates.io-index" 1781 | checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" 1782 | dependencies = [ 1783 | "unicode-bidi", 1784 | "unicode-normalization", 1785 | ] 1786 | 1787 | [[package]] 1788 | name = "indexmap" 1789 | version = "1.9.3" 1790 | source = "registry+https://github.com/rust-lang/crates.io-index" 1791 | checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" 1792 | dependencies = [ 1793 | "autocfg", 1794 | "hashbrown 0.12.3", 1795 | "serde", 1796 | ] 1797 | 1798 | [[package]] 1799 | name = "indexmap" 1800 | version = "2.2.6" 1801 | source = "registry+https://github.com/rust-lang/crates.io-index" 1802 | checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" 1803 | dependencies = [ 1804 | "equivalent", 1805 | "hashbrown 0.14.3", 1806 | "serde", 1807 | ] 1808 | 1809 | [[package]] 1810 | name = "indoc" 1811 | version = "1.0.9" 1812 | source = "registry+https://github.com/rust-lang/crates.io-index" 1813 | checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306" 1814 | 1815 | [[package]] 1816 | name = "inout" 1817 | version = "0.1.3" 1818 | source = "registry+https://github.com/rust-lang/crates.io-index" 1819 | checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" 1820 | dependencies = [ 1821 | "block-padding", 1822 | "generic-array", 1823 | ] 1824 | 1825 | [[package]] 1826 | name = "inquire" 1827 | version = "0.7.4" 1828 | source = "registry+https://github.com/rust-lang/crates.io-index" 1829 | checksum = "fe95f33091b9b7b517a5849bce4dce1b550b430fc20d58059fcaa319ed895d8b" 1830 | dependencies = [ 1831 | "bitflags 2.5.0", 1832 | "crossterm", 1833 | "dyn-clone", 1834 | "fuzzy-matcher", 1835 | "fxhash", 1836 | "newline-converter", 1837 | "once_cell", 1838 | "unicode-segmentation", 1839 | "unicode-width", 1840 | ] 1841 | 1842 | [[package]] 1843 | name = "instant" 1844 | version = "0.1.12" 1845 | source = "registry+https://github.com/rust-lang/crates.io-index" 1846 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 1847 | dependencies = [ 1848 | "cfg-if", 1849 | ] 1850 | 1851 | [[package]] 1852 | name = "io-lifetimes" 1853 | version = "1.0.11" 1854 | source = "registry+https://github.com/rust-lang/crates.io-index" 1855 | checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" 1856 | dependencies = [ 1857 | "hermit-abi 0.3.9", 1858 | "libc", 1859 | "windows-sys 0.48.0", 1860 | ] 1861 | 1862 | [[package]] 1863 | name = "ipnet" 1864 | version = "2.9.0" 1865 | source = "registry+https://github.com/rust-lang/crates.io-index" 1866 | checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" 1867 | 1868 | [[package]] 1869 | name = "itertools" 1870 | version = "0.9.0" 1871 | source = "registry+https://github.com/rust-lang/crates.io-index" 1872 | checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" 1873 | dependencies = [ 1874 | "either", 1875 | ] 1876 | 1877 | [[package]] 1878 | name = "itertools" 1879 | version = "0.10.5" 1880 | source = "registry+https://github.com/rust-lang/crates.io-index" 1881 | checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" 1882 | dependencies = [ 1883 | "either", 1884 | ] 1885 | 1886 | [[package]] 1887 | name = "itoa" 1888 | version = "1.0.11" 1889 | source = "registry+https://github.com/rust-lang/crates.io-index" 1890 | checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" 1891 | 1892 | [[package]] 1893 | name = "jni" 1894 | version = "0.21.1" 1895 | source = "registry+https://github.com/rust-lang/crates.io-index" 1896 | checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" 1897 | dependencies = [ 1898 | "cesu8", 1899 | "cfg-if", 1900 | "combine", 1901 | "jni-sys", 1902 | "log", 1903 | "thiserror", 1904 | "walkdir", 1905 | "windows-sys 0.45.0", 1906 | ] 1907 | 1908 | [[package]] 1909 | name = "jni-sys" 1910 | version = "0.3.0" 1911 | source = "registry+https://github.com/rust-lang/crates.io-index" 1912 | checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" 1913 | 1914 | [[package]] 1915 | name = "jobserver" 1916 | version = "0.1.29" 1917 | source = "registry+https://github.com/rust-lang/crates.io-index" 1918 | checksum = "f08474e32172238f2827bd160c67871cdb2801430f65c3979184dc362e3ca118" 1919 | dependencies = [ 1920 | "libc", 1921 | ] 1922 | 1923 | [[package]] 1924 | name = "js-sys" 1925 | version = "0.3.69" 1926 | source = "registry+https://github.com/rust-lang/crates.io-index" 1927 | checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" 1928 | dependencies = [ 1929 | "wasm-bindgen", 1930 | ] 1931 | 1932 | [[package]] 1933 | name = "lazy_static" 1934 | version = "1.4.0" 1935 | source = "registry+https://github.com/rust-lang/crates.io-index" 1936 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 1937 | 1938 | [[package]] 1939 | name = "lazycell" 1940 | version = "1.3.0" 1941 | source = "registry+https://github.com/rust-lang/crates.io-index" 1942 | checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" 1943 | 1944 | [[package]] 1945 | name = "libc" 1946 | version = "0.2.153" 1947 | source = "registry+https://github.com/rust-lang/crates.io-index" 1948 | checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" 1949 | 1950 | [[package]] 1951 | name = "libesedb" 1952 | version = "0.2.5" 1953 | source = "registry+https://github.com/rust-lang/crates.io-index" 1954 | checksum = "365ccadc1c3b42f16af2a582d59699437c1800d9afc3b93682a3259966671519" 1955 | dependencies = [ 1956 | "libesedb-sys", 1957 | "time", 1958 | ] 1959 | 1960 | [[package]] 1961 | name = "libesedb-sys" 1962 | version = "0.2.0" 1963 | source = "registry+https://github.com/rust-lang/crates.io-index" 1964 | checksum = "f7a5067ea7b882d70851a209bef21f388242d2c2a9dbb45824b502c94033a8f5" 1965 | dependencies = [ 1966 | "cc", 1967 | "walkdir", 1968 | ] 1969 | 1970 | [[package]] 1971 | name = "libloading" 1972 | version = "0.8.3" 1973 | source = "registry+https://github.com/rust-lang/crates.io-index" 1974 | checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" 1975 | dependencies = [ 1976 | "cfg-if", 1977 | "windows-targets 0.52.4", 1978 | ] 1979 | 1980 | [[package]] 1981 | name = "libsqlite3-sys" 1982 | version = "0.28.0" 1983 | source = "registry+https://github.com/rust-lang/crates.io-index" 1984 | checksum = "0c10584274047cb335c23d3e61bcef8e323adae7c5c8c760540f73610177fc3f" 1985 | dependencies = [ 1986 | "cc", 1987 | "pkg-config", 1988 | "vcpkg", 1989 | ] 1990 | 1991 | [[package]] 1992 | name = "link-cplusplus" 1993 | version = "1.0.9" 1994 | source = "registry+https://github.com/rust-lang/crates.io-index" 1995 | checksum = "9d240c6f7e1ba3a28b0249f774e6a9dd0175054b52dfbb61b16eb8505c3785c9" 1996 | dependencies = [ 1997 | "cc", 1998 | ] 1999 | 2000 | [[package]] 2001 | name = "linux-raw-sys" 2002 | version = "0.3.8" 2003 | source = "registry+https://github.com/rust-lang/crates.io-index" 2004 | checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" 2005 | 2006 | [[package]] 2007 | name = "linux-raw-sys" 2008 | version = "0.4.13" 2009 | source = "registry+https://github.com/rust-lang/crates.io-index" 2010 | checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" 2011 | 2012 | [[package]] 2013 | name = "lock_api" 2014 | version = "0.4.11" 2015 | source = "registry+https://github.com/rust-lang/crates.io-index" 2016 | checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" 2017 | dependencies = [ 2018 | "autocfg", 2019 | "scopeguard", 2020 | ] 2021 | 2022 | [[package]] 2023 | name = "log" 2024 | version = "0.4.21" 2025 | source = "registry+https://github.com/rust-lang/crates.io-index" 2026 | checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" 2027 | 2028 | [[package]] 2029 | name = "lz4_flex" 2030 | version = "0.11.3" 2031 | source = "registry+https://github.com/rust-lang/crates.io-index" 2032 | checksum = "75761162ae2b0e580d7e7c390558127e5f01b4194debd6221fd8c207fc80e3f5" 2033 | dependencies = [ 2034 | "twox-hash", 2035 | ] 2036 | 2037 | [[package]] 2038 | name = "malloc_buf" 2039 | version = "0.0.6" 2040 | source = "registry+https://github.com/rust-lang/crates.io-index" 2041 | checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" 2042 | dependencies = [ 2043 | "libc", 2044 | ] 2045 | 2046 | [[package]] 2047 | name = "maybe-async" 2048 | version = "0.2.10" 2049 | source = "registry+https://github.com/rust-lang/crates.io-index" 2050 | checksum = "5cf92c10c7e361d6b99666ec1c6f9805b0bea2c3bd8c78dc6fe98ac5bd78db11" 2051 | dependencies = [ 2052 | "proc-macro2", 2053 | "quote", 2054 | "syn 2.0.58", 2055 | ] 2056 | 2057 | [[package]] 2058 | name = "memchr" 2059 | version = "2.7.2" 2060 | source = "registry+https://github.com/rust-lang/crates.io-index" 2061 | checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" 2062 | 2063 | [[package]] 2064 | name = "memoffset" 2065 | version = "0.7.1" 2066 | source = "registry+https://github.com/rust-lang/crates.io-index" 2067 | checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" 2068 | dependencies = [ 2069 | "autocfg", 2070 | ] 2071 | 2072 | [[package]] 2073 | name = "memoffset" 2074 | version = "0.9.1" 2075 | source = "registry+https://github.com/rust-lang/crates.io-index" 2076 | checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" 2077 | dependencies = [ 2078 | "autocfg", 2079 | ] 2080 | 2081 | [[package]] 2082 | name = "miette" 2083 | version = "5.10.0" 2084 | source = "registry+https://github.com/rust-lang/crates.io-index" 2085 | checksum = "59bb584eaeeab6bd0226ccf3509a69d7936d148cf3d036ad350abe35e8c6856e" 2086 | dependencies = [ 2087 | "miette-derive", 2088 | "once_cell", 2089 | "thiserror", 2090 | "unicode-width", 2091 | ] 2092 | 2093 | [[package]] 2094 | name = "miette-derive" 2095 | version = "5.10.0" 2096 | source = "registry+https://github.com/rust-lang/crates.io-index" 2097 | checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" 2098 | dependencies = [ 2099 | "proc-macro2", 2100 | "quote", 2101 | "syn 2.0.58", 2102 | ] 2103 | 2104 | [[package]] 2105 | name = "mime" 2106 | version = "0.3.17" 2107 | source = "registry+https://github.com/rust-lang/crates.io-index" 2108 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 2109 | 2110 | [[package]] 2111 | name = "minimal-lexical" 2112 | version = "0.2.1" 2113 | source = "registry+https://github.com/rust-lang/crates.io-index" 2114 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 2115 | 2116 | [[package]] 2117 | name = "miniz_oxide" 2118 | version = "0.7.2" 2119 | source = "registry+https://github.com/rust-lang/crates.io-index" 2120 | checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" 2121 | dependencies = [ 2122 | "adler", 2123 | ] 2124 | 2125 | [[package]] 2126 | name = "mio" 2127 | version = "0.8.11" 2128 | source = "registry+https://github.com/rust-lang/crates.io-index" 2129 | checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" 2130 | dependencies = [ 2131 | "libc", 2132 | "log", 2133 | "wasi", 2134 | "windows-sys 0.48.0", 2135 | ] 2136 | 2137 | [[package]] 2138 | name = "moveit" 2139 | version = "0.6.0" 2140 | source = "registry+https://github.com/rust-lang/crates.io-index" 2141 | checksum = "87d7335204cb6ef7bd647fa6db0be3e4d7aa25b5823a7aa030027ddf512cefba" 2142 | dependencies = [ 2143 | "cxx", 2144 | ] 2145 | 2146 | [[package]] 2147 | name = "ndk-context" 2148 | version = "0.1.1" 2149 | source = "registry+https://github.com/rust-lang/crates.io-index" 2150 | checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" 2151 | 2152 | [[package]] 2153 | name = "newline-converter" 2154 | version = "0.3.0" 2155 | source = "registry+https://github.com/rust-lang/crates.io-index" 2156 | checksum = "47b6b097ecb1cbfed438542d16e84fd7ad9b0c76c8a65b7f9039212a3d14dc7f" 2157 | dependencies = [ 2158 | "unicode-segmentation", 2159 | ] 2160 | 2161 | [[package]] 2162 | name = "nix" 2163 | version = "0.26.4" 2164 | source = "registry+https://github.com/rust-lang/crates.io-index" 2165 | checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" 2166 | dependencies = [ 2167 | "bitflags 1.3.2", 2168 | "cfg-if", 2169 | "libc", 2170 | "memoffset 0.7.1", 2171 | ] 2172 | 2173 | [[package]] 2174 | name = "nom" 2175 | version = "7.1.3" 2176 | source = "registry+https://github.com/rust-lang/crates.io-index" 2177 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" 2178 | dependencies = [ 2179 | "memchr", 2180 | "minimal-lexical", 2181 | ] 2182 | 2183 | [[package]] 2184 | name = "normpath" 2185 | version = "1.2.0" 2186 | source = "registry+https://github.com/rust-lang/crates.io-index" 2187 | checksum = "5831952a9476f2fed74b77d74182fa5ddc4d21c72ec45a333b250e3ed0272804" 2188 | dependencies = [ 2189 | "windows-sys 0.52.0", 2190 | ] 2191 | 2192 | [[package]] 2193 | name = "num-conv" 2194 | version = "0.1.0" 2195 | source = "registry+https://github.com/rust-lang/crates.io-index" 2196 | checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" 2197 | 2198 | [[package]] 2199 | name = "num-traits" 2200 | version = "0.2.18" 2201 | source = "registry+https://github.com/rust-lang/crates.io-index" 2202 | checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" 2203 | dependencies = [ 2204 | "autocfg", 2205 | ] 2206 | 2207 | [[package]] 2208 | name = "num_cpus" 2209 | version = "1.16.0" 2210 | source = "registry+https://github.com/rust-lang/crates.io-index" 2211 | checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" 2212 | dependencies = [ 2213 | "hermit-abi 0.3.9", 2214 | "libc", 2215 | ] 2216 | 2217 | [[package]] 2218 | name = "objc" 2219 | version = "0.2.7" 2220 | source = "registry+https://github.com/rust-lang/crates.io-index" 2221 | checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" 2222 | dependencies = [ 2223 | "malloc_buf", 2224 | ] 2225 | 2226 | [[package]] 2227 | name = "object" 2228 | version = "0.32.2" 2229 | source = "registry+https://github.com/rust-lang/crates.io-index" 2230 | checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" 2231 | dependencies = [ 2232 | "memchr", 2233 | ] 2234 | 2235 | [[package]] 2236 | name = "once_cell" 2237 | version = "1.19.0" 2238 | source = "registry+https://github.com/rust-lang/crates.io-index" 2239 | checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" 2240 | 2241 | [[package]] 2242 | name = "opaque-debug" 2243 | version = "0.3.1" 2244 | source = "registry+https://github.com/rust-lang/crates.io-index" 2245 | checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" 2246 | 2247 | [[package]] 2248 | name = "ordered-multimap" 2249 | version = "0.7.3" 2250 | source = "registry+https://github.com/rust-lang/crates.io-index" 2251 | checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79" 2252 | dependencies = [ 2253 | "dlv-list", 2254 | "hashbrown 0.14.3", 2255 | ] 2256 | 2257 | [[package]] 2258 | name = "ordered-stream" 2259 | version = "0.2.0" 2260 | source = "registry+https://github.com/rust-lang/crates.io-index" 2261 | checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" 2262 | dependencies = [ 2263 | "futures-core", 2264 | "pin-project-lite", 2265 | ] 2266 | 2267 | [[package]] 2268 | name = "os_info" 2269 | version = "3.8.2" 2270 | source = "registry+https://github.com/rust-lang/crates.io-index" 2271 | checksum = "ae99c7fa6dd38c7cafe1ec085e804f8f555a2f8659b0dbe03f1f9963a9b51092" 2272 | dependencies = [ 2273 | "log", 2274 | "serde", 2275 | "windows-sys 0.52.0", 2276 | ] 2277 | 2278 | [[package]] 2279 | name = "ovr_overlay" 2280 | version = "0.0.0" 2281 | source = "git+https://github.com/Shays-Forks/ovr_overlay.git#adeb7e657cf3c1cc26553f276a77f2dee4c7ecde" 2282 | dependencies = [ 2283 | "derive_more", 2284 | "enumset", 2285 | "lazy_static", 2286 | "log", 2287 | "ovr_overlay_sys", 2288 | "slice-of-array", 2289 | "thiserror", 2290 | ] 2291 | 2292 | [[package]] 2293 | name = "ovr_overlay_sys" 2294 | version = "0.0.0" 2295 | source = "git+https://github.com/Shays-Forks/ovr_overlay.git#adeb7e657cf3c1cc26553f276a77f2dee4c7ecde" 2296 | dependencies = [ 2297 | "autocxx", 2298 | "autocxx-build", 2299 | "cxx", 2300 | "normpath", 2301 | ] 2302 | 2303 | [[package]] 2304 | name = "parking" 2305 | version = "2.2.0" 2306 | source = "registry+https://github.com/rust-lang/crates.io-index" 2307 | checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" 2308 | 2309 | [[package]] 2310 | name = "parking_lot" 2311 | version = "0.12.1" 2312 | source = "registry+https://github.com/rust-lang/crates.io-index" 2313 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 2314 | dependencies = [ 2315 | "lock_api", 2316 | "parking_lot_core", 2317 | ] 2318 | 2319 | [[package]] 2320 | name = "parking_lot_core" 2321 | version = "0.9.9" 2322 | source = "registry+https://github.com/rust-lang/crates.io-index" 2323 | checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" 2324 | dependencies = [ 2325 | "cfg-if", 2326 | "libc", 2327 | "redox_syscall", 2328 | "smallvec", 2329 | "windows-targets 0.48.5", 2330 | ] 2331 | 2332 | [[package]] 2333 | name = "path-absolutize" 2334 | version = "3.1.1" 2335 | source = "registry+https://github.com/rust-lang/crates.io-index" 2336 | checksum = "e4af381fe79fa195b4909485d99f73a80792331df0625188e707854f0b3383f5" 2337 | dependencies = [ 2338 | "path-dedot", 2339 | ] 2340 | 2341 | [[package]] 2342 | name = "path-dedot" 2343 | version = "3.1.1" 2344 | source = "registry+https://github.com/rust-lang/crates.io-index" 2345 | checksum = "07ba0ad7e047712414213ff67533e6dd477af0a4e1d14fb52343e53d30ea9397" 2346 | dependencies = [ 2347 | "once_cell", 2348 | ] 2349 | 2350 | [[package]] 2351 | name = "pbkdf2" 2352 | version = "0.12.2" 2353 | source = "registry+https://github.com/rust-lang/crates.io-index" 2354 | checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" 2355 | dependencies = [ 2356 | "digest", 2357 | "hmac", 2358 | ] 2359 | 2360 | [[package]] 2361 | name = "peeking_take_while" 2362 | version = "0.1.2" 2363 | source = "registry+https://github.com/rust-lang/crates.io-index" 2364 | checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" 2365 | 2366 | [[package]] 2367 | name = "percent-encoding" 2368 | version = "2.3.1" 2369 | source = "registry+https://github.com/rust-lang/crates.io-index" 2370 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 2371 | 2372 | [[package]] 2373 | name = "pin-project" 2374 | version = "1.1.5" 2375 | source = "registry+https://github.com/rust-lang/crates.io-index" 2376 | checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" 2377 | dependencies = [ 2378 | "pin-project-internal", 2379 | ] 2380 | 2381 | [[package]] 2382 | name = "pin-project-internal" 2383 | version = "1.1.5" 2384 | source = "registry+https://github.com/rust-lang/crates.io-index" 2385 | checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" 2386 | dependencies = [ 2387 | "proc-macro2", 2388 | "quote", 2389 | "syn 2.0.58", 2390 | ] 2391 | 2392 | [[package]] 2393 | name = "pin-project-lite" 2394 | version = "0.2.14" 2395 | source = "registry+https://github.com/rust-lang/crates.io-index" 2396 | checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" 2397 | 2398 | [[package]] 2399 | name = "pin-utils" 2400 | version = "0.1.0" 2401 | source = "registry+https://github.com/rust-lang/crates.io-index" 2402 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 2403 | 2404 | [[package]] 2405 | name = "piper" 2406 | version = "0.2.1" 2407 | source = "registry+https://github.com/rust-lang/crates.io-index" 2408 | checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" 2409 | dependencies = [ 2410 | "atomic-waker", 2411 | "fastrand 2.0.2", 2412 | "futures-io", 2413 | ] 2414 | 2415 | [[package]] 2416 | name = "pkg-config" 2417 | version = "0.3.30" 2418 | source = "registry+https://github.com/rust-lang/crates.io-index" 2419 | checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" 2420 | 2421 | [[package]] 2422 | name = "plugin-chatbox" 2423 | version = "2.6.4" 2424 | dependencies = [ 2425 | "anyhow", 2426 | "async-ffi", 2427 | "derive-config", 2428 | "rosc", 2429 | "serde", 2430 | "tokio", 2431 | "toml 0.8.12", 2432 | "vrc-osc", 2433 | ] 2434 | 2435 | [[package]] 2436 | name = "plugin-clock" 2437 | version = "2.6.4" 2438 | dependencies = [ 2439 | "anyhow", 2440 | "derive-config", 2441 | "rosc", 2442 | "serde", 2443 | "tokio", 2444 | "toml 0.8.12", 2445 | ] 2446 | 2447 | [[package]] 2448 | name = "plugin-control" 2449 | version = "2.6.4" 2450 | dependencies = [ 2451 | "anyhow", 2452 | "enigo", 2453 | "rosc", 2454 | "tokio", 2455 | "windows 0.54.0", 2456 | ] 2457 | 2458 | [[package]] 2459 | name = "plugin-debug" 2460 | version = "2.6.4" 2461 | dependencies = [ 2462 | "anyhow", 2463 | "rosc", 2464 | "tokio", 2465 | ] 2466 | 2467 | [[package]] 2468 | name = "plugin-lastfm" 2469 | version = "2.6.4" 2470 | dependencies = [ 2471 | "anyhow", 2472 | "async-ffi", 2473 | "derive-config", 2474 | "dotenvy_macro", 2475 | "inquire", 2476 | "serde", 2477 | "serde-this-or-that", 2478 | "structstruck", 2479 | "terminal-link", 2480 | "tokio", 2481 | "toml 0.8.12", 2482 | "ureq", 2483 | "vrc-osc", 2484 | ] 2485 | 2486 | [[package]] 2487 | name = "plugin-spotify" 2488 | version = "2.6.4" 2489 | dependencies = [ 2490 | "anyhow", 2491 | "async-ffi", 2492 | "derive-config", 2493 | "dotenvy_macro", 2494 | "ferrispot", 2495 | "inquire", 2496 | "rosc", 2497 | "serde", 2498 | "spotify-lyrics", 2499 | "terminal-link", 2500 | "tiny_http", 2501 | "tokio", 2502 | "toml 0.8.12", 2503 | "url", 2504 | "webbrowser", 2505 | ] 2506 | 2507 | [[package]] 2508 | name = "plugin-steamvr" 2509 | version = "2.6.4" 2510 | dependencies = [ 2511 | "anyhow", 2512 | "derive-config", 2513 | "ovr_overlay", 2514 | "serde", 2515 | "serde_json", 2516 | "structstruck", 2517 | "tokio", 2518 | "toml 0.8.12", 2519 | ] 2520 | 2521 | [[package]] 2522 | name = "polling" 2523 | version = "2.8.0" 2524 | source = "registry+https://github.com/rust-lang/crates.io-index" 2525 | checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" 2526 | dependencies = [ 2527 | "autocfg", 2528 | "bitflags 1.3.2", 2529 | "cfg-if", 2530 | "concurrent-queue", 2531 | "libc", 2532 | "log", 2533 | "pin-project-lite", 2534 | "windows-sys 0.48.0", 2535 | ] 2536 | 2537 | [[package]] 2538 | name = "polling" 2539 | version = "3.6.0" 2540 | source = "registry+https://github.com/rust-lang/crates.io-index" 2541 | checksum = "e0c976a60b2d7e99d6f229e414670a9b85d13ac305cc6d1e9c134de58c5aaaf6" 2542 | dependencies = [ 2543 | "cfg-if", 2544 | "concurrent-queue", 2545 | "hermit-abi 0.3.9", 2546 | "pin-project-lite", 2547 | "rustix 0.38.32", 2548 | "tracing", 2549 | "windows-sys 0.52.0", 2550 | ] 2551 | 2552 | [[package]] 2553 | name = "polyval" 2554 | version = "0.6.2" 2555 | source = "registry+https://github.com/rust-lang/crates.io-index" 2556 | checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" 2557 | dependencies = [ 2558 | "cfg-if", 2559 | "cpufeatures", 2560 | "opaque-debug", 2561 | "universal-hash", 2562 | ] 2563 | 2564 | [[package]] 2565 | name = "powerfmt" 2566 | version = "0.2.0" 2567 | source = "registry+https://github.com/rust-lang/crates.io-index" 2568 | checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" 2569 | 2570 | [[package]] 2571 | name = "ppv-lite86" 2572 | version = "0.2.17" 2573 | source = "registry+https://github.com/rust-lang/crates.io-index" 2574 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 2575 | 2576 | [[package]] 2577 | name = "prettyplease" 2578 | version = "0.2.17" 2579 | source = "registry+https://github.com/rust-lang/crates.io-index" 2580 | checksum = "8d3928fb5db768cb86f891ff014f0144589297e3c6a1aba6ed7cecfdace270c7" 2581 | dependencies = [ 2582 | "proc-macro2", 2583 | "syn 2.0.58", 2584 | ] 2585 | 2586 | [[package]] 2587 | name = "proc-macro-crate" 2588 | version = "1.3.1" 2589 | source = "registry+https://github.com/rust-lang/crates.io-index" 2590 | checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" 2591 | dependencies = [ 2592 | "once_cell", 2593 | "toml_edit 0.19.15", 2594 | ] 2595 | 2596 | [[package]] 2597 | name = "proc-macro-error" 2598 | version = "1.0.4" 2599 | source = "registry+https://github.com/rust-lang/crates.io-index" 2600 | checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" 2601 | dependencies = [ 2602 | "proc-macro-error-attr", 2603 | "proc-macro2", 2604 | "quote", 2605 | "syn 1.0.109", 2606 | "version_check", 2607 | ] 2608 | 2609 | [[package]] 2610 | name = "proc-macro-error-attr" 2611 | version = "1.0.4" 2612 | source = "registry+https://github.com/rust-lang/crates.io-index" 2613 | checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" 2614 | dependencies = [ 2615 | "proc-macro2", 2616 | "quote", 2617 | "version_check", 2618 | ] 2619 | 2620 | [[package]] 2621 | name = "proc-macro2" 2622 | version = "1.0.79" 2623 | source = "registry+https://github.com/rust-lang/crates.io-index" 2624 | checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" 2625 | dependencies = [ 2626 | "unicode-ident", 2627 | ] 2628 | 2629 | [[package]] 2630 | name = "psl-types" 2631 | version = "2.0.11" 2632 | source = "registry+https://github.com/rust-lang/crates.io-index" 2633 | checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" 2634 | 2635 | [[package]] 2636 | name = "publicsuffix" 2637 | version = "2.2.3" 2638 | source = "registry+https://github.com/rust-lang/crates.io-index" 2639 | checksum = "96a8c1bda5ae1af7f99a2962e49df150414a43d62404644d98dd5c3a93d07457" 2640 | dependencies = [ 2641 | "idna 0.3.0", 2642 | "psl-types", 2643 | ] 2644 | 2645 | [[package]] 2646 | name = "quote" 2647 | version = "1.0.36" 2648 | source = "registry+https://github.com/rust-lang/crates.io-index" 2649 | checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" 2650 | dependencies = [ 2651 | "proc-macro2", 2652 | ] 2653 | 2654 | [[package]] 2655 | name = "rand" 2656 | version = "0.8.5" 2657 | source = "registry+https://github.com/rust-lang/crates.io-index" 2658 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 2659 | dependencies = [ 2660 | "libc", 2661 | "rand_chacha", 2662 | "rand_core", 2663 | ] 2664 | 2665 | [[package]] 2666 | name = "rand_chacha" 2667 | version = "0.3.1" 2668 | source = "registry+https://github.com/rust-lang/crates.io-index" 2669 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 2670 | dependencies = [ 2671 | "ppv-lite86", 2672 | "rand_core", 2673 | ] 2674 | 2675 | [[package]] 2676 | name = "rand_core" 2677 | version = "0.6.4" 2678 | source = "registry+https://github.com/rust-lang/crates.io-index" 2679 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 2680 | dependencies = [ 2681 | "getrandom", 2682 | ] 2683 | 2684 | [[package]] 2685 | name = "raw-window-handle" 2686 | version = "0.5.2" 2687 | source = "registry+https://github.com/rust-lang/crates.io-index" 2688 | checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" 2689 | 2690 | [[package]] 2691 | name = "redox_syscall" 2692 | version = "0.4.1" 2693 | source = "registry+https://github.com/rust-lang/crates.io-index" 2694 | checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" 2695 | dependencies = [ 2696 | "bitflags 1.3.2", 2697 | ] 2698 | 2699 | [[package]] 2700 | name = "regex" 2701 | version = "1.10.4" 2702 | source = "registry+https://github.com/rust-lang/crates.io-index" 2703 | checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" 2704 | dependencies = [ 2705 | "aho-corasick", 2706 | "memchr", 2707 | "regex-automata", 2708 | "regex-syntax", 2709 | ] 2710 | 2711 | [[package]] 2712 | name = "regex-automata" 2713 | version = "0.4.6" 2714 | source = "registry+https://github.com/rust-lang/crates.io-index" 2715 | checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" 2716 | dependencies = [ 2717 | "aho-corasick", 2718 | "memchr", 2719 | "regex-syntax", 2720 | ] 2721 | 2722 | [[package]] 2723 | name = "regex-syntax" 2724 | version = "0.8.3" 2725 | source = "registry+https://github.com/rust-lang/crates.io-index" 2726 | checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" 2727 | 2728 | [[package]] 2729 | name = "reqwest" 2730 | version = "0.11.27" 2731 | source = "registry+https://github.com/rust-lang/crates.io-index" 2732 | checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" 2733 | dependencies = [ 2734 | "base64 0.21.7", 2735 | "bytes", 2736 | "encoding_rs", 2737 | "futures-core", 2738 | "futures-util", 2739 | "h2", 2740 | "http 0.2.12", 2741 | "http-body 0.4.6", 2742 | "hyper 0.14.28", 2743 | "hyper-rustls 0.24.2", 2744 | "ipnet", 2745 | "js-sys", 2746 | "log", 2747 | "mime", 2748 | "once_cell", 2749 | "percent-encoding", 2750 | "pin-project-lite", 2751 | "rustls 0.21.10", 2752 | "rustls-pemfile 1.0.4", 2753 | "serde", 2754 | "serde_json", 2755 | "serde_urlencoded", 2756 | "sync_wrapper", 2757 | "system-configuration", 2758 | "tokio", 2759 | "tokio-rustls 0.24.1", 2760 | "tower-service", 2761 | "url", 2762 | "wasm-bindgen", 2763 | "wasm-bindgen-futures", 2764 | "web-sys", 2765 | "webpki-roots 0.25.4", 2766 | "winreg 0.50.0", 2767 | ] 2768 | 2769 | [[package]] 2770 | name = "reqwest" 2771 | version = "0.12.3" 2772 | source = "registry+https://github.com/rust-lang/crates.io-index" 2773 | checksum = "3e6cc1e89e689536eb5aeede61520e874df5a4707df811cd5da4aa5fbb2aae19" 2774 | dependencies = [ 2775 | "base64 0.22.0", 2776 | "bytes", 2777 | "cookie", 2778 | "cookie_store", 2779 | "futures-core", 2780 | "futures-util", 2781 | "http 1.1.0", 2782 | "http-body 1.0.0", 2783 | "http-body-util", 2784 | "hyper 1.2.0", 2785 | "hyper-rustls 0.26.0", 2786 | "hyper-util", 2787 | "ipnet", 2788 | "js-sys", 2789 | "log", 2790 | "mime", 2791 | "once_cell", 2792 | "percent-encoding", 2793 | "pin-project-lite", 2794 | "rustls 0.22.3", 2795 | "rustls-pemfile 2.1.2", 2796 | "rustls-pki-types", 2797 | "serde", 2798 | "serde_json", 2799 | "serde_urlencoded", 2800 | "sync_wrapper", 2801 | "tokio", 2802 | "tokio-rustls 0.25.0", 2803 | "tower-service", 2804 | "url", 2805 | "wasm-bindgen", 2806 | "wasm-bindgen-futures", 2807 | "web-sys", 2808 | "webpki-roots 0.26.1", 2809 | "winreg 0.52.0", 2810 | ] 2811 | 2812 | [[package]] 2813 | name = "ring" 2814 | version = "0.17.8" 2815 | source = "registry+https://github.com/rust-lang/crates.io-index" 2816 | checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" 2817 | dependencies = [ 2818 | "cc", 2819 | "cfg-if", 2820 | "getrandom", 2821 | "libc", 2822 | "spin", 2823 | "untrusted", 2824 | "windows-sys 0.52.0", 2825 | ] 2826 | 2827 | [[package]] 2828 | name = "rookie" 2829 | version = "0.4.0" 2830 | source = "registry+https://github.com/rust-lang/crates.io-index" 2831 | checksum = "a04614d74d89602395872864d41fe0760bfa9d5e3d9ada262b8d78f6b30d7f07" 2832 | dependencies = [ 2833 | "aes", 2834 | "aes-gcm", 2835 | "anyhow", 2836 | "base64 0.22.0", 2837 | "byteorder", 2838 | "cbc", 2839 | "cfg-if", 2840 | "glob", 2841 | "libesedb", 2842 | "log", 2843 | "lz4_flex", 2844 | "pbkdf2", 2845 | "regex", 2846 | "rusqlite", 2847 | "rust-ini", 2848 | "serde", 2849 | "serde_json", 2850 | "sha1", 2851 | "url", 2852 | "windows 0.51.1", 2853 | "zbus", 2854 | "zvariant", 2855 | ] 2856 | 2857 | [[package]] 2858 | name = "rosc" 2859 | version = "0.10.1" 2860 | source = "registry+https://github.com/rust-lang/crates.io-index" 2861 | checksum = "b2e63d9e6b0d090be1485cf159b1e04c3973d2d3e1614963544ea2ff47a4a981" 2862 | dependencies = [ 2863 | "byteorder", 2864 | "nom", 2865 | ] 2866 | 2867 | [[package]] 2868 | name = "rusqlite" 2869 | version = "0.31.0" 2870 | source = "registry+https://github.com/rust-lang/crates.io-index" 2871 | checksum = "b838eba278d213a8beaf485bd313fd580ca4505a00d5871caeb1457c55322cae" 2872 | dependencies = [ 2873 | "bitflags 2.5.0", 2874 | "fallible-iterator", 2875 | "fallible-streaming-iterator", 2876 | "hashlink", 2877 | "libsqlite3-sys", 2878 | "smallvec", 2879 | ] 2880 | 2881 | [[package]] 2882 | name = "rust-ini" 2883 | version = "0.21.0" 2884 | source = "registry+https://github.com/rust-lang/crates.io-index" 2885 | checksum = "0d625ed57d8f49af6cfa514c42e1a71fadcff60eb0b1c517ff82fe41aa025b41" 2886 | dependencies = [ 2887 | "cfg-if", 2888 | "ordered-multimap", 2889 | "trim-in-place", 2890 | ] 2891 | 2892 | [[package]] 2893 | name = "rustc-demangle" 2894 | version = "0.1.23" 2895 | source = "registry+https://github.com/rust-lang/crates.io-index" 2896 | checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" 2897 | 2898 | [[package]] 2899 | name = "rustc-hash" 2900 | version = "1.1.0" 2901 | source = "registry+https://github.com/rust-lang/crates.io-index" 2902 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 2903 | 2904 | [[package]] 2905 | name = "rustc_version" 2906 | version = "0.4.0" 2907 | source = "registry+https://github.com/rust-lang/crates.io-index" 2908 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 2909 | dependencies = [ 2910 | "semver", 2911 | ] 2912 | 2913 | [[package]] 2914 | name = "rustix" 2915 | version = "0.37.27" 2916 | source = "registry+https://github.com/rust-lang/crates.io-index" 2917 | checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" 2918 | dependencies = [ 2919 | "bitflags 1.3.2", 2920 | "errno", 2921 | "io-lifetimes", 2922 | "libc", 2923 | "linux-raw-sys 0.3.8", 2924 | "windows-sys 0.48.0", 2925 | ] 2926 | 2927 | [[package]] 2928 | name = "rustix" 2929 | version = "0.38.32" 2930 | source = "registry+https://github.com/rust-lang/crates.io-index" 2931 | checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" 2932 | dependencies = [ 2933 | "bitflags 2.5.0", 2934 | "errno", 2935 | "libc", 2936 | "linux-raw-sys 0.4.13", 2937 | "windows-sys 0.52.0", 2938 | ] 2939 | 2940 | [[package]] 2941 | name = "rustls" 2942 | version = "0.21.10" 2943 | source = "registry+https://github.com/rust-lang/crates.io-index" 2944 | checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" 2945 | dependencies = [ 2946 | "log", 2947 | "ring", 2948 | "rustls-webpki 0.101.7", 2949 | "sct", 2950 | ] 2951 | 2952 | [[package]] 2953 | name = "rustls" 2954 | version = "0.22.3" 2955 | source = "registry+https://github.com/rust-lang/crates.io-index" 2956 | checksum = "99008d7ad0bbbea527ec27bddbc0e432c5b87d8175178cee68d2eec9c4a1813c" 2957 | dependencies = [ 2958 | "log", 2959 | "ring", 2960 | "rustls-pki-types", 2961 | "rustls-webpki 0.102.2", 2962 | "subtle", 2963 | "zeroize", 2964 | ] 2965 | 2966 | [[package]] 2967 | name = "rustls-pemfile" 2968 | version = "1.0.4" 2969 | source = "registry+https://github.com/rust-lang/crates.io-index" 2970 | checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" 2971 | dependencies = [ 2972 | "base64 0.21.7", 2973 | ] 2974 | 2975 | [[package]] 2976 | name = "rustls-pemfile" 2977 | version = "2.1.2" 2978 | source = "registry+https://github.com/rust-lang/crates.io-index" 2979 | checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" 2980 | dependencies = [ 2981 | "base64 0.22.0", 2982 | "rustls-pki-types", 2983 | ] 2984 | 2985 | [[package]] 2986 | name = "rustls-pki-types" 2987 | version = "1.4.1" 2988 | source = "registry+https://github.com/rust-lang/crates.io-index" 2989 | checksum = "ecd36cc4259e3e4514335c4a138c6b43171a8d61d8f5c9348f9fc7529416f247" 2990 | 2991 | [[package]] 2992 | name = "rustls-webpki" 2993 | version = "0.101.7" 2994 | source = "registry+https://github.com/rust-lang/crates.io-index" 2995 | checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" 2996 | dependencies = [ 2997 | "ring", 2998 | "untrusted", 2999 | ] 3000 | 3001 | [[package]] 3002 | name = "rustls-webpki" 3003 | version = "0.102.2" 3004 | source = "registry+https://github.com/rust-lang/crates.io-index" 3005 | checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" 3006 | dependencies = [ 3007 | "ring", 3008 | "rustls-pki-types", 3009 | "untrusted", 3010 | ] 3011 | 3012 | [[package]] 3013 | name = "rustversion" 3014 | version = "1.0.15" 3015 | source = "registry+https://github.com/rust-lang/crates.io-index" 3016 | checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" 3017 | 3018 | [[package]] 3019 | name = "ryu" 3020 | version = "1.0.17" 3021 | source = "registry+https://github.com/rust-lang/crates.io-index" 3022 | checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" 3023 | 3024 | [[package]] 3025 | name = "same-file" 3026 | version = "1.0.6" 3027 | source = "registry+https://github.com/rust-lang/crates.io-index" 3028 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 3029 | dependencies = [ 3030 | "winapi-util", 3031 | ] 3032 | 3033 | [[package]] 3034 | name = "scopeguard" 3035 | version = "1.2.0" 3036 | source = "registry+https://github.com/rust-lang/crates.io-index" 3037 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 3038 | 3039 | [[package]] 3040 | name = "sct" 3041 | version = "0.7.1" 3042 | source = "registry+https://github.com/rust-lang/crates.io-index" 3043 | checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" 3044 | dependencies = [ 3045 | "ring", 3046 | "untrusted", 3047 | ] 3048 | 3049 | [[package]] 3050 | name = "semver" 3051 | version = "1.0.22" 3052 | source = "registry+https://github.com/rust-lang/crates.io-index" 3053 | checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" 3054 | 3055 | [[package]] 3056 | name = "serde" 3057 | version = "1.0.197" 3058 | source = "registry+https://github.com/rust-lang/crates.io-index" 3059 | checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" 3060 | dependencies = [ 3061 | "serde_derive", 3062 | ] 3063 | 3064 | [[package]] 3065 | name = "serde-this-or-that" 3066 | version = "0.4.2" 3067 | source = "registry+https://github.com/rust-lang/crates.io-index" 3068 | checksum = "634c5a3cb041e56cc2964386151c67d520f845445789da3bd46bfb1c94f5e3bb" 3069 | dependencies = [ 3070 | "serde", 3071 | ] 3072 | 3073 | [[package]] 3074 | name = "serde_derive" 3075 | version = "1.0.197" 3076 | source = "registry+https://github.com/rust-lang/crates.io-index" 3077 | checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" 3078 | dependencies = [ 3079 | "proc-macro2", 3080 | "quote", 3081 | "syn 2.0.58", 3082 | ] 3083 | 3084 | [[package]] 3085 | name = "serde_json" 3086 | version = "1.0.115" 3087 | source = "registry+https://github.com/rust-lang/crates.io-index" 3088 | checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" 3089 | dependencies = [ 3090 | "itoa", 3091 | "ryu", 3092 | "serde", 3093 | ] 3094 | 3095 | [[package]] 3096 | name = "serde_repr" 3097 | version = "0.1.19" 3098 | source = "registry+https://github.com/rust-lang/crates.io-index" 3099 | checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" 3100 | dependencies = [ 3101 | "proc-macro2", 3102 | "quote", 3103 | "syn 2.0.58", 3104 | ] 3105 | 3106 | [[package]] 3107 | name = "serde_spanned" 3108 | version = "0.6.5" 3109 | source = "registry+https://github.com/rust-lang/crates.io-index" 3110 | checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" 3111 | dependencies = [ 3112 | "serde", 3113 | ] 3114 | 3115 | [[package]] 3116 | name = "serde_urlencoded" 3117 | version = "0.7.1" 3118 | source = "registry+https://github.com/rust-lang/crates.io-index" 3119 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 3120 | dependencies = [ 3121 | "form_urlencoded", 3122 | "itoa", 3123 | "ryu", 3124 | "serde", 3125 | ] 3126 | 3127 | [[package]] 3128 | name = "serde_with" 3129 | version = "3.7.0" 3130 | source = "registry+https://github.com/rust-lang/crates.io-index" 3131 | checksum = "ee80b0e361bbf88fd2f6e242ccd19cfda072cb0faa6ae694ecee08199938569a" 3132 | dependencies = [ 3133 | "base64 0.21.7", 3134 | "chrono", 3135 | "hex", 3136 | "indexmap 1.9.3", 3137 | "indexmap 2.2.6", 3138 | "serde", 3139 | "serde_derive", 3140 | "serde_json", 3141 | "serde_with_macros", 3142 | "time", 3143 | ] 3144 | 3145 | [[package]] 3146 | name = "serde_with_macros" 3147 | version = "3.7.0" 3148 | source = "registry+https://github.com/rust-lang/crates.io-index" 3149 | checksum = "6561dc161a9224638a31d876ccdfefbc1df91d3f3a8342eddb35f055d48c7655" 3150 | dependencies = [ 3151 | "darling", 3152 | "proc-macro2", 3153 | "quote", 3154 | "syn 2.0.58", 3155 | ] 3156 | 3157 | [[package]] 3158 | name = "sha1" 3159 | version = "0.10.6" 3160 | source = "registry+https://github.com/rust-lang/crates.io-index" 3161 | checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" 3162 | dependencies = [ 3163 | "cfg-if", 3164 | "cpufeatures", 3165 | "digest", 3166 | ] 3167 | 3168 | [[package]] 3169 | name = "sha2" 3170 | version = "0.10.8" 3171 | source = "registry+https://github.com/rust-lang/crates.io-index" 3172 | checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" 3173 | dependencies = [ 3174 | "cfg-if", 3175 | "cpufeatures", 3176 | "digest", 3177 | ] 3178 | 3179 | [[package]] 3180 | name = "shlex" 3181 | version = "1.3.0" 3182 | source = "registry+https://github.com/rust-lang/crates.io-index" 3183 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 3184 | 3185 | [[package]] 3186 | name = "signal-hook" 3187 | version = "0.3.17" 3188 | source = "registry+https://github.com/rust-lang/crates.io-index" 3189 | checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" 3190 | dependencies = [ 3191 | "libc", 3192 | "signal-hook-registry", 3193 | ] 3194 | 3195 | [[package]] 3196 | name = "signal-hook-mio" 3197 | version = "0.2.3" 3198 | source = "registry+https://github.com/rust-lang/crates.io-index" 3199 | checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" 3200 | dependencies = [ 3201 | "libc", 3202 | "mio", 3203 | "signal-hook", 3204 | ] 3205 | 3206 | [[package]] 3207 | name = "signal-hook-registry" 3208 | version = "1.4.1" 3209 | source = "registry+https://github.com/rust-lang/crates.io-index" 3210 | checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" 3211 | dependencies = [ 3212 | "libc", 3213 | ] 3214 | 3215 | [[package]] 3216 | name = "slab" 3217 | version = "0.4.9" 3218 | source = "registry+https://github.com/rust-lang/crates.io-index" 3219 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 3220 | dependencies = [ 3221 | "autocfg", 3222 | ] 3223 | 3224 | [[package]] 3225 | name = "slice-of-array" 3226 | version = "0.3.2" 3227 | source = "registry+https://github.com/rust-lang/crates.io-index" 3228 | checksum = "a4f120bb98cb4cb0dab21c882968c3cbff79dd23b46f07b1cf5c25044945ce84" 3229 | 3230 | [[package]] 3231 | name = "smallvec" 3232 | version = "1.13.2" 3233 | source = "registry+https://github.com/rust-lang/crates.io-index" 3234 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 3235 | 3236 | [[package]] 3237 | name = "socket2" 3238 | version = "0.4.10" 3239 | source = "registry+https://github.com/rust-lang/crates.io-index" 3240 | checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" 3241 | dependencies = [ 3242 | "libc", 3243 | "winapi", 3244 | ] 3245 | 3246 | [[package]] 3247 | name = "socket2" 3248 | version = "0.5.6" 3249 | source = "registry+https://github.com/rust-lang/crates.io-index" 3250 | checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" 3251 | dependencies = [ 3252 | "libc", 3253 | "windows-sys 0.52.0", 3254 | ] 3255 | 3256 | [[package]] 3257 | name = "spin" 3258 | version = "0.9.8" 3259 | source = "registry+https://github.com/rust-lang/crates.io-index" 3260 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 3261 | 3262 | [[package]] 3263 | name = "spotify-lyrics" 3264 | version = "0.0.7" 3265 | source = "registry+https://github.com/rust-lang/crates.io-index" 3266 | checksum = "4bfea799675175dd722a47ec54969a2752308bbde178c75a469c255b3b3d15c7" 3267 | dependencies = [ 3268 | "anyhow", 3269 | "async-trait", 3270 | "lazy_static", 3271 | "maybe-async", 3272 | "reqwest 0.12.3", 3273 | "rookie", 3274 | "serde", 3275 | "serde_with", 3276 | "tracing", 3277 | "url", 3278 | ] 3279 | 3280 | [[package]] 3281 | name = "static_assertions" 3282 | version = "1.1.0" 3283 | source = "registry+https://github.com/rust-lang/crates.io-index" 3284 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 3285 | 3286 | [[package]] 3287 | name = "strsim" 3288 | version = "0.10.0" 3289 | source = "registry+https://github.com/rust-lang/crates.io-index" 3290 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 3291 | 3292 | [[package]] 3293 | name = "structstruck" 3294 | version = "0.4.1" 3295 | source = "registry+https://github.com/rust-lang/crates.io-index" 3296 | checksum = "1a052ec87a2d9bdd3a35f85ec6a07a5ac0816e4190b1cbede9d67cccb47ea66d" 3297 | dependencies = [ 3298 | "heck", 3299 | "proc-macro2", 3300 | "quote", 3301 | "venial", 3302 | ] 3303 | 3304 | [[package]] 3305 | name = "strum_macros" 3306 | version = "0.24.3" 3307 | source = "registry+https://github.com/rust-lang/crates.io-index" 3308 | checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" 3309 | dependencies = [ 3310 | "heck", 3311 | "proc-macro2", 3312 | "quote", 3313 | "rustversion", 3314 | "syn 1.0.109", 3315 | ] 3316 | 3317 | [[package]] 3318 | name = "subtle" 3319 | version = "2.5.0" 3320 | source = "registry+https://github.com/rust-lang/crates.io-index" 3321 | checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" 3322 | 3323 | [[package]] 3324 | name = "syn" 3325 | version = "1.0.109" 3326 | source = "registry+https://github.com/rust-lang/crates.io-index" 3327 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 3328 | dependencies = [ 3329 | "proc-macro2", 3330 | "quote", 3331 | "unicode-ident", 3332 | ] 3333 | 3334 | [[package]] 3335 | name = "syn" 3336 | version = "2.0.58" 3337 | source = "registry+https://github.com/rust-lang/crates.io-index" 3338 | checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" 3339 | dependencies = [ 3340 | "proc-macro2", 3341 | "quote", 3342 | "unicode-ident", 3343 | ] 3344 | 3345 | [[package]] 3346 | name = "sync_wrapper" 3347 | version = "0.1.2" 3348 | source = "registry+https://github.com/rust-lang/crates.io-index" 3349 | checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" 3350 | 3351 | [[package]] 3352 | name = "system-configuration" 3353 | version = "0.5.1" 3354 | source = "registry+https://github.com/rust-lang/crates.io-index" 3355 | checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" 3356 | dependencies = [ 3357 | "bitflags 1.3.2", 3358 | "core-foundation", 3359 | "system-configuration-sys", 3360 | ] 3361 | 3362 | [[package]] 3363 | name = "system-configuration-sys" 3364 | version = "0.5.0" 3365 | source = "registry+https://github.com/rust-lang/crates.io-index" 3366 | checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" 3367 | dependencies = [ 3368 | "core-foundation-sys", 3369 | "libc", 3370 | ] 3371 | 3372 | [[package]] 3373 | name = "tempfile" 3374 | version = "3.10.1" 3375 | source = "registry+https://github.com/rust-lang/crates.io-index" 3376 | checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" 3377 | dependencies = [ 3378 | "cfg-if", 3379 | "fastrand 2.0.2", 3380 | "rustix 0.38.32", 3381 | "windows-sys 0.52.0", 3382 | ] 3383 | 3384 | [[package]] 3385 | name = "termcolor" 3386 | version = "1.4.1" 3387 | source = "registry+https://github.com/rust-lang/crates.io-index" 3388 | checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" 3389 | dependencies = [ 3390 | "winapi-util", 3391 | ] 3392 | 3393 | [[package]] 3394 | name = "terminal-link" 3395 | version = "0.1.0" 3396 | source = "registry+https://github.com/rust-lang/crates.io-index" 3397 | checksum = "253bcead4f3aa96243b0f8fa46f9010e87ca23bd5d0c723d474ff1d2417bbdf8" 3398 | 3399 | [[package]] 3400 | name = "thiserror" 3401 | version = "1.0.58" 3402 | source = "registry+https://github.com/rust-lang/crates.io-index" 3403 | checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" 3404 | dependencies = [ 3405 | "thiserror-impl", 3406 | ] 3407 | 3408 | [[package]] 3409 | name = "thiserror-impl" 3410 | version = "1.0.58" 3411 | source = "registry+https://github.com/rust-lang/crates.io-index" 3412 | checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" 3413 | dependencies = [ 3414 | "proc-macro2", 3415 | "quote", 3416 | "syn 2.0.58", 3417 | ] 3418 | 3419 | [[package]] 3420 | name = "thread_local" 3421 | version = "1.1.8" 3422 | source = "registry+https://github.com/rust-lang/crates.io-index" 3423 | checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" 3424 | dependencies = [ 3425 | "cfg-if", 3426 | "once_cell", 3427 | ] 3428 | 3429 | [[package]] 3430 | name = "time" 3431 | version = "0.3.36" 3432 | source = "registry+https://github.com/rust-lang/crates.io-index" 3433 | checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" 3434 | dependencies = [ 3435 | "deranged", 3436 | "itoa", 3437 | "num-conv", 3438 | "powerfmt", 3439 | "serde", 3440 | "time-core", 3441 | "time-macros", 3442 | ] 3443 | 3444 | [[package]] 3445 | name = "time-core" 3446 | version = "0.1.2" 3447 | source = "registry+https://github.com/rust-lang/crates.io-index" 3448 | checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" 3449 | 3450 | [[package]] 3451 | name = "time-macros" 3452 | version = "0.2.18" 3453 | source = "registry+https://github.com/rust-lang/crates.io-index" 3454 | checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" 3455 | dependencies = [ 3456 | "num-conv", 3457 | "time-core", 3458 | ] 3459 | 3460 | [[package]] 3461 | name = "tiny-keccak" 3462 | version = "2.0.2" 3463 | source = "registry+https://github.com/rust-lang/crates.io-index" 3464 | checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" 3465 | dependencies = [ 3466 | "crunchy", 3467 | ] 3468 | 3469 | [[package]] 3470 | name = "tiny_http" 3471 | version = "0.12.0" 3472 | source = "registry+https://github.com/rust-lang/crates.io-index" 3473 | checksum = "389915df6413a2e74fb181895f933386023c71110878cd0825588928e64cdc82" 3474 | dependencies = [ 3475 | "ascii", 3476 | "chunked_transfer", 3477 | "httpdate", 3478 | "log", 3479 | ] 3480 | 3481 | [[package]] 3482 | name = "tinyvec" 3483 | version = "1.6.0" 3484 | source = "registry+https://github.com/rust-lang/crates.io-index" 3485 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 3486 | dependencies = [ 3487 | "tinyvec_macros", 3488 | ] 3489 | 3490 | [[package]] 3491 | name = "tinyvec_macros" 3492 | version = "0.1.1" 3493 | source = "registry+https://github.com/rust-lang/crates.io-index" 3494 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 3495 | 3496 | [[package]] 3497 | name = "tokio" 3498 | version = "1.37.0" 3499 | source = "registry+https://github.com/rust-lang/crates.io-index" 3500 | checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" 3501 | dependencies = [ 3502 | "backtrace", 3503 | "bytes", 3504 | "libc", 3505 | "mio", 3506 | "num_cpus", 3507 | "parking_lot", 3508 | "pin-project-lite", 3509 | "signal-hook-registry", 3510 | "socket2 0.5.6", 3511 | "tokio-macros", 3512 | "windows-sys 0.48.0", 3513 | ] 3514 | 3515 | [[package]] 3516 | name = "tokio-macros" 3517 | version = "2.2.0" 3518 | source = "registry+https://github.com/rust-lang/crates.io-index" 3519 | checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" 3520 | dependencies = [ 3521 | "proc-macro2", 3522 | "quote", 3523 | "syn 2.0.58", 3524 | ] 3525 | 3526 | [[package]] 3527 | name = "tokio-rustls" 3528 | version = "0.24.1" 3529 | source = "registry+https://github.com/rust-lang/crates.io-index" 3530 | checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" 3531 | dependencies = [ 3532 | "rustls 0.21.10", 3533 | "tokio", 3534 | ] 3535 | 3536 | [[package]] 3537 | name = "tokio-rustls" 3538 | version = "0.25.0" 3539 | source = "registry+https://github.com/rust-lang/crates.io-index" 3540 | checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" 3541 | dependencies = [ 3542 | "rustls 0.22.3", 3543 | "rustls-pki-types", 3544 | "tokio", 3545 | ] 3546 | 3547 | [[package]] 3548 | name = "tokio-util" 3549 | version = "0.7.10" 3550 | source = "registry+https://github.com/rust-lang/crates.io-index" 3551 | checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" 3552 | dependencies = [ 3553 | "bytes", 3554 | "futures-core", 3555 | "futures-sink", 3556 | "pin-project-lite", 3557 | "tokio", 3558 | "tracing", 3559 | ] 3560 | 3561 | [[package]] 3562 | name = "toml" 3563 | version = "0.5.11" 3564 | source = "registry+https://github.com/rust-lang/crates.io-index" 3565 | checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" 3566 | dependencies = [ 3567 | "serde", 3568 | ] 3569 | 3570 | [[package]] 3571 | name = "toml" 3572 | version = "0.8.12" 3573 | source = "registry+https://github.com/rust-lang/crates.io-index" 3574 | checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" 3575 | dependencies = [ 3576 | "serde", 3577 | "serde_spanned", 3578 | "toml_datetime", 3579 | "toml_edit 0.22.9", 3580 | ] 3581 | 3582 | [[package]] 3583 | name = "toml_datetime" 3584 | version = "0.6.5" 3585 | source = "registry+https://github.com/rust-lang/crates.io-index" 3586 | checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" 3587 | dependencies = [ 3588 | "serde", 3589 | ] 3590 | 3591 | [[package]] 3592 | name = "toml_edit" 3593 | version = "0.19.15" 3594 | source = "registry+https://github.com/rust-lang/crates.io-index" 3595 | checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" 3596 | dependencies = [ 3597 | "indexmap 2.2.6", 3598 | "toml_datetime", 3599 | "winnow 0.5.40", 3600 | ] 3601 | 3602 | [[package]] 3603 | name = "toml_edit" 3604 | version = "0.22.9" 3605 | source = "registry+https://github.com/rust-lang/crates.io-index" 3606 | checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" 3607 | dependencies = [ 3608 | "indexmap 2.2.6", 3609 | "serde", 3610 | "serde_spanned", 3611 | "toml_datetime", 3612 | "winnow 0.6.6", 3613 | ] 3614 | 3615 | [[package]] 3616 | name = "tower" 3617 | version = "0.4.13" 3618 | source = "registry+https://github.com/rust-lang/crates.io-index" 3619 | checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" 3620 | dependencies = [ 3621 | "futures-core", 3622 | "futures-util", 3623 | "pin-project", 3624 | "pin-project-lite", 3625 | "tokio", 3626 | "tower-layer", 3627 | "tower-service", 3628 | "tracing", 3629 | ] 3630 | 3631 | [[package]] 3632 | name = "tower-layer" 3633 | version = "0.3.2" 3634 | source = "registry+https://github.com/rust-lang/crates.io-index" 3635 | checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" 3636 | 3637 | [[package]] 3638 | name = "tower-service" 3639 | version = "0.3.2" 3640 | source = "registry+https://github.com/rust-lang/crates.io-index" 3641 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" 3642 | 3643 | [[package]] 3644 | name = "tracing" 3645 | version = "0.1.40" 3646 | source = "registry+https://github.com/rust-lang/crates.io-index" 3647 | checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" 3648 | dependencies = [ 3649 | "log", 3650 | "pin-project-lite", 3651 | "tracing-attributes", 3652 | "tracing-core", 3653 | ] 3654 | 3655 | [[package]] 3656 | name = "tracing-attributes" 3657 | version = "0.1.27" 3658 | source = "registry+https://github.com/rust-lang/crates.io-index" 3659 | checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" 3660 | dependencies = [ 3661 | "proc-macro2", 3662 | "quote", 3663 | "syn 2.0.58", 3664 | ] 3665 | 3666 | [[package]] 3667 | name = "tracing-core" 3668 | version = "0.1.32" 3669 | source = "registry+https://github.com/rust-lang/crates.io-index" 3670 | checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" 3671 | dependencies = [ 3672 | "once_cell", 3673 | ] 3674 | 3675 | [[package]] 3676 | name = "trim-in-place" 3677 | version = "0.1.7" 3678 | source = "registry+https://github.com/rust-lang/crates.io-index" 3679 | checksum = "343e926fc669bc8cde4fa3129ab681c63671bae288b1f1081ceee6d9d37904fc" 3680 | 3681 | [[package]] 3682 | name = "try-lock" 3683 | version = "0.2.5" 3684 | source = "registry+https://github.com/rust-lang/crates.io-index" 3685 | checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 3686 | 3687 | [[package]] 3688 | name = "twox-hash" 3689 | version = "1.6.3" 3690 | source = "registry+https://github.com/rust-lang/crates.io-index" 3691 | checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" 3692 | dependencies = [ 3693 | "cfg-if", 3694 | "static_assertions", 3695 | ] 3696 | 3697 | [[package]] 3698 | name = "typenum" 3699 | version = "1.17.0" 3700 | source = "registry+https://github.com/rust-lang/crates.io-index" 3701 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 3702 | 3703 | [[package]] 3704 | name = "uds_windows" 3705 | version = "1.1.0" 3706 | source = "registry+https://github.com/rust-lang/crates.io-index" 3707 | checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" 3708 | dependencies = [ 3709 | "memoffset 0.9.1", 3710 | "tempfile", 3711 | "winapi", 3712 | ] 3713 | 3714 | [[package]] 3715 | name = "unicode-bidi" 3716 | version = "0.3.15" 3717 | source = "registry+https://github.com/rust-lang/crates.io-index" 3718 | checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" 3719 | 3720 | [[package]] 3721 | name = "unicode-ident" 3722 | version = "1.0.12" 3723 | source = "registry+https://github.com/rust-lang/crates.io-index" 3724 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 3725 | 3726 | [[package]] 3727 | name = "unicode-normalization" 3728 | version = "0.1.23" 3729 | source = "registry+https://github.com/rust-lang/crates.io-index" 3730 | checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" 3731 | dependencies = [ 3732 | "tinyvec", 3733 | ] 3734 | 3735 | [[package]] 3736 | name = "unicode-segmentation" 3737 | version = "1.11.0" 3738 | source = "registry+https://github.com/rust-lang/crates.io-index" 3739 | checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" 3740 | 3741 | [[package]] 3742 | name = "unicode-width" 3743 | version = "0.1.11" 3744 | source = "registry+https://github.com/rust-lang/crates.io-index" 3745 | checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" 3746 | 3747 | [[package]] 3748 | name = "unicode-xid" 3749 | version = "0.2.4" 3750 | source = "registry+https://github.com/rust-lang/crates.io-index" 3751 | checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" 3752 | 3753 | [[package]] 3754 | name = "universal-hash" 3755 | version = "0.5.1" 3756 | source = "registry+https://github.com/rust-lang/crates.io-index" 3757 | checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" 3758 | dependencies = [ 3759 | "crypto-common", 3760 | "subtle", 3761 | ] 3762 | 3763 | [[package]] 3764 | name = "untrusted" 3765 | version = "0.9.0" 3766 | source = "registry+https://github.com/rust-lang/crates.io-index" 3767 | checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 3768 | 3769 | [[package]] 3770 | name = "ureq" 3771 | version = "2.9.6" 3772 | source = "registry+https://github.com/rust-lang/crates.io-index" 3773 | checksum = "11f214ce18d8b2cbe84ed3aa6486ed3f5b285cf8d8fbdbce9f3f767a724adc35" 3774 | dependencies = [ 3775 | "base64 0.21.7", 3776 | "flate2", 3777 | "log", 3778 | "once_cell", 3779 | "rustls 0.22.3", 3780 | "rustls-pki-types", 3781 | "rustls-webpki 0.102.2", 3782 | "serde", 3783 | "serde_json", 3784 | "url", 3785 | "webpki-roots 0.26.1", 3786 | ] 3787 | 3788 | [[package]] 3789 | name = "url" 3790 | version = "2.5.0" 3791 | source = "registry+https://github.com/rust-lang/crates.io-index" 3792 | checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" 3793 | dependencies = [ 3794 | "form_urlencoded", 3795 | "idna 0.5.0", 3796 | "percent-encoding", 3797 | ] 3798 | 3799 | [[package]] 3800 | name = "utf8parse" 3801 | version = "0.2.1" 3802 | source = "registry+https://github.com/rust-lang/crates.io-index" 3803 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 3804 | 3805 | [[package]] 3806 | name = "uuid" 3807 | version = "1.8.0" 3808 | source = "registry+https://github.com/rust-lang/crates.io-index" 3809 | checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" 3810 | dependencies = [ 3811 | "getrandom", 3812 | ] 3813 | 3814 | [[package]] 3815 | name = "vcpkg" 3816 | version = "0.2.15" 3817 | source = "registry+https://github.com/rust-lang/crates.io-index" 3818 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 3819 | 3820 | [[package]] 3821 | name = "venial" 3822 | version = "0.5.0" 3823 | source = "registry+https://github.com/rust-lang/crates.io-index" 3824 | checksum = "61584a325b16f97b5b25fcc852eb9550843a251057a5e3e5992d2376f3df4bb2" 3825 | dependencies = [ 3826 | "proc-macro2", 3827 | "quote", 3828 | ] 3829 | 3830 | [[package]] 3831 | name = "version_check" 3832 | version = "0.9.4" 3833 | source = "registry+https://github.com/rust-lang/crates.io-index" 3834 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 3835 | 3836 | [[package]] 3837 | name = "vrc-osc" 3838 | version = "2.6.4" 3839 | dependencies = [ 3840 | "anyhow", 3841 | "async-ffi", 3842 | "derive-config", 3843 | "human-panic", 3844 | "inquire", 3845 | "libloading", 3846 | "path-absolutize", 3847 | "rosc", 3848 | "serde", 3849 | "terminal-link", 3850 | "tokio", 3851 | "toml 0.8.12", 3852 | "ureq", 3853 | "walkdir", 3854 | "winres", 3855 | ] 3856 | 3857 | [[package]] 3858 | name = "waker-fn" 3859 | version = "1.1.1" 3860 | source = "registry+https://github.com/rust-lang/crates.io-index" 3861 | checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" 3862 | 3863 | [[package]] 3864 | name = "walkdir" 3865 | version = "2.5.0" 3866 | source = "registry+https://github.com/rust-lang/crates.io-index" 3867 | checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" 3868 | dependencies = [ 3869 | "same-file", 3870 | "winapi-util", 3871 | ] 3872 | 3873 | [[package]] 3874 | name = "want" 3875 | version = "0.3.1" 3876 | source = "registry+https://github.com/rust-lang/crates.io-index" 3877 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 3878 | dependencies = [ 3879 | "try-lock", 3880 | ] 3881 | 3882 | [[package]] 3883 | name = "wasi" 3884 | version = "0.11.0+wasi-snapshot-preview1" 3885 | source = "registry+https://github.com/rust-lang/crates.io-index" 3886 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 3887 | 3888 | [[package]] 3889 | name = "wasm-bindgen" 3890 | version = "0.2.92" 3891 | source = "registry+https://github.com/rust-lang/crates.io-index" 3892 | checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" 3893 | dependencies = [ 3894 | "cfg-if", 3895 | "wasm-bindgen-macro", 3896 | ] 3897 | 3898 | [[package]] 3899 | name = "wasm-bindgen-backend" 3900 | version = "0.2.92" 3901 | source = "registry+https://github.com/rust-lang/crates.io-index" 3902 | checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" 3903 | dependencies = [ 3904 | "bumpalo", 3905 | "log", 3906 | "once_cell", 3907 | "proc-macro2", 3908 | "quote", 3909 | "syn 2.0.58", 3910 | "wasm-bindgen-shared", 3911 | ] 3912 | 3913 | [[package]] 3914 | name = "wasm-bindgen-futures" 3915 | version = "0.4.42" 3916 | source = "registry+https://github.com/rust-lang/crates.io-index" 3917 | checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" 3918 | dependencies = [ 3919 | "cfg-if", 3920 | "js-sys", 3921 | "wasm-bindgen", 3922 | "web-sys", 3923 | ] 3924 | 3925 | [[package]] 3926 | name = "wasm-bindgen-macro" 3927 | version = "0.2.92" 3928 | source = "registry+https://github.com/rust-lang/crates.io-index" 3929 | checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" 3930 | dependencies = [ 3931 | "quote", 3932 | "wasm-bindgen-macro-support", 3933 | ] 3934 | 3935 | [[package]] 3936 | name = "wasm-bindgen-macro-support" 3937 | version = "0.2.92" 3938 | source = "registry+https://github.com/rust-lang/crates.io-index" 3939 | checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" 3940 | dependencies = [ 3941 | "proc-macro2", 3942 | "quote", 3943 | "syn 2.0.58", 3944 | "wasm-bindgen-backend", 3945 | "wasm-bindgen-shared", 3946 | ] 3947 | 3948 | [[package]] 3949 | name = "wasm-bindgen-shared" 3950 | version = "0.2.92" 3951 | source = "registry+https://github.com/rust-lang/crates.io-index" 3952 | checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" 3953 | 3954 | [[package]] 3955 | name = "web-sys" 3956 | version = "0.3.69" 3957 | source = "registry+https://github.com/rust-lang/crates.io-index" 3958 | checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" 3959 | dependencies = [ 3960 | "js-sys", 3961 | "wasm-bindgen", 3962 | ] 3963 | 3964 | [[package]] 3965 | name = "webbrowser" 3966 | version = "0.8.15" 3967 | source = "registry+https://github.com/rust-lang/crates.io-index" 3968 | checksum = "db67ae75a9405634f5882791678772c94ff5f16a66535aae186e26aa0841fc8b" 3969 | dependencies = [ 3970 | "core-foundation", 3971 | "home", 3972 | "jni", 3973 | "log", 3974 | "ndk-context", 3975 | "objc", 3976 | "raw-window-handle", 3977 | "url", 3978 | "web-sys", 3979 | ] 3980 | 3981 | [[package]] 3982 | name = "webpki-roots" 3983 | version = "0.25.4" 3984 | source = "registry+https://github.com/rust-lang/crates.io-index" 3985 | checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" 3986 | 3987 | [[package]] 3988 | name = "webpki-roots" 3989 | version = "0.26.1" 3990 | source = "registry+https://github.com/rust-lang/crates.io-index" 3991 | checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" 3992 | dependencies = [ 3993 | "rustls-pki-types", 3994 | ] 3995 | 3996 | [[package]] 3997 | name = "which" 3998 | version = "4.4.2" 3999 | source = "registry+https://github.com/rust-lang/crates.io-index" 4000 | checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" 4001 | dependencies = [ 4002 | "either", 4003 | "home", 4004 | "once_cell", 4005 | "rustix 0.38.32", 4006 | ] 4007 | 4008 | [[package]] 4009 | name = "winapi" 4010 | version = "0.3.9" 4011 | source = "registry+https://github.com/rust-lang/crates.io-index" 4012 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 4013 | dependencies = [ 4014 | "winapi-i686-pc-windows-gnu", 4015 | "winapi-x86_64-pc-windows-gnu", 4016 | ] 4017 | 4018 | [[package]] 4019 | name = "winapi-i686-pc-windows-gnu" 4020 | version = "0.4.0" 4021 | source = "registry+https://github.com/rust-lang/crates.io-index" 4022 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 4023 | 4024 | [[package]] 4025 | name = "winapi-util" 4026 | version = "0.1.6" 4027 | source = "registry+https://github.com/rust-lang/crates.io-index" 4028 | checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" 4029 | dependencies = [ 4030 | "winapi", 4031 | ] 4032 | 4033 | [[package]] 4034 | name = "winapi-x86_64-pc-windows-gnu" 4035 | version = "0.4.0" 4036 | source = "registry+https://github.com/rust-lang/crates.io-index" 4037 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 4038 | 4039 | [[package]] 4040 | name = "windows" 4041 | version = "0.51.1" 4042 | source = "registry+https://github.com/rust-lang/crates.io-index" 4043 | checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" 4044 | dependencies = [ 4045 | "windows-core 0.51.1", 4046 | "windows-targets 0.48.5", 4047 | ] 4048 | 4049 | [[package]] 4050 | name = "windows" 4051 | version = "0.54.0" 4052 | source = "registry+https://github.com/rust-lang/crates.io-index" 4053 | checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" 4054 | dependencies = [ 4055 | "windows-core 0.54.0", 4056 | "windows-targets 0.52.4", 4057 | ] 4058 | 4059 | [[package]] 4060 | name = "windows-core" 4061 | version = "0.51.1" 4062 | source = "registry+https://github.com/rust-lang/crates.io-index" 4063 | checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" 4064 | dependencies = [ 4065 | "windows-targets 0.48.5", 4066 | ] 4067 | 4068 | [[package]] 4069 | name = "windows-core" 4070 | version = "0.52.0" 4071 | source = "registry+https://github.com/rust-lang/crates.io-index" 4072 | checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" 4073 | dependencies = [ 4074 | "windows-targets 0.52.4", 4075 | ] 4076 | 4077 | [[package]] 4078 | name = "windows-core" 4079 | version = "0.54.0" 4080 | source = "registry+https://github.com/rust-lang/crates.io-index" 4081 | checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" 4082 | dependencies = [ 4083 | "windows-result", 4084 | "windows-targets 0.52.4", 4085 | ] 4086 | 4087 | [[package]] 4088 | name = "windows-result" 4089 | version = "0.1.0" 4090 | source = "registry+https://github.com/rust-lang/crates.io-index" 4091 | checksum = "cd19df78e5168dfb0aedc343d1d1b8d422ab2db6756d2dc3fef75035402a3f64" 4092 | dependencies = [ 4093 | "windows-targets 0.52.4", 4094 | ] 4095 | 4096 | [[package]] 4097 | name = "windows-sys" 4098 | version = "0.45.0" 4099 | source = "registry+https://github.com/rust-lang/crates.io-index" 4100 | checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" 4101 | dependencies = [ 4102 | "windows-targets 0.42.2", 4103 | ] 4104 | 4105 | [[package]] 4106 | name = "windows-sys" 4107 | version = "0.48.0" 4108 | source = "registry+https://github.com/rust-lang/crates.io-index" 4109 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 4110 | dependencies = [ 4111 | "windows-targets 0.48.5", 4112 | ] 4113 | 4114 | [[package]] 4115 | name = "windows-sys" 4116 | version = "0.52.0" 4117 | source = "registry+https://github.com/rust-lang/crates.io-index" 4118 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 4119 | dependencies = [ 4120 | "windows-targets 0.52.4", 4121 | ] 4122 | 4123 | [[package]] 4124 | name = "windows-targets" 4125 | version = "0.42.2" 4126 | source = "registry+https://github.com/rust-lang/crates.io-index" 4127 | checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" 4128 | dependencies = [ 4129 | "windows_aarch64_gnullvm 0.42.2", 4130 | "windows_aarch64_msvc 0.42.2", 4131 | "windows_i686_gnu 0.42.2", 4132 | "windows_i686_msvc 0.42.2", 4133 | "windows_x86_64_gnu 0.42.2", 4134 | "windows_x86_64_gnullvm 0.42.2", 4135 | "windows_x86_64_msvc 0.42.2", 4136 | ] 4137 | 4138 | [[package]] 4139 | name = "windows-targets" 4140 | version = "0.48.5" 4141 | source = "registry+https://github.com/rust-lang/crates.io-index" 4142 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 4143 | dependencies = [ 4144 | "windows_aarch64_gnullvm 0.48.5", 4145 | "windows_aarch64_msvc 0.48.5", 4146 | "windows_i686_gnu 0.48.5", 4147 | "windows_i686_msvc 0.48.5", 4148 | "windows_x86_64_gnu 0.48.5", 4149 | "windows_x86_64_gnullvm 0.48.5", 4150 | "windows_x86_64_msvc 0.48.5", 4151 | ] 4152 | 4153 | [[package]] 4154 | name = "windows-targets" 4155 | version = "0.52.4" 4156 | source = "registry+https://github.com/rust-lang/crates.io-index" 4157 | checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" 4158 | dependencies = [ 4159 | "windows_aarch64_gnullvm 0.52.4", 4160 | "windows_aarch64_msvc 0.52.4", 4161 | "windows_i686_gnu 0.52.4", 4162 | "windows_i686_msvc 0.52.4", 4163 | "windows_x86_64_gnu 0.52.4", 4164 | "windows_x86_64_gnullvm 0.52.4", 4165 | "windows_x86_64_msvc 0.52.4", 4166 | ] 4167 | 4168 | [[package]] 4169 | name = "windows_aarch64_gnullvm" 4170 | version = "0.42.2" 4171 | source = "registry+https://github.com/rust-lang/crates.io-index" 4172 | checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" 4173 | 4174 | [[package]] 4175 | name = "windows_aarch64_gnullvm" 4176 | version = "0.48.5" 4177 | source = "registry+https://github.com/rust-lang/crates.io-index" 4178 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 4179 | 4180 | [[package]] 4181 | name = "windows_aarch64_gnullvm" 4182 | version = "0.52.4" 4183 | source = "registry+https://github.com/rust-lang/crates.io-index" 4184 | checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" 4185 | 4186 | [[package]] 4187 | name = "windows_aarch64_msvc" 4188 | version = "0.42.2" 4189 | source = "registry+https://github.com/rust-lang/crates.io-index" 4190 | checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" 4191 | 4192 | [[package]] 4193 | name = "windows_aarch64_msvc" 4194 | version = "0.48.5" 4195 | source = "registry+https://github.com/rust-lang/crates.io-index" 4196 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 4197 | 4198 | [[package]] 4199 | name = "windows_aarch64_msvc" 4200 | version = "0.52.4" 4201 | source = "registry+https://github.com/rust-lang/crates.io-index" 4202 | checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" 4203 | 4204 | [[package]] 4205 | name = "windows_i686_gnu" 4206 | version = "0.42.2" 4207 | source = "registry+https://github.com/rust-lang/crates.io-index" 4208 | checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" 4209 | 4210 | [[package]] 4211 | name = "windows_i686_gnu" 4212 | version = "0.48.5" 4213 | source = "registry+https://github.com/rust-lang/crates.io-index" 4214 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 4215 | 4216 | [[package]] 4217 | name = "windows_i686_gnu" 4218 | version = "0.52.4" 4219 | source = "registry+https://github.com/rust-lang/crates.io-index" 4220 | checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" 4221 | 4222 | [[package]] 4223 | name = "windows_i686_msvc" 4224 | version = "0.42.2" 4225 | source = "registry+https://github.com/rust-lang/crates.io-index" 4226 | checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" 4227 | 4228 | [[package]] 4229 | name = "windows_i686_msvc" 4230 | version = "0.48.5" 4231 | source = "registry+https://github.com/rust-lang/crates.io-index" 4232 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 4233 | 4234 | [[package]] 4235 | name = "windows_i686_msvc" 4236 | version = "0.52.4" 4237 | source = "registry+https://github.com/rust-lang/crates.io-index" 4238 | checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" 4239 | 4240 | [[package]] 4241 | name = "windows_x86_64_gnu" 4242 | version = "0.42.2" 4243 | source = "registry+https://github.com/rust-lang/crates.io-index" 4244 | checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" 4245 | 4246 | [[package]] 4247 | name = "windows_x86_64_gnu" 4248 | version = "0.48.5" 4249 | source = "registry+https://github.com/rust-lang/crates.io-index" 4250 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 4251 | 4252 | [[package]] 4253 | name = "windows_x86_64_gnu" 4254 | version = "0.52.4" 4255 | source = "registry+https://github.com/rust-lang/crates.io-index" 4256 | checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" 4257 | 4258 | [[package]] 4259 | name = "windows_x86_64_gnullvm" 4260 | version = "0.42.2" 4261 | source = "registry+https://github.com/rust-lang/crates.io-index" 4262 | checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" 4263 | 4264 | [[package]] 4265 | name = "windows_x86_64_gnullvm" 4266 | version = "0.48.5" 4267 | source = "registry+https://github.com/rust-lang/crates.io-index" 4268 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 4269 | 4270 | [[package]] 4271 | name = "windows_x86_64_gnullvm" 4272 | version = "0.52.4" 4273 | source = "registry+https://github.com/rust-lang/crates.io-index" 4274 | checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" 4275 | 4276 | [[package]] 4277 | name = "windows_x86_64_msvc" 4278 | version = "0.42.2" 4279 | source = "registry+https://github.com/rust-lang/crates.io-index" 4280 | checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" 4281 | 4282 | [[package]] 4283 | name = "windows_x86_64_msvc" 4284 | version = "0.48.5" 4285 | source = "registry+https://github.com/rust-lang/crates.io-index" 4286 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 4287 | 4288 | [[package]] 4289 | name = "windows_x86_64_msvc" 4290 | version = "0.52.4" 4291 | source = "registry+https://github.com/rust-lang/crates.io-index" 4292 | checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" 4293 | 4294 | [[package]] 4295 | name = "winnow" 4296 | version = "0.5.40" 4297 | source = "registry+https://github.com/rust-lang/crates.io-index" 4298 | checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" 4299 | dependencies = [ 4300 | "memchr", 4301 | ] 4302 | 4303 | [[package]] 4304 | name = "winnow" 4305 | version = "0.6.6" 4306 | source = "registry+https://github.com/rust-lang/crates.io-index" 4307 | checksum = "f0c976aaaa0e1f90dbb21e9587cdaf1d9679a1cde8875c0d6bd83ab96a208352" 4308 | dependencies = [ 4309 | "memchr", 4310 | ] 4311 | 4312 | [[package]] 4313 | name = "winreg" 4314 | version = "0.50.0" 4315 | source = "registry+https://github.com/rust-lang/crates.io-index" 4316 | checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" 4317 | dependencies = [ 4318 | "cfg-if", 4319 | "windows-sys 0.48.0", 4320 | ] 4321 | 4322 | [[package]] 4323 | name = "winreg" 4324 | version = "0.52.0" 4325 | source = "registry+https://github.com/rust-lang/crates.io-index" 4326 | checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" 4327 | dependencies = [ 4328 | "cfg-if", 4329 | "windows-sys 0.48.0", 4330 | ] 4331 | 4332 | [[package]] 4333 | name = "winres" 4334 | version = "0.1.12" 4335 | source = "registry+https://github.com/rust-lang/crates.io-index" 4336 | checksum = "b68db261ef59e9e52806f688020631e987592bd83619edccda9c47d42cde4f6c" 4337 | dependencies = [ 4338 | "toml 0.5.11", 4339 | ] 4340 | 4341 | [[package]] 4342 | name = "xdg-home" 4343 | version = "1.1.0" 4344 | source = "registry+https://github.com/rust-lang/crates.io-index" 4345 | checksum = "21e5a325c3cb8398ad6cf859c1135b25dd29e186679cf2da7581d9679f63b38e" 4346 | dependencies = [ 4347 | "libc", 4348 | "winapi", 4349 | ] 4350 | 4351 | [[package]] 4352 | name = "zbus" 4353 | version = "3.15.2" 4354 | source = "registry+https://github.com/rust-lang/crates.io-index" 4355 | checksum = "675d170b632a6ad49804c8cf2105d7c31eddd3312555cffd4b740e08e97c25e6" 4356 | dependencies = [ 4357 | "async-broadcast", 4358 | "async-executor", 4359 | "async-fs", 4360 | "async-io 1.13.0", 4361 | "async-lock 2.8.0", 4362 | "async-process", 4363 | "async-recursion", 4364 | "async-task", 4365 | "async-trait", 4366 | "blocking", 4367 | "byteorder", 4368 | "derivative", 4369 | "enumflags2", 4370 | "event-listener 2.5.3", 4371 | "futures-core", 4372 | "futures-sink", 4373 | "futures-util", 4374 | "hex", 4375 | "nix", 4376 | "once_cell", 4377 | "ordered-stream", 4378 | "rand", 4379 | "serde", 4380 | "serde_repr", 4381 | "sha1", 4382 | "static_assertions", 4383 | "tracing", 4384 | "uds_windows", 4385 | "winapi", 4386 | "xdg-home", 4387 | "zbus_macros", 4388 | "zbus_names", 4389 | "zvariant", 4390 | ] 4391 | 4392 | [[package]] 4393 | name = "zbus_macros" 4394 | version = "3.15.2" 4395 | source = "registry+https://github.com/rust-lang/crates.io-index" 4396 | checksum = "7131497b0f887e8061b430c530240063d33bf9455fa34438f388a245da69e0a5" 4397 | dependencies = [ 4398 | "proc-macro-crate", 4399 | "proc-macro2", 4400 | "quote", 4401 | "regex", 4402 | "syn 1.0.109", 4403 | "zvariant_utils", 4404 | ] 4405 | 4406 | [[package]] 4407 | name = "zbus_names" 4408 | version = "2.6.1" 4409 | source = "registry+https://github.com/rust-lang/crates.io-index" 4410 | checksum = "437d738d3750bed6ca9b8d423ccc7a8eb284f6b1d6d4e225a0e4e6258d864c8d" 4411 | dependencies = [ 4412 | "serde", 4413 | "static_assertions", 4414 | "zvariant", 4415 | ] 4416 | 4417 | [[package]] 4418 | name = "zerocopy" 4419 | version = "0.7.32" 4420 | source = "registry+https://github.com/rust-lang/crates.io-index" 4421 | checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" 4422 | dependencies = [ 4423 | "zerocopy-derive", 4424 | ] 4425 | 4426 | [[package]] 4427 | name = "zerocopy-derive" 4428 | version = "0.7.32" 4429 | source = "registry+https://github.com/rust-lang/crates.io-index" 4430 | checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" 4431 | dependencies = [ 4432 | "proc-macro2", 4433 | "quote", 4434 | "syn 2.0.58", 4435 | ] 4436 | 4437 | [[package]] 4438 | name = "zeroize" 4439 | version = "1.7.0" 4440 | source = "registry+https://github.com/rust-lang/crates.io-index" 4441 | checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" 4442 | 4443 | [[package]] 4444 | name = "zvariant" 4445 | version = "3.15.2" 4446 | source = "registry+https://github.com/rust-lang/crates.io-index" 4447 | checksum = "4eef2be88ba09b358d3b58aca6e41cd853631d44787f319a1383ca83424fb2db" 4448 | dependencies = [ 4449 | "byteorder", 4450 | "enumflags2", 4451 | "libc", 4452 | "serde", 4453 | "static_assertions", 4454 | "zvariant_derive", 4455 | ] 4456 | 4457 | [[package]] 4458 | name = "zvariant_derive" 4459 | version = "3.15.2" 4460 | source = "registry+https://github.com/rust-lang/crates.io-index" 4461 | checksum = "37c24dc0bed72f5f90d1f8bb5b07228cbf63b3c6e9f82d82559d4bae666e7ed9" 4462 | dependencies = [ 4463 | "proc-macro-crate", 4464 | "proc-macro2", 4465 | "quote", 4466 | "syn 1.0.109", 4467 | "zvariant_utils", 4468 | ] 4469 | 4470 | [[package]] 4471 | name = "zvariant_utils" 4472 | version = "1.0.1" 4473 | source = "registry+https://github.com/rust-lang/crates.io-index" 4474 | checksum = "7234f0d811589db492d16893e3f21e8e2fd282e6d01b0cddee310322062cc200" 4475 | dependencies = [ 4476 | "proc-macro2", 4477 | "quote", 4478 | "syn 1.0.109", 4479 | ] 4480 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | resolver = "2" 3 | members = [ 4 | "loader", 5 | "plugin-chatbox", 6 | "plugin-clock", 7 | "plugin-control", 8 | "plugin-debug", 9 | "plugin-lastfm", 10 | "plugin-spotify", 11 | "plugin-steamvr", 12 | ] 13 | 14 | [workspace.package] 15 | version = "2.6.4" 16 | authors = ["Shayne Hartford "] 17 | edition = "2021" 18 | readme = "README.md" 19 | repository = "https://github.com/ShayBox/VRC-OSC" 20 | license = "MIT" 21 | 22 | [workspace.dependencies] 23 | anyhow = "1" 24 | async-ffi = "0.5" 25 | derive-config = { version = "2", default-features = false } 26 | dotenvy_macro = "0.15" 27 | enigo = "0.1" 28 | ferrispot = { git = "https://github.com/Shays-Forks/Ferrispot.git", default-features = false } 29 | human-panic = "1" 30 | inquire = "0.7" 31 | libloading = "0.8" 32 | ovr_overlay = { git = "https://github.com/Shays-Forks/ovr_overlay.git" } 33 | path-absolutize = "3" 34 | rosc = "0.10" 35 | serde = "1" 36 | serde_json = "1" 37 | serde-this-or-that = "0.4" 38 | spotify-lyrics = "0.0.7" 39 | structstruck = "0.4" 40 | terminal-link = "0.1" 41 | tiny_http = "0.12" 42 | tokio = "1" 43 | toml = "0.8" 44 | ureq = "2" 45 | url = "2" 46 | vrc-osc = { path = "loader" } 47 | walkdir = "2" 48 | webbrowser = "0.8" 49 | windows = "0.54" 50 | winres = "0.1" 51 | 52 | # https://github.com/johnthagen/min-sized-rust 53 | [profile.release] 54 | strip = true # Automatically strip symbols from the binary. 55 | opt-level = "z" # Optimize for size. 56 | lto = true 57 | codegen-units = 1 58 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Shayne Hartford 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | Discord 4 | 5 | 6 | Downloads 7 | 8 |
9 | 10 | # VRC-OSC 11 | 12 | Dynamically loaded VRChat OSC plugins written in Rust 13 | 14 | ## Plugins: 15 | 16 | - [`plugin-chatbox`](/plugin-chatbox): Sends messages to the chatbox 17 | - [`plugin-clock`](/plugin-clock): Sends the time to avatar prefabs 18 | - [`plugin-control`](/plugin-control): Control media playback via avatar parameters[^1] 19 | - [`plugin-debug`](/plugin-debug): Log received OSC packets for debugging 20 | - [`plugin-lastfm`](/plugin-lastfm): Sends the current song to the chatbox 21 | - [`plugin-spotify`](/plugin-spotify): Sends the current song and lyrics to the chatbox and control playback via avatar prefabs 22 | - [`plugin-steamvr`](/plugin-steamvr): Registers VRC-OSC as a SteamVR overlay for auto-start/stop[^1] 23 | 24 | ## Planned: 25 | 26 | - `plugin-caption`: Live captions your speech to the chatbox[^2] 27 | 28 | [^1]: These plugins are Windows and Linux only 29 | [^2]: This plugin waiting for `whisper-rs`'s stream example -------------------------------------------------------------------------------- /loader/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "vrc-osc" 3 | description = "Dynamically loaded VRChat OSC plugins written in Rust" 4 | version.workspace = true 5 | authors.workspace = true 6 | edition.workspace = true 7 | homepage = "https://git.shaybox.com/vrc-osc/releases/latest" 8 | 9 | [lib] 10 | name = "loader" 11 | path = "lib.rs" 12 | 13 | [[bin]] 14 | name = "vrc-osc" 15 | path = "main.rs" 16 | 17 | [dependencies] 18 | anyhow.workspace = true 19 | async-ffi = { workspace = true, features = ["macros"] } 20 | derive-config = { workspace = true, features = ["toml"] } 21 | human-panic.workspace = true 22 | inquire.workspace = true 23 | libloading.workspace = true 24 | path-absolutize.workspace = true 25 | rosc.workspace = true 26 | serde = { workspace = true, features = ["derive"] } 27 | terminal-link.workspace = true 28 | tokio = { workspace = true, features = ["full"] } 29 | toml.workspace = true 30 | ureq.workspace = true 31 | walkdir.workspace = true 32 | 33 | [build-dependencies] 34 | winres.workspace = true 35 | 36 | [lints.clippy] 37 | pedantic = "warn" 38 | nursery = "warn" 39 | -------------------------------------------------------------------------------- /loader/README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | Discord 4 | 5 | 6 | Downloads 7 | 8 |
9 | 10 | # Loader 11 | 12 | Dynamically loaded VRChat OSC plugins written in Rust 13 | -------------------------------------------------------------------------------- /loader/VRC-OSC.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShayBox/VRC-OSC/4f940ed7dbd629f0dd30203ecf40b09fd9fd422b/loader/VRC-OSC.ico -------------------------------------------------------------------------------- /loader/build.rs: -------------------------------------------------------------------------------- 1 | use std::error::Error; 2 | 3 | fn main() -> Result<(), Box> { 4 | if cfg!(target_os = "windows") { 5 | winres::WindowsResource::new() 6 | .set_icon("VRC-OSC.ico") 7 | .compile()?; 8 | } 9 | 10 | Ok(()) 11 | } 12 | -------------------------------------------------------------------------------- /loader/lib.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | ffi::OsStr, 3 | net::{SocketAddr, UdpSocket}, 4 | }; 5 | 6 | use anyhow::{Context, Result}; 7 | use async_ffi::FfiFuture; 8 | use derive_config::DeriveTomlConfig; 9 | use libloading::{Library, Symbol}; 10 | use path_absolutize::Absolutize; 11 | use serde::{Deserialize, Serialize}; 12 | use tokio::runtime::Handle; 13 | use walkdir::{DirEntry, WalkDir}; 14 | 15 | pub const CARGO_PKG_VERSION: &str = env!("CARGO_PKG_VERSION"); 16 | pub const CARGO_PKG_HOMEPAGE: &str = env!("CARGO_PKG_HOMEPAGE"); 17 | 18 | #[derive(Clone, Debug, DeriveTomlConfig, Deserialize, Serialize)] 19 | pub struct Config { 20 | pub enabled: Vec, 21 | pub bind_addr: String, 22 | pub send_addr: String, 23 | } 24 | 25 | impl Default for Config { 26 | fn default() -> Self { 27 | Self { 28 | enabled: Vec::default(), 29 | bind_addr: "0.0.0.0:9001".into(), 30 | send_addr: "127.0.0.1:9000".into(), 31 | } 32 | } 33 | } 34 | 35 | /// # Errors 36 | /// 37 | /// Will return `Err` if couldn't get the current exe or dir path 38 | pub fn get_plugin_names() -> Result> { 39 | let current_exe = std::env::current_exe()?; 40 | let current_dir = current_exe.parent().context("This shouldn't be possible")?; 41 | 42 | let paths = WalkDir::new(current_dir) 43 | .max_depth(1) 44 | .into_iter() 45 | .filter_map(Result::ok) 46 | .map(DirEntry::into_path) 47 | .collect::>(); 48 | 49 | let mut libraries = Vec::new(); 50 | for path in paths { 51 | let extension = path.extension().and_then(OsStr::to_str); 52 | let Some(extension) = extension else { 53 | continue; // No file extension 54 | }; 55 | if !matches!(extension, "dll" | "dylib" | "so") { 56 | continue; // Not a dynamic library 57 | } 58 | 59 | let Some(filename) = path.file_name().and_then(OsStr::to_str) else { 60 | continue; // No file name 61 | }; 62 | 63 | libraries.push(filename.to_owned()); 64 | } 65 | 66 | Ok(libraries) 67 | } 68 | 69 | /// # Errors 70 | /// 71 | /// Will return `Err` if couldn't get the current exe or dir path 72 | pub fn get_plugin_path(path: String) -> Result { 73 | // libloading doesn't support relative paths on Linux 74 | let current_exe = std::env::current_exe()?; 75 | let current_dir = current_exe.parent().context("This shouldn't be possible")?; 76 | let path = current_dir.join(path); 77 | let path = path.absolutize()?; 78 | 79 | Ok(path.to_str().context("None")?.to_owned()) 80 | } 81 | 82 | /// # Errors 83 | /// 84 | /// Will return `Err` if couldn't get the current exe or dir path 85 | /// 86 | /// # Panics 87 | /// 88 | /// Will panic if a plugin fails to load 89 | pub fn load_plugins(names: Vec, config: &Config) -> Result> { 90 | type LoadFn = fn(socket: UdpSocket); 91 | 92 | let mut addrs = Vec::new(); 93 | for name in names { 94 | if !config.enabled.contains(&name) { 95 | continue; // Skip disabled plugins 96 | } 97 | 98 | let path = get_plugin_path(name)?; 99 | let socket = UdpSocket::bind("127.0.0.1:0")?; // Dynamic port 100 | let loader_addr = config.bind_addr.replace("0.0.0.0", "127.0.0.1"); 101 | let plugin_addr = socket.local_addr()?; 102 | socket.connect(loader_addr)?; 103 | addrs.push(plugin_addr); 104 | 105 | tokio::spawn(async move { 106 | let plugin = unsafe { Library::new(path).expect("Failed to get the plugin") }; 107 | let load_fn: Symbol = unsafe { 108 | plugin 109 | .get(b"load") 110 | .expect("Failed to get the load function") 111 | }; 112 | 113 | load_fn(socket); 114 | }); 115 | } 116 | 117 | Ok(addrs) 118 | } 119 | 120 | pub type ChatMessage = (String, String); 121 | 122 | /// # Errors 123 | /// 124 | /// Will return `Err` if couldn't get the current exe or dir path 125 | pub async fn chat_message( 126 | message: &ChatMessage, 127 | names: &[String], 128 | config: &Config, 129 | ) -> Result { 130 | type ChatFn = 131 | fn(chatbox: String, console: String, handle: Handle) -> FfiFuture>; 132 | 133 | let mut message = message.clone(); 134 | for name in names.iter().cloned() { 135 | if !config.enabled.contains(&name) { 136 | continue; // Skip disabled plugins 137 | } 138 | 139 | let path = get_plugin_path(name)?; 140 | let plugin = unsafe { Library::new(path.clone()) }?; 141 | let chat_fn = match unsafe { plugin.get(b"chat") } { 142 | Ok(chat_fn) => chat_fn as Symbol, 143 | Err(_) => continue, 144 | }; 145 | 146 | let (chatbox, console) = message.clone(); 147 | match chat_fn(chatbox, console, Handle::current()).await { 148 | Ok(new_message) => message = new_message, 149 | Err(error) => eprintln!("Chatbox Error: {error}"), 150 | } 151 | 152 | // This appears to fix a random access violation? 153 | continue; 154 | } 155 | 156 | Ok(message) 157 | } 158 | 159 | /// # Errors 160 | /// 161 | /// Will return `Err` if couldn't get the GitHub repository 162 | pub fn check_for_updates() -> Result { 163 | let response = ureq::get(CARGO_PKG_HOMEPAGE).call()?; 164 | let Some(remote_version) = response.get_url().split('/').last() else { 165 | return Ok(false); 166 | }; 167 | 168 | Ok(remote_version > CARGO_PKG_VERSION) 169 | } 170 | -------------------------------------------------------------------------------- /loader/main.rs: -------------------------------------------------------------------------------- 1 | use std::net::UdpSocket; 2 | 3 | use anyhow::Result; 4 | use derive_config::DeriveTomlConfig; 5 | use inquire::Confirm; 6 | use loader::{Config, CARGO_PKG_HOMEPAGE}; 7 | use rosc::decoder::MTU; 8 | use terminal_link::Link; 9 | 10 | #[tokio::main] 11 | async fn main() -> Result<()> { 12 | human_panic::setup_panic!(); 13 | 14 | if loader::check_for_updates()? { 15 | let link = Link::new("An update is available", CARGO_PKG_HOMEPAGE); 16 | println!("{link}"); 17 | } 18 | 19 | let config = if let Ok(config) = Config::load() { 20 | config 21 | } else { 22 | let mut config = Config::default(); 23 | let mut plugins = loader::get_plugin_names()?; 24 | plugins.sort(); 25 | 26 | for plugin in plugins { 27 | let prompt = format!("Would you like to enable the {plugin} plugin"); 28 | if Confirm::new(&prompt).with_default(false).prompt()? { 29 | config.enabled.push(plugin.clone()); 30 | } 31 | } 32 | 33 | if config.enabled.is_empty() { 34 | println!("You must enable at least one plugin"); 35 | std::process::exit(1); 36 | } 37 | 38 | config.save()?; 39 | config 40 | }; 41 | 42 | let loader_socket = UdpSocket::bind(&config.bind_addr)?; 43 | let plugin_names = loader::get_plugin_names()?; 44 | let plugin_addrs = loader::load_plugins(plugin_names, &config)?; 45 | 46 | loop { 47 | let mut buf = [0u8; MTU]; 48 | let Ok((size, recv_addr)) = loader_socket.recv_from(&mut buf) else { 49 | continue; 50 | }; 51 | 52 | // Plugins -> VRChat 53 | if plugin_addrs.contains(&recv_addr) { 54 | loader_socket.send_to(&buf[..size], &config.send_addr)?; 55 | continue; 56 | } 57 | 58 | // VRChat -> Plugins 59 | for plugin_addr in &plugin_addrs { 60 | loader_socket.send_to(&buf[..size], plugin_addr)?; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /plugin-chatbox/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "plugin-chatbox" 3 | description = "Sends messages to the chatbox" 4 | version.workspace = true 5 | authors.workspace = true 6 | edition.workspace = true 7 | 8 | [lib] 9 | name = "chatbox" 10 | path = "lib.rs" 11 | crate-type = ["cdylib"] 12 | 13 | [dependencies] 14 | anyhow.workspace = true 15 | async-ffi = { workspace = true, features = ["macros"] } 16 | derive-config = { workspace = true, features = ["toml"] } 17 | rosc.workspace = true 18 | serde = { workspace = true, features = ["derive"] } 19 | tokio = { workspace = true, features = ["macros", "rt"] } 20 | toml.workspace = true 21 | vrc-osc.workspace = true 22 | 23 | [lints.clippy] 24 | pedantic = "warn" 25 | nursery = "warn" 26 | -------------------------------------------------------------------------------- /plugin-chatbox/README.md: -------------------------------------------------------------------------------- 1 | 9 | 10 | # Chatbox Plugin 11 | 12 | Sends messages to the chatbox 13 | 14 | ## Polling 15 | 1.5 seconds is the quickest you can send a chatbox message without being timed out for spamming -------------------------------------------------------------------------------- /plugin-chatbox/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::cast_possible_truncation)] 2 | #![allow(clippy::cast_precision_loss)] 3 | 4 | use std::{net::UdpSocket, time::Duration}; 5 | 6 | use anyhow::Result; 7 | use derive_config::DeriveTomlConfig; 8 | use loader::{ChatMessage, Config as LoaderConfig}; 9 | use rosc::{OscMessage, OscPacket, OscType}; 10 | use serde::{Deserialize, Serialize}; 11 | 12 | #[derive(Clone, Debug, DeriveTomlConfig, Deserialize, Serialize)] 13 | pub struct Config { 14 | pub message: ChatMessage, 15 | pub send_once: bool, 16 | pub polling: u64, 17 | } 18 | 19 | impl Default for Config { 20 | fn default() -> Self { 21 | Self { 22 | message: ( 23 | "📻 {song} - {artists}".into(), 24 | "📻 {song} - {artists}".into(), 25 | ), 26 | send_once: true, 27 | polling: 1500, 28 | } 29 | } 30 | } 31 | 32 | #[no_mangle] 33 | #[allow(clippy::needless_pass_by_value)] 34 | #[tokio::main(flavor = "current_thread")] 35 | async extern "Rust" fn load(socket: UdpSocket) -> Result<()> { 36 | let config = Config::load().unwrap_or_default(); 37 | let plugin_names = loader::get_plugin_names()?; 38 | let loader_config = LoaderConfig::load()?; 39 | 40 | config.save()?; 41 | 42 | let mut previous_message: (String, String) = config.message.clone(); 43 | loop { 44 | tokio::time::sleep(Duration::from_millis(config.polling)).await; 45 | 46 | let message = loader::chat_message(&config.message, &plugin_names, &loader_config).await?; 47 | if message == previous_message && config.send_once { 48 | continue; 49 | } 50 | 51 | println!("{}", message.1); 52 | previous_message = message.clone(); 53 | 54 | let packet = OscPacket::Message(OscMessage { 55 | addr: "/chatbox/input".into(), 56 | args: vec![OscType::String(message.0), OscType::Bool(true)], 57 | }); 58 | 59 | let msg_buf = rosc::encoder::encode(&packet)?; 60 | socket.send(&msg_buf)?; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /plugin-clock/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "plugin-clock" 3 | description = "Sends the time to avatar prefabs" 4 | version.workspace = true 5 | authors.workspace = true 6 | edition.workspace = true 7 | 8 | [lib] 9 | name = "clock" 10 | path = "lib.rs" 11 | crate-type = ["cdylib"] 12 | 13 | [dependencies] 14 | anyhow.workspace = true 15 | derive-config = { workspace = true, features = ["toml"] } 16 | rosc.workspace = true 17 | serde = { workspace = true, features = ["derive"] } 18 | tokio = { workspace = true, features = ["macros", "rt"] } 19 | toml.workspace = true 20 | 21 | [lints.clippy] 22 | pedantic = "warn" 23 | nursery = "warn" 24 | -------------------------------------------------------------------------------- /plugin-clock/README.md: -------------------------------------------------------------------------------- 1 | 9 | 10 | # Clock Plugin 11 | 12 | Sends the time to avatar prefabs 13 | 14 | ## Avatar Parameters 15 | 16 | This plugin fully supports the [VRCOSC Watch Prefab] 17 | Support for additional prefabs are welcome 18 | 19 | | Parameter | Type | 20 | |----------------------|-------| 21 | | VRCOSC/Clock/Hours | Float | 22 | | VRCOSC/Clock/Minutes | Float | 23 | | VRCOSC/Clock/Seconds | Float | 24 | 25 | [VRCOSC Watch Prefab]: https://github.com/VolcanicArts/VRCOSC/releases/latest 26 | -------------------------------------------------------------------------------- /plugin-clock/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::cast_possible_truncation)] 2 | #![allow(clippy::cast_precision_loss)] 3 | 4 | use std::{ 5 | collections::HashMap, 6 | net::UdpSocket, 7 | time::{Duration, SystemTime}, 8 | }; 9 | 10 | use anyhow::Result; 11 | use derive_config::DeriveTomlConfig; 12 | use rosc::{OscMessage, OscPacket, OscType}; 13 | use serde::{Deserialize, Serialize}; 14 | 15 | #[derive(Clone, Debug, DeriveTomlConfig, Deserialize, Serialize)] 16 | pub struct Config { 17 | pub mode: bool, 18 | pub polling: u64, 19 | pub smooth: bool, 20 | } 21 | 22 | impl Default for Config { 23 | fn default() -> Self { 24 | Self { 25 | mode: false, 26 | polling: 1000, 27 | smooth: false, 28 | } 29 | } 30 | } 31 | 32 | #[no_mangle] 33 | #[allow(clippy::needless_pass_by_value)] 34 | #[tokio::main(flavor = "current_thread")] 35 | async extern "Rust" fn load(socket: UdpSocket) -> Result<()> { 36 | let config = Config::load()?; 37 | 38 | loop { 39 | let duration = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?; 40 | let seconds = duration.as_secs(); 41 | 42 | let mut hours = (seconds / 3600) as f64; 43 | let mut minutes = ((seconds % 3600) / 60) as f64; 44 | let mut seconds = (seconds % 60) as f64; 45 | 46 | if config.smooth { 47 | let millis = f64::from(duration.subsec_millis()); 48 | seconds += millis / 1000.0; 49 | minutes += seconds / 60.0; 50 | hours += minutes / 60.0; 51 | } 52 | 53 | let mode = if config.mode { 24.0 } else { 12.0 }; 54 | let parameters = HashMap::from([ 55 | ("Hours", hours % mode / mode), 56 | ("Minutes", minutes / 60.0), 57 | ("Seconds", seconds / 60.0), 58 | ]); 59 | 60 | for (parameter, arg) in parameters { 61 | let packet = OscPacket::Message(OscMessage { 62 | addr: "/avatar/parameters/VRCOSC/Clock/".to_owned() + parameter, 63 | args: vec![OscType::Float(arg as f32)], 64 | }); 65 | 66 | let msg_buf = rosc::encoder::encode(&packet)?; 67 | socket.send(&msg_buf)?; 68 | } 69 | 70 | std::thread::sleep(Duration::from_millis(config.polling)); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /plugin-control/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "plugin-control" 3 | description = "Controls media playback via avatar parameters" 4 | version.workspace = true 5 | authors.workspace = true 6 | edition.workspace = true 7 | 8 | [lib] 9 | name = "control" 10 | crate-type = ["cdylib"] 11 | 12 | [dependencies] 13 | anyhow.workspace = true 14 | rosc.workspace = true 15 | tokio = { workspace = true, features = ["macros", "rt"] } 16 | 17 | [target.'cfg(windows)'.dependencies] 18 | windows = { workspace = true, features = ["Foundation", "Media_Control"] } 19 | 20 | [target.'cfg(unix)'.dependencies] 21 | enigo.workspace = true 22 | 23 | [lints.clippy] 24 | pedantic = "warn" 25 | nursery = "warn" 26 | -------------------------------------------------------------------------------- /plugin-control/README.md: -------------------------------------------------------------------------------- 1 | 9 | 10 | # Control Plugin 11 | 12 | Control media playback via avatar parameters 13 | This plugin is Windows and Linux only because macOS doesn't support Media keys 14 | 15 | ## Avatar Parameters 16 | 17 | This plugin **partially**[^1][^2] supports the [VRCOSC Media Prefab] 18 | Support for additional prefabs are welcome 19 | 20 | | Parameter | Type | 🪟 | 🐧 | 21 | |-----------------------|----------|-------|-------| 22 | | VRCOSC/Media/Play | Bool[^2] | ✅ | ✅ | 23 | | VRCOSC/Media/Next | None | ✅ | ✅ | 24 | | VRCOSC/Media/Previous | None | ✅ | ✅ | 25 | | VRCOSC/Media/Shuffle | Bool | ✅ | ❌[^2] | 26 | | VRCOSC/Media/Seeking | Bool | ✅ | ❌[^2] | 27 | | VRCOSC/Media/Muted | Bool | ❌[^1] | ✅ | 28 | | VRCOSC/Media/Repeat | Int | ✅ | ❌[^2] | 29 | | VRCOSC/Media/Volume | Float | ❌[^1] | ❌[^2] | 30 | | VRCOSC/Media/Position | Float | ✅ | ❌[^2] | 31 | 32 | [^1]: The `windows` crate doesn't currently support volume 33 | [^2]: Support for Linux is lacking, issues and pull requests are welcome 34 | 35 | [VRCOSC Media Prefab]: https://github.com/VolcanicArts/VRCOSC/releases/latest 36 | -------------------------------------------------------------------------------- /plugin-control/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(unix)] 2 | pub mod unix; 3 | 4 | #[cfg(windows)] 5 | pub mod windows; 6 | -------------------------------------------------------------------------------- /plugin-control/src/unix.rs: -------------------------------------------------------------------------------- 1 | use std::net::UdpSocket; 2 | 3 | use anyhow::Result; 4 | use enigo::{Enigo, Key, KeyboardControllable}; 5 | use rosc::{decoder::MTU, OscPacket}; 6 | 7 | #[no_mangle] 8 | #[tokio::main(flavor = "current_thread")] 9 | pub async fn load(socket: UdpSocket) -> Result<()> { 10 | let mut enigo = Enigo::new(); 11 | 12 | let mut buf = [0u8; MTU]; 13 | loop { 14 | let size = socket.recv(&mut buf)?; 15 | let (_buf, packet) = rosc::decoder::decode_udp(&buf[..size])?; 16 | let OscPacket::Message(packet) = packet else { 17 | continue; // I don't think VRChat uses bundles 18 | }; 19 | 20 | let addr = packet.addr.replace("/avatar/parameters/VRCOSC/Media/", ""); 21 | match addr.as_ref() { 22 | "Play" => enigo.key_click(Key::MediaPlayPause), 23 | "Next" => enigo.key_click(Key::MediaNextTrack), 24 | "Previous" => enigo.key_click(Key::MediaPrevTrack), 25 | // "Shuffle" => continue, 26 | // Seeking is not required because position is not used multiple times 27 | // "Seeking" => continue, 28 | "Muted" => enigo.key_click(Key::VolumeMute), 29 | // "Repeat" => continue, 30 | // "Volume" => continue, 31 | // "Position" => continue, 32 | _ => continue, 33 | }; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /plugin-control/src/windows.rs: -------------------------------------------------------------------------------- 1 | use std::{collections::HashMap, net::UdpSocket}; 2 | 3 | use anyhow::Result; 4 | use rosc::{decoder::MTU, OscMessage, OscPacket, OscType}; 5 | use windows::Media::{ 6 | Control::GlobalSystemMediaTransportControlsSessionManager as GSMTCSM, 7 | MediaPlaybackAutoRepeatMode, 8 | }; 9 | 10 | /// # Errors 11 | /// 12 | /// # Panics 13 | #[no_mangle] 14 | #[allow(clippy::needless_pass_by_value)] 15 | #[tokio::main(flavor = "current_thread")] 16 | pub async extern "Rust" fn load(socket: UdpSocket) -> Result<()> { 17 | let manager = GSMTCSM::RequestAsync()?.await?; 18 | let mut previous_parameters = HashMap::new(); 19 | let mut buf = [0u8; MTU]; 20 | 21 | loop { 22 | let size = socket.recv(&mut buf)?; 23 | let (_buf, packet) = rosc::decoder::decode_udp(&buf[..size])?; 24 | let OscPacket::Message(packet) = packet else { 25 | continue; // I don't think VRChat uses bundles 26 | }; 27 | 28 | let addr = packet.addr.replace("/avatar/parameters/VRCOSC/Media/", ""); 29 | let Some(arg) = packet.args.first() else { 30 | continue; // No first argument was supplied 31 | }; 32 | 33 | let Ok(session) = manager.GetCurrentSession() else { 34 | continue; // No media is currently playing 35 | }; 36 | 37 | match addr.as_ref() { 38 | "Play" => { 39 | let OscType::Bool(play) = arg.to_owned() else { 40 | continue; 41 | }; 42 | 43 | if play { 44 | session.TryPlayAsync() 45 | } else { 46 | session.TryPauseAsync() 47 | } 48 | } 49 | "Next" => session.TrySkipNextAsync(), 50 | "Previous" => session.TrySkipPreviousAsync(), 51 | "Shuffle" => { 52 | let OscType::Bool(shuffle) = arg.to_owned() else { 53 | continue; 54 | }; 55 | 56 | session.TryChangeShuffleActiveAsync(shuffle) 57 | } 58 | // Seeking is not required because position is not used multiple times 59 | // "Seeking" => continue, 60 | // Muted is removed in newer prefab versions but I still intend to support it 61 | // "Muted" => continue, 62 | "Repeat" => { 63 | let OscType::Int(repeat) = arg.to_owned() else { 64 | continue; 65 | }; 66 | 67 | let repeat_mode = MediaPlaybackAutoRepeatMode(repeat); 68 | session.TryChangeAutoRepeatModeAsync(repeat_mode) 69 | } 70 | // The Windows crate doesn't currently support master system volume adjustment 71 | // "Volume" => continue, 72 | "Position" => { 73 | let OscType::Float(position) = arg.to_owned() else { 74 | continue; 75 | }; 76 | 77 | let timeline = session.GetTimelineProperties()?; 78 | let min = timeline.MinSeekTime()?.Duration; 79 | let max = timeline.MaxSeekTime()?.Duration; 80 | 81 | #[allow(clippy::cast_possible_truncation)] 82 | let playback_position = (min + (max - min) * (position * 100.0) as i64) / 100; 83 | session.TryChangePlaybackPositionAsync(playback_position) 84 | } 85 | _ => { 86 | let playback_info = session.GetPlaybackInfo()?; 87 | let mut parameters = HashMap::new(); 88 | 89 | if let Ok(playback_status) = playback_info.PlaybackStatus() { 90 | let play = OscType::Bool(playback_status.0 == 4); 91 | if previous_parameters.get("Play") != Some(&play) { 92 | parameters.insert("Play", play.clone()); 93 | previous_parameters.insert("Play", play); 94 | } 95 | } 96 | 97 | if let Ok(shuffle_ref) = playback_info.IsShuffleActive() { 98 | if let Ok(shuffle) = shuffle_ref.Value() { 99 | let shuffle = OscType::Bool(shuffle); 100 | if previous_parameters.get("Shuffle") != Some(&shuffle) { 101 | parameters.insert("Shuffle", shuffle.clone()); 102 | previous_parameters.insert("Shuffle", shuffle); 103 | } 104 | } 105 | } 106 | 107 | if let Ok(repeat_mode_ref) = playback_info.AutoRepeatMode() { 108 | if let Ok(repeat_mode) = repeat_mode_ref.Value() { 109 | let repeat = OscType::Int(repeat_mode.0); 110 | if previous_parameters.get("Repeat") != Some(&repeat) { 111 | parameters.insert("Repeat", repeat.clone()); 112 | previous_parameters.insert("Repeat", repeat); 113 | } 114 | } 115 | } 116 | 117 | for (param, arg) in parameters { 118 | let packet = OscPacket::Message(OscMessage { 119 | addr: format!("/avatar/parameters/VRCOSC/Media/{param}"), 120 | args: vec![arg], 121 | }); 122 | 123 | let msg_buf = rosc::encoder::encode(&packet)?; 124 | socket.send(&msg_buf)?; 125 | } 126 | 127 | continue; 128 | } 129 | }? 130 | .await?; 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /plugin-debug/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "plugin-debug" 3 | description = "Log received OSC packets for debugging" 4 | version.workspace = true 5 | authors.workspace = true 6 | edition.workspace = true 7 | 8 | [lib] 9 | name = "debug" 10 | path = "lib.rs" 11 | crate-type = ["cdylib"] 12 | 13 | [dependencies] 14 | anyhow.workspace = true 15 | rosc.workspace = true 16 | tokio = { workspace = true, features = ["macros", "rt"] } 17 | 18 | [lints.clippy] 19 | pedantic = "warn" 20 | nursery = "warn" 21 | -------------------------------------------------------------------------------- /plugin-debug/README.md: -------------------------------------------------------------------------------- 1 | 9 | 10 | # Debug Plugin 11 | 12 | Log received OSC packets for debugging 13 | -------------------------------------------------------------------------------- /plugin-debug/lib.rs: -------------------------------------------------------------------------------- 1 | use std::net::UdpSocket; 2 | 3 | use anyhow::Result; 4 | use rosc::OscPacket; 5 | 6 | #[no_mangle] 7 | #[allow(clippy::needless_pass_by_value)] 8 | #[tokio::main(flavor = "current_thread")] 9 | async extern "Rust" fn load(socket: UdpSocket) -> Result<()> { 10 | println!("Debug Enabled"); 11 | 12 | let mut buf = [0u8; rosc::decoder::MTU]; 13 | loop { 14 | let size = socket.recv(&mut buf).unwrap(); 15 | let (_buf, packet) = rosc::decoder::decode_udp(&buf[..size]).unwrap(); 16 | let OscPacket::Message(packet) = packet else { 17 | continue; // I don't think VRChat uses bundles 18 | }; 19 | 20 | println!("{} | {:?}", packet.addr, packet.args); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /plugin-lastfm/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "plugin-lastfm" 3 | description = "Sends the current song to the chatbox" 4 | version.workspace = true 5 | authors.workspace = true 6 | edition.workspace = true 7 | 8 | [lib] 9 | name = "lastfm" 10 | crate-type = ["cdylib"] 11 | 12 | [dependencies] 13 | anyhow.workspace = true 14 | async-ffi = { workspace = true, features = ["macros"] } 15 | derive-config = { workspace = true, features = ["toml"] } 16 | dotenvy_macro.workspace = true 17 | inquire.workspace = true 18 | serde = { workspace = true, features = ["derive"] } 19 | serde-this-or-that.workspace = true 20 | structstruck.workspace = true 21 | terminal-link.workspace = true 22 | tokio = { workspace = true, features = ["macros", "rt"] } 23 | toml.workspace = true 24 | ureq = { workspace = true, features = ["json"] } 25 | vrc-osc.workspace = true 26 | 27 | [lints.clippy] 28 | pedantic = "warn" 29 | nursery = "warn" 30 | -------------------------------------------------------------------------------- /plugin-lastfm/README.md: -------------------------------------------------------------------------------- 1 | 9 | 10 | # LastFM Plugin 11 | 12 | Sends the current song to the chatbox 13 | 14 | -------------------------------------------------------------------------------- /plugin-lastfm/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature(once_cell_try)] 2 | 3 | mod model; 4 | 5 | use std::{net::UdpSocket, sync::OnceLock}; 6 | 7 | use anyhow::{Context, Error, Result}; 8 | use async_ffi::async_ffi; 9 | use derive_config::DeriveTomlConfig; 10 | #[cfg(debug_assertions)] 11 | use dotenvy_macro::dotenv; 12 | use inquire::Text; 13 | use model::Track; 14 | use serde::{Deserialize, Serialize}; 15 | use terminal_link::Link; 16 | use tokio::runtime::Handle; 17 | 18 | use crate::model::LastFM; 19 | 20 | #[cfg(debug_assertions)] 21 | const LASTFM_API_KEY: &str = dotenv!("LASTFM_API_KEY"); 22 | 23 | #[cfg(debug_assertions)] 24 | const LASTFM_USERNAME: &str = dotenv!("LASTFM_USERNAME"); 25 | 26 | #[cfg(not(debug_assertions))] 27 | const LASTFM_API_KEY: &str = env!("LASTFM_API_KEY"); 28 | 29 | #[cfg(not(debug_assertions))] 30 | const LASTFM_USERNAME: &str = env!("LASTFM_USERNAME"); 31 | 32 | #[derive(Clone, Debug, DeriveTomlConfig, Deserialize, Serialize)] 33 | pub struct Config { 34 | pub api_key: String, 35 | pub username: String, 36 | } 37 | 38 | impl Default for Config { 39 | fn default() -> Self { 40 | Self { 41 | api_key: LASTFM_API_KEY.into(), 42 | username: LASTFM_USERNAME.into(), 43 | } 44 | } 45 | } 46 | 47 | fn config() -> Result<&'static Config> { 48 | static CONFIG: OnceLock = OnceLock::new(); 49 | CONFIG.get_or_try_init(|| { 50 | Config::load().or_else(|_| { 51 | println!("The LastFM plugin requires you to setup a scrobbler app or service"); 52 | println!("https://www.last.fm/about/trackmymusic"); 53 | 54 | Ok::(Config { 55 | username: Text::new("LastFM Username: ").prompt()?, 56 | ..Default::default() 57 | }) 58 | }) 59 | }) 60 | } 61 | 62 | #[no_mangle] 63 | #[allow(clippy::needless_pass_by_value)] 64 | #[tokio::main(flavor = "current_thread")] 65 | async extern "Rust" fn load(_: UdpSocket) -> Result<()> { 66 | config()?.save()?; 67 | 68 | Ok(()) 69 | } 70 | 71 | #[no_mangle] 72 | #[async_ffi(?Send)] 73 | #[allow(clippy::unnecessary_wraps)] 74 | #[allow(clippy::needless_pass_by_value)] 75 | async extern "Rust" fn chat( 76 | mut chatbox: String, 77 | mut console: String, 78 | handle: Handle, 79 | ) -> Result<(String, String)> { 80 | let _enter = handle.enter(); 81 | let config = config()?; 82 | let url = format!("http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user={}&api_key={}&format=json&limit=1", config.username, config.api_key); 83 | let response = ureq::get(&url).call()?; 84 | let lastfm = response.into_json::()?; 85 | let tracks = lastfm 86 | .recent 87 | .tracks 88 | .iter() 89 | .filter(|track| track.attr.as_ref().map_or(false, |attr| attr.nowplaying)) 90 | .collect::>(); 91 | 92 | let track = tracks.first().context("No track found")?; 93 | replace(&mut chatbox, track); 94 | replace(&mut console, track); 95 | 96 | let link = Link::new(&console, &track.url); 97 | Ok((chatbox, link.to_string())) 98 | } 99 | 100 | fn replace(message: &mut String, track: &Track) { 101 | *message = message 102 | .replace("{song}", &track.name) 103 | .replace("{artist}", &track.artist.text) 104 | .replace("{artists}", &track.artist.text); 105 | } 106 | -------------------------------------------------------------------------------- /plugin-lastfm/src/model.rs: -------------------------------------------------------------------------------- 1 | use serde::Deserialize; 2 | use serde_this_or_that::as_bool; 3 | 4 | structstruck::strike! { 5 | #[strikethrough[derive(Debug, Deserialize)]] 6 | pub struct LastFM { 7 | #[serde(rename = "recenttracks")] 8 | pub recent: struct { 9 | #[serde(rename = "track")] 10 | pub tracks: Vec, 22 | pub mbid: String, 23 | pub album: struct { 24 | pub mbid: String, 25 | #[serde(rename = "#text")] 26 | pub text: String, 27 | }, 28 | pub name: String, 29 | #[serde(rename = "@attr")] 30 | pub attr: Option, 34 | pub url: String, 35 | pub date: Option, 40 | }>, 41 | #[serde(rename = "@attr")] 42 | pub attr: struct Attributes { 43 | pub user: String, 44 | #[serde(rename = "totalPages")] 45 | pub total_pages: String, 46 | pub page: String, 47 | pub total: String, 48 | #[serde(rename = "perPage")] 49 | pub per_page: String, 50 | }, 51 | }, 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /plugin-spotify/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "plugin-spotify" 3 | description = "Sends the current song to the chatbox and controls playback via avatar prefabs" 4 | version.workspace = true 5 | authors.workspace = true 6 | edition.workspace = true 7 | 8 | [lib] 9 | name = "spotify" 10 | crate-type = ["cdylib"] 11 | 12 | [dependencies] 13 | anyhow.workspace = true 14 | async-ffi = { workspace = true, features = ["macros"] } 15 | derive-config = { workspace = true, features = ["toml"] } 16 | dotenvy_macro.workspace = true 17 | ferrispot = { workspace = true, features = ["async", "rustls-tls"] } 18 | inquire.workspace = true 19 | rosc.workspace = true 20 | serde = { workspace = true, features = ["derive"] } 21 | spotify-lyrics.workspace = true 22 | terminal-link.workspace = true 23 | tiny_http.workspace = true 24 | tokio = { workspace = true, features = ["macros", "rt", "time"] } 25 | toml.workspace = true 26 | url.workspace = true 27 | webbrowser.workspace = true 28 | 29 | [lints.clippy] 30 | pedantic = "warn" 31 | nursery = "warn" 32 | -------------------------------------------------------------------------------- /plugin-spotify/README.md: -------------------------------------------------------------------------------- 1 | 9 | 10 | # Spotify Plugin 11 | 12 | Sends the current song and lyrics to the chatbox 13 | Control playback via avatar prefabs[^1] 14 | 15 | ## How to Setup 16 | 17 | The Spotify plugin requires you to create a Spotify Developer Application 18 | 19 | 1. Create a [Developer Application](https://developer.spotify.com/dashboard) 20 | 2. Set the `Redirect URI` to `http://127.0.0.1:2345` 21 | 3. Click on the `Settings` button 22 | 4. Copy the `Client ID` and paste it into the Setup Wizard 23 | 5. Click on the `View client secret` button 24 | 6. Copy the `Client secret` and paste it into the Setup Wizard 25 | 7. Make sure the `Redirect URI` matches in the Setup Wizard 26 | 27 | [If you need additional help you can contact me](https://shaybox.com) 28 | 29 | ## Avatar Parameters 30 | 31 | This plugin fully supports the [VRCOSC Media Prefab] 32 | Support for additional prefabs are welcome 33 | 34 | | Parameter | Type | 35 | | --------------------- | ----- | 36 | | VRCOSC/Media/Play | Bool | 37 | | VRCOSC/Media/Next | None | 38 | | VRCOSC/Media/Previous | None | 39 | | VRCOSC/Media/Shuffle | Bool | 40 | | VRCOSC/Media/Seeking | Bool | 41 | | VRCOSC/Media/Muted | Bool | 42 | | VRCOSC/Media/Repeat | Int | 43 | | VRCOSC/Media/Volume | Float | 44 | | VRCOSC/Media/Position | Float | 45 | 46 | [^1]: This feature requires Spotify Premium 47 | [VRCOSC Media Prefab]: https://github.com/VolcanicArts/VRCOSC/releases/latest 48 | -------------------------------------------------------------------------------- /plugin-spotify/src/chatbox.rs: -------------------------------------------------------------------------------- 1 | use anyhow::{bail, Context, Result}; 2 | use async_ffi::async_ffi; 3 | use ferrispot::{ 4 | model::{playback::PlayingType, track::FullTrack}, 5 | prelude::*, 6 | }; 7 | use terminal_link::Link; 8 | use tokio::runtime::Handle; 9 | 10 | use crate::{LYRICS, SPOTIFY}; 11 | 12 | #[no_mangle] 13 | #[async_ffi(?Send)] 14 | #[allow(clippy::unnecessary_wraps)] 15 | #[allow(clippy::needless_pass_by_value)] 16 | async extern "Rust" fn chat( 17 | mut chatbox: String, 18 | mut console: String, 19 | handle: Handle, 20 | ) -> Result<(String, String)> { 21 | let _enter = handle.enter(); 22 | let config = crate::config()?; 23 | let spotify = SPOTIFY.get().context("Spotify is Authenticating...")?; 24 | let mut lyrics = LYRICS.get().context("Lyrics is Authenticating...")?.clone(); 25 | 26 | let current_item = spotify 27 | .currently_playing_item() 28 | .send_async() 29 | .await? 30 | .context("None")?; 31 | 32 | let public_item = current_item.public_playing_item().context("None")?; 33 | let PlayingType::Track(track) = public_item.item() else { 34 | bail!("None") 35 | }; 36 | 37 | if config.enable_lyrics { 38 | if let Ok(color_lyrics) = lyrics.get_color_lyrics(track.id().as_str()).await { 39 | let words = color_lyrics 40 | .lyrics 41 | .lines 42 | .iter() 43 | .rev() 44 | .try_find(|line| { 45 | u64::try_from(public_item.progress().as_millis()) 46 | .map(|progress| line.start_time_ms < progress) 47 | }) 48 | .iter() 49 | .flatten() 50 | .map(|line| line.words.clone()) 51 | .collect::>() 52 | .join(" "); 53 | 54 | if !words.is_empty() && words != "♪" { 55 | chatbox = words.clone(); 56 | console = words; 57 | 58 | return Ok((chatbox, console)); 59 | } 60 | }; 61 | } 62 | 63 | replace(&mut chatbox, track); 64 | replace(&mut console, track); 65 | 66 | let href = track.external_urls().spotify.clone().context("None")?; 67 | let link = Link::new(&console, &href); 68 | Ok((chatbox, link.to_string())) 69 | } 70 | 71 | fn replace(message: &mut String, track: &FullTrack) { 72 | let id = &track.id().to_string(); 73 | let song = track.name(); 74 | let artists = track 75 | .artists() 76 | .iter() 77 | .map(CommonArtistInformation::name) 78 | .collect::>() 79 | .join(", "); 80 | 81 | *message = message 82 | .replace("{id}", id) 83 | .replace("{song}", song) 84 | .replace("{artists}", &artists); 85 | } 86 | -------------------------------------------------------------------------------- /plugin-spotify/src/control.rs: -------------------------------------------------------------------------------- 1 | use std::{collections::HashMap, net::UdpSocket}; 2 | 3 | use anyhow::Result; 4 | use ferrispot::{ 5 | client::authorization_code::AsyncAuthorizationCodeUserClient, 6 | model::playback::RepeatState, 7 | prelude::*, 8 | }; 9 | use rosc::{decoder::MTU, OscMessage, OscPacket, OscType}; 10 | 11 | #[allow(clippy::too_many_lines)] 12 | pub async fn start_loop( 13 | socket: UdpSocket, 14 | spotify: AsyncAuthorizationCodeUserClient, 15 | ) -> Result<()> { 16 | let mut previous_parameters = HashMap::new(); 17 | let mut muted_volume = None; 18 | let mut buf = [0u8; MTU]; 19 | loop { 20 | let size = socket.recv(&mut buf)?; 21 | let (_buf, packet) = rosc::decoder::decode_udp(&buf[..size])?; 22 | let OscPacket::Message(packet) = packet else { 23 | continue; // I don't think VRChat uses bundles 24 | }; 25 | 26 | let addr = packet.addr.replace("/avatar/parameters/VRCOSC/Media/", ""); 27 | let Some(arg) = packet.args.first() else { 28 | continue; // No first argument was supplied 29 | }; 30 | 31 | let Some(playback_state) = spotify.playback_state().send_async().await? else { 32 | continue; // No media is currently playing 33 | }; 34 | 35 | if muted_volume.is_none() { 36 | muted_volume = Some(playback_state.device().volume_percent()); 37 | } 38 | 39 | let request = match addr.as_ref() { 40 | "Play" => { 41 | let OscType::Bool(play) = arg.to_owned() else { 42 | continue; 43 | }; 44 | 45 | if play { 46 | spotify.resume() 47 | } else { 48 | spotify.pause() 49 | } 50 | } 51 | "Next" => spotify.next(), 52 | "Prev" | "Previous" => spotify.previous(), 53 | "Shuffle" => { 54 | let OscType::Bool(shuffle) = arg.to_owned() else { 55 | continue; 56 | }; 57 | 58 | spotify.shuffle(shuffle) 59 | } 60 | // Seeking is not required because position is not used multiple times 61 | // "Seeking" => continue, 62 | "Muted" => { 63 | let OscType::Bool(mute) = arg.to_owned() else { 64 | continue; 65 | }; 66 | 67 | let volume = if mute { 68 | muted_volume = Some(playback_state.device().volume_percent()); 69 | 0 70 | } else { 71 | muted_volume.expect("Failed to get previous volume") 72 | }; 73 | 74 | spotify.volume(volume) 75 | } 76 | "Repeat" => { 77 | let OscType::Int(repeat) = arg.to_owned() else { 78 | continue; 79 | }; 80 | 81 | let repeat_state = match repeat { 82 | 0 => RepeatState::Off, 83 | 1 => RepeatState::Track, 84 | 2 => RepeatState::Context, 85 | _ => continue, 86 | }; 87 | 88 | spotify.repeat_state(repeat_state) 89 | } 90 | "Volume" => { 91 | let OscType::Float(volume) = arg.to_owned() else { 92 | continue; 93 | }; 94 | 95 | #[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)] 96 | spotify.volume((volume * 100.0) as u8) 97 | } 98 | "Position" => { 99 | let OscType::Float(position) = arg.to_owned() else { 100 | continue; 101 | }; 102 | 103 | let min = 0; 104 | let max = playback_state.currently_playing_item().timestamp(); 105 | 106 | #[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)] 107 | spotify.seek((min + (max - min) * (position * 100.0) as u64) / 100) 108 | } 109 | _ => { 110 | let Some(playback_state) = spotify.playback_state().send_async().await? else { 111 | return Ok(()); // No media is currently playing 112 | }; 113 | 114 | let mut parameters = HashMap::new(); 115 | 116 | let play = OscType::Bool(playback_state.device().is_active()); 117 | if previous_parameters.get("Play") != Some(&play) { 118 | parameters.insert("Play", play.clone()); 119 | previous_parameters.insert("Play", play); 120 | } 121 | 122 | let shuffle = OscType::Bool(playback_state.shuffle_state()); 123 | if previous_parameters.get("Shuffle") != Some(&shuffle) { 124 | parameters.insert("Shuffle", shuffle.clone()); 125 | previous_parameters.insert("Shuffle", shuffle); 126 | } 127 | 128 | let repeat = OscType::Int(match playback_state.repeat_state() { 129 | RepeatState::Off => 0, 130 | RepeatState::Track => 1, 131 | RepeatState::Context => 2, 132 | }); 133 | if previous_parameters.get("Repeat") != Some(&repeat) { 134 | parameters.insert("Repeat", repeat.clone()); 135 | previous_parameters.insert("Repeat", repeat); 136 | } 137 | 138 | for (param, arg) in parameters { 139 | let packet = OscPacket::Message(OscMessage { 140 | addr: format!("/avatar/parameters/VRCOSC/Media/{param}"), 141 | args: vec![arg], 142 | }); 143 | 144 | let msg_buf = rosc::encoder::encode(&packet)?; 145 | socket.send(&msg_buf)?; 146 | } 147 | 148 | continue; 149 | } 150 | }; 151 | 152 | if let Err(error) = request.send_async().await { 153 | eprintln!("Spotify Control Error: {error}"); 154 | }; 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /plugin-spotify/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature(once_cell_try)] 2 | #![feature(try_find)] 3 | 4 | mod chatbox; 5 | mod control; 6 | 7 | use std::{net::UdpSocket, sync::OnceLock, time::Duration}; 8 | 9 | use anyhow::{bail, Result}; 10 | use derive_config::DeriveTomlConfig; 11 | #[cfg(debug_assertions)] 12 | use dotenvy_macro::dotenv; 13 | use ferrispot::{ 14 | client::{ 15 | authorization_code::{ 16 | AsyncAuthorizationCodeUserClient, 17 | AsyncIncompleteAuthorizationCodeUserClient, 18 | }, 19 | SpotifyClientBuilder, 20 | }, 21 | prelude::*, 22 | scope::Scope, 23 | }; 24 | use inquire::{Confirm, Text}; 25 | use serde::{Deserialize, Serialize}; 26 | use spotify_lyrics::{Browser, SpotifyLyrics}; 27 | use tiny_http::{Header, Response, Server}; 28 | use url::Url; 29 | 30 | #[cfg(debug_assertions)] 31 | const SPOTIFY_CLIENT: &str = dotenv!("SPOTIFY_CLIENT"); 32 | #[cfg(debug_assertions)] 33 | const SPOTIFY_SECRET: &str = dotenv!("SPOTIFY_SECRET"); 34 | #[cfg(debug_assertions)] 35 | const SPOTIFY_CALLBACK: &str = dotenv!("SPOTIFY_CALLBACK"); 36 | 37 | #[cfg(not(debug_assertions))] 38 | const SPOTIFY_CLIENT: &str = env!("SPOTIFY_CLIENT"); 39 | #[cfg(not(debug_assertions))] 40 | const SPOTIFY_SECRET: &str = env!("SPOTIFY_SECRET"); 41 | #[cfg(not(debug_assertions))] 42 | const SPOTIFY_CALLBACK: &str = env!("SPOTIFY_CALLBACK"); 43 | 44 | #[allow(clippy::struct_excessive_bools)] 45 | #[derive(Clone, Debug, DeriveTomlConfig, Deserialize, Serialize)] 46 | pub struct Config { 47 | pub client: String, 48 | pub format: String, 49 | pub redirect_uri: String, 50 | pub refresh_token: String, 51 | pub secret: String, 52 | pub enable_control: bool, 53 | pub enable_lyrics: bool, 54 | pub pkce: bool, 55 | pub send_once: bool, 56 | pub polling: u64, 57 | } 58 | 59 | impl Default for Config { 60 | fn default() -> Self { 61 | Self { 62 | client: SPOTIFY_CLIENT.into(), 63 | secret: SPOTIFY_SECRET.into(), 64 | redirect_uri: SPOTIFY_CALLBACK.into(), 65 | format: "📻 {song} - {artists}".into(), 66 | refresh_token: String::new(), 67 | enable_control: false, 68 | enable_lyrics: true, 69 | pkce: false, 70 | send_once: true, 71 | polling: 1, 72 | } 73 | } 74 | } 75 | 76 | static SPOTIFY: OnceLock = OnceLock::new(); 77 | static LYRICS: OnceLock = OnceLock::new(); 78 | static CONFIG: OnceLock = OnceLock::new(); 79 | 80 | fn config() -> Result<&'static Config> { 81 | CONFIG.get_or_try_init(|| { 82 | Config::load().or_else(|_| { 83 | println!("The Spotify plugin requires you to create a Spotify Developer Application"); 84 | println!("https://github.com/ShayBox/VRC-OSC/tree/master/plugin-spotify#how-to-setup"); 85 | println!("https://developer.spotify.com/dashboard"); 86 | 87 | let mut config = Config::default(); 88 | 89 | config.enable_control = 90 | Confirm::new("Would you like to enable Spotify Controls? (Spotify Premium)") 91 | .with_default(config.enable_control) 92 | .prompt()?; 93 | 94 | config.enable_lyrics = Confirm::new("Would you like to enable Spotify Lyrics?") 95 | .with_default(config.enable_lyrics) 96 | .prompt()?; 97 | 98 | config.client = Text::new("Spotify Client ID: ") 99 | .with_default(&config.client) 100 | .prompt()?; 101 | 102 | config.secret = Text::new("Spotify Client Secret: ") 103 | .with_default(&config.secret) 104 | .prompt()?; 105 | 106 | config.redirect_uri = Text::new("Spotify Redirect URI: ") 107 | .with_default(&config.redirect_uri) 108 | .prompt()?; 109 | 110 | config.save()?; 111 | 112 | Ok(config) 113 | }) 114 | }) 115 | } 116 | 117 | #[no_mangle] 118 | #[allow(clippy::needless_pass_by_value)] 119 | #[tokio::main(flavor = "current_thread")] 120 | async extern "Rust" fn load(socket: UdpSocket) -> Result<()> { 121 | let mut config = config()?.clone(); 122 | let mut lyrics = SpotifyLyrics::from_browser(Browser::All)?; 123 | let spotify = login_to_spotify(&mut config).await?; 124 | 125 | // Disable lyrics if Spotify Lyrics failed to authenticate 126 | if let Err(error) = lyrics.refresh_authorization().await { 127 | config.enable_lyrics = false; 128 | eprintln!("{error}"); 129 | }; 130 | 131 | SPOTIFY.set(spotify.clone()).expect("Failed to set SPOTIFY"); 132 | LYRICS.set(lyrics).expect("Failed to set LYRICS"); 133 | 134 | if config.enable_control { 135 | control::start_loop(socket, spotify).await?; 136 | } 137 | 138 | loop { 139 | // Keep the threads alive - STATUS_ACCESS_VIOLATION 140 | tokio::time::sleep(Duration::from_secs(u64::MAX)).await; 141 | } 142 | } 143 | 144 | async fn login_to_spotify(config: &mut Config) -> Result { 145 | Ok(if config.pkce { 146 | let spotify_client = SpotifyClientBuilder::new(&config.client).build_async(); 147 | 148 | if let Ok(spotify) = spotify_client 149 | .authorization_code_client_with_refresh_token_and_pkce(&config.refresh_token) 150 | .await 151 | { 152 | spotify 153 | } else { 154 | let incomplete_auth_code_client = spotify_client 155 | .authorization_code_client_with_pkce(&config.redirect_uri) 156 | .show_dialog(config.refresh_token.is_empty()) 157 | .scopes([ 158 | Scope::UserModifyPlaybackState, 159 | Scope::UserReadCurrentlyPlaying, 160 | Scope::UserReadPlaybackState, 161 | ]) 162 | .build(); 163 | 164 | finish_authentication_and_save(config, incomplete_auth_code_client).await? 165 | } 166 | } else { 167 | let spotify_client = SpotifyClientBuilder::new(&config.client) 168 | .client_secret(&config.secret) 169 | .build_async() 170 | .await?; 171 | 172 | if let Ok(spotify) = spotify_client 173 | .authorization_code_client_with_refresh_token(&config.refresh_token) 174 | .await 175 | { 176 | spotify 177 | } else { 178 | let incomplete_auth_code_client = spotify_client 179 | .authorization_code_client(&config.redirect_uri) 180 | .show_dialog(config.refresh_token.is_empty()) 181 | .scopes([ 182 | Scope::UserModifyPlaybackState, 183 | Scope::UserReadCurrentlyPlaying, 184 | Scope::UserReadPlaybackState, 185 | ]) 186 | .build(); 187 | 188 | finish_authentication_and_save(config, incomplete_auth_code_client).await? 189 | } 190 | }) 191 | } 192 | 193 | async fn finish_authentication_and_save( 194 | config: &mut Config, 195 | client: AsyncIncompleteAuthorizationCodeUserClient, 196 | ) -> Result { 197 | let authorize_url = client.get_authorize_url(); 198 | let redirect_uri = &config.redirect_uri; 199 | 200 | let (code, state) = get_user_authorization(&authorize_url, redirect_uri)?; 201 | let spotify = client.finalize(code.trim(), state.trim()).await?; 202 | 203 | spotify.refresh_access_token().await?; 204 | 205 | config.refresh_token = spotify.get_refresh_token(); 206 | config.save()?; 207 | 208 | Ok(spotify) 209 | } 210 | 211 | fn get_user_authorization(authorize_url: &str, redirect_uri: &str) -> Result<(String, String)> { 212 | match webbrowser::open(authorize_url) { 213 | Ok(ok) => ok, 214 | Err(why) => eprintln!( 215 | "Error when trying to open an URL in your browser: {why:?}. \ 216 | Please navigate here manually: {authorize_url}", 217 | ), 218 | } 219 | 220 | let addr = redirect_uri.replace("http://", "").replace("https://", ""); 221 | let server = Server::http(addr).expect("Failed to bind server"); 222 | let request = server.recv()?; 223 | 224 | let request_url = redirect_uri.to_owned() + request.url(); 225 | let parsed_url = Url::parse(&request_url)?; 226 | 227 | let header = Header::from_bytes(&b"Content-Type"[..], &b"text/html"[..]).unwrap(); 228 | let mut response = if parsed_url.query_pairs().count() == 2 { 229 | Response::from_string( 230 | "

You may close this tab

\ 231 | ", 232 | ) 233 | } else { 234 | Response::from_string("

An error has occurred

") 235 | }; 236 | 237 | response.add_header(header); 238 | request.respond(response).expect("Failed to send response"); 239 | 240 | let Some(code) = parsed_url.query_pairs().next() else { 241 | bail!("None") 242 | }; 243 | let Some(state) = parsed_url.query_pairs().nth(1) else { 244 | bail!("None") 245 | }; 246 | 247 | Ok((code.1.into(), state.1.into())) 248 | } 249 | -------------------------------------------------------------------------------- /plugin-steamvr/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "plugin-steamvr" 3 | description = "Registers VRC-OSC as a SteamVR overlay for auto-start/stop" 4 | version.workspace = true 5 | authors.workspace = true 6 | edition.workspace = true 7 | 8 | [lib] 9 | name = "steamvr" 10 | crate-type = ["cdylib"] 11 | 12 | [dependencies] 13 | anyhow.workspace = true 14 | derive-config = { workspace = true, features = ["toml"] } 15 | ovr_overlay = { workspace = true, features = ["ovr_applications"] } 16 | serde = { workspace = true, features = ["derive"] } 17 | serde_json.workspace = true 18 | structstruck.workspace = true 19 | tokio = { workspace = true, features = ["macros", "rt"] } 20 | toml.workspace = true 21 | 22 | [lints.clippy] 23 | pedantic = "warn" 24 | nursery = "warn" 25 | -------------------------------------------------------------------------------- /plugin-steamvr/README.md: -------------------------------------------------------------------------------- 1 | 9 | 10 | # SteamVR Plugin 11 | 12 | Registers VRC-OSC as a SteamVR overlay for auto-start/stop 13 | 14 | This plugin is Windows and Linux only because SteamVR is not available on macOS 15 | -------------------------------------------------------------------------------- /plugin-steamvr/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::net::UdpSocket; 2 | 3 | use anyhow::Result; 4 | use derive_config::DeriveTomlConfig; 5 | use serde::{Deserialize, Serialize}; 6 | 7 | use crate::openvr::Manifest; 8 | 9 | mod openvr; 10 | 11 | #[derive(Clone, Debug, DeriveTomlConfig, Deserialize, Serialize)] 12 | pub struct Config { 13 | pub register: bool, 14 | } 15 | 16 | impl Default for Config { 17 | fn default() -> Self { 18 | Self { register: true } 19 | } 20 | } 21 | 22 | #[no_mangle] 23 | #[allow(clippy::needless_pass_by_value)] 24 | #[tokio::main(flavor = "current_thread")] 25 | async extern "Rust" fn load(_socket: UdpSocket) -> Result<()> { 26 | if let Ok(context) = ovr_overlay::Context::init() { 27 | let manager = &mut context.applications_mngr(); 28 | let config = Config::load()?; 29 | let manifest = Manifest::load()?; 30 | let path = Manifest::get_path()?; 31 | 32 | if manager.is_application_installed(&manifest.applications[0].app_key)? { 33 | manager.remove_application_manifest(&path)?; 34 | } 35 | 36 | if config.register { 37 | manager.add_application_manifest(&path, false)?; 38 | } 39 | } 40 | 41 | Ok(()) 42 | } 43 | -------------------------------------------------------------------------------- /plugin-steamvr/src/openvr.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | collections::HashMap, 3 | fs::File, 4 | io::{BufReader, BufWriter}, 5 | path::PathBuf, 6 | }; 7 | 8 | use anyhow::Result; 9 | use serde::{Deserialize, Serialize}; 10 | 11 | structstruck::strike! { 12 | #[strikethrough[derive(Debug, Serialize, Deserialize)]] 13 | pub struct Manifest { 14 | pub source: String, 15 | pub applications: Vec, 24 | }>, 25 | } 26 | } 27 | 28 | impl Default for Manifest { 29 | fn default() -> Self { 30 | Self { 31 | source: "builtin".into(), 32 | applications: vec![Applications { 33 | app_key: "com.shaybox.vrc-osc".into(), 34 | launch_type: "binary".into(), 35 | binary_path_windows: "vrc-osc.exe".into(), 36 | is_dashboard_overlay: true, 37 | strings: HashMap::from([( 38 | "en_us".into(), 39 | Strings { 40 | name: "VRC-OSC".into(), 41 | description: "VRChat OSC Overlay".into(), 42 | }, 43 | )]), 44 | }], 45 | } 46 | } 47 | } 48 | 49 | impl Manifest { 50 | pub fn get_path() -> Result { 51 | let mut path = std::env::current_exe()?; 52 | path.set_file_name("vrc-osc"); 53 | path.set_extension("vrmanifest"); 54 | 55 | Ok(path) 56 | } 57 | 58 | pub fn load() -> Result { 59 | let path = Self::get_path()?; 60 | let file = File::options() 61 | .append(true) 62 | .create(true) 63 | .read(true) 64 | .open(path)?; 65 | 66 | let reader = BufReader::new(&file); 67 | if let Ok(config) = serde_json::from_reader(reader) { 68 | Ok(config) 69 | } else { 70 | let manifest = Self::default(); 71 | let writer = BufWriter::new(&file); 72 | serde_json::to_writer_pretty(writer, &manifest)?; 73 | 74 | Ok(manifest) 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly" 3 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | enum_discrim_align_threshold = 10 2 | group_imports = "StdExternalCrate" 3 | imports_granularity = "Crate" 4 | imports_layout = "HorizontalVertical" 5 | struct_field_align_threshold = 10 6 | --------------------------------------------------------------------------------