Server side blip and Vector2 argument

This commit is contained in:
Sardelka
2022-07-03 15:28:28 +08:00
parent fa96f4c073
commit 08e17b1714
11 changed files with 270 additions and 33 deletions

View File

@ -20,9 +20,46 @@ namespace RageCoop.Client.Scripting
API.RegisterCustomEventHandler(CustomEvents.DeleteEntity, DeleteEntity);
API.RegisterCustomEventHandler(CustomEvents.SetDisplayNameTag, SetNameTag);
API.RegisterCustomEventHandler(CustomEvents.SetEntity, SetEntity);
API.RegisterCustomEventHandler(CustomEvents.ServerBlipSync, ServerBlipSync);
API.RegisterCustomEventHandler(CustomEvents.DeleteServerBlip, DeleteServerBlip);
API.Events.OnPedDeleted+=(s,p) => { API.SendCustomEvent(CustomEvents.OnPedDeleted,p.ID); };
API.Events.OnVehicleDeleted+=(s, p) => { API.SendCustomEvent(CustomEvents.OnVehicleDeleted, p.ID); };
}
private void DeleteServerBlip(CustomEventReceivedArgs e)
{
if (EntityPool.ServerBlips.TryGetValue((int)e.Args[0], out var blip))
{
EntityPool.ServerBlips.Remove((int)e.Args[0]);
API.QueueAction(()=>{
blip?.Delete();
});
}
}
private void ServerBlipSync(CustomEventReceivedArgs obj)
{
int id= (int)obj.Args[0];
var sprite=(BlipSprite)(short)obj.Args[1];
var color = (BlipColor)(byte)obj.Args[2];
var scale=(Vector2)obj.Args[3];
var pos=(Vector3)obj.Args[4];
int rot= (int)obj.Args[5];
Blip blip;
API.QueueAction(() =>
{
Main.Logger.Debug($"{sprite},{color},{scale},{pos},{rot}");
if (!EntityPool.ServerBlips.TryGetValue(id, out blip))
{
EntityPool.ServerBlips.Add(id, blip=World.CreateBlip(pos));
}
blip.Sprite = sprite;
blip.Color = color;
blip.ScaleX = scale.X;
blip.ScaleY = scale.Y;
blip.Position = pos;
blip.Rotation = rot;
});
}
private void SetEntity(CustomEventReceivedArgs obj)

View File

@ -93,6 +93,26 @@ namespace RageCoop.Client
}
RenderNameTag();
}
// Check if all data avalible
if (!IsReady) { return; }
// Skip update if no new sync message has arrived.
if (!NeedUpdate)
{
return;
}
bool characterExist = (MainPed != null) && MainPed.Exists();
if (!characterExist)
{
CreateCharacter();
return;
}
if (((byte)BlipColor==255) && (PedBlip!=null))
{
PedBlip.Delete();
@ -119,24 +139,6 @@ namespace RageCoop.Client
PedBlip.Color=BlipColor;
}
// Check if all data avalible
if (!IsReady) { return; }
// Skip update if no new sync message has arrived.
if (!NeedUpdate)
{
return;
}
bool characterExist = (MainPed != null) && MainPed.Exists();
if (!characterExist)
{
CreateCharacter();
return;
}
// Need to update state

View File

@ -40,6 +40,10 @@ namespace RageCoop.Client
public static object PropsLock=new object();
public static Dictionary<int,SyncedProp> ServerProps=new Dictionary<int,SyncedProp>();
public static object BlipsLock = new object();
public static Dictionary<int, Blip> ServerBlips = new Dictionary<int, Blip>();
public static void Cleanup(bool keepPlayer=true,bool keepMine=true)
{
foreach(int id in new List<int>(ID_Peds.Keys))
@ -74,6 +78,15 @@ namespace RageCoop.Client
p?.MainProp?.Delete();
}
ServerProps.Clear();
foreach(var b in ServerBlips.Values)
{
if (b.Exists())
{
b.Delete();
}
}
ServerBlips.Clear();
}
#region PEDS

View File

