Add Discord link to launcher.

This commit is contained in:
Nick Blakely 2020-08-16 02:52:58 -07:00
parent 7c51747a26
commit bb376e1f63
7 changed files with 689 additions and 369 deletions

View File

@ -34,6 +34,7 @@
this.btnPlay = new Giants.Launcher.ImageButton();
this.updateProgressBar = new System.Windows.Forms.ProgressBar();
this.txtProgress = new System.Windows.Forms.Label();
this.DiscordLabel = new System.Windows.Forms.LinkLabel();
((System.ComponentModel.ISupportInitialize)(this.btnExit)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.btnOptions)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.btnPlay)).BeginInit();
@ -107,6 +108,20 @@
this.txtProgress.Text = "ProgressText";
this.txtProgress.Visible = false;
//
// DiscordLabel
//
this.DiscordLabel.AutoSize = true;
this.DiscordLabel.BackColor = System.Drawing.Color.Transparent;
this.DiscordLabel.LinkColor = System.Drawing.Color.Aquamarine;
this.DiscordLabel.Location = new System.Drawing.Point(12, 9);
this.DiscordLabel.Name = "DiscordLabel";
this.DiscordLabel.Size = new System.Drawing.Size(69, 13);
this.DiscordLabel.TabIndex = 12;
this.DiscordLabel.TabStop = true;
this.DiscordLabel.Text = "DiscordLabel";
this.DiscordLabel.Visible = false;
this.DiscordLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.DiscordLabel_LinkClicked);
//
// LauncherForm
//
this.AcceptButton = this.btnPlay;
@ -116,6 +131,7 @@
this.CancelButton = this.btnExit;
this.ClientSize = new System.Drawing.Size(800, 500);
this.ControlBox = false;
this.Controls.Add(this.DiscordLabel);
this.Controls.Add(this.txtProgress);
this.Controls.Add(this.updateProgressBar);
this.Controls.Add(this.btnExit);
@ -145,6 +161,7 @@
private ImageButton btnExit;
private System.Windows.Forms.ProgressBar updateProgressBar;
private System.Windows.Forms.Label txtProgress;
private System.Windows.Forms.LinkLabel DiscordLabel;
}
}

View File

