rbx_asset: get_asset_v2

This commit is contained in:
Quaternions 2025-04-03 11:40:13 -07:00
parent fb6fb67954
commit 4d90a74a82
Signed by: Quaternions
GPG Key ID: D0DF5964F79AC131

@ -95,6 +95,56 @@ impl std::fmt::Display for GetError{
}
impl std::error::Error for GetError{}
#[derive(Debug)]
pub enum GetAssetV2Error{
ParseError(url::ParseError),
Response(ResponseError),
VersionHeaderMissing,
ToStr(reqwest::header::ToStrError),
ParseInt(std::num::ParseIntError),
Reqwest(reqwest::Error),
}
impl std::fmt::Display for GetAssetV2Error{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f,"{self:?}")
}
}
impl std::error::Error for GetAssetV2Error{}
#[derive(serde::Deserialize)]
#[allow(nonstandard_style,dead_code)]
pub struct GetAssetV2AssetMetadata{
pub metadataType:u32,
pub value:String,
}
#[derive(serde::Deserialize)]
#[allow(nonstandard_style,dead_code)]
pub struct GetAssetV2Location{
pub assetFormat:String,// "source"
location:String,// this value is private so users cannot mutate it
pub assetMetadatas:Vec<GetAssetV2AssetMetadata>,
}
impl GetAssetV2Location{
pub fn location(&self)->&str{
&self.location
}
}
#[derive(serde::Deserialize)]
#[allow(nonstandard_style,dead_code)]
pub struct GetAssetV2Info{
pub locations:Vec<GetAssetV2Location>,
pub requestId:String,
pub IsHashDynamic:bool,
pub IsCopyrightProtected:bool,
pub isArchived:bool,
pub assetTypeId:u32,
}
pub struct GetAssetV2{
pub version:u64,
pub info:GetAssetV2Info,
}
#[derive(Debug)]
#[derive(serde::Deserialize,serde::Serialize)]
pub enum CreatorType{
@ -411,6 +461,50 @@ impl CookieContext{
Err(e)=>Err(e),
}.map_err(GetError::IO)
}
pub async fn get_asset_v2(&self,config:GetAssetRequest)->Result<GetAssetV2,GetAssetV2Error>{
let mut url=reqwest::Url::parse("https://assetdelivery.roblox.com/v2/asset").map_err(GetAssetV2Error::ParseError)?;
//url borrow scope
{
let mut query=url.query_pairs_mut();//borrow here
query.append_pair("ID",config.asset_id.to_string().as_str());
if let Some(version)=config.version{
query.append_pair("version",version.to_string().as_str());
}
}
let response=crate::response_ok(
self.get(url).await.map_err(GetAssetV2Error::Reqwest)?
).await.map_err(GetAssetV2Error::Response)?;
let version=response
.headers()
.get("roblox-assetversionnumber")
.ok_or(GetAssetV2Error::VersionHeaderMissing)?
.to_str()
.map_err(GetAssetV2Error::ToStr)?
.parse()
.map_err(GetAssetV2Error::ParseInt)?;
let info=response.json().await.map_err(GetAssetV2Error::Reqwest)?;
Ok(GetAssetV2{
version,
info,
})
}
pub async fn get_asset_v2_download(&self,config:&GetAssetV2Location)->Result<Vec<u8>,GetError>{
let url=reqwest::Url::parse(config.location.as_str()).map_err(GetError::ParseError)?;
let body=crate::response_ok(
self.get(url).await.map_err(GetError::Reqwest)?
).await.map_err(GetError::Response)?
.bytes().await.map_err(GetError::Reqwest)?;
match maybe_gzip_decode(std::io::Cursor::new(body)){
Ok(ReaderType::GZip(readable))=>read_readable(readable),
Ok(ReaderType::Raw(readable))=>read_readable(readable),
Err(e)=>Err(e),
}.map_err(GetError::IO)
}
pub async fn get_asset_details(&self,config:GetAssetDetailsRequest)->Result<AssetDetails,GetError>{
let url=reqwest::Url::parse(format!("https://economy.roblox.com/v2/assets/{}/details",config.asset_id).as_str()).map_err(GetError::ParseError)?;
crate::response_ok(