您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
214 行
10 KiB
214 行
10 KiB
using AOT;
|
|
using Unity.Collections;
|
|
using Unity.Collections.LowLevel.Unsafe;
|
|
using Unity.Networking.Transport.Utilities;
|
|
using Unity.Burst;
|
|
|
|
namespace Unity.Networking.Transport
|
|
{
|
|
[BurstCompile]
|
|
public unsafe struct SimulatorPipelineStage : INetworkPipelineStage
|
|
{
|
|
static TransportFunctionPointer<NetworkPipelineStage.ReceiveDelegate> ReceiveFunctionPointer = new TransportFunctionPointer<NetworkPipelineStage.ReceiveDelegate>(Receive);
|
|
static TransportFunctionPointer<NetworkPipelineStage.SendDelegate> SendFunctionPointer = new TransportFunctionPointer<NetworkPipelineStage.SendDelegate>(Send);
|
|
static TransportFunctionPointer<NetworkPipelineStage.InitializeConnectionDelegate> InitializeConnectionFunctionPointer = new TransportFunctionPointer<NetworkPipelineStage.InitializeConnectionDelegate>(InitializeConnection);
|
|
public NetworkPipelineStage StaticInitialize(byte* staticInstanceBuffer, int staticInstanceBufferLength, INetworkParameter[] netParams)
|
|
{
|
|
SimulatorUtility.Parameters param = default;
|
|
foreach (var netParam in netParams)
|
|
{
|
|
if (netParam is SimulatorUtility.Parameters)
|
|
param = (SimulatorUtility.Parameters)netParam;
|
|
}
|
|
|
|
UnsafeUtility.MemCpy(staticInstanceBuffer, ¶m, UnsafeUtility.SizeOf<SimulatorUtility.Parameters>());
|
|
|
|
return new NetworkPipelineStage(
|
|
Receive: ReceiveFunctionPointer,
|
|
Send: SendFunctionPointer,
|
|
InitializeConnection: InitializeConnectionFunctionPointer,
|
|
ReceiveCapacity: param.MaxPacketCount * (param.MaxPacketSize+UnsafeUtility.SizeOf<SimulatorUtility.DelayedPacket>()),
|
|
SendCapacity: 0,
|
|
HeaderCapacity: 0,
|
|
SharedStateCapacity: UnsafeUtility.SizeOf<SimulatorUtility.Context>()
|
|
);
|
|
}
|
|
|
|
[BurstCompile(DisableDirectCall = true)]
|
|
[MonoPInvokeCallback(typeof(NetworkPipelineStage.InitializeConnectionDelegate))]
|
|
private static void InitializeConnection(byte* staticInstanceBuffer, int staticInstanceBufferLength,
|
|
byte* sendProcessBuffer, int sendProcessBufferLength, byte* recvProcessBuffer, int recvProcessBufferLength,
|
|
byte* sharedProcessBuffer, int sharedProcessBufferLength)
|
|
{
|
|
SimulatorUtility.Parameters param = default;
|
|
|
|
UnsafeUtility.MemCpy(¶m, staticInstanceBuffer, UnsafeUtility.SizeOf<SimulatorUtility.Parameters>());
|
|
if (sharedProcessBufferLength >= UnsafeUtility.SizeOf<SimulatorUtility.Parameters>())
|
|
{
|
|
SimulatorUtility.InitializeContext(param, sharedProcessBuffer);
|
|
}
|
|
}
|
|
|
|
[BurstCompile(DisableDirectCall = true)]
|
|
[MonoPInvokeCallback(typeof(NetworkPipelineStage.SendDelegate))]
|
|
private static int Send(ref NetworkPipelineContext ctx, ref InboundSendBuffer inboundBuffer, ref NetworkPipelineStage.Requests requests)
|
|
{
|
|
return (int)Error.StatusCode.Success;
|
|
}
|
|
|
|
[BurstCompile(DisableDirectCall = true)]
|
|
[MonoPInvokeCallback(typeof(NetworkPipelineStage.ReceiveDelegate))]
|
|
private static void Receive(ref NetworkPipelineContext ctx, ref InboundRecvBuffer inboundBuffer, ref NetworkPipelineStage.Requests requests)
|
|
{
|
|
var context = (SimulatorUtility.Context*) ctx.internalSharedProcessBuffer;
|
|
var param = *(SimulatorUtility.Parameters*) ctx.staticInstanceBuffer;
|
|
var simulator = new SimulatorUtility(param.MaxPacketCount, param.MaxPacketSize, param.PacketDelayMs, param.PacketJitterMs);
|
|
|
|
if (inboundBuffer.bufferLength > param.MaxPacketSize)
|
|
{
|
|
//UnityEngine.Debug.LogWarning("Incoming packet too large for internal storage buffer. Passing through. [buffer=" + inboundBuffer.Length + " packet=" + param->MaxPacketSize + "]");
|
|
// TODO: Add error code for this
|
|
return;
|
|
}
|
|
|
|
var timestamp = ctx.timestamp;
|
|
|
|
// Inbound buffer is empty if this is a resumed receive
|
|
if (inboundBuffer.bufferLength > 0)
|
|
{
|
|
context->PacketCount++;
|
|
|
|
if (simulator.ShouldDropPacket(context, param, timestamp))
|
|
{
|
|
context->PacketDropCount++;
|
|
inboundBuffer = default;
|
|
return;
|
|
}
|
|
|
|
var bufferVec = default(InboundSendBuffer);
|
|
bufferVec.bufferWithHeaders = inboundBuffer.buffer;
|
|
bufferVec.bufferWithHeadersLength = inboundBuffer.bufferLength;
|
|
bufferVec.buffer = inboundBuffer.buffer;
|
|
bufferVec.bufferLength = inboundBuffer.bufferLength;
|
|
bufferVec.headerPadding = 0;
|
|
if (context->PacketDelayMs == 0 ||
|
|
!simulator.DelayPacket(ref ctx, bufferVec, ref requests, timestamp))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
InboundSendBuffer returnPacket = default;
|
|
if (simulator.GetDelayedPacket(ref ctx, ref returnPacket, ref requests, timestamp))
|
|
{
|
|
inboundBuffer.buffer = returnPacket.bufferWithHeaders;
|
|
inboundBuffer.bufferLength = returnPacket.bufferWithHeadersLength;
|
|
return;
|
|
}
|
|
|
|
inboundBuffer = default;
|
|
}
|
|
public int StaticSize => UnsafeUtility.SizeOf<SimulatorUtility.Parameters>();
|
|
}
|
|
|
|
[BurstCompile]
|
|
public unsafe struct SimulatorPipelineStageInSend : INetworkPipelineStage
|
|
{
|
|
static TransportFunctionPointer<NetworkPipelineStage.ReceiveDelegate> ReceiveFunctionPointer = new TransportFunctionPointer<NetworkPipelineStage.ReceiveDelegate>(Receive);
|
|
static TransportFunctionPointer<NetworkPipelineStage.SendDelegate> SendFunctionPointer = new TransportFunctionPointer<NetworkPipelineStage.SendDelegate>(Send);
|
|
static TransportFunctionPointer<NetworkPipelineStage.InitializeConnectionDelegate> InitializeConnectionFunctionPointer = new TransportFunctionPointer<NetworkPipelineStage.InitializeConnectionDelegate>(InitializeConnection);
|
|
public NetworkPipelineStage StaticInitialize(byte* staticInstanceBuffer, int staticInstanceBufferLength, INetworkParameter[] netParams)
|
|
{
|
|
SimulatorUtility.Parameters param = default;
|
|
foreach (var netParam in netParams)
|
|
{
|
|
if (netParam is SimulatorUtility.Parameters parameters)
|
|
param = parameters;
|
|
}
|
|
|
|
UnsafeUtility.MemCpy(staticInstanceBuffer, ¶m, UnsafeUtility.SizeOf<SimulatorUtility.Parameters>());
|
|
|
|
return new NetworkPipelineStage(
|
|
Receive: ReceiveFunctionPointer,
|
|
Send: SendFunctionPointer,
|
|
InitializeConnection: InitializeConnectionFunctionPointer,
|
|
ReceiveCapacity: 0,
|
|
SendCapacity: param.MaxPacketCount * (param.MaxPacketSize+UnsafeUtility.SizeOf<SimulatorUtility.DelayedPacket>()),
|
|
HeaderCapacity: 0,
|
|
SharedStateCapacity: UnsafeUtility.SizeOf<SimulatorUtility.Context>()
|
|
);
|
|
}
|
|
|
|
[BurstCompile(DisableDirectCall = true)]
|
|
[MonoPInvokeCallback(typeof(NetworkPipelineStage.InitializeConnectionDelegate))]
|
|
private static void InitializeConnection(byte* staticInstanceBuffer, int staticInstanceBufferLength,
|
|
byte* sendProcessBuffer, int sendProcessBufferLength, byte* recvProcessBuffer, int recvProcessBufferLength,
|
|
byte* sharedProcessBuffer, int sharedProcessBufferLength)
|
|
{
|
|
SimulatorUtility.Parameters param = default;
|
|
|
|
UnsafeUtility.MemCpy(¶m, staticInstanceBuffer, UnsafeUtility.SizeOf<SimulatorUtility.Parameters>());
|
|
if (sharedProcessBufferLength >= UnsafeUtility.SizeOf<SimulatorUtility.Parameters>())
|
|
{
|
|
SimulatorUtility.InitializeContext(param, sharedProcessBuffer);
|
|
}
|
|
}
|
|
|
|
[BurstCompile(DisableDirectCall = true)]
|
|
[MonoPInvokeCallback(typeof(NetworkPipelineStage.SendDelegate))]
|
|
private static int Send(ref NetworkPipelineContext ctx, ref InboundSendBuffer inboundBuffer, ref NetworkPipelineStage.Requests requests)
|
|
{
|
|
var context = (SimulatorUtility.Context*) ctx.internalSharedProcessBuffer;
|
|
var param = *(SimulatorUtility.Parameters*) ctx.staticInstanceBuffer;
|
|
|
|
var simulator = new SimulatorUtility(param.MaxPacketCount, param.MaxPacketSize, param.PacketDelayMs, param.PacketJitterMs);
|
|
if (inboundBuffer.headerPadding+inboundBuffer.bufferLength > param.MaxPacketSize)
|
|
{
|
|
//UnityEngine.Debug.LogWarning("Incoming packet too large for internal storage buffer. Passing through. [buffer=" + (inboundBuffer.headerPadding+inboundBuffer.buffer.Length) + " packet=" + param.MaxPacketSize + "]");
|
|
return (int) Error.StatusCode.NetworkPacketOverflow;
|
|
}
|
|
|
|
var timestamp = ctx.timestamp;
|
|
|
|
if (inboundBuffer.bufferLength > 0)
|
|
{
|
|
context->PacketCount++;
|
|
|
|
if (simulator.ShouldDropPacket(context, param, timestamp))
|
|
{
|
|
context->PacketDropCount++;
|
|
inboundBuffer = default;
|
|
return (int)Error.StatusCode.Success;
|
|
}
|
|
|
|
if (context->FuzzFactor > 0)
|
|
{
|
|
simulator.FuzzPacket(context, ref inboundBuffer);
|
|
}
|
|
|
|
if (context->PacketDelayMs == 0 ||
|
|
!simulator.DelayPacket(ref ctx, inboundBuffer, ref requests, timestamp))
|
|
{
|
|
return (int)Error.StatusCode.Success;
|
|
}
|
|
}
|
|
|
|
InboundSendBuffer returnPacket = default;
|
|
if (simulator.GetDelayedPacket(ref ctx, ref returnPacket, ref requests, timestamp))
|
|
{
|
|
inboundBuffer = returnPacket;
|
|
return (int)Error.StatusCode.Success;
|
|
}
|
|
inboundBuffer = default;
|
|
return (int)Error.StatusCode.Success;
|
|
}
|
|
|
|
[BurstCompile(DisableDirectCall = true)]
|
|
[MonoPInvokeCallback(typeof(NetworkPipelineStage.ReceiveDelegate))]
|
|
private static void Receive(ref NetworkPipelineContext ctx, ref InboundRecvBuffer inboundBuffer,
|
|
ref NetworkPipelineStage.Requests requests)
|
|
{
|
|
}
|
|
public int StaticSize => UnsafeUtility.SizeOf<SimulatorUtility.Parameters>();
|
|
}
|
|
}
|