few more small fixes
complete join button on webfront update for 2.2.6.0
This commit is contained in:
parent
dd82a5e3fa
commit
9d9be7f8af
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using RestEase;
|
||||
using SharedLibraryCore;
|
||||
@ -11,6 +12,7 @@ namespace IW4MAdmin.Application.API.Master
|
||||
public class HeartbeatState
|
||||
{
|
||||
public bool Connected { get; set; }
|
||||
public CancellationToken Token { get; set; }
|
||||
}
|
||||
|
||||
public class Heartbeat
|
||||
|
@ -41,10 +41,9 @@ namespace IW4MAdmin.Application
|
||||
|
||||
public IList<IRConParser> AdditionalRConParsers { get; }
|
||||
public IList<IEventParser> AdditionalEventParsers { get; }
|
||||
|
||||
public ITokenAuthentication TokenAuthenticator => Authenticator;
|
||||
|
||||
public ITokenAuthentication Authenticator => _authenticator;
|
||||
public string ExternalIPAddress { get; private set; }
|
||||
|
||||
static ApplicationManager Instance;
|
||||
readonly List<AsyncStatus> TaskStatuses;
|
||||
@ -158,7 +157,7 @@ namespace IW4MAdmin.Application
|
||||
return Instance ?? (Instance = new ApplicationManager());
|
||||
}
|
||||
|
||||
public async Task UpdateServerStates()
|
||||
public async Task UpdateServerStates(CancellationToken token)
|
||||
{
|
||||
// store the server hash code and task for it
|
||||
var runningUpdateTasks = new Dictionary<long, Task>();
|
||||
@ -215,17 +214,19 @@ namespace IW4MAdmin.Application
|
||||
ThreadPool.GetAvailableThreads(out int availableThreads, out int m);
|
||||
Logger.WriteDebug($"There are {workerThreads - availableThreads} active threading tasks");
|
||||
#endif
|
||||
await Task.Delay(ConfigHandler.Configuration().RConPollRate);
|
||||
try
|
||||
{
|
||||
await Task.Delay(ConfigHandler.Configuration().RConPollRate, token);
|
||||
}
|
||||
// if a cancellation is received, we want to return immediately
|
||||
catch { break; }
|
||||
}
|
||||
|
||||
// trigger the event processing loop to end
|
||||
SetHasEvent();
|
||||
}
|
||||
|
||||
public async Task Init()
|
||||
{
|
||||
Running = true;
|
||||
|
||||
ExternalIPAddress = await Utilities.GetExternalIP();
|
||||
|
||||
#region PLUGINS
|
||||
SharedLibraryCore.Plugins.PluginImporter.Load(this);
|
||||
@ -642,27 +643,34 @@ namespace IW4MAdmin.Application
|
||||
}
|
||||
|
||||
}
|
||||
await Task.Delay(30000);
|
||||
|
||||
try
|
||||
{
|
||||
await Task.Delay(30000, heartbeatState.Token);
|
||||
}
|
||||
catch { break; }
|
||||
}
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
var tokenSource = new CancellationTokenSource();
|
||||
// this needs to be run seperately from the main thread
|
||||
var _ = Task.Run(() => SendHeartbeat(new HeartbeatState()));
|
||||
_ = Task.Run(() => UpdateServerStates());
|
||||
_ = Task.Run(() => SendHeartbeat(new HeartbeatState() { Token = tokenSource.Token }));
|
||||
_ = Task.Run(() => UpdateServerStates(tokenSource.Token));
|
||||
|
||||
while (Running)
|
||||
{
|
||||
OnQuit.Wait();
|
||||
tokenSource.Cancel();
|
||||
OnQuit.Reset();
|
||||
}
|
||||
_servers.Clear();
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
Running = false;
|
||||
OnQuit.Set();
|
||||
}
|
||||
|
||||
public ILogger GetLogger(long serverId)
|
||||
@ -737,7 +745,7 @@ namespace IW4MAdmin.Application
|
||||
|
||||
public void SetHasEvent()
|
||||
{
|
||||
OnQuit.Set();
|
||||
|
||||
}
|
||||
|
||||
public IList<Assembly> GetPluginAssemblies()
|
||||
|
@ -176,7 +176,7 @@ namespace IW4MAdmin
|
||||
{
|
||||
if (E.Type == GameEvent.EventType.ChangePermission)
|
||||
{
|
||||
var newPermission = (EFClient.Permission)E.Extra;
|
||||
var newPermission = (Permission)E.Extra;
|
||||
|
||||
if (newPermission < Permission.Moderator)
|
||||
{
|
||||
@ -189,7 +189,8 @@ namespace IW4MAdmin
|
||||
Manager.GetPrivilegedClients()[E.Target.ClientId] = E.Target;
|
||||
}
|
||||
|
||||
await Manager.GetClientService().UpdateLevel((Permission)E.Extra, E.Target, E.Origin);
|
||||
Logger.WriteInfo($"{E.Origin} is setting {E.Target} to permission level {newPermission}");
|
||||
await Manager.GetClientService().UpdateLevel(newPermission, E.Target, E.Origin);
|
||||
}
|
||||
|
||||
else if (E.Type == GameEvent.EventType.PreConnect)
|
||||
@ -342,7 +343,7 @@ namespace IW4MAdmin
|
||||
#endif
|
||||
}
|
||||
|
||||
else
|
||||
else if (client?.State != ClientState.Disconnecting)
|
||||
{
|
||||
Logger.WriteWarning($"Client {E.Origin} detected as disconnecting, but could not find them in the player list");
|
||||
Logger.WriteDebug($"Expected {E.Origin} but found {GetClientsAsList().FirstOrDefault(_client => _client.ClientNumber == E.Origin.ClientNumber)}");
|
||||
@ -470,9 +471,18 @@ namespace IW4MAdmin
|
||||
if (client.IPAddress == null &&
|
||||
!client.IsBot &&
|
||||
client.State == ClientState.Connected)
|
||||
{
|
||||
try
|
||||
{
|
||||
await client.OnJoin(origin.IPAddress);
|
||||
}
|
||||
|
||||
catch (Exception e)
|
||||
{
|
||||
origin.CurrentServer.Logger.WriteWarning($"Could not execute on join for {origin}");
|
||||
origin.CurrentServer.Logger.WriteDebug(e.GetExceptionInfo());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,8 +40,8 @@ namespace SharedLibraryCore.Database.Models
|
||||
[NotMapped]
|
||||
public virtual string Name
|
||||
{
|
||||
get { return CurrentAlias.Name; }
|
||||
set { CurrentAlias.Name = value; }
|
||||
get { return CurrentAlias?.Name ?? "--"; }
|
||||
set { if (CurrentAlias != null) CurrentAlias.Name = value; }
|
||||
}
|
||||
[NotMapped]
|
||||
public virtual int? IPAddress
|
||||
|
@ -20,5 +20,6 @@ namespace SharedLibraryCore.Dtos
|
||||
public long ID { get; set; }
|
||||
public bool Online { get; set; }
|
||||
public string ConnectProtocolUrl { get; set; }
|
||||
public string IPAddress { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -46,5 +46,6 @@ namespace SharedLibraryCore.Interfaces
|
||||
IEventParser GenerateDynamicEventParser();
|
||||
string Version { get;}
|
||||
ITokenAuthentication TokenAuthenticator { get; }
|
||||
string ExternalIPAddress { get; }
|
||||
}
|
||||
}
|
||||
|
@ -467,9 +467,19 @@ namespace SharedLibraryCore.Database.Models
|
||||
State = ClientState.Disconnecting;
|
||||
TotalConnectionTime += ConnectionLength;
|
||||
LastConnection = DateTime.UtcNow;
|
||||
|
||||
try
|
||||
{
|
||||
await CurrentServer.Manager.GetClientService().Update(this);
|
||||
}
|
||||
|
||||
catch (Exception e)
|
||||
{
|
||||
CurrentServer.Logger.WriteWarning($"Could not update disconnected player {this}");
|
||||
CurrentServer.Logger.WriteDebug(e.GetExceptionInfo());
|
||||
}
|
||||
}
|
||||
|
||||
public async Task OnJoin(int? ipAddress)
|
||||
{
|
||||
CurrentServer.Logger.WriteDebug($"Start join for {this}::{ipAddress}::{Level.ToString()}");
|
||||
|
@ -248,6 +248,7 @@ namespace SharedLibraryCore.Services
|
||||
Type = GameEvent.EventType.ChangePermission,
|
||||
Extra = newPermission,
|
||||
Origin = origin,
|
||||
Owner = temporalClient.CurrentServer,
|
||||
Target = _client
|
||||
}, ctx);
|
||||
#if DEBUG == true
|
||||
@ -255,7 +256,6 @@ namespace SharedLibraryCore.Services
|
||||
#endif
|
||||
});
|
||||
|
||||
|
||||
await ctx.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
@ -730,6 +731,53 @@ namespace SharedLibraryCore
|
||||
return string.Format(output, values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// https://stackoverflow.com/questions/8113546/how-to-determine-whether-an-ip-address-in-private/39120248
|
||||
/// An extension method to determine if an IP address is internal, as specified in RFC1918
|
||||
/// </summary>
|
||||
/// <param name="toTest">The IP address that will be tested</param>
|
||||
/// <returns>Returns true if the IP is internal, false if it is external</returns>
|
||||
public static bool IsInternal(this IPAddress toTest)
|
||||
{
|
||||
if (toTest.ToString().StartsWith("127.0.0"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
byte[] bytes = toTest.GetAddressBytes();
|
||||
switch (bytes[0])
|
||||
{
|
||||
case 10:
|
||||
return true;
|
||||
case 172:
|
||||
return bytes[1] < 32 && bytes[1] >= 16;
|
||||
case 192:
|
||||
return bytes[1] == 168;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// retrieves the external IP address of the current running machine
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static async Task<string> GetExternalIP()
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var wc = new WebClient())
|
||||
{
|
||||
return await wc.DownloadStringTaskAsync("https://api.ipify.org");
|
||||
}
|
||||
}
|
||||
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG == true
|
||||
|
||||
private static readonly TypeInfo QueryCompilerTypeInfo = typeof(QueryCompiler).GetTypeInfo();
|
||||
|
@ -2,6 +2,7 @@
|
||||
using SharedLibraryCore;
|
||||
using SharedLibraryCore.Dtos;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
|
||||
namespace WebfrontCore.ViewComponents
|
||||
{
|
||||
@ -10,6 +11,7 @@ namespace WebfrontCore.ViewComponents
|
||||
public IViewComponentResult Invoke()
|
||||
{
|
||||
var servers = Program.Manager.GetServers();
|
||||
|
||||
var serverInfo = servers.Select(s => new ServerInfo()
|
||||
{
|
||||
Name = s.Hostname,
|
||||
@ -30,7 +32,8 @@ namespace WebfrontCore.ViewComponents
|
||||
}).ToList(),
|
||||
ChatHistory = s.ChatHistory.ToList(),
|
||||
Online = !s.Throttled,
|
||||
ConnectProtocolUrl = s.EventParser.URLProtocolFormat.FormatExt(s.IP, s.GetPort())
|
||||
IPAddress = $"{(IPAddress.Parse(s.IP).IsInternal() ? Program.Manager.ExternalIPAddress : s.IP)}:{s.GetPort()}",
|
||||
ConnectProtocolUrl = s.EventParser.URLProtocolFormat.FormatExt(IPAddress.Parse(s.IP).IsInternal() ? Program.Manager.ExternalIPAddress : s.IP, s.GetPort())
|
||||
}).ToList();
|
||||
return View("_List", serverInfo);
|
||||
}
|
||||
|
@ -7,7 +7,8 @@
|
||||
<div class="col-md-4 text-center text-md-left d-inline-flex justify-content-center justify-content-md-start">
|
||||
<span>@Model.Name</span>
|
||||
<a href="@Model.ConnectProtocolUrl" class="ml-2 align-self-center d-none d-md-flex server-join-button" title="@SharedLibraryCore.Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_HOME_JOIN_DESC"]">
|
||||
<span class="oi oi-play-circle"></span>
|
||||
<span class="oi oi-play-circle mr-2 align-self-center"></span>
|
||||
<span class="server-header-ip-address" style="display:none;">@Model.IPAddress</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="text-center col-md-4">@Model.Map</div>
|
||||
|
@ -89,4 +89,10 @@ function refreshClientActivity() {
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
$('.server-join-button').click(function (e) {
|
||||
$(this).children('.server-header-ip-address').show();
|
||||
});
|
||||
})
|
||||
|
||||
setInterval(refreshClientActivity, 2000);
|
||||
|
Loading…
Reference in New Issue
Block a user