mirror of
https://github.com/Facepunch/Facepunch.Steamworks.git
synced 2025-02-04 01:30:30 +03:00
Friends Swap
This commit is contained in:
parent
b134c8708f
commit
90d9ae8c4c
@ -364,8 +364,8 @@ namespace Facepunch.Steamworks.Test
|
|||||||
|
|
||||||
client.Lobby.OnLobbyMemberDataUpdated = (steamID) =>
|
client.Lobby.OnLobbyMemberDataUpdated = (steamID) =>
|
||||||
{
|
{
|
||||||
string name = client.Friends.GetName(steamID);
|
var friend = new global::Steamworks.Friend( steamID );
|
||||||
Console.WriteLine(name + " updated data");
|
Console.WriteLine( friend.Name + " updated data");
|
||||||
Assert.IsTrue(client.Lobby.GetMemberData(steamID, "testkey") == "testvalue");
|
Assert.IsTrue(client.Lobby.GetMemberData(steamID, "testkey") == "testvalue");
|
||||||
Console.WriteLine("testkey is now: " + client.Lobby.GetMemberData(steamID, "testkey"));
|
Console.WriteLine("testkey is now: " + client.Lobby.GetMemberData(steamID, "testkey"));
|
||||||
};
|
};
|
||||||
|
@ -107,8 +107,6 @@ namespace Facepunch.Steamworks
|
|||||||
MicroTransactions = new MicroTransactions( this );
|
MicroTransactions = new MicroTransactions( this );
|
||||||
RemoteStorage = new RemoteStorage( this );
|
RemoteStorage = new RemoteStorage( this );
|
||||||
|
|
||||||
Workshop.friends = Friends;
|
|
||||||
|
|
||||||
Stats.UpdateStats();
|
Stats.UpdateStats();
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -149,8 +147,6 @@ namespace Facepunch.Steamworks
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
RunCallbacks();
|
RunCallbacks();
|
||||||
Friends.Cycle();
|
|
||||||
|
|
||||||
base.Update();
|
base.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,396 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using SteamNative;
|
|
||||||
|
|
||||||
namespace Facepunch.Steamworks
|
|
||||||
{
|
|
||||||
public partial class Client : IDisposable
|
|
||||||
{
|
|
||||||
Friends _friends;
|
|
||||||
|
|
||||||
public Friends Friends
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if ( _friends == null )
|
|
||||||
_friends = new Friends( this );
|
|
||||||
|
|
||||||
return _friends;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handles most interactions with people in Steam, not just friends as the name would suggest.
|
|
||||||
/// </summary>
|
|
||||||
/// <example>
|
|
||||||
/// foreach ( var friend in client.Friends.AllFriends )
|
|
||||||
/// {
|
|
||||||
/// Console.WriteLine( $"{friend.Id}: {friend.Name}" );
|
|
||||||
/// }
|
|
||||||
/// </example>
|
|
||||||
public class Friends
|
|
||||||
{
|
|
||||||
internal Client client;
|
|
||||||
private byte[] buffer = new byte[1024 * 128];
|
|
||||||
|
|
||||||
internal Friends( Client c )
|
|
||||||
{
|
|
||||||
client = c;
|
|
||||||
|
|
||||||
client.RegisterCallback<AvatarImageLoaded_t>( OnAvatarImageLoaded );
|
|
||||||
client.RegisterCallback<PersonaStateChange_t>( OnPersonaStateChange );
|
|
||||||
client.RegisterCallback<GameRichPresenceJoinRequested_t>( OnGameJoinRequested );
|
|
||||||
client.RegisterCallback<GameConnectedFriendChatMsg_t>( OnFriendChatMessage );
|
|
||||||
}
|
|
||||||
|
|
||||||
public delegate void ChatMessageDelegate( SteamFriend friend, string type, string message );
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called when chat message has been received from a friend. You'll need to turn on
|
|
||||||
/// ListenForFriendsMessages to recieve this.
|
|
||||||
/// </summary>
|
|
||||||
public event ChatMessageDelegate OnChatMessage;
|
|
||||||
|
|
||||||
private unsafe void OnFriendChatMessage( GameConnectedFriendChatMsg_t data )
|
|
||||||
{
|
|
||||||
if ( OnChatMessage == null ) return;
|
|
||||||
|
|
||||||
var friend = Get( data.SteamIDUser );
|
|
||||||
var type = ChatEntryType.ChatMsg;
|
|
||||||
fixed ( byte* ptr = buffer )
|
|
||||||
{
|
|
||||||
var len = client.native.friends.GetFriendMessage( data.SteamIDUser, data.MessageID, (IntPtr)ptr, buffer.Length, out type );
|
|
||||||
|
|
||||||
if ( len == 0 && type == ChatEntryType.Invalid )
|
|
||||||
return;
|
|
||||||
|
|
||||||
var typeName = type.ToString();
|
|
||||||
var message = Encoding.UTF8.GetString( buffer, 0, len );
|
|
||||||
|
|
||||||
OnChatMessage( friend, typeName, message );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool _listenForFriendsMessages;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Listens for Steam friends chat messages.
|
|
||||||
/// You can then show these chats inline in the game. For example with a Blizzard style chat message system or the chat system in Dota 2.
|
|
||||||
/// After enabling this you will receive callbacks when ever the user receives a chat message.
|
|
||||||
/// </summary>
|
|
||||||
public bool ListenForFriendsMessages
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _listenForFriendsMessages;
|
|
||||||
}
|
|
||||||
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_listenForFriendsMessages = value;
|
|
||||||
client.native.friends.SetListenForFriendsMessages( value );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public delegate void JoinRequestedDelegate( SteamFriend friend, string connect );
|
|
||||||
|
|
||||||
//
|
|
||||||
// Called when a friend has invited you to their game (using InviteToGame)
|
|
||||||
//
|
|
||||||
public event JoinRequestedDelegate OnInvitedToGame;
|
|
||||||
|
|
||||||
|
|
||||||
private void OnGameJoinRequested( GameRichPresenceJoinRequested_t data )
|
|
||||||
{
|
|
||||||
if ( OnInvitedToGame != null )
|
|
||||||
{
|
|
||||||
OnInvitedToGame( Get( data.SteamIDFriend ), data.Connect );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Try to get information about this user - which as name and avatar.
|
|
||||||
/// If returns true, we already have this user's information.
|
|
||||||
/// </summary>
|
|
||||||
public bool UpdateInformation( ulong steamid )
|
|
||||||
{
|
|
||||||
return !client.native.friends.RequestUserInformation( steamid, false );
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get this user's name
|
|
||||||
/// </summary>
|
|
||||||
public string GetName( ulong steamid )
|
|
||||||
{
|
|
||||||
client.native.friends.RequestUserInformation( steamid, true );
|
|
||||||
return client.native.friends.GetFriendPersonaName( steamid );
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<SteamFriend> _allFriends;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns all friends, even blocked, ignored, friend requests etc
|
|
||||||
/// </summary>
|
|
||||||
public IEnumerable<SteamFriend> All
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if ( _allFriends == null )
|
|
||||||
{
|
|
||||||
_allFriends = new List<SteamFriend>();
|
|
||||||
Refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _allFriends;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns only friends
|
|
||||||
/// </summary>
|
|
||||||
public IEnumerable<SteamFriend> AllFriends
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
foreach ( var friend in All )
|
|
||||||
{
|
|
||||||
if ( !friend.IsFriend ) continue;
|
|
||||||
|
|
||||||
yield return friend;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns all blocked users
|
|
||||||
/// </summary>
|
|
||||||
public IEnumerable<SteamFriend> AllBlocked
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
foreach ( var friend in All )
|
|
||||||
{
|
|
||||||
if ( !friend.IsBlocked ) continue;
|
|
||||||
|
|
||||||
yield return friend;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Refresh()
|
|
||||||
{
|
|
||||||
if ( _allFriends == null )
|
|
||||||
{
|
|
||||||
_allFriends = new List<SteamFriend>();
|
|
||||||
}
|
|
||||||
|
|
||||||
_allFriends.Clear();
|
|
||||||
|
|
||||||
var flags = (int) SteamNative.FriendFlags.All;
|
|
||||||
var count = client.native.friends.GetFriendCount( flags );
|
|
||||||
|
|
||||||
for ( int i=0; i<count; i++ )
|
|
||||||
{
|
|
||||||
var steamid = client.native.friends.GetFriendByIndex( i, flags );
|
|
||||||
_allFriends.Add( Get( steamid ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum AvatarSize
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Should be 32x32 - but make sure to check!
|
|
||||||
/// </summary>
|
|
||||||
Small,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Should be 64x64 - but make sure to check!
|
|
||||||
/// </summary>
|
|
||||||
Medium,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Should be 184x184 - but make sure to check!
|
|
||||||
/// </summary>
|
|
||||||
Large
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Try to get the avatar immediately. This should work for people on your friends list.
|
|
||||||
/// </summary>
|
|
||||||
public Image GetCachedAvatar( AvatarSize size, ulong steamid )
|
|
||||||
{
|
|
||||||
var imageid = 0;
|
|
||||||
|
|
||||||
switch (size)
|
|
||||||
{
|
|
||||||
case AvatarSize.Small:
|
|
||||||
imageid = client.native.friends.GetSmallFriendAvatar(steamid);
|
|
||||||
break;
|
|
||||||
case AvatarSize.Medium:
|
|
||||||
imageid = client.native.friends.GetMediumFriendAvatar(steamid);
|
|
||||||
break;
|
|
||||||
case AvatarSize.Large:
|
|
||||||
imageid = client.native.friends.GetLargeFriendAvatar(steamid);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( imageid == 1 ) return null; // Placeholder large
|
|
||||||
if ( imageid == 2 ) return null; // Placeholder medium
|
|
||||||
if ( imageid == 3 ) return null; // Placeholder small
|
|
||||||
|
|
||||||
var img = new Image()
|
|
||||||
{
|
|
||||||
Id = imageid
|
|
||||||
};
|
|
||||||
|
|
||||||
if ( !img.TryLoad( client.native.utils ) )
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return img;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Callback will be called when the avatar is ready. If we fail to get an
|
|
||||||
/// avatar, might be called with a null Image.
|
|
||||||
/// </summary>
|
|
||||||
public void GetAvatar( AvatarSize size, ulong steamid, Action<Image> callback )
|
|
||||||
{
|
|
||||||
// Maybe we already have it downloaded?
|
|
||||||
var image = GetCachedAvatar(size, steamid);
|
|
||||||
if ( image != null )
|
|
||||||
{
|
|
||||||
callback(image);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lets request it from Steam
|
|
||||||
if (!client.native.friends.RequestUserInformation(steamid, false))
|
|
||||||
{
|
|
||||||
// from docs: false means that we already have all the details about that user, and functions that require this information can be used immediately
|
|
||||||
// but that's probably not true because we just checked the cache
|
|
||||||
|
|
||||||
// check again in case it was just a race
|
|
||||||
image = GetCachedAvatar(size, steamid);
|
|
||||||
if ( image != null )
|
|
||||||
{
|
|
||||||
callback(image);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// maybe Steam returns false if it was already requested? just add another callback and hope it comes
|
|
||||||
// if not it'll time out anyway
|
|
||||||
}
|
|
||||||
|
|
||||||
PersonaCallbacks.Add( new PersonaCallback
|
|
||||||
{
|
|
||||||
SteamId = steamid,
|
|
||||||
Size = size,
|
|
||||||
Callback = callback,
|
|
||||||
Time = DateTime.Now
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private class PersonaCallback
|
|
||||||
{
|
|
||||||
public ulong SteamId;
|
|
||||||
public AvatarSize Size;
|
|
||||||
public Action<Image> Callback;
|
|
||||||
public DateTime Time;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<PersonaCallback> PersonaCallbacks = new List<PersonaCallback>();
|
|
||||||
|
|
||||||
public SteamFriend Get( ulong steamid )
|
|
||||||
{
|
|
||||||
var friend = All.Where( x => x.Id == steamid ).FirstOrDefault();
|
|
||||||
if ( friend != null ) return friend;
|
|
||||||
|
|
||||||
var f = new SteamFriend()
|
|
||||||
{
|
|
||||||
Id = steamid,
|
|
||||||
Client = client
|
|
||||||
};
|
|
||||||
|
|
||||||
f.Refresh();
|
|
||||||
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void Cycle()
|
|
||||||
{
|
|
||||||
if ( PersonaCallbacks.Count == 0 ) return;
|
|
||||||
|
|
||||||
var timeOut = DateTime.Now.AddSeconds( -10 );
|
|
||||||
|
|
||||||
for ( int i = PersonaCallbacks.Count-1; i >= 0; i-- )
|
|
||||||
{
|
|
||||||
var cb = PersonaCallbacks[i];
|
|
||||||
|
|
||||||
// Timeout
|
|
||||||
if ( cb.Time < timeOut )
|
|
||||||
{
|
|
||||||
if ( cb.Callback != null )
|
|
||||||
{
|
|
||||||
// final attempt, will be null unless the callback was missed somehow
|
|
||||||
var image = GetCachedAvatar( cb.Size, cb.SteamId );
|
|
||||||
|
|
||||||
cb.Callback( image );
|
|
||||||
}
|
|
||||||
|
|
||||||
PersonaCallbacks.Remove( cb );
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void OnPersonaStateChange( PersonaStateChange_t data )
|
|
||||||
{
|
|
||||||
// k_EPersonaChangeAvatar
|
|
||||||
if ( (data.ChangeFlags & 0x0040) == 0x0040 )
|
|
||||||
{
|
|
||||||
LoadAvatarForSteamId( data.SteamID );
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Find and refresh this friend's status
|
|
||||||
//
|
|
||||||
foreach ( var friend in All )
|
|
||||||
{
|
|
||||||
if ( friend.Id != data.SteamID ) continue;
|
|
||||||
|
|
||||||
friend.Refresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoadAvatarForSteamId( ulong Steamid )
|
|
||||||
{
|
|
||||||
for ( int i = PersonaCallbacks.Count - 1; i >= 0; i-- )
|
|
||||||
{
|
|
||||||
var cb = PersonaCallbacks[i];
|
|
||||||
if ( cb.SteamId != Steamid ) continue;
|
|
||||||
|
|
||||||
var image = GetCachedAvatar( cb.Size, cb.SteamId );
|
|
||||||
if ( image == null ) continue;
|
|
||||||
|
|
||||||
PersonaCallbacks.Remove( cb );
|
|
||||||
|
|
||||||
if ( cb.Callback != null )
|
|
||||||
{
|
|
||||||
cb.Callback( image );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnAvatarImageLoaded( AvatarImageLoaded_t data )
|
|
||||||
{
|
|
||||||
LoadAvatarForSteamId( data.SteamID );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -283,7 +283,7 @@ namespace Facepunch.Steamworks
|
|||||||
Score = entry.Score,
|
Score = entry.Score,
|
||||||
SteamId = entry.SteamIDUser,
|
SteamId = entry.SteamIDUser,
|
||||||
SubScores = entry.CDetails == 0 ? null : subEntriesBuffer.Take( entry.CDetails ).ToArray(),
|
SubScores = entry.CDetails == 0 ? null : subEntriesBuffer.Take( entry.CDetails ).ToArray(),
|
||||||
Name = client.Friends.GetName( entry.SteamIDUser ),
|
// Name = client.Friends.GetName( entry.SteamIDUser ),
|
||||||
AttachedFile = (entry.UGC >> 32) == 0xffffffff ? null : new RemoteFile( client.RemoteStorage, entry.UGC )
|
AttachedFile = (entry.UGC >> 32) == 0xffffffff ? null : new RemoteFile( client.RemoteStorage, entry.UGC )
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
@ -1,136 +0,0 @@
|
|||||||
using SteamNative;
|
|
||||||
|
|
||||||
namespace Facepunch.Steamworks
|
|
||||||
{
|
|
||||||
public class SteamFriend
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Steam Id
|
|
||||||
/// </summary>
|
|
||||||
public ulong Id { get; internal set; }
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Return true if blocked
|
|
||||||
/// </summary>
|
|
||||||
public bool IsBlocked => relationship == FriendRelationship.Blocked;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Return true if is a friend. Returns false if blocked, request etc.
|
|
||||||
/// </summary>
|
|
||||||
public bool IsFriend => relationship == FriendRelationship.Friend;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Their current display name
|
|
||||||
/// </summary>
|
|
||||||
public string Name;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns true if this friend is online
|
|
||||||
/// </summary>
|
|
||||||
public bool IsOnline => personaState != PersonaState.Offline;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns true if this friend is marked as away
|
|
||||||
/// </summary>
|
|
||||||
public bool IsAway => personaState == PersonaState.Away;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns true if this friend is marked as busy
|
|
||||||
/// </summary>
|
|
||||||
public bool IsBusy => personaState == PersonaState.Busy;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns true if this friend is marked as snoozing
|
|
||||||
/// </summary>
|
|
||||||
public bool IsSnoozing => personaState == PersonaState.Snooze;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns true if this friend is online and playing this game
|
|
||||||
/// </summary>
|
|
||||||
public bool IsPlayingThisGame => CurrentAppId == Client.AppId;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns true if this friend is online and playing this game
|
|
||||||
/// </summary>
|
|
||||||
public bool IsPlaying => CurrentAppId != 0;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The AppId this guy is playing
|
|
||||||
/// </summary>
|
|
||||||
public ulong CurrentAppId { get; internal set; }
|
|
||||||
|
|
||||||
public uint ServerIp { get; internal set; }
|
|
||||||
public int ServerGamePort { get; internal set; }
|
|
||||||
public int ServerQueryPort { get; internal set; }
|
|
||||||
public ulong ServerLobbyId { get; internal set; }
|
|
||||||
|
|
||||||
internal Client Client { get; set; }
|
|
||||||
private PersonaState personaState;
|
|
||||||
private FriendRelationship relationship;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns null if the value doesn't exist
|
|
||||||
/// </summary>
|
|
||||||
public string GetRichPresence( string key )
|
|
||||||
{
|
|
||||||
var val = Client.native.friends.GetFriendRichPresence( Id, key );
|
|
||||||
if ( string.IsNullOrEmpty( val ) ) return null;
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Update this friend, request the latest data from Steam's servers
|
|
||||||
/// </summary>
|
|
||||||
public void Refresh()
|
|
||||||
{
|
|
||||||
Name = Client.native.friends.GetFriendPersonaName( Id );
|
|
||||||
|
|
||||||
relationship = Client.native.friends.GetFriendRelationship( Id );
|
|
||||||
personaState = Client.native.friends.GetFriendPersonaState( Id );
|
|
||||||
|
|
||||||
CurrentAppId = 0;
|
|
||||||
ServerIp = 0;
|
|
||||||
ServerGamePort = 0;
|
|
||||||
ServerQueryPort = 0;
|
|
||||||
ServerLobbyId = 0;
|
|
||||||
|
|
||||||
var gameInfo = new SteamNative.FriendGameInfo_t();
|
|
||||||
if ( Client.native.friends.GetFriendGamePlayed( Id, ref gameInfo ) && gameInfo.GameID > 0 )
|
|
||||||
{
|
|
||||||
CurrentAppId = gameInfo.GameID;
|
|
||||||
ServerIp = gameInfo.GameIP;
|
|
||||||
ServerGamePort = gameInfo.GamePort;
|
|
||||||
ServerQueryPort = gameInfo.QueryPort;
|
|
||||||
ServerLobbyId = gameInfo.SteamIDLobby;
|
|
||||||
}
|
|
||||||
|
|
||||||
Client.native.friends.RequestFriendRichPresence( Id );
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This will return null if you don't have the target user's avatar in your cache.
|
|
||||||
/// Which usually happens for people not on your friends list.
|
|
||||||
/// </summary>
|
|
||||||
public Image GetAvatar( Friends.AvatarSize size )
|
|
||||||
{
|
|
||||||
return Client.Friends.GetCachedAvatar( size, Id );
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Invite this friend to the game that we are playing
|
|
||||||
/// </summary>
|
|
||||||
public bool InviteToGame(string Text)
|
|
||||||
{
|
|
||||||
return Client.native.friends.InviteUserToGame(Id, Text);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sends a message to a Steam friend. Returns true if success
|
|
||||||
/// </summary>
|
|
||||||
public bool SendMessage( string message )
|
|
||||||
{
|
|
||||||
return Client.native.friends.ReplyToFriendMessage( Id, message );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -203,11 +203,12 @@ namespace Facepunch.Steamworks
|
|||||||
public int ReportScore { get; internal set; }
|
public int ReportScore { get; internal set; }
|
||||||
public string PreviewImageUrl { get; internal set; }
|
public string PreviewImageUrl { get; internal set; }
|
||||||
|
|
||||||
|
/*
|
||||||
string _ownerName = null;
|
string _ownerName = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public string OwnerName
|
public Friend OwnerName
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@ -226,7 +227,7 @@ namespace Facepunch.Steamworks
|
|||||||
|
|
||||||
return _ownerName;
|
return _ownerName;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,6 @@ namespace Facepunch.Steamworks
|
|||||||
public int PerPage { get; set; } = SteamResponseSize;
|
public int PerPage { get; set; } = SteamResponseSize;
|
||||||
|
|
||||||
internal Workshop workshop;
|
internal Workshop workshop;
|
||||||
internal Friends friends;
|
|
||||||
|
|
||||||
private int _resultPage = 0;
|
private int _resultPage = 0;
|
||||||
private int _resultsRemain = 0;
|
private int _resultsRemain = 0;
|
||||||
|
@ -31,7 +31,6 @@ namespace Facepunch.Steamworks
|
|||||||
internal const ulong InvalidHandle = 0xffffffffffffffff;
|
internal const ulong InvalidHandle = 0xffffffffffffffff;
|
||||||
|
|
||||||
internal SteamNative.SteamUGC ugc;
|
internal SteamNative.SteamUGC ugc;
|
||||||
internal Friends friends;
|
|
||||||
internal BaseSteamworks steamworks;
|
internal BaseSteamworks steamworks;
|
||||||
internal SteamNative.SteamRemoteStorage remoteStorage;
|
internal SteamNative.SteamRemoteStorage remoteStorage;
|
||||||
|
|
||||||
@ -66,7 +65,6 @@ namespace Facepunch.Steamworks
|
|||||||
ugc = null;
|
ugc = null;
|
||||||
steamworks = null;
|
steamworks = null;
|
||||||
remoteStorage = null;
|
remoteStorage = null;
|
||||||
friends = null;
|
|
||||||
|
|
||||||
OnFileDownloaded = null;
|
OnFileDownloaded = null;
|
||||||
OnItemInstalled = null;
|
OnItemInstalled = null;
|
||||||
@ -150,7 +148,6 @@ namespace Facepunch.Steamworks
|
|||||||
{
|
{
|
||||||
AppId = steamworks.AppId,
|
AppId = steamworks.AppId,
|
||||||
workshop = this,
|
workshop = this,
|
||||||
friends = friends
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,11 +33,78 @@ namespace Steamworks
|
|||||||
|
|
||||||
internal static void InstallEvents()
|
internal static void InstallEvents()
|
||||||
{
|
{
|
||||||
//new Event<BroadcastUploadStart_t>( x => OnBroadcastStarted?.Invoke() );
|
new Event<PersonaStateChange_t>( x => OnPersonaStateChange?.Invoke( new Friend( x.SteamID ) ) );
|
||||||
//new Event<BroadcastUploadStop_t>( x => OnBroadcastStopped?.Invoke( x.Result ) );
|
new Event<GameRichPresenceJoinRequested_t>( x => OnGameRichPresenceJoinRequested?.Invoke( new Friend( x.SteamIDFriend), x.Connect ) );
|
||||||
|
new Event<GameConnectedFriendChatMsg_t>( OnFriendChatMessage );
|
||||||
|
new Event<GameOverlayActivated_t>( x => OnGameOverlayActivated?.Invoke() );
|
||||||
|
new Event<GameServerChangeRequested_t>( x => OnGameServerChangeRequested?.Invoke( x.Server, x.Password ) );
|
||||||
|
new Event<GameLobbyJoinRequested_t>( x => OnGameLobbyJoinRequested?.Invoke( x.SteamIDLobby, x.SteamIDFriend ) );
|
||||||
|
new Event<FriendRichPresenceUpdate_t>( x => OnFriendRichPresenceUpdate?.Invoke( new Friend( x.SteamIDFriend ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// public static event Action OnBroadcastStarted;
|
/// <summary>
|
||||||
|
/// Called when chat message has been received from a friend. You'll need to turn on
|
||||||
|
/// ListenForFriendsMessages to recieve this. (friend, msgtype, message)
|
||||||
|
/// </summary>
|
||||||
|
public static event Action<Friend, string, string> OnChatMessage;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// called when a friends' status changes
|
||||||
|
/// </summary>
|
||||||
|
public static event Action<Friend> OnPersonaStateChange;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when the user tries to join a game from their friends list
|
||||||
|
/// rich presence will have been set with the "connect" key which is set here
|
||||||
|
/// </summary>
|
||||||
|
public static event Action<Friend, string> OnGameRichPresenceJoinRequested;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Posted when game overlay activates or deactivates
|
||||||
|
/// the game can use this to be pause or resume single player games
|
||||||
|
/// </summary>
|
||||||
|
public static event Action OnGameOverlayActivated;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when the user tries to join a different game server from their friends list
|
||||||
|
/// game client should attempt to connect to specified server when this is received
|
||||||
|
/// </summary>
|
||||||
|
public static event Action<string, string> OnGameServerChangeRequested;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when the user tries to join a lobby from their friends list
|
||||||
|
/// game client should attempt to connect to specified lobby when this is received
|
||||||
|
/// </summary>
|
||||||
|
public static event Action<CSteamID, CSteamID> OnGameLobbyJoinRequested;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Callback indicating updated data about friends rich presence information
|
||||||
|
/// </summary>
|
||||||
|
public static event Action<Friend> OnFriendRichPresenceUpdate;
|
||||||
|
|
||||||
|
static unsafe void OnFriendChatMessage( GameConnectedFriendChatMsg_t data )
|
||||||
|
{
|
||||||
|
if ( OnChatMessage == null ) return;
|
||||||
|
|
||||||
|
var friend = new Friend( data.SteamIDUser );
|
||||||
|
|
||||||
|
var buffer = Helpers.TakeBuffer( 1024 * 32 );
|
||||||
|
var type = ChatEntryType.ChatMsg;
|
||||||
|
|
||||||
|
fixed ( byte* ptr = buffer )
|
||||||
|
{
|
||||||
|
var len = Internal.GetFriendMessage( data.SteamIDUser, data.MessageID, (IntPtr)ptr, buffer.Length, ref type );
|
||||||
|
|
||||||
|
if ( len == 0 && type == ChatEntryType.Invalid )
|
||||||
|
return;
|
||||||
|
|
||||||
|
var typeName = type.ToString();
|
||||||
|
var message = Encoding.UTF8.GetString( buffer, 0, len );
|
||||||
|
|
||||||
|
OnChatMessage( friend, typeName, message );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// returns the local players name - guaranteed to not be NULL.
|
/// returns the local players name - guaranteed to not be NULL.
|
||||||
@ -196,5 +263,23 @@ namespace Steamworks
|
|||||||
Internal.ClearRichPresence();
|
Internal.ClearRichPresence();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool _listenForFriendsMessages;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Listens for Steam friends chat messages.
|
||||||
|
/// You can then show these chats inline in the game. For example with a Blizzard style chat message system or the chat system in Dota 2.
|
||||||
|
/// After enabling this you will receive callbacks when ever the user receives a chat message.
|
||||||
|
/// </summary>
|
||||||
|
public static bool ListenForFriendsMessages
|
||||||
|
{
|
||||||
|
get => _listenForFriendsMessages;
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_listenForFriendsMessages = value;
|
||||||
|
Internal.SetListenForFriendsMessages( value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -37,6 +37,7 @@ namespace Steamworks
|
|||||||
Music.InstallEvents();
|
Music.InstallEvents();
|
||||||
Video.InstallEvents();
|
Video.InstallEvents();
|
||||||
User.InstallEvents();
|
User.InstallEvents();
|
||||||
|
Friends.InstallEvents();
|
||||||
|
|
||||||
RunCallbacks();
|
RunCallbacks();
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,28 @@ namespace Steamworks
|
|||||||
|
|
||||||
public bool IsFriend => Relationship == FriendRelationship.Friend;
|
public bool IsFriend => Relationship == FriendRelationship.Friend;
|
||||||
public bool IsBlocked => Relationship == FriendRelationship.Blocked;
|
public bool IsBlocked => Relationship == FriendRelationship.Blocked;
|
||||||
|
public bool IsPlayingThisGame => GameInfo?.GameID == Utils.AppId;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns true if this friend is online
|
||||||
|
/// </summary>
|
||||||
|
public bool IsOnline => State != PersonaState.Offline;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns true if this friend is marked as away
|
||||||
|
/// </summary>
|
||||||
|
public bool IsAway => State == PersonaState.Away;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns true if this friend is marked as busy
|
||||||
|
/// </summary>
|
||||||
|
public bool IsBusy => State == PersonaState.Busy;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns true if this friend is marked as snoozing
|
||||||
|
/// </summary>
|
||||||
|
public bool IsSnoozing => State == PersonaState.Snooze;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public FriendRelationship Relationship => Friends.Internal.GetFriendRelationship( Id );
|
public FriendRelationship Relationship => Friends.Internal.GetFriendRelationship( Id );
|
||||||
@ -95,5 +117,28 @@ namespace Steamworks
|
|||||||
return await Friends.GetLargeAvatarAsync( Id );
|
return await Friends.GetLargeAvatarAsync( Id );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string GetRichPresence( string key )
|
||||||
|
{
|
||||||
|
var val = Friends.Internal.GetFriendRichPresence( Id, key );
|
||||||
|
if ( string.IsNullOrEmpty( val ) ) return null;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invite this friend to the game that we are playing
|
||||||
|
/// </summary>
|
||||||
|
public bool InviteToGame( string Text )
|
||||||
|
{
|
||||||
|
return Friends.Internal.InviteUserToGame( Id, Text );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sends a message to a Steam friend. Returns true if success
|
||||||
|
/// </summary>
|
||||||
|
public bool SendMessage( string message )
|
||||||
|
{
|
||||||
|
return Friends.Internal.ReplyToFriendMessage( Id, message );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user