@ -123,6 +123,14 @@ namespace RageCoop.Core
Z = ReadFloat()
};
}
public Vector2 ReadVector2()
{
return new Vector2()
{
X = ReadFloat(),
Y = ReadFloat()
};
}
public Quaternion ReadQuaternion()
{
return new Quaternion()

View File

@ -46,6 +46,8 @@ namespace RageCoop.Core
return (0x12, ((Quaternion)obj).GetBytes());
case GTA.Model _:
return (0x13, BitConverter.GetBytes((GTA.Model)obj));
case Vector2 _:
return (0x14, ((Vector2)obj).GetBytes());
case Tuple<byte, byte[]> _:
var tup = (Tuple<byte, byte[]>)obj;
return (tup.Item1, tup.Item2);
@ -129,6 +131,13 @@ namespace RageCoop.Core
// 12 bytes
return new List<byte[]>() { BitConverter.GetBytes(vec.X), BitConverter.GetBytes(vec.Y), BitConverter.GetBytes(vec.Z) }.Join(4);
}
public static byte[] GetBytes(this Vector2 vec)
{
// 8 bytes
return new List<byte[]>() { BitConverter.GetBytes(vec.X), BitConverter.GetBytes(vec.Y) }.Join(4);
}
/// <summary>
///
/// </summary>

View File

