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();
|
||||
}
|
||||
|
||||
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
|
||||
private ulong ArtificialLagCounter;
|
||||
internal static EntitiesPlayer DebugSyncPed;
|
||||
|
@ -135,6 +135,8 @@ namespace CoopClient
|
||||
Latency = 0;
|
||||
LastPlayerFullSync = 0;
|
||||
|
||||
Main.CleanUpWorld();
|
||||
|
||||
Main.NPCsAllowed = false;
|
||||
|
||||
if (Main.MainChat.Focused)
|
||||
@ -158,6 +160,11 @@ namespace CoopClient
|
||||
|
||||
switch (packetType)
|
||||
{
|
||||
case (byte)PacketTypes.CleanUpWorldPacket:
|
||||
{
|
||||
Main.CleanUpWorld();
|
||||
}
|
||||
break;
|
||||
case (byte)PacketTypes.PlayerConnectPacket:
|
||||
{
|
||||
int len = message.ReadInt32();
|
||||
@ -602,6 +609,18 @@ namespace CoopClient
|
||||
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();
|
||||
new NativeResponsePacket()
|
||||
{
|
||||
@ -785,7 +804,9 @@ namespace CoopClient
|
||||
new FullSyncPlayerVehPacket()
|
||||
{
|
||||
NetHandle = Main.LocalNetHandle,
|
||||
PedHandle = player.Handle,
|
||||
Health = player.Health,
|
||||
VehicleHandle = veh.Handle,
|
||||
ModelHash = player.Model.Hash,
|
||||
Clothes = player.GetPedClothes(),
|
||||
VehModelHash = veh.Model.Hash,
|
||||
@ -810,6 +831,7 @@ namespace CoopClient
|
||||
new FullSyncPlayerPacket()
|
||||
{
|
||||
NetHandle = Main.LocalNetHandle,
|
||||
PedHandle = player.Handle,
|
||||
Health = player.Health,
|
||||
ModelHash = player.Model.Hash,
|
||||
Clothes = player.GetPedClothes(),
|
||||
|
@ -112,7 +112,8 @@ namespace CoopClient
|
||||
ChatMessagePacket,
|
||||
NativeCallPacket,
|
||||
NativeResponsePacket,
|
||||
ModPacket
|
||||
ModPacket,
|
||||
CleanUpWorldPacket
|
||||
}
|
||||
|
||||
enum ConnectionChannel
|
||||
@ -416,6 +417,8 @@ namespace CoopClient
|
||||
{
|
||||
public long NetHandle { get; set; }
|
||||
|
||||
public int PedHandle { get; set; }
|
||||
|
||||
public int Health { get; set; }
|
||||
|
||||
public int ModelHash { get; set; }
|
||||
@ -450,6 +453,9 @@ namespace CoopClient
|
||||
// Write player netHandle
|
||||
byteArray.AddRange(BitConverter.GetBytes(NetHandle));
|
||||
|
||||
// Write player ped handle
|
||||
byteArray.AddRange(BitConverter.GetBytes(PedHandle));
|
||||
|
||||
// Write player health
|
||||
byteArray.AddRange(BitConverter.GetBytes(Health));
|
||||
|
||||
@ -545,6 +551,9 @@ namespace CoopClient
|
||||
// Read player netHandle
|
||||
NetHandle = reader.ReadLong();
|
||||
|
||||
// Read player pedHandle
|
||||
PedHandle = reader.ReadInt();
|
||||
|
||||
// Read player health
|
||||
Health = reader.ReadInt();
|
||||
|
||||
@ -635,8 +644,12 @@ namespace CoopClient
|
||||
{
|
||||
public long NetHandle { get; set; }
|
||||
|
||||
public int PedHandle { get; set; }
|
||||
|
||||
public int Health { get; set; }
|
||||
|
||||
public int VehicleHandle { get; set; }
|
||||
|
||||
public int ModelHash { get; set; }
|
||||
|
||||
public Dictionary<byte, short> Clothes { get; set; }
|
||||
@ -683,12 +696,18 @@ namespace CoopClient
|
||||
// Write player netHandle
|
||||
byteArray.AddRange(BitConverter.GetBytes(NetHandle));
|
||||
|
||||
// Write player ped handle
|
||||
byteArray.AddRange(BitConverter.GetBytes(PedHandle));
|
||||
|
||||
// Write vehicles flags
|
||||
byteArray.AddRange(BitConverter.GetBytes(Flag.Value));
|
||||
|
||||
// Write player health
|
||||
byteArray.AddRange(BitConverter.GetBytes(Health));
|
||||
|
||||
// Write player ped handle
|
||||
byteArray.AddRange(BitConverter.GetBytes(VehicleHandle));
|
||||
|
||||
// Write player model hash
|
||||
byteArray.AddRange(BitConverter.GetBytes(ModelHash));
|
||||
|
||||
@ -812,12 +831,18 @@ namespace CoopClient
|
||||
// Read player netHandle
|
||||
NetHandle = reader.ReadLong();
|
||||
|
||||
// Read player ped handle
|
||||
PedHandle = reader.ReadInt();
|
||||
|
||||
// Read vehicle flags
|
||||
Flag = reader.ReadUShort();
|
||||
|
||||
// Read player health
|
||||
Health = reader.ReadInt();
|
||||
|
||||
// Read player vehicle handle
|
||||
VehicleHandle = reader.ReadInt();
|
||||
|
||||
// Read player model hash
|
||||
ModelHash = reader.ReadInt();
|
||||
|
||||
|
@ -11,6 +11,7 @@ namespace CoopServer
|
||||
public float Latency = 0.0f;
|
||||
public PlayerData Player;
|
||||
private readonly Dictionary<string, object> CustomData = new();
|
||||
private long CallbacksCount = 0;
|
||||
internal readonly Dictionary<long, Action<object>> Callbacks = new();
|
||||
|
||||
#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
|
||||
{
|
||||
@ -84,7 +85,7 @@ namespace CoopServer
|
||||
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!");
|
||||
return;
|
||||
@ -93,7 +94,7 @@ namespace CoopServer
|
||||
NativeCallPacket packet = new()
|
||||
{
|
||||
Hash = hash,
|
||||
Args = args ?? new List<object>(),
|
||||
Args = new List<object>(args) ?? new List<object>(),
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
@ -117,14 +118,14 @@ namespace CoopServer
|
||||
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!");
|
||||
return;
|
||||
}
|
||||
|
||||
long id = 0;
|
||||
Callbacks.Add(id = Environment.TickCount64, callback);
|
||||
long id = ++CallbacksCount;
|
||||
Callbacks.Add(id, callback);
|
||||
|
||||
byte returnTypeValue = 0x00;
|
||||
if (returnType == typeof(int))
|
||||
@ -157,7 +158,7 @@ namespace CoopServer
|
||||
new NativeResponsePacket()
|
||||
{
|
||||
Hash = hash,
|
||||
Args = args ?? new List<object>(),
|
||||
Args = new List<object>(args) ?? new List<object>(),
|
||||
ResultType = returnTypeValue,
|
||||
ID = id
|
||||
}.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)
|
||||
{
|
||||
try
|
||||
|
@ -8,6 +8,27 @@ using Newtonsoft.Json;
|
||||
|
||||
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 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 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 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
|
||||
}
|
||||
|
||||
@ -64,7 +98,8 @@ namespace CoopServer
|
||||
ChatMessagePacket,
|
||||
NativeCallPacket,
|
||||
NativeResponsePacket,
|
||||
ModPacket
|
||||
ModPacket,
|
||||
CleanUpWorldPacket
|
||||
}
|
||||
|
||||
enum ConnectionChannel
|
||||
@ -365,6 +400,8 @@ namespace CoopServer
|
||||
{
|
||||
public long NetHandle { get; set; }
|
||||
|
||||
public int PedHandle { get; set; }
|
||||
|
||||
public int Health { get; set; }
|
||||
|
||||
public int ModelHash { get; set; }
|
||||
@ -399,6 +436,9 @@ namespace CoopServer
|
||||
// Write player netHandle
|
||||
byteArray.AddRange(BitConverter.GetBytes(NetHandle));
|
||||
|
||||
// Write player ped handle
|
||||
byteArray.AddRange(BitConverter.GetBytes(PedHandle));
|
||||
|
||||
// Write player health
|
||||
byteArray.AddRange(BitConverter.GetBytes(Health));
|
||||
|
||||
@ -494,6 +534,9 @@ namespace CoopServer
|
||||
// Read player netHandle
|
||||
NetHandle = reader.ReadLong();
|
||||
|
||||
// Read player pedHandle
|
||||
PedHandle = reader.ReadInt();
|
||||
|
||||
// Read player health
|
||||
Health = reader.ReadInt();
|
||||
|
||||
@ -584,8 +627,12 @@ namespace CoopServer
|
||||
{
|
||||
public long NetHandle { get; set; }
|
||||
|
||||
public int PedHandle { get; set; }
|
||||
|
||||
public int Health { get; set; }
|
||||
|
||||
public int VehicleHandle { get; set; }
|
||||
|
||||
public int ModelHash { get; set; }
|
||||
|
||||
public Dictionary<byte, short> Clothes { get; set; }
|
||||
@ -632,12 +679,18 @@ namespace CoopServer
|
||||
// Write player netHandle
|
||||
byteArray.AddRange(BitConverter.GetBytes(NetHandle));
|
||||
|
||||
// Write player ped handle
|
||||
byteArray.AddRange(BitConverter.GetBytes(PedHandle));
|
||||
|
||||
// Write vehicles flags
|
||||
byteArray.AddRange(BitConverter.GetBytes(Flag.Value));
|
||||
|
||||
// Write player health
|
||||
byteArray.AddRange(BitConverter.GetBytes(Health));
|
||||
|
||||
// Write player ped handle
|
||||
byteArray.AddRange(BitConverter.GetBytes(VehicleHandle));
|
||||
|
||||
// Write player model hash
|
||||
byteArray.AddRange(BitConverter.GetBytes(ModelHash));
|
||||
|
||||
@ -761,12 +814,18 @@ namespace CoopServer
|
||||
// Read player netHandle
|
||||
NetHandle = reader.ReadLong();
|
||||
|
||||
// Read player ped handle
|
||||
PedHandle = reader.ReadInt();
|
||||
|
||||
// Read vehicle flags
|
||||
Flag = reader.ReadUShort();
|
||||
|
||||
// Read player health
|
||||
Health = reader.ReadInt();
|
||||
|
||||
// Read player vehicle handle
|
||||
VehicleHandle = reader.ReadInt();
|
||||
|
||||
// Read player model hash
|
||||
ModelHash = reader.ReadInt();
|
||||
|
||||
|
@ -5,6 +5,37 @@ namespace CoopServer
|
||||
public struct PlayerData
|
||||
{
|
||||
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 CurrentPosition { get; set; }
|
||||
public LVector3 Position
|
||||
|
@ -23,6 +23,7 @@ namespace CoopServer
|
||||
internal class Server
|
||||
{
|
||||
private static readonly string CompatibleVersion = "V1_3";
|
||||
private static long CurrentTick = 0;
|
||||
|
||||
public static readonly Settings MainSettings = Util.Read<Settings>("CoopSettings.xml");
|
||||
private readonly Blocklist MainBlocklist = Util.Read<Blocklist>("Blocklist.xml");
|
||||
@ -220,6 +221,14 @@ namespace CoopServer
|
||||
|
||||
while (!Program.ReadyToStop)
|
||||
{
|
||||
if (Resources.Count != 0)
|
||||
{
|
||||
Resources.ForEach(x =>
|
||||
{
|
||||
x.InvokeTick(++CurrentTick);
|
||||
});
|
||||
}
|
||||
|
||||
NetIncomingMessage message;
|
||||
|
||||
while ((message = MainNetServer.ReadMessage()) != null)
|
||||
@ -729,6 +738,8 @@ namespace CoopServer
|
||||
return;
|
||||
}
|
||||
// Save the new data
|
||||
client.Player.PedHandle = packet.PedHandle;
|
||||
client.Player.IsInVehicle = false;
|
||||
client.Player.Position = packet.Position;
|
||||
client.Player.Health = packet.Health;
|
||||
|
||||
@ -769,6 +780,9 @@ namespace CoopServer
|
||||
return;
|
||||
}
|
||||
// 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.Health = packet.Health;
|
||||
|
||||
|
@ -128,12 +128,21 @@ namespace CoopServer
|
||||
_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
|
||||
{
|
||||
#region DELEGATES
|
||||
public delegate void EmptyEvent();
|
||||
public delegate void OnTickEvent(long tick);
|
||||
public delegate void ChatEvent(string username, string message, CancelEventArgs cancel);
|
||||
public delegate void PlayerEvent(Client client);
|
||||
public delegate void ModEvent(long from, long target, string mod, byte customID, byte[] bytes, CancelEventArgs args);
|
||||
@ -141,6 +150,10 @@ namespace CoopServer
|
||||
|
||||
#region EVENTS
|
||||
/// <summary>
|
||||
/// Called every tick
|
||||
/// </summary>
|
||||
public event OnTickEvent OnTick;
|
||||
/// <summary>
|
||||
/// Called when the server has started
|
||||
/// </summary>
|
||||
public event EmptyEvent OnStart;
|
||||
@ -181,6 +194,11 @@ namespace CoopServer
|
||||
/// </summary>
|
||||
public event ModEvent OnModPacketReceived;
|
||||
|
||||
internal void InvokeTick(long tick)
|
||||
{
|
||||
OnTick?.Invoke(tick);
|
||||
}
|
||||
|
||||
internal void InvokeStart()
|
||||
{
|
||||
OnStart?.Invoke();
|
||||
@ -276,7 +294,7 @@ namespace CoopServer
|
||||
/// </summary>
|
||||
/// <param name="hash">The hash (Example: 0x25223CA6B4D20B7F = GET_CLOCK_HOURS)</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
|
||||
{
|
||||
@ -285,7 +303,7 @@ namespace CoopServer
|
||||
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!");
|
||||
return;
|
||||
@ -294,7 +312,7 @@ namespace CoopServer
|
||||
NativeCallPacket packet = new()
|
||||
{
|
||||
Hash = hash,
|
||||
Args = args ?? new List<object>()
|
||||
Args = new List<object>(args) ?? new List<object>()
|
||||
};
|
||||
|
||||
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>
|
||||
/// Register a new command chat command (Example: "/test")
|
||||
/// </summary>
|
||||
|
Reference in New Issue
Block a user