use std::{env, io}; use std::collections::HashSet; use once_cell::sync::Lazy; use rocket::fs::NamedFile; use rocket::{get, Request}; use rocket::http::Status; use rocket::request::{FromRequest, Outcome}; use rocket::response::content::RawXml; use tokio::fs::try_exists; use tokio::sync::RwLock; use tonic::async_trait; use crate::dsresponse::Ds; pub static EVIL_AGREEMENT_THING: Lazy>> = Lazy::new(|| Default::default()); pub struct CFIP(pub String); #[async_trait] impl<'r> FromRequest<'r> for CFIP{ type Error = (); async fn from_request(request: &'r Request<'_>) -> Outcome { match request.headers().get("CF-Connecting-IP").next(){ Some(v) => Outcome::Success(Self(v.to_owned())), None => Outcome::Error((Status::ImATeapot, ())) } } } #[get("/v1/api/content/agreements/Nintendo-Network-EULA//@latest")] pub async fn get_agreement(lang: &str, ip: CFIP) -> io::Result>>{ let base_path = { // if this crashes then something is wrong with the server setup so crashing here is fine imo let mut path = env::current_dir().unwrap(); path.push("res"); path.push("agreement"); path }; if EVIL_AGREEMENT_THING.read().await.contains(&ip.0) { let path = { let mut path = base_path; path.push("EVIL.xml"); path }; Ok(Ds(RawXml(NamedFile::open(&path).await?))) } else { let requested_file_path = { let mut path = base_path.clone(); path.push(format!("{}.xml", lang)); path }; if try_exists(&requested_file_path).await.is_ok_and(|v| v == true) { Ok(Ds(RawXml(NamedFile::open(&requested_file_path).await?))) } else { let fallback_path = { let mut path = base_path; path.push("DEFAULT.xml"); path }; Ok(Ds(RawXml(NamedFile::open(&fallback_path).await?))) } } }