2021-08-15 07:54:25 +02:00
|
|
|
|
using System;
|
2021-11-25 16:32:04 +01:00
|
|
|
|
using System.Collections;
|
2021-08-15 07:54:25 +02:00
|
|
|
|
using System.Collections.Generic;
|
2021-08-18 12:47:36 +02:00
|
|
|
|
using System.ComponentModel;
|
2021-08-22 13:59:15 +02:00
|
|
|
|
using System.Linq;
|
2021-11-20 05:38:00 +01:00
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Threading.Tasks;
|
2022-05-22 15:55:26 +08:00
|
|
|
|
using RageCoop.Core;
|
2021-08-15 07:54:25 +02:00
|
|
|
|
using Lidgren.Network;
|
2021-08-14 21:49:23 +02:00
|
|
|
|
|
2022-05-22 15:55:26 +08:00
|
|
|
|
namespace RageCoop.Server
|
2021-08-14 21:49:23 +02:00
|
|
|
|
{
|
2021-11-27 22:44:00 +01:00
|
|
|
|
public abstract class ServerScript
|
|
|
|
|
{
|
|
|
|
|
public API API { get; } = new();
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-22 15:55:26 +08:00
|
|
|
|
public class Resource
|
2021-11-20 05:38:00 +01:00
|
|
|
|
{
|
2021-12-08 13:45:00 +01:00
|
|
|
|
public bool ReadyToStop = false;
|
|
|
|
|
|
2021-11-20 05:38:00 +01:00
|
|
|
|
private static Thread _mainThread;
|
2021-11-25 16:32:04 +01:00
|
|
|
|
private static Queue _actionQueue;
|
2021-11-20 05:38:00 +01:00
|
|
|
|
private static ServerScript _script;
|
|
|
|
|
|
|
|
|
|
public Resource(ServerScript script)
|
|
|
|
|
{
|
2021-11-25 16:32:04 +01:00
|
|
|
|
_actionQueue = Queue.Synchronized(new Queue());
|
2021-11-20 05:38:00 +01:00
|
|
|
|
_mainThread = new(ThreadLoop) { IsBackground = true };
|
|
|
|
|
_mainThread.Start();
|
|
|
|
|
|
2021-11-25 16:32:04 +01:00
|
|
|
|
lock (_actionQueue.SyncRoot)
|
2021-11-20 05:38:00 +01:00
|
|
|
|
{
|
2021-11-23 23:02:41 +01:00
|
|
|
|
_actionQueue.Enqueue(() =>
|
|
|
|
|
{
|
|
|
|
|
_script = script;
|
|
|
|
|
_script.API.InvokeStart();
|
|
|
|
|
});
|
2021-11-20 05:38:00 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ThreadLoop()
|
|
|
|
|
{
|
2021-12-08 13:45:00 +01:00
|
|
|
|
while (!Program.ReadyToStop)
|
2021-11-20 05:38:00 +01:00
|
|
|
|
{
|
2021-11-25 16:32:04 +01:00
|
|
|
|
Queue localQueue;
|
|
|
|
|
lock (_actionQueue.SyncRoot)
|
2021-11-20 05:38:00 +01:00
|
|
|
|
{
|
2021-11-25 16:32:04 +01:00
|
|
|
|
localQueue = new(_actionQueue);
|
|
|
|
|
_actionQueue.Clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (localQueue.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
(localQueue.Dequeue() as Action)?.Invoke();
|
2021-11-20 05:38:00 +01:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-31 09:14:30 +08:00
|
|
|
|
// 15 milliseconds to sleep to reduce CPU usage
|
|
|
|
|
Thread.Sleep(15);
|
2021-11-25 16:32:04 +01:00
|
|
|
|
}
|
2021-12-08 13:45:00 +01:00
|
|
|
|
|
|
|
|
|
_script.API.InvokeStop();
|
|
|
|
|
ReadyToStop = true;
|
2021-11-20 05:38:00 +01:00
|
|
|
|
}
|
|
|
|
|
|
2022-01-01 03:07:18 +01:00
|
|
|
|
public bool InvokeModPacketReceived(long from, long target, string modName, byte customID, byte[] bytes)
|
2021-11-20 05:38:00 +01:00
|
|
|
|
{
|
2022-01-01 03:07:18 +01:00
|
|
|
|
Task<bool> task = new(() => _script.API.InvokeModPacketReceived(from, target, modName, customID, bytes));
|
2021-11-25 16:32:04 +01:00
|
|
|
|
task.Start();
|
|
|
|
|
task.Wait(5000);
|
2021-11-27 22:44:00 +01:00
|
|
|
|
|
2021-11-25 16:32:04 +01:00
|
|
|
|
return task.Result;
|
|
|
|
|
}
|
2021-11-20 05:38:00 +01:00
|
|
|
|
|
2021-11-25 16:32:04 +01:00
|
|
|
|
public void InvokePlayerHandshake(Client client)
|
|
|
|
|
{
|
|
|
|
|
lock (_actionQueue.SyncRoot)
|
|
|
|
|
{
|
2021-12-17 23:02:53 +01:00
|
|
|
|
_actionQueue.Enqueue(new Action(() => _script.API.InvokePlayerHandshake(client)));
|
2021-11-25 16:32:04 +01:00
|
|
|
|
}
|
2021-11-20 05:38:00 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void InvokePlayerConnected(Client client)
|
|
|
|
|
{
|
2021-11-25 16:32:04 +01:00
|
|
|
|
lock (_actionQueue.SyncRoot)
|
2021-11-20 05:38:00 +01:00
|
|
|
|
{
|
2021-11-25 16:32:04 +01:00
|
|
|
|
_actionQueue.Enqueue(new Action(() => _script.API.InvokePlayerConnected(client)));
|
2021-11-20 05:38:00 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void InvokePlayerDisconnected(Client client)
|
|
|
|
|
{
|
2021-11-25 16:32:04 +01:00
|
|
|
|
lock (_actionQueue.SyncRoot)
|
2021-11-20 05:38:00 +01:00
|
|
|
|
{
|
2021-11-25 16:32:04 +01:00
|
|
|
|
_actionQueue.Enqueue(new Action(() => _script.API.InvokePlayerDisconnected(client)));
|
2021-11-20 05:38:00 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool InvokeChatMessage(string username, string message)
|
|
|
|
|
{
|
2021-11-25 16:32:04 +01:00
|
|
|
|
Task<bool> task = new(() => _script.API.InvokeChatMessage(username, message));
|
|
|
|
|
task.Start();
|
|
|
|
|
task.Wait(5000);
|
2021-11-27 22:44:00 +01:00
|
|
|
|
|
2021-11-25 16:32:04 +01:00
|
|
|
|
return task.Result;
|
2021-11-20 05:38:00 +01:00
|
|
|
|
}
|
|
|
|
|
|
2021-11-25 16:32:04 +01:00
|
|
|
|
|
|
|
|
|
public void InvokePlayerUpdate(Client client)
|
|
|
|
|
{
|
|
|
|
|
lock (_actionQueue.SyncRoot)
|
2021-11-20 05:38:00 +01:00
|
|
|
|
{
|
2021-11-25 16:32:04 +01:00
|
|
|
|
_actionQueue.Enqueue(new Action(() => _script.API.InvokePlayerUpdate(client)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-26 03:25:00 +01:00
|
|
|
|
|
|
|
|
|
public void InvokeTick(long tick)
|
|
|
|
|
{
|
|
|
|
|
lock (_actionQueue.SyncRoot)
|
|
|
|
|
{
|
|
|
|
|
_actionQueue.Enqueue(new Action(() => _script.API.InvokeTick(tick)));
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-11-20 05:38:00 +01:00
|
|
|
|
}
|
|
|
|
|
|
2021-08-18 12:47:36 +02:00
|
|
|
|
public class API
|
|
|
|
|
{
|
|
|
|
|
#region DELEGATES
|
2021-11-25 16:32:04 +01:00
|
|
|
|
public delegate void EmptyEvent();
|
2021-12-26 03:25:00 +01:00
|
|
|
|
public delegate void OnTickEvent(long tick);
|
2021-08-18 12:47:36 +02:00
|
|
|
|
public delegate void ChatEvent(string username, string message, CancelEventArgs cancel);
|
2021-08-26 17:01:32 +02:00
|
|
|
|
public delegate void PlayerEvent(Client client);
|
2022-01-01 03:07:18 +01:00
|
|
|
|
public delegate void ModEvent(long from, long target, string modName, byte customID, byte[] bytes, CancelEventArgs args);
|
2021-08-18 12:47:36 +02:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region EVENTS
|
2021-12-16 14:52:48 +01:00
|
|
|
|
/// <summary>
|
2021-12-26 03:25:00 +01:00
|
|
|
|
/// Called every tick
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event OnTickEvent OnTick;
|
|
|
|
|
/// <summary>
|
2021-12-16 14:52:48 +01:00
|
|
|
|
/// Called when the server has started
|
|
|
|
|
/// </summary>
|
2021-11-25 16:32:04 +01:00
|
|
|
|
public event EmptyEvent OnStart;
|
2021-12-16 14:52:48 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Called when the server has stopped
|
|
|
|
|
/// </summary>
|
2021-12-08 13:45:00 +01:00
|
|
|
|
public event EmptyEvent OnStop;
|
2021-12-16 14:52:48 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Called when the server receives a new chat message for players
|
|
|
|
|
/// </summary>
|
2021-08-18 12:47:36 +02:00
|
|
|
|
public event ChatEvent OnChatMessage;
|
2021-12-16 14:52:48 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Called when the server receives a new incoming connection
|
|
|
|
|
/// </summary>
|
2021-11-25 16:32:04 +01:00
|
|
|
|
public event PlayerEvent OnPlayerHandshake;
|
2021-12-16 14:52:48 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Called when a new player has successfully connected
|
|
|
|
|
/// </summary>
|
2021-08-18 12:47:36 +02:00
|
|
|
|
public event PlayerEvent OnPlayerConnected;
|
2021-12-16 14:52:48 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Called when a new player has successfully disconnected
|
|
|
|
|
/// </summary>
|
2021-08-18 12:47:36 +02:00
|
|
|
|
public event PlayerEvent OnPlayerDisconnected;
|
2021-12-16 14:52:48 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Called when a new player sends data like health
|
|
|
|
|
/// </summary>
|
2021-11-25 16:32:04 +01:00
|
|
|
|
public event PlayerEvent OnPlayerUpdate;
|
2021-09-29 14:34:22 +02:00
|
|
|
|
public event ModEvent OnModPacketReceived;
|
2021-08-18 12:47:36 +02:00
|
|
|
|
|
2022-05-22 15:55:26 +08:00
|
|
|
|
public void InvokeTick(long tick)
|
2021-12-26 03:25:00 +01:00
|
|
|
|
{
|
|
|
|
|
OnTick?.Invoke(tick);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-22 15:55:26 +08:00
|
|
|
|
public void InvokeStart()
|
2021-08-18 12:47:36 +02:00
|
|
|
|
{
|
2021-11-25 16:32:04 +01:00
|
|
|
|
OnStart?.Invoke();
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-22 15:55:26 +08:00
|
|
|
|
public void InvokeStop()
|
2021-12-08 13:45:00 +01:00
|
|
|
|
{
|
|
|
|
|
OnStop?.Invoke();
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-22 15:55:26 +08:00
|
|
|
|
public void InvokePlayerHandshake(Client client)
|
2021-11-25 16:32:04 +01:00
|
|
|
|
{
|
|
|
|
|
OnPlayerHandshake?.Invoke(client);
|
2021-08-18 12:47:36 +02:00
|
|
|
|
}
|
2021-08-15 07:54:25 +02:00
|
|
|
|
|
2022-05-22 15:55:26 +08:00
|
|
|
|
public void InvokePlayerConnected(Client client)
|
2021-08-15 07:54:25 +02:00
|
|
|
|
{
|
2021-08-26 17:01:32 +02:00
|
|
|
|
OnPlayerConnected?.Invoke(client);
|
2021-08-15 07:54:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-22 15:55:26 +08:00
|
|
|
|
public void InvokePlayerDisconnected(Client client)
|
2021-08-15 07:54:25 +02:00
|
|
|
|
{
|
2021-08-26 17:01:32 +02:00
|
|
|
|
OnPlayerDisconnected?.Invoke(client);
|
2021-08-18 11:47:59 +02:00
|
|
|
|
}
|
2021-08-15 07:54:25 +02:00
|
|
|
|
|
2022-05-22 15:55:26 +08:00
|
|
|
|
public void InvokePlayerUpdate(Client client)
|
2021-11-25 16:32:04 +01:00
|
|
|
|
{
|
|
|
|
|
OnPlayerUpdate?.Invoke(client);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-22 15:55:26 +08:00
|
|
|
|
public bool InvokeChatMessage(string username, string message)
|
2021-08-18 11:47:59 +02:00
|
|
|
|
{
|
2021-09-27 20:28:27 +02:00
|
|
|
|
CancelEventArgs args = new(false);
|
2021-08-18 12:47:36 +02:00
|
|
|
|
OnChatMessage?.Invoke(username, message, args);
|
|
|
|
|
return args.Cancel;
|
2021-08-15 07:54:25 +02:00
|
|
|
|
}
|
2021-08-20 17:28:13 +02:00
|
|
|
|
|
2022-05-22 15:55:26 +08:00
|
|
|
|
public bool InvokeModPacketReceived(long from, long target, string modName, byte customID, byte[] bytes)
|
2021-09-29 14:34:22 +02:00
|
|
|
|
{
|
|
|
|
|
CancelEventArgs args = new(false);
|
2022-01-01 03:07:18 +01:00
|
|
|
|
OnModPacketReceived?.Invoke(from, target, modName, customID, bytes, args);
|
2021-09-29 14:34:22 +02:00
|
|
|
|
return args.Cancel;
|
|
|
|
|
}
|
2021-08-18 12:47:36 +02:00
|
|
|
|
#endregion
|
2021-08-15 07:54:25 +02:00
|
|
|
|
|
2021-08-18 12:47:36 +02:00
|
|
|
|
#region FUNCTIONS
|
2021-12-16 14:52:48 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Send a mod packet to all players
|
|
|
|
|
/// </summary>
|
2022-01-01 03:07:18 +01:00
|
|
|
|
/// <param name="modName">The name of the modification that will receive the data</param>
|
2021-12-16 14:52:48 +01:00
|
|
|
|
/// <param name="customID">The ID to check what this data is</param>
|
|
|
|
|
/// <param name="bytes">The serialized data</param>
|
2022-05-31 09:14:30 +08:00
|
|
|
|
/// <param name="playerList">The list of player ID (PedID) that will receive the data</param>
|
|
|
|
|
public static void SendModPacketToAll(string modName, byte customID, byte[] bytes, List<int> playerList = null)
|
2021-11-23 23:17:47 +01:00
|
|
|
|
{
|
2021-11-25 16:32:04 +01:00
|
|
|
|
try
|
2022-05-31 09:14:30 +08:00
|
|
|
|
{// A resource can be calling this function on disconnect of the last player in the server and we will
|
2022-02-12 21:17:41 -07:00
|
|
|
|
// get an empty connection list, make sure connections has at least one handle in it
|
2022-05-31 09:14:30 +08:00
|
|
|
|
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
|
|
|
|
|
new Packets.Mod()
|
|
|
|
|
{
|
|
|
|
|
Name = modName,
|
|
|
|
|
CustomPacketID = customID,
|
|
|
|
|
Bytes = bytes
|
|
|
|
|
}.Pack(outgoingMessage);
|
|
|
|
|
if (playerList==null)
|
2021-11-25 16:32:04 +01:00
|
|
|
|
{
|
2022-05-31 09:14:30 +08:00
|
|
|
|
Server.MainNetServer.SendMessage(outgoingMessage, Server.MainNetServer.Connections, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Mod);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
foreach(var c in Server.Clients.Values)
|
2022-02-12 21:17:41 -07:00
|
|
|
|
{
|
2022-05-31 09:14:30 +08:00
|
|
|
|
if (playerList.Contains(c.Player.PedID))
|
|
|
|
|
{
|
|
|
|
|
Server.MainNetServer.SendMessage(outgoingMessage, c.Connection, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Mod);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-12 21:17:41 -07:00
|
|
|
|
}
|
2022-05-31 09:14:30 +08:00
|
|
|
|
Server.MainNetServer.FlushSendQueue();
|
2021-11-25 16:32:04 +01:00
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
2022-05-31 19:35:01 -08:00
|
|
|
|
Program.Logger.Error($">> {e.Message} <<>> {e.Source ?? string.Empty} <<>> {e.StackTrace ?? string.Empty} <<");
|
2021-11-25 16:32:04 +01:00
|
|
|
|
}
|
2021-11-23 23:17:47 +01:00
|
|
|
|
}
|
|
|
|
|
|
2021-12-16 14:52:48 +01:00
|
|
|
|
/// <summary>
|
2021-12-23 22:03:01 +01:00
|
|
|
|
/// Send a native call (Function.Call) to all players.
|
|
|
|
|
/// Keys = int, float, bool, string and lvector3
|
2021-12-16 14:52:48 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="hash">The hash (Example: 0x25223CA6B4D20B7F = GET_CLOCK_HOURS)</param>
|
2021-12-23 22:03:01 +01:00
|
|
|
|
/// <param name="args">The arguments (Example: string = int, object = 5)</param>
|
2021-12-26 03:25:00 +01:00
|
|
|
|
public static void SendNativeCallToAll(ulong hash, params object[] args)
|
2021-08-15 07:54:25 +02:00
|
|
|
|
{
|
2021-11-25 16:32:04 +01:00
|
|
|
|
try
|
2021-08-20 17:28:13 +02:00
|
|
|
|
{
|
2021-11-25 16:32:04 +01:00
|
|
|
|
if (Server.MainNetServer.ConnectionsCount == 0)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2021-08-18 11:47:59 +02:00
|
|
|
|
|
2021-12-26 03:25:00 +01:00
|
|
|
|
if (args != null && args.Length == 0)
|
2021-11-25 16:32:04 +01:00
|
|
|
|
{
|
2022-05-31 19:35:01 -08:00
|
|
|
|
Program.Logger.Error($"[ServerScript->SendNativeCallToAll(ulong hash, params object[] args)]: args is not null!");
|
2021-11-25 16:32:04 +01:00
|
|
|
|
return;
|
|
|
|
|
}
|
2021-08-15 07:54:25 +02:00
|
|
|
|
|
2022-01-01 03:07:18 +01:00
|
|
|
|
Packets.NativeCall packet = new()
|
2021-11-25 16:32:04 +01:00
|
|
|
|
{
|
|
|
|
|
Hash = hash,
|
2021-12-26 03:25:00 +01:00
|
|
|
|
Args = new List<object>(args) ?? new List<object>()
|
2021-11-25 16:32:04 +01:00
|
|
|
|
};
|
2021-08-20 17:28:13 +02:00
|
|
|
|
|
2021-11-25 16:32:04 +01:00
|
|
|
|
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
|
2022-05-22 15:55:26 +08:00
|
|
|
|
packet.Pack(outgoingMessage);
|
2021-12-23 22:03:01 +01:00
|
|
|
|
Server.MainNetServer.SendMessage(outgoingMessage, Server.MainNetServer.Connections, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Native);
|
2021-11-25 16:32:04 +01:00
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
2022-05-31 19:35:01 -08:00
|
|
|
|
Program.Logger.Error($">> {e.Message} <<>> {e.Source ?? string.Empty} <<>> {e.StackTrace ?? string.Empty} <<");
|
2021-11-25 16:32:04 +01:00
|
|
|
|
}
|
2021-08-18 11:47:59 +02:00
|
|
|
|
}
|
2021-08-15 07:54:25 +02:00
|
|
|
|
|
2022-03-25 15:45:22 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Get a list of all Clients
|
|
|
|
|
/// </summary>
|
2022-05-31 09:14:30 +08:00
|
|
|
|
/// <returns>All clients as a dictionary indexed by NetID</returns>
|
2022-05-30 11:11:40 +08:00
|
|
|
|
public static Dictionary<long,Client> GetAllClients()
|
2021-08-22 13:59:15 +02:00
|
|
|
|
{
|
2021-08-26 17:01:32 +02:00
|
|
|
|
return Server.Clients;
|
2021-08-22 13:59:15 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-03-25 15:45:22 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Get the client by its username
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="username">The username to search for</param>
|
|
|
|
|
/// <returns>The Client from this user or null</returns>
|
2021-08-26 17:01:32 +02:00
|
|
|
|
public static Client GetClientByUsername(string username)
|
2021-08-18 11:47:59 +02:00
|
|
|
|
{
|
2022-05-30 11:11:40 +08:00
|
|
|
|
return Server.Clients.Values.FirstOrDefault(x => x.Player.Username.ToLower() == username.ToLower());
|
2021-08-15 07:54:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
2021-12-16 14:52:48 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Send a chat message to all players
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="message">The chat message</param>
|
|
|
|
|
/// <param name="username">The username which send this message (default = "Server")</param>
|
|
|
|
|
/// <param name="netHandleList">The list of connections (players) who received this chat message</param>
|
2021-12-15 13:24:24 -07:00
|
|
|
|
public static void SendChatMessageToAll(string message, string username = "Server", List<long> netHandleList = null)
|
2021-08-14 21:49:23 +02:00
|
|
|
|
{
|
2021-11-25 16:32:04 +01:00
|
|
|
|
try
|
2021-08-15 07:54:25 +02:00
|
|
|
|
{
|
2021-11-25 16:32:04 +01:00
|
|
|
|
if (Server.MainNetServer.ConnectionsCount == 0)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2021-08-15 07:54:25 +02:00
|
|
|
|
|
2021-12-16 14:52:48 +01:00
|
|
|
|
List<NetConnection> connections = netHandleList == null
|
|
|
|
|
? Server.MainNetServer.Connections
|
|
|
|
|
: Server.MainNetServer.Connections.FindAll(c => netHandleList.Contains(c.RemoteUniqueIdentifier));
|
|
|
|
|
|
2021-12-23 22:03:01 +01:00
|
|
|
|
Server.SendChatMessage(username, message, connections);
|
2021-11-25 16:32:04 +01:00
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
2021-08-20 17:28:13 +02:00
|
|
|
|
{
|
2022-05-31 19:35:01 -08:00
|
|
|
|
Program.Logger.Error($">> {e.Message} <<>> {e.Source ?? string.Empty} <<>> {e.StackTrace ?? string.Empty} <<");
|
2021-11-25 16:32:04 +01:00
|
|
|
|
}
|
2021-08-14 21:49:23 +02:00
|
|
|
|
}
|
|
|
|
|
|
2021-12-26 03:25:00 +01:00
|
|
|
|
/// <summary>
|
2022-03-25 15:45:22 +01:00
|
|
|
|
/// Send CleanUpWorld to all players to delete all objects created by the server
|
2021-12-26 03:25:00 +01:00
|
|
|
|
/// </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();
|
2022-01-01 03:07:18 +01:00
|
|
|
|
outgoingMessage.Write((byte)PacketTypes.CleanUpWorld);
|
2021-12-26 03:25:00 +01:00
|
|
|
|
Server.MainNetServer.SendMessage(outgoingMessage, connections, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Default);
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-16 14:52:48 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Register a new command chat command (Example: "/test")
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="name">The name of the command (Example: "test" for "/test")</param>
|
|
|
|
|
/// <param name="usage">How to use this message (argsLength required!)</param>
|
|
|
|
|
/// <param name="argsLength">The length of args (Example: "/message USERNAME MESSAGE" = 2) (usage required!)</param>
|
|
|
|
|
/// <param name="callback">Create a new function!</param>
|
2021-12-02 23:05:22 +01:00
|
|
|
|
public static void RegisterCommand(string name, string usage, short argsLength, Action<CommandContext> callback)
|
|
|
|
|
{
|
|
|
|
|
Server.RegisterCommand(name, usage, argsLength, callback);
|
|
|
|
|
}
|
2021-12-16 14:52:48 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Register a new command chat command (Example: "/test")
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="name">The name of the command (Example: "test" for "/test")</param>
|
|
|
|
|
/// <param name="callback">Create a new function!</param>
|
2021-08-18 11:47:59 +02:00
|
|
|
|
public static void RegisterCommand(string name, Action<CommandContext> callback)
|
2021-08-14 21:49:23 +02:00
|
|
|
|
{
|
2021-08-18 11:47:59 +02:00
|
|
|
|
Server.RegisterCommand(name, callback);
|
|
|
|
|
}
|
2021-08-14 21:49:23 +02:00
|
|
|
|
|
2021-12-16 14:52:48 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Register a class of commands
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="T">The name of your class with functions</typeparam>
|
2021-08-18 11:47:59 +02:00
|
|
|
|
public static void RegisterCommands<T>()
|
|
|
|
|
{
|
|
|
|
|
Server.RegisterCommands<T>();
|
2021-08-14 21:49:23 +02:00
|
|
|
|
}
|
2022-04-12 06:04:02 +02:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Register a class of events
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="T">The name of your class with functions</typeparam>
|
|
|
|
|
public static void RegisterEvents<T>()
|
|
|
|
|
{
|
|
|
|
|
Server.RegisterEvents<T>();
|
|
|
|
|
}
|
2021-08-18 12:47:36 +02:00
|
|
|
|
#endregion
|
2021-08-18 11:47:59 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-04-12 06:04:02 +02:00
|
|
|
|
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
|
|
|
|
|
public class TriggerEvent : Attribute
|
|
|
|
|
{
|
|
|
|
|
public string EventName { get; set; }
|
|
|
|
|
|
|
|
|
|
public TriggerEvent(string eventName)
|
|
|
|
|
{
|
|
|
|
|
EventName = eventName;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class EventContext
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the client which executed the command
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Client Client { get; internal set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Arguments (all standard but no string!)
|
|
|
|
|
/// </summary>
|
|
|
|
|
public object[] Args { get; internal set; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
|
2021-12-02 23:05:22 +01:00
|
|
|
|
public class Command : Attribute
|
2021-08-18 11:47:59 +02:00
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Sets name of the command
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Name { get; set; }
|
|
|
|
|
|
2021-12-16 14:52:48 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Set the Usage (Example: "Please use "/help"". ArgsLength required!)
|
|
|
|
|
/// </summary>
|
2021-12-02 23:05:22 +01:00
|
|
|
|
public string Usage { get; set; }
|
|
|
|
|
|
2021-12-16 14:52:48 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Set the length of arguments (Example: 2 for "/message USERNAME MESSAGE". Usage required!)
|
|
|
|
|
/// </summary>
|
2021-12-02 23:05:22 +01:00
|
|
|
|
public short ArgsLength { get; set; }
|
|
|
|
|
|
|
|
|
|
public Command(string name)
|
2021-08-15 07:54:25 +02:00
|
|
|
|
{
|
2021-08-18 11:47:59 +02:00
|
|
|
|
Name = name;
|
2021-08-15 07:54:25 +02:00
|
|
|
|
}
|
2021-08-14 21:49:23 +02:00
|
|
|
|
}
|
2021-08-18 11:47:59 +02:00
|
|
|
|
|
|
|
|
|
public class CommandContext
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the client which executed the command
|
|
|
|
|
/// </summary>
|
2021-08-26 17:01:32 +02:00
|
|
|
|
public Client Client { get; internal set; }
|
2021-08-18 11:47:59 +02:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
2021-12-16 14:52:48 +01:00
|
|
|
|
/// Gets the arguments (Example: "/message USERNAME MESSAGE", Args[0] for USERNAME)
|
2021-08-18 11:47:59 +02:00
|
|
|
|
/// </summary>
|
|
|
|
|
public string[] Args { get; internal set; }
|
|
|
|
|
}
|
2021-08-14 21:49:23 +02:00
|
|
|
|
}
|