Better packet reuse

This commit is contained in:
Sardelka
2022-08-13 08:22:14 +08:00
parent 6e5f72ee70
commit d24d786fd3
5 changed files with 67 additions and 91 deletions

View File

@ -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:

View File

@ -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);
}

View File

@ -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>

View File

@ -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;
}

View File

@ -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;
}
}
}