game interface improvements

This commit is contained in:
RaidMax 2022-02-13 21:38:40 -06:00
parent f4b892d8f4
commit 037fac5786
5 changed files with 91 additions and 40 deletions

View File

@ -236,7 +236,7 @@ namespace IW4MAdmin
private async Task CreatePluginTask(IPlugin plugin, GameEvent gameEvent) private async Task CreatePluginTask(IPlugin plugin, GameEvent gameEvent)
{ {
// we don't want to run the events on parser plugins // we don't want to run the events on parser plugins
if (plugin is ScriptPlugin scriptPlugin && scriptPlugin.IsParser) if (plugin is ScriptPlugin { IsParser: true })
{ {
return; return;
} }
@ -248,6 +248,11 @@ namespace IW4MAdmin
{ {
await plugin.OnEventAsync(gameEvent, this).WithWaitCancellation(tokenSource.Token); await plugin.OnEventAsync(gameEvent, this).WithWaitCancellation(tokenSource.Token);
} }
catch (OperationCanceledException)
{
ServerLogger.LogWarning("Timed out executing event {EventType} for {Plugin}", gameEvent.Type,
plugin.Name);
}
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(loc["SERVER_PLUGIN_ERROR"].FormatExt(plugin.Name, ex.GetType().Name)); Console.WriteLine(loc["SERVER_PLUGIN_ERROR"].FormatExt(plugin.Name, ex.GetType().Name));

View File

@ -223,47 +223,49 @@ namespace IW4MAdmin.Application.Misc
public async Task OnEventAsync(GameEvent gameEvent, Server server) public async Task OnEventAsync(GameEvent gameEvent, Server server)
{ {
if (_successfullyLoaded) if (!_successfullyLoaded)
{ {
try return;
{ }
await _onProcessing.WaitAsync();
_scriptEngine.SetValue("_gameEvent", gameEvent);
_scriptEngine.SetValue("_server", server);
_scriptEngine.SetValue("_IW4MAdminClient", Utilities.IW4MAdminClient(server));
_scriptEngine.Evaluate("plugin.onEventAsync(_gameEvent, _server)");
}
catch (JavaScriptException ex)
{
using (LogContext.PushProperty("Server", server.ToString()))
{
_logger.LogError(ex,
"Encountered JavaScript runtime error while executing {MethodName} for script plugin {Plugin} with event type {EventType} {@LocationInfo}",
nameof(OnEventAsync), Path.GetFileName(_fileName), gameEvent.Type, ex.Location);
}
throw new PluginException("An error occured while executing action for script plugin"); try
{
await _onProcessing.WaitAsync();
_scriptEngine.SetValue("_gameEvent", gameEvent);
_scriptEngine.SetValue("_server", server);
_scriptEngine.SetValue("_IW4MAdminClient", Utilities.IW4MAdminClient(server));
_scriptEngine.Evaluate("plugin.onEventAsync(_gameEvent, _server)");
}
catch (JavaScriptException ex)
{
using (LogContext.PushProperty("Server", server.ToString()))
{
_logger.LogError(ex,
"Encountered JavaScript runtime error while executing {MethodName} for script plugin {Plugin} with event type {EventType} {@LocationInfo}",
nameof(OnEventAsync), Path.GetFileName(_fileName), gameEvent.Type, ex.Location);
} }
catch (Exception ex) throw new PluginException("An error occured while executing action for script plugin");
{ }
using (LogContext.PushProperty("Server", server.ToString()))
{
_logger.LogError(ex,
"Encountered error while running {MethodName} for script plugin {Plugin} with event type {EventType}",
nameof(OnEventAsync), _fileName, gameEvent.Type);
}
throw new PluginException("An error occured while executing action for script plugin"); catch (Exception ex)
{
using (LogContext.PushProperty("Server", server.ToString()))
{
_logger.LogError(ex,
"Encountered error while running {MethodName} for script plugin {Plugin} with event type {EventType}",
nameof(OnEventAsync), _fileName, gameEvent.Type);
} }
finally throw new PluginException("An error occured while executing action for script plugin");
}
finally
{
if (_onProcessing.CurrentCount == 0)
{ {
if (_onProcessing.CurrentCount == 0) _onProcessing.Release(1);
{
_onProcessing.Release(1);
}
} }
} }
} }

View File

@ -37,7 +37,7 @@ let plugin = {
break; break;
case 'preconnect': case 'preconnect':
// when the plugin is reloaded after the servers are started // when the plugin is reloaded after the servers are started
if (servers[server.EndPoint] == null) { if (servers[server.EndPoint] === undefined || servers[server.EndPoint] == null) {
const enabled = initialize(server); const enabled = initialize(server);
if (!enabled) { if (!enabled) {
@ -222,7 +222,7 @@ const sendEvent = (server, responseExpected, event, subtype, client, data) => {
let pendingCheckCount = 0; let pendingCheckCount = 0;
const start = new Date(); const start = new Date();
while (pendingOut && pendingCheckCount <= 30) { while (pendingOut && pendingCheckCount <= 10) {
try { try {
const out = server.GetServerDvar(outDvar); const out = server.GetServerDvar(outDvar);
pendingOut = !(out == null || out === '' || out === 'null'); pendingOut = !(out == null || out === '' || out === 'null');

View File

@ -390,17 +390,48 @@ namespace SharedLibraryCore
public string[] ExecuteServerCommand(string command) public string[] ExecuteServerCommand(string command)
{ {
return this.ExecuteCommandAsync(command).GetAwaiter().GetResult(); var tokenSource = new CancellationTokenSource();
tokenSource.CancelAfter(TimeSpan.FromMilliseconds(400));
try
{
return this.ExecuteCommandAsync(command).WithWaitCancellation(tokenSource.Token).GetAwaiter().GetResult();
}
catch
{
return null;
}
} }
public string GetServerDvar(string dvarName) public string GetServerDvar(string dvarName)
{ {
return this.GetDvarAsync<string>(dvarName).GetAwaiter().GetResult()?.Value; var tokenSource = new CancellationTokenSource();
tokenSource.CancelAfter(TimeSpan.FromSeconds(400));
try
{
return this.GetDvarAsync<string>(dvarName).WithWaitCancellation(tokenSource.Token).GetAwaiter()
.GetResult()?.Value;
}
catch
{
return null;
}
} }
public void SetServerDvar(string dvarName, string dvarValue) public bool SetServerDvar(string dvarName, string dvarValue)
{ {
this.SetDvarAsync(dvarName, dvarValue).GetAwaiter().GetResult(); var tokenSource = new CancellationTokenSource();
tokenSource.CancelAfter(TimeSpan.FromSeconds(400));
try
{
this.SetDvarAsync(dvarName, dvarValue).WithWaitCancellation(tokenSource.Token).GetAwaiter().GetResult();
return true;
}
catch
{
return false;
}
} }
public EFClient GetClientByNumber(int clientNumber) => public EFClient GetClientByNumber(int clientNumber) =>

View File

@ -956,6 +956,19 @@ namespace SharedLibraryCore
} }
} }
public static async Task<T> WithWaitCancellation<T>(this Task<T> task,
CancellationToken cancellationToken)
{
var completedTask = await Task.WhenAny(task, Task.Delay(Timeout.Infinite, cancellationToken));
if (completedTask == task)
{
return await task;
}
cancellationToken.ThrowIfCancellationRequested();
throw new InvalidOperationException("Infinite delay task completed.");
}
public static async Task<T> WithTimeout<T>(this Task<T> task, TimeSpan timeout) public static async Task<T> WithTimeout<T>(this Task<T> task, TimeSpan timeout)
{ {
await Task.WhenAny(task, Task.Delay(timeout)); await Task.WhenAny(task, Task.Delay(timeout));