@ -16,25 +16,34 @@ namespace Giants.Launcher
public partial class LauncherForm : Form
{
// Constant settings
private const string GAME_NAME = "Giants: Citizen Kabuto";
private const string GAME_PATH = "GiantsMain.exe";
private const string REGISTRY_KEY = @"HKEY_CURRENT_USER\Software\PlanetMoon\Giants";
private const string REGISTRY_VALUE = "DestDir";
private readonly VersionClient httpClient;
private const string GameName = "Giants: Citizen Kabuto";
private const string GamePath = "GiantsMain.exe";
private const string RegistryKey = @"HKEY_CURRENT_USER\Software\PlanetMoon\Giants";
private const string RegistryValue = "DestDir";
private const string BaseUrl = "https://giants.azurewebsites.net"; // TODO: Read from file
private readonly HttpClient httpClient;
private readonly VersionClient versionHttpClient;
private readonly DiscordClient discordHttpClient;
private string commandLine = String.Empty;
private string gamePath = null;
private Updater updater;
private string discordUri;
public LauncherForm()
{
this.InitializeComponent();
// Set window title
this.Text = GAME_NAME;
this.Text = GameName;
this.httpClient = new VersionClient(new HttpClient());
this.httpClient.BaseUrl = "https://giants.azurewebsites.net"; // TODO: Read from file
this.httpClient = new HttpClient();
this.versionHttpClient = new VersionClient(this.httpClient);
this.versionHttpClient.BaseUrl = BaseUrl;
this.discordHttpClient = new DiscordClient(this.httpClient);
this.discordHttpClient.BaseUrl = BaseUrl;
}
private void btnExit_Click(object sender, EventArgs e)
@ -73,7 +82,7 @@ namespace Giants.Launcher
private void btnOptions_Click(object sender, EventArgs e)
{
OptionsForm form = new OptionsForm(GAME_NAME + " Options", this.gamePath);
OptionsForm form = new OptionsForm(GameName + " Options", this.gamePath);
form.ShowDialog();
}
@ -82,16 +91,16 @@ namespace Giants.Launcher
{
// Find the game executable, first looking for it relative to our current directory and then
// using the registry path if that fails.
this.gamePath = Path.GetDirectoryName(Application.ExecutablePath) + "\\" + GAME_PATH;
this.gamePath = Path.GetDirectoryName(Application.ExecutablePath) + "\\" + GamePath;
if (!File.Exists(this.gamePath))
{
this.gamePath = (string)Registry.GetValue(REGISTRY_KEY, REGISTRY_VALUE, null);
this.gamePath = (string)Registry.GetValue(RegistryKey, RegistryValue, null);
if (this.gamePath != null)
this.gamePath = Path.Combine(this.gamePath, GAME_PATH);
this.gamePath = Path.Combine(this.gamePath, GamePath);
if (this.gamePath == null || !File.Exists(this.gamePath))
{
string message = string.Format(Resources.AppNotFound, GAME_NAME);
string message = string.Format(Resources.AppNotFound, GameName);
MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
Application.Exit();
return;
@ -102,43 +111,68 @@ namespace Giants.Launcher
GameSettings.Load(this.gamePath);
if (GameSettings.Get<int>("NoAutoUpdate") == 0)
{
Version gameVersion = VersionHelper.GetGameVersion(this.gamePath);
if (gameVersion == null)
{
string message = string.Format(Resources.AppNotFound, GAME_NAME);
MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
Application.Exit();
}
{
Version gameVersion = VersionHelper.GetGameVersion(this.gamePath);
if (gameVersion == null)
{
string message = string.Format(Resources.AppNotFound, GameName);
MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
Application.Exit();
}
var appVersions = new Dictionary<ApplicationType, Version>()
{
[ApplicationType.Game] = gameVersion,
[ApplicationType.Launcher] = VersionHelper.GetLauncherVersion()
};
var appVersions = new Dictionary<ApplicationType, Version>()
{
[ApplicationType.Game] = gameVersion,
[ApplicationType.Launcher] = VersionHelper.GetLauncherVersion()
};
// Check for updates
this.updater = new Updater(
appVersions: appVersions,
updateCompletedCallback: this.LauncherForm_DownloadCompletedCallback,
updateProgressCallback: this.LauncherForm_DownloadProgressCallback);
// Check for updates
Task updateTask = this.CheckForUpdates(appVersions);
Task discordTask = this.CheckDiscordStatus();
Task<VersionInfo> gameVersionInfo = this.GetVersionInfo(ApplicationNames.Giants);
Task<VersionInfo> launcherVersionInfo = this.GetVersionInfo(ApplicationNames.GiantsLauncher);
await Task.WhenAll(gameVersionInfo, launcherVersionInfo);
await this.updater.UpdateApplication(ApplicationType.Game, gameVersionInfo.Result);
await this.updater.UpdateApplication(ApplicationType.Launcher, launcherVersionInfo.Result);
}
await Task.WhenAll(updateTask, discordTask);
}
}
private async Task<VersionInfo> GetVersionInfo(string appName)
private async Task CheckDiscordStatus()
{
try
{
var status = await this.discordHttpClient.GetDiscordStatusAsync();
this.discordUri = status.DiscordUri;
this.DiscordLabel.Text = Resources.DiscordLabel;
this.DiscordLabel.Visible = true;
}
catch (Exception)
{
// Ignore
}
}
private async Task CheckForUpdates(Dictionary<ApplicationType, Version> appVersions)
{
this.updater = new Updater(
appVersions: appVersions,
updateCompletedCallback: this.LauncherForm_DownloadCompletedCallback,
updateProgressCallback: this.LauncherForm_DownloadProgressCallback);
Task<VersionInfo> gameVersionInfo = this.GetVersionInfo(ApplicationNames.Giants);
Task<VersionInfo> launcherVersionInfo = this.GetVersionInfo(ApplicationNames.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);
versionInfo = await this.versionHttpClient.GetVersionInfoAsync(appName);
return versionInfo;
}
catch (ApiException ex)
@ -236,5 +270,22 @@ namespace Giants.Launcher
this.txtProgress.Visible = true;
this.txtProgress.Text = string.Format(Resources.DownloadProgress, e.ProgressPercentage, info.FileSize / 1024 / 1024);
}
}
private void DiscordLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
if (string.IsNullOrEmpty(this.discordUri))
{
return;
}
var uri = new Uri(this.discordUri);
if (uri.Scheme != "https")
{
// For security, reject any non-HTTPS or local file system URIs
return;
}
Process.Start(this.discordUri);
}
}
}

