diff --git a/SteamTransport/Client.cs b/SteamTransport/Client.cs index 5144fac3..d490c29c 100644 --- a/SteamTransport/Client.cs +++ b/SteamTransport/Client.cs @@ -16,9 +16,9 @@ public class Client _onStatusChanged = Steamworks.Callback.Create(t => { - Console.WriteLine($"STATUS CHANGED for {t.m_info.m_szConnectionDescription}\n" + + _transport.Log($"STATUS CHANGED for {t.m_info.m_szConnectionDescription}\n" + $"state = {t.m_info.m_eState}\n" + - $"end = {(ESteamNetConnectionEnd)t.m_info.m_eEndReason} {t.m_info.m_szEndDebug}"); + $"end = {(ESteamNetConnectionEnd)t.m_info.m_eEndReason} {t.m_info.m_szEndDebug}\n"); switch (t.m_info.m_eState) { @@ -27,12 +27,15 @@ public class Client IsConnected = false; break; case ESteamNetworkingConnectionState.k_ESteamNetworkingConnectionState_Connected: + _transport.OnClientConnected?.Invoke(); IsConnecting = false; IsConnected = true; break; case ESteamNetworkingConnectionState.k_ESteamNetworkingConnectionState_ClosedByPeer: case ESteamNetworkingConnectionState.k_ESteamNetworkingConnectionState_ProblemDetectedLocally: - _transport.OnClientError(TransportError.ConnectionClosed, $"end = {(ESteamNetConnectionEnd)t.m_info.m_eEndReason} {t.m_info.m_szEndDebug}"); + _transport.OnClientError?.Invoke(TransportError.ConnectionClosed, t.m_info.m_szEndDebug); + SteamNetworkingSockets.CloseConnection(_conn, t.m_info.m_eEndReason, t.m_info.m_szEndDebug, false); + _transport.OnClientDisconnected?.Invoke(); IsConnecting = false; IsConnected = false; break; @@ -54,6 +57,7 @@ public class Client if (!parsed) { _transport.OnClientError(TransportError.DnsResolve, $"couldnt parse address {address} when connect"); + // should we call disconnect here? idk return; } @@ -63,10 +67,19 @@ public class Client public void Send(ArraySegment segment, int channelId) { - throw new NotImplementedException(); + var data = new byte[segment.Count]; + Array.Copy(segment.Array, segment.Offset, data, 0, data.Length); + unsafe + { + fixed (byte* pData = data) + { + var result = SteamNetworkingSockets.SendMessageToConnection(_conn, (IntPtr)pData, (uint)data.Length, Util.MirrorChannel2SendFlag(channelId), out _); + _transport.OnClientDataSent?.Invoke(segment, channelId); + } + } } - public void RecieveData() + public void Receive() { const int maxMessages = 10; var ppOutMessages = new IntPtr[maxMessages]; @@ -80,7 +93,7 @@ public class Client var data = new byte[msg.m_cbSize]; Marshal.Copy(msg.m_pData, data, 0, data.Length); var channel = Util.SendFlag2MirrorChannel(msg.m_nFlags); - _transport.OnClientDataReceived(new ArraySegment(data), channel); + _transport.OnClientDataReceived?.Invoke(new ArraySegment(data), channel); msg.Release(); } } @@ -88,12 +101,14 @@ public class Client public void Flush() { - SteamNetworkingSockets.FlushMessagesOnConnection(_conn); + var result = SteamNetworkingSockets.FlushMessagesOnConnection(_conn); } public void Close() { + _transport.Log("client close"); SteamNetworkingSockets.CloseConnection(_conn, 0, "client closed connection", false); + _transport.OnClientDisconnected?.Invoke(); _onStatusChanged.Dispose(); } diff --git a/SteamTransport/Server.cs b/SteamTransport/Server.cs index 6c8ba3d8..cbc81a6b 100644 --- a/SteamTransport/Server.cs +++ b/SteamTransport/Server.cs @@ -1,5 +1,8 @@ -using Steamworks; +using Mirror; +using Steamworks; using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; namespace SteamTransport; @@ -14,24 +17,26 @@ public class Server _onStatusChanged = Steamworks.Callback.Create(t => { - Console.WriteLine($"STATUS CHANGED for {t.m_info.m_szConnectionDescription}\n" + + _transport.Log($"STATUS CHANGED for {t.m_info.m_szConnectionDescription}\n" + $"state = {t.m_info.m_eState}\n" + - $"end = {(ESteamNetConnectionEnd)t.m_info.m_eEndReason} {t.m_info.m_szEndDebug}"); + $"end = {(ESteamNetConnectionEnd)t.m_info.m_eEndReason} {t.m_info.m_szEndDebug}\n"); switch (t.m_info.m_eState) { case ESteamNetworkingConnectionState.k_ESteamNetworkingConnectionState_Connecting: - SteamNetworkingSockets.GetConnectionInfo(t.m_hConn, out var pInfo); - pInfo.m_addrRemote.ToString(out var address, true); - _transport.Log($"accepting conn from {address}"); - // ignore max connections for now SteamNetworkingSockets.AcceptConnection(t.m_hConn); break; case ESteamNetworkingConnectionState.k_ESteamNetworkingConnectionState_Connected: + _conns.Add(t.m_hConn); + _transport.OnServerConnected?.Invoke((int)t.m_hConn.m_HSteamNetConnection); break; case ESteamNetworkingConnectionState.k_ESteamNetworkingConnectionState_ClosedByPeer: case ESteamNetworkingConnectionState.k_ESteamNetworkingConnectionState_ProblemDetectedLocally: + _transport.OnServerError?.Invoke((int)t.m_hConn.m_HSteamNetConnection, TransportError.ConnectionClosed, t.m_info.m_szEndDebug); + SteamNetworkingSockets.CloseConnection(t.m_hConn, t.m_info.m_eEndReason, t.m_info.m_szEndDebug, false); + _transport.OnServerDisconnected?.Invoke((int)t.m_hConn.m_HSteamNetConnection); + _conns.Remove(t.m_hConn); break; } }); @@ -39,6 +44,7 @@ public class Server public bool IsListening; private HSteamListenSocket _listenSocket; + private readonly List _conns = new(); public void StartListening() { @@ -50,18 +56,66 @@ public class Server IsListening = true; } - public void Send(int connectionId, ArraySegment segment, int channelId) { } + public void Send(int connectionId, ArraySegment segment, int channelId) + { + var conn = new HSteamNetConnection((uint)connectionId); - public void RecieveData() { } + var data = new byte[segment.Count]; + Array.Copy(segment.Array, segment.Offset, data, 0, data.Length); + unsafe + { + fixed (byte* pData = data) + { + var result = SteamNetworkingSockets.SendMessageToConnection(conn, (IntPtr)pData, (uint)data.Length, Util.MirrorChannel2SendFlag(channelId), out _); + _transport.OnServerDataSent?.Invoke(connectionId, segment, channelId); + } + } + } - public void Flush() { } + public void Receive() + { + const int maxMessages = 10; + var ppOutMessages = new IntPtr[maxMessages]; - public void Disconnect(int connectionId) { } + foreach (var conn in _conns) + { + var numMessages = SteamNetworkingSockets.ReceiveMessagesOnConnection(conn, ppOutMessages, maxMessages); + for (var i = 0; i < numMessages; i++) + { + var ppOutMessage = ppOutMessages[i]; + unsafe + { + var msg = *(SteamNetworkingMessage_t*)ppOutMessage; // probably not gonna work + var data = new byte[msg.m_cbSize]; + Marshal.Copy(msg.m_pData, data, 0, data.Length); + var channel = Util.SendFlag2MirrorChannel(msg.m_nFlags); + _transport.OnServerDataReceived((int)conn.m_HSteamNetConnection, new ArraySegment(data), channel); + msg.Release(); + } + } + } + } + + public void Flush() + { + foreach (var conn in _conns) + { + var result = SteamNetworkingSockets.FlushMessagesOnConnection(conn); + } + } + + public void Disconnect(int connectionId) + { + var conn = new HSteamNetConnection((uint)connectionId); + SteamNetworkingSockets.CloseConnection(conn, 0, "disconnected by server", false); + _conns.Remove(conn); + } public void Close() { - SteamNetworkingSockets.CloseListenSocket(_listenSocket); _transport.Log("stop server"); + SteamNetworkingSockets.CloseListenSocket(_listenSocket); + IsListening = false; _onStatusChanged.Dispose(); } diff --git a/SteamTransport/SteamTransport.cs b/SteamTransport/SteamTransport.cs index 7c29798a..07f15a00 100644 --- a/SteamTransport/SteamTransport.cs +++ b/SteamTransport/SteamTransport.cs @@ -13,6 +13,9 @@ public class SteamTransport : Transport private Server _server; private Client _client; + /// + /// logs will verbosely go here. must be set + /// public Action Log; /// /// use localhost port 1234 instead of steam p2p @@ -59,7 +62,7 @@ public class SteamTransport : Transport _server.Disconnect(connectionId); } - public override string ServerGetClientAddress(int connectionId) => throw new NotImplementedException(); + public override string ServerGetClientAddress(int connectionId) => throw new NotImplementedException("shouldnt be used"); public override void ServerStop() { @@ -84,12 +87,12 @@ public class SteamTransport : Transport public override void ClientEarlyUpdate() { - _client.RecieveData(); + _client.Receive(); } public override void ServerEarlyUpdate() { - _server.RecieveData(); + _server.Receive(); } public override void ClientLateUpdate() diff --git a/SteamTransport/Util.cs b/SteamTransport/Util.cs index 00b1c298..682e2dcf 100644 --- a/SteamTransport/Util.cs +++ b/SteamTransport/Util.cs @@ -19,4 +19,16 @@ public static class Util Channels.Unreliable => Constants.k_nSteamNetworkingSend_Unreliable, _ => throw new ArgumentOutOfRangeException(nameof(mirrorChannel), mirrorChannel, null) }; + + public static string CustomToString(this HSteamNetConnection conn) + { + SteamNetworkingSockets.GetConnectionInfo(conn, out var pInfo); + return pInfo.m_szConnectionDescription; + } + + public static string CustomToString(this SteamNetworkingIPAddr addr) + { + addr.ToString(out var s, true); + return s; + } }