diff --git a/Facepunch.Steamworks/Networking/ConnectionManager.cs b/Facepunch.Steamworks/Networking/ConnectionManager.cs index e2f024f..2007cc7 100644 --- a/Facepunch.Steamworks/Networking/ConnectionManager.cs +++ b/Facepunch.Steamworks/Networking/ConnectionManager.cs @@ -6,7 +6,21 @@ namespace Steamworks { public class ConnectionManager { + /// + /// An optional interface to use instead of deriving + /// + public IConnectionManager Interface { get; set; } + + /// + /// The actual connection we're managing + /// public Connection Connection; + + /// + /// The last received ConnectionInfo + /// + public ConnectionInfo ConnectionInfo { get; internal set; } + public bool Connected = false; public bool Connecting = true; @@ -28,6 +42,8 @@ namespace Steamworks public virtual void OnConnectionChanged( ConnectionInfo info ) { + ConnectionInfo = info; + switch ( info.State ) { case ConnectionState.Connecting: @@ -49,6 +65,8 @@ namespace Steamworks /// public virtual void OnConnecting( ConnectionInfo info ) { + Interface?.OnConnecting( info ); + Connecting = true; } @@ -57,6 +75,8 @@ namespace Steamworks /// public virtual void OnConnected( ConnectionInfo info ) { + Interface?.OnConnected( info ); + Connected = true; Connecting = false; } @@ -66,6 +86,8 @@ namespace Steamworks /// public virtual void OnDisconnected( ConnectionInfo info ) { + Interface?.OnDisconnected( info ); + Connected = false; Connecting = false; } @@ -114,7 +136,7 @@ namespace Steamworks public virtual void OnMessage( IntPtr data, int size, long messageNum, long recvTime, int channel ) { - + Interface?.OnMessage( data, size, messageNum, recvTime, channel ); } } } \ No newline at end of file diff --git a/Facepunch.Steamworks/Networking/IConnectionManager.cs b/Facepunch.Steamworks/Networking/IConnectionManager.cs new file mode 100644 index 0000000..b94af7a --- /dev/null +++ b/Facepunch.Steamworks/Networking/IConnectionManager.cs @@ -0,0 +1,28 @@ +using System; +using Steamworks.Data; + +namespace Steamworks +{ + public interface IConnectionManager + { + /// + /// We started connecting to this guy + /// + void OnConnecting( ConnectionInfo info ); + + /// + /// Called when the connection is fully connected and can start being communicated with + /// + void OnConnected( ConnectionInfo info ); + + /// + /// We got disconnected + /// + void OnDisconnected( ConnectionInfo info ); + + /// + /// Received a message + /// + void OnMessage( IntPtr data, int size, long messageNum, long recvTime, int channel ); + } +} \ No newline at end of file diff --git a/Facepunch.Steamworks/Networking/ISocketManager.cs b/Facepunch.Steamworks/Networking/ISocketManager.cs new file mode 100644 index 0000000..faab31d --- /dev/null +++ b/Facepunch.Steamworks/Networking/ISocketManager.cs @@ -0,0 +1,28 @@ +using System; +using Steamworks.Data; + +namespace Steamworks +{ + public interface ISocketManager + { + /// + /// Must call Accept or Close on the connection within a second or so + /// + void OnConnecting( Connection connection, ConnectionInfo info ); + + /// + /// Called when the connection is fully connected and can start being communicated with + /// + void OnConnected( Connection connection, ConnectionInfo info ); + + /// + /// Called when the connection leaves + /// + void OnDisconnected( Connection connection, ConnectionInfo info ); + + /// + /// Received a message from a connection + /// + void OnMessage( Connection connection, NetIdentity identity, IntPtr data, int size, long messageNum, long recvTime, int channel ); + } +} \ No newline at end of file diff --git a/Facepunch.Steamworks/Networking/Socket.cs b/Facepunch.Steamworks/Networking/Socket.cs index 21e5695..334f589 100644 --- a/Facepunch.Steamworks/Networking/Socket.cs +++ b/Facepunch.Steamworks/Networking/Socket.cs @@ -20,10 +20,10 @@ namespace Steamworks.Data return SteamNetworkingSockets.Internal.CloseListenSocket( Id ); } - public SocketManager Interface + public SocketManager Manager { - get => SteamNetworkingSockets.GetSocketInterface( Id ); - set => SteamNetworkingSockets.SetSocketInterface( Id, value ); + get => SteamNetworkingSockets.GetSocketManager( Id ); + set => SteamNetworkingSockets.SetSocketManager( Id, value ); } } } \ No newline at end of file diff --git a/Facepunch.Steamworks/Networking/SocketManager.cs b/Facepunch.Steamworks/Networking/SocketManager.cs index ff7addd..5c585fa 100644 --- a/Facepunch.Steamworks/Networking/SocketManager.cs +++ b/Facepunch.Steamworks/Networking/SocketManager.cs @@ -12,8 +12,10 @@ namespace Steamworks /// You can override all the virtual functions to turn it into what you /// want it to do. /// - public class SocketManager + public partial class SocketManager { + public ISocketManager Interface { get; set; } + public List Connecting = new List(); public List Connected = new List(); public Socket Socket { get; internal set; } @@ -47,12 +49,16 @@ namespace Steamworks case ConnectionState.Connecting: if ( !Connecting.Contains( connection ) ) { + Connecting.Add( connection ); OnConnecting( connection, info ); } break; case ConnectionState.Connected: if ( !Connected.Contains( connection ) ) { + Connecting.Remove( connection ); + Connected.Add( connection ); + OnConnected( connection, info ); } break; @@ -72,8 +78,15 @@ namespace Steamworks /// public virtual void OnConnecting( Connection connection, ConnectionInfo info ) { - connection.Accept(); - Connecting.Add( connection ); + if ( Interface != null ) + { + Interface.OnConnecting( connection, info ); + return; + } + else + { + connection.Accept(); + } } /// @@ -81,9 +94,9 @@ namespace Steamworks /// public virtual void OnConnected( Connection connection, ConnectionInfo info ) { - Connecting.Remove( connection ); - Connected.Add( connection ); SteamNetworkingSockets.Internal.SetConnectionPollGroup( connection, pollGroup ); + + Interface?.OnConnected( connection, info ); } /// @@ -97,6 +110,8 @@ namespace Steamworks Connecting.Remove( connection ); Connected.Remove( connection ); + + Interface?.OnDisconnected( connection, info ); } 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 ) { - + Interface?.OnMessage( connection, identity, data, size, messageNum, recvTime, channel ); } } } \ No newline at end of file diff --git a/Facepunch.Steamworks/SteamNetworkingSockets.cs b/Facepunch.Steamworks/SteamNetworkingSockets.cs index 83b7a7f..1891309 100644 --- a/Facepunch.Steamworks/SteamNetworkingSockets.cs +++ b/Facepunch.Steamworks/SteamNetworkingSockets.cs @@ -15,18 +15,14 @@ namespace Steamworks internal override void InitializeInterface( bool server ) { SetInterface( server, new ISteamNetworkingSockets( server ) ); - - SocketInterfaces = new Dictionary(); - ConnectionInterfaces = new Dictionary(); - InstallEvents( server ); } #region SocketInterface - static Dictionary SocketInterfaces; + static readonly Dictionary SocketInterfaces = new Dictionary(); - internal static SocketManager GetSocketInterface( uint id ) + internal static SocketManager GetSocketManager( uint id ) { if ( SocketInterfaces == null ) return null; if ( id == 0 ) throw new System.ArgumentException( "Invalid Socket" ); @@ -37,18 +33,17 @@ namespace Steamworks 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" ); - SocketInterfaces[id] = iface; + SocketInterfaces[id] = manager; } #endregion #region ConnectionInterface - static Dictionary ConnectionInterfaces; + static readonly Dictionary ConnectionInterfaces = new Dictionary(); - - internal static ConnectionManager GetConnectionInterface( uint id ) + internal static ConnectionManager GetConnectionManager( uint id ) { if ( ConnectionInterfaces == null ) return null; if ( id == 0 ) return null; @@ -59,10 +54,10 @@ namespace Steamworks 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" ); - ConnectionInterfaces[id] = iface; + ConnectionInterfaces[id] = manager; } #endregion @@ -81,12 +76,12 @@ namespace Steamworks // 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 ); } else { - var iface = GetConnectionInterface( data.Conn.Id ); + var iface = GetConnectionManager( data.Conn.Id ); iface?.OnConnectionChanged( data.Nfo ); } @@ -99,6 +94,9 @@ namespace Steamworks /// /// Creates a "server" socket that listens for clients to connect to by calling /// Connect, over ordinary UDP (IPv4 or IPv6) + /// + /// To use this derive a class from SocketManager and override as much as you want. + /// /// public static T CreateNormalSocket( NetAddress address ) where T : SocketManager, new() { @@ -107,7 +105,33 @@ namespace Steamworks t.Socket = Internal.CreateListenSocketIP( ref address, options.Length, options ); t.Initialize(); - SetSocketInterface( t.Socket.Id, t ); + SetSocketManager( t.Socket.Id, t ); + return t; + } + + /// + /// 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. + /// + /// + public static SocketManager CreateNormalSocket( NetAddress address, ISocketManager intrface ) + { + var options = Array.Empty(); + 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; } @@ -119,7 +143,25 @@ namespace Steamworks var t = new T(); var options = Array.Empty(); t.Connection = Internal.ConnectByIPAddress( ref address, options.Length, options ); - SetConnectionInterface( t.Connection.Id, t ); + SetConnectionManager( t.Connection.Id, t ); + return t; + } + + /// + /// Connect to a socket created via CreateListenSocketIP + /// + public static ConnectionManager ConnectNormal( NetAddress address, IConnectionManager iface ) + { + var options = Array.Empty(); + var connection = Internal.ConnectByIPAddress( ref address, options.Length, options ); + + var t = new ConnectionManager + { + Connection = connection, + Interface = iface + }; + + SetConnectionManager( t.Connection.Id, t ); return t; } @@ -131,8 +173,8 @@ namespace Steamworks var t = new T(); var options = Array.Empty(); t.Socket = Internal.CreateListenSocketP2P( virtualport, options.Length, options ); - SetSocketInterface( t.Socket.Id, t ); t.Initialize(); + SetSocketManager( t.Socket.Id, t ); return t; } @@ -145,7 +187,7 @@ namespace Steamworks NetIdentity identity = serverId; var options = Array.Empty(); t.Connection = Internal.ConnectP2P( ref identity, virtualport, options.Length, options ); - SetConnectionInterface( t.Connection.Id, t ); + SetConnectionManager( t.Connection.Id, t ); return t; } }