Only take 35 NPCs to share. Don't wait any longer to send a package. Vehicle synchronization updated. Small changes

This commit is contained in:
EntenKoeniq
2021-12-24 15:33:27 +01:00
parent 5393378317
commit a4ffc25823
9 changed files with 117 additions and 38 deletions

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Drawing; using System.Drawing;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using GTA; using GTA;
using GTA.Native; using GTA.Native;
@ -26,9 +27,34 @@ namespace CoopClient.Entities
private bool AllDataAvailable = false; private bool AllDataAvailable = false;
internal bool LastSyncWasFull { get; set; } = false; internal bool LastSyncWasFull { get; set; } = false;
/// <summary> /// <summary>
/// PLEASE USE LastUpdateReceived
/// </summary>
private ulong LastUpdate;
/// <summary>
/// Get the last update = TickCount64() /// Get the last update = TickCount64()
/// </summary> /// </summary>
public ulong LastUpdateReceived { get; internal set; } public ulong LastUpdateReceived
{
get => LastUpdate;
internal set
{
if (LastUpdate != 0)
{
LatencyAverager.Enqueue(value - LastUpdate);
if (LatencyAverager.Count >= 10)
{
LatencyAverager.Dequeue();
}
}
LastUpdate = value;
}
}
private Queue<double> LatencyAverager = new Queue<double>();
private double AverageLatency
{
get => LatencyAverager.Count == 0 ? 0 : LatencyAverager.Average();
}
/// <summary> /// <summary>
/// Get the player latency /// Get the player latency
/// </summary> /// </summary>

View File

