Added interface versions of Connection/SocketManagers

This commit is contained in:
Garry Newman 2020-02-27 14:01:27 +00:00
parent 66b221984f
commit ebf77a8fde
6 changed files with 164 additions and 29 deletions

View File

@ -6,7 +6,21 @@ namespace Steamworks
{ {
public class ConnectionManager public class ConnectionManager
{ {
/// <summary>
/// An optional interface to use instead of deriving
/// </summary>
public IConnectionManager Interface { get; set; }
/// <summary>
/// The actual connection we're managing
/// </summary>
public Connection Connection; public Connection Connection;
/// <summary>
/// The last received ConnectionInfo
/// </summary>
public ConnectionInfo ConnectionInfo { get; internal set; }
public bool Connected = false; public bool Connected = false;
public bool Connecting = true; public bool Connecting = true;
@ -28,6 +42,8 @@ namespace Steamworks
public virtual void OnConnectionChanged( ConnectionInfo info ) public virtual void OnConnectionChanged( ConnectionInfo info )
{ {
ConnectionInfo = info;
switch ( info.State ) switch ( info.State )
{ {
case ConnectionState.Connecting: case ConnectionState.Connecting:
@ -49,6 +65,8 @@ namespace Steamworks
/// </summary> /// </summary>
public virtual void OnConnecting( ConnectionInfo info ) public virtual void OnConnecting( ConnectionInfo info )
{ {
Interface?.OnConnecting( info );
Connecting = true; Connecting = true;
} }
@ -57,6 +75,8 @@ namespace Steamworks
/// </summary> /// </summary>
public virtual void OnConnected( ConnectionInfo info ) public virtual void OnConnected( ConnectionInfo info )
{ {
Interface?.OnConnected( info );
Connected = true; Connected = true;
Connecting = false; Connecting = false;
} }
@ -66,6 +86,8 @@ namespace Steamworks
/// </summary> /// </summary>
public virtual void OnDisconnected( ConnectionInfo info ) public virtual void OnDisconnected( ConnectionInfo info )
{ {
Interface?.OnDisconnected( info );
Connected = false; Connected = false;
Connecting = false; Connecting = false;
} }
@ -114,7 +136,7 @@ namespace Steamworks
public virtual void OnMessage( IntPtr data, int size, long messageNum, long recvTime, int channel ) public virtual void OnMessage( IntPtr data, int size, long messageNum, long recvTime, int channel )
{ {
Interface?.OnMessage( data, size, messageNum, recvTime, channel );
} }
} }
} }

View File

@ -0,0 +1,28 @@
using System;
using Steamworks.Data;
namespace Steamworks
{
public interface IConnectionManager
{
/// <summary>
/// We started connecting to this guy
/// </summary>
void OnConnecting( ConnectionInfo info );
/// <summary>
/// Called when the connection is fully connected and can start being communicated with
/// </summary>
void OnConnected( ConnectionInfo info );
/// <summary>
/// We got disconnected
/// </summary>
void OnDisconnected( ConnectionInfo info );
/// <summary>
/// Received a message
/// </summary>
void OnMessage( IntPtr data, int size, long messageNum, long recvTime, int channel );
}
}

View File

@ -0,0 +1,28 @@
using System;
using Steamworks.Data;
namespace Steamworks
{
public interface ISocketManager
{
/// <summary>
/// Must call Accept or Close on the connection within a second or so
/// </summary>
void OnConnecting( Connection connection, ConnectionInfo info );
/// <summary>
/// Called when the connection is fully connected and can start being communicated with
/// </summary>
void OnConnected( Connection connection, ConnectionInfo info );
/// <summary>
/// Called when the connection leaves
/// </summary>
void OnDisconnected( Connection connection, ConnectionInfo info );
/// <summary>
/// Received a message from a connection
/// </summary>
void OnMessage( Connection connection, NetIdentity identity, IntPtr data, int size, long messageNum, long recvTime, int channel );
}
}

View File

@ -20,10 +20,10 @@ namespace Steamworks.Data
return SteamNetworkingSockets.Internal.CloseListenSocket( Id ); return SteamNetworkingSockets.Internal.CloseListenSocket( Id );
} }
public SocketManager Interface public SocketManager Manager
{ {
get => SteamNetworkingSockets.GetSocketInterface( Id ); get => SteamNetworkingSockets.GetSocketManager( Id );
set => SteamNetworkingSockets.SetSocketInterface( Id, value ); set => SteamNetworkingSockets.SetSocketManager( Id, value );
} }
} }
} }

View File

