2022-07-03 10:46:24 +08:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
2022-07-03 15:28:28 +08:00
|
|
|
|
using System.Threading;
|
2022-07-03 10:46:24 +08:00
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using GTA;
|
2022-07-03 10:55:49 +08:00
|
|
|
|
using GTA.Native;
|
2022-07-03 10:46:24 +08:00
|
|
|
|
using GTA.Math;
|
|
|
|
|
using RageCoop.Core;
|
|
|
|
|
using RageCoop.Core.Scripting;
|
|
|
|
|
|
2022-07-07 16:57:43 +08:00
|
|
|
|
namespace RageCoop.Server.Scripting
|
2022-07-03 10:46:24 +08:00
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Server-side object controller
|
|
|
|
|
/// </summary>
|
|
|
|
|
public abstract class ServerObject
|
|
|
|
|
{
|
2022-07-04 09:41:00 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Server that this object belongs to
|
|
|
|
|
/// </summary>
|
2022-07-04 23:59:51 +08:00
|
|
|
|
internal readonly Server Server;
|
2022-07-04 09:41:00 +08:00
|
|
|
|
internal ServerObject(Server server) { Server=server; }
|
2022-07-03 15:28:28 +08:00
|
|
|
|
|
2022-07-03 10:46:24 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Pass this as an argument in CustomEvent or NativeCall to convert this object to handle at client side.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Tuple<byte, byte[]> 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();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The client that owns this object, null if it's owned by server.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Client Owner { get; internal set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Network ID of this object.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public int ID { get; internal set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The object's model
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Model Model { get; internal set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets or sets this object's position
|
|
|
|
|
/// </summary>
|
|
|
|
|
public virtual Vector3 Position
|
|
|
|
|
{
|
|
|
|
|
get { return _pos; }
|
2022-07-04 09:41:00 +08:00
|
|
|
|
set { _pos=value; Owner.SendNativeCall(Hash.SET_ENTITY_COORDS_NO_OFFSET, Handle, value.X, value.Y, value.Z,1, 1,1 ); }
|
2022-07-03 10:46:24 +08:00
|
|
|
|
}
|
|
|
|
|
internal Vector3 _pos;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets or sets this object's rotation
|
|
|
|
|
/// </summary>
|
|
|
|
|
public virtual Vector3 Rotation
|
|
|
|
|
{
|
|
|
|
|
get { return _rot; }
|
2022-07-04 09:41:00 +08:00
|
|
|
|
set { _rot=value; Owner.SendNativeCall(Hash.SET_ENTITY_ROTATION, Handle, value.X, value.Y, value.Z ,2,1); }
|
2022-07-03 10:46:24 +08:00
|
|
|
|
}
|
|
|
|
|
internal Vector3 _rot;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2022-07-03 15:28:28 +08:00
|
|
|
|
/// Send updated information to clients, would be called automatically.
|
2022-07-03 10:46:24 +08:00
|
|
|
|
/// </summary>
|
2022-07-05 11:18:26 +08:00
|
|
|
|
|
2022-07-03 10:46:24 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Delete this object
|
|
|
|
|
/// </summary>
|
|
|
|
|
public virtual void Delete()
|
|
|
|
|
{
|
2022-07-05 11:18:26 +08:00
|
|
|
|
Owner?.SendCustomEventQueued(CustomEvents.DeleteEntity, Handle);
|
2022-07-03 10:46:24 +08:00
|
|
|
|
}
|
2022-07-03 10:55:49 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Freeze this object, will throw an exception if it's a ServerProp.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="toggle"></param>
|
|
|
|
|
/// <exception cref="InvalidOperationException"></exception>
|
|
|
|
|
public virtual void Freeze(bool toggle)
|
|
|
|
|
{
|
|
|
|
|
if (GetTypeByte()==50)
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException("Can't freeze or unfreeze static server object");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Owner.SendNativeCall(Hash.FREEZE_ENTITY_POSITION, Handle, toggle);
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-07-03 10:46:24 +08:00
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Represents an prop owned by server.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class ServerProp : ServerObject
|
|
|
|
|
{
|
|
|
|
|
|
2022-07-04 09:41:00 +08:00
|
|
|
|
internal ServerProp(Server server) : base(server) { }
|
2022-07-03 10:46:24 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Delete this prop
|
|
|
|
|
/// </summary>
|
|
|
|
|
public override void Delete()
|
|
|
|
|
{
|
2022-07-05 11:18:26 +08:00
|
|
|
|
Server.API.SendCustomEventQueued(null,CustomEvents.DeleteServerProp,ID);
|
2022-07-04 09:41:00 +08:00
|
|
|
|
Server.API.Entities.RemoveProp(ID);
|
2022-07-03 10:46:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-04 09:41:00 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets or sets this object's position
|
|
|
|
|
/// </summary>
|
|
|
|
|
public override Vector3 Position
|
|
|
|
|
{
|
|
|
|
|
get { return _pos; }
|
2022-07-04 21:35:01 +08:00
|
|
|
|
set { _pos=value; Server.API.SendNativeCall(null, Hash.SET_ENTITY_COORDS_NO_OFFSET, Handle, value.X, value.Y, value.Z, 1, 1, 1); }
|
2022-07-04 09:41:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets or sets this object's rotation
|
|
|
|
|
/// </summary>
|
|
|
|
|
public override Vector3 Rotation
|
|
|
|
|
{
|
|
|
|
|
get { return _rot; }
|
2022-07-04 21:35:01 +08:00
|
|
|
|
set { _rot=value; Server.API.SendNativeCall(null, Hash.SET_ENTITY_ROTATION, Handle, value.X, value.Y, value.Z, 2, 1); }
|
2022-07-04 09:41:00 +08:00
|
|
|
|
}
|
2022-07-03 10:46:24 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2022-07-03 15:28:28 +08:00
|
|
|
|
/// Send updated information to clients, would be called automatically.
|
2022-07-03 10:46:24 +08:00
|
|
|
|
/// </summary>
|
2022-07-05 11:18:26 +08:00
|
|
|
|
internal void Update()
|
2022-07-03 10:46:24 +08:00
|
|
|
|
{
|
2022-07-04 09:41:00 +08:00
|
|
|
|
Server.API.Server.BaseScript.SendServerPropsTo(new() { this });
|
2022-07-03 10:46:24 +08:00
|
|
|
|
}
|
2022-07-03 10:55:49 +08:00
|
|
|
|
|
2022-07-03 10:46:24 +08:00
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Represents a ped from a client
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class ServerPed : ServerObject
|
|
|
|
|
{
|
2022-07-04 09:41:00 +08:00
|
|
|
|
internal ServerPed(Server server) : base(server) { }
|
2022-07-03 10:46:24 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Get the ped's last vehicle
|
|
|
|
|
/// </summary>
|
|
|
|
|
public ServerVehicle LastVehicle { get; internal set; }
|
|
|
|
|
|
2022-07-04 23:59:51 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Get the <see cref="PedBlip"/> attached to this ped.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public PedBlip AttachedBlip { get; internal set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Attach a blip to this ped.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public PedBlip AddBlip()
|
|
|
|
|
{
|
|
|
|
|
AttachedBlip = new PedBlip(this);
|
|
|
|
|
AttachedBlip.Update();
|
|
|
|
|
return AttachedBlip;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-03 10:46:24 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Health
|
|
|
|
|
/// </summary>
|
|
|
|
|
public int Health { get; internal set; }
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Represents a vehicle from a client
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class ServerVehicle : ServerObject
|
|
|
|
|
{
|
2022-07-04 09:41:00 +08:00
|
|
|
|
internal ServerVehicle(Server server) : base(server) { }
|
2022-07-03 10:46:24 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets or sets vehicle rotation
|
|
|
|
|
/// </summary>
|
|
|
|
|
public override Vector3 Rotation
|
|
|
|
|
{
|
2022-07-04 09:41:00 +08:00
|
|
|
|
get { return _quat.ToEulerAngles().ToDegree(); }
|
|
|
|
|
set { Owner.SendNativeCall(Hash.SET_ENTITY_ROTATION, Handle ,value.X, value.Y ,value.Z); }
|
2022-07-03 10:46:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-04 09:41:00 +08:00
|
|
|
|
internal Quaternion _quat;
|
2022-07-03 10:46:24 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Get this vehicle's quaternion
|
|
|
|
|
/// </summary>
|
2022-07-04 09:41:00 +08:00
|
|
|
|
public Quaternion Quaternion
|
|
|
|
|
{
|
|
|
|
|
get { return _quat; }
|
|
|
|
|
set { _quat = value ;Owner.SendNativeCall(Hash.SET_ENTITY_QUATERNION, Handle, value.X, value.Y, value.Z, value.W); }
|
|
|
|
|
}
|
2022-07-03 10:46:24 +08:00
|
|
|
|
}
|
2022-07-03 15:28:28 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// A static blip owned by server.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class ServerBlip
|
2022-07-03 10:46:24 +08:00
|
|
|
|
{
|
2022-07-03 15:28:28 +08:00
|
|
|
|
private readonly Server Server;
|
|
|
|
|
internal ServerBlip(Server server)
|
2022-07-03 10:46:24 +08:00
|
|
|
|
{
|
2022-07-03 15:28:28 +08:00
|
|
|
|
Server = server;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-04 09:54:43 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Pass this as an argument in CustomEvent or NativeCall to convert this object to handle at client side.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Tuple<byte, byte[]> Handle
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return new(60, BitConverter.GetBytes(ID));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-03 15:28:28 +08:00
|
|
|
|
/// <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(); }
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-04 23:59:51 +08:00
|
|
|
|
internal BlipSprite _sprite=BlipSprite.Standard;
|
2022-07-03 15:28:28 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Sprite of this blip
|
|
|
|
|
/// </summary>
|
|
|
|
|
public BlipSprite Sprite {
|
|
|
|
|
get { return _sprite; }
|
|
|
|
|
set { _sprite=value; Update();}
|
|
|
|
|
}
|
2022-07-03 10:46:24 +08:00
|
|
|
|
|
2022-07-03 21:00:05 +08:00
|
|
|
|
internal float _scale =1;
|
2022-07-03 15:28:28 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Scale of this blip
|
|
|
|
|
/// </summary>
|
2022-07-03 21:00:05 +08:00
|
|
|
|
public float Scale
|
2022-07-03 15:28:28 +08:00
|
|
|
|
{
|
|
|
|
|
get { return _scale; }
|
|
|
|
|
set { _scale=value;Update(); }
|
2022-07-03 10:46:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-03 15:28:28 +08:00
|
|
|
|
internal Vector3 _pos = new();
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Position of this blip
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Vector3 Position
|
|
|
|
|
{
|
|
|
|
|
get { return _pos; }
|
|
|
|
|
set { _pos=value; Update(); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal int _rot;
|
|
|
|
|
/// <summary>
|
2022-07-03 21:00:05 +08:00
|
|
|
|
/// Rotation of this blip
|
2022-07-03 15:28:28 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
public int Rotation
|
|
|
|
|
{
|
|
|
|
|
get { return _rot; }
|
|
|
|
|
set { _rot=value; Update(); }
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-03 21:00:05 +08:00
|
|
|
|
internal string _name="Beeeeeee";
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Name of this blip
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Name
|
|
|
|
|
{
|
|
|
|
|
get { return _name;}
|
|
|
|
|
set { _name=value; Update(); }
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-03 15:28:28 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Delete this blip
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void Delete()
|
|
|
|
|
{
|
2022-07-05 11:18:26 +08:00
|
|
|
|
Server.API.SendCustomEventQueued(null, CustomEvents.DeleteServerBlip,ID);
|
2022-07-03 15:28:28 +08:00
|
|
|
|
Server.Entities.RemoveServerBlip(ID);
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-04 09:54:43 +08:00
|
|
|
|
|
2022-07-03 15:28:28 +08:00
|
|
|
|
private bool _bouncing=false;
|
|
|
|
|
internal void Update()
|
|
|
|
|
{
|
|
|
|
|
// 5ms debounce
|
|
|
|
|
if (!_bouncing)
|
|
|
|
|
{
|
|
|
|
|
_bouncing=true;
|
|
|
|
|
Task.Run(() =>
|
|
|
|
|
{
|
|
|
|
|
Thread.Sleep(5);
|
|
|
|
|
DoUpdate();
|
|
|
|
|
_bouncing=false;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private void DoUpdate()
|
|
|
|
|
{
|
2022-07-03 15:37:51 +08:00
|
|
|
|
// Server.Logger?.Debug("bee");
|
2022-07-03 15:28:28 +08:00
|
|
|
|
// Serve-side blip
|
|
|
|
|
Server.BaseScript.SendServerBlipsTo(new() { this });
|
|
|
|
|
|
|
|
|
|
}
|
2022-07-03 10:46:24 +08:00
|
|
|
|
}
|
2022-07-04 23:59:51 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Represent a blip attached to ped.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class PedBlip
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Get the <see cref="ServerPed"/> that this blip attached to.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public ServerPed Ped { get;internal set; }
|
|
|
|
|
internal PedBlip(ServerPed ped)
|
|
|
|
|
{
|
|
|
|
|
Ped = ped;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
internal BlipColor _color;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Color of this blip
|
|
|
|
|
/// </summary>
|
|
|
|
|
public BlipColor Color
|
|
|
|
|
{
|
|
|
|
|
get { return _color; }
|
|
|
|
|
set { _color=value; Update(); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal BlipSprite _sprite=BlipSprite.Standard;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Sprite of this blip
|
|
|
|
|
/// </summary>
|
|
|
|
|
public BlipSprite Sprite
|
|
|
|
|
{
|
|
|
|
|
get { return _sprite; }
|
|
|
|
|
set { _sprite=value; Update(); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal float _scale = 1;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Scale of this blip
|
|
|
|
|
/// </summary>
|
|
|
|
|
public float Scale
|
|
|
|
|
{
|
|
|
|
|
get { return _scale; }
|
|
|
|
|
set { _scale=value; Update(); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool _bouncing = false;
|
|
|
|
|
internal void Update()
|
|
|
|
|
{
|
|
|
|
|
// 5ms debounce
|
|
|
|
|
if (!_bouncing)
|
|
|
|
|
{
|
|
|
|
|
_bouncing=true;
|
|
|
|
|
Task.Run(() =>
|
|
|
|
|
{
|
|
|
|
|
Thread.Sleep(5);
|
|
|
|
|
DoUpdate();
|
|
|
|
|
_bouncing=false;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private void DoUpdate()
|
|
|
|
|
{
|
2022-07-05 11:18:26 +08:00
|
|
|
|
Ped.Owner.SendCustomEventQueued(CustomEvents.UpdatePedBlip,Ped.Handle,(byte)Color,(ushort)Sprite,Scale);
|
2022-07-04 23:59:51 +08:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-07-03 10:46:24 +08:00
|
|
|
|
}
|