1
0
mirror of https://github.com/ncblakely/GiantsTools synced 2024-11-22 06:05:38 +01:00

Partial refactor of updater code and version API.

This commit is contained in:
Nick Blakely 2020-08-11 01:29:45 -07:00
parent ff7df4960a
commit d4df4e42e0
15 changed files with 174 additions and 223 deletions

View File

@ -3,7 +3,7 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
public class GiantsVersion public class AppVersion
{ {
[Required] [Required]
public int Build { get; set; } public int Build { get; set; }
@ -19,7 +19,7 @@
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
return obj is GiantsVersion info && return obj is AppVersion info &&
Build == info.Build && Build == info.Build &&
Major == info.Major && Major == info.Major &&
Minor == info.Minor && Minor == info.Minor &&

View File

@ -12,7 +12,7 @@
public string GameName { get; set; } public string GameName { get; set; }
[Required] [Required]
public GiantsVersion Version { get; set; } public AppVersion Version { get; set; }
[Required] [Required]
[StringLength(100)] [StringLength(100)]
@ -55,7 +55,7 @@
{ {
return obj is ServerInfo info && return obj is ServerInfo info &&
GameName == info.GameName && GameName == info.GameName &&
EqualityComparer<GiantsVersion>.Default.Equals(Version, info.Version) && EqualityComparer<AppVersion>.Default.Equals(Version, info.Version) &&
SessionName == info.SessionName && SessionName == info.SessionName &&
Port == info.Port && Port == info.Port &&
MapName == info.MapName && MapName == info.MapName &&

View File

@ -6,15 +6,12 @@
public class VersionInfo public class VersionInfo
{ {
[Required] [Required]
public string GameName { get; set; } public string AppName { get; set; }
[Required] [Required]
public GiantsVersion GameVersion { get; set; } public AppVersion Version { get; set; }
[Required] [Required]
public GiantsVersion LauncherVersion { get; set; } public Uri InstallerUri { get; set; }
[Required]
public Uri PatchUri { get; set; }
} }
} }

View File

@ -4,7 +4,10 @@ using System.Diagnostics;
using System.IO; using System.IO;
using System.Media; using System.Media;
using System.Net; using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using Giants.WebApi.Clients;
using Microsoft.Win32; using Microsoft.Win32;
namespace Giants.Launcher namespace Giants.Launcher
@ -12,15 +15,16 @@ namespace Giants.Launcher
public partial class LauncherForm : Form public partial class LauncherForm : Form
{ {
// Constant settings // Constant settings
const string GAME_NAME = "Giants: Citizen Kabuto"; private const string GAME_NAME = "Giants: Citizen Kabuto";
const string GAME_PATH = "GiantsMain.exe"; private const string GAME_PATH = "GiantsMain.exe";
const string REGISTRY_KEY = @"HKEY_CURRENT_USER\Software\PlanetMoon\Giants"; private const string REGISTRY_KEY = @"HKEY_CURRENT_USER\Software\PlanetMoon\Giants";
const string REGISTRY_VALUE = "DestDir"; private const string REGISTRY_VALUE = "DestDir";
const string UPDATE_URL = @"https://google.com"; // update me private const string UPDATE_URL = @"https://google.com"; // update me
private readonly VersionClient httpClient;
string _commandLine = String.Empty; private string commandLine = String.Empty;
string _gamePath = null; private string gamePath = null;
Updater _Updater; private Updater updater;
public LauncherForm() public LauncherForm()
{ {
@ -28,6 +32,9 @@ namespace Giants.Launcher
// Set window title // Set window title
this.Text = GAME_NAME; this.Text = GAME_NAME;
this.httpClient = new VersionClient(new HttpClient());
this.httpClient.BaseUrl = "https://giants.azurewebsites.net";
} }
private void btnExit_Click(object sender, EventArgs e) private void btnExit_Click(object sender, EventArgs e)
@ -40,48 +47,49 @@ namespace Giants.Launcher
GameSettings.Save(); GameSettings.Save();
foreach (string c in Environment.GetCommandLineArgs()) foreach (string c in Environment.GetCommandLineArgs())
this._commandLine = this._commandLine + c + " "; {
this.commandLine = this.commandLine + c + " ";
}
string commandLine = string.Format("{0} -launcher", this._commandLine.Trim()); string commandLine = string.Format("{0} -launcher", this.commandLine.Trim());
try try
{ {
Process gameProcess = new Process(); Process gameProcess = new Process();
gameProcess.StartInfo.Arguments = commandLine; gameProcess.StartInfo.Arguments = commandLine;
gameProcess.StartInfo.FileName = this._gamePath; gameProcess.StartInfo.FileName = this.gamePath;
gameProcess.StartInfo.WorkingDirectory = Path.GetDirectoryName(this._gamePath); gameProcess.StartInfo.WorkingDirectory = Path.GetDirectoryName(this.gamePath);
gameProcess.Start(); gameProcess.Start();
Application.Exit(); Application.Exit();
} }
catch(Exception ex) catch(Exception ex)
{ {
MessageBox.Show(string.Format("Failed to launch game process at: {0}. {1}", this._gamePath, ex.Message), MessageBox.Show(string.Format("Failed to launch game process at: {0}. {1}", this.gamePath, ex.Message),
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error); "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
} }
private void btnOptions_Click(object sender, EventArgs e) private void btnOptions_Click(object sender, EventArgs e)
{ {
OptionsForm form = new OptionsForm(GAME_NAME + " Options", this._gamePath); OptionsForm form = new OptionsForm(GAME_NAME + " Options", this.gamePath);
//form.MdiParent = this;
form.ShowDialog(); form.ShowDialog();
} }
private void LauncherForm_Load(object sender, EventArgs e) private async void LauncherForm_Load(object sender, EventArgs e)
{ {
// Find the game executable, first looking for it relative to our current directory and then // Find the game executable, first looking for it relative to our current directory and then
// using the registry path if that fails. // using the registry path if that fails.
this._gamePath = Path.GetDirectoryName(Application.ExecutablePath) + "\\" + GAME_PATH; this.gamePath = Path.GetDirectoryName(Application.ExecutablePath) + "\\" + GAME_PATH;
if (!File.Exists(this._gamePath)) if (!File.Exists(this.gamePath))
{ {
this._gamePath = (string)Registry.GetValue(REGISTRY_KEY, REGISTRY_VALUE, null); this.gamePath = (string)Registry.GetValue(REGISTRY_KEY, REGISTRY_VALUE, null);
if (this._gamePath != null) if (this.gamePath != null)
this._gamePath = Path.Combine(this._gamePath, GAME_PATH); this.gamePath = Path.Combine(this.gamePath, GAME_PATH);
if (this._gamePath == null || !File.Exists(this._gamePath)) if (this.gamePath == null || !File.Exists(this.gamePath))
{ {
string message = string.Format(Resources.AppNotFound, GAME_NAME); string message = string.Format(Resources.AppNotFound, GAME_NAME);
MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
@ -94,7 +102,7 @@ namespace Giants.Launcher
try try
{ {
FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(this._gamePath); FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(this.gamePath);
gameVersion = new Version(fvi.FileVersion.Replace(',', '.')); gameVersion = new Version(fvi.FileVersion.Replace(',', '.'));
} }
finally finally
@ -108,13 +116,47 @@ namespace Giants.Launcher
} }
// Read game settings from registry // Read game settings from registry
GameSettings.Load(this._gamePath); GameSettings.Load(this.gamePath);
if ((int)GameSettings.Get("NoAutoUpdate") == 0) if ((int)GameSettings.Get("NoAutoUpdate") == 0)
{ {
// Check for updates // Check for updates
this._Updater = new Updater(new Uri(UPDATE_URL), gameVersion); this.updater = new Updater(
this._Updater.DownloadUpdateInfo(this.LauncherForm_DownloadCompletedCallback, this.LauncherForm_DownloadProgressCallback); appVersion: gameVersion,
updateCompletedCallback: this.LauncherForm_DownloadCompletedCallback,
updateProgressCallback: this.LauncherForm_DownloadProgressCallback);
Task<VersionInfo> gameVersionInfo = this.GetVersionInfo("Giants");
Task<VersionInfo> launcherVersionInfo = this.GetVersionInfo("GiantsLauncher");
await Task.WhenAll(gameVersionInfo, launcherVersionInfo);
await this.updater.UpdateApplication(ApplicationType.Game, gameVersionInfo.Result);
await this.updater.UpdateApplication(ApplicationType.Launcher, launcherVersionInfo.Result);
}
}
private async Task<VersionInfo> GetVersionInfo(string appName)
{
VersionInfo versionInfo;
try
{
versionInfo = await this.httpClient.GetVersionInfoAsync(appName);
return versionInfo;
}
catch (ApiException ex)
{
#if DEBUG
MessageBox.Show($"Exception retrieving version information: {ex.StatusCode}");
#endif
return null;
}
catch (Exception ex)
{
#if DEBUG
MessageBox.Show($"Exception retrieving version information: {ex.Message}");
#endif
return null;
} }
} }
@ -143,7 +185,9 @@ namespace Giants.Launcher
private void LauncherForm_DownloadCompletedCallback(object sender, AsyncCompletedEventArgs e) private void LauncherForm_DownloadCompletedCallback(object sender, AsyncCompletedEventArgs e)
{ {
if (e.Cancelled) if (e.Cancelled)
{
return; return;
}
this.updateProgressBar.Value = 0; this.updateProgressBar.Value = 0;
this.updateProgressBar.Visible = false; this.updateProgressBar.Visible = false;
@ -164,15 +208,15 @@ namespace Giants.Launcher
// Start the installer process // Start the installer process
Process updaterProcess = new Process(); Process updaterProcess = new Process();
updaterProcess.StartInfo.FileName = Path.Combine(Path.GetTempPath(), updateInfo.FileName); updaterProcess.StartInfo.FileName = updateInfo.FilePath;
updaterProcess.StartInfo.WorkingDirectory = Directory.GetCurrentDirectory(); updaterProcess.StartInfo.WorkingDirectory = Directory.GetCurrentDirectory();
if (updateInfo.UpdateType == UpdateType.Game) if (updateInfo.ApplicationType == ApplicationType.Game)
{ {
// Default installation directory to current directory // Default installation directory to current directory
updaterProcess.StartInfo.Arguments = string.Format("/D {0}", Path.GetDirectoryName(Application.ExecutablePath)); updaterProcess.StartInfo.Arguments = string.Format("/D {0}", Path.GetDirectoryName(Application.ExecutablePath));
} }
else if (updateInfo.UpdateType == UpdateType.Launcher) else if (updateInfo.ApplicationType == ApplicationType.Launcher)
{ {
// Default installation directory to current directory and launch a silent install // Default installation directory to current directory and launch a silent install
updaterProcess.StartInfo.Arguments = string.Format("/S /D {0}", Path.GetDirectoryName(Application.ExecutablePath)); updaterProcess.StartInfo.Arguments = string.Format("/S /D {0}", Path.GetDirectoryName(Application.ExecutablePath));

View File

@ -1,6 +1,6 @@
namespace Giants.Launcher namespace Giants.Launcher
{ {
public enum UpdateType public enum ApplicationType
{ {
Launcher, Launcher,
Game, Game,

View File

@ -5,24 +5,8 @@ namespace Giants.Launcher
{ {
public class UpdateInfo public class UpdateInfo
{ {
public Version VersionFrom { get; set; }
public Version VersionTo { get; set; }
public Uri DownloadUri
{
get
{
return this.downloadUri;
}
set
{
this.downloadUri = value;
this.FileName = Path.GetFileName(value.AbsoluteUri);
}
}
public int FileSize { get; set; } public int FileSize { get; set; }
public string FileName { get; set; } public string FilePath { get; set; }
public UpdateType UpdateType { get; set; } public ApplicationType ApplicationType { get; set; }
private Uri downloadUri;
} }
} }

View File

@ -1,37 +1,43 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.IO; using System.IO;
using System.Linq;
using System.Net; using System.Net;
using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using System.Xml.Linq; using Giants.WebApi.Clients;
namespace Giants.Launcher namespace Giants.Launcher
{ {
public class Updater public class Updater
{ {
private readonly Uri updateUri;
private readonly Version appVersion; private readonly Version appVersion;
private AsyncCompletedEventHandler updateCompletedCallback; private readonly AsyncCompletedEventHandler updateCompletedCallback;
private DownloadProgressChangedEventHandler updateProgressCallback; private readonly DownloadProgressChangedEventHandler updateProgressCallback;
public Updater(Uri updateUri, Version appVersion) public Updater(
Version appVersion,
AsyncCompletedEventHandler updateCompletedCallback,
DownloadProgressChangedEventHandler updateProgressCallback)
{ {
this.updateUri = updateUri;
this.appVersion = appVersion; this.appVersion = appVersion;
this.updateCompletedCallback = updateCompletedCallback;
this.updateProgressCallback = updateProgressCallback;
} }
public void DownloadUpdateInfo(AsyncCompletedEventHandler downloadCompleteCallback, DownloadProgressChangedEventHandler downloadProgressCallback)
public Task UpdateApplication(ApplicationType applicationType, VersionInfo versionInfo)
{ {
WebClient client = new WebClient(); try
{
if (this.ToVersion(versionInfo.Version) > this.appVersion)
{
this.StartApplicationUpdate(applicationType, versionInfo);
}
}
catch (Exception)
{
}
// Keep track of our progress callbacks return Task.CompletedTask;
this.updateCompletedCallback = downloadCompleteCallback;
this.updateProgressCallback = downloadProgressCallback;
// Download update info XML
client.Proxy = null;
client.DownloadDataCompleted += new DownloadDataCompletedEventHandler(this.DownloadDataCallback);
client.DownloadDataAsync(this.updateUri);
} }
private int GetHttpFileSize(Uri uri) private int GetHttpFileSize(Uri uri)
@ -52,125 +58,53 @@ namespace Giants.Launcher
} }
private void StartGameUpdate(XElement root, Version currentVersion) private void StartApplicationUpdate(ApplicationType applicationType, VersionInfo versionInfo)
{ {
var updates = from update in root.Elements("Update")
select new UpdateInfo()
{
VersionFrom = new Version(update.Attribute("FromVersion").Value),
VersionTo = new Version(update.Attribute("ToVersion").Value),
DownloadUri = new Uri(update.Attribute("Url").Value),
UpdateType = UpdateType.Game
};
// Grab the download path for the update to our current version, otherwise fall back to the full installer
// (specially defined as FromVersion 0.0.0.0 in the XML)
UpdateInfo info = updates.FirstOrDefault(update => update.VersionFrom == currentVersion);
if (info == null)
info = updates.Single(update => update.VersionFrom == new Version("0.0.0.0"));
// Display update prompt // Display update prompt
string updateMsg = string.Format(Resources.UpdateAvailableText, info.VersionTo.ToString()); string updateMsg = applicationType == ApplicationType.Game ?
if (MessageBox.Show(updateMsg, Resources.UpdateAvailableTitle, MessageBoxButtons.YesNo) == DialogResult.No) string.Format(Resources.UpdateAvailableText, this.ToVersion(versionInfo.Version).ToString()) :
return; // User declined update string.Format(Resources.LauncherUpdateAvailableText, this.ToVersion(versionInfo.Version).ToString());
string path = Path.Combine(Path.GetTempPath(), info.FileName); if (MessageBox.Show(updateMsg, Resources.UpdateAvailableTitle, MessageBoxButtons.YesNo) == DialogResult.No)
{
return; // User declined update
}
string patchFileName = Path.GetFileName(versionInfo.InstallerUri.AbsoluteUri);
string localPath = Path.Combine(Path.GetTempPath(), patchFileName);
// Delete the file locally if it already exists, just to be safe // Delete the file locally if it already exists, just to be safe
if (File.Exists(path)) if (File.Exists(localPath))
File.Delete(path); {
File.Delete(localPath);
}
info.FileSize = this.GetHttpFileSize(info.DownloadUri); int fileSize = this.GetHttpFileSize(versionInfo.InstallerUri);
if (info.FileSize == -1) if (fileSize == -1)
{ {
string errorMsg = string.Format(Resources.UpdateDownloadFailedText, "File not found on server."); string errorMsg = string.Format(Resources.UpdateDownloadFailedText, "File not found on server.");
MessageBox.Show(errorMsg, Resources.UpdateDownloadFailedTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBox.Show(errorMsg, Resources.UpdateDownloadFailedTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
return; return;
} }
var updateInfo = new UpdateInfo()
{
FilePath = localPath,
FileSize = fileSize,
ApplicationType = applicationType
};
// Download the update // Download the update
WebClient client = new WebClient() // TODO: Super old code, replace this with async HttpClient
{ WebClient client = new WebClient();
Proxy = null client.DownloadFileAsync(versionInfo.InstallerUri, localPath, updateInfo);
};
client.DownloadFileAsync(info.DownloadUri, path, info);
client.DownloadFileCompleted += this.updateCompletedCallback; client.DownloadFileCompleted += this.updateCompletedCallback;
client.DownloadProgressChanged += this.updateProgressCallback; client.DownloadProgressChanged += this.updateProgressCallback;
} }
private void StartLauncherUpdate(XElement root) private Version ToVersion(AppVersion version)
{ {
var query = from update in root.Descendants("LauncherUpdate") return new Version(version.Major, version.Minor, version.Build, version.Revision);
select new UpdateInfo()
{
VersionTo = new Version(update.Attribute("ToVersion").Value),
DownloadUri = new Uri(update.Attribute("Url").Value),
UpdateType = UpdateType.Launcher
};
UpdateInfo info = query.FirstOrDefault();
// Display update prompt
string updateMsg = string.Format(Resources.LauncherUpdateAvailableText, info.VersionTo.ToString());
if (MessageBox.Show(updateMsg, Resources.UpdateAvailableTitle, MessageBoxButtons.YesNo) == DialogResult.No)
return; // User declined update
string path = Path.Combine(Path.GetTempPath(), info.FileName);
// Delete the file locally if it already exists, just to be safe
if (File.Exists(path))
File.Delete(path);
info.FileSize = this.GetHttpFileSize(info.DownloadUri);
if (info.FileSize == -1)
{
string errorMsg = string.Format(Resources.UpdateDownloadFailedText, "File not found on server.");
MessageBox.Show(errorMsg, Resources.UpdateDownloadFailedTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
// Download the update
WebClient client = new WebClient()
{
Proxy = null
};
client.DownloadFileAsync(info.DownloadUri, path, info);
client.DownloadFileCompleted += this.updateCompletedCallback;
client.DownloadProgressChanged += this.updateProgressCallback;
}
private void DownloadDataCallback(Object sender, DownloadDataCompletedEventArgs e)
{
try
{
if (!e.Cancelled && e.Error == null)
{
byte[] data = (byte[])e.Result;
string textData = System.Text.Encoding.UTF8.GetString(data);
XElement root = XElement.Parse(textData);
Version launcherVersion = new Version(root.Attribute("CurrentLauncherVersion").Value);
Version gameVersion = new Version(root.Attribute("CurrentGameVersion").Value);
Version ourVersion = new Version(Application.ProductVersion);
if (launcherVersion > ourVersion)
{
this.StartLauncherUpdate(root);
return;
}
else if (gameVersion > this.appVersion)
this.StartGameUpdate(root, this.appVersion);
}
}
catch (Exception ex)
{
#if DEBUG
MessageBox.Show(string.Format("Exception in DownloadDataCallback: {0}", ex.Message));
#endif
}
} }
} }
} }

View File

@ -4,7 +4,7 @@ namespace Giants.Services
{ {
public class VersionInfo : DataContract.VersionInfo, IIdentifiable public class VersionInfo : DataContract.VersionInfo, IIdentifiable
{ {
public string id => GenerateId(this.GameName); public string id => GenerateId(this.AppName);
public string DocumentType => nameof(VersionInfo); public string DocumentType => nameof(VersionInfo);

View File

@ -11,11 +11,11 @@ namespace Giants.Services
this.updaterStore = updaterStore; this.updaterStore = updaterStore;
} }
public async Task<VersionInfo> GetVersionInfo(string gameName) public async Task<VersionInfo> GetVersionInfo(string appName)
{ {
ArgumentUtility.CheckStringForNullOrEmpty(gameName, nameof(gameName)); ArgumentUtility.CheckStringForNullOrEmpty(appName, nameof(appName));
return await this.updaterStore.GetVersionInfo(gameName); return await this.updaterStore.GetVersionInfo(appName);
} }
} }
} }

View File

@ -23,16 +23,16 @@
this.configuration = configuration; this.configuration = configuration;
} }
public async Task<VersionInfo> GetVersionInfo(string gameName) public async Task<VersionInfo> GetVersionInfo(string appName)
{ {
VersionInfo versionInfo = await this.memoryCache.GetOrCreateAsync<VersionInfo>( VersionInfo versionInfo = await this.memoryCache.GetOrCreateAsync<VersionInfo>(
key: GetCacheKey(gameName), key: GetCacheKey(appName),
factory: async (entry) => factory: async (entry) =>
{ {
entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5); entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5);
return await this.client.GetItemById<VersionInfo>( return await this.client.GetItemById<VersionInfo>(
VersionInfo.GenerateId(gameName), VersionInfo.GenerateId(appName),
nameof(VersionInfo)); nameof(VersionInfo));
}); });

View File

@ -5,7 +5,7 @@
public class FileUpdaterStore : IUpdaterStore public class FileUpdaterStore : IUpdaterStore
{ {
public Task<VersionInfo> GetVersionInfo(string gameName) public Task<VersionInfo> GetVersionInfo(string appName)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

View File

@ -4,7 +4,7 @@
public interface IUpdaterStore public interface IUpdaterStore
{ {
Task<VersionInfo> GetVersionInfo(string gameName); Task<VersionInfo> GetVersionInfo(string appName);
Task Initialize(); Task Initialize();
} }

View File

@ -48,20 +48,20 @@ namespace Giants.WebApi.Clients
partial void ProcessResponse(System.Net.Http.HttpClient client, System.Net.Http.HttpResponseMessage response); partial void ProcessResponse(System.Net.Http.HttpClient client, System.Net.Http.HttpResponseMessage response);
/// <exception cref="ApiException">A server side error occurred.</exception> /// <exception cref="ApiException">A server side error occurred.</exception>
public System.Threading.Tasks.Task<VersionInfo> GetVersionInfoAsync(string gameName) public System.Threading.Tasks.Task<VersionInfo> GetVersionInfoAsync(string appName)
{ {
return GetVersionInfoAsync(gameName, System.Threading.CancellationToken.None); return GetVersionInfoAsync(appName, System.Threading.CancellationToken.None);
} }
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <exception cref="ApiException">A server side error occurred.</exception> /// <exception cref="ApiException">A server side error occurred.</exception>
public async System.Threading.Tasks.Task<VersionInfo> GetVersionInfoAsync(string gameName, System.Threading.CancellationToken cancellationToken) public async System.Threading.Tasks.Task<VersionInfo> GetVersionInfoAsync(string appName, System.Threading.CancellationToken cancellationToken)
{ {
var urlBuilder_ = new System.Text.StringBuilder(); var urlBuilder_ = new System.Text.StringBuilder();
urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/api/Version?"); urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/api/Version?");
if (gameName != null) if (appName != null)
{ {
urlBuilder_.Append(System.Uri.EscapeDataString("gameName") + "=").Append(System.Uri.EscapeDataString(ConvertToString(gameName, System.Globalization.CultureInfo.InvariantCulture))).Append("&"); urlBuilder_.Append(System.Uri.EscapeDataString("appName") + "=").Append(System.Uri.EscapeDataString(ConvertToString(appName, System.Globalization.CultureInfo.InvariantCulture))).Append("&");
} }
urlBuilder_.Length--; urlBuilder_.Length--;
@ -550,27 +550,23 @@ namespace Giants.WebApi.Clients
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.24.0 (Newtonsoft.Json v11.0.0.0)")] [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.24.0 (Newtonsoft.Json v11.0.0.0)")]
public partial class VersionInfo public partial class VersionInfo
{ {
[Newtonsoft.Json.JsonProperty("gameName", Required = Newtonsoft.Json.Required.Always)] [Newtonsoft.Json.JsonProperty("appName", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required] [System.ComponentModel.DataAnnotations.Required]
public string GameName { get; set; } public string AppName { get; set; }
[Newtonsoft.Json.JsonProperty("gameVersion", Required = Newtonsoft.Json.Required.Always)] [Newtonsoft.Json.JsonProperty("version", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required] [System.ComponentModel.DataAnnotations.Required]
public GiantsVersion GameVersion { get; set; } = new GiantsVersion(); public AppVersion Version { get; set; } = new AppVersion();
[Newtonsoft.Json.JsonProperty("launcherVersion", Required = Newtonsoft.Json.Required.Always)] [Newtonsoft.Json.JsonProperty("installerUri", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required] [System.ComponentModel.DataAnnotations.Required]
public GiantsVersion LauncherVersion { get; set; } = new GiantsVersion(); public System.Uri InstallerUri { get; set; }
[Newtonsoft.Json.JsonProperty("patchUri", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required]
public System.Uri PatchUri { get; set; }
} }
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.24.0 (Newtonsoft.Json v11.0.0.0)")] [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.24.0 (Newtonsoft.Json v11.0.0.0)")]
public partial class GiantsVersion public partial class AppVersion
{ {
[Newtonsoft.Json.JsonProperty("build", Required = Newtonsoft.Json.Required.Always)] [Newtonsoft.Json.JsonProperty("build", Required = Newtonsoft.Json.Required.Always)]
public int Build { get; set; } public int Build { get; set; }
@ -607,7 +603,7 @@ namespace Giants.WebApi.Clients
[Newtonsoft.Json.JsonProperty("version", Required = Newtonsoft.Json.Required.Always)] [Newtonsoft.Json.JsonProperty("version", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required] [System.ComponentModel.DataAnnotations.Required]
public GiantsVersion Version { get; set; } = new GiantsVersion(); public AppVersion Version { get; set; } = new AppVersion();
[Newtonsoft.Json.JsonProperty("sessionName", Required = Newtonsoft.Json.Required.Always)] [Newtonsoft.Json.JsonProperty("sessionName", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]

View File

@ -19,7 +19,7 @@
"operationId": "Version_GetVersionInfo", "operationId": "Version_GetVersionInfo",
"parameters": [ "parameters": [
{ {
"name": "gameName", "name": "appName",
"in": "query", "in": "query",
"schema": { "schema": {
"type": "string", "type": "string",
@ -106,30 +106,26 @@
"type": "object", "type": "object",
"additionalProperties": false, "additionalProperties": false,
"required": [ "required": [
"gameName", "appName",
"gameVersion", "version",
"launcherVersion", "installerUri"
"patchUri"
], ],
"properties": { "properties": {
"gameName": { "appName": {
"type": "string", "type": "string",
"minLength": 1 "minLength": 1
}, },
"gameVersion": { "version": {
"$ref": "#/components/schemas/GiantsVersion" "$ref": "#/components/schemas/AppVersion"
}, },
"launcherVersion": { "installerUri": {
"$ref": "#/components/schemas/GiantsVersion"
},
"patchUri": {
"type": "string", "type": "string",
"format": "uri", "format": "uri",
"minLength": 1 "minLength": 1
} }
} }
}, },
"GiantsVersion": { "AppVersion": {
"type": "object", "type": "object",
"additionalProperties": false, "additionalProperties": false,
"required": [ "required": [
@ -202,7 +198,7 @@
"minLength": 0 "minLength": 0
}, },
"version": { "version": {
"$ref": "#/components/schemas/GiantsVersion" "$ref": "#/components/schemas/AppVersion"
}, },
"sessionName": { "sessionName": {
"type": "string", "type": "string",

View File

@ -22,9 +22,9 @@ namespace Giants.WebApi.Controllers
} }
[HttpGet] [HttpGet]
public async Task<DataContract.VersionInfo> GetVersionInfo(string gameName) public async Task<DataContract.VersionInfo> GetVersionInfo(string appName)
{ {
Services.VersionInfo versionInfo = await this.updaterService.GetVersionInfo(gameName); Services.VersionInfo versionInfo = await this.updaterService.GetVersionInfo(appName);
return mapper.Map<DataContract.VersionInfo>(versionInfo); return mapper.Map<DataContract.VersionInfo>(versionInfo);
} }