Better packet reuse
This commit is contained in:
@ -10,7 +10,20 @@ namespace RageCoop.Client
|
||||
{
|
||||
internal static partial class Networking
|
||||
{
|
||||
private static PacketPool PacketPool=new PacketPool();
|
||||
|
||||
/// <summary>
|
||||
/// Reduce GC pressure by reusing frequently used packets
|
||||
/// </summary>
|
||||
static class ReceivedPackets
|
||||
{
|
||||
public static Packets.PedSync PedPacket = new Packets.PedSync();
|
||||
public static Packets.VehicleSync VehicelPacket = new Packets.VehicleSync();
|
||||
public static Packets.ProjectileSync ProjectilePacket = new Packets.ProjectileSync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to reslove entity handle in a <see cref="Packets.CustomEvent"/>
|
||||
/// </summary>
|
||||
private static readonly Func<byte, BitReader, object> _resolveHandle = (t, reader) =>
|
||||
{
|
||||
switch (t)
|
||||
@ -201,7 +214,6 @@ namespace RageCoop.Client
|
||||
|
||||
Peer.Recycle(message);
|
||||
}
|
||||
static Packet packet;
|
||||
private static void HandlePacket(PacketType packetType, byte[] data, NetConnection senderConnection)
|
||||
{
|
||||
|
||||
@ -224,18 +236,17 @@ namespace RageCoop.Client
|
||||
break;
|
||||
|
||||
case PacketType.VehicleSync:
|
||||
packet = data.GetPacket<Packets.VehicleSync>(PacketPool);
|
||||
VehicleSync((Packets.VehicleSync)packet);
|
||||
PacketPool.Recycle((Packets.VehicleSync)packet);
|
||||
ReceivedPackets.VehicelPacket.Deserialize(data);
|
||||
VehicleSync(ReceivedPackets.VehicelPacket);
|
||||
break;
|
||||
|
||||
case PacketType.PedSync:
|
||||
packet = data.GetPacket<Packets.PedSync>(PacketPool);
|
||||
PedSync((Packets.PedSync)packet);
|
||||
PacketPool.Recycle((Packets.PedSync)packet);
|
||||
ReceivedPackets.PedPacket.Deserialize(data);
|
||||
PedSync(ReceivedPackets.PedPacket);
|
||||
break;
|
||||
case PacketType.ProjectileSync:
|
||||
ProjectileSync(data.GetPacket<Packets.ProjectileSync>());
|
||||
ReceivedPackets.ProjectilePacket.Deserialize(data);
|
||||
ProjectileSync(ReceivedPackets.ProjectilePacket);
|
||||
break;
|
||||
|
||||
case PacketType.ChatMessage:
|
||||
|
@ -10,7 +10,15 @@ namespace RageCoop.Client
|
||||
{
|
||||
internal static partial class Networking
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Reduce GC pressure by reusing frequently used packets
|
||||
/// </summary>
|
||||
static class SendPackets
|
||||
{
|
||||
public static Packets.PedSync PedPacket = new Packets.PedSync();
|
||||
public static Packets.VehicleSync VehicelPacket = new Packets.VehicleSync();
|
||||
public static Packets.ProjectileSync ProjectilePacket = new Packets.ProjectileSync();
|
||||
}
|
||||
public static int SyncInterval = 30;
|
||||
public static List<NetConnection> Targets = new List<NetConnection>();
|
||||
public static void SendSync(Packet p, ConnectionChannel channel = ConnectionChannel.Default, NetDeliveryMethod method = NetDeliveryMethod.UnreliableSequenced)
|
||||
@ -25,17 +33,15 @@ namespace RageCoop.Client
|
||||
return;
|
||||
}
|
||||
Ped p = c.MainPed;
|
||||
var packet = new Packets.PedSync()
|
||||
{
|
||||
ID =c.ID,
|
||||
OwnerID=c.OwnerID,
|
||||
Health = p.Health,
|
||||
Rotation = p.ReadRotation(),
|
||||
Velocity = p.ReadVelocity(),
|
||||
Speed = p.GetPedSpeed(),
|
||||
Flags = p.GetPedFlags(),
|
||||
Heading=p.Heading,
|
||||
};
|
||||
var packet = SendPackets.PedPacket;
|
||||
packet.ID =c.ID;
|
||||
packet.OwnerID=c.OwnerID;
|
||||
packet.Health = p.Health;
|
||||
packet.Rotation = p.ReadRotation();
|
||||
packet.Velocity = p.ReadVelocity();
|
||||
packet.Speed = p.GetPedSpeed();
|
||||
packet.Flags = p.GetPedFlags();
|
||||
packet.Heading=p.Heading;
|
||||
if (packet.Flags.HasPedFlag(PedDataFlags.IsAiming))
|
||||
{
|
||||
packet.AimCoords = p.GetAimCoord();
|
||||
@ -77,6 +83,10 @@ namespace RageCoop.Client
|
||||
packet.BlipScale=0.5f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
packet.BlipColor=(BlipColor)255;
|
||||
}
|
||||
}
|
||||
SendSync(packet, ConnectionChannel.PedSync);
|
||||
}
|
||||
@ -87,19 +97,17 @@ namespace RageCoop.Client
|
||||
return;
|
||||
}
|
||||
Vehicle veh = v.MainVehicle;
|
||||
var packet = new Packets.VehicleSync()
|
||||
{
|
||||
ID =v.ID,
|
||||
OwnerID=v.OwnerID,
|
||||
Flags = veh.GetVehicleFlags(),
|
||||
SteeringAngle = veh.SteeringAngle,
|
||||
Position = veh.Position,
|
||||
Velocity=veh.Velocity,
|
||||
Quaternion=veh.ReadQuaternion(),
|
||||
RotationVelocity=veh.RotationVelocity,
|
||||
ThrottlePower = veh.ThrottlePower,
|
||||
BrakePower = veh.BrakePower,
|
||||
};
|
||||
var packet = SendPackets.VehicelPacket;
|
||||
packet.ID =v.ID;
|
||||
packet.OwnerID=v.OwnerID;
|
||||
packet.Flags = veh.GetVehicleFlags();
|
||||
packet.SteeringAngle = veh.SteeringAngle;
|
||||
packet.Position = veh.Position;
|
||||
packet.Velocity=veh.Velocity;
|
||||
packet.Quaternion=veh.ReadQuaternion();
|
||||
packet.RotationVelocity=veh.RotationVelocity;
|
||||
packet.ThrottlePower = veh.ThrottlePower;
|
||||
packet.BrakePower = veh.BrakePower;
|
||||
if (v.LastVelocity==default) {v.LastVelocity=packet.Velocity; }
|
||||
packet.Acceleration = (packet.Velocity-v.LastVelocity)*1000/v.LastSentStopWatch.ElapsedMilliseconds;
|
||||
v.LastSentStopWatch.Restart();
|
||||
@ -140,16 +148,14 @@ namespace RageCoop.Client
|
||||
public static void SendProjectile(SyncedProjectile sp)
|
||||
{
|
||||
var p = sp.MainProjectile;
|
||||
var packet = new Packets.ProjectileSync()
|
||||
{
|
||||
ID =sp.ID,
|
||||
ShooterID=sp.ShooterID,
|
||||
Rotation=p.Rotation,
|
||||
Position=p.Position,
|
||||
Velocity=p.Velocity,
|
||||
WeaponHash=(uint)p.WeaponHash,
|
||||
Exploded=p.IsDead
|
||||
};
|
||||
var packet = SendPackets.ProjectilePacket;
|
||||
packet.ID =sp.ID;
|
||||
packet.ShooterID=sp.ShooterID;
|
||||
packet.Rotation=p.Rotation;
|
||||
packet.Position=p.Position;
|
||||
packet.Velocity=p.Velocity;
|
||||
packet.WeaponHash=(uint)p.WeaponHash;
|
||||
packet.Exploded=p.IsDead;
|
||||
if (p.IsDead) { EntityPool.RemoveProjectile(sp.ID, "Dead"); }
|
||||
SendSync(packet, ConnectionChannel.ProjectileSync);
|
||||
}
|
||||
|
@ -258,6 +258,7 @@
|
||||
</Target>
|
||||
<Import Project="..\packages\Costura.Fody.5.7.0\build\Costura.Fody.targets" Condition="Exists('..\packages\Costura.Fody.5.7.0\build\Costura.Fody.targets')" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>cd /d $(ProjectDir) %26%26 copy ..\bin\$(Configuration)\Core\RageCoop.Core.dll $(OutDir)RageCoop.Core.dll /y</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
@ -290,14 +290,14 @@ namespace RageCoop.Core
|
||||
}
|
||||
|
||||
|
||||
public static T GetPacket<T>(this NetIncomingMessage msg,PacketPool pool=null) where T : Packet, new()
|
||||
public static T GetPacket<T>(this NetIncomingMessage msg, T existingPacket = null) where T : Packet, new()
|
||||
{
|
||||
msg.ReadByte();
|
||||
return GetPacket<T>(msg.ReadBytes(msg.ReadInt32()));
|
||||
return GetPacket<T>(msg.ReadBytes(msg.ReadInt32()),existingPacket);
|
||||
}
|
||||
public static T GetPacket<T>(this byte[] data, PacketPool pool = null) where T : Packet, new()
|
||||
public static T GetPacket<T>(this byte[] data, T existingPacket=null) where T : Packet, new()
|
||||
{
|
||||
T p = pool?.Get<T>() ?? new T();
|
||||
var p = existingPacket??new T();
|
||||
p.Deserialize(data);
|
||||
return p;
|
||||
}
|
||||
|
@ -1,42 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Extensions.ObjectPool;
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
internal class PacketPool
|
||||
{
|
||||
public ObjectPool<Packets.VehicleSync> VehicleSyncPool=ObjectPool.Create<Packets.VehicleSync>();
|
||||
public ObjectPool<Packets.PedSync> PedSyncPool = ObjectPool.Create<Packets.PedSync>();
|
||||
|
||||
public void Recycle(Packets.VehicleSync p)
|
||||
{
|
||||
VehicleSyncPool.Return(p);
|
||||
}
|
||||
public void Recycle(Packets.PedSync p)
|
||||
{
|
||||
PedSyncPool.Return(p);
|
||||
}
|
||||
public Packets.PedSync GetPedPacket()
|
||||
{
|
||||
return PedSyncPool.Get();
|
||||
}
|
||||
public Packets.VehicleSync GetVehiclePacket()
|
||||
{
|
||||
return VehicleSyncPool.Get();
|
||||
}
|
||||
public T Get<T>() where T : Packet
|
||||
{
|
||||
var type=typeof(T);
|
||||
if (type==typeof(Packets.VehicleSync))
|
||||
{
|
||||
return (T)(Packet)VehicleSyncPool.Get();
|
||||
}
|
||||
else if (type==typeof(Packets.PedSync))
|
||||
{
|
||||
return (T)(Packet)PedSyncPool.Get();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user