Some optimization.

This commit is contained in:
Sardelka
2022-05-30 11:11:40 +08:00
parent 811e7df14e
commit aefea337f1
11 changed files with 68 additions and 103 deletions

View File

@ -738,9 +738,9 @@ namespace RageCoop.Client
veh.IsLeftHeadLightBroken = model.LeftHeadLightBroken > 0; veh.IsLeftHeadLightBroken = model.LeftHeadLightBroken > 0;
veh.IsRightHeadLightBroken = model.RightHeadLightBroken > 0; veh.IsRightHeadLightBroken = model.RightHeadLightBroken > 0;
} }
public static Vector3 PredictPosition(this Entity e) public static Vector3 PredictPosition(this Entity e,bool applyDefault=true)
{ {
return e.Position+e.Velocity*(SyncParameters.PositioinPredictionDefault+Networking.Latency); return e.Position+e.Velocity*((applyDefault?SyncParameters.PositioinPredictionDefault:0)+Networking.Latency);
} }
#endregion #endregion

View File

@ -117,7 +117,7 @@ namespace RageCoop.Client
{ {
ID =sp.ID, ID =sp.ID,
ShooterID=sp.ShooterID, ShooterID=sp.ShooterID,
Position=p.PredictPosition().ToLVector(), Position=p.Position.ToLVector(),
Rotation=p.Rotation.ToLVector(), Rotation=p.Rotation.ToLVector(),
Velocity=p.Velocity.ToLVector(), Velocity=p.Velocity.ToLVector(),
WeaponHash=(uint)p.WeaponHash, WeaponHash=(uint)p.WeaponHash,

View File

@ -55,7 +55,7 @@ namespace RageCoop.Client
_mainScaleform.CallFunction("SET_DATA_SLOT", i++, $"{player.Latency * 1000:N0}ms", player.Username, 116, 0, i - 1, "", "", 2, "", "", ' '); _mainScaleform.CallFunction("SET_DATA_SLOT", i++, $"{player.Latency * 1000:N0}ms", player.Username, 116, 0, i - 1, "", "", 2, "", "", ' ');
} }
_mainScaleform.CallFunction("SET_TITLE", "Player list", (Players.Count) + " players"); _mainScaleform.CallFunction("SET_TITLE", "Player list", $"{Players.Count+1} players");
_mainScaleform.CallFunction("DISPLAY_VIEW"); _mainScaleform.CallFunction("DISPLAY_VIEW");
} }
public static void SetPlayer(int id, string username,float latency=0) public static void SetPlayer(int id, string username,float latency=0)

View File

@ -169,7 +169,7 @@ namespace RageCoop.Client
{ {
SyncedPed c = Passengers[seat]; SyncedPed c = Passengers[seat];
if ((c!=null)&&c.MainPed!=null&&(!currentPassengers.ContainsKey(i))&&(!c.MainPed.IsBeingJacked)) { if (c?.MainPed!=null&&(!currentPassengers.ContainsKey(i))&&(!c.MainPed.IsBeingJacked)&&(!c.MainPed.IsTaskActive(TaskType.CTaskExitVehicleSeat))) {
Passengers[seat].MainPed.SetIntoVehicle(MainVehicle, seat); Passengers[seat].MainPed.SetIntoVehicle(MainVehicle, seat);
} }
} }

View File