@ -12,8 +12,10 @@ namespace Steamworks
/// You can override all the virtual functions to turn it into what you /// You can override all the virtual functions to turn it into what you
/// want it to do. /// want it to do.
/// </summary> /// </summary>
public class SocketManager public partial class SocketManager
{ {
public ISocketManager Interface { get; set; }
public List<Connection> Connecting = new List<Connection>(); public List<Connection> Connecting = new List<Connection>();
public List<Connection> Connected = new List<Connection>(); public List<Connection> Connected = new List<Connection>();
public Socket Socket { get; internal set; } public Socket Socket { get; internal set; }
@ -47,12 +49,16 @@ namespace Steamworks
case ConnectionState.Connecting: case ConnectionState.Connecting:
if ( !Connecting.Contains( connection ) ) if ( !Connecting.Contains( connection ) )
{ {
Connecting.Add( connection );
OnConnecting( connection, info ); OnConnecting( connection, info );
} }
break; break;
case ConnectionState.Connected: case ConnectionState.Connected:
if ( !Connected.Contains( connection ) ) if ( !Connected.Contains( connection ) )
{ {
Connecting.Remove( connection );
Connected.Add( connection );
OnConnected( connection, info ); OnConnected( connection, info );
} }
break; break;
@ -71,9 +77,16 @@ namespace Steamworks
/// Default behaviour is to accept every connection /// Default behaviour is to accept every connection
/// </summary> /// </summary>
public virtual void OnConnecting( Connection connection, ConnectionInfo info ) public virtual void OnConnecting( Connection connection, ConnectionInfo info )
{
if ( Interface != null )
{
Interface.OnConnecting( connection, info );
return;
}
else
{ {
connection.Accept(); connection.Accept();
Connecting.Add( connection ); }
} }
/// <summary> /// <summary>
@ -81,9 +94,9 @@ namespace Steamworks
/// </summary> /// </summary>
public virtual void OnConnected( Connection connection, ConnectionInfo info ) public virtual void OnConnected( Connection connection, ConnectionInfo info )
{ {
Connecting.Remove( connection );
Connected.Add( connection );
SteamNetworkingSockets.Internal.SetConnectionPollGroup( connection, pollGroup ); SteamNetworkingSockets.Internal.SetConnectionPollGroup( connection, pollGroup );
Interface?.OnConnected( connection, info );
} }
/// <summary> /// <summary>
@ -97,6 +110,8 @@ namespace Steamworks
Connecting.Remove( connection ); Connecting.Remove( connection );
Connected.Remove( connection ); Connected.Remove( connection );
Interface?.OnDisconnected( connection, info );
} }
public void Receive( int bufferSize = 32 ) public void Receive( int bufferSize = 32 )
@ -144,7 +159,7 @@ namespace Steamworks
public virtual void OnMessage( Connection connection, NetIdentity identity, IntPtr data, int size, long messageNum, long recvTime, int channel ) public virtual void OnMessage( Connection connection, NetIdentity identity, IntPtr data, int size, long messageNum, long recvTime, int channel )
{ {
Interface?.OnMessage( connection, identity, data, size, messageNum, recvTime, channel );
} }
} }
} }

View File

