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 ) {