@ -9,6 +9,7 @@ namespace RageCoop.Server
{ {
public long ClientID = 0; public long ClientID = 0;
private float _currentLatency = 0f; private float _currentLatency = 0f;
public NetConnection Connection { get; set; }
public float Latency public float Latency
{ {
get => _currentLatency; get => _currentLatency;

View File

@ -105,7 +105,7 @@ namespace RageCoop.Server
{ {
lock (Server.Clients) lock (Server.Clients)
{ {
Client x = Server.Clients.FirstOrDefault(x => x.ClientID == client.NetHandle); Client x = Util.GetClientByID(client.NetHandle);
if (x != null) if (x != null)
{ {
x.FilesReceived = true; x.FilesReceived = true;

View File

@ -32,6 +32,9 @@
<Reference Include="Newtonsoft.Json"> <Reference Include="Newtonsoft.Json">
<HintPath>..\Libs\Release\scripts\Newtonsoft.Json.dll</HintPath> <HintPath>..\Libs\Release\scripts\Newtonsoft.Json.dll</HintPath>
</Reference> </Reference>
<Reference Include="ScriptHookVDotNet3">
<HintPath>..\Libs\Release\ScriptHookVDotNet3.dll</HintPath>
</Reference>
</ItemGroup> </ItemGroup>

View File

@ -36,7 +36,7 @@ namespace RageCoop.Server
public static readonly Dictionary<TriggerEvent, Action<EventContext>> TriggerEvents = new(); public static readonly Dictionary<TriggerEvent, Action<EventContext>> TriggerEvents = new();
private static Thread BackgroundThread; private static Thread BackgroundThread;
public static readonly List<Client> Clients = new(); public static readonly Dictionary<long,Client> Clients = new();
public Server() public Server()
{ {
@ -213,6 +213,7 @@ namespace RageCoop.Server
Listen(); Listen();
BackgroundThread=new Thread(() => Background()); BackgroundThread=new Thread(() => Background());
BackgroundThread.Start();
} }
private void Listen() private void Listen()
@ -232,7 +233,7 @@ namespace RageCoop.Server
{ {
lock (Clients) lock (Clients)
{ {
Clients.ForEach(client => Clients.Values.ToList().ForEach(client =>
{ {
if (!client.FilesSent) if (!client.FilesSent)
{ {
@ -317,7 +318,7 @@ namespace RageCoop.Server
Packets.PedStateSync packet = new(); Packets.PedStateSync packet = new();
packet.Unpack(data); packet.Unpack(data);
CharacterStateSync(packet, message.SenderConnection.RemoteUniqueIdentifier); PedStateSync(packet, message.SenderConnection.RemoteUniqueIdentifier);
} }
catch (Exception e) catch (Exception e)
{ {
@ -353,7 +354,7 @@ namespace RageCoop.Server
Packets.PedSync packet = new(); Packets.PedSync packet = new();
packet.Unpack(data); packet.Unpack(data);
CharacterSync(packet, message.SenderConnection.RemoteUniqueIdentifier); PedSync(packet, message.SenderConnection.RemoteUniqueIdentifier);
} }
catch (Exception e) catch (Exception e)
{ {
@ -429,7 +430,7 @@ namespace RageCoop.Server
Packets.NativeResponse packet = new(); Packets.NativeResponse packet = new();
packet.Unpack(data); packet.Unpack(data);
Client client = Clients.Find(x => x.ClientID == message.SenderConnection.RemoteUniqueIdentifier); Client client = Util.GetClientByID(message.SenderConnection.RemoteUniqueIdentifier);
if (client != null) if (client != null)
{ {
if (client.Callbacks.ContainsKey(packet.ID)) if (client.Callbacks.ContainsKey(packet.ID))
@ -514,7 +515,7 @@ namespace RageCoop.Server
Packets.FileTransferComplete packet = new(); Packets.FileTransferComplete packet = new();
packet.Unpack(data); packet.Unpack(data);
Client client = Clients.Find(x => x.ClientID == message.SenderConnection.RemoteUniqueIdentifier); Client client = Util.GetClientByID(message.SenderConnection.RemoteUniqueIdentifier);
if (client != null && !client.FilesReceived) if (client != null && !client.FilesReceived)
{ {
DownloadManager.TryToRemoveClient(client.ClientID, packet.ID); DownloadManager.TryToRemoveClient(client.ClientID, packet.ID);
@ -601,7 +602,7 @@ namespace RageCoop.Server
break; break;
case NetIncomingMessageType.ConnectionLatencyUpdated: case NetIncomingMessageType.ConnectionLatencyUpdated:
{ {
Client client = Clients.Find(x => x.ClientID == message.SenderConnection.RemoteUniqueIdentifier); Client client = Util.GetClientByID(message.SenderConnection.RemoteUniqueIdentifier);
if (client != null) if (client != null)
{ {
client.Latency = message.ReadFloat(); client.Latency = message.ReadFloat();
@ -653,7 +654,7 @@ namespace RageCoop.Server
{ {
while (true) while (true)
{ {
foreach(Client c in Clients) foreach(Client c in Clients.Values)
{ {
MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != c.ClientID).ForEach(x => MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != c.ClientID).ForEach(x =>
{ {
@ -717,7 +718,7 @@ namespace RageCoop.Server
local.Deny("This IP was blocked by this server!"); local.Deny("This IP was blocked by this server!");
return; return;
} }
if (Clients.Any(x => x.Player.Username.ToLower() == packet.Username.ToLower())) if (Clients.Values.Any(x => x.Player.Username.ToLower() == packet.Username.ToLower()))
{ {
local.Deny("Username is already taken!"); local.Deny("Username is already taken!");
return; return;
@ -730,14 +731,15 @@ namespace RageCoop.Server
// Add the player to Players // Add the player to Players
lock (Clients) lock (Clients)
{ {
Clients.Add( Clients.Add(local.RemoteUniqueIdentifier,
tmpClient = new Client() tmpClient = new Client()
{ {
ClientID = local.RemoteUniqueIdentifier, ClientID = local.RemoteUniqueIdentifier,
Connection=local,
Player = new() Player = new()
{ {
Username = packet.Username, Username = packet.Username,
PedID=packet.PedID PedID=packet.PedID,
} }
} }
);; );;
@ -766,7 +768,7 @@ namespace RageCoop.Server
// The connection has been approved, now we need to send all other players to the new player and the new player to all players // The connection has been approved, now we need to send all other players to the new player and the new player to all players
private static void SendPlayerConnectPacket(NetConnection local) private static void SendPlayerConnectPacket(NetConnection local)
{ {
Client localClient = Clients.Find(x => x.ClientID == local.RemoteUniqueIdentifier); Client localClient = Util.GetClientByID(local.RemoteUniqueIdentifier);
if (localClient == null) if (localClient == null)
{ {
local.Disconnect("No data found!"); local.Disconnect("No data found!");
@ -781,7 +783,7 @@ namespace RageCoop.Server
{ {
long targetNetHandle = targetPlayer.RemoteUniqueIdentifier; long targetNetHandle = targetPlayer.RemoteUniqueIdentifier;
Client targetClient = Clients.Find(x => x.ClientID == targetNetHandle); Client targetClient = Util.GetClientByID(targetNetHandle);
if (targetClient != null) if (targetClient != null)
{ {
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage(); NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
@ -826,7 +828,7 @@ namespace RageCoop.Server
private static void SendPlayerDisconnectPacket(long nethandle) private static void SendPlayerDisconnectPacket(long nethandle)
{ {
List<NetConnection> clients = MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != nethandle); List<NetConnection> clients = MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != nethandle);
int playerPedID = Clients.Where(x => x.ClientID==nethandle).First().Player.PedID; int playerPedID = Clients[nethandle].Player.PedID;
if (clients.Count > 0) if (clients.Count > 0)
{ {
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage(); NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
@ -838,13 +840,13 @@ namespace RageCoop.Server
MainNetServer.SendMessage(outgoingMessage, clients, NetDeliveryMethod.ReliableOrdered, 0); MainNetServer.SendMessage(outgoingMessage, clients, NetDeliveryMethod.ReliableOrdered, 0);
} }
Client localClient = Clients.FirstOrDefault(x => x.ClientID == nethandle); Client localClient = Util.GetClientByID( nethandle);
if (localClient == null) if (localClient == null)
{ {
return; return;
} }
Clients.Remove(localClient); Clients.Remove(localClient.ClientID);
if (RunningResource != null) if (RunningResource != null)
{ {
@ -857,7 +859,7 @@ namespace RageCoop.Server
} }
#region SyncEntities #region SyncEntities
private static void CharacterStateSync(Packets.PedStateSync packet,long ClientID) private static void PedStateSync(Packets.PedStateSync packet,long ClientID)
{ {
@ -868,14 +870,13 @@ namespace RageCoop.Server
} }
foreach (var c in Clients.Values)
MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != ClientID).ForEach(x =>
{ {
if (c.ClientID==client.ClientID) { continue; }
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage(); NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
packet.Pack(outgoingMessage); packet.Pack(outgoingMessage);
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PedSync); MainNetServer.SendMessage(outgoingMessage, c.Connection, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PedSync);
}
});
if (RunningResource != null && packet.ID==client.Player.PedID) if (RunningResource != null && packet.ID==client.Player.PedID)
{ {
@ -896,15 +897,15 @@ namespace RageCoop.Server
client.Player.VehicleID = packet.ID; client.Player.VehicleID = packet.ID;
} }
MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != ClientID).ForEach(x => foreach (var c in Clients.Values)
{ {
if (c.ClientID==client.ClientID) { continue; }
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage(); NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
packet.Pack(outgoingMessage); packet.Pack(outgoingMessage);
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.VehicleSync); MainNetServer.SendMessage(outgoingMessage, c.Connection, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PedSync);
});
} }
private static void CharacterSync(Packets.PedSync packet, long ClientID) }
private static void PedSync(Packets.PedSync packet, long ClientID)
{ {
Client client = Util.GetClientByID(ClientID); Client client = Util.GetClientByID(ClientID);
if (client == null) if (client == null)
@ -913,14 +914,14 @@ namespace RageCoop.Server
} }
foreach(var c in Clients.Values)
MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != ClientID).ForEach(x =>
{ {
// Don't send data back
if (c.ClientID==client.ClientID) { continue; }
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage(); NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
packet.Pack(outgoingMessage); packet.Pack(outgoingMessage);
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PedSync); MainNetServer.SendMessage(outgoingMessage,c.Connection, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PedSync);
}
});
if (RunningResource != null && packet.ID==client.Player.PedID) if (RunningResource != null && packet.ID==client.Player.PedID)
{ {
@ -935,13 +936,13 @@ namespace RageCoop.Server
return; return;
} }
MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != ClientID).ForEach(x => foreach (var c in Clients.Values)
{ {
if (c.ClientID==client.ClientID) { continue; }
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage(); NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
packet.Pack(outgoingMessage); packet.Pack(outgoingMessage);
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.VehicleSync); MainNetServer.SendMessage(outgoingMessage, c.Connection, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PedSync);
}
});
/* /*
Client client = Util.GetClientByID(ClientID); Client client = Util.GetClientByID(ClientID);
if (client == null) if (client == null)
@ -980,12 +981,13 @@ namespace RageCoop.Server
return; return;
} }
MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != ClientID).ForEach(x => foreach (var c in Clients.Values)
{ {
if (c.ClientID==client.ClientID) { continue; }
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage(); NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
packet.Pack(outgoingMessage); packet.Pack(outgoingMessage);
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.ProjectileSync); MainNetServer.SendMessage(outgoingMessage, c.Connection, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PedSync);
}); }
} }
#endregion #endregion
@ -1004,7 +1006,7 @@ namespace RageCoop.Server
CommandContext ctx = new() CommandContext ctx = new()
{ {
Client = Clients.Find(x => x.Player.Username == packet.Username), Client = Clients.Values.Where(x => x.Player.Username == packet.Username).FirstOrDefault(),
Args = argsWithoutCmd Args = argsWithoutCmd
}; };

View File

@ -105,13 +105,6 @@ namespace RageCoop.Server
return task.Result; return task.Result;
} }
public void InvokePlayerPositionUpdate(string username)
{
lock (_actionQueue.SyncRoot)
{
_actionQueue.Enqueue(new Action(() => _script.API.InvokePlayerPositionUpdate(username)));
}
}
public void InvokePlayerUpdate(Client client) public void InvokePlayerUpdate(Client client)
{ {
@ -121,29 +114,6 @@ namespace RageCoop.Server
} }
} }
public void InvokePlayerHealthUpdate(string username)
{
lock (_actionQueue.SyncRoot)
{
_actionQueue.Enqueue(new Action(() => _script.API.InvokePlayerHealthUpdate(username)));
}
}
public void InvokePlayerPedHandleUpdate(string username)
{
lock (_actionQueue.SyncRoot)
{
_actionQueue.Enqueue(new Action(() => _script.API.InvokePlayerPedHandleUpdate(username)));
}
}
public void InvokePlayerVehicleHandleUpdate(string username)
{
lock (_actionQueue.SyncRoot)
{
_actionQueue.Enqueue(new Action(() => _script.API.InvokePlayerVehicleHandleUpdate(username)));
}
}
public void InvokeTick(long tick) public void InvokeTick(long tick)
{ {
@ -253,11 +223,6 @@ namespace RageCoop.Server
OnPlayerUpdate?.Invoke(client); OnPlayerUpdate?.Invoke(client);
} }
public void InvokePlayerHealthUpdate(string username)
{
OnPlayerHealthUpdate?.Invoke(Server.Clients.FirstOrDefault(x => x.Player.Username == username));
}
public bool InvokeChatMessage(string username, string message) public bool InvokeChatMessage(string username, string message)
{ {
CancelEventArgs args = new(false); CancelEventArgs args = new(false);
@ -265,21 +230,6 @@ namespace RageCoop.Server
return args.Cancel; return args.Cancel;
} }
public void InvokePlayerPositionUpdate(string username)
{
OnPlayerPositionUpdate?.Invoke(Server.Clients.FirstOrDefault(x => x.Player.Username == username));
}
public void InvokePlayerPedHandleUpdate(string username)
{
OnPlayerPedHandleUpdate?.Invoke(Server.Clients.FirstOrDefault(x => x.Player.Username == username));
}
public void InvokePlayerVehicleHandleUpdate(string username)
{
OnPlayerVehicleHandleUpdate?.Invoke(Server.Clients.FirstOrDefault(x => x.Player.Username == username));
}
public bool InvokeModPacketReceived(long from, long target, string modName, byte customID, byte[] bytes) public bool InvokeModPacketReceived(long from, long target, string modName, byte customID, byte[] bytes)
{ {
CancelEventArgs args = new(false); CancelEventArgs args = new(false);
@ -389,8 +339,8 @@ namespace RageCoop.Server
/// <summary> /// <summary>
/// Get a list of all Clients /// Get a list of all Clients
/// </summary> /// </summary>
/// <returns>All Clients as a List</returns> /// <returns>All Clients as a dictionary indexed by ClientID</returns>
public static List<Client> GetAllClients() public static Dictionary<long,Client> GetAllClients()
{ {
return Server.Clients; return Server.Clients;
} }
@ -402,7 +352,7 @@ namespace RageCoop.Server
/// <returns>The Client from this user or null</returns> /// <returns>The Client from this user or null</returns>
public static Client GetClientByUsername(string username) public static Client GetClientByUsername(string username)
{ {
return Server.Clients.FirstOrDefault(x => x.Player.Username.ToLower() == username.ToLower()); return Server.Clients.Values.FirstOrDefault(x => x.Player.Username.ToLower() == username.ToLower());
} }
/// <summary> /// <summary>

View File

@ -14,5 +14,13 @@
public bool AnnounceSelf { get; set; } = false; public bool AnnounceSelf { get; set; } = false;
public string MasterServer { get; set; } = "https://ragecoop.online/gtav/servers"; public string MasterServer { get; set; } = "https://ragecoop.online/gtav/servers";
public bool DebugMode { get; set; } = false; public bool DebugMode { get; set; } = false;
/// <summary>
/// NPC data won't be sent to a player if distance is greater than this value. -1 for unlimited.
/// </summary>
public float NpcStreamingDistance { get; set; } = 200;
/// <summary>
/// Player's data won't be sent to another player if their distance is greater than this value. -1 for unlimited.
/// </summary>
public float PlayerStreamingDistance { get; set; } = -1;
} }
} }

View File

@ -30,7 +30,8 @@ namespace RageCoop.Server
public static Client GetClientByID(long id) public static Client GetClientByID(long id)
{ {
Client result = Server.Clients.Find(x => x.ClientID == id); Client result = null;
Server.Clients.TryGetValue(id,out result);
if (result == null) if (result == null)
{ {
NetConnection localConn = Server.MainNetServer.Connections.Find(x => id == x.RemoteUniqueIdentifier); NetConnection localConn = Server.MainNetServer.Connections.Find(x => id == x.RemoteUniqueIdentifier);
@ -46,7 +47,7 @@ namespace RageCoop.Server
public static NetConnection GetConnectionByUsername(string username) public static NetConnection GetConnectionByUsername(string username)
{ {
Client client = Server.Clients.Find(x => x.Player.Username.ToLower() == username.ToLower()); Client client = Server.Clients.Values.ToList().Find(x => x.Player.Username.ToLower() == username.ToLower());
if (client == null) if (client == null)
{ {
return null; return null;
@ -70,7 +71,7 @@ namespace RageCoop.Server
{ {
return new(Server.MainNetServer.Connections.FindAll(e => return new(Server.MainNetServer.Connections.FindAll(e =>
{ {
Client client = Server.Clients.First(x => x.ClientID == e.RemoteUniqueIdentifier); Client client = Server.Clients.Values.First(x => x.ClientID == e.RemoteUniqueIdentifier);
return client != null && client.Player.IsInRangeOf(position, range); return client != null && client.Player.IsInRangeOf(position, range);
})); }));
} }
@ -79,7 +80,7 @@ namespace RageCoop.Server
{ {
return new(Server.MainNetServer.Connections.Where(e => return new(Server.MainNetServer.Connections.Where(e =>
{ {
Client client = Server.Clients.First(x => x.ClientID == e.RemoteUniqueIdentifier); Client client = Server.Clients.Values.First(x => x.ClientID == e.RemoteUniqueIdentifier);
return e != local && client != null && client.Player.IsInRangeOf(position, range); return e != local && client != null && client.Player.IsInRangeOf(position, range);
})); }));
} }