using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using RageCoop.Core; using GTA.Math; using GTA; namespace RageCoop.Server { /// /// Represents a ped from a client /// public class ServerPed { /// /// The that is responsible synchronizing for this ped. /// public Client Owner { get; internal set; } /// /// The ped's network ID (not handle!). /// public int ID { get; internal set; } /// /// Whether this ped is a player. /// public bool IsPlayer { get { return Owner?.Player==this; } } /// /// The ped's last vehicle. /// public ServerVehicle LastVehicle { get; internal set; } /// /// Position of this ped /// public Vector3 Position { get; internal set; } /// /// Gets or sets this ped's rotation /// public Vector3 Rotation { get; internal set; } /// /// Health /// public int Health { get; internal set; } } /// /// Represents a vehicle from a client /// public class ServerVehicle { /// /// The that is responsible synchronizing for this vehicle. /// public Client Owner { get; internal set; } /// /// The vehicle's network ID (not handle!). /// public int ID { get; internal set; } /// /// Position of this vehicle /// public Vector3 Position { get; internal set; } /// /// Gets or sets this vehicle's quaternion /// public Quaternion Quaternion { get; internal set; } } /// /// Represents an object owned by server. /// public class ServerObject { internal ServerObject() { } /// /// The object's model /// public Model Model { get; internal set; } /// /// Gets or sets this object's position /// public Vector3 Position { get;set; } /// /// Gets or sets this object's quaternion /// public Quaternion Quaternion { get; set; } /// /// Whether this object is invincible /// public bool IsInvincible { get; set; } } /// /// Manipulate entities from the server /// public class ServerEntities { private readonly Server Server; internal ServerEntities(Server server) { Server = server; } internal Dictionary Peds { get; set; } = new(); internal Dictionary Vehicles { get; set; } = new(); internal Dictionary ServerObjects { get; set; }=new(); /// /// Get all peds on this server /// /// public ServerPed[] GetAllPeds() { return Peds.Values.ToArray(); } /// /// Get all vehicles on this server /// /// public ServerVehicle[] GetAllVehicle() { return Vehicles.Values.ToArray(); } /// /// Get all static objects owned by server /// /// public ServerObject[] GetAllObjects() { return ServerObjects.Values.ToArray(); } /// /// Not thread safe /// internal void Update(Packets.PedSync p,Client sender) { ServerPed ped; if(!Peds.TryGetValue(p.ID,out ped)) { Peds.Add(p.ID,ped=new ServerPed()); ped.ID=p.ID; } ped.Position = p.Position; ped.Owner=sender; ped.Health=p.Health; ped.Rotation=p.Rotation; ped.Owner=sender; } internal void Update(Packets.VehicleSync p, Client sender) { ServerVehicle veh; if (!Vehicles.TryGetValue(p.ID, out veh)) { Vehicles.Add(p.ID, veh=new ServerVehicle()); veh.ID=p.ID; } veh.Position = p.Position; veh.Owner=sender; veh.Quaternion=p.Quaternion; } internal void Update(Packets.VehicleStateSync p, Client sender) { ServerVehicle veh; if (!Vehicles.TryGetValue(p.ID, out veh)) { Vehicles.Add(p.ID, veh=new ServerVehicle()); veh.ID=p.ID; } foreach(var pair in p.Passengers) { 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(() => Server.Logger?.Trace("Remaining entities: "+(Peds.Count+Vehicles.Count))); } internal void RemoveVehicle(int id) { // Server.Logger?.Trace($"Removing vehicle:{id}"); if (Vehicles.ContainsKey(id)) { Vehicles.Remove(id); } } internal void RemovePed(int id) { // Server.Logger?.Trace($"Removing ped:{id}"); if (Peds.ContainsKey(id)) { Peds.Remove(id); } } } }