-
-
Notifications
You must be signed in to change notification settings - Fork 43
/
Copy pathMasterCommunication.cs
176 lines (160 loc) · 6.37 KB
/
MasterCommunication.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
using IW4MAdmin.Application.API.Master;
using SharedLibraryCore;
using SharedLibraryCore.Configuration;
using SharedLibraryCore.Helpers;
using SharedLibraryCore.Interfaces;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Refit;
using ILogger = Microsoft.Extensions.Logging.ILogger;
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;
private static readonly TimeSpan Interval = TimeSpan.FromSeconds(30);
private string _authorizationToken;
public MasterCommunication(ILogger<MasterCommunication> 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.LogWarning(e, "Unable to retrieve IW4MAdmin version information");
}
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)
{
while (!token.IsCancellationRequested)
{
try
{
if (_manager.IsRunning)
{
await UploadStatus();
}
}
catch (Exception ex)
{
_logger.LogWarning("Could not send heartbeat - {Message}", ex.Message);
}
try
{
await Task.Delay(Interval, token);
}
catch
{
break;
}
}
}
private async Task UploadStatus()
{
if (_firstHeartBeat)
{
var token = await _apiInstance.Authenticate(new AuthenticationId
{
Id = _appConfig.Id
});
_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.ListenPort,
IPAddress = s.ListenAddress
}).ToList(),
WebfrontUrl = _appConfig.WebfrontUrl
};
IApiResponse<ResultMessage> response;
if (_firstHeartBeat)
{
response = await _apiInstance.AddInstance(instance, _authorizationToken);
}
else
{
response = await _apiInstance.UpdateInstance(instance.Id, instance, _authorizationToken);
_firstHeartBeat = false;
}
if (response.StatusCode != System.Net.HttpStatusCode.OK)
{
_logger.LogWarning("Non success response code from master is {StatusCode}, message is {Message}", response.StatusCode, response.Error?.Content);
}
}
}
}