From 2e00389033e9837177bce887186df5d98609c80e Mon Sep 17 00:00:00 2001 From: Shadow Cat Date: Sat, 15 Nov 2025 02:10:30 -0500 Subject: [PATCH] OPENWORM GAMAING (can send messages to server) --- :w | 75 +++++++++++++++++++++++++++++++++++++++++++++++ src/client/mod.rs | 15 +++++----- src/client/ui.rs | 23 +++++++-------- src/net/client.rs | 33 +++++++++++++++------ src/server/mod.rs | 6 ++-- 5 files changed, 120 insertions(+), 32 deletions(-) create mode 100644 :w diff --git a/:w b/:w new file mode 100644 index 0000000..b0ba85d --- /dev/null +++ b/:w @@ -0,0 +1,75 @@ +use crate::client::{AppHandle, ClientEvent}; +use quinn::{crypto::rustls::QuicClientConfig, rustls::pki_types::CertificateDer}; +use std::{ + fs, + io::ErrorKind, + net::{IpAddr, Ipv6Addr, SocketAddr}, + str::FromStr, + sync::Arc, +}; +use tokio::sync::mpsc::UnboundedSender; + +pub fn connect(handle: AppHandle) { + std::thread::spawn(|| { + connect_the(handle).unwrap(); + }); +} + +pub enum NetCmd { + SendMsg(String), +} + +pub type NetSender = UnboundedSender; + +#[tokio::main] +async fn connect_the(handle: AppHandle) -> anyhow::Result<()> { + let dirs = directories_next::ProjectDirs::from("", "", "openworm").unwrap(); + let mut roots = quinn::rustls::RootCertStore::empty(); + match fs::read(dirs.data_local_dir().join("cert.der")) { + Ok(cert) => { + roots.add(CertificateDer::from(cert))?; + } + Err(ref e) if e.kind() == ErrorKind::NotFound => { + eprintln!("local server certificate not found"); + } + Err(e) => { + eprintln!("failed to open local server certificate: {}", e); + } + } + let client_crypto = quinn::rustls::ClientConfig::builder() + .with_root_certificates(roots) + .with_no_client_auth(); + let client_config = + quinn::ClientConfig::new(Arc::new(QuicClientConfig::try_from(client_crypto)?)); + let mut endpoint = quinn::Endpoint::client(SocketAddr::from_str("[::]:0").unwrap())?; + endpoint.set_default_client_config(client_config); + let remote = SocketAddr::new(IpAddr::V6(Ipv6Addr::LOCALHOST), 4433); + let host = "localhost"; + let conn = endpoint + .connect(remote, host)? + .await + .map_err(|e| anyhow::anyhow!("failed to connect: {}", e))?; + + let (client_send, mut client_recv) = tokio::sync::mpsc::unbounded_channel::(); + + handle.send(ClientEvent::Connect(client_send)); + + while let Some(msg) = client_recv.recv().await { + match msg { + NetCmd::SendMsg(content) => { + let (mut send, recv) = conn + .open_bi() + .await + .map_err(|e| anyhow::anyhow!("failed to open stream: {}", e))?; + + drop(recv); + + send.write_all(content.as_bytes()).await.expect("failed to send"); + send.finish().unwrap(); + send.stopped().await.unwrap(); + } + } + } + + Ok(()) +} diff --git a/src/client/mod.rs b/src/client/mod.rs index b52c2fd..79f2e1b 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -5,7 +5,10 @@ use iris::prelude::*; use render::Renderer; use winit::{event::WindowEvent, event_loop::ActiveEventLoop}; -use crate::client::ui::{Submit, UiData}; +use crate::{ + client::ui::{Submit, main_view}, + net::client::NetSender, +}; mod app; mod input; @@ -16,7 +19,7 @@ pub use app::AppHandle; #[derive(Debug)] pub enum ClientEvent { - Connect, + Connect(NetSender), } pub struct Client { @@ -24,7 +27,6 @@ pub struct Client { input: Input, ui: Ui, focus: Option>, - ui_data: UiData, clipboard: Clipboard, } @@ -32,13 +34,12 @@ impl Client { pub fn new(handle: AppHandle) -> Self { let renderer = Renderer::new(handle.window.clone()); - let (ui, ui_data) = ui::ui(handle); + let ui = ui::ui(handle); Self { renderer, input: Input::default(), ui, - ui_data, focus: None, clipboard: Clipboard::new().unwrap(), } @@ -46,8 +47,8 @@ impl Client { pub fn event(&mut self, event: ClientEvent, _: &ActiveEventLoop) { match event { - ClientEvent::Connect => { - self.ui.set_root(self.ui_data.main_view.clone()); + ClientEvent::Connect(send) => { + main_view(&mut self.ui, send).set_root(&mut self.ui); } } } diff --git a/src/client/ui.rs b/src/client/ui.rs index 4b83fd3..79bc378 100644 --- a/src/client/ui.rs +++ b/src/client/ui.rs @@ -3,7 +3,7 @@ use len_fns::*; use crate::{ client::{Client, app::AppHandle}, - net::client::connect, + net::client::{NetCmd, NetSender, connect}, }; #[derive(Eq, PartialEq, Hash, Clone)] @@ -13,21 +13,17 @@ impl DefaultEvent for Submit { type Data = (); } -pub struct UiData { - pub main_view: WidgetId, +pub fn ui(handle: AppHandle) -> Ui { + let mut ui = Ui::new(); + login_screen(&mut ui, handle).set_root(&mut ui); + ui } -pub fn ui(handle: AppHandle) -> (Ui, UiData) { - let mut ui = Ui::new(); - - let msg_panel = msg_panel(&mut ui); +pub fn main_view(ui: &mut Ui, network: NetSender) -> WidgetId { + let msg_panel = msg_panel(ui, network); let side_bar = rect(Color::BLACK.brighter(0.05)).width(80); - let main_view = (side_bar, msg_panel).span(Dir::RIGHT).add(&mut ui).any(); - login_screen(&mut ui, handle).set_root(&mut ui); - - let data = UiData { main_view }; - (ui, data) + (side_bar, msg_panel).span(Dir::RIGHT).add(ui).any() } fn login_screen(ui: &mut Ui, handle: AppHandle) -> WidgetId { @@ -100,7 +96,7 @@ pub fn focus(id: WidgetId) -> impl Fn(&mut Client, CursorData) { } } -pub fn msg_panel(ui: &mut Ui) -> impl WidgetFn + use<> { +pub fn msg_panel(ui: &mut Ui, network: NetSender) -> impl WidgetFn + use<> { let msg_area = Span::empty(Dir::DOWN).gap(15).add(ui); let send_text = text("some stuff idk") @@ -120,6 +116,7 @@ pub fn msg_panel(ui: &mut Ui) -> impl WidgetFn + use<> { .clone() .id_on(Submit, move |id, client: &mut Client, _| { let content = client.ui.text(id).take(); + network.send(NetCmd::SendMsg(content.clone())).unwrap(); let msg = msg_widget(content).add(&mut client.ui); client.ui[&msg_area].children.push(msg.any()); }) diff --git a/src/net/client.rs b/src/net/client.rs index 0101b84..b0ba85d 100644 --- a/src/net/client.rs +++ b/src/net/client.rs @@ -7,6 +7,7 @@ use std::{ str::FromStr, sync::Arc, }; +use tokio::sync::mpsc::UnboundedSender; pub fn connect(handle: AppHandle) { std::thread::spawn(|| { @@ -14,6 +15,12 @@ pub fn connect(handle: AppHandle) { }); } +pub enum NetCmd { + SendMsg(String), +} + +pub type NetSender = UnboundedSender; + #[tokio::main] async fn connect_the(handle: AppHandle) -> anyhow::Result<()> { let dirs = directories_next::ProjectDirs::from("", "", "openworm").unwrap(); @@ -43,18 +50,26 @@ async fn connect_the(handle: AppHandle) -> anyhow::Result<()> { .await .map_err(|e| anyhow::anyhow!("failed to connect: {}", e))?; - let (mut send, recv) = conn - .open_bi() - .await - .map_err(|e| anyhow::anyhow!("failed to open stream: {}", e))?; + let (client_send, mut client_recv) = tokio::sync::mpsc::unbounded_channel::(); - drop(recv); + handle.send(ClientEvent::Connect(client_send)); - handle.send(ClientEvent::Connect); + while let Some(msg) = client_recv.recv().await { + match msg { + NetCmd::SendMsg(content) => { + let (mut send, recv) = conn + .open_bi() + .await + .map_err(|e| anyhow::anyhow!("failed to open stream: {}", e))?; - send.write_all(&[39]).await.expect("failed to send"); - send.finish().unwrap(); - send.stopped().await.unwrap(); + drop(recv); + + send.write_all(content.as_bytes()).await.expect("failed to send"); + send.finish().unwrap(); + send.stopped().await.unwrap(); + } + } + } Ok(()) } diff --git a/src/server/mod.rs b/src/server/mod.rs index 2b4e72c..4342c95 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -112,11 +112,11 @@ async fn handle_stream( (send, mut recv): (quinn::SendStream, quinn::RecvStream), ) -> Result<(), String> { drop(send); - let msg = recv + let bytes = recv .read_to_end(std::mem::size_of::()) .await .map_err(|e| format!("failed reading request: {}", e))?; - println!("received message"); - println!("{:?}", msg); + let msg = String::from_utf8(bytes).unwrap(); + println!("received message: {:?}", msg); Ok(()) }