-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathSteamPeer.cs
66 lines (53 loc) · 2.68 KB
/
SteamPeer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// This file is a 1:1 conversion from Tom Weilands Riptide Transport https://github.com/tom-weiland/RiptideSteamTransport/
using Steamworks;
using System;
using System.Runtime.InteropServices;
using Godot;
namespace Riptide.Transports.Steam
{
public abstract class SteamPeer
{
/// <summary>The name to use when logging messages via <see cref="Utils.RiptideLogger"/>.</summary>
public const string LogName = "STEAM";
protected const int MaxMessages = 256;
private readonly byte[] receiveBuffer;
protected SteamPeer()
{
receiveBuffer = new byte[Message.MaxSize + sizeof(ushort)];
}
protected void Receive(SteamConnection fromConnection)
{
IntPtr[] ptrs = new IntPtr[MaxMessages]; // TODO: remove allocation?
// TODO: consider using poll groups -> https://partner.steamgames.com/doc/api/ISteamNetworkingSockets#functions_poll_groups
int messageCount = SteamNetworkingSockets.ReceiveMessagesOnConnection(fromConnection.SteamNetConnection, ptrs, MaxMessages);
if (messageCount > 0)
{
for (int i = 0; i < messageCount; i++)
{
SteamNetworkingMessage_t data = Marshal.PtrToStructure<SteamNetworkingMessage_t>(ptrs[i]);
if (data.m_cbSize > 0)
{
int byteCount = data.m_cbSize;
if (data.m_cbSize > receiveBuffer.Length)
{
GD.Print($"{LogName}: Can't fully handle {data.m_cbSize} bytes because it exceeds the maximum of {receiveBuffer.Length}. Data will be incomplete!");
byteCount = receiveBuffer.Length;
}
Marshal.Copy(data.m_pData, receiveBuffer, 0, data.m_cbSize);
OnDataReceived(receiveBuffer, byteCount, fromConnection);
}
}
}
}
internal void Send(byte[] dataBuffer, int numBytes, HSteamNetConnection toConnection)
{
GCHandle handle = GCHandle.Alloc(dataBuffer, GCHandleType.Pinned);
IntPtr pDataBuffer = handle.AddrOfPinnedObject();
EResult result = SteamNetworkingSockets.SendMessageToConnection(toConnection, pDataBuffer, (uint)numBytes, Constants.k_nSteamNetworkingSend_Unreliable, out long _);
if (result != EResult.k_EResultOK)
GD.Print($"{LogName}: Failed to send {numBytes} bytes - {result}");
handle.Free();
}
protected abstract void OnDataReceived(byte[] dataBuffer, int amount, SteamConnection fromConnection);
}
}