2022-07-01 19:02:38 +08:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using RageCoop.Core;
|
2022-07-02 17:14:56 +08:00
|
|
|
|
using RageCoop.Core.Scripting;
|
|
|
|
|
using System.Security.Cryptography;
|
2022-07-01 19:02:38 +08:00
|
|
|
|
using GTA.Math;
|
|
|
|
|
using GTA;
|
|
|
|
|
|
|
|
|
|
namespace RageCoop.Server
|
|
|
|
|
{
|
2022-07-03 10:46:24 +08:00
|
|
|
|
|
2022-07-01 19:02:38 +08:00
|
|
|
|
/// <summary>
|
2022-07-02 17:14:56 +08:00
|
|
|
|
/// Manipulate entities from the server
|
2022-07-01 19:02:38 +08:00
|
|
|
|
/// </summary>
|
2022-07-02 17:14:56 +08:00
|
|
|
|
public class ServerEntities
|
2022-07-01 19:02:38 +08:00
|
|
|
|
{
|
2022-07-02 17:14:56 +08:00
|
|
|
|
private readonly Server Server;
|
|
|
|
|
internal ServerEntities(Server server)
|
2022-07-01 19:02:38 +08:00
|
|
|
|
{
|
2022-07-02 17:14:56 +08:00
|
|
|
|
Server = server;
|
2022-07-01 19:02:38 +08:00
|
|
|
|
}
|
2022-07-02 17:14:56 +08:00
|
|
|
|
internal Dictionary<int, ServerPed> Peds { get; set; } = new();
|
|
|
|
|
internal Dictionary<int, ServerVehicle> Vehicles { get; set; } = new();
|
|
|
|
|
internal Dictionary<int,ServerProp> ServerProps { get; set; }=new();
|
2022-07-03 15:28:28 +08:00
|
|
|
|
internal Dictionary<int,ServerBlip> Blips { get; set; } = new();
|
2022-07-02 17:14:56 +08:00
|
|
|
|
|
2022-07-01 19:02:38 +08:00
|
|
|
|
/// <summary>
|
2022-07-02 17:14:56 +08:00
|
|
|
|
/// Get a <see cref="ServerPed"/> by it's id
|
2022-07-01 19:02:38 +08:00
|
|
|
|
/// </summary>
|
2022-07-02 17:14:56 +08:00
|
|
|
|
/// <param name="id"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public ServerPed GetPedByID(int id)
|
|
|
|
|
{
|
|
|
|
|
if(Peds.TryGetValue(id,out var ped))
|
|
|
|
|
{
|
|
|
|
|
return ped;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-07-01 19:02:38 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
2022-07-02 17:14:56 +08:00
|
|
|
|
/// Get a <see cref="ServerVehicle"/> by it's id
|
2022-07-01 19:02:38 +08:00
|
|
|
|
/// </summary>
|
2022-07-02 17:14:56 +08:00
|
|
|
|
/// <param name="id"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public ServerVehicle GetVehicleByID(int id)
|
|
|
|
|
{
|
|
|
|
|
if (Vehicles.TryGetValue(id, out var veh))
|
|
|
|
|
{
|
|
|
|
|
return veh;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-01 19:02:38 +08:00
|
|
|
|
/// <summary>
|
2022-07-02 17:14:56 +08:00
|
|
|
|
/// Get a <see cref="ServerProp"/> owned by server from it's ID.
|
2022-07-01 19:02:38 +08:00
|
|
|
|
/// </summary>
|
2022-07-02 17:14:56 +08:00
|
|
|
|
/// <param name="id"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public ServerProp GetPropByID(int id)
|
|
|
|
|
{
|
|
|
|
|
if (ServerProps.TryGetValue(id, out var obj))
|
|
|
|
|
{
|
|
|
|
|
return obj;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-07-03 15:28:28 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Get a <see cref="ServerBlip"/> by it's id.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="id"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public ServerBlip GetBlipByID(int id)
|
|
|
|
|
{
|
|
|
|
|
if (Blips.TryGetValue(id, out var obj))
|
|
|
|
|
{
|
|
|
|
|
return obj;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-01 19:02:38 +08:00
|
|
|
|
/// <summary>
|
2022-07-02 17:14:56 +08:00
|
|
|
|
/// Create a static prop owned by server.
|
2022-07-01 19:02:38 +08:00
|
|
|
|
/// </summary>
|
2022-07-02 17:14:56 +08:00
|
|
|
|
/// <param name="model"></param>
|
|
|
|
|
/// <param name="pos"></param>
|
|
|
|
|
/// <param name="rot"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public ServerProp CreateProp(Model model,Vector3 pos,Vector3 rot)
|
2022-07-01 19:02:38 +08:00
|
|
|
|
{
|
2022-07-03 15:28:28 +08:00
|
|
|
|
int id = RequestNetworkID();
|
2022-07-02 17:14:56 +08:00
|
|
|
|
ServerProp prop;
|
|
|
|
|
ServerProps.Add(id,prop=new ServerProp(Server)
|
|
|
|
|
{
|
|
|
|
|
ID=id,
|
|
|
|
|
Model=model,
|
2022-07-03 15:28:28 +08:00
|
|
|
|
_pos=pos,
|
|
|
|
|
_rot=rot
|
2022-07-02 17:14:56 +08:00
|
|
|
|
});
|
2022-07-03 15:28:28 +08:00
|
|
|
|
prop.Update();
|
2022-07-02 17:14:56 +08:00
|
|
|
|
return prop;
|
2022-07-01 19:02:38 +08:00
|
|
|
|
}
|
2022-07-02 17:14:56 +08:00
|
|
|
|
|
2022-07-04 21:29:13 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Create a vehicle
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="owner">Owner of this vehicle</param>
|
|
|
|
|
/// <param name="model">model</param>
|
|
|
|
|
/// <param name="pos">position</param>
|
|
|
|
|
/// <param name="heading">heading of this vehicle</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public ServerVehicle CreateVehicle(Client owner,Model model,Vector3 pos,float heading)
|
|
|
|
|
{
|
|
|
|
|
if(owner == null) { throw new ArgumentNullException("Owner cannot be null"); }
|
|
|
|
|
ServerVehicle veh = new(Server)
|
|
|
|
|
{
|
|
|
|
|
ID=RequestNetworkID(),
|
|
|
|
|
Model=model,
|
|
|
|
|
_pos= pos,
|
|
|
|
|
};
|
|
|
|
|
owner.SendCustomEvent(CustomEvents.CreateVehicle,veh.ID, model, pos, heading);
|
|
|
|
|
Vehicles.Add(veh.ID, veh);
|
|
|
|
|
return veh;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-03 15:28:28 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Create a static <see cref="ServerBlip"/> owned by server.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="pos"></param>
|
|
|
|
|
/// <param name="rotation"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public ServerBlip CreateBlip(Vector3 pos,int rotation)
|
|
|
|
|
{
|
|
|
|
|
var b = new ServerBlip(Server)
|
|
|
|
|
{
|
|
|
|
|
ID=RequestNetworkID(),
|
|
|
|
|
Position=pos,
|
|
|
|
|
Rotation=rotation
|
|
|
|
|
};
|
|
|
|
|
Blips.Add(b.ID,b);
|
|
|
|
|
b.Update();
|
|
|
|
|
return b;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-01 19:02:38 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Get all peds on this server
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public ServerPed[] GetAllPeds()
|
|
|
|
|
{
|
|
|
|
|
return Peds.Values.ToArray();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Get all vehicles on this server
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
2022-07-03 10:46:24 +08:00
|
|
|
|
public ServerVehicle[] GetAllVehicles()
|
2022-07-01 19:02:38 +08:00
|
|
|
|
{
|
|
|
|
|
return Vehicles.Values.ToArray();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2022-07-03 15:28:28 +08:00
|
|
|
|
/// Get all static prop objects owned by server
|
2022-07-01 19:02:38 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
2022-07-02 17:53:35 +08:00
|
|
|
|
public ServerProp[] GetAllProps()
|
2022-07-01 19:02:38 +08:00
|
|
|
|
{
|
2022-07-02 17:14:56 +08:00
|
|
|
|
return ServerProps.Values.ToArray();
|
2022-07-03 15:28:28 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2022-07-03 21:00:05 +08:00
|
|
|
|
/// Get all blips owned by server
|
2022-07-03 15:28:28 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public ServerBlip[] GetAllBlips()
|
|
|
|
|
{
|
|
|
|
|
return Blips.Values.ToArray();
|
|
|
|
|
}
|
2022-07-01 19:02:38 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Not thread safe
|
|
|
|
|
/// </summary>
|
|
|
|
|
internal void Update(Packets.PedSync p,Client sender)
|
|
|
|
|
{
|
|
|
|
|
ServerPed ped;
|
|
|
|
|
if(!Peds.TryGetValue(p.ID,out ped))
|
|
|
|
|
{
|
2022-07-04 09:41:00 +08:00
|
|
|
|
Peds.Add(p.ID,ped=new ServerPed(Server));
|
2022-07-01 19:02:38 +08:00
|
|
|
|
ped.ID=p.ID;
|
|
|
|
|
}
|
2022-07-03 10:46:24 +08:00
|
|
|
|
ped._pos = p.Position;
|
2022-07-01 19:02:38 +08:00
|
|
|
|
ped.Owner=sender;
|
|
|
|
|
ped.Health=p.Health;
|
2022-07-03 10:46:24 +08:00
|
|
|
|
ped._rot=p.Rotation;
|
2022-07-01 19:02:38 +08:00
|
|
|
|
ped.Owner=sender;
|
|
|
|
|
}
|
|
|
|
|
internal void Update(Packets.VehicleSync p, Client sender)
|
|
|
|
|
{
|
|
|
|
|
ServerVehicle veh;
|
|
|
|
|
if (!Vehicles.TryGetValue(p.ID, out veh))
|
|
|
|
|
{
|
2022-07-04 09:41:00 +08:00
|
|
|
|
Vehicles.Add(p.ID, veh=new ServerVehicle(Server));
|
2022-07-01 19:02:38 +08:00
|
|
|
|
veh.ID=p.ID;
|
|
|
|
|
}
|
2022-07-03 10:46:24 +08:00
|
|
|
|
veh._pos = p.Position;
|
2022-07-01 19:02:38 +08:00
|
|
|
|
veh.Owner=sender;
|
2022-07-04 09:41:00 +08:00
|
|
|
|
veh._quat=p.Quaternion;
|
2022-07-01 19:02:38 +08:00
|
|
|
|
}
|
|
|
|
|
internal void Update(Packets.VehicleStateSync p, Client sender)
|
|
|
|
|
{
|
|
|
|
|
ServerVehicle veh;
|
|
|
|
|
if (!Vehicles.TryGetValue(p.ID, out veh))
|
|
|
|
|
{
|
2022-07-04 09:41:00 +08:00
|
|
|
|
Vehicles.Add(p.ID, veh=new ServerVehicle(Server));
|
2022-07-01 19:02:38 +08:00
|
|
|
|
}
|
2022-07-03 10:46:24 +08:00
|
|
|
|
veh.ID=p.ID;
|
|
|
|
|
veh.Owner=sender;
|
|
|
|
|
foreach (var pair in p.Passengers)
|
2022-07-01 19:02:38 +08:00
|
|
|
|
{
|
|
|
|
|
if(Peds.TryGetValue(pair.Value,out var ped))
|
|
|
|
|
{
|
|
|
|
|
ped.LastVehicle=veh;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
internal void CleanUp(Client left)
|
|
|
|
|
{
|
|
|
|
|
Server.Logger?.Trace("Removing all entities from: "+left.Username);
|
|
|
|
|
|
|
|
|
|
foreach (var pair in Peds)
|
|
|
|
|
{
|
|
|
|
|
if (pair.Value.Owner==left)
|
|
|
|
|
{
|
|
|
|
|
Server.QueueJob(()=>Peds.Remove(pair.Key));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
foreach (var pair in Vehicles)
|
|
|
|
|
{
|
|
|
|
|
if (pair.Value.Owner==left)
|
|
|
|
|
{
|
|
|
|
|
Server.QueueJob(() => Vehicles.Remove(pair.Key));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Server.QueueJob(() =>
|
2022-07-02 17:14:56 +08:00
|
|
|
|
Server.Logger?.Trace("Remaining entities: "+(Peds.Count+Vehicles.Count+ServerProps.Count)));
|
2022-07-01 19:02:38 +08:00
|
|
|
|
}
|
|
|
|
|
internal void RemoveVehicle(int id)
|
|
|
|
|
{
|
|
|
|
|
// Server.Logger?.Trace($"Removing vehicle:{id}");
|
|
|
|
|
if (Vehicles.ContainsKey(id)) { Vehicles.Remove(id); }
|
|
|
|
|
}
|
2022-07-03 15:28:28 +08:00
|
|
|
|
|
|
|
|
|
internal void RemoveProp(int id)
|
|
|
|
|
{
|
|
|
|
|
// Server.Logger?.Trace($"Removing vehicle:{id}");
|
|
|
|
|
if (ServerProps.ContainsKey(id)) { ServerProps.Remove(id); }
|
|
|
|
|
}
|
|
|
|
|
internal void RemoveServerBlip(int id)
|
|
|
|
|
{
|
|
|
|
|
// Server.Logger?.Trace($"Removing vehicle:{id}");
|
|
|
|
|
if (Blips.ContainsKey(id)) { Blips.Remove(id); }
|
|
|
|
|
}
|
2022-07-01 19:02:38 +08:00
|
|
|
|
internal void RemovePed(int id)
|
|
|
|
|
{
|
|
|
|
|
// Server.Logger?.Trace($"Removing ped:{id}");
|
|
|
|
|
if (Peds.ContainsKey(id)) { Peds.Remove(id); }
|
|
|
|
|
}
|
2022-07-02 12:39:50 +08:00
|
|
|
|
|
|
|
|
|
internal void Add(ServerPed ped)
|
|
|
|
|
{
|
|
|
|
|
if (Peds.ContainsKey(ped.ID))
|
|
|
|
|
{
|
|
|
|
|
Peds[ped.ID]=ped;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Peds.Add(ped.ID, ped);
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-07-03 15:28:28 +08:00
|
|
|
|
internal int RequestNetworkID()
|
2022-07-02 17:14:56 +08:00
|
|
|
|
{
|
|
|
|
|
int ID = 0;
|
|
|
|
|
while ((ID==0)
|
|
|
|
|
|| ServerProps.ContainsKey(ID)
|
|
|
|
|
|| Peds.ContainsKey(ID)
|
2022-07-03 15:28:28 +08:00
|
|
|
|
|| Vehicles.ContainsKey(ID)
|
|
|
|
|
|| Blips.ContainsKey(ID))
|
2022-07-02 17:14:56 +08:00
|
|
|
|
{
|
|
|
|
|
byte[] rngBytes = new byte[4];
|
|
|
|
|
|
|
|
|
|
RandomNumberGenerator.Create().GetBytes(rngBytes);
|
|
|
|
|
|
|
|
|
|
// Convert the bytes into an integer
|
|
|
|
|
ID = BitConverter.ToInt32(rngBytes, 0);
|
|
|
|
|
}
|
|
|
|
|
return ID;
|
|
|
|
|
}
|
2022-07-01 19:02:38 +08:00
|
|
|
|
}
|
|
|
|
|
}
|