@ -23,7 +23,6 @@ namespace CoopClient.Entities
} }
Tick += OnTick; Tick += OnTick;
Interval = Util.GetGameMs<int>();
} }
private void OnTick(object sender, EventArgs e) private void OnTick(object sender, EventArgs e)
@ -41,7 +40,7 @@ namespace CoopClient.Entities
ulong tickCount = Util.GetTickCount64(); ulong tickCount = Util.GetTickCount64();
foreach (KeyValuePair<long, EntitiesPed> npc in new Dictionary<long, EntitiesPed>(localNPCs)) foreach (KeyValuePair<long, EntitiesPed> npc in new Dictionary<long, EntitiesPed>(localNPCs))
{ {
if ((tickCount - npc.Value.LastUpdateReceived) > 3000) if ((tickCount - npc.Value.LastUpdateReceived) > 2500)
{ {
if (npc.Value.Character != null && npc.Value.Character.Exists() && !npc.Value.Character.IsDead) if (npc.Value.Character != null && npc.Value.Character.Exists() && !npc.Value.Character.IsDead)
{ {
@ -50,7 +49,7 @@ namespace CoopClient.Entities
npc.Value.Character.Delete(); npc.Value.Character.Delete();
} }
if (npc.Value.MainVehicle != null && npc.Value.MainVehicle.Exists() && !npc.Value.MainVehicle.IsDead && npc.Value.MainVehicle.IsSeatFree(VehicleSeat.Driver) && npc.Value.MainVehicle.PassengerCount == 0) if (npc.Value.MainVehicle != null && npc.Value.MainVehicle.Exists() && npc.Value.MainVehicle.IsSeatFree(VehicleSeat.Driver) && npc.Value.MainVehicle.PassengerCount == 0)
{ {
if (npc.Value.NPCVehHandle != 0) if (npc.Value.NPCVehHandle != 0)
{ {
@ -62,8 +61,12 @@ namespace CoopClient.Entities
} }
} }
} }
npc.Value.MainVehicle.MarkAsNoLongerNeeded();
npc.Value.MainVehicle.Delete(); if (!npc.Value.MainVehicle.IsDead)
{
npc.Value.MainVehicle.MarkAsNoLongerNeeded();
npc.Value.MainVehicle.Delete();
}
} }
localNPCs.Remove(npc.Key); localNPCs.Remove(npc.Key);
@ -81,9 +84,10 @@ namespace CoopClient.Entities
if (Main.ShareNPCsWithPlayers) if (Main.ShareNPCsWithPlayers)
{ {
// Send all npcs from the current player // Send all npcs from the current player
foreach (Ped ped in World.GetNearbyPeds(Game.Player.Character.Position, 150f) foreach (Ped ped in World.GetNearbyPeds(Game.Player.Character.Position, 200f) // Get all NPCs around 200f
.Where(p => p.Handle != Game.Player.Character.Handle && p.RelationshipGroup != Main.RelationshipGroup) .Where(p => !p.IsDead && p.Handle != Game.Player.Character.Handle && p.RelationshipGroup != Main.RelationshipGroup)
.OrderBy(p => (p.Position - Game.Player.Character.Position).Length())) .OrderBy(p => (p.Position - Game.Player.Character.Position).Length()) // Get the nearest NPCs
.Take(35)) // We shouldn't sync more peds than 35 as the network traffic can be too high for many players
{ {
Main.MainNetworking.SendNpcData(ped); Main.MainNetworking.SendNpcData(ped);
} }

View File

@ -299,21 +299,24 @@ namespace CoopClient.Entities
} }
// Good enough for now, but we need to create a better sync // Good enough for now, but we need to create a better sync
if (CurrentVehicleSpeed > 0.05f && MainVehicle.IsInRange(Position, 7.0f)) float latency = (((int)((Latency * 1000 / 2) + Main.MainNetworking.Latency * 1000 / 2)) * 2 / 50000f) + (Util.GetTickCount64() - LastUpdateReceived) / (float)AverageLatency;
Vector3 dir = Position - MainVehicle.Position;
if (CurrentVehicleSpeed > 0.02f && MainVehicle.IsInRange(Position, 7.0f))
{ {
Vector3 posTarget = Vector3.Lerp(Position, Position + dir, Math.Min(1.5f, latency));
int forceMultiplier = (Game.Player.Character.IsInVehicle() && MainVehicle.IsTouching(Game.Player.Character.CurrentVehicle)) ? 1 : 3; int forceMultiplier = (Game.Player.Character.IsInVehicle() && MainVehicle.IsTouching(Game.Player.Character.CurrentVehicle)) ? 1 : 3;
MainVehicle.Velocity = VehicleVelocity + forceMultiplier * (Position - MainVehicle.Position); MainVehicle.Velocity = VehicleVelocity + forceMultiplier * (posTarget - MainVehicle.Position);
MainVehicle.Quaternion = Quaternion.Slerp(MainVehicle.Quaternion, VehicleRotation, 0.5f); MainVehicle.Quaternion = Quaternion.Slerp(MainVehicle.Quaternion, VehicleRotation, Math.Min(1.5f, latency));
VehicleStopTime = Util.GetTickCount64(); VehicleStopTime = Util.GetTickCount64();
} }
else if ((Util.GetTickCount64() - VehicleStopTime) <= 1000) else if ((Util.GetTickCount64() - VehicleStopTime) <= 1000)
{ {
Vector3 posTarget = Util.LinearVectorLerp(MainVehicle.Position, Position + (Position - MainVehicle.Position), Util.GetTickCount64() - VehicleStopTime, 1000); MainVehicle.PositionNoOffset = Util.LinearVectorLerp(MainVehicle.Position, Position + dir, Util.GetTickCount64() - VehicleStopTime, 1000);
MainVehicle.Quaternion = Quaternion.Slerp(MainVehicle.Quaternion, VehicleRotation, Math.Min(1.5f, latency));
MainVehicle.PositionNoOffset = posTarget;
MainVehicle.Quaternion = Quaternion.Slerp(MainVehicle.Quaternion, VehicleRotation, 0.5f);
} }
else else
{ {

View File

@ -84,7 +84,6 @@ namespace CoopClient
Util.NativeMemory(); Util.NativeMemory();
} }
private ulong LastDataSend;
#if DEBUG #if DEBUG
private ulong LastDebugData; private ulong LastDebugData;
private int DebugBytesSend; private int DebugBytesSend;
@ -156,14 +155,7 @@ namespace CoopClient
} }
#endif #endif
if ((Util.GetTickCount64() - LastDataSend) < Util.GetGameMs<ulong>())
{
return;
}
MainNetworking.SendPlayerData(); MainNetworking.SendPlayerData();
LastDataSend = Util.GetTickCount64();
} }
#if !NON_INTERACTIVE #if !NON_INTERACTIVE
@ -275,7 +267,7 @@ namespace CoopClient
DebugSyncPed = Players[0]; DebugSyncPed = Players[0];
} }
if ((Util.GetTickCount64() - ArtificialLagCounter) < 30) if ((Util.GetTickCount64() - ArtificialLagCounter) < 20)
{ {
return; return;
} }

View File

