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:
@ -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>
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -19,7 +19,6 @@ namespace CoopClient
|
||||
public WorldThread()
|
||||
{
|
||||
Tick += OnTick;
|
||||
Interval = Util.GetGameMs<int>();
|
||||
Aborted += (sender, e) =>
|
||||
{
|
||||
if (LastDisableTraffic)
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user