Files
K-C-Multiplayer/RiptideSteamTransport/Transport/SteamPeer.cs
2025-12-14 21:08:19 +01:00

70 lines
2.9 KiB
C#

// This file is provided under The MIT License as part of RiptideSteamTransport.
// Copyright (c) Tom Weiland
// For additional information please see the included LICENSE.md file or view it on GitHub:
// https://github.com/tom-weiland/RiptideSteamTransport/blob/main/LICENSE.md
using Steamworks;
using System;
using System.Runtime.InteropServices;
using UnityEngine;
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)
{
Debug.LogWarning($"{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)
Debug.LogWarning($"{LogName}: Failed to send {numBytes} bytes - {result}");
handle.Free();
}
protected abstract void OnDataReceived(byte[] dataBuffer, int amount, SteamConnection fromConnection);
}
}