Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
8 changes: 8 additions & 0 deletions .github/Asset Store Tools/Api.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .github/Asset Store Tools/Api/Abstractions.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 48 additions & 0 deletions .github/Asset Store Tools/Api/Abstractions/AuthenticationBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using AssetStoreTools.Api.Responses;
using AssetStoreTools.Utility;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;

namespace AssetStoreTools.Api
{
internal abstract class AuthenticationBase : IAuthenticationType
{
protected Uri LoginUrl = ApiUtility.CreateUri(Constants.Api.AuthenticateUrl, true);
protected FormUrlEncodedContent AuthenticationContent;

protected FormUrlEncodedContent GetAuthenticationContent(params KeyValuePair<string, string>[] content)
{
var baseContent = Constants.Api.DefaultAssetStoreQuery();

try { baseContent.Add("license_hash", ApiUtility.GetLicenseHash()); } catch { ASDebug.LogWarning("Could not retrieve license hash"); }
try { baseContent.Add("hardware_hash", ApiUtility.GetHardwareHash()); } catch { ASDebug.LogWarning("Could not retrieve hardware hash"); }

foreach (var extraContent in content)
{
baseContent.Add(extraContent.Key, extraContent.Value);
}

return new FormUrlEncodedContent(baseContent);
}

protected AuthenticationResponse ParseResponse(HttpResponseMessage response)
{
try
{
response.EnsureSuccessStatusCode();
var responseString = response.Content.ReadAsStringAsync().Result;
return new AuthenticationResponse(responseString);
}
catch (HttpRequestException e)
{
return new AuthenticationResponse(response.StatusCode, e) { Success = false };
}
}

public abstract Task<AuthenticationResponse> Authenticate(IAssetStoreClient client, CancellationToken cancellationToken = default);
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions .github/Asset Store Tools/Api/Abstractions/IAssetStoreApi.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using AssetStoreTools.Api.Models;
using AssetStoreTools.Api.Responses;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace AssetStoreTools.Api
{
internal interface IAssetStoreApi
{
Task<AssetStoreToolsVersionResponse> GetLatestAssetStoreToolsVersion(CancellationToken cancellationToken = default);
Task<AuthenticationResponse> Authenticate(IAuthenticationType authenticationType, CancellationToken cancellationToken = default);
void Deauthenticate();
Task<PackagesDataResponse> GetPackages(CancellationToken cancellationToken = default);
Task<CategoryDataResponse> GetCategories(CancellationToken cancellationToken = default);
Task<PackageThumbnailResponse> GetPackageThumbnail(Package package, CancellationToken cancellationToken = default);
Task<RefreshedPackageDataResponse> RefreshPackageMetadata(Package package, CancellationToken cancellationToken = default);
Task<PackageUploadedUnityVersionDataResponse> GetPackageUploadedVersions(Package package, CancellationToken cancellationToken = default);
Task<PackageUploadResponse> UploadPackage(IPackageUploader uploader, IProgress<float> progress = null, CancellationToken cancellationToken = default);
}
}
11 changes: 11 additions & 0 deletions .github/Asset Store Tools/Api/Abstractions/IAssetStoreApi.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions .github/Asset Store Tools/Api/Abstractions/IAssetStoreClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

namespace AssetStoreTools.Api
{
internal interface IAssetStoreClient
{
void SetSessionId(string sessionId);
void ClearSessionId();

Task<HttpResponseMessage> Get(Uri uri, CancellationToken cancellationToken = default);
Task<HttpResponseMessage> Post(Uri uri, HttpContent content, CancellationToken cancellationToken = default);
Task<HttpResponseMessage> Put(Uri uri, HttpContent content, CancellationToken cancellationToken = default);
Task<HttpResponseMessage> Send(HttpRequestMessage request, CancellationToken cancellationToken = default);
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions .github/Asset Store Tools/Api/Abstractions/IAuthenticationType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using AssetStoreTools.Api.Responses;
using System.Threading;
using System.Threading.Tasks;

namespace AssetStoreTools.Api
{
internal interface IAuthenticationType
{
Task<AuthenticationResponse> Authenticate(IAssetStoreClient client, CancellationToken cancellationToken);
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions .github/Asset Store Tools/Api/Abstractions/IPackageUploader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using AssetStoreTools.Api.Responses;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace AssetStoreTools.Api
{
internal interface IPackageUploader
{
Task<PackageUploadResponse> Upload(IAssetStoreClient client, IProgress<float> progress, CancellationToken cancellationToken = default);
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

59 changes: 59 additions & 0 deletions .github/Asset Store Tools/Api/Abstractions/PackageUploaderBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using AssetStoreTools.Api.Responses;
using System;
using System.IO;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

namespace AssetStoreTools.Api
{
internal abstract class PackageUploaderBase : IPackageUploader
{
protected const int UploadChunkSizeBytes = 32768;
protected const int UploadResponseTimeoutMs = 10000;

protected abstract void ValidateSettings();
public abstract Task<PackageUploadResponse> Upload(IAssetStoreClient client, IProgress<float> progress = null, CancellationToken cancellationToken = default);

protected void EnsureSuccessResponse(HttpResponseMessage response)
{
try
{
response.EnsureSuccessStatusCode();
}
catch
{
throw new Exception(response.Content.ReadAsStringAsync().Result);
}
}

protected void WaitForUploadCompletion(Task<HttpResponseMessage> response, FileStream requestFileStream, IProgress<float> progress, CancellationToken cancellationToken)
{
// Progress tracking
int updateIntervalMs = 100;
bool allBytesSent = false;
DateTime timeOfCompletion = default;

while (!response.IsCompleted)
{
float uploadProgress = (float)requestFileStream.Position / requestFileStream.Length * 100;
progress?.Report(uploadProgress);
Thread.Sleep(updateIntervalMs);

// A timeout for rare cases, when package uploading reaches 100%, but Put task IsComplete value remains 'False'
if (requestFileStream.Position == requestFileStream.Length)
{
if (!allBytesSent)
{
allBytesSent = true;
timeOfCompletion = DateTime.UtcNow;
}
else if (DateTime.UtcNow.Subtract(timeOfCompletion).TotalMilliseconds > UploadResponseTimeoutMs)
{
throw new TimeoutException();
}
}
}
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

76 changes: 76 additions & 0 deletions .github/Asset Store Tools/Api/ApiUtility.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using AssetStoreTools.Api.Models;
using AssetStoreTools.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditorInternal;

namespace AssetStoreTools.Api
{
internal class ApiUtility
{
public static Uri CreateUri(string url, bool includeDefaultAssetStoreQuery) => CreateUri(url, null, includeDefaultAssetStoreQuery);
public static Uri CreateUri(string url, IDictionary<string, string> queryParameters, bool includeDefaultAssetStoreQuery)
{
IDictionary<string, string> fullQueryParameters = includeDefaultAssetStoreQuery ?
Constants.Api.DefaultAssetStoreQuery() : new Dictionary<string, string>();

if (queryParameters != null && queryParameters.Count > 0)
{
foreach (var kvp in queryParameters)
fullQueryParameters.Add(kvp);
}

var builder = new UriBuilder(url);
if (fullQueryParameters.Count == 0)
return builder.Uri;

var fullQueryParameterString = string.Empty;
foreach (var queryParam in fullQueryParameters)
{
var escapedValue = queryParam.Value != null ? Uri.EscapeDataString(queryParam.Value) : string.Empty;
fullQueryParameterString += $"{queryParam.Key}={escapedValue}&";
}
fullQueryParameterString = fullQueryParameterString.Remove(fullQueryParameterString.Length - 1);

builder.Query = fullQueryParameterString;
return builder.Uri;
}

public static List<Package> CombinePackageData(List<Package> mainPackageData, List<PackageAdditionalData> extraPackageData, List<Category> categoryData)
{
foreach (var package in mainPackageData)
{
var extraData = extraPackageData.FirstOrDefault(x => package.PackageId == x.PackageId);

if (extraData == null)
{
ASDebug.LogWarning($"Could not find extra data for Package {package.PackageId}");
continue;
}

var categoryId = extraData.CategoryId;
var category = categoryData.FirstOrDefault(x => x.Id.ToString() == categoryId);
if (category != null)
package.Category = category.Name;
else
package.Category = "Unknown";

package.Modified = extraData.Modified;
package.Size = extraData.Size;
}

return mainPackageData;
}

public static string GetLicenseHash()
{
return InternalEditorUtility.GetAuthToken().Substring(0, 40);
}

public static string GetHardwareHash()
{
return InternalEditorUtility.GetAuthToken().Substring(40, 40);
}
}
}
11 changes: 11 additions & 0 deletions .github/Asset Store Tools/Api/ApiUtility.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading