mirror of
https://github.com/RaidMax/IW4M-Admin.git
synced 2025-06-11 15:52:25 -05:00
support custom master url
refactor api instatation to allow custom master url in config
This commit is contained in:
@ -1,72 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using RestEase;
|
||||
|
||||
namespace IW4MAdmin.Application.API.Master
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the heartbeat functionality for IW4MAdmin
|
||||
/// </summary>
|
||||
public class Heartbeat
|
||||
{
|
||||
/// <summary>
|
||||
/// Sends heartbeat to master server
|
||||
/// </summary>
|
||||
/// <param name="mgr"></param>
|
||||
/// <param name="firstHeartbeat"></param>
|
||||
/// <returns></returns>
|
||||
public static async Task Send(ApplicationManager mgr, bool firstHeartbeat = false)
|
||||
{
|
||||
var api = Endpoint.Get();
|
||||
|
||||
if (firstHeartbeat)
|
||||
{
|
||||
var token = await api.Authenticate(new AuthenticationId()
|
||||
{
|
||||
Id = mgr.GetApplicationSettings().Configuration().Id
|
||||
});
|
||||
|
||||
api.AuthorizationToken = $"Bearer {token.AccessToken}";
|
||||
}
|
||||
|
||||
var instance = new ApiInstance()
|
||||
{
|
||||
Id = mgr.GetApplicationSettings().Configuration().Id,
|
||||
Uptime = (int)(DateTime.UtcNow - mgr.StartTime).TotalSeconds,
|
||||
Version = Program.Version,
|
||||
Servers = mgr.Servers.Select(s =>
|
||||
new ApiServer()
|
||||
{
|
||||
ClientNum = s.ClientNum,
|
||||
Game = s.GameName.ToString(),
|
||||
Version = s.Version,
|
||||
Gametype = s.Gametype,
|
||||
Hostname = s.Hostname,
|
||||
Map = s.CurrentMap.Name,
|
||||
MaxClientNum = s.MaxClients,
|
||||
Id = s.EndPoint,
|
||||
Port = (short)s.Port,
|
||||
IPAddress = s.IP
|
||||
}).ToList()
|
||||
};
|
||||
|
||||
Response<ResultMessage> response = null;
|
||||
|
||||
if (firstHeartbeat)
|
||||
{
|
||||
response = await api.AddInstance(instance);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
response = await api.UpdateInstance(instance.Id, instance);
|
||||
}
|
||||
|
||||
if (response.ResponseMessage.StatusCode != System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
mgr.Logger.WriteWarning($"Response code from master is {response.ResponseMessage.StatusCode}, message is {response.StringContent}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using RestEase;
|
||||
@ -37,16 +35,6 @@ namespace IW4MAdmin.Application.API.Master
|
||||
public string Message { get; set; }
|
||||
}
|
||||
|
||||
public class Endpoint
|
||||
{
|
||||
#if !DEBUG
|
||||
private static readonly IMasterApi api = RestClient.For<IMasterApi>("http://api.raidmax.org:5000");
|
||||
#else
|
||||
private static readonly IMasterApi api = RestClient.For<IMasterApi>("http://127.0.0.1");
|
||||
#endif
|
||||
public static IMasterApi Get() => api;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the capabilities of the master API
|
||||
/// </summary>
|
||||
|
@ -648,85 +648,7 @@ namespace IW4MAdmin.Application
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SendHeartbeat()
|
||||
{
|
||||
bool connected = false;
|
||||
|
||||
while (!_tokenSource.IsCancellationRequested)
|
||||
{
|
||||
if (!connected)
|
||||
{
|
||||
try
|
||||
{
|
||||
await Heartbeat.Send(this, true);
|
||||
connected = true;
|
||||
}
|
||||
|
||||
catch (Exception e)
|
||||
{
|
||||
connected = false;
|
||||
Logger.WriteWarning($"Could not connect to heartbeat server - {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
await Heartbeat.Send(this);
|
||||
}
|
||||
|
||||
catch (System.Net.Http.HttpRequestException e)
|
||||
{
|
||||
Logger.WriteWarning($"Could not send heartbeat - {e.Message}");
|
||||
}
|
||||
|
||||
catch (AggregateException e)
|
||||
{
|
||||
Logger.WriteWarning($"Could not send heartbeat - {e.Message}");
|
||||
var exceptions = e.InnerExceptions.Where(ex => ex.GetType() == typeof(RestEase.ApiException));
|
||||
|
||||
foreach (var ex in exceptions)
|
||||
{
|
||||
if (((RestEase.ApiException)ex).StatusCode == System.Net.HttpStatusCode.Unauthorized)
|
||||
{
|
||||
connected = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
catch (RestEase.ApiException e)
|
||||
{
|
||||
Logger.WriteWarning($"Could not send heartbeat - {e.Message}");
|
||||
if (e.StatusCode == System.Net.HttpStatusCode.Unauthorized)
|
||||
{
|
||||
connected = false;
|
||||
}
|
||||
}
|
||||
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.WriteWarning($"Could not send heartbeat - {e.Message}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await Task.Delay(30000, _tokenSource.Token);
|
||||
}
|
||||
catch { break; }
|
||||
}
|
||||
}
|
||||
|
||||
public async Task Start()
|
||||
{
|
||||
await Task.WhenAll(new[]
|
||||
{
|
||||
SendHeartbeat(),
|
||||
UpdateServerStates()
|
||||
});
|
||||
}
|
||||
public async Task Start() => await UpdateServerStates();
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
|
@ -11,7 +11,7 @@ namespace IW4MAdmin.Application.Localization
|
||||
{
|
||||
public class Configure
|
||||
{
|
||||
public static ITranslationLookup Initialize(bool useLocalTranslation, string customLocale = null)
|
||||
public static ITranslationLookup Initialize(bool useLocalTranslation, IMasterApi apiInstance, string customLocale = null)
|
||||
{
|
||||
string currentLocale = string.IsNullOrEmpty(customLocale) ? CultureInfo.CurrentCulture.Name : customLocale;
|
||||
string[] localizationFiles = Directory.GetFiles(Path.Join(Utilities.OperatingDirectory, "Localization"), $"*.{currentLocale}.json");
|
||||
@ -20,8 +20,7 @@ namespace IW4MAdmin.Application.Localization
|
||||
{
|
||||
try
|
||||
{
|
||||
var api = Endpoint.Get();
|
||||
var localization = api.GetLocalization(currentLocale).Result;
|
||||
var localization = apiInstance.GetLocalization(currentLocale).Result;
|
||||
Utilities.CurrentLocalization = localization;
|
||||
return localization.LocalizationIndex;
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
using IW4MAdmin.Application.EventParsers;
|
||||
using IW4MAdmin.Application.API.Master;
|
||||
using IW4MAdmin.Application.EventParsers;
|
||||
using IW4MAdmin.Application.Factories;
|
||||
using IW4MAdmin.Application.Helpers;
|
||||
using IW4MAdmin.Application.Migration;
|
||||
using IW4MAdmin.Application.Misc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using RestEase;
|
||||
using SharedLibraryCore;
|
||||
using SharedLibraryCore.Configuration;
|
||||
using SharedLibraryCore.Exceptions;
|
||||
@ -23,7 +25,6 @@ namespace IW4MAdmin.Application
|
||||
public static BuildNumber Version { get; private set; } = BuildNumber.Parse(Utilities.GetVersionAsString());
|
||||
public static ApplicationManager ServerManager;
|
||||
private static Task ApplicationTask;
|
||||
private static readonly BuildNumber _fallbackVersion = BuildNumber.Parse("99.99.99.99");
|
||||
private static ServiceProvider serviceProvider;
|
||||
|
||||
/// <summary>
|
||||
@ -76,12 +77,13 @@ namespace IW4MAdmin.Application
|
||||
|
||||
var services = ConfigureServices(args);
|
||||
serviceProvider = services.BuildServiceProvider();
|
||||
var versionChecker = serviceProvider.GetRequiredService<IMasterCommunication>();
|
||||
ServerManager = (ApplicationManager)serviceProvider.GetRequiredService<IManager>();
|
||||
translationLookup = serviceProvider.GetRequiredService<ITranslationLookup>();
|
||||
|
||||
ServerManager.Logger.WriteInfo(Utilities.CurrentLocalization.LocalizationIndex["MANAGER_VERSION"].FormatExt(Version));
|
||||
|
||||
await CheckVersion(translationLookup);
|
||||
await versionChecker.CheckVersion();
|
||||
await ServerManager.Init();
|
||||
}
|
||||
|
||||
@ -155,6 +157,7 @@ namespace IW4MAdmin.Application
|
||||
{
|
||||
ServerManager.Start(),
|
||||
webfrontTask,
|
||||
serviceProvider.GetRequiredService<IMasterCommunication>().RunUploadStatus(ServerManager.CancellationToken)
|
||||
};
|
||||
|
||||
await Task.WhenAll(tasks);
|
||||
@ -162,68 +165,6 @@ namespace IW4MAdmin.Application
|
||||
ServerManager.Logger.WriteVerbose(Utilities.CurrentLocalization.LocalizationIndex["MANAGER_SHUTDOWN_SUCCESS"]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// checks for latest version of the application
|
||||
/// notifies user if an update is available
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static async Task CheckVersion(ITranslationLookup translationLookup)
|
||||
{
|
||||
var api = API.Master.Endpoint.Get();
|
||||
var loc = translationLookup;
|
||||
|
||||
var version = new API.Master.VersionInfo()
|
||||
{
|
||||
CurrentVersionStable = _fallbackVersion
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
version = await api.GetVersion(1);
|
||||
}
|
||||
|
||||
catch (Exception e)
|
||||
{
|
||||
ServerManager.Logger.WriteWarning(loc["MANAGER_VERSION_FAIL"]);
|
||||
while (e.InnerException != null)
|
||||
{
|
||||
e = e.InnerException;
|
||||
}
|
||||
|
||||
ServerManager.Logger.WriteDebug(e.Message);
|
||||
}
|
||||
|
||||
if (version.CurrentVersionStable == _fallbackVersion)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine(loc["MANAGER_VERSION_FAIL"]);
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
}
|
||||
|
||||
#if !PRERELEASE
|
||||
else if (version.CurrentVersionStable > Version)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
||||
Console.WriteLine($"IW4MAdmin {loc["MANAGER_VERSION_UPDATE"]} [v{version.CurrentVersionStable.ToString()}]");
|
||||
Console.WriteLine(loc["MANAGER_VERSION_CURRENT"].FormatExt($"[v{Version.ToString()}]"));
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
}
|
||||
#else
|
||||
else if (version.CurrentVersionPrerelease > Version)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
||||
Console.WriteLine($"IW4MAdmin-Prerelease {loc["MANAGER_VERSION_UPDATE"]} [v{version.CurrentVersionPrerelease.ToString()}-pr]");
|
||||
Console.WriteLine(loc["MANAGER_VERSION_CURRENT"].FormatExt($"[v{Version.ToString()}-pr]"));
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
Console.WriteLine(loc["MANAGER_VERSION_SUCCESS"]);
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// reads input from the console and executes entered commands on the default server
|
||||
@ -299,9 +240,12 @@ namespace IW4MAdmin.Application
|
||||
{
|
||||
var config = _serviceProvider.GetRequiredService<IConfigurationHandler<ApplicationConfiguration>>().Configuration();
|
||||
return Localization.Configure.Initialize(useLocalTranslation: config?.UseLocalTranslations ?? false,
|
||||
apiInstance: _serviceProvider.GetRequiredService<IMasterApi>(),
|
||||
customLocale: config?.EnableCustomLocale ?? false ? (config.CustomLocale ?? "en-US") : "en-US");
|
||||
})
|
||||
.AddSingleton<IManager, ApplicationManager>();
|
||||
.AddSingleton<IManager, ApplicationManager>()
|
||||
.AddSingleton(_serviceProvider => RestClient.For<IMasterApi>(Utilities.IsDevelopment ? new Uri("http://127.0.0.1:8080") : _serviceProvider.GetRequiredService<ApplicationConfiguration>().MasterUrl))
|
||||
.AddSingleton<IMasterCommunication, MasterCommunication>();
|
||||
|
||||
if (args.Contains("serialevents"))
|
||||
{
|
||||
|
209
Application/Misc/MasterCommunication.cs
Normal file
209
Application/Misc/MasterCommunication.cs
Normal file
@ -0,0 +1,209 @@
|
||||
using IW4MAdmin.Application.API.Master;
|
||||
using RestEase;
|
||||
using SharedLibraryCore;
|
||||
using SharedLibraryCore.Configuration;
|
||||
using SharedLibraryCore.Helpers;
|
||||
using SharedLibraryCore.Interfaces;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IW4MAdmin.Application.Misc
|
||||
{
|
||||
/// <summary>
|
||||
/// implementation of IMasterCommunication
|
||||
/// talks to the master server
|
||||
/// </summary>
|
||||
class MasterCommunication : IMasterCommunication
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly ITranslationLookup _transLookup;
|
||||
private readonly IMasterApi _apiInstance;
|
||||
private readonly IManager _manager;
|
||||
private readonly ApplicationConfiguration _appConfig;
|
||||
private readonly BuildNumber _fallbackVersion = BuildNumber.Parse("99.99.99.99");
|
||||
private readonly int _apiVersion = 1;
|
||||
|
||||
private bool firstHeartBeat = true;
|
||||
|
||||
public MasterCommunication(ILogger logger, ApplicationConfiguration appConfig, ITranslationLookup translationLookup, IMasterApi apiInstance, IManager manager)
|
||||
{
|
||||
_logger = logger;
|
||||
_transLookup = translationLookup;
|
||||
_apiInstance = apiInstance;
|
||||
_appConfig = appConfig;
|
||||
_manager = manager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// checks for latest version of the application
|
||||
/// notifies user if an update is available
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task CheckVersion()
|
||||
{
|
||||
var version = new VersionInfo()
|
||||
{
|
||||
CurrentVersionStable = _fallbackVersion
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
version = await _apiInstance.GetVersion(_apiVersion);
|
||||
}
|
||||
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.WriteWarning(_transLookup["MANAGER_VERSION_FAIL"]);
|
||||
while (e.InnerException != null)
|
||||
{
|
||||
e = e.InnerException;
|
||||
}
|
||||
|
||||
_logger.WriteDebug(e.Message);
|
||||
}
|
||||
|
||||
if (version.CurrentVersionStable == _fallbackVersion)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine(_transLookup["MANAGER_VERSION_FAIL"]);
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
}
|
||||
|
||||
#if !PRERELEASE
|
||||
else if (version.CurrentVersionStable > Program.Version)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
||||
Console.WriteLine($"IW4MAdmin {_transLookup["MANAGER_VERSION_UPDATE"]} [v{version.CurrentVersionStable.ToString()}]");
|
||||
Console.WriteLine(_transLookup["MANAGER_VERSION_CURRENT"].FormatExt($"[v{Program.Version.ToString()}]"));
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
}
|
||||
#else
|
||||
else if (version.CurrentVersionPrerelease > Program.Version)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
||||
Console.WriteLine($"IW4MAdmin-Prerelease {_transLookup["MANAGER_VERSION_UPDATE"]} [v{version.CurrentVersionPrerelease.ToString()}-pr]");
|
||||
Console.WriteLine(_transLookup["MANAGER_VERSION_CURRENT"].FormatExt($"[v{Program.Version.ToString()}-pr]"));
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
Console.WriteLine(_transLookup["MANAGER_VERSION_SUCCESS"]);
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task RunUploadStatus(CancellationToken token)
|
||||
{
|
||||
// todo: clean up this logic
|
||||
bool connected;
|
||||
|
||||
while (!token.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
await UploadStatus();
|
||||
}
|
||||
|
||||
catch (System.Net.Http.HttpRequestException e)
|
||||
{
|
||||
_logger.WriteWarning($"Could not send heartbeat - {e.Message}");
|
||||
}
|
||||
|
||||
catch (AggregateException e)
|
||||
{
|
||||
_logger.WriteWarning($"Could not send heartbeat - {e.Message}");
|
||||
var exceptions = e.InnerExceptions.Where(ex => ex.GetType() == typeof(ApiException));
|
||||
|
||||
foreach (var ex in exceptions)
|
||||
{
|
||||
if (((ApiException)ex).StatusCode == System.Net.HttpStatusCode.Unauthorized)
|
||||
{
|
||||
connected = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
catch (ApiException e)
|
||||
{
|
||||
_logger.WriteWarning($"Could not send heartbeat - {e.Message}");
|
||||
if (e.StatusCode == System.Net.HttpStatusCode.Unauthorized)
|
||||
{
|
||||
connected = false;
|
||||
}
|
||||
}
|
||||
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.WriteWarning($"Could not send heartbeat - {e.Message}");
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
await Task.Delay(30000, token);
|
||||
}
|
||||
|
||||
catch
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task UploadStatus()
|
||||
{
|
||||
if (firstHeartBeat)
|
||||
{
|
||||
var token = await _apiInstance.Authenticate(new AuthenticationId
|
||||
{
|
||||
Id = _appConfig.Id
|
||||
});
|
||||
|
||||
_apiInstance.AuthorizationToken = $"Bearer {token.AccessToken}";
|
||||
}
|
||||
|
||||
var instance = new ApiInstance
|
||||
{
|
||||
Id = _appConfig.Id,
|
||||
Uptime = (int)(DateTime.UtcNow - (_manager as ApplicationManager).StartTime).TotalSeconds,
|
||||
Version = Program.Version,
|
||||
Servers = _manager.GetServers().Select(s =>
|
||||
new ApiServer()
|
||||
{
|
||||
ClientNum = s.ClientNum,
|
||||
Game = s.GameName.ToString(),
|
||||
Version = s.Version,
|
||||
Gametype = s.Gametype,
|
||||
Hostname = s.Hostname,
|
||||
Map = s.CurrentMap.Name,
|
||||
MaxClientNum = s.MaxClients,
|
||||
Id = s.EndPoint,
|
||||
Port = (short)s.Port,
|
||||
IPAddress = s.IP
|
||||
}).ToList()
|
||||
};
|
||||
|
||||
Response<ResultMessage> response = null;
|
||||
|
||||
if (firstHeartBeat)
|
||||
{
|
||||
response = await _apiInstance.AddInstance(instance);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
response = await _apiInstance.UpdateInstance(instance.Id, instance);
|
||||
firstHeartBeat = false;
|
||||
}
|
||||
|
||||
if (response.ResponseMessage.StatusCode != System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
_logger.WriteWarning($"Response code from master is {response.ResponseMessage.StatusCode}, message is {response.StringContent}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user