Characters
This commit is contained in:
114
Game/Scripts/Networking/SteamP2PTransport.cs
Normal file
114
Game/Scripts/Networking/SteamP2PTransport.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using Steamworks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MegaKoop.Game.Networking
|
||||
{
|
||||
/// <summary>
|
||||
/// Low level Steam P2P messaging helper. Prepends a byte message type header for easy routing.
|
||||
/// </summary>
|
||||
public class SteamP2PTransport : MonoBehaviour
|
||||
{
|
||||
public event Action<NetworkMessage> MessageReceived;
|
||||
|
||||
[SerializeField] private EP2PSend defaultSendType = EP2PSend.k_EP2PSendReliable;
|
||||
[SerializeField] private int listenChannel = 0;
|
||||
|
||||
private byte[] receiveBuffer = new byte[8192];
|
||||
private CSteamID activeLobby = CSteamID.Nil;
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!SteamBootstrap.IsInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PumpIncomingPackets();
|
||||
}
|
||||
|
||||
public void SetActiveLobby(CSteamID lobbyId)
|
||||
{
|
||||
activeLobby = lobbyId;
|
||||
}
|
||||
|
||||
public void Send(CSteamID recipient, NetworkMessageType type, byte[] payload, EP2PSend sendType = EP2PSend.k_EP2PSendReliable)
|
||||
{
|
||||
if (!SteamBootstrap.IsInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int payloadLength = payload != null ? payload.Length : 0;
|
||||
byte[] packet = new byte[payloadLength + 1];
|
||||
packet[0] = (byte)type;
|
||||
if (payloadLength > 0)
|
||||
{
|
||||
Buffer.BlockCopy(payload, 0, packet, 1, payloadLength);
|
||||
}
|
||||
|
||||
bool sent = SteamNetworking.SendP2PPacket(recipient, packet, (uint)packet.Length, sendType, listenChannel);
|
||||
if (!sent)
|
||||
{
|
||||
Debug.LogWarning("[SteamP2PTransport] Failed to send packet to " + recipient);
|
||||
}
|
||||
}
|
||||
|
||||
public void Broadcast(NetworkMessageType type, byte[] payload, EP2PSend sendType = EP2PSend.k_EP2PSendReliable)
|
||||
{
|
||||
if (activeLobby == CSteamID.Nil)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int members = SteamMatchmaking.GetNumLobbyMembers(activeLobby);
|
||||
CSteamID self = SteamUser.GetSteamID();
|
||||
|
||||
for (int i = 0; i < members; i++)
|
||||
{
|
||||
CSteamID member = SteamMatchmaking.GetLobbyMemberByIndex(activeLobby, i);
|
||||
if (member == self)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Send(member, type, payload, sendType);
|
||||
}
|
||||
}
|
||||
|
||||
private void PumpIncomingPackets()
|
||||
{
|
||||
while (SteamNetworking.IsP2PPacketAvailable(out uint packetSize, listenChannel))
|
||||
{
|
||||
if (packetSize == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (packetSize > receiveBuffer.Length)
|
||||
{
|
||||
receiveBuffer = new byte[(int)packetSize];
|
||||
}
|
||||
|
||||
if (SteamNetworking.ReadP2PPacket(receiveBuffer, (uint)receiveBuffer.Length, out uint bytesRead, out CSteamID remote, listenChannel))
|
||||
{
|
||||
SteamNetworking.AcceptP2PSessionWithUser(remote);
|
||||
|
||||
if (bytesRead == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
NetworkMessageType type = (NetworkMessageType)receiveBuffer[0];
|
||||
byte[] payload = new byte[Mathf.Max(0, (int)bytesRead - 1)];
|
||||
if (bytesRead > 1)
|
||||
{
|
||||
Buffer.BlockCopy(receiveBuffer, 1, payload, 0, (int)bytesRead - 1);
|
||||
}
|
||||
|
||||
MessageReceived?.Invoke(new NetworkMessage(type, payload, remote.m_SteamID));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user