View File

@ -112,12 +112,12 @@
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="btnPlay.NormalImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAAEYAAAAnCAYAAACyhj57AAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6

View File

@ -79,6 +79,15 @@ namespace Giants.Launcher {
}
}
/// <summary>
/// Looks up a localized string similar to Join the community on Discord!.
/// </summary>
internal static string DiscordLabel {
get {
return ResourceManager.GetString("DiscordLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Downloading - {0}% of {1} MB.
/// </summary>

View File

@ -199,4 +199,7 @@
<data name="OptionSamples" xml:space="preserve">
<value>{0} Samples</value>
</data>
<data name="DiscordLabel" xml:space="preserve">
<value>Join the community on Discord!</value>
</data>
</root>

View File

@ -14,212 +14,6 @@ namespace Giants.WebApi.Clients
{
using System = global::System;
[System.CodeDom.Compiler.GeneratedCode("NSwag", "13.7.0.0 (NJsonSchema v10.1.24.0 (Newtonsoft.Json v11.0.0.0))")]
public partial class VersionClient
{
private string _baseUrl = "https://localhost:44304";
private System.Net.Http.HttpClient _httpClient;
private System.Lazy<Newtonsoft.Json.JsonSerializerSettings> _settings;
public VersionClient(System.Net.Http.HttpClient httpClient)
{
_httpClient = httpClient;
_settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>(CreateSerializerSettings);
}
private Newtonsoft.Json.JsonSerializerSettings CreateSerializerSettings()
{
var settings = new Newtonsoft.Json.JsonSerializerSettings();
UpdateJsonSerializerSettings(settings);
return settings;
}
public string BaseUrl
{
get { return _baseUrl; }
set { _baseUrl = value; }
}
protected Newtonsoft.Json.JsonSerializerSettings JsonSerializerSettings { get { return _settings.Value; } }
partial void UpdateJsonSerializerSettings(Newtonsoft.Json.JsonSerializerSettings settings);
partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, string url);
partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, System.Text.StringBuilder urlBuilder);
partial void ProcessResponse(System.Net.Http.HttpClient client, System.Net.Http.HttpResponseMessage response);
/// <exception cref="ApiException">A server side error occurred.</exception>
public System.Threading.Tasks.Task<VersionInfo> GetVersionInfoAsync(string appName)
{
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>
/// <exception cref="ApiException">A server side error occurred.</exception>
public async System.Threading.Tasks.Task<VersionInfo> GetVersionInfoAsync(string appName, System.Threading.CancellationToken cancellationToken)
{
var urlBuilder_ = new System.Text.StringBuilder();
urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/api/Version?");
if (appName != null)
{
urlBuilder_.Append(System.Uri.EscapeDataString("appName") + "=").Append(System.Uri.EscapeDataString(ConvertToString(appName, System.Globalization.CultureInfo.InvariantCulture))).Append("&");
}
urlBuilder_.Length--;
var client_ = _httpClient;
try
{
using (var request_ = new System.Net.Http.HttpRequestMessage())
{
request_.Method = new System.Net.Http.HttpMethod("GET");
request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
PrepareRequest(client_, request_, urlBuilder_);
var url_ = urlBuilder_.ToString();
request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
PrepareRequest(client_, request_, url_);
var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
try
{
var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.Content.Headers != null)
{
foreach (var item_ in response_.Content.Headers)
headers_[item_.Key] = item_.Value;
}
ProcessResponse(client_, response_);
var status_ = (int)response_.StatusCode;
if (status_ == 200)
{
var objectResponse_ = await ReadObjectResponseAsync<VersionInfo>(response_, headers_).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
}
return objectResponse_.Object;
}
else
{
var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (response_ != null)
response_.Dispose();
}
}
}
finally
{
}
}
protected struct ObjectResponseResult<T>
{
public ObjectResponseResult(T responseObject, string responseText)
{
this.Object = responseObject;
this.Text = responseText;
}
public T Object { get; }
public string Text { get; }
}
public bool ReadResponseAsString { get; set; }
protected virtual async System.Threading.Tasks.Task<ObjectResponseResult<T>> ReadObjectResponseAsync<T>(System.Net.Http.HttpResponseMessage response, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers)
{
if (response == null || response.Content == null)
{
return new ObjectResponseResult<T>(default(T), string.Empty);
}
if (ReadResponseAsString)
{
var responseText = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
try
{
var typedBody = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(responseText, JsonSerializerSettings);
return new ObjectResponseResult<T>(typedBody, responseText);
}
catch (Newtonsoft.Json.JsonException exception)
{
var message = "Could not deserialize the response body string as " + typeof(T).FullName + ".";
throw new ApiException(message, (int)response.StatusCode, responseText, headers, exception);
}
}
else
{
try
{
using (var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
using (var streamReader = new System.IO.StreamReader(responseStream))
using (var jsonTextReader = new Newtonsoft.Json.JsonTextReader(streamReader))
{
var serializer = Newtonsoft.Json.JsonSerializer.Create(JsonSerializerSettings);
var typedBody = serializer.Deserialize<T>(jsonTextReader);
return new ObjectResponseResult<T>(typedBody, string.Empty);
}
}
catch (Newtonsoft.Json.JsonException exception)
{
var message = "Could not deserialize the response body stream as " + typeof(T).FullName + ".";
throw new ApiException(message, (int)response.StatusCode, string.Empty, headers, exception);
}
}
}
private string ConvertToString(object value, System.Globalization.CultureInfo cultureInfo)
{
if (value == null)
{
return null;
}
if (value is System.Enum)
{
var name = System.Enum.GetName(value.GetType(), value);
if (name != null)
{
var field = System.Reflection.IntrospectionExtensions.GetTypeInfo(value.GetType()).GetDeclaredField(name);
if (field != null)
{
var attribute = System.Reflection.CustomAttributeExtensions.GetCustomAttribute(field, typeof(System.Runtime.Serialization.EnumMemberAttribute))
as System.Runtime.Serialization.EnumMemberAttribute;
if (attribute != null)
{
return attribute.Value != null ? attribute.Value : name;
}
}
return System.Convert.ToString(System.Convert.ChangeType(value, System.Enum.GetUnderlyingType(value.GetType()), cultureInfo));
}
}
else if (value is bool)
{
return System.Convert.ToString((bool)value, cultureInfo).ToLowerInvariant();
}
else if (value is byte[])
{
return System.Convert.ToBase64String((byte[]) value);
}
else if (value.GetType().IsArray)
{
var array = System.Linq.Enumerable.OfType<object>((System.Array) value);
return string.Join(",", System.Linq.Enumerable.Select(array, o => ConvertToString(o, cultureInfo)));
}
var result = System.Convert.ToString(value, cultureInfo);
return (result is null) ? string.Empty : result;
}
}
[System.CodeDom.Compiler.GeneratedCode("NSwag", "13.7.0.0 (NJsonSchema v10.1.24.0 (Newtonsoft.Json v11.0.0.0))")]
public partial class ServersClient
{
@ -546,43 +340,414 @@ namespace Giants.WebApi.Clients
return (result is null) ? string.Empty : result;
}
}
[System.CodeDom.Compiler.GeneratedCode("NSwag", "13.7.0.0 (NJsonSchema v10.1.24.0 (Newtonsoft.Json v11.0.0.0))")]
public partial class DiscordClient
{
private string _baseUrl = "https://localhost:44304";
private System.Net.Http.HttpClient _httpClient;
private System.Lazy<Newtonsoft.Json.JsonSerializerSettings> _settings;
public DiscordClient(System.Net.Http.HttpClient httpClient)
{
_httpClient = httpClient;
_settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>(CreateSerializerSettings);
}
private Newtonsoft.Json.JsonSerializerSettings CreateSerializerSettings()
{
var settings = new Newtonsoft.Json.JsonSerializerSettings();
UpdateJsonSerializerSettings(settings);
return settings;
}
public string BaseUrl
{
get { return _baseUrl; }
set { _baseUrl = value; }
}
protected Newtonsoft.Json.JsonSerializerSettings JsonSerializerSettings { get { return _settings.Value; } }
partial void UpdateJsonSerializerSettings(Newtonsoft.Json.JsonSerializerSettings settings);
partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, string url);
partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, System.Text.StringBuilder urlBuilder);
partial void ProcessResponse(System.Net.Http.HttpClient client, System.Net.Http.HttpResponseMessage response);
/// <exception cref="ApiException">A server side error occurred.</exception>
public System.Threading.Tasks.Task<DiscordStatus> GetDiscordStatusAsync()
{
return GetDiscordStatusAsync(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>
/// <exception cref="ApiException">A server side error occurred.</exception>
public async System.Threading.Tasks.Task<DiscordStatus> GetDiscordStatusAsync(System.Threading.CancellationToken cancellationToken)
{
var urlBuilder_ = new System.Text.StringBuilder();
urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/api/Discord");
var client_ = _httpClient;
try
{
using (var request_ = new System.Net.Http.HttpRequestMessage())
{
request_.Method = new System.Net.Http.HttpMethod("GET");
request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
PrepareRequest(client_, request_, urlBuilder_);
var url_ = urlBuilder_.ToString();
request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
PrepareRequest(client_, request_, url_);
var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
try
{
var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.Content.Headers != null)
{
foreach (var item_ in response_.Content.Headers)
headers_[item_.Key] = item_.Value;
}
ProcessResponse(client_, response_);
var status_ = (int)response_.StatusCode;
if (status_ == 200)
{
var objectResponse_ = await ReadObjectResponseAsync<DiscordStatus>(response_, headers_).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
}
return objectResponse_.Object;
}
else
{
var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (response_ != null)
response_.Dispose();
}
}
}
finally
{
}
}
protected struct ObjectResponseResult<T>
{
public ObjectResponseResult(T responseObject, string responseText)
{
this.Object = responseObject;
this.Text = responseText;
}
public T Object { get; }
public string Text { get; }
}
public bool ReadResponseAsString { get; set; }
protected virtual async System.Threading.Tasks.Task<ObjectResponseResult<T>> ReadObjectResponseAsync<T>(System.Net.Http.HttpResponseMessage response, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers)
{
if (response == null || response.Content == null)
{
return new ObjectResponseResult<T>(default(T), string.Empty);
}
if (ReadResponseAsString)
{
var responseText = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
try
{
var typedBody = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(responseText, JsonSerializerSettings);
return new ObjectResponseResult<T>(typedBody, responseText);
}
catch (Newtonsoft.Json.JsonException exception)
{
var message = "Could not deserialize the response body string as " + typeof(T).FullName + ".";
throw new ApiException(message, (int)response.StatusCode, responseText, headers, exception);
}
}
else
{
try
{
using (var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
using (var streamReader = new System.IO.StreamReader(responseStream))
using (var jsonTextReader = new Newtonsoft.Json.JsonTextReader(streamReader))
{
var serializer = Newtonsoft.Json.JsonSerializer.Create(JsonSerializerSettings);
var typedBody = serializer.Deserialize<T>(jsonTextReader);
return new ObjectResponseResult<T>(typedBody, string.Empty);
}
}
catch (Newtonsoft.Json.JsonException exception)
{
var message = "Could not deserialize the response body stream as " + typeof(T).FullName + ".";
throw new ApiException(message, (int)response.StatusCode, string.Empty, headers, exception);
}
}
}
private string ConvertToString(object value, System.Globalization.CultureInfo cultureInfo)
{
if (value == null)
{
return null;
}
if (value is System.Enum)
{
var name = System.Enum.GetName(value.GetType(), value);
if (name != null)
{
var field = System.Reflection.IntrospectionExtensions.GetTypeInfo(value.GetType()).GetDeclaredField(name);
if (field != null)
{
var attribute = System.Reflection.CustomAttributeExtensions.GetCustomAttribute(field, typeof(System.Runtime.Serialization.EnumMemberAttribute))
as System.Runtime.Serialization.EnumMemberAttribute;
if (attribute != null)
{
return attribute.Value != null ? attribute.Value : name;
}
}
return System.Convert.ToString(System.Convert.ChangeType(value, System.Enum.GetUnderlyingType(value.GetType()), cultureInfo));
}
}
else if (value is bool)
{
return System.Convert.ToString((bool)value, cultureInfo).ToLowerInvariant();
}
else if (value is byte[])
{
return System.Convert.ToBase64String((byte[]) value);
}
else if (value.GetType().IsArray)
{
var array = System.Linq.Enumerable.OfType<object>((System.Array) value);
return string.Join(",", System.Linq.Enumerable.Select(array, o => ConvertToString(o, cultureInfo)));
}
var result = System.Convert.ToString(value, cultureInfo);
return (result is null) ? string.Empty : result;
}
}
[System.CodeDom.Compiler.GeneratedCode("NSwag", "13.7.0.0 (NJsonSchema v10.1.24.0 (Newtonsoft.Json v11.0.0.0))")]
public partial class VersionClient
{
private string _baseUrl = "https://localhost:44304";
private System.Net.Http.HttpClient _httpClient;
private System.Lazy<Newtonsoft.Json.JsonSerializerSettings> _settings;
public VersionClient(System.Net.Http.HttpClient httpClient)
{
_httpClient = httpClient;
_settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>(CreateSerializerSettings);
}
private Newtonsoft.Json.JsonSerializerSettings CreateSerializerSettings()
{
var settings = new Newtonsoft.Json.JsonSerializerSettings();
UpdateJsonSerializerSettings(settings);
return settings;
}
public string BaseUrl
{
get { return _baseUrl; }
set { _baseUrl = value; }
}
protected Newtonsoft.Json.JsonSerializerSettings JsonSerializerSettings { get { return _settings.Value; } }
partial void UpdateJsonSerializerSettings(Newtonsoft.Json.JsonSerializerSettings settings);
partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, string url);
partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, System.Text.StringBuilder urlBuilder);
partial void ProcessResponse(System.Net.Http.HttpClient client, System.Net.Http.HttpResponseMessage response);
/// <exception cref="ApiException">A server side error occurred.</exception>
public System.Threading.Tasks.Task<VersionInfo> GetVersionInfoAsync(string appName)
{
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>
/// <exception cref="ApiException">A server side error occurred.</exception>
public async System.Threading.Tasks.Task<VersionInfo> GetVersionInfoAsync(string appName, System.Threading.CancellationToken cancellationToken)
{
var urlBuilder_ = new System.Text.StringBuilder();
urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/api/Version?");
if (appName != null)
{
urlBuilder_.Append(System.Uri.EscapeDataString("appName") + "=").Append(System.Uri.EscapeDataString(ConvertToString(appName, System.Globalization.CultureInfo.InvariantCulture))).Append("&");
}
urlBuilder_.Length--;
var client_ = _httpClient;
try
{
using (var request_ = new System.Net.Http.HttpRequestMessage())
{
request_.Method = new System.Net.Http.HttpMethod("GET");
request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
PrepareRequest(client_, request_, urlBuilder_);
var url_ = urlBuilder_.ToString();
request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
PrepareRequest(client_, request_, url_);
var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
try
{
var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.Content.Headers != null)
{
foreach (var item_ in response_.Content.Headers)
headers_[item_.Key] = item_.Value;
}
ProcessResponse(client_, response_);
var status_ = (int)response_.StatusCode;
if (status_ == 200)
{
var objectResponse_ = await ReadObjectResponseAsync<VersionInfo>(response_, headers_).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
}
return objectResponse_.Object;
}
else
{
var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (response_ != null)
response_.Dispose();
}
}
}
finally
{
}
}
protected struct ObjectResponseResult<T>
{
public ObjectResponseResult(T responseObject, string responseText)
{
this.Object = responseObject;
this.Text = responseText;
}
public T Object { get; }
public string Text { get; }
}
public bool ReadResponseAsString { get; set; }
protected virtual async System.Threading.Tasks.Task<ObjectResponseResult<T>> ReadObjectResponseAsync<T>(System.Net.Http.HttpResponseMessage response, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers)
{
if (response == null || response.Content == null)
{
return new ObjectResponseResult<T>(default(T), string.Empty);
}
if (ReadResponseAsString)
{
var responseText = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
try
{
var typedBody = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(responseText, JsonSerializerSettings);
return new ObjectResponseResult<T>(typedBody, responseText);
}
catch (Newtonsoft.Json.JsonException exception)
{
var message = "Could not deserialize the response body string as " + typeof(T).FullName + ".";
throw new ApiException(message, (int)response.StatusCode, responseText, headers, exception);
}
}
else
{
try
{
using (var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
using (var streamReader = new System.IO.StreamReader(responseStream))
using (var jsonTextReader = new Newtonsoft.Json.JsonTextReader(streamReader))
{
var serializer = Newtonsoft.Json.JsonSerializer.Create(JsonSerializerSettings);
var typedBody = serializer.Deserialize<T>(jsonTextReader);
return new ObjectResponseResult<T>(typedBody, string.Empty);
}
}
catch (Newtonsoft.Json.JsonException exception)
{
var message = "Could not deserialize the response body stream as " + typeof(T).FullName + ".";
throw new ApiException(message, (int)response.StatusCode, string.Empty, headers, exception);
}
}
}
private string ConvertToString(object value, System.Globalization.CultureInfo cultureInfo)
{
if (value == null)
{
return null;
}
if (value is System.Enum)
{
var name = System.Enum.GetName(value.GetType(), value);
if (name != null)
{
var field = System.Reflection.IntrospectionExtensions.GetTypeInfo(value.GetType()).GetDeclaredField(name);
if (field != null)
{
var attribute = System.Reflection.CustomAttributeExtensions.GetCustomAttribute(field, typeof(System.Runtime.Serialization.EnumMemberAttribute))
as System.Runtime.Serialization.EnumMemberAttribute;
if (attribute != null)
{
return attribute.Value != null ? attribute.Value : name;
}
}
return System.Convert.ToString(System.Convert.ChangeType(value, System.Enum.GetUnderlyingType(value.GetType()), cultureInfo));
}
}
else if (value is bool)
{
return System.Convert.ToString((bool)value, cultureInfo).ToLowerInvariant();
}
else if (value is byte[])
{
return System.Convert.ToBase64String((byte[]) value);
}
else if (value.GetType().IsArray)
{
var array = System.Linq.Enumerable.OfType<object>((System.Array) value);
return string.Join(",", System.Linq.Enumerable.Select(array, o => ConvertToString(o, cultureInfo)));
}
var result = System.Convert.ToString(value, cultureInfo);
return (result is null) ? string.Empty : result;
}
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.24.0 (Newtonsoft.Json v11.0.0.0)")]
public partial class VersionInfo
{
[Newtonsoft.Json.JsonProperty("appName", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required]
public string AppName { get; set; }
[Newtonsoft.Json.JsonProperty("version", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required]
public AppVersion Version { get; set; } = new AppVersion();
[Newtonsoft.Json.JsonProperty("installerUri", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required]
public System.Uri InstallerUri { get; set; }
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.24.0 (Newtonsoft.Json v11.0.0.0)")]
public partial class AppVersion
{
[Newtonsoft.Json.JsonProperty("build", Required = Newtonsoft.Json.Required.Always)]
public int Build { get; set; }
[Newtonsoft.Json.JsonProperty("major", Required = Newtonsoft.Json.Required.Always)]
public int Major { get; set; }
[Newtonsoft.Json.JsonProperty("minor", Required = Newtonsoft.Json.Required.Always)]
public int Minor { get; set; }
[Newtonsoft.Json.JsonProperty("revision", Required = Newtonsoft.Json.Required.Always)]
public int Revision { get; set; }
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.24.0 (Newtonsoft.Json v11.0.0.0)")]
public partial class ServerInfoWithHostAddress : ServerInfo
{
@ -648,6 +813,24 @@ namespace Giants.WebApi.Clients
public System.Collections.Generic.ICollection<PlayerInfo> PlayerInfo { get; set; } = new System.Collections.ObjectModel.Collection<PlayerInfo>();
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.24.0 (Newtonsoft.Json v11.0.0.0)")]
public partial class AppVersion
{
[Newtonsoft.Json.JsonProperty("build", Required = Newtonsoft.Json.Required.Always)]
public int Build { get; set; }
[Newtonsoft.Json.JsonProperty("major", Required = Newtonsoft.Json.Required.Always)]
public int Major { get; set; }
[Newtonsoft.Json.JsonProperty("minor", Required = Newtonsoft.Json.Required.Always)]
public int Minor { get; set; }
[Newtonsoft.Json.JsonProperty("revision", Required = Newtonsoft.Json.Required.Always)]
public int Revision { get; set; }
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.24.0 (Newtonsoft.Json v11.0.0.0)")]
@ -671,6 +854,33 @@ namespace Giants.WebApi.Clients
public string TeamName { get; set; }
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.24.0 (Newtonsoft.Json v11.0.0.0)")]
public partial class DiscordStatus
{
[Newtonsoft.Json.JsonProperty("discordUri", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public string DiscordUri { get; set; }
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.24.0 (Newtonsoft.Json v11.0.0.0)")]
public partial class VersionInfo
{
[Newtonsoft.Json.JsonProperty("appName", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required]
public string AppName { get; set; }
[Newtonsoft.Json.JsonProperty("version", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required]
public AppVersion Version { get; set; } = new AppVersion();
[Newtonsoft.Json.JsonProperty("installerUri", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required]
public System.Uri InstallerUri { get; set; }
}
[System.CodeDom.Compiler.GeneratedCode("NSwag", "13.7.0.0 (NJsonSchema v10.1.24.0 (Newtonsoft.Json v11.0.0.0))")]

View File

@ -11,37 +11,6 @@
}
],
"paths": {
"/api/Version": {
"get": {
"tags": [
"Version"
],
"operationId": "Version_GetVersionInfo",
"parameters": [
{
"name": "appName",
"in": "query",
"schema": {
"type": "string",
"nullable": true
},
"x-position": 1
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/VersionInfo"
}
}
}
}
}
}
},
"/api/Servers": {
"delete": {
"tags": [
@ -98,61 +67,61 @@
}
}
}
},
"/api/Discord": {
"get": {
"tags": [
"Discord"
],
"operationId": "Discord_GetDiscordStatus",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DiscordStatus"
}
}
}
}
}
}
},
"/api/Version": {
"get": {
"tags": [
"Version"
],
"operationId": "Version_GetVersionInfo",
"parameters": [
{
"name": "appName",
"in": "query",
"schema": {
"type": "string",
"nullable": true
},
"x-position": 1
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/VersionInfo"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"VersionInfo": {
"type": "object",
"additionalProperties": false,
"required": [
"appName",
"version",
"installerUri"
],
"properties": {
"appName": {
"type": "string",
"minLength": 1
},
"version": {
"$ref": "#/components/schemas/AppVersion"
},
"installerUri": {
"type": "string",
"format": "uri",
"minLength": 1
}
}
},
"AppVersion": {
"type": "object",
"additionalProperties": false,
"required": [
"build",
"major",
"minor",
"revision"
],
"properties": {
"build": {
"type": "integer",
"format": "int32"
},
"major": {
"type": "integer",
"format": "int32"
},
"minor": {
"type": "integer",
"format": "int32"
},
"revision": {
"type": "integer",
"format": "int32"
}
}
},
"ServerInfoWithHostAddress": {
"allOf": [
{
@ -251,6 +220,34 @@
}
}
},
"AppVersion": {
"type": "object",
"additionalProperties": false,
"required": [
"build",
"major",
"minor",
"revision"
],
"properties": {
"build": {
"type": "integer",
"format": "int32"
},
"major": {
"type": "integer",
"format": "int32"
},
"minor": {
"type": "integer",
"format": "int32"
},
"revision": {
"type": "integer",
"format": "int32"
}
}
},
"PlayerInfo": {
"type": "object",
"additionalProperties": false,
@ -283,6 +280,39 @@
"minLength": 1
}
}
},
"DiscordStatus": {
"type": "object",
"additionalProperties": false,
"properties": {
"discordUri": {
"type": "string",
"nullable": true
}
}
},
"VersionInfo": {
"type": "object",
"additionalProperties": false,
"required": [
"appName",
"version",
"installerUri"
],
"properties": {
"appName": {
"type": "string",
"minLength": 1
},
"version": {
"$ref": "#/components/schemas/AppVersion"
},
"installerUri": {
"type": "string",
"format": "uri",
"minLength": 1
}
}
}
}
}