Skip to content

Commit

Permalink
0.9.0 - Additional Provider
Browse files Browse the repository at this point in the history
  • Loading branch information
ShayBox committed Oct 18, 2024
1 parent 214afcc commit 416243d
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 70 deletions.
78 changes: 39 additions & 39 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "vrc-log"
version = "0.8.2"
version = "0.9.0"
authors = ["Shayne Hartford <[email protected]>"]
edition = "2021"
description = "VRChat Local Cache Avatar ID Logger"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Place the file in the VRChat directory or `PATH` and set your launch options
`vrc-log(.exe) %command%`

### Supported Avatar Database Providers
<!-- - [AVTRDB] - [Discord](https://discord.gg/ZxB6w2hGfU) / [Web](https://avtrdb.com) / [VRCX](https://api.avtrdb.com/v1/avatar/search/vrcx) -->
- [AVTRDB] - [Discord](https://discord.gg/ZxB6w2hGfU) / [Web](https://avtrdb.com) / [VRCX](https://api.avtrdb.com/v1/avatar/search/vrcx)
- [DOUGHNUT] - [Discord](https://discord.gg/tjfXPzzaxu) / [Web](https://avtr1.nekosunevr.co.uk/search.php) / [VRCX](https://avtr1.nekosunevr.co.uk/vrcx_search.php)
- [NEKO] - [Discord](https://discord.gg/tjfXPzzaxu) / [Web](https://avtr.nekosunevr.co.uk/search.php) / [VRCX](https://avtr.nekosunevr.co.uk/vrcx_search.php)
- [VRCDB] - [Discord](https://discord.gg/q427ecnUvj) / [Web](https://vrcdb.com) / [World](https://vrchat.com/home/world/wrld_1146f625-5d42-40f5-bfe7-06a7664e2796) / [VRCX](vrcx.vrcdb.com/avatars/Avatar/VRCX)
Expand Down
33 changes: 21 additions & 12 deletions src/provider/avtrdb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@ use std::{time::Duration, vec};

use anyhow::{bail, Result};
use reqwest::{blocking::Client, StatusCode, Url};

use serde::{Deserialize, Serialize};
use crate::{
provider::{Provider, Type},
USER_AGENT,
};

const BASE_URL: &str = "https://api.avtrdb.com/v1/";

pub struct AvtrDB {
client: Client,
attribution: Option<String>,
base_url: Url,
}

const AVTRDB_URL: &str = "https://api.avtrdb.com/v1/";

impl AvtrDB {
#[must_use]
pub fn new(attribution: Option<String>, base_url: Url) -> Self {
Expand All @@ -34,30 +34,31 @@ impl Default for AvtrDB {
let attribution = std::env::var("AVTRDB_ATTRIBUTION")
.ok()
.or_else(crate::discord::get_user_id);

Self {
attribution,
base_url: Url::parse(BASE_URL).expect("Failed to parse BASE_URL"),
client: Client::builder()
.timeout(Duration::from_secs(10))
.user_agent(USER_AGENT)
.build()
.unwrap(),
attribution,
base_url: Url::parse(AVTRDB_URL).unwrap(),
}
}
}

#[derive(Debug, serde::Serialize)]
#[derive(Debug, Serialize)]
struct AvtrDBRequest {
avatar_ids: Vec<String>,
attribution: Option<String>,
}

#[derive(Debug, serde::Deserialize)]
#[derive(Debug, Deserialize)]
struct AvtrDBResponse {
valid_avatar_ids: u64,
}

#[derive(Debug, serde::Deserialize)]
#[derive(Debug, Deserialize)]
struct AvtrDBSearchResponse {
avatars: Vec<serde_json::Value>,
}
Expand All @@ -66,16 +67,19 @@ impl Provider for AvtrDB {
fn check_avatar_id(&self, avatar_id: &str) -> Result<bool> {
let mut url = self.base_url.join("avatar/search")?;
url.set_query(Some(format!("query={avatar_id}").as_str()));

let response = self.client.get(url).send()?;
let status = response.status();
let text = response.text()?;
debug!("[{}] {status} | {text}", Type::AVTRDB);

if status != StatusCode::OK {
bail!(
"[{}] Failed to check avatar: {status} | {text}",
Type::AVTRDB
);
}

let data = serde_json::from_str::<AvtrDBSearchResponse>(&text)?;

Ok(data.avatars.len() == 1)
Expand All @@ -100,17 +104,22 @@ impl Provider for AvtrDB {
.post(self.base_url.join("avatar/ingest")?)
.json(&request)
.send()?;

let status = response.status();
let text = response.text()?;
let data = serde_json::from_str::<AvtrDBResponse>(&text)?;
debug!("[{}] {status} | {text}", Type::AVTRDB);

match status {
StatusCode::OK => Ok(data.valid_avatar_ids == 1),
let unique = match status {
StatusCode::OK => data.valid_avatar_ids == 1,
StatusCode::TOO_MANY_REQUESTS => {
bail!("[{}] 429 Rate Limit, try again in 10 seconds", Type::AVTRDB)
warn!("[{}] 429 Rate Limit, trying again in 10 seconds", Type::VRCDB);
std::thread::sleep(Duration::from_secs(10));
self.send_avatar_id(avatar_id)?
}
_ => bail!("[{}] Unknown Error: {status} | {text}", Type::AVTRDB),
}
};

Ok(unique)
}
}
12 changes: 7 additions & 5 deletions src/provider/doughnut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ use std::collections::HashMap;

use anyhow::{bail, Result};
use reqwest::blocking::Client;

use reqwest::StatusCode;
use crate::{
provider::{Provider, Type},
USER_AGENT,
};

const URL: &str = "https://avtr1.nekosunevr.co.uk/v1/vrchat/avatars/store/putavatarExternal";

pub struct Doughnut {
client: Client,
userid: String,
Expand All @@ -30,7 +32,7 @@ impl Provider for Doughnut {
fn send_avatar_id(&self, avatar_id: &str) -> Result<bool> {
let response = self
.client
.post("https://avtr1.nekosunevr.co.uk/v1/vrchat/avatars/store/putavatarExternal")
.post(URL)
.header("User-Agent", USER_AGENT)
.json(&HashMap::from([
("id", avatar_id),
Expand All @@ -42,9 +44,9 @@ impl Provider for Doughnut {
let text = response.text()?;
debug!("[{}] {status} | {text}", Type::DOUGHNUT);

let unique = match status.as_u16() {
200 => false,
404 => true,
let unique = match status {
StatusCode::OK => false,
StatusCode::NOT_FOUND => true,
_ => bail!("[{}] {status} | {text}", Type::DOUGHNUT),
};

Expand Down
Loading

0 comments on commit 416243d

Please sign in to comment.