at main 2.4 kB view raw
1#![windows_subsystem = "windows"] 2 3use std::{ 4 collections::HashMap, 5 io::{BufRead, BufReader, Write}, 6 net::{TcpListener, TcpStream}, 7}; 8 9use quad_snd::*; 10 11fn main() { 12 let ctx = AudioContext::new(); 13 let sounds = std::fs::read_dir("sounds") 14 .expect("cant read sounds") 15 .flat_map(|f| { 16 let p = f.ok()?.path(); 17 let n = p.file_stem()?.to_string_lossy().into_owned(); 18 Some(( 19 n, 20 Sound::load(&ctx, &std::fs::read(p).expect("can't load sound")), 21 )) 22 }) 23 .collect::<HashMap<String, Sound>>(); 24 25 let handle_request = |mut stream: TcpStream| { 26 let mut lines = BufReader::new(&stream) 27 .lines() 28 .flatten() 29 .take_while(|line| !line.is_empty()); 30 31 let request_line = lines.next()?; 32 let query = parse_query_from_request(request_line.as_str()); 33 let kind = query.get("kind").cloned().unwrap_or("sound"); 34 35 if let Some(sound) = sounds.get(kind) { 36 sound.play(&ctx, PlaySoundParams::default()); 37 } 38 39 // exhaust connection to not get "connection reset by peer" 40 lines.for_each(drop); 41 // this never "fails" 42 let response = "HTTP/1.1 200 OK\r\n\r\n"; 43 let _ = stream.write_all(response.as_bytes()); 44 45 Some(()) 46 }; 47 48 let port = std::env::var("PORT") 49 .ok() 50 .and_then(|p| p.parse::<u16>().ok()) 51 .unwrap_or(8668); 52 let listener = TcpListener::bind(("0.0.0.0", port)).expect("cant bind"); 53 54 for stream in listener.incoming() { 55 let Ok(stream) = stream else { 56 continue; 57 }; 58 handle_request(stream); 59 } 60} 61 62fn parse_query_from_request(request_line: &str) -> HashMap<&str, &str> { 63 request_line 64 .split_whitespace() 65 .nth(1) 66 .and_then(|path| path.split_once('?')) 67 .map(|(_, query)| { 68 query 69 .split('&') 70 .filter_map(|param| { 71 if let Some((key, value)) = param.split_once('=') { 72 Some((key, value)) 73 } else if !param.is_empty() { 74 Some((param, "")) 75 } else { 76 None 77 } 78 }) 79 .collect() 80 }) 81 .unwrap_or_default() 82}