diff options
author | metamuffin <metamuffin@disroot.org> | 2025-01-08 13:32:01 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-01-08 13:32:01 +0100 |
commit | ac5020c972739d418eabbc2809ccb162890934dc (patch) | |
tree | bcd7155ee69a3d39254dbac1f3a3544dfc915782 /client/src | |
parent | b2145131ccde0a33b9840ac04c8b7d79e733ae12 (diff) | |
download | twclient-ac5020c972739d418eabbc2809ccb162890934dc.tar twclient-ac5020c972739d418eabbc2809ccb162890934dc.tar.bz2 twclient-ac5020c972739d418eabbc2809ccb162890934dc.tar.zst |
a
Diffstat (limited to 'client/src')
-rw-r--r-- | client/src/client.rs | 128 | ||||
-rw-r--r-- | client/src/main.rs | 21 | ||||
-rw-r--r-- | client/src/window.rs | 39 |
3 files changed, 186 insertions, 2 deletions
diff --git a/client/src/client.rs b/client/src/client.rs new file mode 100644 index 0000000..0db4389 --- /dev/null +++ b/client/src/client.rs @@ -0,0 +1,128 @@ +use anyhow::Result; +use arrayvec::ArrayVec; +use libtw2_event_loop::{ + Addr, Application, Chunk, ConnlessChunk, Loop, PeerId, SocketLoop, Timeout, +}; +use libtw2_gamenet_ddnet::{ + enums::{Team, VERSION}, + msg::{ + self, Game, System, SystemOrGame, + game::{ClSetTeam, ClStartInfo}, + system::{EnterGame, Info, Ready}, + }, +}; +use libtw2_packer::{Unpacker, with_packer}; +use log::warn; +use std::{ + fmt::{self, Debug}, + net::{IpAddr, Ipv4Addr}, +}; + +pub struct Client {} +impl Client { + pub fn new() -> Result<Self> { + let mut sloop = SocketLoop::client(); + sloop.connect(Addr { + ip: IpAddr::V4(Ipv4Addr::LOCALHOST), + port: 8303, + }); + sloop.run(ClientNetwork {}); + Ok(Self {}) + } +} + +pub struct ClientNetwork {} +impl<L: Loop> Application<L> for ClientNetwork { + fn needs_tick(&mut self) -> Timeout { + Timeout::inactive() + } + + fn on_tick(&mut self, loop_: &mut L) {} + + fn on_packet(&mut self, loop_: &mut L, chunk: Chunk) { + let pid = chunk.pid; + let msg; + match msg::decode(&mut Warn(chunk.data), &mut Unpacker::new(chunk.data)) { + Ok(m) => msg = m, + Err(err) => { + warn!("decode error {:?}:", err); + return; + } + } + eprintln!("{msg:?}"); + match msg { + SystemOrGame::System(System::MapChange(map)) => { + loop_.sends(pid, Ready); + } + SystemOrGame::System(System::ConReady(..)) => { + loop_.sendg(pid, ClStartInfo { + name: b"testclient", + clan: b"metamuffin", + country: -1, + skin: b"limekittygirl", + use_custom_color: true, + color_body: 0xFF00FF, + color_feet: 0x550055, + }); + } + SystemOrGame::Game(Game::SvReadyToEnter(..)) => { + loop_.sends(pid, EnterGame); + loop_.sendg(pid, ClSetTeam { team: Team::Red }); + } + _ => {} + } + } + + fn on_connless_packet(&mut self, loop_: &mut L, chunk: ConnlessChunk) {} + + fn on_connect(&mut self, loop_: &mut L, pid: PeerId) { + todo!() + } + + fn on_ready(&mut self, loop_: &mut L, pid: PeerId) { + loop_.sends(pid, Info { + version: VERSION.as_bytes(), + password: Some(b""), + }); + loop_.flush(pid); + } + + fn on_disconnect(&mut self, loop_: &mut L, pid: PeerId, remote: bool, reason: &[u8]) {} +} + +// Copied straight from libtw2/downloader/src/main.rs by heinrich5991, MIT-or-Apache-2.0 +trait LoopExt: Loop { + fn sends<'a, S: Into<System<'a>>>(&mut self, pid: PeerId, msg: S) { + fn inner<L: Loop + ?Sized>(msg: System, pid: PeerId, loop_: &mut L) { + let mut buf: ArrayVec<[u8; 2048]> = ArrayVec::new(); + with_packer(&mut buf, |p| msg.encode(p).unwrap()); + loop_.send(Chunk { + pid, + vital: true, + data: &buf, + }) + } + inner(msg.into(), pid, self) + } + fn sendg<'a, G: Into<Game<'a>>>(&mut self, pid: PeerId, msg: G) { + fn inner<L: Loop + ?Sized>(msg: Game, pid: PeerId, loop_: &mut L) { + let mut buf: ArrayVec<[u8; 2048]> = ArrayVec::new(); + with_packer(&mut buf, |p| msg.encode(p).unwrap()); + loop_.send(Chunk { + pid, + vital: true, + data: &buf, + }) + } + inner(msg.into(), pid, self) + } +} +impl<L: Loop> LoopExt for L {} + +struct Warn<'a>(&'a [u8]); + +impl<'a, W: Debug> warn::Warn<W> for Warn<'a> { + fn warn(&mut self, w: W) { + warn!("{:?}", w); + } +} diff --git a/client/src/main.rs b/client/src/main.rs index e7a11a9..02b9055 100644 --- a/client/src/main.rs +++ b/client/src/main.rs @@ -1,3 +1,20 @@ -fn main() { - println!("Hello, world!"); +use anyhow::Result; +use client::Client; +use window::WindowState; +use winit::event_loop::EventLoop; + +pub mod window; +pub mod client; + +fn main() -> Result<()> { + env_logger::init_from_env("LOG"); + + Client::new()?; + + + // let evloop = EventLoop::new()?; + // evloop.run_app(&mut WindowState::new())?; + + + Ok(()) } diff --git a/client/src/window.rs b/client/src/window.rs new file mode 100644 index 0000000..f003574 --- /dev/null +++ b/client/src/window.rs @@ -0,0 +1,39 @@ +use winit::{ + application::ApplicationHandler, + event::WindowEvent, + event_loop::ActiveEventLoop, + window::{Window, WindowAttributes, WindowId}, +}; + +pub struct WindowState { + window: Option<Window>, +} + +impl WindowState { + pub fn new() -> Self { + Self { window: None } + } +} +impl ApplicationHandler for WindowState { + fn resumed(&mut self, event_loop: &ActiveEventLoop) { + self.window = Some( + event_loop + .create_window(WindowAttributes::default().with_maximized(true)) + .unwrap(), + ) + } + + fn window_event( + &mut self, + event_loop: &ActiveEventLoop, + window_id: WindowId, + event: WindowEvent, + ) { + if let Some(win) = &self.window { + match event { + WindowEvent::RedrawRequested => {} + _ => (), + } + } + } +} |