fix issues with game interface reconnecting after rcon connection lost
This commit is contained in:
parent
527ffbaced
commit
7526f86dab
@ -42,6 +42,7 @@ namespace IW4MAdmin.Application.Misc
|
|||||||
private Engine _scriptEngine;
|
private Engine _scriptEngine;
|
||||||
private readonly string _fileName;
|
private readonly string _fileName;
|
||||||
private readonly SemaphoreSlim _onProcessing = new(1, 1);
|
private readonly SemaphoreSlim _onProcessing = new(1, 1);
|
||||||
|
private readonly SemaphoreSlim _onDvarActionComplete = new(1, 1);
|
||||||
private bool _successfullyLoaded;
|
private bool _successfullyLoaded;
|
||||||
private readonly List<string> _registeredCommandNames;
|
private readonly List<string> _registeredCommandNames;
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
@ -458,18 +459,16 @@ namespace IW4MAdmin.Application.Misc
|
|||||||
|
|
||||||
private void BeginGetDvar(Server server, string dvarName, Delegate onCompleted)
|
private void BeginGetDvar(Server server, string dvarName, Delegate onCompleted)
|
||||||
{
|
{
|
||||||
var tokenSource = new CancellationTokenSource();
|
void OnComplete(IAsyncResult result)
|
||||||
tokenSource.CancelAfter(TimeSpan.FromSeconds(15));
|
|
||||||
|
|
||||||
server.BeginGetDvar(dvarName, result =>
|
|
||||||
{
|
{
|
||||||
var shouldRelease = false;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_onProcessing.Wait(tokenSource.Token);
|
|
||||||
shouldRelease = true;
|
|
||||||
var (success, value) = (ValueTuple<bool, string>)result.AsyncState;
|
var (success, value) = (ValueTuple<bool, string>)result.AsyncState;
|
||||||
|
|
||||||
|
_logger.LogDebug("Waiting for onDvarActionComplete -> get");
|
||||||
|
_onDvarActionComplete.Wait();
|
||||||
|
_logger.LogDebug("Completed wait for onDvarActionComplete -> get");
|
||||||
|
|
||||||
onCompleted.DynamicInvoke(JsValue.Undefined,
|
onCompleted.DynamicInvoke(JsValue.Undefined,
|
||||||
new[]
|
new[]
|
||||||
{
|
{
|
||||||
@ -479,9 +478,43 @@ namespace IW4MAdmin.Application.Misc
|
|||||||
JsValue.FromObject(_scriptEngine, success)
|
JsValue.FromObject(_scriptEngine, success)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
catch (JavaScriptException ex)
|
||||||
|
{
|
||||||
|
using (LogContext.PushProperty("Server", server.ToString()))
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Could complete BeginGetDvar for {Filename} {@Location}",
|
||||||
|
Path.GetFileName(_fileName), ex.Location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Could not complete {BeginGetDvar} for {Class}", nameof(BeginGetDvar), Name);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (_onDvarActionComplete.CurrentCount == 0)
|
||||||
|
{
|
||||||
|
_onDvarActionComplete.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var tokenSource = new CancellationTokenSource();
|
||||||
|
tokenSource.CancelAfter(TimeSpan.FromSeconds(15));
|
||||||
|
|
||||||
|
server.BeginGetDvar(dvarName, result =>
|
||||||
|
{
|
||||||
|
var shouldRelease = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_onProcessing.Wait(tokenSource.Token);
|
||||||
|
shouldRelease = true;
|
||||||
|
}
|
||||||
|
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
OnComplete(result);
|
||||||
|
|
||||||
if (_onProcessing.CurrentCount == 0 && shouldRelease)
|
if (_onProcessing.CurrentCount == 0 && shouldRelease)
|
||||||
{
|
{
|
||||||
_onProcessing.Release();
|
_onProcessing.Release();
|
||||||
@ -495,15 +528,15 @@ namespace IW4MAdmin.Application.Misc
|
|||||||
var tokenSource = new CancellationTokenSource();
|
var tokenSource = new CancellationTokenSource();
|
||||||
tokenSource.CancelAfter(TimeSpan.FromSeconds(15));
|
tokenSource.CancelAfter(TimeSpan.FromSeconds(15));
|
||||||
|
|
||||||
server.BeginSetDvar(dvarName, dvarValue, result =>
|
void OnComplete(IAsyncResult result)
|
||||||
{
|
{
|
||||||
var shouldRelease = false;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_onProcessing.Wait(tokenSource.Token);
|
|
||||||
shouldRelease = true;
|
|
||||||
var success = (bool)result.AsyncState;
|
var success = (bool)result.AsyncState;
|
||||||
|
|
||||||
|
_logger.LogDebug("Waiting for onDvarActionComplete -> set");
|
||||||
|
_onDvarActionComplete.Wait();
|
||||||
|
_logger.LogDebug("Completed wait for onDvarActionComplete -> set");
|
||||||
onCompleted.DynamicInvoke(JsValue.Undefined,
|
onCompleted.DynamicInvoke(JsValue.Undefined,
|
||||||
new[]
|
new[]
|
||||||
{
|
{
|
||||||
@ -513,8 +546,38 @@ namespace IW4MAdmin.Application.Misc
|
|||||||
JsValue.FromObject(_scriptEngine, success)
|
JsValue.FromObject(_scriptEngine, success)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
catch (JavaScriptException ex)
|
||||||
|
{
|
||||||
|
using (LogContext.PushProperty("Server", server.ToString()))
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Could complete BeginSetDvar for {Filename} {@Location}",
|
||||||
|
Path.GetFileName(_fileName), ex.Location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Could not complete {BeginSetDvar} for {Class}", nameof(BeginSetDvar), Name);
|
||||||
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
if (_onDvarActionComplete.CurrentCount == 0)
|
||||||
|
{
|
||||||
|
_onDvarActionComplete.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
server.BeginSetDvar(dvarName, dvarValue, result =>
|
||||||
|
{
|
||||||
|
var shouldRelease = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_onProcessing.Wait(tokenSource.Token);
|
||||||
|
shouldRelease = true;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
OnComplete(result);
|
||||||
if (_onProcessing.CurrentCount == 0 && shouldRelease)
|
if (_onProcessing.CurrentCount == 0 && shouldRelease)
|
||||||
{
|
{
|
||||||
_onProcessing.Release();
|
_onProcessing.Release();
|
||||||
|
@ -111,7 +111,7 @@ public class ScriptPluginTimerHelper : IScriptPluginTimerHelper
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
_logger.LogDebug("-Releasing OnTick for timer");
|
||||||
_onDependentAction?.Release(1);
|
_onDependentAction?.Release(1);
|
||||||
}
|
}
|
||||||
private void OnTick()
|
private void OnTick()
|
||||||
@ -128,7 +128,8 @@ public class ScriptPluginTimerHelper : IScriptPluginTimerHelper
|
|||||||
_onRunningTick.Reset();
|
_onRunningTick.Reset();
|
||||||
|
|
||||||
// the js engine is not thread safe so we need to ensure we're not executing OnTick and OnEventAsync simultaneously
|
// the js engine is not thread safe so we need to ensure we're not executing OnTick and OnEventAsync simultaneously
|
||||||
_onDependentAction?.WaitAsync().Wait();
|
_onDependentAction?.Wait();
|
||||||
|
_logger.LogDebug("+Running OnTick for timer");
|
||||||
var start = DateTime.Now;
|
var start = DateTime.Now;
|
||||||
_jsAction.DynamicInvoke(JsValue.Undefined, new[] { JsValue.Undefined });
|
_jsAction.DynamicInvoke(JsValue.Undefined, new[] { JsValue.Undefined });
|
||||||
_logger.LogDebug("OnTick took {Time}ms", (DateTime.Now - start).TotalMilliseconds);
|
_logger.LogDebug("OnTick took {Time}ms", (DateTime.Now - start).TotalMilliseconds);
|
||||||
|
@ -147,7 +147,7 @@ namespace IW4MAdmin.Application.RConParsers
|
|||||||
{
|
{
|
||||||
GetDvarAsync<string>(connection, dvarName, token: token).ContinueWith(action =>
|
GetDvarAsync<string>(connection, dvarName, token: token).ContinueWith(action =>
|
||||||
{
|
{
|
||||||
if (action.Exception is null)
|
if (action.Exception is null && !action.IsCanceled)
|
||||||
{
|
{
|
||||||
callback?.Invoke(new AsyncResult
|
callback?.Invoke(new AsyncResult
|
||||||
{
|
{
|
||||||
@ -164,7 +164,7 @@ namespace IW4MAdmin.Application.RConParsers
|
|||||||
AsyncState = (false, (string)null)
|
AsyncState = (false, (string)null)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, token);
|
}, CancellationToken.None);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<IStatusResponse> GetStatusAsync(IRConConnection connection, CancellationToken token = default)
|
public virtual async Task<IStatusResponse> GetStatusAsync(IRConConnection connection, CancellationToken token = default)
|
||||||
@ -227,7 +227,7 @@ namespace IW4MAdmin.Application.RConParsers
|
|||||||
{
|
{
|
||||||
SetDvarAsync(connection, dvarName, dvarValue, token).ContinueWith(action =>
|
SetDvarAsync(connection, dvarName, dvarValue, token).ContinueWith(action =>
|
||||||
{
|
{
|
||||||
if (action.Exception is null)
|
if (action.Exception is null && !action.IsCanceled)
|
||||||
{
|
{
|
||||||
callback?.Invoke(new AsyncResult
|
callback?.Invoke(new AsyncResult
|
||||||
{
|
{
|
||||||
@ -244,7 +244,7 @@ namespace IW4MAdmin.Application.RConParsers
|
|||||||
AsyncState = false
|
AsyncState = false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, token);
|
}, CancellationToken.None);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<EFClient> ClientsFromStatus(string[] Status)
|
private List<EFClient> ClientsFromStatus(string[] Status)
|
||||||
|
Loading…
Reference in New Issue
Block a user