Resources are now multithreaded. GameMode renamed to Resource
This commit is contained in:
@ -18,9 +18,9 @@
|
||||
LastPosition = CurrentPosition;
|
||||
CurrentPosition = value;
|
||||
|
||||
if (Server.GameMode != null && !LVector3.Equals(CurrentPosition, LastPosition))
|
||||
if (Server.MainResource != null && !LVector3.Equals(CurrentPosition, LastPosition))
|
||||
{
|
||||
Server.GameMode.API.InvokePlayerPositionUpdate(this);
|
||||
Server.MainResource.InvokePlayerPositionUpdate(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ namespace CoopServer
|
||||
|
||||
public static NetServer MainNetServer;
|
||||
|
||||
public static ServerScript GameMode;
|
||||
public static Resource MainResource;
|
||||
public static Dictionary<Command, Action<CommandContext>> Commands;
|
||||
|
||||
public static readonly List<Client> Clients = new();
|
||||
@ -62,13 +62,13 @@ namespace CoopServer
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(MainSettings.GameMode))
|
||||
if (!string.IsNullOrEmpty(MainSettings.Resource))
|
||||
{
|
||||
try
|
||||
{
|
||||
Logging.Info("Loading gamemode...");
|
||||
Logging.Info("Loading resource...");
|
||||
|
||||
Assembly asm = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + "gamemodes" + Path.DirectorySeparatorChar + MainSettings.GameMode + ".dll");
|
||||
Assembly asm = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + "resources" + Path.DirectorySeparatorChar + MainSettings.Resource + ".dll");
|
||||
Type[] types = asm.GetExportedTypes();
|
||||
IEnumerable<Type> validTypes = types.Where(t => !t.IsInterface && !t.IsAbstract).Where(t => typeof(ServerScript).IsAssignableFrom(t));
|
||||
Type[] enumerable = validTypes as Type[] ?? validTypes.ToArray();
|
||||
@ -81,14 +81,13 @@ namespace CoopServer
|
||||
{
|
||||
Commands = new();
|
||||
|
||||
GameMode = Activator.CreateInstance(enumerable.ToArray()[0]) as ServerScript;
|
||||
if (GameMode == null)
|
||||
if (Activator.CreateInstance(enumerable.ToArray()[0]) is ServerScript script)
|
||||
{
|
||||
Logging.Warning("Could not create gamemode: it is null.");
|
||||
MainResource = new(script);
|
||||
}
|
||||
else
|
||||
{
|
||||
GameMode.API.InvokeStart();
|
||||
Logging.Warning("Could not create resource: it is null.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -289,9 +288,10 @@ namespace CoopServer
|
||||
packet.NetIncomingMessageToPacket(message);
|
||||
|
||||
ModPacket modPacket = (ModPacket)packet;
|
||||
if (GameMode != null)
|
||||
if (MainResource != null)
|
||||
{
|
||||
if (GameMode.API.InvokeModPacketReceived(modPacket.ID, modPacket.Target, modPacket.Mod, modPacket.CustomPacketID, modPacket.Bytes))
|
||||
// TODO: We need the true/false result
|
||||
if (MainResource.InvokeModPacketReceived(modPacket.ID, modPacket.Target, modPacket.Mod, modPacket.CustomPacketID, modPacket.Bytes))
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -458,9 +458,9 @@ namespace CoopServer
|
||||
SendChatMessage(new ChatMessagePacket() { Username = "Server", Message = MainSettings.WelcomeMessage }, new List<NetConnection>() { local });
|
||||
}
|
||||
|
||||
if (GameMode != null)
|
||||
if (MainResource != null)
|
||||
{
|
||||
GameMode.API.InvokePlayerConnected(Clients.Find(x => x.ID == packet.ID));
|
||||
MainResource.InvokePlayerConnected(Clients.Find(x => x.ID == packet.ID));
|
||||
}
|
||||
|
||||
List<NetConnection> clients;
|
||||
@ -502,9 +502,9 @@ namespace CoopServer
|
||||
// Send all players a message that someone has left the server
|
||||
private static void SendPlayerDisconnectPacket(PlayerDisconnectPacket packet)
|
||||
{
|
||||
if (GameMode != null)
|
||||
if (MainResource != null)
|
||||
{
|
||||
GameMode.API.InvokePlayerDisconnected(Clients.Find(x => x.ID == packet.ID));
|
||||
MainResource.InvokePlayerDisconnected(Clients.Find(x => x.ID == packet.ID));
|
||||
}
|
||||
|
||||
List<NetConnection> clients;
|
||||
@ -643,7 +643,7 @@ namespace CoopServer
|
||||
{
|
||||
NetOutgoingMessage outgoingMessage;
|
||||
|
||||
if (GameMode != null)
|
||||
if (MainResource != null)
|
||||
{
|
||||
if (packet.Message.StartsWith("/"))
|
||||
{
|
||||
@ -679,7 +679,7 @@ namespace CoopServer
|
||||
|
||||
return;
|
||||
}
|
||||
else if (GameMode.API.InvokeChatMessage(packet.Username, packet.Message))
|
||||
else if (MainResource.InvokeChatMessage(packet.Username, packet.Message)) // TODO: We need the true/false result
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2,11 +2,96 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Lidgren.Network;
|
||||
|
||||
namespace CoopServer
|
||||
{
|
||||
internal class Resource
|
||||
{
|
||||
private static Thread _mainThread;
|
||||
private static bool _hasToStop = false;
|
||||
private static Queue<Action> _actionQueue;
|
||||
private static TaskFactory _factory;
|
||||
private static ServerScript _script;
|
||||
|
||||
public Resource(ServerScript script)
|
||||
{
|
||||
_factory = new();
|
||||
_actionQueue = new();
|
||||
_mainThread = new(ThreadLoop) { IsBackground = true };
|
||||
_mainThread.Start();
|
||||
|
||||
lock (_actionQueue)
|
||||
{
|
||||
_actionQueue.Enqueue(() => _script = script);
|
||||
}
|
||||
}
|
||||
|
||||
private void ThreadLoop()
|
||||
{
|
||||
do
|
||||
{
|
||||
// 16 milliseconds to sleep to reduce CPU usage
|
||||
Thread.Sleep(1000 / 60);
|
||||
|
||||
if (_actionQueue.Count == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
lock (_actionQueue)
|
||||
{
|
||||
_factory.StartNew(() => _actionQueue.Dequeue()?.Invoke());
|
||||
}
|
||||
} while (_hasToStop);
|
||||
}
|
||||
|
||||
public bool InvokeModPacketReceived(long from, long target, string mod, byte customID, byte[] bytes)
|
||||
{
|
||||
Task<bool> shutdownTask = new(() => _script.API.InvokeModPacketReceived(from, target, mod, customID, bytes));
|
||||
shutdownTask.Start();
|
||||
shutdownTask.Wait(5000);
|
||||
|
||||
return shutdownTask.Result;
|
||||
}
|
||||
|
||||
public void InvokePlayerConnected(Client client)
|
||||
{
|
||||
lock (_actionQueue)
|
||||
{
|
||||
_actionQueue.Enqueue(() => _script.API.InvokePlayerConnected(client));
|
||||
}
|
||||
}
|
||||
|
||||
public void InvokePlayerDisconnected(Client client)
|
||||
{
|
||||
lock (_actionQueue)
|
||||
{
|
||||
_actionQueue.Enqueue(() => _script.API.InvokePlayerDisconnected(client));
|
||||
}
|
||||
}
|
||||
|
||||
public bool InvokeChatMessage(string username, string message)
|
||||
{
|
||||
Task<bool> shutdownTask = new(() => _script.API.InvokeChatMessage(username, message));
|
||||
shutdownTask.Start();
|
||||
shutdownTask.Wait(5000);
|
||||
|
||||
return shutdownTask.Result;
|
||||
}
|
||||
|
||||
public void InvokePlayerPositionUpdate(PlayerData playerData)
|
||||
{
|
||||
lock (_actionQueue)
|
||||
{
|
||||
_actionQueue.Enqueue(() => _script.API.InvokePlayerPositionUpdate(playerData));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class ServerScript
|
||||
{
|
||||
public API API { get; } = new();
|
||||
|
@ -6,7 +6,7 @@
|
||||
public int MaxPlayers { get; set; } = 16;
|
||||
public string ServerName { get; set; } = "GTACoop:R server";
|
||||
public string WelcomeMessage { get; set; } = "Welcome on this server :)";
|
||||
public string GameMode { get; set; } = "";
|
||||
public string Resource { get; set; } = "";
|
||||
public bool Allowlist { get; set; } = false;
|
||||
public bool NpcsAllowed { get; set; } = true;
|
||||
public bool ModsAllowed { get; set; } = false;
|
||||
|
Reference in New Issue
Block a user