Skip to content

Commit

Permalink
Merge pull request #19 from C0D3-M4513R/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
C0D3-M4513R authored Sep 12, 2024
2 parents c890687 + 0d15bc2 commit 6b7b88f
Show file tree
Hide file tree
Showing 10 changed files with 182 additions and 39 deletions.
4 changes: 3 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ strip = true
lto = true

[patch.crates-io]
egui_tracing = { git = "https://github.com/grievouz/egui_tracing.git", rev = "7604668cb94e1b60b9d6291f15e22bd3fe70dbca"}
egui_tracing = { git = "https://github.com/C0D3-M4513R/egui_tracing.git", rev = "2562729fa1de46d288aea2373aaac856737f10e9"}
1 change: 0 additions & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,3 @@ If that happens, just scroll up, so you are not on the very bottom anymore and t

# Notes
- The Application doesn't handle one Udp Packet containting multiple OSC Packets well.
- The Osc Multplexer might interact wierdly with raw message forwarding. Some bits of packets might be sent multiple times in a row in certain situations.
5 changes: 3 additions & 2 deletions app/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ aes = "0.8.3"
#block-padding = "0.3.3"

[features]
default = ["file_dialog"]
default = ["file_dialog", "egui/deadlock_detection"]
file_dialog = ["dep:rfd"]
no_decryption_keys = []
oscquery = []
oscquery = []
debug_log = []
15 changes: 10 additions & 5 deletions app/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::osc::OscCreateData;
pub struct App<'a>{
logs_visible: bool,
#[serde(skip)]
collector:egui_tracing::EventCollector,
collector:egui_tracing::Logs,
auto_connect_launch: bool,
ip:String,
path:String,
Expand Down Expand Up @@ -69,7 +69,7 @@ impl<'a> Default for App<'a>{
fn default() -> Self {
Self{
logs_visible: false,
collector:egui_tracing::EventCollector::new(),
collector:egui_tracing::Logs::new(egui_tracing::EventCollector::new()),
auto_connect_launch: true,
ip:"127.0.0.1".to_string(),
path: "".to_string(),
Expand Down Expand Up @@ -127,7 +127,7 @@ impl<'a> App<'a> {

#[cfg(not(debug_assertions))]
log::info!("You are running a release build. Some log statements were disabled.");
slf.collector = collector;
slf.collector = egui_tracing::Logs::new(collector);
if slf.auto_connect_launch{
slf.spawn_osc_from_creation_data();
}
Expand Down Expand Up @@ -275,7 +275,8 @@ impl<'a> App<'a> {
ui.heading("Osc Multiplexer:");
ui.label("All messages Received from the Osc Receive Port will be forwarded to the Ports specified in the list below.");
ui.label("This allows you to use multiple Osc Applications, that need to Receive Messages, at the same time.");
ui.checkbox(&mut self.osc_multiplexer_parse_packets, "Parse Packets and Ignore Packets that can't be parsed: ");

ui.checkbox(&mut self.osc_multiplexer_parse_packets, "Parse Packets and Ignore Packets that can't be parsed");
if ui.add_enabled(self.osc_multiplexer_port_popup.is_none(), egui::Button::new("Manage Ports")).clicked() {
self.osc_multiplexer_port_popup = Some(popup_creator_collapsible("Osc Multiplexer Ports:", true, |app, ui|{
let mut i = 0;
Expand Down Expand Up @@ -327,6 +328,9 @@ impl<'a> App<'a> {
.speed(1)
.range(1..=usize::try_from(isize::MAX).unwrap_or(usize::MAX))
.ui(ui);
if ui.button("Reset to Default").clicked() {
self.max_message_size = osc_handler::OSC_RECV_BUFFER_SIZE;
}
});
ui.label("Please note that the Settings in the Ui will only be applied after you Reconnect/Connect.");
ui.horizontal(|ui|{
Expand Down Expand Up @@ -405,7 +409,8 @@ impl<'a> eframe::App for App<'a> {
});
if logs_visible {
strip.cell(|ui|{
ui.add(egui_tracing::Logs::new(self.collector.clone()));
ctx.request_repaint_after_secs(15.);
ui.add(&mut self.collector);
});
}
});
Expand Down
106 changes: 99 additions & 7 deletions app/src/osc/dex.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
use std::collections::VecDeque;
use std::collections::{HashMap, VecDeque};
use std::future::Future;
use std::ops::{Index, Shr};
use std::pin::Pin;
use std::str::FromStr;
use std::sync::Arc;
use std::time::Duration;
use aes::cipher::KeyIvInit;
use cbc::cipher::BlockDecryptMut;
use egui::mutex::Mutex;
use rosc::{OscBundle, OscMessage, OscPacket, OscType};
use unicode_bom::Bom;
use super::OscSender;
use super::OscCreateData;

const DEX_KEY_WAIT_MS:u64 = 1_500;
const DEX_KEY_WAIT_DESC:&'static str = "1.5 seconds";

#[derive(Clone)]
pub(super) struct DexOscHandler {
path: Arc<std::path::Path>,
dex_use_bundles: bool,
osc: Arc<OscSender>,
params: Arc<Mutex<Option<(tokio::task::AbortHandle, HashMap<String, f32>)>>>,
}

impl DexOscHandler {
Expand All @@ -24,6 +30,7 @@ impl DexOscHandler {
path: Arc::from(osc_create_data.path.clone()),
dex_use_bundles: osc_create_data.dex_use_bundles,
osc,
params: Arc::new(Mutex::new(None)),
}
}
}
Expand Down Expand Up @@ -53,13 +60,66 @@ impl osc_handler::MessageHandler for DexOscHandler
}
}
if let Some(id) = id {
log::info!("Got Avatar Change to {id}");
let clone = self.clone();
return futures::future::Either::Right(Box::pin(clone.handle_avatar_change(Arc::from(id.as_str()))))
}else{
log::error!("No avatar id was found for the '/avatar/change' message. This is unexpected and might be a change to VRChat's OSC messages.")
}
} else if message.addr.starts_with("/avatar/parameters/") {
let mut replace = false;

{
let mut params = self.params.lock();
match params.as_mut() {
Some((abort, params)) => {
match params.remove(&message.addr) {
None => {
#[cfg(all(debug_assertions, feature="debug_log"))]
{
log::trace!("Got a non-avatar-key parameter set: {}", message.addr);
}
}
Some(val) => {
if message.args.len() > 1 {
log::error!("An Avatar Key parameter at the path '{}' was set to multiple values. Currently this is unexpected. Values: {:?}", message.addr, message.args);
replace = true;
}
match message.args.get(0) {
None => {
log::error!("An Avatar Key parameter at the path '{}' was set to no values. Currently this is unexpected.", message.addr);
replace = true;
}
Some(OscType::Float(f)) => {
if *f != val {
log::error!("An Avatar Key parameter at the path '{}' was set to a different value than the key. ", message.addr);
replace = true;
}
}
Some(v) => {
log::error!("An Avatar Key parameter at the path '{}' was set to a non-float value. Currently this is unexpected. Value: {v:?}", message.addr);
replace = true;
}
}
}
}

if params.is_empty() {
log::info!("Key has been applied successfully.");
abort.abort();
replace = true;
}
}
None => {}
}
}

//create a different arc here, so that any cloned arcs are still valid.
if replace {
self.params = Arc::new(Mutex::new(None));
}
}else{
#[cfg(debug_assertions)]
#[cfg(all(debug_assertions, feature="debug_log"))]
log::trace!("Uninteresting OSC Message for DexProtect: {:?}", message)
}
futures::future::Either::Left(core::future::ready(()))
Expand All @@ -74,7 +134,7 @@ impl DexOscHandler {
}
path.set_file_name(id.as_ref());
path.set_extension("key");
match tokio::fs::read(path).await{
match tokio::fs::read(path.as_path()).await{
Ok(potentially_decrypted) => {
let (v, err) = decrpyt(potentially_decrypted);
if let Some(err) = err {
Expand All @@ -87,11 +147,11 @@ impl DexOscHandler {
return;
}
};
#[cfg(debug_assertions)]
#[cfg(all(debug_assertions, feature="debug_log"))]
log::debug!("Decoded Avatar id '{}' Key file: '{}'", id, decoded);
let mut key:Vec<rosc::OscPacket> = Vec::new();
decoded = decoded.replace(",", ".");
#[cfg(debug_assertions)]
#[cfg(all(debug_assertions, feature="debug_log"))]
log::debug!("Decoded Avatar id '{}' post processed Key file: '{}'", id, decoded);
let split:Vec<&str> = decoded.split("|").collect();
let len = if split.len()%2 == 0 {
Expand All @@ -101,8 +161,10 @@ impl DexOscHandler {
split.len()-1
};
let mut i = 0;
let mut params = HashMap::with_capacity(len);
while i < len {
let float = split[i];
#[cfg(all(debug_assertions, feature="debug_log"))]
log::trace!("Decoding float: {}", float);
let whole:u32;
let part:u32;
Expand All @@ -111,6 +173,7 @@ impl DexOscHandler {
let (whole_str, part_str) = float.split_at(index);
let mut part_string = part_str.to_string();
part_string.remove(0);
#[cfg(all(debug_assertions, feature="debug_log"))]
log::trace!("Decoding float: {}, whole: {}, part:{}", float,whole_str, part_string);
whole = match decode_number(whole_str, &id){
Some(v) => v,
Expand All @@ -130,6 +193,7 @@ impl DexOscHandler {
part_digits = 0;
}
let amount = whole as f32 + part as f32/(10.0f32.powf(part_digits as f32));
params.insert(format!("/avatar/parameters/{}", split[i+1]), amount);
if self.dex_use_bundles {
key.push(OscPacket::Message(OscMessage{
addr: format!("/avatar/parameters/{}", split[i+1]),
Expand Down Expand Up @@ -157,11 +221,39 @@ impl DexOscHandler {
let _ = v.await;
};
}
log::info!("Avatar Change Detected to Avatar id '{}'. Key was detected, has been decoded and the Avatar has been Unlocked.", id);
log::info!("A Key for the Avatar id '{}' was detected and decoded. The Avatar has been attempted to be Unlocked.", id);
params.shrink_to_fit();
let params_clone = self.params.clone();
let jh = tokio::task::spawn(async move {
tokio::time::sleep(Duration::from_millis(DEX_KEY_WAIT_MS)).await;
let params = params_clone.lock();
let params = &*params;
match params {
None => {
log::warn!("Unexpected None variant in the Avatar Key application. This is unexpected and might be a bug.");
log::trace!("All Avatar Keys have been supplied after {DEX_KEY_WAIT_DESC}.")
}
Some((_, params)) => {
if params.is_empty() {
log::trace!("All Avatar Keys have been supplied after {DEX_KEY_WAIT_DESC}.")
} else {
#[cfg(all(debug_assertions, feature="debug_log"))]
{
log::error!("The Avatar Key has not been fully applied after {DEX_KEY_WAIT_DESC}. There are {} avatar keys, that were not applied. {params:?}", params.len());
}
#[cfg(not(all(debug_assertions, feature="debug_log")))]
{
log::error!("The Avatar Key has not been fully applied after {DEX_KEY_WAIT_DESC}. There are {} avatar keys, that were not applied.", params.len());
}
}
}
}
});
*self.params.lock() = Some((jh.abort_handle(), params));
}
Err(e) => {
if e.kind() == std::io::ErrorKind::NotFound{
log::info!("No key detected for avatar ID {}, not unlocking.\nAssuming that the following error actually means the file doesn't exist and not just a directory along the way:\n {}", id, e);
log::info!("No key detected for avatar ID {id} at {}, not unlocking.\nAssuming that the following error actually means the file doesn't exist and not just a directory along the way:\n {e}", path.display());
return;
}
log::error!("Failed to read the Avatar id '{}' from the Avatar Folder: {}.", id, e);
Expand Down
4 changes: 2 additions & 2 deletions app/src/osc/sender.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl OscSender {
/// If there are any errors, they will be logged.
/// If debug assertions are enabled, the sending attempt of the message will be logged and the successful sending will also be logged.
pub fn send_message_with_logs(&self, message: &rosc::OscPacket) -> Result<SendMessageLogs<Vec<u8>>, rosc::OscError> {
#[cfg(debug_assertions)]
#[cfg(all(debug_assertions, feature="debug_log"))]
log::trace!("Sending OSC Message: {:#?}", message);
match self.send_message_no_logs(message) {
Ok(fut) => Ok(SendMessageLogs{fut}),
Expand Down Expand Up @@ -98,7 +98,7 @@ impl<A: AsRef<[u8]>+Debug> Future for SendMessageLogs<A>{
match self.fut.poll_send(cx) {
Poll::Pending => Poll::Pending,
Poll::Ready((Ok(v), bytes)) => {
#[cfg(debug_assertions)]
#[cfg(all(debug_assertions, feature="debug_log"))]
{
log::debug!("Sent the following OSC Message with {v} bytes:{bytes:#?}");
}
Expand Down
4 changes: 3 additions & 1 deletion osc-handler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,6 @@ parking_lot = "0.12"
#We allow an async handler function.
#Because async recursion is not possible without Boxing, it was opted
tokio = "1"
futures = "0.3.30"
futures = "0.3.30"
[features]
debug_log = []
40 changes: 31 additions & 9 deletions osc-handler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ pub(crate) struct MessageDestructuring<H, P, R>
R: RawPacketHandler,
{
bundle_buf: Buf,
message_handler: H,
packet_handler: P,
raw_handler: R,
pub(crate) message_handler: H,
pub(crate) packet_handler: P,
pub(crate) raw_handler: R,
}

impl<H, P, R> MessageDestructuring<H, P, R>
Expand All @@ -87,20 +87,42 @@ where
}
}

pub(crate) fn handle_raw_packet<'a>(&mut self, packet_raw: &'a[u8]) -> Result<(&'a[u8], R::Fut<'a>, P::Fut, Results<H::Fut,H::Output>), rosc::OscError> {
#[cfg(debug_assertions)]
pub(crate) fn handle_raw_packets<'a>(&mut self, mut packet_raw: &'a[u8]) -> (&'a[u8], R::Fut<'a>, Vec<(P::Fut, Results<H::Fut,H::Output>)>, Option<rosc::OscError>) {
let orig_packet = packet_raw;
let mut results = Vec::new();
let mut e = None;
loop {
match self.handle_raw_packet(packet_raw) {
Ok((r, jp, res)) => {
results.push((jp, res));
packet_raw = r;
if packet_raw.is_empty() {
break;
}
}
Err(err) => {
e = Some(err);
break;
}
}
}
//Todo: assumption: rest is always at the end of the packet.
let js = self.raw_handler.handle(&orig_packet[..orig_packet.len()-packet_raw.len()]);
return (packet_raw, js, results, e);
}
pub(crate) fn handle_raw_packet<'a>(&mut self, packet_raw: &'a[u8]) -> Result<(&'a[u8], P::Fut, Results<H::Fut,H::Output>), rosc::OscError> {
#[cfg(all(debug_assertions, feature="debug_log"))]
log::trace!("Received UDP Packet with size {} ",packet_raw.len());
match rosc::decoder::decode_udp(packet_raw) {
Err(e) => {
log::error!("Error decoding udp packet into an OSC Packet: {}", e);
#[cfg(debug_assertions)]
#[cfg(all(debug_assertions, feature="debug_log"))]
log::trace!("Packet contents were: {:#X?}",packet_raw);
Err(e)
}
Ok((rest, packet)) => {
let js = self.raw_handler.handle(packet_raw);
let (fut, res) = self.handle_packet(Arc::new(osc_types_arc::OscPacket::from(packet)));
Ok((rest, js, fut, res))
Ok((rest, fut, res))
},
}
}
Expand Down Expand Up @@ -172,7 +194,7 @@ where
fn internal_handle_packet(&mut self, packet: &Arc<osc_types_arc::OscPacket>) -> Results<H::Fut,H::Output> {
match packet.as_ref() {
osc_types_arc::OscPacket::Message(msg) => {
#[cfg(debug_assertions)]
#[cfg(all(debug_assertions, feature="debug_log"))]
log::trace!("Got a OSC Packet: {}: {:?}", msg.addr, msg.args);
self.handle_message(msg.clone())
}
Expand Down
Loading

0 comments on commit 6b7b88f

Please sign in to comment.