Skip to content

Commit 700a70a

Browse files
committed
feat(pishock): add dynamic intensity cap
1 parent df5bbbc commit 700a70a

File tree

6 files changed

+269
-36
lines changed

6 files changed

+269
-36
lines changed

Cargo.lock

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ async-osc = "0.2.0"
1313
cfg-if = "1.0.0"
1414
chrono = "0.4.24"
1515
clap = { version = "4.1.4", features = ["derive"] }
16+
debounced = "0.1.0"
1617
directories = "5.0.1"
1718
file-rotate = "0.7.4"
1819
log = "0.4.17"

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,14 @@ VRChat parameters:
7575
| `PS_ShockLeft_Pressed` | `bool` | Left shock button pressed |
7676
| `PS_ShockRight_Pressed` | `bool` | Right shock button pressed |
7777
| `PS_Intensity` | `float` | Intensity going from 0.0 to 1.0 |
78+
| `PS_IntensityCap` | `float` | Intensity cap going from 0.0 to 1.0 |
7879
| `PS_QuickShock` | `float` | Triggers a short shock with the given intensity once. Reset it by setting it to a negative value. |
7980
| `PS_ShockActive` | `bool` | Set to true while a shock is active, then automatically reset to false. |
8081

81-
You can configure the duration (default 4) and an intensity cap (default 1.0) through the configuration file. You must
82-
also set your credentials in there.
82+
You can configure the duration (default 4) through the configuration file. You must also set your credentials in there.
83+
84+
The intensity and intensity cap are periodically saved after 10 seconds of being changed. When an avatar loads in, it
85+
will automatically be populated with the last values.
8386

8487
Quick shocks are always send with a duration of 1 second. You can trigger these with your own contact receivers, e.g.
8588
by driving the variable through an animation controller.

src/config.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use anyhow::{Context, Result};
22
use directories::BaseDirs;
33
use serde::{Deserialize, Serialize};
4-
use tokio::fs::File;
4+
use tokio::fs::{metadata, File};
55
use tokio::io::{AsyncReadExt, AsyncWriteExt};
66

77
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -28,7 +28,6 @@ pub struct PiShockConfig {
2828
pub api_key: String,
2929
pub code: String,
3030
pub duration: u8,
31-
pub intensity_cap: f32,
3231
}
3332

3433
impl Default for PiShockConfig {
@@ -38,7 +37,6 @@ impl Default for PiShockConfig {
3837
api_key: "".to_string(),
3938
code: "".to_string(),
4039
duration: 4,
41-
intensity_cap: 1.,
4240
}
4341
}
4442
}
@@ -57,7 +55,7 @@ pub async fn load_config() -> Result<Config> {
5755
let config_dir = base_dirs.config_dir();
5856
let path = config_dir.join("vrc-osc-manager.toml");
5957

60-
if !path.exists() {
58+
if metadata(&path).await.is_err() {
6159
let config: Config = Default::default();
6260
let mut file = File::create(&path)
6361
.await

src/main.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use file_rotate::suffix::{AppendTimestamp, FileLimit};
1919
use file_rotate::{ContentLimit, FileRotate, TimeFrequency};
2020
use log::{debug, error, info, LevelFilter};
2121
use simplelog::{ColorChoice, CombinedLogger, TermLogger, TerminalMode, WriteLogger};
22+
use std::path::PathBuf;
2223
use std::sync::Arc;
2324
use std::time::Duration;
2425
use sysinfo::{ProcessRefreshKind, RefreshKind, System, SystemExt};
@@ -83,6 +84,7 @@ impl VrChatActivity {
8384
async fn run_plugins(
8485
subsys: SubsystemHandle,
8586
config: Arc<Config>,
87+
data_dir: PathBuf,
8688
receiver_tx: broadcast::Sender<OscMessage>,
8789
sender_tx: mpsc::Sender<OscMessage>,
8890
) -> Result<()> {
@@ -99,7 +101,7 @@ async fn run_plugins(
99101
let sender_tx = sender_tx.clone();
100102
let receiver_rx = receiver_tx.subscribe();
101103
subsys.start("PluginPiShock", |subsys| {
102-
plugins::pishock::PiShock::new(sender_tx, receiver_rx, config).run(subsys)
104+
plugins::pishock::PiShock::new(sender_tx, receiver_rx, config, data_dir).run(subsys)
103105
});
104106
}
105107

@@ -110,6 +112,7 @@ async fn run_plugins(
110112
struct Launcher {
111113
rx: mpsc::Receiver<bool>,
112114
config: Arc<Config>,
115+
data_dir: PathBuf,
113116
receiver_tx: broadcast::Sender<OscMessage>,
114117
sender_tx: mpsc::Sender<OscMessage>,
115118
dark_mode_icons: bool,
@@ -119,13 +122,15 @@ impl Launcher {
119122
fn new(
120123
rx: mpsc::Receiver<bool>,
121124
config: Arc<Config>,
125+
data_dir: PathBuf,
122126
receiver_tx: broadcast::Sender<OscMessage>,
123127
sender_tx: mpsc::Sender<OscMessage>,
124128
dark_mode_icons: bool,
125129
) -> Self {
126130
Self {
127131
rx,
128132
config,
133+
data_dir,
129134
receiver_tx,
130135
sender_tx,
131136
dark_mode_icons,
@@ -151,9 +156,10 @@ impl Launcher {
151156
let config = self.config.clone();
152157
let receiver_tx = self.receiver_tx.clone();
153158
let sender_tx = self.sender_tx.clone();
159+
let data_dir = self.data_dir.clone();
154160

155161
maybe_plugin_subsys = Some(subsys.start("Plugins", move |subsys| {
156-
run_plugins(subsys, config, receiver_tx, sender_tx)
162+
run_plugins(subsys, config, data_dir, receiver_tx, sender_tx)
157163
}));
158164
}
159165
}
@@ -171,9 +177,10 @@ impl Launcher {
171177
let config = self.config.clone();
172178
let receiver_tx = self.receiver_tx.clone();
173179
let sender_tx = self.sender_tx.clone();
180+
let data_dir = self.data_dir.clone();
174181

175182
maybe_plugin_subsys = Some(subsys.start("Plugins", move |subsys| {
176-
run_plugins(subsys, config, receiver_tx, sender_tx)
183+
run_plugins(subsys, config, data_dir, receiver_tx, sender_tx)
177184
}));
178185
}
179186
} else if !vrchat_running {
@@ -226,8 +233,8 @@ async fn main() -> Result<()> {
226233
let args = Args::parse();
227234

228235
let base_dirs = BaseDirs::new().context("Base directories not available")?;
229-
let data_dir = base_dirs.data_dir();
230-
let log_dir = data_dir.join("vrc-osc-manager/logs/log");
236+
let data_dir = base_dirs.data_dir().join("vrc-osc-manager");
237+
let log_dir = data_dir.join("logs/log");
231238

232239
let log_file = FileRotate::new(
233240
log_dir,
@@ -274,6 +281,7 @@ async fn main() -> Result<()> {
274281
Launcher::new(
275282
rx,
276283
config,
284+
data_dir,
277285
launcher_receiver_tx,
278286
sender_tx,
279287
args.dark_mode_icons,

0 commit comments

Comments
 (0)