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.Drawing;
using System.Collections.Generic;
using System.Linq;
using GTA;
using GTA.Native;
@ -26,9 +27,34 @@ namespace CoopClient.Entities
private bool AllDataAvailable = false;
internal bool LastSyncWasFull { get; set; } = false;
/// <summary>
/// PLEASE USE LastUpdateReceived
/// </summary>
private ulong LastUpdate;
/// <summary>
/// Get the last update = TickCount64()
/// </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>
/// Get the player latency
/// </summary>

View File

@ -23,7 +23,6 @@ namespace CoopClient.Entities
}
Tick += OnTick;
Interval = Util.GetGameMs<int>();
}
private void OnTick(object sender, EventArgs e)
@ -41,7 +40,7 @@ namespace CoopClient.Entities
ulong tickCount = Util.GetTickCount64();
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)
{
@ -50,7 +49,7 @@ namespace CoopClient.Entities
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)
{
@ -62,9 +61,13 @@ namespace CoopClient.Entities
}
}
}
if (!npc.Value.MainVehicle.IsDead)
{
npc.Value.MainVehicle.MarkAsNoLongerNeeded();
npc.Value.MainVehicle.Delete();
}
}
localNPCs.Remove(npc.Key);
Main.NPCs.Remove(npc.Key);
@ -81,9 +84,10 @@ namespace CoopClient.Entities
if (Main.ShareNPCsWithPlayers)
{
// Send all npcs from the current player
foreach (Ped ped in World.GetNearbyPeds(Game.Player.Character.Position, 150f)
.Where(p => p.Handle != Game.Player.Character.Handle && p.RelationshipGroup != Main.RelationshipGroup)
.OrderBy(p => (p.Position - Game.Player.Character.Position).Length()))
foreach (Ped ped in World.GetNearbyPeds(Game.Player.Character.Position, 200f) // Get all NPCs around 200f
.Where(p => !p.IsDead && p.Handle != Game.Player.Character.Handle && p.RelationshipGroup != Main.RelationshipGroup)
.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);
}

View File

@ -299,21 +299,24 @@ namespace CoopClient.Entities
}
// 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;
MainVehicle.Velocity = VehicleVelocity + forceMultiplier * (Position - MainVehicle.Position);
MainVehicle.Quaternion = Quaternion.Slerp(MainVehicle.Quaternion, VehicleRotation, 0.5f);
MainVehicle.Velocity = VehicleVelocity + forceMultiplier * (posTarget - MainVehicle.Position);
MainVehicle.Quaternion = Quaternion.Slerp(MainVehicle.Quaternion, VehicleRotation, Math.Min(1.5f, latency));
VehicleStopTime = Util.GetTickCount64();
}
else if ((Util.GetTickCount64() - VehicleStopTime) <= 1000)
{
Vector3 posTarget = Util.LinearVectorLerp(MainVehicle.Position, Position + (Position - MainVehicle.Position), Util.GetTickCount64() - VehicleStopTime, 1000);
MainVehicle.PositionNoOffset = posTarget;
MainVehicle.Quaternion = Quaternion.Slerp(MainVehicle.Quaternion, VehicleRotation, 0.5f);
MainVehicle.PositionNoOffset = Util.LinearVectorLerp(MainVehicle.Position, Position + dir, Util.GetTickCount64() - VehicleStopTime, 1000);
MainVehicle.Quaternion = Quaternion.Slerp(MainVehicle.Quaternion, VehicleRotation, Math.Min(1.5f, latency));
}
else
{

View File

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

View File

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

View File

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

View File

@ -47,11 +47,6 @@ namespace CoopClient
}
#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)
{
Model model = new Model(hash);

View File

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

View File

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