common auth interface

This commit is contained in:
William Wallace 2019-03-27 17:10:09 +00:00
parent 26a64f64e7
commit dfa04d1a70
9 changed files with 217 additions and 168 deletions

View File

@ -80,7 +80,7 @@ namespace Facepunch.Steamworks.Test
server.Auth.OnAuthChange = ( steamid, ownerid, status ) =>
{
Authed = status == ServerAuth.Status.OK;
Authed = status == Auth.AuthStatus.OK;
Assert.AreEqual( steamid, client.SteamId );
Assert.AreEqual( steamid, ownerid );
@ -101,10 +101,8 @@ namespace Facepunch.Steamworks.Test
}
GC.Collect();
if ( !server.Auth.StartSession( ticketBinary, client.SteamId ) )
{
Assert.Fail( "Start Session returned false" );
}
var startStatus = server.Auth.StartSession( ticketBinary, client.SteamId );
Assert.IsTrue( startStatus == Auth.StartAuthResult.OK );
GC.Collect();
//

View File

@ -16,6 +16,7 @@ namespace Facepunch.Steamworks
/// </summary>
public uint AppId { get; internal set; }
public Auth Auth { get; internal set; }
public Networking Networking { get; internal set; }
public Inventory Inventory { get; internal set; }
public Workshop Workshop { get; internal set; }

View File

