Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(friends): adding getFriendsFromSource & avatar wrappers #166

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions src/friends.rs
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,82 @@ impl<Manager> Friends<Manager> {
}
}

/// Returns a small (32x32) avatar for the current user in RGBA format
pub fn small_avatar(&self) -> Option<Vec<u8>> {
unsafe {
let user: *mut sys::ISteamUser = sys::SteamAPI_SteamUser_v023();
let steam_id = sys::SteamAPI_ISteamUser_GetSteamID(user);
let utils = sys::SteamAPI_SteamUtils_v010();
let img = sys::SteamAPI_ISteamFriends_GetSmallFriendAvatar(self.friends, steam_id);
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;
}
assert_eq!(width, 32);
assert_eq!(height, 32);
let mut dest = vec![0; 32 * 32 * 4];
if !sys::SteamAPI_ISteamUtils_GetImageRGBA(utils, img, dest.as_mut_ptr(), 32 * 32 * 4) {
return None;
}
Some(dest)
}
}

/// Returns a small (64x64) avatar for the current user in RGBA format
pub fn medium_avatar(&self) -> Option<Vec<u8>> {
unsafe {
let user: *mut sys::ISteamUser = sys::SteamAPI_SteamUser_v023();
let steam_id = sys::SteamAPI_ISteamUser_GetSteamID(user);
let utils = sys::SteamAPI_SteamUtils_v010();
let img = sys::SteamAPI_ISteamFriends_GetMediumFriendAvatar(self.friends, steam_id);
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;
}
assert_eq!(width, 64);
assert_eq!(height, 64);
let mut dest = vec![0; 64 * 64 * 4];
if !sys::SteamAPI_ISteamUtils_GetImageRGBA(utils, img, dest.as_mut_ptr(), 64 * 64 * 4) {
return None;
}
Some(dest)
}
}

/// Returns a small (184x184) avatar for the current user in RGBA format
pub fn large_avatar(&self) -> Option<Vec<u8>> {
unsafe {
let user: *mut sys::ISteamUser = sys::SteamAPI_SteamUser_v023();
let steam_id = sys::SteamAPI_ISteamUser_GetSteamID(user);
let utils = sys::SteamAPI_SteamUtils_v010();
let img = sys::SteamAPI_ISteamFriends_GetLargeFriendAvatar(self.friends, steam_id);
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;
}
assert_eq!(width, 184);
assert_eq!(height, 184);
let mut dest = vec![0; 184 * 184 * 4];
if !sys::SteamAPI_ISteamUtils_GetImageRGBA(utils, img, dest.as_mut_ptr(), 184 * 184 * 4)
{
return None;
}
Some(dest)
}
}

pub fn get_friends(&self, flags: FriendFlags) -> Vec<Friend<Manager>> {
unsafe {
let count = sys::SteamAPI_ISteamFriends_GetFriendCount(self.friends, flags.bits() as _);
Expand All @@ -111,6 +187,31 @@ impl<Manager> Friends<Manager> {
friends
}
}

/// Get a list of users from a specific source (e.g. gameserver)
/// Despite the misleading name, it does not return only friends
/// but all users from the source that are currently connected.
/// This does however require some local client to be connected to the source.
pub fn get_friends_from_source(&self, source: SteamId) -> Vec<Friend<Manager>> {
unsafe {
let count =
sys::SteamAPI_ISteamFriends_GetFriendCountFromSource(self.friends, source.0);
if count == -1 {
return Vec::new();
}
let mut friends = Vec::with_capacity(count as usize);
for idx in 0..count {
let friend = SteamId(sys::SteamAPI_ISteamFriends_GetFriendFromSourceByIndex(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be implemented as an iterator instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the vec is initialized with size count to make it explicit that the index is important.
the steam api requires the index to get further information

what do you think?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that's the issue I'm raising here. Forcing this into Vec requires it to allocate on each call. If we had a lazy iterator, the caller can the n decide whether to collect it into a Vec or just iterate/filter/postprocess or whatever they please with it instead.

self.friends,
source.0,
idx,
));
friends.push(self.get_friend(friend));
}
friends
}
}

/// Returns recently played with players list
pub fn get_coplay_friends(&self) -> Vec<Friend<Manager>> {
unsafe {
Expand Down