From dc5cf2b965488506cc59a9b7e1aedd489326c3a5 Mon Sep 17 00:00:00 2001 From: Sardelka Date: Sun, 3 Jul 2022 10:46:24 +0800 Subject: [PATCH] ServerObject Inheritance, getter and setter for Position and Roatation, Fix connect error. --- RageCoop.Client/Networking/DownloadManager.cs | 8 +- RageCoop.Client/Networking/Networking.cs | 1 + RageCoop.Client/Networking/Receive.cs | 1 + RageCoop.Client/Networking/Send.cs | 14 +- RageCoop.Client/PlayerList.cs | 12 +- RageCoop.Client/Scripting/API.cs | 6 + RageCoop.Client/Scripting/BaseScript.cs | 35 ++- RageCoop.Client/Sync/Entities/SyncedPed.cs | 45 ++-- .../Sync/Entities/SyncedProjectile.cs | 7 +- RageCoop.Client/Sync/EntityPool.cs | 9 +- RageCoop.Client/Util/PedExtensions.cs | 1 + RageCoop.Client/Util/Util.cs | 1 + .../Util => RageCoop.Core}/MathExtensions.cs | 5 +- RageCoop.Core/Packets/Packets.cs | 2 +- RageCoop.Core/Packets/PedPackets.cs | 8 +- RageCoop.Core/Packets/PlayerPackets.cs | 12 - RageCoop.Core/Scripting/CustomEvents.cs | 4 +- RageCoop.Server/Client.cs | 75 +++---- RageCoop.Server/Scripting/BaseScript.cs | 10 +- RageCoop.Server/Server.cs | 5 +- RageCoop.Server/ServerEntities.cs | 173 +-------------- RageCoop.Server/ServerObject.cs | 206 ++++++++++++++++++ 22 files changed, 361 insertions(+), 279 deletions(-) rename {RageCoop.Client/Util => RageCoop.Core}/MathExtensions.cs (96%) create mode 100644 RageCoop.Server/ServerObject.cs diff --git a/RageCoop.Client/Networking/DownloadManager.cs b/RageCoop.Client/Networking/DownloadManager.cs index fddb025..703738c 100644 --- a/RageCoop.Client/Networking/DownloadManager.cs +++ b/RageCoop.Client/Networking/DownloadManager.cs @@ -158,9 +158,13 @@ namespace RageCoop.Client } InProgressDownloads.Clear(); } - foreach (var zip in Directory.GetDirectories(ResourceFolder, "*.zip")) + if (Directory.Exists(ResourceFolder)) { - File.Delete(zip); + + foreach (var zip in Directory.GetDirectories(ResourceFolder, "*.zip")) + { + File.Delete(zip); + } } } diff --git a/RageCoop.Client/Networking/Networking.cs b/RageCoop.Client/Networking/Networking.cs index 5a12b5e..5e4010b 100644 --- a/RageCoop.Client/Networking/Networking.cs +++ b/RageCoop.Client/Networking/Networking.cs @@ -97,6 +97,7 @@ namespace RageCoop.Client catch(Exception ex) { Main.Logger.Error("Cannot connect to server", ex); + Main.QueueAction(() => GTA.UI.Notification.Show("Cannot connect to server"+ex.Message)); } }); diff --git a/RageCoop.Client/Networking/Receive.cs b/RageCoop.Client/Networking/Receive.cs index 27e0aba..16e8fc6 100644 --- a/RageCoop.Client/Networking/Receive.cs +++ b/RageCoop.Client/Networking/Receive.cs @@ -333,6 +333,7 @@ namespace RageCoop.Client c.WeaponTint=packet.WeaponTint; c.ModelHash=packet.ModelHash; c.LastStateSynced = Main.Ticked; + c.BlipColor=packet.BlipColor; } private static void VehicleSync(Packets.VehicleSync packet) { diff --git a/RageCoop.Client/Networking/Send.cs b/RageCoop.Client/Networking/Send.cs index 3fdca49..1675d6b 100644 --- a/RageCoop.Client/Networking/Send.cs +++ b/RageCoop.Client/Networking/Send.cs @@ -53,16 +53,24 @@ namespace RageCoop.Client { Ped p = c.MainPed; - var packet=new Packets.PedStateSync() + var packet = new Packets.PedStateSync() { ID = c.ID, OwnerID=c.OwnerID, Clothes=p.GetPedClothes(), ModelHash=p.Model.Hash, WeaponComponents=p.Weapons.Current.GetWeaponComponents(), - WeaponTint=(byte)Function.Call(Hash.GET_PED_WEAPON_TINT_INDEX, p, p.Weapons.Current.Hash) + WeaponTint=(byte)Function.Call(Hash.GET_PED_WEAPON_TINT_INDEX, p, p.Weapons.Current.Hash), }; - + Blip b; + if (c.IsPlayer) + { + packet.BlipColor=Scripting.API.Config.BlipColor; + } + else if ((b = p.AttachedBlip) !=null) + { + packet.BlipColor=b.Color; + } Send(packet, ConnectionChannel.PedSync); } public static void SendVehicle(SyncedVehicle v) diff --git a/RageCoop.Client/PlayerList.cs b/RageCoop.Client/PlayerList.cs index 0bd57e3..f14a5d3 100644 --- a/RageCoop.Client/PlayerList.cs +++ b/RageCoop.Client/PlayerList.cs @@ -80,17 +80,7 @@ namespace RageCoop.Client var p = GetPlayer(packet.PedID); if(p?.Character != null) { - p.Character.DisplayNameTag=packet.Flags.HasConfigFlag(PlayerConfigFlags.ShowNameTag); - p.Character.DisplayBlip=packet.Flags.HasConfigFlag(PlayerConfigFlags.ShowBlip); - Main.Logger.Info($"blip color:{packet.BlipColor}"); - // Need to be dispatched to script thread. - Main.QueueAction(() => { - if (p.Character.PedBlip!=null && p.Character.PedBlip.Exists() && p.Character.PedBlip.Color!=packet.BlipColor) - { - p.Character.PedBlip.Color=packet.BlipColor; - } - }); - + p.Latency= packet.Latency; } } public static PlayerData GetPlayer(int id) diff --git a/RageCoop.Client/Scripting/API.cs b/RageCoop.Client/Scripting/API.cs index b17a289..01db6b8 100644 --- a/RageCoop.Client/Scripting/API.cs +++ b/RageCoop.Client/Scripting/API.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System; using System.Linq; using RageCoop.Core; +using GTA; namespace RageCoop.Client.Scripting { @@ -52,6 +53,11 @@ namespace RageCoop.Client.Scripting /// Enable automatic respawn for this player. /// public static bool EnableAutoRespawn { get; set; } = true; + + /// + /// Get or set player's blip color + /// + public static BlipColor BlipColor { get; set; } = BlipColor.White; } /// /// Base events for RageCoop diff --git a/RageCoop.Client/Scripting/BaseScript.cs b/RageCoop.Client/Scripting/BaseScript.cs index d9afbdc..d21544e 100644 --- a/RageCoop.Client/Scripting/BaseScript.cs +++ b/RageCoop.Client/Scripting/BaseScript.cs @@ -17,14 +17,40 @@ namespace RageCoop.Client.Scripting API.RegisterCustomEventHandler(CustomEvents.NativeCall,NativeCall); API.RegisterCustomEventHandler(CustomEvents.ServerPropSync, ServerObjectSync); API.RegisterCustomEventHandler(CustomEvents.DeleteServerProp, DeleteServerProp); + API.RegisterCustomEventHandler(CustomEvents.DeleteEntity, DeleteEntity); + API.RegisterCustomEventHandler(CustomEvents.SetDisplayNameTag, SetNameTag); + API.RegisterCustomEventHandler(CustomEvents.SetEntity, SetEntity); API.Events.OnPedDeleted+=(s,p) => { API.SendCustomEvent(CustomEvents.OnPedDeleted,p.ID); }; API.Events.OnVehicleDeleted+=(s, p) => { API.SendCustomEvent(CustomEvents.OnVehicleDeleted, p.ID); }; } + private void SetEntity(CustomEventReceivedArgs obj) + { + Main.QueueAction(() => + { + var e=Entity.FromHandle((int)obj.Args[0]); + e.Position = (Vector3)obj.Args[1]; + e.Rotation = (Vector3)obj.Args[2]; + }); + } + + private void DeleteEntity(CustomEventReceivedArgs e) + { + Entity.FromHandle((int)e.Args[0]).Delete(); + } + public override void OnStop() { } + private void SetNameTag(CustomEventReceivedArgs e) + { + var p = EntityPool.GetPedByID((int)e.Args[0]); + if(p!= null) + { + p.DisplayNameTag=(bool)e.Args[1]; + } + } private void SetAutoRespawn(CustomEventReceivedArgs args) { API.Config.EnableAutoRespawn=(bool)args.Args[0]; @@ -42,15 +68,18 @@ namespace RageCoop.Client.Scripting { SyncedProp prop; var id = (int)e.Args[0]; - if (!EntityPool.ServerProps.TryGetValue(id,out prop)) + lock (EntityPool.PropsLock) { - EntityPool.ServerProps.Add(id,prop=new SyncedProp(id)); + if (!EntityPool.ServerProps.TryGetValue(id, out prop)) + { + EntityPool.ServerProps.Add(id, prop=new SyncedProp(id)); + } } prop.LastSynced=Main.Ticked+1; prop.ModelHash= (Model)e.Args[1]; prop.Position=(Vector3)e.Args[2]; prop.Rotation=(Vector3)e.Args[3]; - Main.Logger.Trace($"{Main.Ticked},{(VehicleHash)prop.ModelHash},{prop.Position},{prop.Rotation}"); + Main.QueueAction(() => { prop.Update(); }); } private void NativeCall(CustomEventReceivedArgs e) { diff --git a/RageCoop.Client/Sync/Entities/SyncedPed.cs b/RageCoop.Client/Sync/Entities/SyncedPed.cs index 7302a69..d0e3b4c 100644 --- a/RageCoop.Client/Sync/Entities/SyncedPed.cs +++ b/RageCoop.Client/Sync/Entities/SyncedPed.cs @@ -48,7 +48,7 @@ namespace RageCoop.Client #region PLAYER -- ONLY internal string Username = "N/A"; internal Blip PedBlip = null; - internal bool DisplayBlip { get; set; } = true; + internal BlipColor BlipColor = (BlipColor)255; internal bool DisplayNameTag { get; set; } = true; #endregion @@ -88,20 +88,36 @@ namespace RageCoop.Client if (p!=null) { Username=p.Username; - if (PedBlip!=null) - { - PedBlip.Name=Username; - } } } - if((!DisplayBlip) && (PedBlip!=null)) - { - PedBlip.Delete(); - PedBlip=null; - } RenderNameTag(); } + if (((byte)BlipColor==255) && (PedBlip!=null)) + { + PedBlip.Delete(); + PedBlip=null; + } + else if(PedBlip==null) + { + PedBlip=MainPed.AddBlip(); + if (IsPlayer) + { + Main.QueueAction(() => + { + if (Username=="N/A") + { + return false; + } + else + { + PedBlip.Name=Username; + return true; + } + }); + } + PedBlip.Color=BlipColor; + } // Check if all data avalible if (!IsReady) { return; } @@ -269,15 +285,6 @@ namespace RageCoop.Client if (IsPlayer) { - if (DisplayBlip) - { - // Add a new blip for the ped - PedBlip=MainPed.AddBlip(); - MainPed.AttachedBlip.Color = BlipColor.White; - MainPed.AttachedBlip.Scale = 0.8f; - MainPed.AttachedBlip.Name =Username; - } - MainPed.IsInvincible=true; } if (IsInvincible) { MainPed.IsInvincible=true; } diff --git a/RageCoop.Client/Sync/Entities/SyncedProjectile.cs b/RageCoop.Client/Sync/Entities/SyncedProjectile.cs index d0412e3..cf478f5 100644 --- a/RageCoop.Client/Sync/Entities/SyncedProjectile.cs +++ b/RageCoop.Client/Sync/Entities/SyncedProjectile.cs @@ -5,6 +5,7 @@ using System.Text; using System.Threading.Tasks; using GTA; using GTA.Math; +using RageCoop.Core; namespace RageCoop.Client { @@ -37,17 +38,17 @@ namespace RageCoop.Client IsValid=false; } ShooterID=shooter.ID; - IsMine=shooter.IsLocal; + IsLocal=shooter.IsLocal; } } public SyncedProjectile(int id) { ID= id; - IsMine=false; + IsLocal=false; } public bool IsValid { get; private set; } = true; - public new bool IsMine { get; private set; } = false; + public new bool IsLocal { get; private set; } = false; public bool Exploded { get; set; } = false; public Projectile MainProjectile { get; set; } public int ShooterID { get; set; } diff --git a/RageCoop.Client/Sync/EntityPool.cs b/RageCoop.Client/Sync/EntityPool.cs index a94aa15..e150622 100644 --- a/RageCoop.Client/Sync/EntityPool.cs +++ b/RageCoop.Client/Sync/EntityPool.cs @@ -352,7 +352,7 @@ namespace RageCoop.Client { // Outgoing sync - if (p.IsMine) + if (p.IsLocal) { if (p.MainProjectile.AttachedEntity==null) { @@ -530,13 +530,6 @@ namespace RageCoop.Client } - lock (PropsLock) - { - foreach (var p in ServerProps.Values) - { - p.Update(); - } - } #if BENCHMARK Debug.TimeStamps[TimeStamp.VehicleTotal]=PerfCounter.ElapsedTicks; #endif diff --git a/RageCoop.Client/Util/PedExtensions.cs b/RageCoop.Client/Util/PedExtensions.cs index 5717e3e..0b6855d 100644 --- a/RageCoop.Client/Util/PedExtensions.cs +++ b/RageCoop.Client/Util/PedExtensions.cs @@ -139,6 +139,7 @@ namespace RageCoop.Client { flags |= PedDataFlags.IsInStealthMode; } + return flags; } diff --git a/RageCoop.Client/Util/Util.cs b/RageCoop.Client/Util/Util.cs index 0b745b3..a61b627 100644 --- a/RageCoop.Client/Util/Util.cs +++ b/RageCoop.Client/Util/Util.cs @@ -5,6 +5,7 @@ using System.Text; using System.Threading.Tasks; using GTA.Math; using GTA; +using RageCoop.Core; using GTA.Native; using System.IO; using System.Xml.Serialization; diff --git a/RageCoop.Client/Util/MathExtensions.cs b/RageCoop.Core/MathExtensions.cs similarity index 96% rename from RageCoop.Client/Util/MathExtensions.cs rename to RageCoop.Core/MathExtensions.cs index 2836f29..0c7a479 100644 --- a/RageCoop.Client/Util/MathExtensions.cs +++ b/RageCoop.Core/MathExtensions.cs @@ -1,11 +1,13 @@ using System; using GTA.Math; -namespace RageCoop.Client +namespace RageCoop.Core { internal static class MathExtensions { + public const float Deg2Rad=(float)(Math.PI* 2) / 360; + public const float Rad2Deg = 360 / (float)(Math.PI * 2); /// /// /// @@ -145,5 +147,6 @@ namespace RageCoop.Client return Vector3.Dot(v1, v2)/(v1.Length()*v2.Length()); } + } } diff --git a/RageCoop.Core/Packets/Packets.cs b/RageCoop.Core/Packets/Packets.cs index c503086..7559e09 100644 --- a/RageCoop.Core/Packets/Packets.cs +++ b/RageCoop.Core/Packets/Packets.cs @@ -94,7 +94,7 @@ namespace RageCoop.Core IsParachuteOpen = 1 << 7, IsOnLadder = 1 << 8, IsVaulting = 1 << 9, - IsInCover = 1<< 10, + IsInCover = 1 << 10, } #region ===== VEHICLE DATA ===== diff --git a/RageCoop.Core/Packets/PedPackets.cs b/RageCoop.Core/Packets/PedPackets.cs index e5a12e8..1890fb8 100644 --- a/RageCoop.Core/Packets/PedPackets.cs +++ b/RageCoop.Core/Packets/PedPackets.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Text; using GTA.Math; +using GTA; using Lidgren.Network; namespace RageCoop.Core @@ -23,8 +24,9 @@ namespace RageCoop.Core public int OwnerID { get; set; } public Dictionary WeaponComponents { get; set; } - + public byte WeaponTint { get;set; } + public BlipColor BlipColor { get; set; } = (BlipColor)255; public override void Pack(NetOutgoingMessage message) @@ -64,6 +66,8 @@ namespace RageCoop.Core byteArray.Add(WeaponTint); + byteArray.Add((byte)BlipColor); + byte[] result = byteArray.ToArray(); message.Write(result.Length); message.Write(result); @@ -98,6 +102,8 @@ namespace RageCoop.Core } } WeaponTint=reader.ReadByte(); + + BlipColor=(BlipColor)reader.ReadByte(); #endregion } } diff --git a/RageCoop.Core/Packets/PlayerPackets.cs b/RageCoop.Core/Packets/PlayerPackets.cs index ce24218..9b68f1c 100644 --- a/RageCoop.Core/Packets/PlayerPackets.cs +++ b/RageCoop.Core/Packets/PlayerPackets.cs @@ -176,8 +176,6 @@ namespace RageCoop.Core public int PedID { get; set; } public string Username { get; set; } public float Latency { get; set; } - public PlayerConfigFlags Flags { get; set; } - public GTA.BlipColor BlipColor { get; set; } public override void Pack(NetOutgoingMessage message) { #region PacketToNetOutGoingMessage @@ -201,12 +199,6 @@ namespace RageCoop.Core // Write Latency byteArray.AddFloat(Latency); - // Write Flags - byteArray.Add((byte)Flags); - - // Write BlipColor - byteArray.Add((byte)BlipColor); - byte[] result = byteArray.ToArray(); message.Write(result.Length); @@ -226,10 +218,6 @@ namespace RageCoop.Core Username = reader.ReadString(usernameLength); Latency=reader.ReadFloat(); - - Flags=(PlayerConfigFlags)reader.ReadByte(); - - BlipColor=(GTA.BlipColor)reader.ReadByte(); } } diff --git a/RageCoop.Core/Scripting/CustomEvents.cs b/RageCoop.Core/Scripting/CustomEvents.cs index 8776ec7..18b0241 100644 --- a/RageCoop.Core/Scripting/CustomEvents.cs +++ b/RageCoop.Core/Scripting/CustomEvents.cs @@ -16,12 +16,14 @@ namespace RageCoop.Core.Scripting internal static readonly int OnPedDeleted = Hash("RageCoop.OnPedDeleted"); internal static readonly int OnVehicleDeleted = Hash("RageCoop.OnVehicleDeleted"); internal static readonly int SetAutoRespawn = Hash("RageCoop.SetAutoRespawn"); + internal static readonly int SetDisplayNameTag = Hash("RageCoop.SetDisplayNameTag"); internal static readonly int NativeCall = Hash("RageCoop.NativeCall"); internal static readonly int NativeResponse = Hash("RageCoop.NativeResponse"); internal static readonly int AllResourcesSent = Hash("RageCoop.AllResourcesSent"); internal static readonly int ServerPropSync = Hash("RageCoop.ServerPropSync"); + internal static readonly int SetEntity = Hash("RageCoop.SetEntity"); internal static readonly int DeleteServerProp = Hash("RageCoop.DeleteServerProp"); - + internal static readonly int DeleteEntity = Hash("RageCoop.DeleteEntity"); /// /// Get a Int32 hash of a string. /// diff --git a/RageCoop.Server/Client.cs b/RageCoop.Server/Client.cs index 5137672..bc338d9 100644 --- a/RageCoop.Server/Client.cs +++ b/RageCoop.Server/Client.cs @@ -3,48 +3,12 @@ using System.Collections.Generic; using RageCoop.Core; using Lidgren.Network; using System.Linq; +using GTA; using RageCoop.Core.Scripting; using System.Security.Cryptography; namespace RageCoop.Server { - /// - /// - /// - public class PlayerConfig - { - #region CLIENT - /// - /// Whether to enable automatic respawn for this player. if set to false, player will just lay on the ground when it's dead - /// - public bool EnableAutoRespawn { get; set; }=true; - #endregion - /// - /// Whether to show the player's blip on map. - /// - public bool ShowBlip { get; set; } = true; - /// - /// Whether the player's nametag is visible to other players. - /// - public bool ShowNameTag { get; set; } = true; - /// - /// The blip's color. - /// - public GTA.BlipColor BlipColor { get; set; } = GTA.BlipColor.White; - internal PlayerConfigFlags GetFlags() - { - var flag=PlayerConfigFlags.None; - if (ShowBlip) - { - flag|= PlayerConfigFlags.ShowBlip; - } - if (ShowNameTag) - { - flag |= PlayerConfigFlags.ShowNameTag; - } - return flag; - } - } /// /// Represent a player connected to this server. /// @@ -69,12 +33,6 @@ namespace RageCoop.Server /// The client's latency in seconds. /// public float Latency { get; internal set; } - private PlayerConfig _config { get; set; }=new PlayerConfig(); - /// - /// The client's configuration - /// - public PlayerConfig Config { get { return _config; }set { _config=value;Server.SendPlayerInfos(); } } - internal readonly Dictionary> Callbacks = new(); internal byte[] PublicKey { get; set; } /// @@ -82,9 +40,38 @@ namespace RageCoop.Server /// public bool IsReady { get; internal set; }=false; /// - /// + /// The client's username. /// public string Username { get;internal set; } = "N/A"; + + + private bool _autoRespawn=true; + + /// + /// Gets or sets whether to enable automatic respawn for this client's main ped. + /// + public bool EnableAutoRespawn { + get { return _autoRespawn; } + set { + Server.BaseScript.SetAutoRespawn(this,value); + _autoRespawn=value; + } + } + + private bool _displayNameTag=true; + + /// + /// Gets or sets whether to enable automatic respawn for this client's main ped. + /// + public bool DisplayNameTag + { + get { return _displayNameTag; } + set + { + Server.BaseScript.SetNameTag(this,value); + _displayNameTag=value; + } + } #region CUSTOMDATA FUNCTIONS /* public void SetData(string name, T data) diff --git a/RageCoop.Server/Scripting/BaseScript.cs b/RageCoop.Server/Scripting/BaseScript.cs index d08fc91..45664fe 100644 --- a/RageCoop.Server/Scripting/BaseScript.cs +++ b/RageCoop.Server/Scripting/BaseScript.cs @@ -29,7 +29,15 @@ namespace RageCoop.Server.Scripting { c.SendCustomEvent(CustomEvents.SetAutoRespawn, toggle ); } - public void SendServerObjectsTo(List objects,List clients=null) + public void SetNameTag(Client c, bool toggle) + { + foreach(var other in API.GetAllClients().Values) + { + if (c==other) { continue; } + other.SendCustomEvent(CustomEvents.SetDisplayNameTag,c.Player.ID, toggle); + } + } + public void SendServerPropsTo(List objects,List clients=null) { foreach(var obj in objects) { diff --git a/RageCoop.Server/Server.cs b/RageCoop.Server/Server.cs index 78fac0f..43703ff 100644 --- a/RageCoop.Server/Server.cs +++ b/RageCoop.Server/Server.cs @@ -511,7 +511,6 @@ namespace RageCoop.Server { foreach (Client c in Clients.Values) { - BaseScript.SetAutoRespawn(c,c.Config.EnableAutoRespawn); MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != c.NetID).ForEach(x => { NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage(); @@ -520,8 +519,6 @@ namespace RageCoop.Server PedID=c.Player.ID, Username=c.Username, Latency=c.Latency, - Flags=c.Config.GetFlags(), - BlipColor=c.Config.BlipColor, }.Pack(outgoingMessage); MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.ReliableSequenced, (byte)ConnectionChannel.Default); }); @@ -639,7 +636,7 @@ namespace RageCoop.Server }); // Send all props to this player - BaseScript.SendServerObjectsTo( new(Entities.ServerProps.Values), new() { newClient}); + BaseScript.SendServerPropsTo( new(Entities.ServerProps.Values), new() { newClient}); // Send new client to all players var cons = MainNetServer.Connections.Exclude(newClient.Connection); diff --git a/RageCoop.Server/ServerEntities.cs b/RageCoop.Server/ServerEntities.cs index 1f515e7..65b4265 100644 --- a/RageCoop.Server/ServerEntities.cs +++ b/RageCoop.Server/ServerEntities.cs @@ -11,165 +11,7 @@ using GTA; namespace RageCoop.Server { - /// - /// Represents an prop owned by server. - /// - public class ServerProp - { - private Server Server; - internal ServerProp(Server server) - { - Server= server; - } - - - /// - /// Pass this as an argument in CustomEvent or NativeCall to convert this object to handle at client side. - /// - public Tuple Handle - { - get - { - return new(50, BitConverter.GetBytes(ID)); - } - } - - /// - /// Delete this prop - /// - public void Delete() - { - Server.API.SendCustomEvent(CustomEvents.DeleteServerProp, new() { ID }); - } - - /// - /// Network ID of this object. - /// - public int ID { get; internal set; } - - /// - /// The object's model - /// - public Model Model { get; internal set; } - - /// - /// Gets or sets this object's position - /// - public Vector3 Position - { - get { return _pos; } - set { _pos=value; Server.BaseScript.SendServerObjectsTo(new() { this }); } - } - private Vector3 _pos; - - /// - /// Gets or sets this object's rotation - /// - public Vector3 Rotation - { - get { return _rot; } - set { _rot=value; Server.BaseScript.SendServerObjectsTo(new() { this }); } - } - private Vector3 _rot; - } - /// - /// Represents a ped from a client - /// - public class ServerPed - { - internal ServerPed() - { - - } - - /// - /// Pass this as an argument in CustomEvent or NativeCall to convert this object to handle at client side. - /// - public Tuple Handle - { - get - { - return new(51, BitConverter.GetBytes(ID)); - } - } - - /// - /// 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 - { - internal ServerVehicle() - { - - } - - /// - /// Pass this as an argument in CustomEvent or NativeCall to convert this object to handle at client side. - /// - public Tuple Handle - { - get{ - return new(52, BitConverter.GetBytes(ID)); - } - } - - /// - /// 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; } - } - + /// /// Manipulate entities from the server /// @@ -268,7 +110,7 @@ namespace RageCoop.Server /// Get all vehicles on this server /// /// - public ServerVehicle[] GetAllVehicle() + public ServerVehicle[] GetAllVehicles() { return Vehicles.Values.ToArray(); } @@ -293,10 +135,10 @@ namespace RageCoop.Server Peds.Add(p.ID,ped=new ServerPed()); ped.ID=p.ID; } - ped.Position = p.Position; + ped._pos = p.Position; ped.Owner=sender; ped.Health=p.Health; - ped.Rotation=p.Rotation; + ped._rot=p.Rotation; ped.Owner=sender; } internal void Update(Packets.VehicleSync p, Client sender) @@ -307,7 +149,7 @@ namespace RageCoop.Server Vehicles.Add(p.ID, veh=new ServerVehicle()); veh.ID=p.ID; } - veh.Position = p.Position; + veh._pos = p.Position; veh.Owner=sender; veh.Quaternion=p.Quaternion; } @@ -317,9 +159,10 @@ namespace RageCoop.Server if (!Vehicles.TryGetValue(p.ID, out veh)) { Vehicles.Add(p.ID, veh=new ServerVehicle()); - veh.ID=p.ID; } - foreach(var pair in p.Passengers) + veh.ID=p.ID; + veh.Owner=sender; + foreach (var pair in p.Passengers) { if(Peds.TryGetValue(pair.Value,out var ped)) { diff --git a/RageCoop.Server/ServerObject.cs b/RageCoop.Server/ServerObject.cs new file mode 100644 index 0000000..610e2d5 --- /dev/null +++ b/RageCoop.Server/ServerObject.cs @@ -0,0 +1,206 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using GTA; +using GTA.Math; +using RageCoop.Core; +using RageCoop.Core.Scripting; + +namespace RageCoop.Server +{ + + /// + /// Server-side object controller + /// + public abstract class ServerObject + { + /// + /// Pass this as an argument in CustomEvent or NativeCall to convert this object to handle at client side. + /// + public Tuple Handle + { + get + { + return new(GetTypeByte(), BitConverter.GetBytes(ID)); + } + } + + private byte GetTypeByte() + { + switch (this) + { + case ServerProp _: + return 50; + case ServerPed _: + return 51; + case ServerVehicle _: + return 52; + default: + throw new NotImplementedException(); + } + } + + /// + /// The client that owns this object, null if it's owned by server. + /// + public Client Owner { get; internal set; } + + /// + /// Network ID of this object. + /// + public int ID { get; internal set; } + + /// + /// The object's model + /// + public Model Model { get; internal set; } + + /// + /// Gets or sets this object's position + /// + public virtual Vector3 Position + { + get { return _pos; } + set { _pos=value; Update(); } + } + internal Vector3 _pos; + + /// + /// Gets or sets this object's rotation + /// + public virtual Vector3 Rotation + { + get { return _rot; } + set { _rot=value; Update(); } + } + internal Vector3 _rot; + + /// + /// Send updated information to clients + /// + public virtual void Update() { + Owner.SendCustomEvent(CustomEvents.SetEntity, Handle, Position, Rotation); + } + + /// + /// Delete this object + /// + public virtual void Delete() + { + Owner?.SendCustomEvent(CustomEvents.DeleteEntity, Handle); + } + } + /// + /// Represents an prop owned by server. + /// + public class ServerProp : ServerObject + { + private Server Server; + internal ServerProp(Server server) + { + Server= server; + } + + + + + /// + /// Delete this prop + /// + public override void Delete() + { + Server.API.SendCustomEvent(CustomEvents.DeleteServerProp, new() { ID }); + } + + + + + /// + /// Send updated information to clients + /// + public override void Update() + { + Server.BaseScript.SendServerPropsTo(new() { this }); + } + } + /// + /// Represents a ped from a client + /// + public class ServerPed : ServerObject + { + internal ServerPed() + { + + } + + /// + /// Get the ped's last vehicle + /// + public ServerVehicle LastVehicle { get; internal set; } + + /// + /// Health + /// + public int Health { get; internal set; } + } + /// + /// Represents a vehicle from a client + /// + public class ServerVehicle : ServerObject + { + internal ServerVehicle() + { + + } + + /// + /// Gets or sets vehicle rotation + /// + public override Vector3 Rotation + { + get { return Quaternion.ToEulerAngles().ToDegree(); } + set { Quaternion=value.ToQuaternion(); Update(); } + } + + /// + /// Get this vehicle's quaternion + /// + public Quaternion Quaternion { get; internal set; } + } + internal class ServerBlip : ServerObject + { + internal ServerBlip() + { + + } + + /// + /// Invalid + /// + private new Vector3 Rotation { get; set; } + + BlipColor _color; + public BlipColor Color { + get { + return _color; + } + set { + if(Owner != null) + { + + } + else + { + throw new NotImplementedException(); + } + _color = value; + } + } + private new Vector2 Position + { + get; set; + } + } +}