@ -15,18 +15,14 @@ namespace Steamworks
internal override void InitializeInterface( bool server ) internal override void InitializeInterface( bool server )
{ {
SetInterface( server, new ISteamNetworkingSockets( server ) ); SetInterface( server, new ISteamNetworkingSockets( server ) );
SocketInterfaces = new Dictionary<uint, SocketManager>();
ConnectionInterfaces = new Dictionary<uint, ConnectionManager>();
InstallEvents( server ); InstallEvents( server );
} }
#region SocketInterface #region SocketInterface
static Dictionary<uint, SocketManager> SocketInterfaces; static readonly Dictionary<uint, SocketManager> SocketInterfaces = new Dictionary<uint, SocketManager>();
internal static SocketManager GetSocketInterface( uint id ) internal static SocketManager GetSocketManager( uint id )
{ {
if ( SocketInterfaces == null ) return null; if ( SocketInterfaces == null ) return null;
if ( id == 0 ) throw new System.ArgumentException( "Invalid Socket" ); if ( id == 0 ) throw new System.ArgumentException( "Invalid Socket" );
@ -37,18 +33,17 @@ namespace Steamworks
return null; return null;
} }
internal static void SetSocketInterface( uint id, SocketManager iface ) internal static void SetSocketManager( uint id, SocketManager manager )
{ {
if ( id == 0 ) throw new System.ArgumentException( "Invalid Socket" ); if ( id == 0 ) throw new System.ArgumentException( "Invalid Socket" );
SocketInterfaces[id] = iface; SocketInterfaces[id] = manager;
} }
#endregion #endregion
#region ConnectionInterface #region ConnectionInterface
static Dictionary<uint, ConnectionManager> ConnectionInterfaces; static readonly Dictionary<uint, ConnectionManager> ConnectionInterfaces = new Dictionary<uint, ConnectionManager>();
internal static ConnectionManager GetConnectionManager( uint id )
internal static ConnectionManager GetConnectionInterface( uint id )
{ {
if ( ConnectionInterfaces == null ) return null; if ( ConnectionInterfaces == null ) return null;
if ( id == 0 ) return null; if ( id == 0 ) return null;
@ -59,10 +54,10 @@ namespace Steamworks
return null; return null;
} }
internal static void SetConnectionInterface( uint id, ConnectionManager iface ) internal static void SetConnectionManager( uint id, ConnectionManager manager )
{ {
if ( id == 0 ) throw new System.ArgumentException( "Invalid Connection" ); if ( id == 0 ) throw new System.ArgumentException( "Invalid Connection" );
ConnectionInterfaces[id] = iface; ConnectionInterfaces[id] = manager;
} }
#endregion #endregion
@ -81,12 +76,12 @@ namespace Steamworks
// //
if ( data.Nfo.listenSocket.Id > 0 ) if ( data.Nfo.listenSocket.Id > 0 )
{ {
var iface = GetSocketInterface( data.Nfo.listenSocket.Id ); var iface = GetSocketManager( data.Nfo.listenSocket.Id );
iface?.OnConnectionChanged( data.Conn, data.Nfo ); iface?.OnConnectionChanged( data.Conn, data.Nfo );
} }
else else
{ {
var iface = GetConnectionInterface( data.Conn.Id ); var iface = GetConnectionManager( data.Conn.Id );
iface?.OnConnectionChanged( data.Nfo ); iface?.OnConnectionChanged( data.Nfo );
} }
@ -99,6 +94,9 @@ namespace Steamworks
/// <summary> /// <summary>
/// Creates a "server" socket that listens for clients to connect to by calling /// Creates a "server" socket that listens for clients to connect to by calling
/// Connect, over ordinary UDP (IPv4 or IPv6) /// Connect, over ordinary UDP (IPv4 or IPv6)
///
/// To use this derive a class from SocketManager and override as much as you want.
///
/// </summary> /// </summary>
public static T CreateNormalSocket<T>( NetAddress address ) where T : SocketManager, new() public static T CreateNormalSocket<T>( NetAddress address ) where T : SocketManager, new()
{ {
@ -107,7 +105,33 @@ namespace Steamworks
t.Socket = Internal.CreateListenSocketIP( ref address, options.Length, options ); t.Socket = Internal.CreateListenSocketIP( ref address, options.Length, options );
t.Initialize(); t.Initialize();
SetSocketInterface( t.Socket.Id, t ); SetSocketManager( t.Socket.Id, t );
return t;
}
/// <summary>
/// Creates a "server" socket that listens for clients to connect to by calling
/// Connect, over ordinary UDP (IPv4 or IPv6).
///
/// To use this you should pass a class that inherits ISocketManager. You can use
/// SocketManager to get connections and send messages, but the ISocketManager class
/// will received all the appropriate callbacks.
///
/// </summary>
public static SocketManager CreateNormalSocket( NetAddress address, ISocketManager intrface )
{
var options = Array.Empty<NetKeyValue>();
var socket = Internal.CreateListenSocketIP( ref address, options.Length, options );
var t = new SocketManager
{
Socket = socket,
Interface = intrface
};
t.Initialize();
SetSocketManager( t.Socket.Id, t );
return t; return t;
} }
@ -119,7 +143,25 @@ namespace Steamworks
var t = new T(); var t = new T();
var options = Array.Empty<NetKeyValue>(); var options = Array.Empty<NetKeyValue>();
t.Connection = Internal.ConnectByIPAddress( ref address, options.Length, options ); t.Connection = Internal.ConnectByIPAddress( ref address, options.Length, options );
SetConnectionInterface( t.Connection.Id, t ); SetConnectionManager( t.Connection.Id, t );
return t;
}
/// <summary>
/// Connect to a socket created via <method>CreateListenSocketIP</method>
/// </summary>
public static ConnectionManager ConnectNormal( NetAddress address, IConnectionManager iface )
{
var options = Array.Empty<NetKeyValue>();
var connection = Internal.ConnectByIPAddress( ref address, options.Length, options );
var t = new ConnectionManager
{
Connection = connection,
Interface = iface
};
SetConnectionManager( t.Connection.Id, t );
return t; return t;
} }
@ -131,8 +173,8 @@ namespace Steamworks
var t = new T(); var t = new T();
var options = Array.Empty<NetKeyValue>(); var options = Array.Empty<NetKeyValue>();
t.Socket = Internal.CreateListenSocketP2P( virtualport, options.Length, options ); t.Socket = Internal.CreateListenSocketP2P( virtualport, options.Length, options );
SetSocketInterface( t.Socket.Id, t );
t.Initialize(); t.Initialize();
SetSocketManager( t.Socket.Id, t );
return t; return t;
} }
@ -145,7 +187,7 @@ namespace Steamworks
NetIdentity identity = serverId; NetIdentity identity = serverId;
var options = Array.Empty<NetKeyValue>(); var options = Array.Empty<NetKeyValue>();
t.Connection = Internal.ConnectP2P( ref identity, virtualport, options.Length, options ); t.Connection = Internal.ConnectP2P( ref identity, virtualport, options.Length, options );
SetConnectionInterface( t.Connection.Id, t ); SetConnectionManager( t.Connection.Id, t );
return t; return t;
} }
} }