use anyhow::{Context, Result}; use byteorder::WriteBytesExt; use std::{ io::{BufReader, BufWriter, Write}, net::{TcpStream, ToSocketAddrs}, }; use xbf_rs::{XbfMetadata, XbfPrimitive, XbfStruct, XbfType}; fn find_galbatorix(value: &XbfType) -> Option<&XbfStruct> { if let XbfType::Vec(v) = value { for value in v { if let XbfType::Struct(s) = value { if let Some(XbfType::Primitive(XbfPrimitive::String(name))) = s.get("name") { if name == "Galbatorix" { return Some(s); } } } } } None } fn get_connection( addr: impl ToSocketAddrs, ) -> Result<(BufWriter, BufReader)> { let stream = TcpStream::connect(addr).context("Unable to connect to server")?; let writer = BufWriter::new(stream.try_clone().context("Unable to clone stream")?); let reader = BufReader::new(stream); Ok((writer, reader)) } fn get_data_and_metadata(addr: impl ToSocketAddrs) -> Result<(XbfMetadata, XbfType)> { let (mut writer, mut reader) = get_connection(addr)?; writer.write_u8(0)?; writer.flush()?; let metadata = XbfMetadata::deserialize_base_metadata(&mut reader)?; let value = XbfType::deserialize_base_type(&metadata, &mut reader)?; Ok((metadata, value)) } fn get_data(addr: impl ToSocketAddrs, known_metadata: &XbfMetadata) -> Result { let (mut writer, mut reader) = get_connection(addr)?; writer.write_u8(1)?; writer.flush()?; let value = XbfType::deserialize_base_type(known_metadata, &mut reader)?; Ok(value) } fn unknown_request(addr: impl ToSocketAddrs) -> Result<(XbfMetadata, XbfType)> { let (mut writer, mut reader) = get_connection(addr)?; writer.write_u8(2)?; writer.flush()?; let metadata = XbfMetadata::deserialize_base_metadata(&mut reader)?; let value = XbfType::deserialize_base_type(&metadata, &mut reader)?; Ok((metadata, value)) } fn main() -> Result<()> { let (metadata, value) = get_data_and_metadata("127.0.0.1:6969")?; println!("{:?}", find_galbatorix(&value)); let value = get_data("127.0.0.1:6969", &metadata)?; println!("{:?}", find_galbatorix(&value)); let unnown_request = unknown_request("127.0.0.1:6969")?; println!("{:?}", unnown_request); Ok(()) }