use async handlers, add delay in PingHandler

client do NOT like ping < 16ms (considers it to be zero and this disables updates to other players' positions) ... so add some delay in PNG handler
This commit is contained in:
Robert Paciorek 2024-04-02 13:08:09 +00:00 committed by Spirtix
parent 04b906b21c
commit d0c1839b11
21 changed files with 145 additions and 94 deletions

View File

@ -5,14 +5,15 @@ using sodoffmmo.Data;
namespace sodoffmmo.CommandHandlers;
[ExtensionCommandHandler("SCM")]
class ChatMessageHandler : ICommandHandler {
public void Handle(Client client, NetworkObject receivedObject) {
class ChatMessageHandler : CommandHandler {
public override Task Handle(Client client, NetworkObject receivedObject) {
if (!Configuration.ServerConfiguration.EnableChat) {
ChatDisabled(client, receivedObject);
return;
}
} else {
Chat(client, receivedObject);
}
return Task.CompletedTask;
}
public void ChatDisabled(Client client, NetworkObject receivedObject) {
NetworkObject cmd = new();

View File

@ -5,13 +5,14 @@ using sodoffmmo.Data;
namespace sodoffmmo.CommandHandlers;
[ExtensionCommandHandler("DT")]
class DateTimeHandler : ICommandHandler {
public void Handle(Client client, NetworkObject receivedObject) {
class DateTimeHandler : CommandHandler {
public override Task Handle(Client client, NetworkObject receivedObject) {
NetworkObject cmd = new();
NetworkObject obj = new();
obj.Add("arr", new string[] { "DT", DateTime.UtcNow.ToString("MM/dd/yyyy HH:mm:ss") });
cmd.Add("c", "DT");
cmd.Add("p", obj);
client.Send(NetworkObject.WrapObject(1, 13, cmd).Serialize());
return Task.CompletedTask;
}
}

View File

@ -5,8 +5,9 @@ using sodoffmmo.Data;
namespace sodoffmmo.CommandHandlers;
[CommandHandler(26)]
class ExitHandler : ICommandHandler {
public void Handle(Client client, NetworkObject receivedObject) {
class ExitHandler : CommandHandler {
public override Task Handle(Client client, NetworkObject receivedObject) {
client.SetRoom(null);
return Task.CompletedTask;
}
}

View File

@ -9,27 +9,29 @@ namespace sodoffmmo.CommandHandlers;
// Host Room For Any
[ExtensionCommandHandler("gs.HRFA")]
class GauntletCreateRoomHandler : ICommandHandler
class GauntletCreateRoomHandler : CommandHandler
{
public void Handle(Client client, NetworkObject receivedObject) {
public override Task Handle(Client client, NetworkObject receivedObject) {
GauntletRoom.Join(client);
return Task.CompletedTask;
}
}
// Join Any Room
[ExtensionCommandHandler("gs.JAR")]
class GauntletJoinRoomHandler : ICommandHandler
class GauntletJoinRoomHandler : CommandHandler
{
public void Handle(Client client, NetworkObject receivedObject) {
public override Task Handle(Client client, NetworkObject receivedObject) {
GauntletRoom.Join(client);
return Task.CompletedTask;
}
}
// Play Again
[ExtensionCommandHandler("gs.PA")]
class GauntletPlayAgainHandler : ICommandHandler
class GauntletPlayAgainHandler : CommandHandler
{
public void Handle(Client client, NetworkObject receivedObject) {
public override Task Handle(Client client, NetworkObject receivedObject) {
GauntletRoom room = (client.Room as GauntletRoom)!;
room.SetPlayerReady(client, false);
@ -41,14 +43,15 @@ class GauntletPlayAgainHandler : ICommandHandler
room.Send(packet, client);
room.SendPA(client);
return Task.CompletedTask;
}
}
// Lobby User Ready
[ExtensionCommandHandler("gs.LUR")]
class GauntletLobbyUserReadyHandler : ICommandHandler
class GauntletLobbyUserReadyHandler : CommandHandler
{
public void Handle(Client client, NetworkObject receivedObject) {
public override Task Handle(Client client, NetworkObject receivedObject) {
GauntletRoom room = (client.Room as GauntletRoom)!;
room.SetPlayerReady(client);
@ -69,14 +72,15 @@ class GauntletLobbyUserReadyHandler : ICommandHandler
room.Send(packet);
}
return Task.CompletedTask;
}
}
// Lobby User Not Ready
[ExtensionCommandHandler("gs.LUNR")]
class GauntletLobbyUserNotReadyHandler : ICommandHandler
class GauntletLobbyUserNotReadyHandler : CommandHandler
{
public void Handle(Client client, NetworkObject receivedObject) {
public override Task Handle(Client client, NetworkObject receivedObject) {
GauntletRoom room = (client.Room as GauntletRoom)!;
room.SetPlayerReady(client, false);
@ -87,14 +91,15 @@ class GauntletLobbyUserNotReadyHandler : ICommandHandler
}, "msg", room.Id);
room.Send(packet);
return Task.CompletedTask;
}
}
// Game Level Load
[ExtensionCommandHandler("gs.GLL")]
class GauntletLevelLoadHandler : ICommandHandler
class GauntletLevelLoadHandler : CommandHandler
{
public void Handle(Client client, NetworkObject receivedObject) { // {"a":13,"c":1,"p":{"c":"gs.GLL","p":{"0":"0","1":"0","2":"5","en":"GauntletGameExtension"},"r":365587}}
public override Task Handle(Client client, NetworkObject receivedObject) { // {"a":13,"c":1,"p":{"c":"gs.GLL","p":{"0":"0","1":"0","2":"5","en":"GauntletGameExtension"},"r":365587}}
GauntletRoom room = (client.Room as GauntletRoom)!;
NetworkObject p = receivedObject.Get<NetworkObject>("p");
@ -106,18 +111,19 @@ class GauntletLevelLoadHandler : ICommandHandler
p.Get<string>("2") // TODO use size of p.fields - 1
}, "msg", room.Id);
room.Send(packet);
return Task.CompletedTask;
}
}
// Game Level Loaded
[ExtensionCommandHandler("gs.GLLD")]
class GauntletLevelLoadedHandler : ICommandHandler
class GauntletLevelLoadedHandler : CommandHandler
{
private System.Timers.Timer? timer = null;
private int counter;
private GauntletRoom room;
public void Handle(Client client, NetworkObject receivedObject) {
public override Task Handle(Client client, NetworkObject receivedObject) {
room = (client.Room as GauntletRoom)!;
counter = 5;
@ -133,6 +139,7 @@ class GauntletLevelLoadedHandler : ICommandHandler
timer.AutoReset = true;
timer.Enabled = true;
timer.Elapsed += OnTick;
return Task.CompletedTask;
}
private void OnTick(Object? source, ElapsedEventArgs e) {
@ -161,9 +168,9 @@ class GauntletLevelLoadedHandler : ICommandHandler
// Relay Game Data
[ExtensionCommandHandler("gs.RGD")]
class GauntletRelayGameDataHandler : ICommandHandler
class GauntletRelayGameDataHandler : CommandHandler
{
public void Handle(Client client, NetworkObject receivedObject) // {"a":13,"c":1,"p":{"c":"gs.RGD","p":{"0":"2700","1":"78","en":"GauntletGameExtension"},"r":4}}
public override Task Handle(Client client, NetworkObject receivedObject) // {"a":13,"c":1,"p":{"c":"gs.RGD","p":{"0":"2700","1":"78","en":"GauntletGameExtension"},"r":4}}
{
GauntletRoom room = (client.Room as GauntletRoom)!;
NetworkObject p = receivedObject.Get<NetworkObject>("p");
@ -176,19 +183,21 @@ class GauntletRelayGameDataHandler : ICommandHandler
p.Get<string>("1")
}, "msg", room.Id);
room.Send(packet, client);
return Task.CompletedTask;
}
}
// Game Complete
[ExtensionCommandHandler("gs.GC")]
class GauntletGameCompleteHandler : ICommandHandler
class GauntletGameCompleteHandler : CommandHandler
{
public void Handle(Client client, NetworkObject receivedObject) // {"a":13,"c":1,"p":{"c":"gs.GC","p":{"0":"1550","1":"84","en":"GauntletGameExtension"},"r":4}}
public override Task Handle(Client client, NetworkObject receivedObject) // {"a":13,"c":1,"p":{"c":"gs.GC","p":{"0":"1550","1":"84","en":"GauntletGameExtension"},"r":4}}
{
GauntletRoom room = (client.Room as GauntletRoom)!;
NetworkObject p = receivedObject.Get<NetworkObject>("p");
room.ProcessResult(client, p.Get<string>("0"), p.Get<string>("1"));
return Task.CompletedTask;
}
}

View File

@ -5,9 +5,10 @@ using sodoffmmo.Data;
namespace sodoffmmo.CommandHandlers;
[CommandHandler(7)]
class GenericMessageHandler : ICommandHandler {
public void Handle(Client client, NetworkObject receivedObject) {
class GenericMessageHandler : CommandHandler {
public override Task Handle(Client client, NetworkObject receivedObject) {
NetworkPacket packet = NetworkObject.WrapObject(0, 7, receivedObject).Serialize();
client.Room.Send(packet);
return Task.CompletedTask;
}
}

View File

@ -7,14 +7,14 @@ using System;
namespace sodoffmmo.CommandHandlers;
[CommandHandler(0)]
class HandshakeHandler : ICommandHandler
class HandshakeHandler : CommandHandler
{
public void Handle(Client client, NetworkObject receivedObject)
public override Task Handle(Client client, NetworkObject receivedObject)
{
string? token = receivedObject.Get<string>("rt");
if (token != null) {
client.Send(NetworkObject.WrapObject(0, 1006, new NetworkObject()).Serialize());
return;
return Task.CompletedTask;
}
NetworkObject obj = new();
@ -24,6 +24,7 @@ class HandshakeHandler : ICommandHandler
obj.Add("ms", 1000000);
client.Send(NetworkObject.WrapObject(0, 0, obj).Serialize());
return Task.CompletedTask;
}
private string RandomString(int length) {

View File

@ -5,13 +5,14 @@ using sodoffmmo.Data;
namespace sodoffmmo.CommandHandlers;
[ExtensionCommandHandler("JO")]
class JoinPrivateRoomHandler : ICommandHandler
class JoinPrivateRoomHandler : CommandHandler
{
public void Handle(Client client, NetworkObject receivedObject)
public override Task Handle(Client client, NetworkObject receivedObject)
{
var p = receivedObject.Get<NetworkObject>("p");
string roomName = p.Get<string>("rn") + "_" + p.Get<string>("0");
Room room = Room.GetOrAdd(roomName, autoRemove: true);
client.SetRoom(room);
return Task.CompletedTask;
}
}

View File

@ -5,12 +5,13 @@ using sodoffmmo.Data;
namespace sodoffmmo.CommandHandlers;
[ExtensionCommandHandler("JA")]
class JoinRoomHandler : ICommandHandler
class JoinRoomHandler : CommandHandler
{
public void Handle(Client client, NetworkObject receivedObject)
public override Task Handle(Client client, NetworkObject receivedObject)
{
string roomName = receivedObject.Get<NetworkObject>("p").Get<string>("rn");
Room room = Room.GetOrAdd(roomName);
client.SetRoom(room);
return Task.CompletedTask;
}
}

View File

@ -6,9 +6,9 @@ using sodoffmmo.Management;
namespace sodoffmmo.CommandHandlers;
[CommandHandler(1)]
class LoginHandler : ICommandHandler
class LoginHandler : CommandHandler
{
public void Handle(Client client, NetworkObject receivedObject)
public override Task Handle(Client client, NetworkObject receivedObject)
{
client.PlayerData.UNToken = receivedObject.Get<string>("un");
if (!ValidToken(client)) {
@ -16,7 +16,7 @@ class LoginHandler : ICommandHandler
obj.Add("dr", (byte)1);
client.Send(NetworkObject.WrapObject(0, 1005, obj).Serialize());
client.ScheduleDisconnect();
return;
return Task.CompletedTask;
}
NetworkArray rl = new();
@ -68,6 +68,7 @@ class LoginHandler : ICommandHandler
content.Add("pi", (short)1);
client.Send(NetworkObject.WrapObject(0, 1, content).Serialize());
return Task.CompletedTask;
}
private bool ValidToken(Client client) {

View File

@ -5,8 +5,13 @@ using sodoffmmo.Data;
namespace sodoffmmo.CommandHandlers;
[ExtensionCommandHandler("PNG")]
class PingHandler : ICommandHandler {
public void Handle(Client client, NetworkObject receivedObject) {
class PingHandler : CommandHandler {
public bool RunInBackground { get; } = true;
public override async Task Handle(Client client, NetworkObject receivedObject) {
if (Configuration.ServerConfiguration.PingDelay > 0) {
await Task.Delay(Configuration.ServerConfiguration.PingDelay);
}
NetworkObject cmd = new();
NetworkObject obj = new();
obj.Add("arr", new string[] { "PNG", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString() });

View File

@ -5,10 +5,10 @@ using sodoffmmo.Data;
namespace sodoffmmo.CommandHandlers;
[ExtensionCommandHandler("PM")]
class RacingPMHandler : ICommandHandler
class RacingPMHandler : CommandHandler
{
// rec: {"a":13,"c":1,"p":{"c":"PM","p":{"M":"DT:c4647597-a72a-4f34-973c-5a10218d9a64:1000","en":"we"},"r":-1}}
public void Handle(Client client, NetworkObject receivedObject) {
public override Task Handle(Client client, NetworkObject receivedObject) {
// send: {"a":13,"c":1,"p":{"c":"PM","p":{"arr":[{"M":["DT:f05fc387-7358-4bff-be04-7c316f0a8de8:1000"],"MID":3529441}]}}}
NetworkObject cmd = new();
NetworkObject p = new();
@ -25,5 +25,6 @@ class RacingPMHandler : ICommandHandler
NetworkPacket packet = NetworkObject.WrapObject(1, 13, cmd).Serialize();
client.Room.Send(packet);
return Task.CompletedTask;
}
}

View File

@ -8,9 +8,9 @@ namespace sodoffmmo.CommandHandlers;
// Set Player Ready
[ExtensionCommandHandler("dr.PR")]
class RacingPlayerReadyHandler : ICommandHandler
class RacingPlayerReadyHandler : CommandHandler
{
public void Handle(Client client, NetworkObject receivedObject) { // {"a":13,"c":1,"p":{"c":"dr.PR","p":{"IMR":"True","en":""},"r":-1}}
public override Task Handle(Client client, NetworkObject receivedObject) { // {"a":13,"c":1,"p":{"c":"dr.PR","p":{"IMR":"True","en":""},"r":-1}}
NetworkObject p = receivedObject.Get<NetworkObject>("p");
RacingPlayerState ready = p.Get<string>("IMR") == "True" ? RacingPlayerState.Ready : RacingPlayerState.NotReady;
@ -26,33 +26,37 @@ class RacingPlayerReadyHandler : ICommandHandler
RacingLobby.Lobby.SetPlayerState(client, ready);
Console.WriteLine($"IMR: {client.ClientID} {ready}");
}
return Task.CompletedTask;
}
}
// Player Status Request
[ExtensionCommandHandler("dr.PS")]
class RacingPlayerStatusHandler : ICommandHandler
class RacingPlayerStatusHandler : CommandHandler
{
public void Handle(Client client, NetworkObject receivedObject) {
public override Task Handle(Client client, NetworkObject receivedObject) {
client.Send(RacingLobby.Lobby.GetPS());
return Task.CompletedTask;
}
}
// User Ready ACK
[ExtensionCommandHandler("dr.UACK")]
class RacingUACKHandler : ICommandHandler
class RacingUACKHandler : CommandHandler
{
public void Handle(Client client, NetworkObject receivedObject) {
public override Task Handle(Client client, NetworkObject receivedObject) {
RacingRoom room = (client.Room as RacingRoom)!;
room.SetPlayerState(client, RacingPlayerState.RaceReady1);
return Task.CompletedTask;
}
}
// All Ready ACK
[ExtensionCommandHandler("dr.ARACK")]
class RacingARACKHandler : ICommandHandler
class RacingARACKHandler : CommandHandler
{
public void Handle(Client client, NetworkObject receivedObject) {
public override Task Handle(Client client, NetworkObject receivedObject) {
RacingRoom room = (client.Room as RacingRoom)!;
room.SetPlayerState(client, RacingPlayerState.RaceReady2);
@ -61,17 +65,19 @@ class RacingARACKHandler : ICommandHandler
room.Send(packet);
Console.WriteLine($"STA");
}
return Task.CompletedTask;
}
}
[ExtensionCommandHandler("dr.AR")]
class RacingARHandler : ICommandHandler
class RacingARHandler : CommandHandler
{
public void Handle(Client client, NetworkObject receivedObject) { // {"a":13,"c":1,"p":{"c":"dr.AR","p":{"CT":"112.1268","FD":"3008.283","LC":"3","UN":"scourgexxwulf","en":""},"r":412467}}
public override Task Handle(Client client, NetworkObject receivedObject) { // {"a":13,"c":1,"p":{"c":"dr.AR","p":{"CT":"112.1268","FD":"3008.283","LC":"3","UN":"scourgexxwulf","en":""},"r":412467}}
RacingRoom room = (client.Room as RacingRoom)!;
NetworkObject p = receivedObject.Get<NetworkObject>("p");
room.SetResults(client, p.Get<string>("UN"), p.Get<string>("CT"), p.Get<string>("LC"));
room.SendResults();
return Task.CompletedTask;
}
}

View File

@ -5,20 +5,22 @@ using sodoffmmo.Data;
namespace sodoffmmo.CommandHandlers;
[ExtensionCommandHandler("SPV")]
class SetPositionVariablesHandler : ICommandHandler {
class SetPositionVariablesHandler : CommandHandler {
Client client;
NetworkObject spvData;
public void Handle(Client client, NetworkObject receivedObject) {
public override Task Handle(Client client, NetworkObject receivedObject) {
if (client.Room == null) {
Console.WriteLine($"SPV Missing Room IID: {client.ClientID}");
client.Send(NetworkObject.WrapObject(0, 1006, new NetworkObject()).Serialize());
client.ScheduleDisconnect();
return;
return Task.CompletedTask;
}
this.client = client;
spvData = receivedObject;
UpdatePositionVariables();
SendSPVCommand();
return Task.CompletedTask;
}
private void UpdatePositionVariables() {

View File

@ -6,16 +6,16 @@ using System.Globalization;
namespace sodoffmmo.CommandHandlers;
[ExtensionCommandHandler("SUV")]
class SetUserVariablesHandler : ICommandHandler {
class SetUserVariablesHandler : CommandHandler {
NetworkObject suvData;
Client client;
string? uid;
public void Handle(Client client, NetworkObject receivedObject) {
public override Task Handle(Client client, NetworkObject receivedObject) {
if (client.Room == null) {
Console.WriteLine($"SUV Missing Room IID: {client.ClientID}");
client.Send(NetworkObject.WrapObject(0, 1006, new NetworkObject()).Serialize());
client.ScheduleDisconnect();
return;
return Task.CompletedTask;
}
this.client = client;
suvData = receivedObject.Get<NetworkObject>("p");
@ -27,6 +27,7 @@ class SetUserVariablesHandler : ICommandHandler {
else
UpdateVars();
return Task.CompletedTask;
}
private void ProcessPlayerData() {

View File

@ -6,20 +6,21 @@ using sodoffmmo.Data;
namespace sodoffmmo.CommandHandlers;
[ExtensionCommandHandler("wex.WES")] // event status request
class WorldEventStatusHandler : ICommandHandler {
public void Handle(Client client, NetworkObject receivedObject) {
class WorldEventStatusHandler : CommandHandler {
public override Task Handle(Client client, NetworkObject receivedObject) {
client.Send(Utils.ArrNetworkPacket( new string[] {
"WESR",
"WE_ScoutAttack|" + WorldEvent.Get().EventInfo(),
"EvEnd|" + WorldEvent.Get().GetLastResults()
}));
return Task.CompletedTask;
}
}
[ExtensionCommandHandler("wex.OV")]
class WorldEventHealthHandler : ICommandHandler {
class WorldEventHealthHandler : CommandHandler {
// rec: {"a":13,"c":1,"p":{"c":"wex.OV","p":{"en":"","event":"ScoutAttack","eventUID":"ZydLUmCC","oh":"0.003444444","uid":"ZydLUmCC1"},"r":-1}}
public void Handle(Client client, NetworkObject receivedObject) {
public override Task Handle(Client client, NetworkObject receivedObject) {
// NOTE: this should be process on event in any state - we use it to make event active
NetworkObject p = receivedObject.Get<NetworkObject>("p");
float healthUpdateVal = float.Parse(
@ -39,15 +40,16 @@ class WorldEventHealthHandler : ICommandHandler {
);
WorldEvent.Get().GetRoom().Send(packet);
}
return Task.CompletedTask;
}
}
[ExtensionCommandHandler("wex.OVF")] // flare info from ship AI -> resend as WEF_
class WorldEventFlareHandler : ICommandHandler {
class WorldEventFlareHandler : CommandHandler {
// rec: {"a":13,"c":1,"p":{"c":"wex.OVF","p":{"en":"","fuid":"WpnpDyJ51,14,0","oh":"0","ts":"6/29/2023 3:03:18 AM"},"r":-1}}
public void Handle(Client client, NetworkObject receivedObject) {
public override Task Handle(Client client, NetworkObject receivedObject) {
if (!WorldEvent.Get().IsActive())
return;
return Task.CompletedTask;
NetworkObject p = receivedObject.Get<NetworkObject>("p");
@ -58,15 +60,17 @@ class WorldEventFlareHandler : ICommandHandler {
WorldEvent.Get().GetRoom().Id
);
WorldEvent.Get().GetRoom().Send(packet);
return Task.CompletedTask;
}
}
[ExtensionCommandHandler("wex.ST")] // missile info from ship AI -> resend as WA
class WorldEventMissileHandler : ICommandHandler {
class WorldEventMissileHandler : CommandHandler {
// rec: {"a":13,"c":1,"p":{"c":"wex.ST","p":{"en":"","objID":"-4X_gWAo1","tID":"f5b6254a-df78-4e24-aa9d-7e14539fb858","uID":"1f8eeb6b-753f-4e7f-af13-42cdd69d14e7","wID":"5"},"r":-1}}
public void Handle(Client client, NetworkObject receivedObject) {
public override Task Handle(Client client, NetworkObject receivedObject) {
if (!WorldEvent.Get().IsActive())
return;
return Task.CompletedTask;
NetworkObject p = receivedObject.Get<NetworkObject>("p");
@ -79,45 +83,52 @@ class WorldEventMissileHandler : ICommandHandler {
p.Get<string>("objID")
});
WorldEvent.Get().GetRoom().Send(packet);
return Task.CompletedTask;
}
}
[ExtensionCommandHandler("wex.PS")]
class WorldEventScoreHandler : ICommandHandler {
class WorldEventScoreHandler : CommandHandler {
// rec: {"a":13,"c":1,"p":{"c":"wex.PS","p":{"ScoreData":"Datashyo/10","en":"","id":"ScoutAttack"},"r":-1}}
public void Handle(Client client, NetworkObject receivedObject) {
public override Task Handle(Client client, NetworkObject receivedObject) {
if (!WorldEvent.Get().IsActive())
return;
return Task.CompletedTask;
string scoreData = receivedObject.Get<NetworkObject>("p").Get<string>("ScoreData");
string[] keyValPair = scoreData.Split('/');
WorldEvent.Get().UpdateScore(keyValPair[0], keyValPair[1]);
return Task.CompletedTask;
}
}
[ExtensionCommandHandler("wex.AIACK")] // AI ack
class WorldEventAIACKHandler : ICommandHandler {
class WorldEventAIACKHandler : CommandHandler {
// rec: {"a":13,"c":1,"p":{"c":"wex.AIACK","p":{"en":"","id":"f322dd98-e9fb-4b2d-a5e0-1c98680517b5","uid":"SoDOff1"},"r":-1}}
public void Handle(Client client, NetworkObject receivedObject) {
public override Task Handle(Client client, NetworkObject receivedObject) {
WorldEvent.Get().UpdateAI(client);
return Task.CompletedTask;
}
}
[ExtensionCommandHandler("wex.AIP")] // AI ping
class WorldEventAIPingHandler : ICommandHandler {
class WorldEventAIPingHandler : CommandHandler {
// rec: {"a":13,"c":1,"p":{"c":"wex.AIP","p":{"en":""},"r":-1}}
public void Handle(Client client, NetworkObject receivedObject) {
public override Task Handle(Client client, NetworkObject receivedObject) {
WorldEvent.Get().UpdateAI(client);
return Task.CompletedTask;
}
}
[ExtensionCommandHandler("wex.ETS")] // time span
class WorldEventTimeSpanHandler : ICommandHandler {
class WorldEventTimeSpanHandler : CommandHandler {
// rec: {"a":13,"c":1,"p":{"c":"wex.ETS","p":{"en":"","timeSpan":"300"},"r":-1}}
public void Handle(Client client, NetworkObject receivedObject) {
public override Task Handle(Client client, NetworkObject receivedObject) {
float timeSpan = float.Parse(
receivedObject.Get<NetworkObject>("p").Get<string>("timeSpan"),
System.Globalization.CultureInfo.InvariantCulture
);
WorldEvent.Get().SetTimeSpan(client, timeSpan);
return Task.CompletedTask;
}
}

View File

@ -0,0 +1,8 @@
using sodoffmmo.Data;
namespace sodoffmmo.Core;
public abstract class CommandHandler {
public bool RunInBackground { get; }
public abstract Task Handle(Client client, NetworkObject receivedObject);
}

View File

@ -34,6 +34,7 @@ internal sealed class ServerConfiguration {
public int RacingMaxPlayers { get; set; } = 6;
public int RacingMinPlayers { get; set; } = 2;
public int RacingMainLobbyTimer { get; set; } = 15;
public int PingDelay { get; set; } = 17;
public bool EnableChat { get; set; } = true;
public bool AllowChaos { get; set; } = false;
public bool Authentication { get; set; } = false;

View File

@ -1,6 +0,0 @@
using sodoffmmo.Data;
namespace sodoffmmo.Core;
public interface ICommandHandler {
public void Handle(Client client, NetworkObject receivedObject);
}

View File

@ -12,22 +12,22 @@ class ModuleManager {
RegisterExtensionHandlers();
}
public ICommandHandler GetCommandHandler(int id) {
public CommandHandler GetCommandHandler(int id) {
if (handlers.TryGetValue(id, out Type? handler))
return (ICommandHandler)Activator.CreateInstance(handler)!;
return (CommandHandler)Activator.CreateInstance(handler)!;
throw new Exception($"Command handler with ID {id} not found!");
}
public ICommandHandler GetCommandHandler(string name) {
public CommandHandler GetCommandHandler(string name) {
if (extHandlers.TryGetValue(name, out Type? handler))
return (ICommandHandler)Activator.CreateInstance(handler)!;
return (CommandHandler)Activator.CreateInstance(handler)!;
throw new Exception($"Command handler with name \"{name}\" not found!");
}
private void RegisterHandlers() {
handlers.Clear();
var handlerTypes = Assembly.GetExecutingAssembly().GetTypes()
.Where(type => typeof(ICommandHandler).IsAssignableFrom(type))
.Where(type => typeof(CommandHandler).IsAssignableFrom(type))
.Where(type => type.GetCustomAttribute<CommandHandlerAttribute>() != null);
foreach (var handlerType in handlerTypes) {
@ -39,7 +39,7 @@ class ModuleManager {
private void RegisterExtensionHandlers() {
extHandlers.Clear();
var extHandlerTypes = Assembly.GetExecutingAssembly().GetTypes()
.Where(type => typeof(ICommandHandler).IsAssignableFrom(type))
.Where(type => typeof(CommandHandler).IsAssignableFrom(type))
.Where(type => type.GetCustomAttribute<ExtensionCommandHandlerAttribute>() != null);
foreach (var extHandlerType in extHandlerTypes) {

View File

@ -49,7 +49,7 @@ public class Server {
while (client.TryGetNextPacket(out NetworkPacket packet))
networkObjects.Add(packet.GetObject());
HandleObjects(networkObjects, client);
await HandleObjects(networkObjects, client);
}
} finally {
try {
@ -60,18 +60,20 @@ public class Server {
}
}
private void HandleObjects(List<NetworkObject> networkObjects, Client client) {
private async Task HandleObjects(List<NetworkObject> networkObjects, Client client) {
foreach (var obj in networkObjects) {
try {
short commandId = obj.Get<short>("a");
ICommandHandler handler;
CommandHandler handler;
if (commandId != 13) {
if (commandId == 0 || commandId == 1)
Console.WriteLine($"System command: {commandId} IID: {client.ClientID}");
handler = moduleManager.GetCommandHandler(commandId);
} else
handler = moduleManager.GetCommandHandler(obj.Get<NetworkObject>("p").Get<string>("c"));
handler.Handle(client, obj.Get<NetworkObject>("p"));
Task task = handler.Handle(client, obj.Get<NetworkObject>("p"));
if (!handler.RunInBackground)
await task;
} catch (Exception ex) {
Console.WriteLine($"Exception IID: {client.ClientID} - {ex}");
}

View File

@ -6,6 +6,9 @@
"// Port": "Listening port number for the MMO server",
"Port": 9933,
"// PingDelay": "delay (in milliseconds) for PNG response",
"PingDelay": 17,
"// EnableChat": "When true, in-game chat will be enabled",
"EnableChat": true,