@ -16,7 +16,7 @@ namespace CoopClient
public class Networking public class Networking
{ {
internal NetClient Client; internal NetClient Client;
internal float Latency; internal float Latency = 0;
internal bool ShowNetworkInfo = false; internal bool ShowNetworkInfo = false;
@ -132,6 +132,7 @@ namespace CoopClient
break; break;
case NetConnectionStatus.Disconnected: case NetConnectionStatus.Disconnected:
// Reset all values // Reset all values
Latency = 0;
LastPlayerFullSync = 0; LastPlayerFullSync = 0;
Main.NPCsAllowed = false; Main.NPCsAllowed = false;
@ -456,10 +457,7 @@ namespace CoopClient
player.IsInVehicle = false; player.IsInVehicle = false;
player.LastSyncWasFull = false; player.LastSyncWasFull = false;
if (packet.Flag.HasValue) player.Latency = packet.Latency.Value;
{
player.Latency = packet.Latency.Value;
}
player.LastUpdateReceived = Util.GetTickCount64(); player.LastUpdateReceived = Util.GetTickCount64();
} }
} }
@ -646,6 +644,7 @@ namespace CoopClient
npc.IsInVehicle = false; npc.IsInVehicle = false;
npc.LastSyncWasFull = true; npc.LastSyncWasFull = true;
npc.Latency = packet.Latency.Value;
npc.LastUpdateReceived = Util.GetTickCount64(); npc.LastUpdateReceived = Util.GetTickCount64();
} }
else else
@ -670,6 +669,7 @@ namespace CoopClient
IsInVehicle = false, IsInVehicle = false,
LastSyncWasFull = true, LastSyncWasFull = true,
Latency = packet.Latency.Value,
LastUpdateReceived = Util.GetTickCount64() LastUpdateReceived = Util.GetTickCount64()
}); });
} }
@ -712,6 +712,7 @@ namespace CoopClient
npc.IsInVehicle = true; npc.IsInVehicle = true;
npc.LastSyncWasFull = true; npc.LastSyncWasFull = true;
npc.Latency = packet.Latency.Value;
npc.LastUpdateReceived = Util.GetTickCount64(); npc.LastUpdateReceived = Util.GetTickCount64();
} }
else else
@ -746,6 +747,7 @@ namespace CoopClient
IsInVehicle = true, IsInVehicle = true,
LastSyncWasFull = true, LastSyncWasFull = true,
Latency = packet.Latency.Value,
LastUpdateReceived = Util.GetTickCount64() LastUpdateReceived = Util.GetTickCount64()
}); });
} }
@ -910,7 +912,8 @@ namespace CoopClient
VehMods = veh.Mods.GetVehicleMods(), VehMods = veh.Mods.GetVehicleMods(),
VehDamageModel = veh.GetVehicleDamageModel(), VehDamageModel = veh.GetVehicleDamageModel(),
VehLandingGear = veh.IsPlane ? (byte)veh.LandingGearState : (byte)0, VehLandingGear = veh.IsPlane ? (byte)veh.LandingGearState : (byte)0,
Flag = npc.GetVehicleFlags(veh) Flag = npc.GetVehicleFlags(veh),
Latency = Latency
}.PacketToNetOutGoingMessage(outgoingMessage); }.PacketToNetOutGoingMessage(outgoingMessage);
} }
else else
@ -927,7 +930,8 @@ namespace CoopClient
Speed = npc.GetPedSpeed(), Speed = npc.GetPedSpeed(),
AimCoords = npc.GetPedAimCoords(true).ToLVector(), AimCoords = npc.GetPedAimCoords(true).ToLVector(),
CurrentWeaponHash = (uint)npc.Weapons.Current.Hash, CurrentWeaponHash = (uint)npc.Weapons.Current.Hash,
Flag = npc.GetPedFlags(true) Flag = npc.GetPedFlags(true),
Latency = Latency
}.PacketToNetOutGoingMessage(outgoingMessage); }.PacketToNetOutGoingMessage(outgoingMessage);
} }

View File

