OnTick added. Bug fixes. Remove server created objects/vehicles/peds/checkpoints/blips on disconnect. More...
This commit is contained in:
@ -251,6 +251,59 @@ namespace CoopClient
|
|||||||
NPCsVehicles.Clear();
|
NPCsVehicles.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static readonly Dictionary<ulong, byte> CheckNativeHash = new Dictionary<ulong, byte>()
|
||||||
|
{
|
||||||
|
{ 0xD49F9B0955C367DE, 1 },
|
||||||
|
{ 0xEF29A16337FACADB, 1 },
|
||||||
|
{ 0xB4AC7D0CF06BFE8F, 1 },
|
||||||
|
{ 0x9B62392B474F44A0, 1 },
|
||||||
|
{ 0x7DD959874C1FD534, 1 },
|
||||||
|
{ 0xAF35D0D2583051B0, 2 },
|
||||||
|
{ 0x63C6CCA8E68AE8C8, 2 },
|
||||||
|
{ 0x509D5878EB39E842, 3 },
|
||||||
|
{ 0x9A294B2138ABB884, 3 },
|
||||||
|
{ 0x46818D79B1F7499A, 4 },
|
||||||
|
{ 0x5CDE92C702A8FCE7, 4 },
|
||||||
|
{ 0xBE339365C863BD36, 4 },
|
||||||
|
{ 0x5A039BB0BCA604B6, 4 },
|
||||||
|
{ 0x0134F0835AB6BFCB, 5 }
|
||||||
|
};
|
||||||
|
internal static Dictionary<int, byte> ServerItems = new Dictionary<int, byte>();
|
||||||
|
internal static void CleanUpWorld()
|
||||||
|
{
|
||||||
|
if (ServerItems.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lock (ServerItems)
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<int, byte> item in ServerItems)
|
||||||
|
{
|
||||||
|
switch (item.Value)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
World.GetAllEntities().Where(x => x.Handle == item.Key).First().Delete();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
World.GetAllVehicles().Where(x => x.Handle == item.Key).First().Delete();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
World.GetAllProps().Where(x => x.Handle == item.Key).First().Delete();
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
World.GetAllBlips().Where(x => x.Handle == item.Key).First().Delete();
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
World.GetAllCheckpoints().Where(x => x.Handle == item.Key).First().Delete();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerItems.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
private ulong ArtificialLagCounter;
|
private ulong ArtificialLagCounter;
|
||||||
internal static EntitiesPlayer DebugSyncPed;
|
internal static EntitiesPlayer DebugSyncPed;
|
||||||
|
@ -135,6 +135,8 @@ namespace CoopClient
|
|||||||
Latency = 0;
|
Latency = 0;
|
||||||
LastPlayerFullSync = 0;
|
LastPlayerFullSync = 0;
|
||||||
|
|
||||||
|
Main.CleanUpWorld();
|
||||||
|
|
||||||
Main.NPCsAllowed = false;
|
Main.NPCsAllowed = false;
|
||||||
|
|
||||||
if (Main.MainChat.Focused)
|
if (Main.MainChat.Focused)
|
||||||
@ -158,6 +160,11 @@ namespace CoopClient
|
|||||||
|
|
||||||
switch (packetType)
|
switch (packetType)
|
||||||
{
|
{
|
||||||
|
case (byte)PacketTypes.CleanUpWorldPacket:
|
||||||
|
{
|
||||||
|
Main.CleanUpWorld();
|
||||||
|
}
|
||||||
|
break;
|
||||||
case (byte)PacketTypes.PlayerConnectPacket:
|
case (byte)PacketTypes.PlayerConnectPacket:
|
||||||
{
|
{
|
||||||
int len = message.ReadInt32();
|
int len = message.ReadInt32();
|
||||||
@ -602,6 +609,18 @@ namespace CoopClient
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Main.CheckNativeHash.ContainsKey(packet.Hash))
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<ulong, byte> hash in Main.CheckNativeHash)
|
||||||
|
{
|
||||||
|
if (hash.Key == packet.Hash)
|
||||||
|
{
|
||||||
|
Main.ServerItems.Add((int)result, hash.Value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NetOutgoingMessage outgoingMessage = Client.CreateMessage();
|
NetOutgoingMessage outgoingMessage = Client.CreateMessage();
|
||||||
new NativeResponsePacket()
|
new NativeResponsePacket()
|
||||||
{
|
{
|
||||||
@ -785,7 +804,9 @@ namespace CoopClient
|
|||||||
new FullSyncPlayerVehPacket()
|
new FullSyncPlayerVehPacket()
|
||||||
{
|
{
|
||||||
NetHandle = Main.LocalNetHandle,
|
NetHandle = Main.LocalNetHandle,
|
||||||
|
PedHandle = player.Handle,
|
||||||
Health = player.Health,
|
Health = player.Health,
|
||||||
|
VehicleHandle = veh.Handle,
|
||||||
ModelHash = player.Model.Hash,
|
ModelHash = player.Model.Hash,
|
||||||
Clothes = player.GetPedClothes(),
|
Clothes = player.GetPedClothes(),
|
||||||
VehModelHash = veh.Model.Hash,
|
VehModelHash = veh.Model.Hash,
|
||||||
@ -810,6 +831,7 @@ namespace CoopClient
|
|||||||
new FullSyncPlayerPacket()
|
new FullSyncPlayerPacket()
|
||||||
{
|
{
|
||||||
NetHandle = Main.LocalNetHandle,
|
NetHandle = Main.LocalNetHandle,
|
||||||
|
PedHandle = player.Handle,
|
||||||
Health = player.Health,
|
Health = player.Health,
|
||||||
ModelHash = player.Model.Hash,
|
ModelHash = player.Model.Hash,
|
||||||
Clothes = player.GetPedClothes(),
|
Clothes = player.GetPedClothes(),
|
||||||
|
@ -112,7 +112,8 @@ namespace CoopClient
|
|||||||
ChatMessagePacket,
|
ChatMessagePacket,
|
||||||
NativeCallPacket,
|
NativeCallPacket,
|
||||||
NativeResponsePacket,
|
NativeResponsePacket,
|
||||||
ModPacket
|
ModPacket,
|
||||||
|
CleanUpWorldPacket
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ConnectionChannel
|
enum ConnectionChannel
|
||||||
@ -416,6 +417,8 @@ namespace CoopClient
|
|||||||
{
|
{
|
||||||
public long NetHandle { get; set; }
|
public long NetHandle { get; set; }
|
||||||
|
|
||||||
|
public int PedHandle { get; set; }
|
||||||
|
|
||||||
public int Health { get; set; }
|
public int Health { get; set; }
|
||||||
|
|
||||||
public int ModelHash { get; set; }
|
public int ModelHash { get; set; }
|
||||||
@ -450,6 +453,9 @@ namespace CoopClient
|
|||||||
// Write player netHandle
|
// Write player netHandle
|
||||||
byteArray.AddRange(BitConverter.GetBytes(NetHandle));
|
byteArray.AddRange(BitConverter.GetBytes(NetHandle));
|
||||||
|
|
||||||
|
// Write player ped handle
|
||||||
|
byteArray.AddRange(BitConverter.GetBytes(PedHandle));
|
||||||
|
|
||||||
// Write player health
|
// Write player health
|
||||||
byteArray.AddRange(BitConverter.GetBytes(Health));
|
byteArray.AddRange(BitConverter.GetBytes(Health));
|
||||||
|
|
||||||
@ -545,6 +551,9 @@ namespace CoopClient
|
|||||||
// Read player netHandle
|
// Read player netHandle
|
||||||
NetHandle = reader.ReadLong();
|
NetHandle = reader.ReadLong();
|
||||||
|
|
||||||
|
// Read player pedHandle
|
||||||
|
PedHandle = reader.ReadInt();
|
||||||
|
|
||||||
// Read player health
|
// Read player health
|
||||||
Health = reader.ReadInt();
|
Health = reader.ReadInt();
|
||||||
|
|
||||||
@ -635,8 +644,12 @@ namespace CoopClient
|
|||||||
{
|
{
|
||||||
public long NetHandle { get; set; }
|
public long NetHandle { get; set; }
|
||||||
|
|
||||||
|
public int PedHandle { get; set; }
|
||||||
|
|
||||||
public int Health { get; set; }
|
public int Health { get; set; }
|
||||||
|
|
||||||
|
public int VehicleHandle { get; set; }
|
||||||
|
|
||||||
public int ModelHash { get; set; }
|
public int ModelHash { get; set; }
|
||||||
|
|
||||||
public Dictionary<byte, short> Clothes { get; set; }
|
public Dictionary<byte, short> Clothes { get; set; }
|
||||||
@ -683,12 +696,18 @@ namespace CoopClient
|
|||||||
// Write player netHandle
|
// Write player netHandle
|
||||||
byteArray.AddRange(BitConverter.GetBytes(NetHandle));
|
byteArray.AddRange(BitConverter.GetBytes(NetHandle));
|
||||||
|
|
||||||
|
// Write player ped handle
|
||||||
|
byteArray.AddRange(BitConverter.GetBytes(PedHandle));
|
||||||
|
|
||||||
// Write vehicles flags
|
// Write vehicles flags
|
||||||
byteArray.AddRange(BitConverter.GetBytes(Flag.Value));
|
byteArray.AddRange(BitConverter.GetBytes(Flag.Value));
|
||||||
|
|
||||||
// Write player health
|
// Write player health
|
||||||
byteArray.AddRange(BitConverter.GetBytes(Health));
|
byteArray.AddRange(BitConverter.GetBytes(Health));
|
||||||
|
|
||||||
|
// Write player ped handle
|
||||||
|
byteArray.AddRange(BitConverter.GetBytes(VehicleHandle));
|
||||||
|
|
||||||
// Write player model hash
|
// Write player model hash
|
||||||
byteArray.AddRange(BitConverter.GetBytes(ModelHash));
|
byteArray.AddRange(BitConverter.GetBytes(ModelHash));
|
||||||
|
|
||||||
@ -812,12 +831,18 @@ namespace CoopClient
|
|||||||
// Read player netHandle
|
// Read player netHandle
|
||||||
NetHandle = reader.ReadLong();
|
NetHandle = reader.ReadLong();
|
||||||
|
|
||||||
|
// Read player ped handle
|
||||||
|
PedHandle = reader.ReadInt();
|
||||||
|
|
||||||
// Read vehicle flags
|
// Read vehicle flags
|
||||||
Flag = reader.ReadUShort();
|
Flag = reader.ReadUShort();
|
||||||
|
|
||||||
// Read player health
|
// Read player health
|
||||||
Health = reader.ReadInt();
|
Health = reader.ReadInt();
|
||||||
|
|
||||||
|
// Read player vehicle handle
|
||||||
|
VehicleHandle = reader.ReadInt();
|
||||||
|
|
||||||
// Read player model hash
|
// Read player model hash
|
||||||
ModelHash = reader.ReadInt();
|
ModelHash = reader.ReadInt();
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ namespace CoopServer
|
|||||||
public float Latency = 0.0f;
|
public float Latency = 0.0f;
|
||||||
public PlayerData Player;
|
public PlayerData Player;
|
||||||
private readonly Dictionary<string, object> CustomData = new();
|
private readonly Dictionary<string, object> CustomData = new();
|
||||||
|
private long CallbacksCount = 0;
|
||||||
internal readonly Dictionary<long, Action<object>> Callbacks = new();
|
internal readonly Dictionary<long, Action<object>> Callbacks = new();
|
||||||
|
|
||||||
#region CUSTOMDATA FUNCTIONS
|
#region CUSTOMDATA FUNCTIONS
|
||||||
@ -73,7 +74,7 @@ namespace CoopServer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendNativeCall(ulong hash, List<object> args = null)
|
public void SendNativeCall(ulong hash, params object[] args)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -84,7 +85,7 @@ namespace CoopServer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args != null && args.Count == 0)
|
if (args != null && args.Length == 0)
|
||||||
{
|
{
|
||||||
Logging.Error($"[Client->SendNativeCall(ulong hash, Dictionary<string, object> args)]: Missing arguments!");
|
Logging.Error($"[Client->SendNativeCall(ulong hash, Dictionary<string, object> args)]: Missing arguments!");
|
||||||
return;
|
return;
|
||||||
@ -93,7 +94,7 @@ namespace CoopServer
|
|||||||
NativeCallPacket packet = new()
|
NativeCallPacket packet = new()
|
||||||
{
|
{
|
||||||
Hash = hash,
|
Hash = hash,
|
||||||
Args = args ?? new List<object>(),
|
Args = new List<object>(args) ?? new List<object>(),
|
||||||
};
|
};
|
||||||
|
|
||||||
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
|
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
|
||||||
@ -106,7 +107,7 @@ namespace CoopServer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendNativeResponse(Action<object> callback, ulong hash, Type returnType, List<object> args = null)
|
public void SendNativeResponse(Action<object> callback, ulong hash, Type returnType, params object[] args)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -117,14 +118,14 @@ namespace CoopServer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args != null && args.Count == 0)
|
if (args != null && args.Length == 0)
|
||||||
{
|
{
|
||||||
Logging.Error($"[Client->SendNativeCall(ulong hash, Dictionary<string, object> args)]: Missing arguments!");
|
Logging.Error($"[Client->SendNativeCall(ulong hash, Dictionary<string, object> args)]: Missing arguments!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
long id = 0;
|
long id = ++CallbacksCount;
|
||||||
Callbacks.Add(id = Environment.TickCount64, callback);
|
Callbacks.Add(id, callback);
|
||||||
|
|
||||||
byte returnTypeValue = 0x00;
|
byte returnTypeValue = 0x00;
|
||||||
if (returnType == typeof(int))
|
if (returnType == typeof(int))
|
||||||
@ -157,7 +158,7 @@ namespace CoopServer
|
|||||||
new NativeResponsePacket()
|
new NativeResponsePacket()
|
||||||
{
|
{
|
||||||
Hash = hash,
|
Hash = hash,
|
||||||
Args = args ?? new List<object>(),
|
Args = new List<object>(args) ?? new List<object>(),
|
||||||
ResultType = returnTypeValue,
|
ResultType = returnTypeValue,
|
||||||
ID = id
|
ID = id
|
||||||
}.PacketToNetOutGoingMessage(outgoingMessage);
|
}.PacketToNetOutGoingMessage(outgoingMessage);
|
||||||
@ -169,6 +170,20 @@ namespace CoopServer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SendCleanUpWorld()
|
||||||
|
{
|
||||||
|
NetConnection userConnection = Server.MainNetServer.Connections.Find(x => x.RemoteUniqueIdentifier == NetHandle);
|
||||||
|
if (userConnection == null)
|
||||||
|
{
|
||||||
|
Logging.Error($"[Client->SendCleanUpWorld()]: Connection \"{NetHandle}\" not found!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
|
||||||
|
outgoingMessage.Write((byte)PacketTypes.CleanUpWorldPacket);
|
||||||
|
Server.MainNetServer.SendMessage(outgoingMessage, userConnection, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Default);
|
||||||
|
}
|
||||||
|
|
||||||
public void SendModPacket(string mod, byte customID, byte[] bytes)
|
public void SendModPacket(string mod, byte customID, byte[] bytes)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -8,6 +8,27 @@ using Newtonsoft.Json;
|
|||||||
|
|
||||||
namespace CoopServer
|
namespace CoopServer
|
||||||
{
|
{
|
||||||
|
public static class VectorExtensions
|
||||||
|
{
|
||||||
|
public static LVector3 Normalize(this LVector3 value)
|
||||||
|
{
|
||||||
|
float value2 = value.Length();
|
||||||
|
return value / value2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Distance(this LVector3 value1, LVector3 value2)
|
||||||
|
{
|
||||||
|
LVector3 vector = value1 - value2;
|
||||||
|
float num = Dot(vector, vector);
|
||||||
|
return (float)Math.Sqrt(num);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Dot(this LVector3 vector1, LVector3 vector2)
|
||||||
|
{
|
||||||
|
return vector1.X * vector2.X + vector1.Y * vector2.Y + vector1.Z * vector2.Z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public struct LVector3
|
public struct LVector3
|
||||||
{
|
{
|
||||||
public LVector3(float X, float Y, float Z)
|
public LVector3(float X, float Y, float Z)
|
||||||
@ -27,6 +48,19 @@ namespace CoopServer
|
|||||||
public float Length() => (float)Math.Sqrt((X * X) + (Y * Y) + (Z * Z));
|
public float Length() => (float)Math.Sqrt((X * X) + (Y * Y) + (Z * Z));
|
||||||
public static LVector3 Subtract(LVector3 pos1, LVector3 pos2) => new(pos1.X - pos2.X, pos1.Y - pos2.Y, pos1.Z - pos2.Z);
|
public static LVector3 Subtract(LVector3 pos1, LVector3 pos2) => new(pos1.X - pos2.X, pos1.Y - pos2.Y, pos1.Z - pos2.Z);
|
||||||
public static bool Equals(LVector3 value1, LVector3 value2) => value1.X == value2.X && value1.Y == value2.Y && value1.Z == value2.Z;
|
public static bool Equals(LVector3 value1, LVector3 value2) => value1.X == value2.X && value1.Y == value2.Y && value1.Z == value2.Z;
|
||||||
|
public static LVector3 operator /(LVector3 value1, float value2)
|
||||||
|
{
|
||||||
|
float num = 1f / value2;
|
||||||
|
return new LVector3(value1.X * num, value1.Y * num, value1.Z * num);
|
||||||
|
}
|
||||||
|
public static LVector3 operator -(LVector3 left, LVector3 right)
|
||||||
|
{
|
||||||
|
return new LVector3(left.X - right.X, left.Y - right.Y, left.Z - right.Z);
|
||||||
|
}
|
||||||
|
public static LVector3 operator -(LVector3 value)
|
||||||
|
{
|
||||||
|
return default(LVector3) - value;
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +98,8 @@ namespace CoopServer
|
|||||||
ChatMessagePacket,
|
ChatMessagePacket,
|
||||||
NativeCallPacket,
|
NativeCallPacket,
|
||||||
NativeResponsePacket,
|
NativeResponsePacket,
|
||||||
ModPacket
|
ModPacket,
|
||||||
|
CleanUpWorldPacket
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ConnectionChannel
|
enum ConnectionChannel
|
||||||
@ -365,6 +400,8 @@ namespace CoopServer
|
|||||||
{
|
{
|
||||||
public long NetHandle { get; set; }
|
public long NetHandle { get; set; }
|
||||||
|
|
||||||
|
public int PedHandle { get; set; }
|
||||||
|
|
||||||
public int Health { get; set; }
|
public int Health { get; set; }
|
||||||
|
|
||||||
public int ModelHash { get; set; }
|
public int ModelHash { get; set; }
|
||||||
@ -399,6 +436,9 @@ namespace CoopServer
|
|||||||
// Write player netHandle
|
// Write player netHandle
|
||||||
byteArray.AddRange(BitConverter.GetBytes(NetHandle));
|
byteArray.AddRange(BitConverter.GetBytes(NetHandle));
|
||||||
|
|
||||||
|
// Write player ped handle
|
||||||
|
byteArray.AddRange(BitConverter.GetBytes(PedHandle));
|
||||||
|
|
||||||
// Write player health
|
// Write player health
|
||||||
byteArray.AddRange(BitConverter.GetBytes(Health));
|
byteArray.AddRange(BitConverter.GetBytes(Health));
|
||||||
|
|
||||||
@ -494,6 +534,9 @@ namespace CoopServer
|
|||||||
// Read player netHandle
|
// Read player netHandle
|
||||||
NetHandle = reader.ReadLong();
|
NetHandle = reader.ReadLong();
|
||||||
|
|
||||||
|
// Read player pedHandle
|
||||||
|
PedHandle = reader.ReadInt();
|
||||||
|
|
||||||
// Read player health
|
// Read player health
|
||||||
Health = reader.ReadInt();
|
Health = reader.ReadInt();
|
||||||
|
|
||||||
@ -584,8 +627,12 @@ namespace CoopServer
|
|||||||
{
|
{
|
||||||
public long NetHandle { get; set; }
|
public long NetHandle { get; set; }
|
||||||
|
|
||||||
|
public int PedHandle { get; set; }
|
||||||
|
|
||||||
public int Health { get; set; }
|
public int Health { get; set; }
|
||||||
|
|
||||||
|
public int VehicleHandle { get; set; }
|
||||||
|
|
||||||
public int ModelHash { get; set; }
|
public int ModelHash { get; set; }
|
||||||
|
|
||||||
public Dictionary<byte, short> Clothes { get; set; }
|
public Dictionary<byte, short> Clothes { get; set; }
|
||||||
@ -632,12 +679,18 @@ namespace CoopServer
|
|||||||
// Write player netHandle
|
// Write player netHandle
|
||||||
byteArray.AddRange(BitConverter.GetBytes(NetHandle));
|
byteArray.AddRange(BitConverter.GetBytes(NetHandle));
|
||||||
|
|
||||||
|
// Write player ped handle
|
||||||
|
byteArray.AddRange(BitConverter.GetBytes(PedHandle));
|
||||||
|
|
||||||
// Write vehicles flags
|
// Write vehicles flags
|
||||||
byteArray.AddRange(BitConverter.GetBytes(Flag.Value));
|
byteArray.AddRange(BitConverter.GetBytes(Flag.Value));
|
||||||
|
|
||||||
// Write player health
|
// Write player health
|
||||||
byteArray.AddRange(BitConverter.GetBytes(Health));
|
byteArray.AddRange(BitConverter.GetBytes(Health));
|
||||||
|
|
||||||
|
// Write player ped handle
|
||||||
|
byteArray.AddRange(BitConverter.GetBytes(VehicleHandle));
|
||||||
|
|
||||||
// Write player model hash
|
// Write player model hash
|
||||||
byteArray.AddRange(BitConverter.GetBytes(ModelHash));
|
byteArray.AddRange(BitConverter.GetBytes(ModelHash));
|
||||||
|
|
||||||
@ -761,12 +814,18 @@ namespace CoopServer
|
|||||||
// Read player netHandle
|
// Read player netHandle
|
||||||
NetHandle = reader.ReadLong();
|
NetHandle = reader.ReadLong();
|
||||||
|
|
||||||
|
// Read player ped handle
|
||||||
|
PedHandle = reader.ReadInt();
|
||||||
|
|
||||||
// Read vehicle flags
|
// Read vehicle flags
|
||||||
Flag = reader.ReadUShort();
|
Flag = reader.ReadUShort();
|
||||||
|
|
||||||
// Read player health
|
// Read player health
|
||||||
Health = reader.ReadInt();
|
Health = reader.ReadInt();
|
||||||
|
|
||||||
|
// Read player vehicle handle
|
||||||
|
VehicleHandle = reader.ReadInt();
|
||||||
|
|
||||||
// Read player model hash
|
// Read player model hash
|
||||||
ModelHash = reader.ReadInt();
|
ModelHash = reader.ReadInt();
|
||||||
|
|
||||||
|
@ -5,6 +5,37 @@ namespace CoopServer
|
|||||||
public struct PlayerData
|
public struct PlayerData
|
||||||
{
|
{
|
||||||
public string Username { get; set; }
|
public string Username { get; set; }
|
||||||
|
private int LastPedHandle = 0;
|
||||||
|
private int CurrentPedHandle = 0;
|
||||||
|
public int PedHandle
|
||||||
|
{
|
||||||
|
get => CurrentPedHandle;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
LastPedHandle = CurrentPedHandle;
|
||||||
|
CurrentPedHandle = value;
|
||||||
|
if (CurrentPedHandle != LastPedHandle)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private int LastVehicleHandle { get; set; }
|
||||||
|
private int CurrentVehicleHandle { get; set; }
|
||||||
|
public int VehicleHandle
|
||||||
|
{
|
||||||
|
get => CurrentPedHandle;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
LastVehicleHandle = CurrentVehicleHandle;
|
||||||
|
CurrentVehicleHandle = value;
|
||||||
|
if (CurrentVehicleHandle != LastVehicleHandle)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public bool IsInVehicle { get; set; }
|
||||||
private LVector3 LastPosition { get; set; }
|
private LVector3 LastPosition { get; set; }
|
||||||
private LVector3 CurrentPosition { get; set; }
|
private LVector3 CurrentPosition { get; set; }
|
||||||
public LVector3 Position
|
public LVector3 Position
|
||||||
|
@ -23,6 +23,7 @@ namespace CoopServer
|
|||||||
internal class Server
|
internal class Server
|
||||||
{
|
{
|
||||||
private static readonly string CompatibleVersion = "V1_3";
|
private static readonly string CompatibleVersion = "V1_3";
|
||||||
|
private static long CurrentTick = 0;
|
||||||
|
|
||||||
public static readonly Settings MainSettings = Util.Read<Settings>("CoopSettings.xml");
|
public static readonly Settings MainSettings = Util.Read<Settings>("CoopSettings.xml");
|
||||||
private readonly Blocklist MainBlocklist = Util.Read<Blocklist>("Blocklist.xml");
|
private readonly Blocklist MainBlocklist = Util.Read<Blocklist>("Blocklist.xml");
|
||||||
@ -220,6 +221,14 @@ namespace CoopServer
|
|||||||
|
|
||||||
while (!Program.ReadyToStop)
|
while (!Program.ReadyToStop)
|
||||||
{
|
{
|
||||||
|
if (Resources.Count != 0)
|
||||||
|
{
|
||||||
|
Resources.ForEach(x =>
|
||||||
|
{
|
||||||
|
x.InvokeTick(++CurrentTick);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
NetIncomingMessage message;
|
NetIncomingMessage message;
|
||||||
|
|
||||||
while ((message = MainNetServer.ReadMessage()) != null)
|
while ((message = MainNetServer.ReadMessage()) != null)
|
||||||
@ -729,6 +738,8 @@ namespace CoopServer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Save the new data
|
// Save the new data
|
||||||
|
client.Player.PedHandle = packet.PedHandle;
|
||||||
|
client.Player.IsInVehicle = false;
|
||||||
client.Player.Position = packet.Position;
|
client.Player.Position = packet.Position;
|
||||||
client.Player.Health = packet.Health;
|
client.Player.Health = packet.Health;
|
||||||
|
|
||||||
@ -769,6 +780,9 @@ namespace CoopServer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Save the new data
|
// Save the new data
|
||||||
|
client.Player.PedHandle = packet.PedHandle;
|
||||||
|
client.Player.VehicleHandle = packet.VehicleHandle;
|
||||||
|
client.Player.IsInVehicle = true;
|
||||||
client.Player.Position = packet.Position;
|
client.Player.Position = packet.Position;
|
||||||
client.Player.Health = packet.Health;
|
client.Player.Health = packet.Health;
|
||||||
|
|
||||||
|
@ -128,12 +128,21 @@ namespace CoopServer
|
|||||||
_actionQueue.Enqueue(new Action(() => _script.API.InvokePlayerHealthUpdate(playerData)));
|
_actionQueue.Enqueue(new Action(() => _script.API.InvokePlayerHealthUpdate(playerData)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void InvokeTick(long tick)
|
||||||
|
{
|
||||||
|
lock (_actionQueue.SyncRoot)
|
||||||
|
{
|
||||||
|
_actionQueue.Enqueue(new Action(() => _script.API.InvokeTick(tick)));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class API
|
public class API
|
||||||
{
|
{
|
||||||
#region DELEGATES
|
#region DELEGATES
|
||||||
public delegate void EmptyEvent();
|
public delegate void EmptyEvent();
|
||||||
|
public delegate void OnTickEvent(long tick);
|
||||||
public delegate void ChatEvent(string username, string message, CancelEventArgs cancel);
|
public delegate void ChatEvent(string username, string message, CancelEventArgs cancel);
|
||||||
public delegate void PlayerEvent(Client client);
|
public delegate void PlayerEvent(Client client);
|
||||||
public delegate void ModEvent(long from, long target, string mod, byte customID, byte[] bytes, CancelEventArgs args);
|
public delegate void ModEvent(long from, long target, string mod, byte customID, byte[] bytes, CancelEventArgs args);
|
||||||
@ -141,6 +150,10 @@ namespace CoopServer
|
|||||||
|
|
||||||
#region EVENTS
|
#region EVENTS
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Called every tick
|
||||||
|
/// </summary>
|
||||||
|
public event OnTickEvent OnTick;
|
||||||
|
/// <summary>
|
||||||
/// Called when the server has started
|
/// Called when the server has started
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EmptyEvent OnStart;
|
public event EmptyEvent OnStart;
|
||||||
@ -181,6 +194,11 @@ namespace CoopServer
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public event ModEvent OnModPacketReceived;
|
public event ModEvent OnModPacketReceived;
|
||||||
|
|
||||||
|
internal void InvokeTick(long tick)
|
||||||
|
{
|
||||||
|
OnTick?.Invoke(tick);
|
||||||
|
}
|
||||||
|
|
||||||
internal void InvokeStart()
|
internal void InvokeStart()
|
||||||
{
|
{
|
||||||
OnStart?.Invoke();
|
OnStart?.Invoke();
|
||||||
@ -276,7 +294,7 @@ namespace CoopServer
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="hash">The hash (Example: 0x25223CA6B4D20B7F = GET_CLOCK_HOURS)</param>
|
/// <param name="hash">The hash (Example: 0x25223CA6B4D20B7F = GET_CLOCK_HOURS)</param>
|
||||||
/// <param name="args">The arguments (Example: string = int, object = 5)</param>
|
/// <param name="args">The arguments (Example: string = int, object = 5)</param>
|
||||||
public static void SendNativeCallToAll(ulong hash, List<object> args = null)
|
public static void SendNativeCallToAll(ulong hash, params object[] args)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -285,7 +303,7 @@ namespace CoopServer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args != null && args.Count == 0)
|
if (args != null && args.Length == 0)
|
||||||
{
|
{
|
||||||
Logging.Error($"[ServerScript->SendNativeCallToAll(ulong hash, params object[] args)]: args is not null!");
|
Logging.Error($"[ServerScript->SendNativeCallToAll(ulong hash, params object[] args)]: args is not null!");
|
||||||
return;
|
return;
|
||||||
@ -294,7 +312,7 @@ namespace CoopServer
|
|||||||
NativeCallPacket packet = new()
|
NativeCallPacket packet = new()
|
||||||
{
|
{
|
||||||
Hash = hash,
|
Hash = hash,
|
||||||
Args = args ?? new List<object>()
|
Args = new List<object>(args) ?? new List<object>()
|
||||||
};
|
};
|
||||||
|
|
||||||
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
|
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
|
||||||
@ -362,6 +380,25 @@ namespace CoopServer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public static void SendCleanUpWorldToAll(List<long> netHandleList = null)
|
||||||
|
{
|
||||||
|
if (Server.MainNetServer.ConnectionsCount == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<NetConnection> connections = netHandleList == null
|
||||||
|
? Server.MainNetServer.Connections
|
||||||
|
: Server.MainNetServer.Connections.FindAll(c => netHandleList.Contains(c.RemoteUniqueIdentifier));
|
||||||
|
|
||||||
|
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
|
||||||
|
outgoingMessage.Write((byte)PacketTypes.CleanUpWorldPacket);
|
||||||
|
Server.MainNetServer.SendMessage(outgoingMessage, connections, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Default);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Register a new command chat command (Example: "/test")
|
/// Register a new command chat command (Example: "/test")
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
Reference in New Issue
Block a user