etwin_cli 0.12.5

Command Line Interface for Eternaltwin
Documentation
use clap::Parser;
use dialoguer::{theme::ColorfulTheme, Input, Password, Select};
use etwin_core::clock::SystemClock;
use etwin_core::dinorpg::{DinorpgClient, DinorpgServer, DinorpgSession};
use etwin_core::email::EmailAddress;
use etwin_core::twinoid::{TwinoidClient, TwinoidCredentials, TwinoidPassword, TwinoidSessionKey};
use etwin_core::types::AnyError;
use etwin_dinorpg_client::http::HttpDinorpgClient;
use etwin_mt_dns::MtDnsResolver;
use etwin_twinoid_client::http::HttpTwinoidClient;
use std::str::FromStr;

/// Arguments to the `dinorpg` task.
#[derive(Debug, Parser)]
pub struct Args {}

pub async fn run(_args: &Args) -> Result<(), AnyError> {
  let clock = SystemClock;
  let twinoid_client = HttpTwinoidClient::new(clock).unwrap();
  let dinorpg_client = HttpDinorpgClient::new(clock).unwrap();

  let servers = vec!["www.dinorpg.com", "en.dinorpg.com", "es.dinorpg.com"];
  let server = Select::with_theme(&ColorfulTheme::default())
    .with_prompt("DinoRPG server?")
    .items(&servers)
    .default(0)
    .interact_opt()?;

  let server = match server {
    Some(0) => DinorpgServer::DinorpgCom,
    Some(1) => DinorpgServer::EnDinorpgCom,
    Some(2) => DinorpgServer::EsDinorpgCom,
    _ => panic!("Failed to select server"),
  };

  let auth_method = vec!["Twinoid credentials", "Twinoid session"];
  let auth_method = Select::with_theme(&ColorfulTheme::default())
    .with_prompt("Authentication method?")
    .items(&auth_method)
    .default(0)
    .interact_opt()?;

  let session = match auth_method {
    Some(0) => auth_tid_creds(&twinoid_client, &dinorpg_client, server).await.unwrap(),
    Some(1) => auth_tid_key(&dinorpg_client, server).await.unwrap(),
    _ => panic!("Failed to select authentication method"),
  };

  eprintln!("Acquired DinoRPG session:");
  eprintln!("{:#?}", session);

  eprintln!("Fetching ingredients");
  let ingredients = dinorpg_client.get_own_ingredients(&session).await;
  eprintln!("{:#?}", ingredients);

  eprintln!("Fetching missions");
  let missions = dinorpg_client.get_own_missions(&session).await;
  eprintln!("{:#?}", missions);

  eprintln!("Fetching demon shop");
  let demon_shop = dinorpg_client.get_own_demon_shop(&session).await;
  eprintln!("{:#?}", demon_shop);

  Ok(())
}

pub async fn auth_tid_creds(
  tid_client: &HttpTwinoidClient<SystemClock>,
  drpg_client: &HttpDinorpgClient<SystemClock, MtDnsResolver>,
  server: DinorpgServer,
) -> Result<DinorpgSession, AnyError> {
  let email: String = Input::with_theme(&ColorfulTheme::default())
    .with_prompt("Email?")
    .interact_text()
    .unwrap();

  let email = EmailAddress::from_str(email.as_str())?;

  let password: String = Password::with_theme(&ColorfulTheme::default())
    .with_prompt("Password?")
    .interact()?;

  let password = TwinoidPassword::new(password.to_string());

  let credentials = TwinoidCredentials { email, password };

  eprintln!("Starting authentication");
  let tid_session = tid_client.create_session(&credentials).await?;
  eprintln!("Acquired Twinoid session key: {}", &tid_session.key);
  let drpg_session = drpg_client.create_session(server, &tid_session.key).await?;
  Ok(drpg_session)
}

pub async fn auth_tid_key(
  drpg_client: &HttpDinorpgClient<SystemClock, MtDnsResolver>,
  server: DinorpgServer,
) -> Result<DinorpgSession, AnyError> {
  let key: String = Input::with_theme(&ColorfulTheme::default())
    .with_prompt("Twinoid session key?")
    .interact_text()?;

  let key = TwinoidSessionKey::from_str(key.as_str())?;

  eprintln!("Starting authentication");
  let drpg_session = drpg_client.create_session(server, &key).await?;
  Ok(drpg_session)
}