use super::*;
pub struct AchievementHelper<'parent> {
pub(crate) name: CString,
pub(crate) parent: &'parent UserStats,
}
impl AchievementHelper<'_> {
pub fn get(&self) -> Result<bool, ()> {
unsafe {
let mut achieved = false;
let success = sys::SteamAPI_ISteamUserStats_GetAchievement(
self.parent.user_stats,
self.name.as_ptr(),
&mut achieved,
);
if success {
Ok(achieved)
} else {
Err(())
}
}
}
pub fn set(&self) -> Result<(), ()> {
let success = unsafe {
sys::SteamAPI_ISteamUserStats_SetAchievement(self.parent.user_stats, self.name.as_ptr())
};
if success {
Ok(())
} else {
Err(())
}
}
pub fn clear(&self) -> Result<(), ()> {
let success = unsafe {
sys::SteamAPI_ISteamUserStats_ClearAchievement(
self.parent.user_stats,
self.name.as_ptr(),
)
};
if success {
Ok(())
} else {
Err(())
}
}
pub fn get_achievement_achieved_percent(&self) -> Result<f32, ()> {
unsafe {
let mut percent = 0.0;
let success = sys::SteamAPI_ISteamUserStats_GetAchievementAchievedPercent(
self.parent.user_stats,
self.name.as_ptr(),
&mut percent,
);
if success {
Ok(percent)
} else {
Err(())
}
}
}
pub fn get_achievement_and_unlock_time(&self) -> Result<(bool, u32), ()> {
let mut achieved = false;
let mut unlocktime = 0u32;
let success = unsafe {
sys::SteamAPI_ISteamUserStats_GetAchievementAndUnlockTime(
self.parent.user_stats,
self.name.as_ptr(),
&mut achieved,
&mut unlocktime,
)
};
if success {
Ok((achieved, unlocktime))
} else {
Err(())
}
}
pub fn get_achievement_display_attribute(&self, key: &str) -> Result<&str, ()> {
unsafe {
let key_c_str = CString::new(key).expect("Failed to create c_str from key parameter");
let str = sys::SteamAPI_ISteamUserStats_GetAchievementDisplayAttribute(
self.parent.user_stats,
self.name.as_ptr(),
key_c_str.as_ptr(),
);
let c_str = CStr::from_ptr(str);
match c_str.to_str() {
Ok(result) => Ok(result),
Err(_) => Err(()),
}
}
}
pub fn get_achievement_icon(&self) -> Option<Vec<u8>> {
Some(self.internal_get_achievement_icon(true)?.0)
}
fn internal_get_achievement_icon(&self, avoid_big_icons: bool) -> Option<(Vec<u8>, u32, u32)> {
unsafe {
let utils: *mut sys::ISteamUtils = sys::SteamAPI_SteamUtils_v010();
let img = sys::SteamAPI_ISteamUserStats_GetAchievementIcon(
self.parent.user_stats,
self.name.as_ptr(),
);
if img == 0 {
return None;
}
let mut width = 0;
let mut height = 0;
if !sys::SteamAPI_ISteamUtils_GetImageSize(utils, img, &mut width, &mut height) {
return None;
}
if avoid_big_icons && (width != 64 || height != 64) {
return None;
}
let mut dest = vec![0; (width * height * 4).try_into().unwrap()];
if !sys::SteamAPI_ISteamUtils_GetImageRGBA(
utils,
img,
dest.as_mut_ptr(),
(width * height * 4).try_into().unwrap(),
) {
return None;
}
Some((dest, width, height))
}
}
#[cfg(feature = "image")]
pub fn get_achievement_icon_v2(&self) -> Option<image::ImageBuffer<image::Rgba<u8>, Vec<u8>>> {
let (vec, width, height) = self.internal_get_achievement_icon(false)?;
let img = image::ImageBuffer::<image::Rgba<u8>, Vec<u8>>::from_vec(width, height, vec)?;
return Some(img);
}
}