@ -79,6 +79,8 @@ namespace RageCoop.Core
Args.Add(reader.ReadQuaternion()); break;
case 0x13:
Args.Add((GTA.Model)reader.ReadInt()); break;
case 0x14:
Args.Add(reader.ReadVector2()); break;
default:
if (_resolve==null)
{

View File

@ -21,9 +21,11 @@ namespace RageCoop.Core.Scripting
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 ServerBlipSync = Hash("RageCoop.ServerBlipSync");
internal static readonly int SetEntity = Hash("RageCoop.SetEntity");
internal static readonly int DeleteServerProp = Hash("RageCoop.DeleteServerProp");
internal static readonly int DeleteEntity = Hash("RageCoop.DeleteEntity");
internal static readonly int DeleteServerBlip = Hash("RageCoop.DeleteServerBlip");
/// <summary>
/// Get a Int32 hash of a string.
/// </summary>

View File

@ -44,6 +44,13 @@ namespace RageCoop.Server.Scripting
API.SendCustomEvent(CustomEvents.ServerPropSync, new() { obj.ID, obj.Model ,obj.Position,obj.Rotation },clients);
}
}
public void SendServerBlipsTo(List<ServerBlip> objects, List<Client> clients = null)
{
foreach (var obj in objects)
{
API.SendCustomEvent(CustomEvents.ServerBlipSync, new() { obj.ID, (short)obj.Sprite, (byte)obj.Color, obj.Scale,obj.Position,obj.Rotation }, clients);
}
}
void NativeResponse(CustomEventReceivedArgs e)
{
try

View File

@ -638,6 +638,9 @@ namespace RageCoop.Server
// Send all props to this player
BaseScript.SendServerPropsTo( new(Entities.ServerProps.Values), new() { newClient});
// Send all blips to this player
BaseScript.SendServerBlipsTo(new(Entities.Blips.Values), new() { newClient});
// Send new client to all players
var cons = MainNetServer.Connections.Exclude(newClient.Connection);
if (cons.Count!=0)

View File

@ -25,6 +25,7 @@ namespace RageCoop.Server
internal Dictionary<int, ServerPed> Peds { get; set; } = new();
internal Dictionary<int, ServerVehicle> Vehicles { get; set; } = new();
internal Dictionary<int,ServerProp> ServerProps { get; set; }=new();
internal Dictionary<int,ServerBlip> Blips { get; set; } = new();
/// <summary>
/// Get a <see cref="ServerPed"/> by it's id
@ -76,6 +77,24 @@ namespace RageCoop.Server
return null;
}
}
/// <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;
}
}
/// <summary>
/// Create a static prop owned by server.
/// </summary>
@ -85,18 +104,38 @@ namespace RageCoop.Server
/// <returns></returns>
public ServerProp CreateProp(Model model,Vector3 pos,Vector3 rot)
{
int id = RequestID();
int id = RequestNetworkID();
ServerProp prop;
ServerProps.Add(id,prop=new ServerProp(Server)
{
ID=id,
Model=model,
Position=pos,
Rotation=rot
_pos=pos,
_rot=rot
});
prop.Update();
return prop;
}
/// <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;
}
/// <summary>
/// Get all peds on this server
/// </summary>
@ -116,7 +155,7 @@ namespace RageCoop.Server
}
/// <summary>
/// Get all static objects owned by server
/// Get all static prop objects owned by server
/// </summary>
/// <returns></returns>
public ServerProp[] GetAllProps()
@ -124,6 +163,15 @@ namespace RageCoop.Server
return ServerProps.Values.ToArray();
}
/// <summary>
/// Get all static objects owned by server
/// </summary>
/// <returns></returns>
public ServerBlip[] GetAllBlips()
{
return Blips.Values.ToArray();
}
/// <summary>
/// Not thread safe
/// </summary>
@ -196,6 +244,17 @@ namespace RageCoop.Server
// Server.Logger?.Trace($"Removing vehicle:{id}");
if (Vehicles.ContainsKey(id)) { Vehicles.Remove(id); }
}
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); }
}
internal void RemovePed(int id)
{
// Server.Logger?.Trace($"Removing ped:{id}");
@ -213,13 +272,14 @@ namespace RageCoop.Server
Peds.Add(ped.ID, ped);
}
}
internal int RequestID()
internal int RequestNetworkID()
{
int ID = 0;
while ((ID==0)
|| ServerProps.ContainsKey(ID)
|| Peds.ContainsKey(ID)
|| Vehicles.ContainsKey(ID))
|| Vehicles.ContainsKey(ID)
|| Blips.ContainsKey(ID))
{
byte[] rngBytes = new byte[4];

View File

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using GTA;
using GTA.Native;
@ -17,6 +18,8 @@ namespace RageCoop.Server
/// </summary>
public abstract class ServerObject
{
internal ServerObject() { }
/// <summary>
/// Pass this as an argument in CustomEvent or NativeCall to convert this object to handle at client side.
/// </summary>
@ -79,7 +82,7 @@ namespace RageCoop.Server
internal Vector3 _rot;
/// <summary>
/// Send updated information to clients
/// Send updated information to clients, would be called automatically.
/// </summary>
public virtual void Update() {
Owner.SendCustomEvent(CustomEvents.SetEntity, Handle, Position, Rotation);
@ -130,13 +133,14 @@ namespace RageCoop.Server
public override void Delete()
{
Server.API.SendCustomEvent(CustomEvents.DeleteServerProp, new() { ID });
Server.Entities.RemoveProp(ID);
}
/// <summary>
/// Send updated information to clients
/// Send updated information to clients, would be called automatically.
/// </summary>
public override void Update()
{
@ -188,12 +192,102 @@ namespace RageCoop.Server
/// </summary>
public Quaternion Quaternion { get; internal set; }
}
internal class ServerBlip
{
internal ServerBlip()
{
/// <summary>
/// A static blip owned by server.
/// </summary>
public class ServerBlip
{
private readonly Server Server;
internal ServerBlip(Server server)
{
Server = server;
}
/// <summary>
/// Network ID (not handle!)
/// </summary>
public int ID { get; internal set; }
internal BlipColor _color;
/// <summary>
/// Color of this blip
/// </summary>
public BlipColor Color {
get { return _color; }
set { _color=value; Update(); }
}
internal BlipSprite _sprite;
/// <summary>
/// Sprite of this blip
/// </summary>
public BlipSprite Sprite {
get { return _sprite; }
set { _sprite=value; Update();}
}
internal Vector2 _scale=new(1f,1f);
/// <summary>
/// Scale of this blip
/// </summary>
public Vector2 Scale
{
get { return _scale; }
set { _scale=value;Update(); }
}
internal Vector3 _pos = new();
/// <summary>
/// Position of this blip
/// </summary>
public Vector3 Position
{
get { return _pos; }
set { _pos=value; Update(); }
}
internal int _rot;
/// <summary>
/// Scale of this blip
/// </summary>
public int Rotation
{
get { return _rot; }
set { _rot=value; Update(); }
}
/// <summary>
/// Delete this blip
/// </summary>
public void Delete()
{
Server.API.SendCustomEvent(CustomEvents.DeleteServerBlip, new() { ID });
Server.Entities.RemoveServerBlip(ID);
}
private bool _bouncing=false;
internal void Update()
{
// 5ms debounce
if (!_bouncing)
{
_bouncing=true;
Task.Run(() =>
{
Thread.Sleep(5);
DoUpdate();
_bouncing=false;
});
}
}
private void DoUpdate()
{
Server.Logger?.Debug("bee");
// Serve-side blip
Server.BaseScript.SendServerBlipsTo(new() { this });
}
}
}