use crate::{handle_error, Error, ErrorResponse, Result, Tarkov, PROD_ENDPOINT};
use crate::bad_json::deserialize_integer_to_string;
use crate::inventory::Item;
use crate::ragfair::Offer;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Deserialize)]
struct ProfileResponse {
#[serde(flatten)]
error: ErrorResponse,
data: Option<Vec<Profile>>,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct Profile {
#[serde(rename = "_id")]
pub id: String,
#[serde(rename = "aid")]
pub aid: u64,
#[serde(rename = "savage")]
pub savage: Option<String>,
pub info: Info,
pub customization: Customization,
pub health: Health,
pub inventory: Inventory,
pub skills: Skills,
pub stats: Stats,
pub encyclopedia: HashMap<String, bool>,
pub condition_counters: ConditionCounters,
pub backend_counters: HashMap<String, BackendCounter>,
pub insured_items: Vec<InsuredItem>,
pub hideout: serde_json::Value,
pub notes: serde_json::Value,
pub bonuses: Vec<Bonus>,
pub quests: Vec<Quest>,
#[serde(rename = "RagfairInfo")]
pub ragfair: Ragfair,
pub trader_standings: serde_json::Value,
#[serde(rename = "WishList")]
pub wishlist: Vec<String>,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct Info {
pub nickname: String,
pub lower_nickname: String,
pub side: Side,
pub voice: String,
pub level: u64,
pub experience: u64,
pub registration_date: u64,
pub game_version: String,
pub account_type: u64,
#[serde(deserialize_with = "deserialize_integer_to_string")]
pub member_category: String,
#[serde(rename = "lockedMoveCommands")]
pub locked_move_commands: bool,
pub savage_lock_time: u64,
pub last_time_played_as_savage: u64,
pub settings: Settings,
pub need_wipe: bool,
pub global_wipe: bool,
pub nickname_change_date: u64,
pub bans: serde_json::Value,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
pub enum Side {
Bear,
Usec,
Savage,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct Settings {
pub role: Option<String>,
pub bot_difficulty: Option<String>,
pub experience: Option<i64>,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct Customization {
pub head: String,
pub body: String,
pub feet: String,
pub hands: String,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct Health {
pub hydration: HealthLevel,
pub energy: HealthLevel,
pub body_parts: BodyParts,
pub update_time: u64,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct HealthLevel {
pub current: f64,
pub maximum: f64,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct BodyParts {
pub head: Head,
pub chest: Chest,
pub stomach: Stomach,
pub left_arm: LeftArm,
pub right_arm: RightArm,
pub left_leg: LeftLeg,
pub right_leg: RightLeg,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct Head {
pub health: HealthLevel,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct Chest {
pub health: HealthLevel,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct Stomach {
pub health: HealthLevel,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct LeftArm {
pub health: HealthLevel,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct RightArm {
pub health: HealthLevel,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct LeftLeg {
pub health: HealthLevel,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct RightLeg {
pub health: HealthLevel,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Inventory {
pub items: Vec<Item>,
pub equipment: String,
pub stash: Option<String>,
pub quest_raid_items: String,
pub quest_stash_items: String,
pub fast_panel: serde_json::Value,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct Skills {
pub common: Vec<CommonSkill>,
pub mastering: Vec<MasteringSkill>,
pub points: f64,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct CommonSkill {
pub id: String,
pub progress: f64,
pub points_earned_during_session: Option<f64>,
pub last_access: i64,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct MasteringSkill {
pub id: String,
pub progress: u64,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct Stats {
pub session_counters: SessionCounters,
pub overall_counters: OverallCounters,
pub session_experience_mult: f64,
pub experience_bonus_mult: f64,
pub total_session_experience: u64,
pub last_session_date: u64,
pub aggressor: Option<Aggressor>,
pub total_in_game_time: u64,
pub survivor_class: String,
pub dropped_items: serde_json::Value,
pub found_in_raid_items: serde_json::Value,
pub victims: Vec<Victim>,
pub carried_quest_items: serde_json::Value,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct SessionCounters {
pub items: Vec<SessionItem>,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct OverallCounters {
pub items: Vec<SessionItem>,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct SessionItem {
pub key: Vec<String>,
pub value: u64,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct Aggressor {
pub name: String,
pub side: Side,
pub body_part: String,
pub head_segment: Option<String>,
pub weapon_name: String,
pub category: String,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct Victim {
pub name: String,
pub side: Side,
pub time: String,
pub level: u64,
pub body_part: String,
pub weapon: String,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct ConditionCounters {
pub counters: Vec<ConditionCounter>,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct ConditionCounter {
pub id: String,
pub value: u64,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct BackendCounter {
pub id: String,
pub qid: String,
pub value: u64,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct InsuredItem {
#[serde(rename = "tid")]
id: String,
item_id: String,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Bonus {
#[serde(rename = "type")]
pub bonus_type: String,
pub template_id: Option<String>,
pub value: Option<i64>,
pub passive: Option<bool>,
pub visible: Option<bool>,
pub production: Option<bool>,
pub filter: Option<Vec<String>>,
pub id: Option<String>,
pub icon: Option<String>,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Quest {
#[serde(rename = "qid")]
pub id: String,
pub start_time: u64,
pub status: u64,
pub status_timers: HashMap<String, u64>,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Ragfair {
pub rating: f64,
pub is_rating_growing: bool,
pub offers: Vec<Offer>,
}
#[derive(Debug, err_derive::Error)]
pub enum ProfileError {
#[error(display = "invalid user id selected")]
InvalidUserID,
#[error(display = "select profile failed")]
SelectProfileFail,
}
#[derive(Debug, Serialize)]
struct SelectRequest<'a> {
uid: &'a str,
}
#[derive(Debug, Deserialize)]
struct SelectResponse {
#[serde(flatten)]
error: ErrorResponse,
data: Option<ProfileSelected>,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "camelCase")]
struct ProfileSelected {
pub status: String,
pub notifier: Notifier,
pub notifier_server: String,
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
pub struct Notifier {
pub server: String,
pub channel_id: String,
pub url: String,
}
impl Tarkov {
pub async fn get_profiles(&self) -> Result<Vec<Profile>> {
let url = format!("{}/client/game/profile/list", PROD_ENDPOINT);
let res: ProfileResponse = self.post_json(&url, &{}).await?;
handle_error(res.error, res.data)
}
pub async fn select_profile(&self, user_id: &str) -> Result<()> {
if user_id.is_empty() {
return Err(Error::InvalidParameters);
}
let url = format!("{}/client/game/profile/select", PROD_ENDPOINT);
let res: SelectResponse = self
.post_json(&url, &SelectRequest { uid: user_id })
.await?;
let res = handle_error(res.error, res.data)?;
if res.status != "ok" {
return Err(ProfileError::SelectProfileFail)?;
}
Ok(())
}
}