Added cool file parsing QoL features and some arguments to make this actually usable

This commit is contained in:
Kyan Wanschers 2024-09-16 00:07:45 +02:00
parent 9924e9b0cb
commit b316c547de
8 changed files with 116 additions and 18 deletions

4
.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
debug/
target/
**/*.rs.bk
*.pdb

13
Cargo.lock generated
View file

@ -379,6 +379,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
@ -393,6 +394,18 @@ dependencies = [
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 2.0.77",
]
[[package]]
name = "clap_lex"
version = "0.7.2"

View file

@ -8,7 +8,7 @@ license = "GPL-3.0"
readme = "README.md"
[dependencies]
clap = { version = "4.5.17", features = ["cargo"] }
clap = { version = "4.5.17", features = ["derive"] }
image = "0.25.2"
piston = "1.0.0"
piston2d-graphics = "0.44.0"

View file

@ -1,15 +1,15 @@
use std::fs::{self, read, File};
use image::ImageReader;
use std::{ffi::OsStr, fs::{self, read, File}, os::raw, path::Path};
use image::{ImageFormat, ImageReader};
use unreal_asset::{asset::AssetTrait, cast, engine_version::EngineVersion, exports::{self, normal_export::NormalExport, Export, ExportBaseTrait}, properties::{array_property::ArrayProperty, color_property::ColorProperty, struct_property::StructProperty, Property}, types::{fname::FNameContainer, PackageIndex}, Asset};
pub fn rawrgb(path: &str) -> Result<Vec<u8>, String> {
fn rawrgb(path: &str) -> Result<Vec<u8>, String> {
match fs::read(path) {
Ok(res) => Ok(res),
Err(e) => Err(e.to_string()),
}
}
pub fn image(path: &str) -> Result<Vec<u8>, String> {
fn image(path: &str) -> Result<Vec<u8>, String> {
match image::ImageReader::open(path) {
Ok(res) => {
match res.decode() {
@ -23,8 +23,8 @@ pub fn image(path: &str) -> Result<Vec<u8>, String> {
}
}
pub fn uasset(path: &str) -> Result<Vec<u8>, String> {
//Shitty formats = Shitty code
fn uasset(path: &str) -> Result<Vec<u8>, String> {
let Some(path) = path.strip_suffix(".uasset") else {
return Err("File not .uasset".to_string())
};
@ -77,3 +77,18 @@ pub fn uasset(path: &str) -> Result<Vec<u8>, String> {
}
Ok(output)
}
pub fn parse(path: &str) -> Result<Vec<u8>, String> {
match Path::new(path).extension().and_then(OsStr::to_str) {
Some(s) => {
if s == "uasset" {
uasset(path)
} else if ImageFormat::from_extension(s).is_some() {
image(path)
} else {
rawrgb(path)
}
},
None => rawrgb(path),
}
}

View file

@ -1,5 +1,5 @@
#![allow(non_camel_case_types)]
use std::{io::Read, net::UdpSocket, sync::mpsc::{self, Receiver, Sender}, thread, time::{Duration, Instant}};
use crate::{ parser, fileparser };
pub fn stdin(tx: Sender<Vec<[f32; 4]>>) {
@ -23,7 +23,7 @@ pub fn stdin(tx: Sender<Vec<[f32; 4]>>) {
let _ = tx.send(r);
},
Err(_) => {
std::process::exit(0x0100);
std::process::exit(0);
},
};
}
@ -42,9 +42,9 @@ pub fn realtimeudp(tx: Sender<Vec<[f32; 4]>>) {
});
}
pub fn file(tx: Sender<Vec<[f32; 4]>>) {
pub fn file(tx: Sender<Vec<[f32; 4]>>, path: String) {
thread::spawn( move || {
let Ok(rawbytes) = fileparser::rawrgb("out.raw.lily") else {
let Ok(rawbytes) = fileparser::parse(&path) else {
std::process::exit(1)
};
for frame in rawbytes.chunks(720) {
@ -58,3 +58,10 @@ pub fn file(tx: Sender<Vec<[f32; 4]>>) {
std::process::exit(0);
});
}
#[derive(clap::ValueEnum, Clone, Debug)]
pub enum Input {
stdin,
realtimeudp,
file,
}

View file

@ -6,9 +6,27 @@ mod utils;
mod fileparser;
use std::sync::mpsc::{self, Receiver, Sender};
use clap::{command, Parser};
use clap::{command, error::{self, ContextKind, ContextValue, ErrorKind}, Parser};
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Args {
/// Name of the person to greet
#[arg(short, long)]
input: input::Input,
#[arg(required(false), short, long, requires = "input")]
file: Option<String>,
#[arg(short, long)]
output: output::Output,
#[arg(required(false), short, long, requires = "output")]
destip: Option<String>,
}
fn main() {
let args = Args::parse();
// let mut arg = clap::command!()
// .arg(clap::arg!(-o --output <file> "The output file to write to. Use - for stdout."))
// .arg_required_else_help(true);
@ -19,8 +37,27 @@ fn main() {
// } else {
// input::realtimeudp(tx)
// }
input::file(tx);
output::realtimeudp(rx)
match args.input {
input::Input::stdin => input::stdin(tx),
input::Input::realtimeudp => input::realtimeudp(tx),
input::Input::file => {
if args.file.is_some() {
input::file(tx, args.file.unwrap());
} else {
utils::err_missing_args(vec!["--file".to_owned()])
}
},
}
// input::file(tx);
// output::piston(rx) 21324
match args.output {
output::Output::piston => output::piston(rx),
output::Output::realtimeudp => {
if args.destip.is_some() {
output::realtimeudp(rx, args.destip.unwrap())
} else {
utils::err_missing_args(vec!["--destip".to_owned()])
}
},
}
}

View file

@ -1,3 +1,4 @@
#![allow(non_camel_case_types)]
extern crate piston_window;
use graphics;
@ -31,7 +32,7 @@ pub fn piston(rx: Receiver<Vec<[f32; 4]>>) {
}
}
pub fn realtimeudp(rx: Receiver<Vec<[f32; 4]>>) {
pub fn realtimeudp(rx: Receiver<Vec<[f32; 4]>>, addr: String) {
let socket = UdpSocket::bind("0.0.0.0:0").unwrap();
loop {
let leds = rx.recv().unwrap();
@ -41,6 +42,18 @@ pub fn realtimeudp(rx: Receiver<Vec<[f32; 4]>>) {
packet.push((led[1]*255.0) as u8);
packet.push((led[2]*255.0) as u8);
}
let _ = socket.send_to(&packet, SocketAddr::from(([204, 2, 68, 140 ], 21324))).unwrap();
match socket.send_to(&packet, &addr) {
Ok(_) => (),
Err(err) => {
println!("Error while sending trying to send data: {}", err);
std::process::exit(1);
},
};
}
}
#[derive(clap::ValueEnum, Clone, Debug)]
pub enum Output {
piston,
realtimeudp,
}

View file

@ -1,3 +1,5 @@
use clap::error::{ContextKind, ContextValue, ErrorKind};
pub fn compare(a: f64, b: f64) -> f64 {
if a > b {
b
@ -16,4 +18,11 @@ pub fn offset(n: i16, max: i16, offset: i16) -> i16 {
pub fn scaleu8tof32(old_value: u8) -> f32 { // Convert a u8 between 0 and 255 to a f32 between 0.0 and 1.0 for piston colors
(((old_value as f32 - 0.0) * (0.0 - 1.0)) / (0.0 - 255.0)) + 0.0
}
pub fn err_missing_args(args: Vec<String>) {
let mut err = clap::Error::new(ErrorKind::MissingRequiredArgument);
err.insert(ContextKind::InvalidArg, ContextValue::Strings(args));
let _ = err.print();
std::process::exit(1);
}