update libs

This commit is contained in:
Kirill Chikalin
2025-02-13 17:48:12 +03:00
parent e17e7c2786
commit 275dc598c7
816 changed files with 22479 additions and 10792 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 17f95678acdb51548908d81be7146b5b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,45 @@
using AssetStoreTools.Uploader.Services.Analytics.Data;
using UnityEditor;
using UnityEngine.Analytics;
#if !UNITY_2023_2_OR_NEWER
using AnalyticsConstants = AssetStoreTools.Constants.Uploader.Analytics;
#endif
namespace AssetStoreTools.Uploader.Services.Analytics
{
internal class AnalyticsService : IAnalyticsService
{
public AnalyticsResult Send(IAssetStoreAnalytic analytic)
{
if (!EditorAnalytics.enabled)
return AnalyticsResult.AnalyticsDisabled;
if (!Register(analytic))
return AnalyticsResult.AnalyticsDisabled;
#if UNITY_2023_2_OR_NEWER
return EditorAnalytics.SendAnalytic(analytic);
#else
return EditorAnalytics.SendEventWithLimit(analytic.EventName,
analytic.Data,
analytic.EventVersion);
#endif
}
private bool Register(IAssetStoreAnalytic analytic)
{
#if UNITY_2023_2_OR_NEWER
return true;
#else
var result = EditorAnalytics.RegisterEventWithLimit(
eventName: analytic.EventName,
maxEventPerHour: AnalyticsConstants.MaxEventsPerHour,
maxItems: AnalyticsConstants.MaxNumberOfElements,
vendorKey: AnalyticsConstants.VendorKey,
ver: analytic.EventVersion);
return result == AnalyticsResult.Ok;
#endif
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 408b5b0136da9ca4f9598b8688f6210e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 12.0.1
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/Services/Analytics/AnalyticsService.cs
uploadId: 724584

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: df1fca726619f2f4fae3bd93b0ef5a8b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,46 @@
using AssetStoreTools.Api;
using System;
#if UNITY_2023_2_OR_NEWER
using UnityEngine.Analytics;
#endif
using AnalyticsConstants = AssetStoreTools.Constants.Uploader.Analytics;
namespace AssetStoreTools.Uploader.Services.Analytics.Data
{
#if UNITY_2023_2_OR_NEWER
[AnalyticInfo
(eventName: AnalyticsConstants.AuthenticationAnalytics.EventName,
vendorKey: AnalyticsConstants.VendorKey,
version: AnalyticsConstants.AuthenticationAnalytics.EventVersion,
maxEventsPerHour: AnalyticsConstants.MaxEventsPerHour,
maxNumberOfElements: AnalyticsConstants.MaxNumberOfElements)]
#endif
internal class AuthenticationAnalytic : BaseAnalytic
{
[Serializable]
public class AuthenticationAnalyticData : BaseAnalyticData
{
public string AuthenticationType;
public string PublisherId;
}
public override string EventName => AnalyticsConstants.AuthenticationAnalytics.EventName;
public override int EventVersion => AnalyticsConstants.AuthenticationAnalytics.EventVersion;
private AuthenticationAnalyticData _data;
public AuthenticationAnalytic(IAuthenticationType authenticationType, string publisherId)
{
_data = new AuthenticationAnalyticData
{
AuthenticationType = authenticationType.GetType().Name,
PublisherId = publisherId
};
}
protected override BaseAnalyticData GetData()
{
return _data;
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 4b9389e3ee578484493d36775c75baa1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 12.0.1
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/Services/Analytics/Data/AuthenticationAnalytic.cs
uploadId: 724584

View File

@@ -0,0 +1,35 @@
using System;
#if UNITY_2023_2_OR_NEWER
using UnityEngine.Analytics;
#endif
namespace AssetStoreTools.Uploader.Services.Analytics.Data
{
internal abstract class BaseAnalytic : IAssetStoreAnalytic
{
[Serializable]
public class BaseAnalyticData : IAssetStoreAnalyticData
{
public string ToolVersion = Constants.Api.ApiVersion;
}
public abstract string EventName { get; }
public abstract int EventVersion { get; }
public IAssetStoreAnalyticData Data => GetData();
protected abstract BaseAnalyticData GetData();
#if UNITY_2023_2_OR_NEWER
public bool TryGatherData(out IAnalytic.IData data, [System.Diagnostics.CodeAnalysis.NotNullWhen(false)] out Exception error)
{
error = null;
data = Data;
if (data == null)
error = new Exception("Analytic data is null");
return error == null;
}
#endif
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 51ec1e4b6505b694ab01f7c523744fbc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 12.0.1
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/Services/Analytics/Data/BaseAnalytic.cs
uploadId: 724584

View File

@@ -0,0 +1,16 @@
#if UNITY_2023_2_OR_NEWER
using UnityEngine.Analytics;
#endif
namespace AssetStoreTools.Uploader.Services.Analytics.Data
{
internal interface IAssetStoreAnalytic
#if UNITY_2023_2_OR_NEWER
: IAnalytic
#endif
{
string EventName { get; }
int EventVersion { get; }
IAssetStoreAnalyticData Data { get; }
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 6e9b53aa176bbed48bafa538c26df304
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 12.0.1
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/Services/Analytics/Data/IAssetStoreAnalytic.cs
uploadId: 724584

View File

@@ -0,0 +1,8 @@
namespace AssetStoreTools.Uploader.Services.Analytics.Data
{
interface IAssetStoreAnalyticData
#if UNITY_2023_2_OR_NEWER
: UnityEngine.Analytics.IAnalytic.IData
#endif
{ }
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: b639e25d9b9abd34d8eb67b0e17dde86
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 12.0.1
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/Services/Analytics/Data/IAssetStoreAnalyticData.cs
uploadId: 724584

View File

@@ -0,0 +1,72 @@
using AssetStoreTools.Api;
using AssetStoreTools.Validator.Data;
using System;
#if UNITY_2023_2_OR_NEWER
using UnityEngine.Analytics;
#endif
using AnalyticsConstants = AssetStoreTools.Constants.Uploader.Analytics;
namespace AssetStoreTools.Uploader.Services.Analytics.Data
{
#if UNITY_2023_2_OR_NEWER
[AnalyticInfo
(eventName: AnalyticsConstants.PackageUploadAnalytics.EventName,
vendorKey: AnalyticsConstants.VendorKey,
version: AnalyticsConstants.PackageUploadAnalytics.EventVersion,
maxEventsPerHour: AnalyticsConstants.MaxEventsPerHour,
maxNumberOfElements: AnalyticsConstants.MaxNumberOfElements)]
#endif
internal class PackageUploadAnalytic : BaseAnalytic
{
[Serializable]
public class PackageUploadAnalyticData : BaseAnalyticData
{
public string PackageId;
public string Category;
public bool UsedValidator;
public string ValidatorResults;
public string UploadFinishedReason;
public double TimeTaken;
public long PackageSize;
public string Workflow;
public string EndpointUrl;
}
public override string EventName => AnalyticsConstants.PackageUploadAnalytics.EventName;
public override int EventVersion => AnalyticsConstants.PackageUploadAnalytics.EventVersion;
private PackageUploadAnalyticData _data;
public PackageUploadAnalytic(
string packageId,
string category,
bool usedValidator,
ValidationSettings validationSettings,
ValidationResult validationResult,
UploadStatus uploadFinishedReason,
double timeTaken,
long packageSize,
string workflow
)
{
_data = new PackageUploadAnalyticData()
{
PackageId = packageId,
Category = category,
UsedValidator = usedValidator,
ValidatorResults = usedValidator ?
ValidationResultsSerializer.ConstructValidationResultsJson(validationSettings, validationResult) : null,
UploadFinishedReason = uploadFinishedReason.ToString(),
TimeTaken = timeTaken,
PackageSize = packageSize,
Workflow = workflow,
EndpointUrl = Constants.Api.AssetStoreBaseUrl
};
}
protected override BaseAnalyticData GetData()
{
return _data;
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 6cc34de12dce9964b9c900d5bb159966
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 12.0.1
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/Services/Analytics/Data/PackageUploadAnalytic.cs
uploadId: 724584

View File

@@ -0,0 +1,91 @@
using AssetStoreTools.Validator.Data;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System.Collections.Generic;
using System.Reflection;
namespace AssetStoreTools.Uploader.Services.Analytics.Data
{
internal class ValidationResultsSerializer
{
private class ValidationResults
{
public bool HasCompilationErrors;
public string[] Paths;
public Dictionary<string, TestResultOutcome> Results;
}
private class TestResultOutcome
{
public int IntegerValue;
public string StringValue;
public TestResultOutcome(TestResultStatus status)
{
IntegerValue = (int)status;
StringValue = status.ToString();
}
}
private class ValidationResultsResolver : DefaultContractResolver
{
private static ValidationResultsResolver _instance;
public static ValidationResultsResolver Instance => _instance ?? (_instance = new ValidationResultsResolver());
private Dictionary<string, string> _propertyConversion;
private ValidationResultsResolver()
{
_propertyConversion = new Dictionary<string, string>()
{
{ nameof(ValidationResults.HasCompilationErrors), "has_compilation_errors" },
{ nameof(ValidationResults.Paths), "validation_paths" },
{ nameof(ValidationResults.Results), "validation_results" },
{ nameof(TestResultOutcome.IntegerValue), "int" },
{ nameof(TestResultOutcome.StringValue), "string" },
};
}
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if (_propertyConversion.ContainsKey(property.PropertyName))
property.PropertyName = _propertyConversion[property.PropertyName];
return property;
}
}
public static string ConstructValidationResultsJson(ValidationSettings settings, ValidationResult result)
{
if (result == null)
return string.Empty;
var resultObject = new ValidationResults();
resultObject.HasCompilationErrors = result.HadCompilationErrors;
switch (settings)
{
case CurrentProjectValidationSettings currentProjectValidationSettings:
resultObject.Paths = currentProjectValidationSettings.ValidationPaths.ToArray();
break;
case ExternalProjectValidationSettings externalProjectValidationSettings:
resultObject.Paths = new string[] { externalProjectValidationSettings.PackagePath };
break;
}
resultObject.Results = new Dictionary<string, TestResultOutcome>();
foreach (var test in result.Tests)
{
resultObject.Results.Add(test.Id.ToString(), new TestResultOutcome(test.Result.Status));
}
var serializerSettings = new JsonSerializerSettings()
{
ContractResolver = ValidationResultsResolver.Instance
};
return JsonConvert.SerializeObject(resultObject, serializerSettings);
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: fa15fc27c7f3d044884885b3dad73efc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 12.0.1
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/Services/Analytics/Data/ValidationResultsSerializer.cs
uploadId: 724584

View File

@@ -0,0 +1,10 @@
using AssetStoreTools.Uploader.Services.Analytics.Data;
using UnityEngine.Analytics;
namespace AssetStoreTools.Uploader.Services.Analytics
{
internal interface IAnalyticsService : IUploaderService
{
AnalyticsResult Send(IAssetStoreAnalytic analytic);
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: faa1f39fc83b86b438f6e0f34f01167b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 12.0.1
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/Services/Analytics/IAnalyticsService.cs
uploadId: 724584

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4d983b64bd0866a428f937434252f537
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,100 @@
using AssetStoreTools.Api;
using AssetStoreTools.Api.Models;
using AssetStoreTools.Api.Responses;
using AssetStoreTools.Uploader.Services.Analytics;
using AssetStoreTools.Uploader.Services.Analytics.Data;
using AssetStoreTools.Utility;
using System;
using System.Threading.Tasks;
using UnityEditor;
namespace AssetStoreTools.Uploader.Services.Api
{
internal class AuthenticationService : IAuthenticationService
{
private IAssetStoreApi _api;
private ICachingService _cachingService;
private IAnalyticsService _analyticsService;
public User User { get; private set; }
public AuthenticationService(IAssetStoreApi api, ICachingService cachingService, IAnalyticsService analyticsService)
{
_api = api;
_cachingService = cachingService;
_analyticsService = analyticsService;
}
public async Task<AuthenticationResponse> AuthenticateWithCredentials(string email, string password)
{
var authenticationType = new CredentialsAuthentication(email, password);
return await Authenticate(authenticationType);
}
public async Task<AuthenticationResponse> AuthenticateWithSessionToken()
{
if (!_cachingService.GetCachedSessionToken(out var cachedSessionToken))
{
return new AuthenticationResponse() { Success = false, Exception = new Exception("No cached session token found") };
}
var authenticationType = new SessionAuthentication(cachedSessionToken);
return await Authenticate(authenticationType);
}
public async Task<AuthenticationResponse> AuthenticateWithCloudToken()
{
var authenticationType = new CloudTokenAuthentication(CloudProjectSettings.accessToken);
return await Authenticate(authenticationType);
}
private async Task<AuthenticationResponse> Authenticate(IAuthenticationType authenticationType)
{
var response = await _api.Authenticate(authenticationType);
HandleLoginResponse(authenticationType, response);
return response;
}
private void HandleLoginResponse(IAuthenticationType authenticationType, AuthenticationResponse response)
{
if (!response.Success)
{
Deauthenticate();
return;
}
User = response.User;
_cachingService.CacheSessionToken(User.SessionId);
SendAnalytics(authenticationType, User);
}
public bool CloudAuthenticationAvailable(out string username, out string cloudToken)
{
username = CloudProjectSettings.userName;
cloudToken = CloudProjectSettings.accessToken;
return !username.Equals("anonymous");
}
public void Deauthenticate()
{
_api.Deauthenticate();
User = null;
_cachingService.ClearCachedSessionToken();
}
private void SendAnalytics(IAuthenticationType authenticationType, User user)
{
try
{
// Do not send session authentication events
if (authenticationType is SessionAuthentication)
return;
var analytic = new AuthenticationAnalytic(authenticationType, user.PublisherId);
var result = _analyticsService.Send(analytic);
}
catch (Exception e) { ASDebug.LogError($"Could not send analytics: {e}"); }
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: c1c3d6578d298d049a8dcf858fd3686e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 12.0.1
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/Services/Api/AuthenticationService.cs
uploadId: 724584

View File

@@ -0,0 +1,16 @@
using AssetStoreTools.Api.Models;
using AssetStoreTools.Api.Responses;
using System.Threading.Tasks;
namespace AssetStoreTools.Uploader.Services.Api
{
internal interface IAuthenticationService : IUploaderService
{
User User { get; }
Task<AuthenticationResponse> AuthenticateWithCredentials(string email, string password);
Task<AuthenticationResponse> AuthenticateWithSessionToken();
Task<AuthenticationResponse> AuthenticateWithCloudToken();
bool CloudAuthenticationAvailable(out string username, out string cloudToken);
void Deauthenticate();
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: ff0518dc0d95d3540857d138215bb900
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 12.0.1
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/Services/Api/IAuthenticationService.cs
uploadId: 724584

View File

@@ -0,0 +1,16 @@
using AssetStoreTools.Api.Responses;
using AssetStoreTools.Uploader.Data;
using System.Threading.Tasks;
namespace AssetStoreTools.Uploader.Services.Api
{
internal interface IPackageDownloadingService : IUploaderService
{
Task<PackagesDataResponse> GetPackageData();
Task<RefreshedPackageDataResponse> UpdatePackageData(IPackage package);
void ClearPackageData();
Task<PackageThumbnailResponse> GetPackageThumbnail(IPackage package);
Task<PackageUploadedUnityVersionDataResponse> GetPackageUploadedVersions(IPackage package, int timeoutMs);
void StopDownloading();
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 96acd12a628311d429cc285f418f8b90
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 12.0.1
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/Services/Api/IPackageDownloadingService.cs
uploadId: 724584

View File

@@ -0,0 +1,16 @@
using AssetStoreTools.Api;
using AssetStoreTools.Api.Responses;
using System;
using System.Threading.Tasks;
namespace AssetStoreTools.Uploader.Services.Api
{
internal interface IPackageUploadingService : IUploaderService
{
bool IsUploading { get; }
Task<PackageUploadResponse> UploadPackage(IPackageUploader uploader, IProgress<float> progress);
void StopUploading(IPackageUploader package);
void StopAllUploadinng();
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 9a3d78f3bc68d3d44b4300bc8ffe69c2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 12.0.1
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/Services/Api/IPackageUploadingService.cs
uploadId: 724584

View File

@@ -0,0 +1,109 @@
using AssetStoreTools.Api;
using AssetStoreTools.Api.Responses;
using AssetStoreTools.Uploader.Data;
using System.Threading;
using System.Threading.Tasks;
namespace AssetStoreTools.Uploader.Services.Api
{
internal class PackageDownloadingService : IPackageDownloadingService
{
public const int MaxConcurrentTumbnailDownloads = 10;
private IAssetStoreApi _api;
private ICachingService _cachingService;
private int _currentDownloads;
private CancellationTokenSource _cancellationTokenSource;
public PackageDownloadingService(IAssetStoreApi api, ICachingService cachingService)
{
_api = api;
_cachingService = cachingService;
_cancellationTokenSource = new CancellationTokenSource();
}
public void ClearPackageData()
{
_cachingService.DeletePackageMetadata();
}
public async Task<PackagesDataResponse> GetPackageData()
{
if (!_cachingService.GetCachedPackageMetadata(out var models))
{
var cancellationToken = _cancellationTokenSource.Token;
var packagesResponse = await _api.GetPackages(cancellationToken);
if (packagesResponse.Cancelled || !packagesResponse.Success)
return packagesResponse;
_cachingService.CachePackageMetadata(packagesResponse.Packages);
return packagesResponse;
}
return new PackagesDataResponse() { Success = true, Packages = models };
}
public async Task<RefreshedPackageDataResponse> UpdatePackageData(IPackage package)
{
var response = await _api.RefreshPackageMetadata(package.ToModel());
if (response.Success)
_cachingService.UpdatePackageMetadata(response.Package);
return response;
}
public async Task<PackageThumbnailResponse> GetPackageThumbnail(IPackage package)
{
if (_cachingService.GetCachedPackageThumbnail(package.PackageId, out var cachedTexture))
{
return new PackageThumbnailResponse() { Success = true, Thumbnail = cachedTexture };
}
var cancellationToken = _cancellationTokenSource.Token;
while (_currentDownloads >= MaxConcurrentTumbnailDownloads)
await Task.Delay(100);
if (cancellationToken.IsCancellationRequested)
return new PackageThumbnailResponse() { Success = false, Cancelled = true };
_currentDownloads++;
var result = await _api.GetPackageThumbnail(package.ToModel(), cancellationToken);
_currentDownloads--;
if (result.Success && result.Thumbnail != null)
_cachingService.CachePackageThumbnail(package.PackageId, result.Thumbnail);
return result;
}
public async Task<PackageUploadedUnityVersionDataResponse> GetPackageUploadedVersions(IPackage package, int timeoutMs)
{
var timeoutTokenSource = new CancellationTokenSource();
try
{
var versionsTask = _api.GetPackageUploadedVersions(package.ToModel(), timeoutTokenSource.Token);
// Wait for versions to be retrieved, or a timeout to occur, whichever is first
if (await Task.WhenAny(versionsTask, Task.Delay(timeoutMs)) != versionsTask)
{
timeoutTokenSource.Cancel();
}
return await versionsTask;
}
finally
{
timeoutTokenSource.Dispose();
}
}
public void StopDownloading()
{
_cancellationTokenSource.Cancel();
_cancellationTokenSource = new CancellationTokenSource();
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: adc44e974cb91b54fac3819284b7ba82
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 12.0.1
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/Services/Api/PackageDownloadingService.cs
uploadId: 724584

View File

@@ -0,0 +1,103 @@
using AssetStoreTools.Api;
using AssetStoreTools.Api.Responses;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using UnityEditor;
namespace AssetStoreTools.Uploader.Services.Api
{
internal class PackageUploadingService : IPackageUploadingService
{
private class UploadInProgress
{
public IPackageUploader Uploader;
public IProgress<float> Progress = new Progress<float>();
public CancellationTokenSource CancellationTokenSource = new CancellationTokenSource();
public UploadInProgress(IPackageUploader uploader, IProgress<float> progress)
{
Uploader = uploader;
Progress = progress;
CancellationTokenSource = new CancellationTokenSource();
}
}
private IAssetStoreApi _api;
private List<UploadInProgress> _uploadsInProgress;
public bool IsUploading => _uploadsInProgress.Count > 0;
public PackageUploadingService(IAssetStoreApi api)
{
_api = api;
_uploadsInProgress = new List<UploadInProgress>();
}
public async Task<PackageUploadResponse> UploadPackage(IPackageUploader uploader, IProgress<float> progress)
{
using (var cancellationTokenSource = new CancellationTokenSource())
{
var uploadInProgress = StartTrackingUpload(uploader, progress);
var response = await _api.UploadPackage(uploadInProgress.Uploader, uploadInProgress.Progress, uploadInProgress.CancellationTokenSource.Token);
StopTrackingUpload(uploadInProgress);
return response;
}
}
private UploadInProgress StartTrackingUpload(IPackageUploader uploader, IProgress<float> progress)
{
// If this is the first upload - lock reload assemblies and prevent entering play mode
if (_uploadsInProgress.Count == 0)
{
EditorApplication.LockReloadAssemblies();
EditorApplication.playModeStateChanged += PreventEnteringPlayMode;
}
var uploadInProgress = new UploadInProgress(uploader, progress);
_uploadsInProgress.Add(uploadInProgress);
return uploadInProgress;
}
private void StopTrackingUpload(UploadInProgress uploadInProgress)
{
_uploadsInProgress.Remove(uploadInProgress);
// If this was the last upload - unlock reload assemblies and allow entering play mode
if (_uploadsInProgress.Count > 0)
return;
EditorApplication.UnlockReloadAssemblies();
EditorApplication.playModeStateChanged -= PreventEnteringPlayMode;
}
private void PreventEnteringPlayMode(PlayModeStateChange change)
{
if (change != PlayModeStateChange.ExitingEditMode)
return;
EditorApplication.ExitPlaymode();
EditorUtility.DisplayDialog("Notice", "Entering Play Mode is not allowed while there's a package upload in progress.\n\n" +
"Please wait until the upload is finished or cancel the upload from the Asset Store Uploader window", "OK");
}
public void StopUploading(IPackageUploader uploader)
{
var uploadInProgress = _uploadsInProgress.FirstOrDefault(x => x.Uploader == uploader);
if (uploadInProgress == null)
return;
uploadInProgress.CancellationTokenSource.Cancel();
}
public void StopAllUploadinng()
{
foreach (var uploadInProgress in _uploadsInProgress)
uploadInProgress.CancellationTokenSource.Cancel();
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 22e23997fe339a74bb5355d6a88ce731
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 12.0.1
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/Services/Api/PackageUploadingService.cs
uploadId: 724584

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a834946d92154754493879c5fcc7dbc9
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,157 @@
using AssetStoreTools.Api.Models;
using AssetStoreTools.Uploader.Data.Serialization;
using AssetStoreTools.Utility;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
namespace AssetStoreTools.Uploader.Services
{
internal class CachingService : ICachingService
{
private VisualElement _cachedUploaderWindow;
public bool GetCachedUploaderWindow(out VisualElement uploaderWindow)
{
uploaderWindow = _cachedUploaderWindow;
return uploaderWindow != null;
}
public void CacheUploaderWindow(VisualElement uploaderWindow)
{
_cachedUploaderWindow = uploaderWindow;
}
public void CacheSessionToken(string sessionToken)
{
if (string.IsNullOrEmpty(sessionToken))
throw new ArgumentException("Session token cannot be null");
EditorPrefs.SetString(Constants.Cache.SessionTokenKey, sessionToken);
}
public bool GetCachedSessionToken(out string sessionToken)
{
sessionToken = EditorPrefs.GetString(Constants.Cache.SessionTokenKey, string.Empty);
return !string.IsNullOrEmpty(sessionToken);
}
public void ClearCachedSessionToken()
{
EditorPrefs.DeleteKey(Constants.Cache.SessionTokenKey);
}
public bool GetCachedPackageMetadata(out List<Package> data)
{
data = new List<Package>();
if (!CacheUtil.GetFileFromTempCache(Constants.Cache.PackageDataFileName, out var filePath))
return false;
try
{
var serializerSettings = new JsonSerializerSettings()
{
ContractResolver = Package.CachedPackageResolver.Instance
};
data = JsonConvert.DeserializeObject<List<Package>>(File.ReadAllText(filePath, Encoding.UTF8), serializerSettings);
return true;
}
catch
{
return false;
}
}
public void CachePackageMetadata(List<Package> data)
{
if (data == null)
throw new ArgumentException("Package data cannot be null");
var serializerSettings = new JsonSerializerSettings()
{
ContractResolver = Package.CachedPackageResolver.Instance,
Formatting = Formatting.Indented
};
CacheUtil.CreateFileInTempCache(Constants.Cache.PackageDataFileName, JsonConvert.SerializeObject(data, serializerSettings), true);
}
public void DeletePackageMetadata()
{
CacheUtil.DeleteFileFromTempCache(Constants.Cache.PackageDataFileName);
}
public void UpdatePackageMetadata(Package data)
{
if (!GetCachedPackageMetadata(out var cachedData))
return;
var index = cachedData.FindIndex(x => x.PackageId.Equals(data.PackageId));
if (index == -1)
{
cachedData.Add(data);
}
else
{
cachedData.RemoveAt(index);
cachedData.Insert(index, data);
}
CachePackageMetadata(cachedData);
}
public bool GetCachedPackageThumbnail(string packageId, out Texture2D texture)
{
texture = null;
if (!CacheUtil.GetFileFromTempCache(Constants.Cache.PackageThumbnailFileName(packageId), out var filePath))
return false;
texture = new Texture2D(1, 1);
texture.LoadImage(File.ReadAllBytes(filePath));
return true;
}
public void CachePackageThumbnail(string packageId, Texture2D texture)
{
CacheUtil.CreateFileInTempCache(Constants.Cache.PackageThumbnailFileName(packageId), texture.EncodeToPNG(), true);
}
public bool GetCachedWorkflowStateData(string packageId, out WorkflowStateData data)
{
data = null;
if (string.IsNullOrEmpty(packageId))
return false;
if (!CacheUtil.GetFileFromPersistentCache(Constants.Cache.WorkflowStateDataFileName(packageId), out var filePath))
return false;
try
{
data = JsonConvert.DeserializeObject<WorkflowStateData>(File.ReadAllText(filePath, Encoding.UTF8));
if (string.IsNullOrEmpty(data.GetPackageId()))
return false;
}
catch
{
return false;
}
return true;
}
public void CacheWorkflowStateData(WorkflowStateData data)
{
if (data == null)
throw new ArgumentException("Workflow state data cannot be null");
CacheUtil.CreateFileInPersistentCache(Constants.Cache.WorkflowStateDataFileName(data.GetPackageId()), JsonConvert.SerializeObject(data, Formatting.Indented), true);
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: fffaed09a3f76f945a7ececfb355f3e0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 12.0.1
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/Services/Caching/CachingService.cs
uploadId: 724584

View File

@@ -0,0 +1,25 @@
using AssetStoreTools.Api.Models;
using AssetStoreTools.Uploader.Data.Serialization;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
namespace AssetStoreTools.Uploader.Services
{
internal interface ICachingService : IUploaderService
{
void CacheUploaderWindow(VisualElement uploaderWindow);
bool GetCachedUploaderWindow(out VisualElement uploaderWindow);
void CacheSessionToken(string sessionToken);
bool GetCachedSessionToken(out string sessionToken);
void ClearCachedSessionToken();
bool GetCachedPackageMetadata(out List<Package> data);
void UpdatePackageMetadata(Package data);
void CachePackageMetadata(List<Package> data);
void DeletePackageMetadata();
bool GetCachedPackageThumbnail(string packageId, out Texture2D texture);
void CachePackageThumbnail(string packageId, Texture2D texture);
bool GetCachedWorkflowStateData(string packageId, out WorkflowStateData data);
void CacheWorkflowStateData(WorkflowStateData data);
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: a904477679e07bc4889bc15e894c0c48
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 12.0.1
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/Services/Caching/ICachingService.cs
uploadId: 724584

View File

@@ -0,0 +1,4 @@
namespace AssetStoreTools.Uploader.Services
{
internal interface IUploaderService { }
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 757d7a4dc29863740859c936be514fea
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 12.0.1
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/Services/IUploaderService.cs
uploadId: 724584

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 02e4a5ee9e2fb7941b876b207078e01d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,18 @@
using AssetStoreTools.Uploader.Data;
using AssetStoreTools.Uploader.Data.Serialization;
using System.Collections.Generic;
using PackageModel = AssetStoreTools.Api.Models.Package;
namespace AssetStoreTools.Uploader.Services
{
internal interface IPackageFactoryService : IUploaderService
{
IPackageGroup CreatePackageGroup(string groupName, List<IPackage> packages);
IPackage CreatePackage(PackageModel packageModel);
IPackageContent CreatePackageContent(IPackage package);
List<IWorkflow> CreateWorkflows(IPackage package, WorkflowStateData stateData);
AssetsWorkflow CreateAssetsWorkflow(IPackage package, AssetsWorkflowState stateData);
UnityPackageWorkflow CreateUnityPackageWorkflow(IPackage package, UnityPackageWorkflowState stateData);
HybridPackageWorkflow CreateHybridPackageWorkflow(IPackage package, HybridPackageWorkflowState stateData);
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 14324b71768a1ea499baa06de33f05af
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 12.0.1
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/Services/PackageFactory/IPackageFactoryService.cs
uploadId: 724584

View File

@@ -0,0 +1,95 @@
using AssetStoreTools.Uploader.Data;
using AssetStoreTools.Uploader.Data.Serialization;
using AssetStoreTools.Uploader.Services.Analytics;
using AssetStoreTools.Uploader.Services.Api;
using System.Collections.Generic;
using PackageModel = AssetStoreTools.Api.Models.Package;
namespace AssetStoreTools.Uploader.Services
{
internal class PackageFactoryService : IPackageFactoryService
{
private IWorkflowServices _workflowServices;
// Service dependencies
private ICachingService _cachingService;
private IPackageDownloadingService _packageDownloadingService;
private IPackageUploadingService _packageUploadingService;
private IAnalyticsService _analyticsService;
public PackageFactoryService(
ICachingService cachingService,
IPackageDownloadingService packageDownloadingService,
IPackageUploadingService packageUploadingService,
IAnalyticsService analyticsService
)
{
_cachingService = cachingService;
_packageDownloadingService = packageDownloadingService;
_packageUploadingService = packageUploadingService;
_analyticsService = analyticsService;
_workflowServices = new WorkflowServices(_packageDownloadingService, _packageUploadingService, _analyticsService);
}
public IPackage CreatePackage(PackageModel packageModel)
{
var package = new Package(packageModel);
return package;
}
public IPackageGroup CreatePackageGroup(string groupName, List<IPackage> packages)
{
return new PackageGroup(groupName, packages);
}
public IPackageContent CreatePackageContent(IPackage package)
{
if (!package.IsDraft)
return null;
WorkflowStateData stateData = GetOrCreateWorkflowStateData(package);
var workflows = CreateWorkflows(package, stateData);
var packageContent = new PackageContent(workflows, stateData, _cachingService);
return packageContent;
}
public List<IWorkflow> CreateWorkflows(IPackage package, WorkflowStateData stateData)
{
var workflows = new List<IWorkflow>
{
CreateAssetsWorkflow(package, stateData.GetAssetsWorkflowState()),
CreateUnityPackageWorkflow(package, stateData.GetUnityPackageWorkflowState()),
#if UNITY_ASTOOLS_EXPERIMENTAL
CreateHybridPackageWorkflow(package, stateData.GetHybridPackageWorkflowState()),
#endif
};
return workflows;
}
public AssetsWorkflow CreateAssetsWorkflow(IPackage package, AssetsWorkflowState stateData)
{
return new AssetsWorkflow(package, stateData, _workflowServices);
}
public UnityPackageWorkflow CreateUnityPackageWorkflow(IPackage package, UnityPackageWorkflowState stateData)
{
return new UnityPackageWorkflow(package, stateData, _workflowServices);
}
public HybridPackageWorkflow CreateHybridPackageWorkflow(IPackage package, HybridPackageWorkflowState stateData)
{
return new HybridPackageWorkflow(package, stateData, _workflowServices);
}
private WorkflowStateData GetOrCreateWorkflowStateData(IPackage package)
{
if (!_cachingService.GetCachedWorkflowStateData(package.PackageId, out var stateData))
stateData = new WorkflowStateData(package.PackageId);
return stateData;
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 4074a5b21b6201d449974dcfb652a00b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 12.0.1
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/Services/PackageFactory/PackageFactoryService.cs
uploadId: 724584

View File

@@ -0,0 +1,26 @@
using AssetStoreTools.Api;
using AssetStoreTools.Uploader.Services.Analytics;
using AssetStoreTools.Uploader.Services.Api;
using AssetStoreTools.Utility;
namespace AssetStoreTools.Uploader.Services
{
internal class UploaderServiceProvider : ServiceProvider<IUploaderService>
{
public static UploaderServiceProvider Instance => _instance ?? (_instance = new UploaderServiceProvider());
private static UploaderServiceProvider _instance;
private UploaderServiceProvider() { }
protected override void RegisterServices()
{
var api = new AssetStoreApi(new AssetStoreClient());
Register<IAnalyticsService, AnalyticsService>();
Register<ICachingService, CachingService>();
Register<IAuthenticationService>(() => new AuthenticationService(api, GetService<ICachingService>(), GetService<IAnalyticsService>()));
Register<IPackageDownloadingService>(() => new PackageDownloadingService(api, GetService<ICachingService>()));
Register<IPackageUploadingService>(() => new PackageUploadingService(api));
Register<IPackageFactoryService, PackageFactoryService>();
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: e66f9c7f198baff41ba77f4d0ed7b60f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 12.0.1
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/Services/UploaderServiceProvider.cs
uploadId: 724584