use crate::server::Server; use anyhow::{bail, Result}; use hurrycurry_protocol::{registry::Submission, VERSION}; use log::{info, warn}; use rand::random; use reqwest::{header::USER_AGENT, Client, Url}; use std::{str::FromStr, sync::Arc, time::Duration}; use tokio::{sync::RwLock, time::interval}; const REGISTRY_URI: &'static str = "https://hurrycurry-registry.metamuffin.org"; pub struct Register { name: String, port: u16, register_uri: Option, state: Arc>, client: Client, secret: u128, players: usize, } impl Register { pub fn new( name: String, port: u16, register_uri: Option, state: Arc>, ) -> Self { Self { name, register_uri, players: 0, port, secret: random(), state, client: Client::new(), } } pub async fn register_loop(mut self) { let mut interval = interval(Duration::from_secs(60)); loop { interval.tick().await; self.players = self.state.read().await.count_chefs(); if let Err(e) = self.register().await { warn!("register error: {e}") } } } // TODO ip v6 pub async fn register(&mut self) -> Result<()> { let res = self .client .post(Url::from_str(&format!("{REGISTRY_URI}/v1/register")).unwrap()) .header( USER_AGENT, format!("hurrycurry-server {}", env!("CARGO_PKG_VERSION")), ) .json(&Submission { last_game: 0, name: self.name.clone(), uri: self .register_uri .clone() .unwrap_or_else(|| format!("ws://0.0.0.0:{}", self.port)), players: self.players, secret: self.secret, version: VERSION, }) .send() .await?; let r = res.text().await?; if r == "ok" { info!("register ok"); Ok(()) } else { bail!("{r}"); } } }