-
Notifications
You must be signed in to change notification settings - Fork 80
Expand file tree
/
Copy pathGameUpdateManager.cs
More file actions
137 lines (113 loc) · 4.36 KB
/
GameUpdateManager.cs
File metadata and controls
137 lines (113 loc) · 4.36 KB
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
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
using NLog;
using Sandbox.Game;
using Torch.API;
using Torch.API.Managers;
using Torch.Managers;
using Torch.Managers.ChatManager;
namespace Torch.Server.Managers
{
public class GameUpdateManager : Manager
{
private CancellationTokenSource _cancellationTokenSource;
private readonly HttpClient _httpClient;
private const string UpdateCheckUrl = "https://mirror.keenswh.com/news/SpaceEngineersChangelog.xml";
private static readonly Logger _log = LogManager.GetCurrentClassLogger();
public GameUpdateManager(ITorchBase torchInstance) : base(torchInstance)
{
_httpClient = new HttpClient();
}
public override void Attach()
{
_log.Debug("Starting game update manager");
base.Attach();
_cancellationTokenSource = new CancellationTokenSource();
Task.Run(async () =>
{
while (!_cancellationTokenSource.Token.IsCancellationRequested)
{
await CheckForUpdates();
await Task.Delay(TimeSpan.FromSeconds(120), _cancellationTokenSource.Token);
}
}, _cancellationTokenSource.Token);
}
public override void Detach()
{
_cancellationTokenSource?.Cancel();
base.Detach();
}
private async Task CheckForUpdates()
{
_log.Debug("Checking for updates...");
if (!ShouldCheckForUpdates())
{
_log.Debug("Update check skipped");
return;
}
var latestVersion = await GetLatestVersionAsync();
if (latestVersion == null)
{
_log.Debug("Could not fetch the latest game version");
return;
}
var currentVersion = MyPerGameSettings.BasicGameInfo.GameVersion.Value;
if (IsNewerVersion(latestVersion, currentVersion.ToString()))
{
await HandleNewVersion(latestVersion);
}
}
private bool ShouldCheckForUpdates()
{
return TorchBase.Instance.GameState == TorchGameState.Loaded && TorchBase.Instance.Config.RestartOnGameUpdate;
}
private async Task<string> GetLatestVersionAsync()
{
var response = await _httpClient.GetStringAsync(UpdateCheckUrl);
var xml = XDocument.Parse(response);
var latestEntry = xml.Root.Element("Entry");
return latestEntry?.Attribute("version")?.Value;
}
private bool IsNewerVersion(string latestVersion, string currentVersion)
{
var latestVersionParts = latestVersion.Split('.');
var currentVersionParts = currentVersion.Split('.');
for (int i = 0; i < Math.Min(latestVersionParts.Length, currentVersionParts.Length); i++)
{
if (int.Parse(latestVersionParts[i]) > int.Parse(currentVersionParts[i]))
{
return true;
}
}
return latestVersionParts.Length > currentVersionParts.Length;
}
private async Task HandleNewVersion(string latestVersion)
{
_log.Debug($"Game update detected!");
try
{
var chatManager = Torch.CurrentSession?.Managers.GetManager<ChatManagerServer>();
if (chatManager != null)
{
var message = $"A new version of Space Engineers is available! The server will restart in {TorchBase.Instance.Config.GameUpdateRestartDelayMins} minutes to update to version {latestVersion}.";
_log.Debug(message);
chatManager.SendMessageAsOther("Server", message);
}
await Task.Delay(TimeSpan.FromMinutes(TorchBase.Instance.Config.GameUpdateRestartDelayMins), _cancellationTokenSource.Token);
// Restart the server
Torch.Restart();
}
catch (TaskCanceledException)
{
// Task was cancelled, do nothing
}
catch
{
// ignored
}
}
}
}