@ -1654,6 +1654,8 @@ namespace CoopClient
public byte? Flag { get; set; } = 0; public byte? Flag { get; set; } = 0;
public float? Latency { get; set; }
public override void PacketToNetOutGoingMessage(NetOutgoingMessage message) public override void PacketToNetOutGoingMessage(NetOutgoingMessage message)
{ {
#region PacketToNetOutGoingMessage #region PacketToNetOutGoingMessage
@ -1715,6 +1717,12 @@ namespace CoopClient
// Write npc weapon hash // Write npc weapon hash
byteArray.AddRange(BitConverter.GetBytes(CurrentWeaponHash)); byteArray.AddRange(BitConverter.GetBytes(CurrentWeaponHash));
// Write player latency
if (Latency.HasValue)
{
byteArray.AddRange(BitConverter.GetBytes(Latency.Value));
}
byte[] result = byteArray.ToArray(); byte[] result = byteArray.ToArray();
message.Write(result.Length); message.Write(result.Length);
@ -1799,6 +1807,12 @@ namespace CoopClient
// Read npc weapon hash // Read npc weapon hash
CurrentWeaponHash = reader.ReadUInt(); CurrentWeaponHash = reader.ReadUInt();
// Read player latency
if (reader.CanRead(4))
{
Latency = reader.ReadFloat();
}
#endregion #endregion
} }
} }
@ -1843,6 +1857,8 @@ namespace CoopClient
public ushort? Flag { get; set; } public ushort? Flag { get; set; }
public float? Latency { get; set; }
public override void PacketToNetOutGoingMessage(NetOutgoingMessage message) public override void PacketToNetOutGoingMessage(NetOutgoingMessage message)
{ {
#region PacketToNetOutGoingMessage #region PacketToNetOutGoingMessage
@ -1950,6 +1966,12 @@ namespace CoopClient
byteArray.Add(0x00); byteArray.Add(0x00);
} }
// Write player latency
if (Latency.HasValue)
{
byteArray.AddRange(BitConverter.GetBytes(Latency.Value));
}
byte[] result = byteArray.ToArray(); byte[] result = byteArray.ToArray();
message.Write(result.Length); message.Write(result.Length);
@ -2075,6 +2097,12 @@ namespace CoopClient
PuncturedTires = reader.ReadUShort() PuncturedTires = reader.ReadUShort()
}; };
} }
// Read player latency
if (reader.CanRead(4))
{
Latency = reader.ReadFloat();
}
#endregion #endregion
} }
} }

View File

@ -47,11 +47,6 @@ namespace CoopClient
} }
#endregion #endregion
public static T GetGameMs<T>() where T : IConvertible
{
return (T)Convert.ChangeType(1f / (Game.FPS > 60f ? 60f : Game.FPS) * 1000f, typeof(T));
}
public static Model ModelRequest(this int hash) public static Model ModelRequest(this int hash)
{ {
Model model = new Model(hash); Model model = new Model(hash);

View File

@ -19,7 +19,6 @@ namespace CoopClient
public WorldThread() public WorldThread()
{ {
Tick += OnTick; Tick += OnTick;
Interval = Util.GetGameMs<int>();
Aborted += (sender, e) => Aborted += (sender, e) =>
{ {
if (LastDisableTraffic) if (LastDisableTraffic)

View File

@ -1603,6 +1603,8 @@ namespace CoopServer
public byte? Flag { get; set; } = 0; public byte? Flag { get; set; } = 0;
public float? Latency { get; set; }
public override void PacketToNetOutGoingMessage(NetOutgoingMessage message) public override void PacketToNetOutGoingMessage(NetOutgoingMessage message)
{ {
#region PacketToNetOutGoingMessage #region PacketToNetOutGoingMessage
@ -1664,6 +1666,12 @@ namespace CoopServer
// Write npc weapon hash // Write npc weapon hash
byteArray.AddRange(BitConverter.GetBytes(CurrentWeaponHash)); byteArray.AddRange(BitConverter.GetBytes(CurrentWeaponHash));
// Write player latency
if (Latency.HasValue)
{
byteArray.AddRange(BitConverter.GetBytes(Latency.Value));
}
byte[] result = byteArray.ToArray(); byte[] result = byteArray.ToArray();
message.Write(result.Length); message.Write(result.Length);
@ -1748,6 +1756,12 @@ namespace CoopServer
// Read npc weapon hash // Read npc weapon hash
CurrentWeaponHash = reader.ReadUInt(); CurrentWeaponHash = reader.ReadUInt();
// Read player latency
if (reader.CanRead(4))
{
Latency = reader.ReadFloat();
}
#endregion #endregion
} }
} }
@ -1792,6 +1806,8 @@ namespace CoopServer
public ushort? Flag { get; set; } public ushort? Flag { get; set; }
public float? Latency { get; set; }
public override void PacketToNetOutGoingMessage(NetOutgoingMessage message) public override void PacketToNetOutGoingMessage(NetOutgoingMessage message)
{ {
#region PacketToNetOutGoingMessage #region PacketToNetOutGoingMessage
@ -1899,6 +1915,12 @@ namespace CoopServer
byteArray.Add(0x00); byteArray.Add(0x00);
} }
// Write player latency
if (Latency.HasValue)
{
byteArray.AddRange(BitConverter.GetBytes(Latency.Value));
}
byte[] result = byteArray.ToArray(); byte[] result = byteArray.ToArray();
message.Write(result.Length); message.Write(result.Length);
@ -2024,6 +2046,12 @@ namespace CoopServer
PuncturedTires = reader.ReadUShort() PuncturedTires = reader.ReadUShort()
}; };
} }
// Read player latency
if (reader.CanRead(4))
{
Latency = reader.ReadFloat();
}
#endregion #endregion
} }
} }