Error handling, bug fixes, new API functions and more added!
This commit is contained in:
@ -442,7 +442,7 @@ namespace CoopClient
|
||||
|
||||
if (VehicleSteeringAngle != MainVehicle.SteeringAngle)
|
||||
{
|
||||
MainVehicle.Handle.CustomSteeringAngle((float)(Math.PI / 180) * VehicleSteeringAngle);
|
||||
MainVehicle.CustomSteeringAngle((float)(Math.PI / 180) * VehicleSteeringAngle);
|
||||
}
|
||||
|
||||
// Good enough for now, but we need to create a better sync
|
||||
|
@ -25,8 +25,11 @@ namespace FirstGameMode
|
||||
RunningSinceTimer.Start();
|
||||
RunningSinceTimer.Elapsed += new ElapsedEventHandler((sender, e) => RunningSince += 1);
|
||||
|
||||
API.OnStart += OnResourceStarted;
|
||||
API.OnPlayerConnected += OnPlayerConnected;
|
||||
API.OnPlayerDisconnected += OnPlayerDisconnected;
|
||||
API.OnPlayerHealthUpdate += OnPlayerHealthUpdate;
|
||||
API.OnPlayerPositionUpdate += OnPlayerPositionUpdate;
|
||||
API.OnChatMessage += OnChatMessage;
|
||||
API.OnModPacketReceived += OnModPacketReceived;
|
||||
|
||||
@ -34,7 +37,25 @@ namespace FirstGameMode
|
||||
API.RegisterCommands<Commands>();
|
||||
}
|
||||
|
||||
private void OnModPacketReceived(long from, long target, string mod, byte customID, byte[] bytes, CancelEventArgs args)
|
||||
public void OnResourceStarted()
|
||||
{
|
||||
Logging.Info("Resource started successfully!");
|
||||
}
|
||||
|
||||
public void OnPlayerHealthUpdate(Client client)
|
||||
{
|
||||
if (client.Player.Health == 0)
|
||||
{
|
||||
Logging.Warning($"Player {client.Player.Username} has died!");
|
||||
}
|
||||
}
|
||||
|
||||
public void OnPlayerPositionUpdate(Client client)
|
||||
{
|
||||
// Code...
|
||||
}
|
||||
|
||||
public void OnModPacketReceived(long from, long target, string mod, byte customID, byte[] bytes, CancelEventArgs args)
|
||||
{
|
||||
if (mod != "FirstScript" || customID != 1)
|
||||
{
|
||||
@ -56,22 +77,22 @@ namespace FirstGameMode
|
||||
targetClient.SendNativeCall(0x47C3B5848C3E45D8, setPlayerTime.Hours, setPlayerTime.Minutes, setPlayerTime.Seconds);
|
||||
}
|
||||
|
||||
public static void RunningCommand(CommandContext ctx)
|
||||
public void RunningCommand(CommandContext ctx)
|
||||
{
|
||||
ctx.Client.SendChatMessage("Server has been running for: " + RunningSince + " seconds!");
|
||||
ctx.Client.SendChatMessage($"Server has been running for: {RunningSince} seconds!");
|
||||
}
|
||||
|
||||
public static void OnPlayerConnected(Client client)
|
||||
public void OnPlayerConnected(Client client)
|
||||
{
|
||||
API.SendChatMessageToAll("Player " + client.Player.Username + " connected!");
|
||||
client.SendChatMessage($"Welcome {client.Player.Username}!");
|
||||
}
|
||||
|
||||
public static void OnPlayerDisconnected(Client client)
|
||||
public void OnPlayerDisconnected(Client client)
|
||||
{
|
||||
API.SendChatMessageToAll("Player " + client.Player.Username + " disconnected!");
|
||||
API.SendChatMessageToAll($"Player {client.Player.Username} disconnected!");
|
||||
}
|
||||
|
||||
public static void OnChatMessage(string username, string message, CancelEventArgs e)
|
||||
public void OnChatMessage(string username, string message, CancelEventArgs e)
|
||||
{
|
||||
e.Cancel = true;
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Lidgren.Network;
|
||||
|
||||
@ -43,14 +44,21 @@ namespace CoopServer
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region FUNCTIONS
|
||||
public void Kick(string[] reason)
|
||||
{
|
||||
Server.MainNetServer.Connections.Find(x => x.RemoteUniqueIdentifier == ID).Disconnect(string.Join(" ", reason));
|
||||
Server.MainNetServer.Connections.Find(x => x.RemoteUniqueIdentifier == ID)?.Disconnect(string.Join(" ", reason));
|
||||
}
|
||||
|
||||
public void SendChatMessage(string message, string from = "Server")
|
||||
{
|
||||
try
|
||||
{
|
||||
NetConnection userConnection = Server.MainNetServer.Connections.Find(x => x.RemoteUniqueIdentifier == ID);
|
||||
if (userConnection == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ChatMessagePacket packet = new()
|
||||
{
|
||||
@ -62,10 +70,21 @@ namespace CoopServer
|
||||
packet.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
Server.MainNetServer.SendMessage(outgoingMessage, userConnection, NetDeliveryMethod.ReliableOrdered, 0);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Error($">> {e.Message} <<>> {e.Source ?? string.Empty} <<>> {e.StackTrace ?? string.Empty} <<");
|
||||
}
|
||||
}
|
||||
|
||||
public void SendNativeCall(ulong hash, params object[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
NetConnection userConnection = Server.MainNetServer.Connections.Find(x => x.RemoteUniqueIdentifier == ID);
|
||||
if (userConnection == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<NativeArgument> arguments = Util.ParseNativeArguments(args);
|
||||
if (arguments == null)
|
||||
@ -83,15 +102,26 @@ namespace CoopServer
|
||||
packet.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
Server.MainNetServer.SendMessage(outgoingMessage, userConnection, NetDeliveryMethod.ReliableOrdered, 0);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Error($">> {e.Message} <<>> {e.Source ?? string.Empty} <<>> {e.StackTrace ?? string.Empty} <<");
|
||||
}
|
||||
}
|
||||
|
||||
public void SendModPacket(string mod, byte customID, byte[] bytes)
|
||||
{
|
||||
try
|
||||
{
|
||||
NetConnection userConnection = Server.MainNetServer.Connections.Find(x => x.RemoteUniqueIdentifier == ID);
|
||||
if (userConnection == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
|
||||
new ModPacket()
|
||||
{
|
||||
ID = -1,
|
||||
ID = 0,
|
||||
Target = 0,
|
||||
Mod = mod,
|
||||
CustomPacketID = customID,
|
||||
@ -100,5 +130,11 @@ namespace CoopServer
|
||||
Server.MainNetServer.SendMessage(outgoingMessage, userConnection, NetDeliveryMethod.ReliableOrdered, 0);
|
||||
Server.MainNetServer.FlushSendQueue();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Error($">> {e.Message} <<>> {e.Source ?? string.Empty} <<>> {e.StackTrace ?? string.Empty} <<");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -8,11 +8,7 @@
|
||||
private LVector3 CurrentPosition { get; set; }
|
||||
public LVector3 Position
|
||||
{
|
||||
get
|
||||
{
|
||||
return CurrentPosition;
|
||||
}
|
||||
|
||||
get => CurrentPosition;
|
||||
set
|
||||
{
|
||||
LastPosition = CurrentPosition;
|
||||
@ -24,6 +20,20 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
private int CurrentHealth { get; set; }
|
||||
public int Health
|
||||
{
|
||||
get => CurrentHealth;
|
||||
set
|
||||
{
|
||||
if (CurrentHealth != value && Server.MainResource != null)
|
||||
{
|
||||
Server.MainResource.InvokePlayerHealthUpdate(this);
|
||||
}
|
||||
|
||||
CurrentHealth = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsInRangeOf(LVector3 position, float distance)
|
||||
{
|
||||
|
161
Server/Server.cs
161
Server/Server.cs
@ -299,15 +299,16 @@ namespace CoopServer
|
||||
if (modPacket.Target != 0)
|
||||
{
|
||||
NetConnection target = MainNetServer.Connections.FirstOrDefault(x => x.RemoteUniqueIdentifier == modPacket.Target);
|
||||
if (target == null)
|
||||
if (target.Equals(default(Client)))
|
||||
{
|
||||
Logging.Error($"[ModPacket] target \"{modPacket.Target}\" not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// Send back to target
|
||||
MainNetServer.SendMessage(outgoingMessage, target, NetDeliveryMethod.ReliableOrdered, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send back to all players
|
||||
@ -331,7 +332,7 @@ namespace CoopServer
|
||||
break;
|
||||
case NetIncomingMessageType.ConnectionLatencyUpdated:
|
||||
Client client = Clients.FirstOrDefault(x => x.ID == message.SenderConnection.RemoteUniqueIdentifier);
|
||||
if (client != default)
|
||||
if (!client.Equals(default(Client)))
|
||||
{
|
||||
client.Latency = message.ReadFloat();
|
||||
}
|
||||
@ -420,9 +421,13 @@ namespace CoopServer
|
||||
|
||||
long localID = local.RemoteUniqueIdentifier;
|
||||
|
||||
Client tmpClient;
|
||||
|
||||
// Add the player to Players
|
||||
lock (Clients)
|
||||
{
|
||||
Clients.Add(
|
||||
new Client()
|
||||
tmpClient = new Client()
|
||||
{
|
||||
ID = localID,
|
||||
Player = new()
|
||||
@ -432,6 +437,7 @@ namespace CoopServer
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||
|
||||
@ -447,47 +453,51 @@ namespace CoopServer
|
||||
|
||||
// Accept the connection and send back a new handshake packet with the connection ID
|
||||
local.Approve(outgoingMessage);
|
||||
|
||||
if (MainResource != null)
|
||||
{
|
||||
MainResource.InvokePlayerHandshake(tmpClient);
|
||||
}
|
||||
}
|
||||
|
||||
// The connection has been approved, now we need to send all other players to the new player and the new player to all players
|
||||
private static void SendPlayerConnectPacket(NetConnection local, PlayerConnectPacket packet)
|
||||
{
|
||||
Client localClient = Clients.FirstOrDefault(x => x.ID == packet.ID);
|
||||
if (localClient.Equals(default(Client)))
|
||||
{
|
||||
local.Disconnect("No data found!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(MainSettings.WelcomeMessage))
|
||||
{
|
||||
SendChatMessage(new ChatMessagePacket() { Username = "Server", Message = MainSettings.WelcomeMessage }, new List<NetConnection>() { local });
|
||||
}
|
||||
|
||||
if (MainResource != null)
|
||||
{
|
||||
MainResource.InvokePlayerConnected(Clients.Find(x => x.ID == packet.ID));
|
||||
}
|
||||
|
||||
List<NetConnection> clients;
|
||||
if ((clients = Util.FilterAllLocal(local)).Count == 0)
|
||||
if ((clients = Util.FilterAllLocal(local)).Count > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Send all players to local
|
||||
clients.ForEach(targetPlayer =>
|
||||
{
|
||||
long targetPlayerID = targetPlayer.RemoteUniqueIdentifier;
|
||||
|
||||
Client targetEntity = Clients.First(x => x.ID == targetPlayerID);
|
||||
|
||||
Client targetClient = Clients.FirstOrDefault(x => x.ID == targetPlayerID);
|
||||
if (!targetClient.Equals(default(Client)))
|
||||
{
|
||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||
new PlayerConnectPacket()
|
||||
{
|
||||
ID = targetPlayerID,
|
||||
SocialClubName = targetEntity.Player.SocialClubName,
|
||||
Username = targetEntity.Player.Username
|
||||
SocialClubName = targetClient.Player.SocialClubName,
|
||||
Username = targetClient.Player.Username
|
||||
}.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
MainNetServer.SendMessage(outgoingMessage, local, NetDeliveryMethod.ReliableOrdered, 0);
|
||||
}
|
||||
});
|
||||
|
||||
// Send local to all players
|
||||
Client localClient = Clients.First(x => x.ID == packet.ID);
|
||||
|
||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||
new PlayerConnectPacket()
|
||||
{
|
||||
@ -498,14 +508,15 @@ namespace CoopServer
|
||||
MainNetServer.SendMessage(outgoingMessage, clients, NetDeliveryMethod.ReliableOrdered, 0);
|
||||
}
|
||||
|
||||
if (MainResource != null)
|
||||
{
|
||||
MainResource.InvokePlayerConnected(localClient);
|
||||
}
|
||||
}
|
||||
|
||||
// Send all players a message that someone has left the server
|
||||
private static void SendPlayerDisconnectPacket(PlayerDisconnectPacket packet)
|
||||
{
|
||||
if (MainResource != null)
|
||||
{
|
||||
MainResource.InvokePlayerDisconnected(Clients.Find(x => x.ID == packet.ID));
|
||||
}
|
||||
|
||||
List<NetConnection> clients;
|
||||
if ((clients = Util.FilterAllLocal(packet.ID)).Count > 0)
|
||||
{
|
||||
@ -514,16 +525,40 @@ namespace CoopServer
|
||||
MainNetServer.SendMessage(outgoingMessage, clients, NetDeliveryMethod.ReliableOrdered, 0);
|
||||
}
|
||||
|
||||
Clients.Remove(Clients.Find(x => x.ID == packet.ID));
|
||||
Client localClient = Clients.FirstOrDefault(x => x.ID == packet.ID);
|
||||
if (localClient.Equals(default(Client)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (MainResource != null)
|
||||
{
|
||||
MainResource.InvokePlayerDisconnected(localClient);
|
||||
}
|
||||
|
||||
lock (Clients)
|
||||
{
|
||||
Clients.Remove(localClient);
|
||||
}
|
||||
}
|
||||
|
||||
private static void FullSyncPlayer(FullSyncPlayerPacket packet)
|
||||
{
|
||||
Client client = Clients.First(x => x.ID == packet.Extra.ID);
|
||||
client.Player.Position = packet.Extra.Position;
|
||||
Client tmpClient = Clients.FirstOrDefault(x => x.ID == packet.Extra.ID);
|
||||
if (tmpClient.Equals(default(Client)))
|
||||
{
|
||||
NetConnection localConn = MainNetServer.Connections.Find(x => packet.Extra.ID == x.RemoteUniqueIdentifier);
|
||||
if (localConn != null)
|
||||
{
|
||||
localConn.Disconnect("No data found!");
|
||||
}
|
||||
return;
|
||||
}
|
||||
tmpClient.Player.Position = packet.Extra.Position;
|
||||
tmpClient.Player.Health = packet.Extra.Health;
|
||||
|
||||
PlayerPacket playerPacket = packet.Extra;
|
||||
playerPacket.Latency = client.Latency;
|
||||
playerPacket.Latency = tmpClient.Latency;
|
||||
|
||||
packet.Extra = playerPacket;
|
||||
|
||||
@ -545,15 +580,30 @@ namespace CoopServer
|
||||
|
||||
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, 0);
|
||||
});
|
||||
|
||||
if (MainResource != null)
|
||||
{
|
||||
MainResource.InvokePlayerUpdate(tmpClient);
|
||||
}
|
||||
}
|
||||
|
||||
private static void FullSyncPlayerVeh(FullSyncPlayerVehPacket packet)
|
||||
{
|
||||
Client client = Clients.First(x => x.ID == packet.Extra.ID);
|
||||
client.Player.Position = packet.Extra.Position;
|
||||
Client tmpClient = Clients.FirstOrDefault(x => x.ID == packet.Extra.ID);
|
||||
if (tmpClient.Equals(default(Client)))
|
||||
{
|
||||
NetConnection localConn = MainNetServer.Connections.Find(x => packet.Extra.ID == x.RemoteUniqueIdentifier);
|
||||
if (localConn != null)
|
||||
{
|
||||
localConn.Disconnect("No data found!");
|
||||
}
|
||||
return;
|
||||
}
|
||||
tmpClient.Player.Position = packet.Extra.Position;
|
||||
tmpClient.Player.Health = packet.Extra.Health;
|
||||
|
||||
PlayerPacket playerPacket = packet.Extra;
|
||||
playerPacket.Latency = client.Latency;
|
||||
playerPacket.Latency = tmpClient.Latency;
|
||||
|
||||
packet.Extra = playerPacket;
|
||||
|
||||
@ -575,15 +625,30 @@ namespace CoopServer
|
||||
|
||||
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, 0);
|
||||
});
|
||||
|
||||
if (MainResource != null)
|
||||
{
|
||||
MainResource.InvokePlayerUpdate(tmpClient);
|
||||
}
|
||||
}
|
||||
|
||||
private static void LightSyncPlayer(LightSyncPlayerPacket packet)
|
||||
{
|
||||
Client client = Clients.First(x => x.ID == packet.Extra.ID);
|
||||
client.Player.Position = packet.Extra.Position;
|
||||
Client tmpClient = Clients.FirstOrDefault(x => x.ID == packet.Extra.ID);
|
||||
if (tmpClient.Equals(default(Client)))
|
||||
{
|
||||
NetConnection localConn = MainNetServer.Connections.Find(x => packet.Extra.ID == x.RemoteUniqueIdentifier);
|
||||
if (localConn != null)
|
||||
{
|
||||
localConn.Disconnect("No data found!");
|
||||
}
|
||||
return;
|
||||
}
|
||||
tmpClient.Player.Position = packet.Extra.Position;
|
||||
tmpClient.Player.Health = packet.Extra.Health;
|
||||
|
||||
PlayerPacket playerPacket = packet.Extra;
|
||||
playerPacket.Latency = client.Latency;
|
||||
playerPacket.Latency = tmpClient.Latency;
|
||||
|
||||
packet.Extra = playerPacket;
|
||||
|
||||
@ -605,15 +670,30 @@ namespace CoopServer
|
||||
|
||||
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, 0);
|
||||
});
|
||||
|
||||
if (MainResource != null)
|
||||
{
|
||||
MainResource.InvokePlayerUpdate(tmpClient);
|
||||
}
|
||||
}
|
||||
|
||||
private static void LightSyncPlayerVeh(LightSyncPlayerVehPacket packet)
|
||||
{
|
||||
Client client = Clients.First(x => x.ID == packet.Extra.ID);
|
||||
client.Player.Position = packet.Extra.Position;
|
||||
Client tmpClient = Clients.FirstOrDefault(x => x.ID == packet.Extra.ID);
|
||||
if (tmpClient.Equals(default(Client)))
|
||||
{
|
||||
NetConnection localConn = MainNetServer.Connections.Find(x => packet.Extra.ID == x.RemoteUniqueIdentifier);
|
||||
if (localConn != null)
|
||||
{
|
||||
localConn.Disconnect("No data found!");
|
||||
}
|
||||
return;
|
||||
}
|
||||
tmpClient.Player.Position = packet.Extra.Position;
|
||||
tmpClient.Player.Health = packet.Extra.Health;
|
||||
|
||||
PlayerPacket playerPacket = packet.Extra;
|
||||
playerPacket.Latency = client.Latency;
|
||||
playerPacket.Latency = tmpClient.Latency;
|
||||
|
||||
packet.Extra = playerPacket;
|
||||
|
||||
@ -635,6 +715,11 @@ namespace CoopServer
|
||||
|
||||
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, 0);
|
||||
});
|
||||
|
||||
if (MainResource != null)
|
||||
{
|
||||
MainResource.InvokePlayerUpdate(tmpClient);
|
||||
}
|
||||
}
|
||||
|
||||
// Send a message to targets or all players
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
@ -13,18 +14,16 @@ namespace CoopServer
|
||||
{
|
||||
private static Thread _mainThread;
|
||||
private static bool _hasToStop = false;
|
||||
private static Queue<Action> _actionQueue;
|
||||
private static TaskFactory _factory;
|
||||
private static Queue _actionQueue;
|
||||
private static ServerScript _script;
|
||||
|
||||
public Resource(ServerScript script)
|
||||
{
|
||||
_factory = new();
|
||||
_actionQueue = new();
|
||||
_actionQueue = Queue.Synchronized(new Queue());
|
||||
_mainThread = new(ThreadLoop) { IsBackground = true };
|
||||
_mainThread.Start();
|
||||
|
||||
lock (_actionQueue)
|
||||
lock (_actionQueue.SyncRoot)
|
||||
{
|
||||
_actionQueue.Enqueue(() =>
|
||||
{
|
||||
@ -36,60 +35,88 @@ namespace CoopServer
|
||||
|
||||
private void ThreadLoop()
|
||||
{
|
||||
do
|
||||
while (!_hasToStop)
|
||||
{
|
||||
if (_actionQueue.Count != 0)
|
||||
Queue localQueue;
|
||||
lock (_actionQueue.SyncRoot)
|
||||
{
|
||||
lock (_actionQueue)
|
||||
{
|
||||
_factory.StartNew(() => _actionQueue.Dequeue()?.Invoke());
|
||||
localQueue = new(_actionQueue);
|
||||
_actionQueue.Clear();
|
||||
}
|
||||
|
||||
while (localQueue.Count > 0)
|
||||
{
|
||||
(localQueue.Dequeue() as Action)?.Invoke();
|
||||
}
|
||||
|
||||
// 16 milliseconds to sleep to reduce CPU usage
|
||||
Thread.Sleep(1000 / 60);
|
||||
} 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);
|
||||
Task<bool> task = new(() => _script.API.InvokeModPacketReceived(from, target, mod, customID, bytes));
|
||||
task.Start();
|
||||
task.Wait(5000);
|
||||
|
||||
return shutdownTask.Result;
|
||||
return task.Result;
|
||||
}
|
||||
|
||||
public void InvokePlayerHandshake(Client client)
|
||||
{
|
||||
lock (_actionQueue.SyncRoot)
|
||||
{
|
||||
_actionQueue.Enqueue(new Action(() => _script.API.InvokePlayerConnected(client)));
|
||||
}
|
||||
}
|
||||
|
||||
public void InvokePlayerConnected(Client client)
|
||||
{
|
||||
lock (_actionQueue)
|
||||
lock (_actionQueue.SyncRoot)
|
||||
{
|
||||
_actionQueue.Enqueue(() => _script.API.InvokePlayerConnected(client));
|
||||
_actionQueue.Enqueue(new Action(() => _script.API.InvokePlayerConnected(client)));
|
||||
}
|
||||
}
|
||||
|
||||
public void InvokePlayerDisconnected(Client client)
|
||||
{
|
||||
lock (_actionQueue)
|
||||
lock (_actionQueue.SyncRoot)
|
||||
{
|
||||
_actionQueue.Enqueue(() => _script.API.InvokePlayerDisconnected(client));
|
||||
_actionQueue.Enqueue(new Action(() => _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);
|
||||
Task<bool> task = new(() => _script.API.InvokeChatMessage(username, message));
|
||||
task.Start();
|
||||
task.Wait(5000);
|
||||
|
||||
return shutdownTask.Result;
|
||||
return task.Result;
|
||||
}
|
||||
|
||||
public void InvokePlayerPositionUpdate(PlayerData playerData)
|
||||
{
|
||||
lock (_actionQueue)
|
||||
lock (_actionQueue.SyncRoot)
|
||||
{
|
||||
_actionQueue.Enqueue(() => _script.API.InvokePlayerPositionUpdate(playerData));
|
||||
_actionQueue.Enqueue(new Action(() => _script.API.InvokePlayerPositionUpdate(playerData)));
|
||||
}
|
||||
}
|
||||
|
||||
public void InvokePlayerUpdate(Client client)
|
||||
{
|
||||
lock (_actionQueue.SyncRoot)
|
||||
{
|
||||
_actionQueue.Enqueue(new Action(() => _script.API.InvokePlayerUpdate(client)));
|
||||
}
|
||||
}
|
||||
|
||||
public void InvokePlayerHealthUpdate(PlayerData playerData)
|
||||
{
|
||||
lock (_actionQueue.SyncRoot)
|
||||
{
|
||||
_actionQueue.Enqueue(new Action(() => _script.API.InvokePlayerHealthUpdate(playerData)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -102,22 +129,31 @@ namespace CoopServer
|
||||
public class API
|
||||
{
|
||||
#region DELEGATES
|
||||
public delegate void EmptyEvent();
|
||||
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);
|
||||
#endregion
|
||||
|
||||
#region EVENTS
|
||||
public event EventHandler OnStart;
|
||||
public event EmptyEvent OnStart;
|
||||
public event ChatEvent OnChatMessage;
|
||||
public event PlayerEvent OnPlayerHandshake;
|
||||
public event PlayerEvent OnPlayerConnected;
|
||||
public event PlayerEvent OnPlayerDisconnected;
|
||||
public event PlayerEvent OnPlayerUpdate;
|
||||
public event PlayerEvent OnPlayerHealthUpdate;
|
||||
public event PlayerEvent OnPlayerPositionUpdate;
|
||||
public event ModEvent OnModPacketReceived;
|
||||
|
||||
internal void InvokeStart()
|
||||
{
|
||||
OnStart?.Invoke(this, EventArgs.Empty);
|
||||
OnStart?.Invoke();
|
||||
}
|
||||
|
||||
internal void InvokePlayerHandshake(Client client)
|
||||
{
|
||||
OnPlayerHandshake?.Invoke(client);
|
||||
}
|
||||
|
||||
internal void InvokePlayerConnected(Client client)
|
||||
@ -130,6 +166,16 @@ namespace CoopServer
|
||||
OnPlayerDisconnected?.Invoke(client);
|
||||
}
|
||||
|
||||
internal void InvokePlayerUpdate(Client client)
|
||||
{
|
||||
OnPlayerUpdate?.Invoke(client);
|
||||
}
|
||||
|
||||
internal void InvokePlayerHealthUpdate(PlayerData playerData)
|
||||
{
|
||||
OnPlayerHealthUpdate?.Invoke(Server.Clients.First(x => x.Player.Username == playerData.Username));
|
||||
}
|
||||
|
||||
internal bool InvokeChatMessage(string username, string message)
|
||||
{
|
||||
CancelEventArgs args = new(false);
|
||||
@ -152,11 +198,13 @@ namespace CoopServer
|
||||
|
||||
#region FUNCTIONS
|
||||
public static void SendModPacketToAll(string mod, byte customID, byte[] bytes)
|
||||
{
|
||||
try
|
||||
{
|
||||
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
|
||||
new ModPacket()
|
||||
{
|
||||
ID = -1,
|
||||
ID = 0,
|
||||
Target = 0,
|
||||
Mod = mod,
|
||||
CustomPacketID = customID,
|
||||
@ -165,8 +213,15 @@ namespace CoopServer
|
||||
Server.MainNetServer.SendMessage(outgoingMessage, Server.MainNetServer.Connections, NetDeliveryMethod.ReliableOrdered, 0);
|
||||
Server.MainNetServer.FlushSendQueue();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Error($">> {e.Message} <<>> {e.Source ?? string.Empty} <<>> {e.StackTrace ?? string.Empty} <<");
|
||||
}
|
||||
}
|
||||
|
||||
public static void SendNativeCallToAll(ulong hash, params object[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Server.MainNetServer.ConnectionsCount == 0)
|
||||
{
|
||||
@ -189,6 +244,11 @@ namespace CoopServer
|
||||
packet.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
Server.MainNetServer.SendMessage(outgoingMessage, Server.MainNetServer.Connections, NetDeliveryMethod.ReliableOrdered, 0);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Error($">> {e.Message} <<>> {e.Source ?? string.Empty} <<>> {e.StackTrace ?? string.Empty} <<");
|
||||
}
|
||||
}
|
||||
|
||||
public static List<long> GetAllConnections()
|
||||
{
|
||||
@ -211,26 +271,32 @@ namespace CoopServer
|
||||
|
||||
public static Client GetClientByUsername(string username)
|
||||
{
|
||||
return Server.Clients.FirstOrDefault(x => x.Player.Username == username);
|
||||
Client client = Server.Clients.FirstOrDefault(x => x.Player.Username == username);
|
||||
return client.Equals(default(Client)) ? null : client;
|
||||
}
|
||||
|
||||
public static void SendChatMessageToAll(string message, string username = "Server")
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Server.MainNetServer.ConnectionsCount == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ChatMessagePacket packet = new()
|
||||
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
|
||||
new ChatMessagePacket()
|
||||
{
|
||||
Username = username,
|
||||
Message = message
|
||||
};
|
||||
|
||||
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
|
||||
packet.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
}.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
Server.MainNetServer.SendMessage(outgoingMessage, Server.MainNetServer.Connections, NetDeliveryMethod.ReliableOrdered, 0);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Error($">> {e.Message} <<>> {e.Source ?? string.Empty} <<>> {e.StackTrace ?? string.Empty} <<");
|
||||
}
|
||||
}
|
||||
|
||||
public static void RegisterCommand(string name, Action<CommandContext> callback)
|
||||
{
|
||||
|
@ -50,13 +50,13 @@ namespace CoopServer
|
||||
|
||||
public static NetConnection GetConnectionByUsername(string username)
|
||||
{
|
||||
long clientID;
|
||||
if ((clientID = Server.Clients.FirstOrDefault(x => x.Player.Username == username).ID) == default)
|
||||
Client client = Server.Clients.FirstOrDefault(x => x.Player.Username == username);
|
||||
if (client.Equals(default(Client)))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return Server.MainNetServer.Connections.FirstOrDefault(x => x.RemoteUniqueIdentifier == clientID);
|
||||
return Server.MainNetServer.Connections.FirstOrDefault(x => x.RemoteUniqueIdentifier == client.ID);
|
||||
}
|
||||
|
||||
// Return a list of all connections but not the local connection
|
||||
@ -72,12 +72,20 @@ namespace CoopServer
|
||||
// Return a list of players within range of ...
|
||||
public static List<NetConnection> GetAllInRange(LVector3 position, float range)
|
||||
{
|
||||
return new(Server.MainNetServer.Connections.FindAll(e => Server.Clients.First(x => x.ID == e.RemoteUniqueIdentifier).Player.IsInRangeOf(position, range)));
|
||||
return new(Server.MainNetServer.Connections.FindAll(e =>
|
||||
{
|
||||
Client client = Server.Clients.First(x => x.ID == e.RemoteUniqueIdentifier);
|
||||
return !client.Equals(default(Client)) && client.Player.IsInRangeOf(position, range);
|
||||
}));
|
||||
}
|
||||
// Return a list of players within range of ... but not the local one
|
||||
public static List<NetConnection> GetAllInRange(LVector3 position, float range, NetConnection local)
|
||||
{
|
||||
return new(Server.MainNetServer.Connections.Where(e => e != local && Server.Clients.First(x => x.ID == e.RemoteUniqueIdentifier).Player.IsInRangeOf(position, range)));
|
||||
return new(Server.MainNetServer.Connections.Where(e =>
|
||||
{
|
||||
Client client = Server.Clients.First(x => x.ID == e.RemoteUniqueIdentifier);
|
||||
return e != local && !client.Equals(default(Client)) && client.Player.IsInRangeOf(position, range);
|
||||
}));
|
||||
}
|
||||
|
||||
public static T Read<T>(string file) where T : new()
|
||||
|
Reference in New Issue
Block a user