@ -104,6 +104,7 @@ namespace Facepunch.Steamworks
//
// Client only interfaces
//
Auth = new ClientAuth( this );
Voice = new Voice( this );
ServerList = new ServerList( this );
LobbyList = new LobbyList(this);
@ -178,6 +179,11 @@ namespace Facepunch.Steamworks
{
if ( disposed ) return;
if ( Auth != null )
{
Auth = null;
}
if ( Voice != null )
{
Voice = null;

View File

@ -1,82 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Facepunch.Steamworks
{
public partial class Client : IDisposable
{
Auth _auth;
public Auth Auth
{
get
{
if ( _auth == null )
_auth = new Auth{ client = this };
return _auth;
}
}
}
public class Auth
{
internal Client client;
public class Ticket : IDisposable
{
internal Client client;
public byte[] Data;
public uint Handle;
/// <summary>
/// Cancels a ticket.
/// You should cancel your ticket when you close the game or leave a server.
/// </summary>
public void Cancel()
{
if ( client.IsValid && Handle != 0 )
{
client.native.user.CancelAuthTicket( Handle );
Handle = 0;
Data = null;
}
}
public void Dispose()
{
Cancel();
}
}
/// <summary>
/// Creates an auth ticket.
/// Which you can send to a server to authenticate that you are who you say you are.
/// </summary>
public unsafe Ticket GetAuthSessionTicket()
{
var data = new byte[1024];
fixed ( byte* b = data )
{
uint ticketLength = 0;
uint ticket = client.native.user.GetAuthSessionTicket( (IntPtr) b, data.Length, out ticketLength );
if ( ticket == 0 )
return null;
return new Ticket()
{
client = client,
Data = data.Take( (int)ticketLength ).ToArray(),
Handle = ticket
};
}
}
}
}

View File

@ -0,0 +1,55 @@
using System;
using System.Linq;
namespace Facepunch.Steamworks
{
internal class ClientAuth : Auth
{
private Client _client;
public ClientAuth( Client client )
{
_client = client;
_client.RegisterCallback<SteamNative.ValidateAuthTicketResponse_t>( OnAuthTicketValidate );
}
public unsafe override Ticket GetAuthSessionTicket()
{
var data = new byte[1024];
fixed ( byte* p = data )
{
uint ticketLength = 0;
uint ticket = _client.native.user.GetAuthSessionTicket( (IntPtr) p, data.Length, out ticketLength );
if ( ticket == 0 )
return null;
return new Ticket( this, ticket, data.Take( (int)ticketLength ).ToArray() );
}
}
public override void CancelAuthTicket( Ticket ticket )
{
_client.native.user.CancelAuthTicket( ticket.Handle );
}
public unsafe override StartAuthResult StartSession( byte[] data, ulong steamid )
{
fixed ( byte* p = data )
{
return (StartAuthResult) _client.native.user.BeginAuthSession( (IntPtr) p, data.Length, steamid );
}
}
public override void EndSession( ulong steamid )
{
_client.native.user.EndAuthSession( steamid );
}
public override void Dispose()
{
_client = null;
}
}
}

View File

@ -0,0 +1,91 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Facepunch.Steamworks
{
/// <summary>
/// Common authentication functionality for servers and clients
/// </summary>
public abstract class Auth : IDisposable
{
public enum StartAuthResult : int
{
OK = SteamNative.BeginAuthSessionResult.OK,
InvalidTicket = SteamNative.BeginAuthSessionResult.InvalidTicket,
DuplicateRequest = SteamNative.BeginAuthSessionResult.DuplicateRequest,
InvalidVersion = SteamNative.BeginAuthSessionResult.InvalidVersion,
GameMismatch = SteamNative.BeginAuthSessionResult.GameMismatch,
ExpiredTicket = SteamNative.BeginAuthSessionResult.ExpiredTicket
}
public enum AuthStatus : int
{
OK = SteamNative.AuthSessionResponse.OK,
UserNotConnectedToSteam = SteamNative.AuthSessionResponse.UserNotConnectedToSteam,
NoLicenseOrExpired = SteamNative.AuthSessionResponse.NoLicenseOrExpired,
VACBanned = SteamNative.AuthSessionResponse.VACBanned,
LoggedInElseWhere = SteamNative.AuthSessionResponse.LoggedInElseWhere,
VACCheckTimedOut = SteamNative.AuthSessionResponse.VACCheckTimedOut,
AuthTicketCanceled = SteamNative.AuthSessionResponse.AuthTicketCanceled,
AuthTicketInvalidAlreadyUsed = SteamNative.AuthSessionResponse.AuthTicketInvalidAlreadyUsed,
AuthTicketInvalid = SteamNative.AuthSessionResponse.AuthTicketInvalid,
PublisherIssuedBan = SteamNative.AuthSessionResponse.PublisherIssuedBan
}
/// <summary>
/// This is ran whenever the status of an ongoing session changes
/// SteamId, OwnerSteamId, Status
/// </summary>
public Action<ulong, ulong, AuthStatus> OnAuthChange;
internal void OnAuthTicketValidate( SteamNative.ValidateAuthTicketResponse_t data )
{
if ( OnAuthChange != null )
OnAuthChange( data.SteamID, data.OwnerSteamID, (AuthStatus) data.AuthSessionResponse );
}
/// <summary>
/// An auth ticket for the local client/server (never remote)
/// You should not cancel this ticket until you are disconnected from the remote user
/// </summary>
public class Ticket : IDisposable
{
private Auth _auth;
public uint Handle { get; }
public byte[] Data { get; }
public Ticket( Auth auth, uint handle, byte[] data )
{
_auth = auth;
Handle = handle;
Data = data;
}
public void Cancel()
{
_auth.CancelAuthTicket( this );
}
public void Dispose()
{
Cancel();
}
}
public abstract Ticket GetAuthSessionTicket();
public abstract void CancelAuthTicket( Ticket ticket );
/// <summary>
/// Start authorizing a ticket. This user isn't authorized yet. Wait for a call to OnAuthChange.
/// </summary>
public abstract StartAuthResult StartSession( byte[] data, ulong steamid );
/// <summary>
/// Forget this guy. They're no longer in the game.
/// </summary>
public abstract void EndSession( ulong steamid );
public abstract void Dispose();
}
}

View File

@ -19,7 +19,6 @@ namespace Facepunch.Steamworks
public ServerQuery Query { get; internal set; }
public ServerStats Stats { get; internal set; }
public ServerAuth Auth { get; internal set; }
/// <summary>
/// Initialize a Steam Server instance
@ -60,8 +59,6 @@ namespace Facepunch.Steamworks
//
SetupCommonInterfaces();
//
// Initial settings
//
@ -77,9 +74,9 @@ namespace Facepunch.Steamworks
//
// Child classes
//
Auth = new ServerAuth( this );
Query = new ServerQuery( this );
Stats = new ServerStats( this );
Auth = new ServerAuth( this );
//
// Run update, first call does some initialization
@ -267,6 +264,11 @@ namespace Facepunch.Steamworks
{
if ( disposed ) return;
if ( Auth != null )
{
Auth = null;
}
if ( Query != null )
{
Query = null;
@ -277,11 +279,6 @@ namespace Facepunch.Steamworks
Stats = null;
}
if ( Auth != null )
{
Auth = null;
}
if ( Instance == this )
{
Instance = null;

View File

@ -1,72 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Facepunch.Steamworks
{
public class ServerAuth
{
internal Server server;
/// <summary>
/// Steamid, Ownerid, Status
/// </summary>
public Action<ulong, ulong, Status> OnAuthChange;
/// <summary>
/// Steam authetication statuses
/// </summary>
public enum Status : int
{
OK = 0,
UserNotConnectedToSteam = 1,
NoLicenseOrExpired = 2,
VACBanned = 3,
LoggedInElseWhere = 4,
VACCheckTimedOut = 5,
AuthTicketCanceled = 6,
AuthTicketInvalidAlreadyUsed = 7,
AuthTicketInvalid = 8,
PublisherIssuedBan = 9,
}
internal ServerAuth( Server s )
{
server = s;
server.RegisterCallback<SteamNative.ValidateAuthTicketResponse_t>( OnAuthTicketValidate );
}
void OnAuthTicketValidate( SteamNative.ValidateAuthTicketResponse_t data )
{
if ( OnAuthChange != null )
OnAuthChange( data.SteamID, data.OwnerSteamID, (Status) data.AuthSessionResponse );
}
/// <summary>
/// Start authorizing a ticket. This user isn't authorized yet. Wait for a call to OnAuthChange.
/// </summary>
public unsafe bool StartSession( byte[] data, ulong steamid )
{
fixed ( byte* p = data )
{
var result = server.native.gameServer.BeginAuthSession( (IntPtr)p, data.Length, steamid );
if ( result == SteamNative.BeginAuthSessionResult.OK )
return true;
return false;
}
}
/// <summary>
/// Forget this guy. They're no longer in the game.
/// </summary>
public void EndSession( ulong steamid )
{
server.native.gameServer.EndAuthSession( steamid );
}
}
}

View File

@ -0,0 +1,55 @@
using System;
using System.Linq;
namespace Facepunch.Steamworks
{
internal class ServerAuth : Auth
{
private Server _server;
public ServerAuth( Server server )
{
_server = server;
_server.RegisterCallback<SteamNative.ValidateAuthTicketResponse_t>( OnAuthTicketValidate );
}
public unsafe override Ticket GetAuthSessionTicket()
{
var data = new byte[1024];
fixed ( byte* p = data )
{
uint ticketLength = 0;
uint ticket = _server.native.gameServer.GetAuthSessionTicket( (IntPtr) p, data.Length, out ticketLength );
if ( ticket == 0 )
return null;
return new Ticket( this, ticket, data.Take( (int)ticketLength ).ToArray() );
}
}
public override void CancelAuthTicket( Ticket ticket )
{
_server.native.gameServer.CancelAuthTicket( ticket.Handle );
}
public unsafe override StartAuthResult StartSession( byte[] data, ulong steamid )
{
fixed ( byte* p = data )
{
return (StartAuthResult) _server.native.gameServer.BeginAuthSession( (IntPtr) p, data.Length, steamid );
}
}
public override void EndSession( ulong steamid )
{
_server.native.gameServer.EndAuthSession( steamid );
}
public override void Dispose()
{
_server = null;
}
}
}