Async avatars

This commit is contained in:
Garry Newman 2019-04-15 16:43:55 +01:00
parent ca20e5a75a
commit e4ddd1fe6c
5 changed files with 170 additions and 43 deletions

View File

@ -1,6 +1,7 @@
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Linq;
using System.Threading.Tasks;
namespace Steamworks
{
@ -44,6 +45,70 @@ namespace Steamworks
}
}
[TestMethod]
public async Task LargeAvatar()
{
ulong id = (ulong)(76561197960279927 + (new Random().Next() % 10000));
var image = await Friends.GetLargeAvatarAsync( id );
if ( !image.HasValue )
return;
Console.WriteLine( $"image.Width {image.Value.Width}" );
Console.WriteLine( $"image.Height {image.Value.Height}" );
DrawImage( image.Value );
}
[TestMethod]
public async Task MediumAvatar()
{
ulong id = (ulong)(76561197960279927 + (new Random().Next() % 10000));
Console.WriteLine( $"Steam: http://steamcommunity.com/profiles/{id}" );
var image = await Friends.GetMediumAvatarAsync( id );
if ( !image.HasValue )
return;
Console.WriteLine( $"image.Width {image.Value.Width}" );
Console.WriteLine( $"image.Height {image.Value.Height}" );
DrawImage( image.Value );
}
[TestMethod]
public async Task SmallAvatar()
{
ulong id = (ulong)(76561197960279927 + (new Random().Next() % 10000));
var image = await Friends.GetSmallAvatarAsync( id );
if ( !image.HasValue )
return;
Console.WriteLine( $"image.Width {image.Value.Width}" );
Console.WriteLine( $"image.Height {image.Value.Height}" );
DrawImage( image.Value );
}
[TestMethod]
public async Task GetFriendsAvatars()
{
foreach ( var friend in Friends.GetFriends() )
{
Console.WriteLine( $"{friend.Id.Value}: {friend.Name}" );
var image = await friend.GetSmallAvatarAsync();
if ( image.HasValue )
{
DrawImage( image.Value );
}
// Assert.IsNotNull( friend.GetAvatar( Steamworks.Friends.AvatarSize.Medium ) );
}
}
/*
[TestMethod]
public void FriendListWithoutRefresh()
@ -59,40 +124,7 @@ namespace Steamworks
}
}
[TestMethod]
public void Avatar()
{
using ( var client = new Facepunch.Steamworks.Client( 252490 ) )
{
Assert.IsTrue( client.IsValid );
ulong id = (ulong)( 76561197960279927 + (new Random().Next() % 10000));
bool passed = false;
client.Friends.GetAvatar( Steamworks.Friends.AvatarSize.Medium, id, ( avatar) =>
{
if ( avatar == null )
{
Console.WriteLine( "No Avatar" );
}
else
{
Assert.AreEqual( avatar.Width, 64 );
Assert.AreEqual( avatar.Height, 64 );
Assert.AreEqual( avatar.Data.Length, avatar.Width * avatar.Height * 4 );
DrawImage( avatar );
}
passed = true;
});
while (passed == false )
{
client.Update();
System.Threading.Thread.Sleep( 10 );
}
}
}
[TestMethod]
public void CachedAvatar()
@ -113,8 +145,8 @@ namespace Steamworks
}
}
}
public static void DrawImage( Image img )
*/
public static void DrawImage( Image img )
{
var grad = " -:+#";
@ -136,6 +168,6 @@ namespace Steamworks
Console.WriteLine( str );
}
}
*/
}
}

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Facepunch.Steamworks;
using SteamNative;
namespace Steamworks
@ -113,5 +114,52 @@ namespace Steamworks
/// </summary>
public static void SetPlayedWith( CSteamID steamid ) => Internal.SetPlayedWith( steamid );
static async Task CacheUserInformationAsync( CSteamID steamid, bool nameonly )
{
// Got it straight away, skip any waiting.
if ( !Internal.RequestUserInformation( steamid, nameonly ) )
return;
await Task.Delay( 100 );
while ( Internal.RequestUserInformation( steamid, nameonly ) )
{
await Task.Delay( 50 );
}
//
// And extra wait here seems to solve avatars loading as [?]
//
await Task.Delay( 500 );
}
public static async Task<Image?> GetSmallAvatarAsync( CSteamID steamid )
{
await CacheUserInformationAsync( steamid, false );
return Utils.GetImage( Internal.GetSmallFriendAvatar( steamid ) );
}
public static async Task<Image?> GetMediumAvatarAsync( CSteamID steamid )
{
await CacheUserInformationAsync( steamid, false );
return Utils.GetImage( Internal.GetMediumFriendAvatar( steamid ) );
}
public static async Task<Image?> GetLargeAvatarAsync( CSteamID steamid )
{
await CacheUserInformationAsync( steamid, false );
var imageid = Internal.GetLargeFriendAvatar( steamid );
// Wait for the image to download
while ( imageid == -1 )
{
await Task.Delay( 50 );
imageid = Internal.GetLargeFriendAvatar( steamid );
}
return Utils.GetImage( imageid );
}
}
}

View File

@ -3,7 +3,7 @@ using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace Steamworks
{
@ -80,6 +80,20 @@ namespace Steamworks
}
}
public async Task<Image?> GetSmallAvatarAsync()
{
return await Friends.GetSmallAvatarAsync( Id );
}
public async Task<Image?> GetMediumAvatarAsync()
{
return await Friends.GetMediumAvatarAsync( Id );
}
public async Task<Image?> GetLargeAvatarAsync()
{
return await Friends.GetLargeAvatarAsync( Id );
}
}
}

View File

@ -0,0 +1,28 @@
using Facepunch.Steamworks;
namespace Steamworks
{
public struct Image
{
public uint Width;
public uint Height;
public byte[] Data;
public Color GetPixel( int x, int y )
{
if ( x < 0 || x >= Width ) throw new System.Exception( "x out of bounds" );
if ( y < 0 || y >= Height ) throw new System.Exception( "y out of bounds" );
Color c = new Color();
var i = (y * Width + x) * 4;
c.r = Data[i + 0];
c.g = Data[i + 1];
c.b = Data[i + 2];
c.a = Data[i + 3];
return c;
}
}
}

View File

@ -92,18 +92,23 @@ namespace Steamworks
/// <summary>
/// returns the image in RGBA format
/// </summary>
public static byte[] GetImageRGBA( int image )
public static Image? GetImage( int image )
{
if ( !GetImageSize( image, out var w, out var h ) )
var i = new Image();
if ( !GetImageSize( image, out i.Width, out i.Height ) )
return null;
var size = w * h * 4 * sizeof( char );
var data = new byte[size];
var size = i.Width * i.Height * 4;
if ( !Internal.GetImageRGBA( image, data, data.Length ) )
var buf = Helpers.TakeBuffer( (int) size );
if ( !Internal.GetImageRGBA( image, buf, (int)size ) )
return null;
return data;
i.Data = new byte[size];
Array.Copy( buf, 0, i.Data, 0, size );
return i;
}
/// <summary>