#![feature(random)] use std::{ fs::File, io::Write, net::{SocketAddr, TcpStream}, path::PathBuf, random::random, }; use anyhow::Result; use clap::{Parser, Subcommand}; use log::info; use weareshared::{ helper::ReadWrite, packets::{Data, Object, Packet}, respack::RespackReader, store::ResourceStore, }; #[derive(Parser)] struct Args { #[clap(subcommand)] action: Action, } #[derive(Subcommand)] enum Action { Add(Add), } #[derive(Parser)] struct Add { address: SocketAddr, pack: PathBuf, #[arg(short = 'A', long)] announce: bool, #[arg(short, long)] add: bool, #[arg(short, long)] disown: bool, } fn main() -> Result<()> { env_logger::init_from_env("LOG"); let args = Args::parse(); match args.action { Action::Add(a) => action_add(a), } } fn action_add(args: Add) -> Result<()> { info!("loading pack"); let pack = RespackReader::open(File::open(&args.pack)?)?; let entry = pack.entry().unwrap(); let store = ResourceStore::new_respack(pack)?; let entry = store.get(entry)?.unwrap(); info!("connecting"); let mut sock = TcpStream::connect(args.address)?; Packet::Connect(random()).write(&mut sock)?; for p in entry.c_prefab { info!("adding {p}"); if args.announce { Packet::AnnouncePrefab(p.clone()).write(&mut sock)?; } if args.add { let ob = Object::new(); Packet::Add(ob, p.clone()).write(&mut sock)?; if args.disown { // TODO disown packet once it exists } } } sock.flush()?; info!("idling for resource requests"); loop { let packet = Packet::read(&mut sock)?; match packet { Packet::RequestResource(hash) => { if let Some(d) = store.get_raw(hash)? { Packet::RespondResource(hash, Data(d)).write(&mut sock)?; sock.flush()?; } } _ => (), } } }