Resources are now multithreaded. GameMode renamed to Resource
This commit is contained in:
@ -18,9 +18,9 @@
|
|||||||
LastPosition = CurrentPosition;
|
LastPosition = CurrentPosition;
|
||||||
CurrentPosition = value;
|
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 NetServer MainNetServer;
|
||||||
|
|
||||||
public static ServerScript GameMode;
|
public static Resource MainResource;
|
||||||
public static Dictionary<Command, Action<CommandContext>> Commands;
|
public static Dictionary<Command, Action<CommandContext>> Commands;
|
||||||
|
|
||||||
public static readonly List<Client> Clients = new();
|
public static readonly List<Client> Clients = new();
|
||||||
@ -62,13 +62,13 @@ namespace CoopServer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(MainSettings.GameMode))
|
if (!string.IsNullOrEmpty(MainSettings.Resource))
|
||||||
{
|
{
|
||||||
try
|
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();
|
Type[] types = asm.GetExportedTypes();
|
||||||
IEnumerable<Type> validTypes = types.Where(t => !t.IsInterface && !t.IsAbstract).Where(t => typeof(ServerScript).IsAssignableFrom(t));
|
IEnumerable<Type> validTypes = types.Where(t => !t.IsInterface && !t.IsAbstract).Where(t => typeof(ServerScript).IsAssignableFrom(t));
|
||||||
Type[] enumerable = validTypes as Type[] ?? validTypes.ToArray();
|
Type[] enumerable = validTypes as Type[] ?? validTypes.ToArray();
|
||||||
@ -81,14 +81,13 @@ namespace CoopServer
|
|||||||
{
|
{
|
||||||
Commands = new();
|
Commands = new();
|
||||||
|
|
||||||
GameMode = Activator.CreateInstance(enumerable.ToArray()[0]) as ServerScript;
|
if (Activator.CreateInstance(enumerable.ToArray()[0]) is ServerScript script)
|
||||||
if (GameMode == null)
|
|
||||||
{
|
{
|
||||||
Logging.Warning("Could not create gamemode: it is null.");
|
MainResource = new(script);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GameMode.API.InvokeStart();
|
Logging.Warning("Could not create resource: it is null.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -289,9 +288,10 @@ namespace CoopServer
|
|||||||
packet.NetIncomingMessageToPacket(message);
|
packet.NetIncomingMessageToPacket(message);
|
||||||
|
|
||||||
ModPacket modPacket = (ModPacket)packet;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
@ -458,9 +458,9 @@ namespace CoopServer
|
|||||||
SendChatMessage(new ChatMessagePacket() { Username = "Server", Message = MainSettings.WelcomeMessage }, new List<NetConnection>() { local });
|
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;
|
List<NetConnection> clients;
|
||||||
@ -502,9 +502,9 @@ namespace CoopServer
|
|||||||
// Send all players a message that someone has left the server
|
// Send all players a message that someone has left the server
|
||||||
private static void SendPlayerDisconnectPacket(PlayerDisconnectPacket packet)
|
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;
|
List<NetConnection> clients;
|
||||||
@ -643,7 +643,7 @@ namespace CoopServer
|
|||||||
{
|
{
|
||||||
NetOutgoingMessage outgoingMessage;
|
NetOutgoingMessage outgoingMessage;
|
||||||
|
|
||||||
if (GameMode != null)
|
if (MainResource != null)
|
||||||
{
|
{
|
||||||
if (packet.Message.StartsWith("/"))
|
if (packet.Message.StartsWith("/"))
|
||||||
{
|
{
|
||||||
@ -679,7 +679,7 @@ namespace CoopServer
|
|||||||
|
|
||||||
return;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,96 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using Lidgren.Network;
|
using Lidgren.Network;
|
||||||
|
|
||||||
namespace CoopServer
|
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 abstract class ServerScript
|
||||||
{
|
{
|
||||||
public API API { get; } = new();
|
public API API { get; } = new();
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
public int MaxPlayers { get; set; } = 16;
|
public int MaxPlayers { get; set; } = 16;
|
||||||
public string ServerName { get; set; } = "GTACoop:R server";
|
public string ServerName { get; set; } = "GTACoop:R server";
|
||||||
public string WelcomeMessage { get; set; } = "Welcome on this 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 Allowlist { get; set; } = false;
|
||||||
public bool NpcsAllowed { get; set; } = true;
|
public bool NpcsAllowed { get; set; } = true;
|
||||||
public bool ModsAllowed { get; set; } = false;
|
public bool ModsAllowed { get; set; } = false;
|
||||||
|
Reference in New Issue
Block a user