diff --git a/Facepunch.Steamworks.Test/Client/FriendsTest.cs b/Facepunch.Steamworks.Test/Client/FriendsTest.cs
index 4a0b06d..e0548df 100644
--- a/Facepunch.Steamworks.Test/Client/FriendsTest.cs
+++ b/Facepunch.Steamworks.Test/Client/FriendsTest.cs
@@ -2,32 +2,49 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Linq;
-namespace Facepunch.Steamworks.Test
+namespace Steamworks
{
[DeploymentItem( "steam_api64.dll" )]
[TestClass]
- public class Friends
+ public class FriendsTest
{
[TestMethod]
- public void FriendList()
+ public void GetFriends()
{
- using ( var client = new Facepunch.Steamworks.Client( 252490 ) )
- {
- Assert.IsTrue( client.IsValid );
+ foreach ( var friend in Friends.GetFriends() )
+ {
+ Console.WriteLine( $"{friend.Id.Value}: {friend.Name} (Friend:{friend.IsFriend}) (Blocked:{friend.IsBlocked})" );
+ Console.WriteLine( $" {string.Join( ", ", friend.NameHistory)}" );
- client.Friends.Refresh();
-
- Assert.IsNotNull( client.Friends.All );
-
- foreach ( var friend in client.Friends.All )
- {
- Console.WriteLine( "{0}: {1} (Friend:{2}) (Blocked:{3})", friend.Id, friend.Name, friend.IsFriend, friend.IsBlocked );
-
- Assert.IsNotNull(friend.GetAvatar( Steamworks.Friends.AvatarSize.Medium ));
- }
- }
+ // Assert.IsNotNull( friend.GetAvatar( Steamworks.Friends.AvatarSize.Medium ) );
+ }
}
+ [TestMethod]
+ public void GetBlocked()
+ {
+ foreach ( var friend in Friends.GetBlocked() )
+ {
+ Console.WriteLine( $"{friend.Id.Value}: {friend.Name} (Friend:{friend.IsFriend}) (Blocked:{friend.IsBlocked})" );
+ Console.WriteLine( $" {string.Join( ", ", friend.NameHistory )}" );
+
+ // Assert.IsNotNull( friend.GetAvatar( Steamworks.Friends.AvatarSize.Medium ) );
+ }
+ }
+
+ [TestMethod]
+ public void GetPlayedWith()
+ {
+ foreach ( var friend in Friends.GetPlayedWith() )
+ {
+ Console.WriteLine( $"{friend.Id.Value}: {friend.Name} (Friend:{friend.IsFriend}) (Blocked:{friend.IsBlocked})" );
+ Console.WriteLine( $" {string.Join( ", ", friend.NameHistory )}" );
+
+ // Assert.IsNotNull( friend.GetAvatar( Steamworks.Friends.AvatarSize.Medium ) );
+ }
+ }
+
+ /*
[TestMethod]
public void FriendListWithoutRefresh()
{
@@ -119,5 +136,6 @@ namespace Facepunch.Steamworks.Test
Console.WriteLine( str );
}
}
- }
+ */
+ }
}
diff --git a/Facepunch.Steamworks/Redux/Friends.cs b/Facepunch.Steamworks/Redux/Friends.cs
new file mode 100644
index 0000000..7310e5c
--- /dev/null
+++ b/Facepunch.Steamworks/Redux/Friends.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+using SteamNative;
+
+namespace Steamworks
+{
+ ///
+ /// Undocumented Parental Settings
+ ///
+ public static class Friends
+ {
+ static Internal.ISteamFriends _internal;
+ internal static Internal.ISteamFriends Internal
+ {
+ get
+ {
+ if ( _internal == null )
+ _internal = new Internal.ISteamFriends();
+
+ return _internal;
+ }
+ }
+
+ internal static void InstallEvents()
+ {
+ //new Event( x => OnBroadcastStarted?.Invoke() );
+ //new Event( x => OnBroadcastStopped?.Invoke( x.Result ) );
+ }
+
+ // public static event Action OnBroadcastStarted;
+
+ ///
+ /// returns the local players name - guaranteed to not be NULL.
+ /// this is the same name as on the users community profile page
+ ///
+ public static string PersonaName => Internal.GetPersonaName();
+
+ ///
+ /// gets the status of the current user
+ ///
+ public static PersonaState PersonaState => Internal.GetPersonaState();
+
+ public static IEnumerable GetFriends()
+ {
+ for ( int i=0; i GetBlocked()
+ {
+ for ( int i = 0; i < Internal.GetFriendCount( (int)FriendFlags.Blocked ); i++ )
+ {
+ yield return new Friend( Internal.GetFriendByIndex( i, 0xFFFF ) );
+ }
+ }
+
+ public static IEnumerable GetPlayedWith()
+ {
+ for ( int i = 0; i < Internal.GetFriendCount( (int)FriendFlags.Blocked ); i++ )
+ {
+ yield return new Friend( Internal.GetFriendByIndex( i, 0xFFFF ) );
+ }
+ }
+
+
+
+ }
+}
\ No newline at end of file
diff --git a/Facepunch.Steamworks/Redux/Structs/Friend.cs b/Facepunch.Steamworks/Redux/Structs/Friend.cs
new file mode 100644
index 0000000..94fa561
--- /dev/null
+++ b/Facepunch.Steamworks/Redux/Structs/Friend.cs
@@ -0,0 +1,79 @@
+using SteamNative;
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Text;
+
+
+namespace Steamworks
+{
+ public struct Friend
+ {
+ public CSteamID Id;
+
+ public Friend( CSteamID steamid )
+ {
+ Id = steamid;
+ }
+
+ public bool IsFriend => Relationship == FriendRelationship.Friend;
+ public bool IsBlocked => Relationship == FriendRelationship.Blocked;
+
+
+ public FriendRelationship Relationship => Friends.Internal.GetFriendRelationship( Id );
+ public PersonaState State => Friends.Internal.GetFriendPersonaState( Id );
+ public string Name => Friends.Internal.GetFriendPersonaName( Id );
+ public IEnumerable NameHistory
+ {
+ get
+ {
+ for( int i=0; i<32; i++ )
+ {
+ var n = Friends.Internal.GetFriendPersonaNameHistory( Id, i );
+ if ( string.IsNullOrEmpty( n ) )
+ break;
+
+ yield return n;
+ }
+ }
+ }
+
+ public int SteamLevel => Friends.Internal.GetFriendSteamLevel( Id );
+
+
+
+ public FriendGameInfo? GameInfo
+ {
+ get
+ {
+ FriendGameInfo_t gameInfo = default( FriendGameInfo_t );
+ if ( !Friends.Internal.GetFriendGamePlayed( Id, ref gameInfo ) )
+ return null;
+
+ return FriendGameInfo.From( gameInfo );
+ }
+ }
+
+ public struct FriendGameInfo
+ {
+ internal ulong GameID; // m_gameID class CGameID
+ internal uint GameIP; // m_unGameIP uint32
+ internal ushort GamePort; // m_usGamePort uint16
+ internal ushort QueryPort; // m_usQueryPort uint16
+ internal ulong SteamIDLobby; // m_steamIDLobby class CSteamID
+
+ public static FriendGameInfo From( FriendGameInfo_t i )
+ {
+ return new FriendGameInfo
+ {
+ GameID = i.GameID,
+ GameIP = i.GameIP,
+ GamePort = i.GamePort,
+ QueryPort = i.QueryPort,
+ SteamIDLobby = i.SteamIDLobby,
+ };
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Facepunch.Steamworks/Utility/BaseSteamInterface.cs b/Facepunch.Steamworks/Utility/BaseSteamInterface.cs
index ccf2b18..da2bd9c 100644
--- a/Facepunch.Steamworks/Utility/BaseSteamInterface.cs
+++ b/Facepunch.Steamworks/Utility/BaseSteamInterface.cs
@@ -38,6 +38,9 @@ namespace Steamworks.Internal
internal string GetString( IntPtr p )
{
+ if ( p == IntPtr.Zero )
+ return null;
+
// return Marshal.PtrToStringUTF8( p );
lock ( stringbuffer )
{