using System;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
namespace Steamworks.Data
{
///
/// Represents a Steam lobby.
///
public struct Lobby
{
public SteamId Id { get; internal set; }
public Result Result { get; internal set; }
public Lobby( SteamId id )
{
Id = id;
Result = Result.OK;
}
///
/// Try to join this room. Will return on success,
/// and anything else is a failure.
///
public async Task Join()
{
if (SteamMatchmaking.Internal is null) { return RoomEnter.Error; }
var result = await SteamMatchmaking.Internal.JoinLobby( Id );
if ( !result.HasValue ) return RoomEnter.Error;
return (RoomEnter) result.Value.EChatRoomEnterResponse;
}
///
/// Leave a lobby; this will take effect immediately on the client side
/// other users in the lobby will be notified by a LobbyChatUpdate_t callback
///
public void Leave()
{
SteamMatchmaking.Internal?.LeaveLobby( Id );
}
///
/// Invite another user to the lobby.
/// Will return if the invite is successfully sent, whether or not the target responds
/// returns if the local user is not connected to the Steam servers
///
public bool InviteFriend( SteamId steamid )
{
return SteamMatchmaking.Internal != null && SteamMatchmaking.Internal.InviteUserToLobby( Id, steamid );
}
///
/// Gets the number of users in this lobby.
///
public int MemberCount => SteamMatchmaking.Internal?.GetNumLobbyMembers( Id ) ?? 0;
///
/// Returns current members in the lobby. The current user must be in the lobby in order to see the users.
///
public IEnumerable Members
{
get
{
for( int i = 0; i < MemberCount; i++ )
{
if (SteamMatchmaking.Internal is null) { break; }
yield return new Friend( SteamMatchmaking.Internal.GetLobbyMemberByIndex( Id, i ) );
}
}
}
///
/// Get data associated with this lobby.
///
public string? GetData( string key )
{
return SteamMatchmaking.Internal?.GetLobbyData( Id, key );
}
///
/// Set data associated with this lobby.
///
public bool SetData( string key, string value )
{
if ( key.Length > 255 ) throw new System.ArgumentException( "Key should be < 255 chars", nameof( key ) );
if ( value.Length > 8192 ) throw new System.ArgumentException( "Value should be < 8192 chars", nameof( key ) );
return SteamMatchmaking.Internal != null && SteamMatchmaking.Internal.SetLobbyData( Id, key, value );
}
///
/// Removes a metadata key from the lobby.
///
public bool DeleteData( string key )
{
return SteamMatchmaking.Internal != null && SteamMatchmaking.Internal.DeleteLobbyData( Id, key );
}
///
/// Get all data for this lobby.
///
public IEnumerable> Data
{
get
{
var cnt = SteamMatchmaking.Internal?.GetLobbyDataCount( Id ) ?? 0;
for ( int i =0; i( a, b );
}
}
}
}
///
/// Gets per-user metadata for someone in this lobby.
///
public string? GetMemberData( Friend member, string key )
{
return SteamMatchmaking.Internal?.GetLobbyMemberData( Id, member.Id, key );
}
///
/// Sets per-user metadata (for the local user implicitly).
///
public void SetMemberData( string key, string value )
{
SteamMatchmaking.Internal?.SetLobbyMemberData( Id, key, value );
}
///
/// Sends a string to the chat room.
///
public bool SendChatString( string message )
{
//adding null terminator as it's used in Helpers.MemoryToString
var data = System.Text.Encoding.UTF8.GetBytes( message + '\0' );
return SendChatBytes( data );
}
///
/// Sends bytes to the chat room.
///
public unsafe bool SendChatBytes( byte[] data )
{
fixed ( byte* ptr = data )
{
return SendChatBytesUnsafe( ptr, data.Length );
}
}
///
/// Sends bytes to the chat room from an unsafe buffer.
///
public unsafe bool SendChatBytesUnsafe( byte* ptr, int length )
{
return SteamMatchmaking.Internal != null && SteamMatchmaking.Internal.SendLobbyChatMsg( Id, (IntPtr)ptr, length );
}
///
/// Refreshes metadata for a lobby you're not necessarily in right now.
///
/// You never do this for lobbies you're a member of, only if your
/// this will send down all the metadata associated with a lobby.
/// This is an asynchronous call.
/// Returns if the local user is not connected to the Steam servers.
/// Results will be returned by a LobbyDataUpdate_t callback.
/// If the specified lobby doesn't exist, LobbyDataUpdate_t::m_bSuccess will be set to .
///
///
public bool Refresh()
{
return SteamMatchmaking.Internal != null && SteamMatchmaking.Internal.RequestLobbyData( Id );
}
///
/// Max members able to join this lobby. Cannot be over 250.
/// Can only be set by the owner of the lobby.
///
public int MaxMembers
{
get => SteamMatchmaking.Internal?.GetLobbyMemberLimit( Id ) ?? 0;
set => SteamMatchmaking.Internal?.SetLobbyMemberLimit( Id, value );
}
///
/// Sets the lobby as public.
///
public bool SetPublic()
{
return SteamMatchmaking.Internal != null && SteamMatchmaking.Internal.SetLobbyType( Id, LobbyType.Public );
}
///
/// Sets the lobby as private.
///
public bool SetPrivate()
{
return SteamMatchmaking.Internal != null && SteamMatchmaking.Internal.SetLobbyType( Id, LobbyType.Private );
}
///
/// Sets the lobby as invisible.
///
public bool SetInvisible()
{
return SteamMatchmaking.Internal != null && SteamMatchmaking.Internal.SetLobbyType( Id, LobbyType.Invisible );
}
///
/// Sets the lobby as friends only.
///
public bool SetFriendsOnly()
{
return SteamMatchmaking.Internal != null && SteamMatchmaking.Internal.SetLobbyType( Id, LobbyType.FriendsOnly );
}
///
/// Set whether or not the lobby can be joined.
///
/// Whether or not the lobby can be joined.
public bool SetJoinable( bool b )
{
return SteamMatchmaking.Internal != null && SteamMatchmaking.Internal.SetLobbyJoinable( Id, b );
}
///
/// [SteamID variant]
/// Allows the owner to set the game server associated with the lobby. Triggers the
/// Steammatchmaking.OnLobbyGameCreated event.
///
public void SetGameServer( SteamId steamServer )
{
if ( !steamServer.IsValid )
throw new ArgumentException( $"SteamId for server is invalid" );
SteamMatchmaking.Internal?.SetLobbyGameServer( Id, 0, 0, steamServer );
}
///
/// [IP/Port variant]
/// Allows the owner to set the game server associated with the lobby. Triggers the
/// Steammatchmaking.OnLobbyGameCreated event.
///
public void SetGameServer( string ip, ushort port )
{
if ( !IPAddress.TryParse( ip, out IPAddress add ) )
throw new ArgumentException( $"IP address for server is invalid" );
SteamMatchmaking.Internal?.SetLobbyGameServer( Id, add.IpToInt32(), port, new SteamId() );
}
///
/// Gets the details of the lobby's game server, if set. Returns true if the lobby is
/// valid and has a server set, otherwise returns false.
///
public bool GetGameServer( ref uint ip, ref ushort port, ref SteamId serverId )
{
return SteamMatchmaking.Internal != null && SteamMatchmaking.Internal.GetLobbyGameServer( Id, ref ip, ref port, ref serverId );
}
///
/// Gets or sets the owner of the lobby. You must be the lobby owner to set the owner
///
public Friend Owner
{
get => new Friend( SteamMatchmaking.Internal?.GetLobbyOwner( Id ) ?? 0 );
set => SteamMatchmaking.Internal?.SetLobbyOwner( Id, value.Id );
}
///
/// Check if the specified SteamId owns the lobby.
///
public bool IsOwnedBy( SteamId k ) => Owner.Id == k;
}
}