update libs
This commit is contained in:
@@ -1,227 +0,0 @@
|
||||
using AssetStoreTools.Utility.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using AssetStoreTools.Utility;
|
||||
using UnityEditor;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using AssetStoreTools.Uploader.Utility;
|
||||
using AssetStoreTools.Uploader.UIElements;
|
||||
|
||||
namespace AssetStoreTools.Uploader
|
||||
{
|
||||
internal class AssetStoreUploader : AssetStoreToolsWindow
|
||||
{
|
||||
public const string MinRequiredPackageVersion = "2021.3";
|
||||
public const long MaxPackageSizeBytes = 6442450944; // 6 GB
|
||||
|
||||
private const string MainWindowVisualTree = "Packages/com.unity.asset-store-tools/Editor/Uploader/Styles/Base/BaseWindow_Main";
|
||||
private const string DebugPhrase = "debug";
|
||||
|
||||
// UI Windows
|
||||
private LoginWindow _loginWindow;
|
||||
private UploadWindow _uploadWindow;
|
||||
|
||||
private readonly List<char> _debugBuffer = new List<char>();
|
||||
|
||||
public static bool ShowPackageVersionDialog
|
||||
{
|
||||
get => string.Compare(Application.unityVersion, MinRequiredPackageVersion, StringComparison.Ordinal) == -1 && ASToolsPreferences.Instance.UploadVersionCheck;
|
||||
set { ASToolsPreferences.Instance.UploadVersionCheck = value; ASToolsPreferences.Instance.Save(); }
|
||||
}
|
||||
|
||||
protected override string WindowTitle => "Asset Store Uploader";
|
||||
|
||||
protected override void Init()
|
||||
{
|
||||
if (_loginWindow != null && _uploadWindow != null)
|
||||
return;
|
||||
|
||||
minSize = new Vector2(400, 430);
|
||||
this.SetAntiAliasing(4);
|
||||
|
||||
base.Init();
|
||||
|
||||
VisualElement root = rootVisualElement;
|
||||
root.AddToClassList("root");
|
||||
|
||||
// Getting a reference to the UXML Document and adding to the root
|
||||
var visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>($"{MainWindowVisualTree}.uxml");
|
||||
VisualElement uxmlRoot = visualTree.CloneTree();
|
||||
uxmlRoot.style.flexGrow = 1;
|
||||
root.Add(uxmlRoot);
|
||||
|
||||
root.styleSheets.Add(StyleSelector.UploaderWindow.BaseWindowStyle);
|
||||
root.styleSheets.Add(StyleSelector.UploaderWindow.BaseWindowTheme);
|
||||
|
||||
|
||||
// Find necessary windows / views and sets up appropriate functionality
|
||||
SetupCoreElements();
|
||||
|
||||
if (!AssetStoreAPI.IsUploading)
|
||||
{
|
||||
// Should only authenticate if the session is available. Other authentications are only available
|
||||
// in the login window. See "SetupLoginElements".
|
||||
HideElement(_uploadWindow);
|
||||
Authenticate();
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowUploadWindow();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
CheckForDebugMode();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (AssetStoreAPI.IsUploading)
|
||||
EditorUtility.DisplayDialog("Notice", "Assets are still being uploaded to the Asset Store. " +
|
||||
"If you wish to check on the progress, please re-open the Asset Store Uploader window", "OK");
|
||||
}
|
||||
|
||||
private void SetupCoreElements()
|
||||
{
|
||||
_loginWindow = rootVisualElement.Q<LoginWindow>("LoginWindow");
|
||||
_uploadWindow = rootVisualElement.Q<UploadWindow>("UploadWindow");
|
||||
|
||||
_loginWindow.SetupLoginElements(OnLoginSuccess, OnLoginFail);
|
||||
_uploadWindow.SetupWindows(OnLogout, OnPackageDownloadFail);
|
||||
}
|
||||
|
||||
#region Login Interface
|
||||
|
||||
private async void Authenticate()
|
||||
{
|
||||
ShowLoginWindow();
|
||||
|
||||
// 1 - Check if there's an active session
|
||||
// 2 - Check if there's a saved session
|
||||
// 3 - Attempt to login via Cloud session token
|
||||
// 4 - Prompt manual login
|
||||
EnableLoginWindow(false);
|
||||
var result = await AssetStoreAPI.LoginWithSessionAsync();
|
||||
if (result.Success)
|
||||
OnLoginSuccess(result.Response);
|
||||
else if (result.SilentFail)
|
||||
OnLoginFailSession();
|
||||
else
|
||||
OnLoginFail(result.Error);
|
||||
}
|
||||
|
||||
private void OnLoginFail(ASError error)
|
||||
{
|
||||
Debug.LogError(error.Message);
|
||||
|
||||
_loginWindow.EnableErrorBox(true, error.Message);
|
||||
EnableLoginWindow(true);
|
||||
}
|
||||
|
||||
private void OnLoginFailSession()
|
||||
{
|
||||
// All previous login methods are unavailable
|
||||
EnableLoginWindow(true);
|
||||
}
|
||||
|
||||
private void OnLoginSuccess(JsonValue json)
|
||||
{
|
||||
ASDebug.Log($"Login json\n{json}");
|
||||
|
||||
if (!AssetStoreAPI.IsPublisherValid(json, out var error))
|
||||
{
|
||||
EnableLoginWindow(true);
|
||||
_loginWindow.EnableErrorBox(true, error.Message);
|
||||
ASDebug.Log($"Publisher {json["name"]} is invalid.");
|
||||
return;
|
||||
}
|
||||
|
||||
ASDebug.Log($"Publisher {json["name"]} is valid.");
|
||||
AssetStoreAPI.SavedSessionId = json["xunitysession"].AsString();
|
||||
AssetStoreAPI.LastLoggedInUser = json["username"].AsString();
|
||||
|
||||
ShowUploadWindow();
|
||||
}
|
||||
|
||||
private void OnPackageDownloadFail(ASError error)
|
||||
{
|
||||
_loginWindow.EnableErrorBox(true, error.Message);
|
||||
EnableLoginWindow(true);
|
||||
ShowLoginWindow();
|
||||
}
|
||||
|
||||
private void OnLogout()
|
||||
{
|
||||
AssetStoreAPI.SavedSessionId = String.Empty;
|
||||
AssetStoreCache.ClearTempCache();
|
||||
|
||||
_loginWindow.ClearLoginBoxes();
|
||||
ShowLoginWindow();
|
||||
EnableLoginWindow(true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region UI Window Utils
|
||||
private void ShowLoginWindow()
|
||||
{
|
||||
HideElement(_uploadWindow);
|
||||
ShowElement(_loginWindow);
|
||||
}
|
||||
|
||||
private void ShowUploadWindow()
|
||||
{
|
||||
HideElement(_loginWindow);
|
||||
ShowElement(_uploadWindow);
|
||||
|
||||
_uploadWindow.ShowAllPackagesView();
|
||||
_uploadWindow.ShowPublisherEmail(AssetStoreAPI.LastLoggedInUser);
|
||||
_uploadWindow.LoadPackages(true, OnPackageDownloadFail);
|
||||
}
|
||||
|
||||
private void ShowElement(params VisualElement[] elements)
|
||||
{
|
||||
foreach(var e in elements)
|
||||
e.style.display = DisplayStyle.Flex;
|
||||
}
|
||||
|
||||
private void HideElement(params VisualElement[] elements)
|
||||
{
|
||||
foreach(var e in elements)
|
||||
e.style.display = DisplayStyle.None;
|
||||
}
|
||||
|
||||
private void EnableLoginWindow(bool enable)
|
||||
{
|
||||
_loginWindow.SetEnabled(enable);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Debug Utility
|
||||
|
||||
private void CheckForDebugMode()
|
||||
{
|
||||
Event e = Event.current;
|
||||
|
||||
if (e.type != EventType.KeyDown || e.keyCode == KeyCode.None)
|
||||
return;
|
||||
|
||||
_debugBuffer.Add(e.keyCode.ToString().ToLower()[0]);
|
||||
if (_debugBuffer.Count > DebugPhrase.Length)
|
||||
_debugBuffer.RemoveAt(0);
|
||||
|
||||
if (string.Join(string.Empty, _debugBuffer.ToArray()) != DebugPhrase)
|
||||
return;
|
||||
|
||||
ASDebug.DebugModeEnabled = !ASDebug.DebugModeEnabled;
|
||||
ASDebug.Log($"DEBUG MODE ENABLED: {ASDebug.DebugModeEnabled}");
|
||||
_debugBuffer.Clear();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 337 B |
@@ -0,0 +1,130 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 92f8a779a7c786a4f87ed8e1b36a66b3
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 12
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMasterTextureLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 0
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 5e97eb03825dee720800000000000000
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
nameFileIdTable: {}
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 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/Icons/account-dark.png
|
||||
uploadId: 724584
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 387 B |
@@ -0,0 +1,130 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7c0661b9a6385a3488c075711f368cf4
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 12
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMasterTextureLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 0
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 5e97eb03825dee720800000000000000
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
nameFileIdTable: {}
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 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/Icons/account-light.png
|
||||
uploadId: 724584
|
||||
@@ -149,6 +149,6 @@ AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 11.4.4
|
||||
packageVersion: 12.0.1
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Icons/open-in-browser.png
|
||||
uploadId: 712972
|
||||
uploadId: 724584
|
||||
|
||||
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
@@ -130,6 +130,6 @@ AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 11.4.4
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Icons/publisher_portal_white.png
|
||||
uploadId: 712972
|
||||
packageVersion: 12.0.1
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Icons/publisher-portal-dark.png
|
||||
uploadId: 724584
|
||||
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
@@ -3,7 +3,7 @@ guid: 8e0749dce5b14cc46b73b0303375c162
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 11
|
||||
serializedVersion: 12
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
@@ -23,6 +23,8 @@ TextureImporter:
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMasterTextureLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
@@ -40,7 +42,7 @@ TextureImporter:
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 2
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
@@ -54,10 +56,14 @@ TextureImporter:
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
cookieLightType: 1
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
@@ -113,13 +119,14 @@ TextureImporter:
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
spriteID: 5e97eb03825dee720800000000000000
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
nameFileIdTable: {}
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
@@ -130,6 +137,6 @@ AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 11.4.4
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Icons/publisher_portal_black.png
|
||||
uploadId: 712972
|
||||
packageVersion: 12.0.1
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Icons/publisher-portal-light.png
|
||||
uploadId: 724584
|
||||
@@ -1,796 +0,0 @@
|
||||
using AssetStoreTools.Uploader.Data;
|
||||
using AssetStoreTools.Uploader.Utility;
|
||||
using AssetStoreTools.Utility;
|
||||
using AssetStoreTools.Utility.Json;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AssetStoreTools.Uploader
|
||||
{
|
||||
/// <summary>
|
||||
/// A class for retrieving data from the Asset Store backend <para/>
|
||||
/// <b>Note:</b> most data retrieval methods require <see cref="SavedSessionId"/> to be set
|
||||
/// </summary>
|
||||
internal static class AssetStoreAPI
|
||||
{
|
||||
public const string ToolVersion = "V11.4.4";
|
||||
|
||||
private const string UnauthSessionId = "26c4202eb475d02864b40827dfff11a14657aa41";
|
||||
private const string KharmaSessionId = "kharma.sessionid";
|
||||
private const int UploadResponseTimeoutMs = 10000;
|
||||
|
||||
public static string AssetStoreProdUrl = "https://kharma.unity3d.com";
|
||||
private static string s_sessionId = EditorPrefs.GetString(KharmaSessionId);
|
||||
private static HttpClient httpClient = new HttpClient();
|
||||
private static CancellationTokenSource s_downloadCancellationSource;
|
||||
|
||||
public static string SavedSessionId
|
||||
{
|
||||
get => s_sessionId;
|
||||
set
|
||||
{
|
||||
s_sessionId = value;
|
||||
EditorPrefs.SetString(KharmaSessionId, value);
|
||||
httpClient.DefaultRequestHeaders.Clear();
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
httpClient.DefaultRequestHeaders.Add("X-Unity-Session", SavedSessionId);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsCloudUserAvailable => CloudProjectSettings.userName != "anonymous";
|
||||
public static string LastLoggedInUser = "";
|
||||
public static ConcurrentDictionary<string, OngoingUpload> ActiveUploads = new ConcurrentDictionary<string, OngoingUpload>();
|
||||
public static bool IsUploading => (ActiveUploads.Count > 0);
|
||||
|
||||
static AssetStoreAPI()
|
||||
{
|
||||
ServicePointManager.DefaultConnectionLimit = 500;
|
||||
httpClient.DefaultRequestHeaders.ConnectionClose = false;
|
||||
httpClient.Timeout = TimeSpan.FromMinutes(1320);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A structure used to return the success outcome and the result of Asset Store API calls
|
||||
/// </summary>
|
||||
internal class APIResult
|
||||
{
|
||||
public JsonValue Response;
|
||||
public bool Success;
|
||||
public bool SilentFail;
|
||||
public ASError Error;
|
||||
|
||||
public static implicit operator bool(APIResult value)
|
||||
{
|
||||
return value != null && value.Success != false;
|
||||
}
|
||||
}
|
||||
|
||||
#region Login API
|
||||
|
||||
/// <summary>
|
||||
/// A login API call that uses the email and password credentials
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <b>Note:</b> this method only returns a response from the server and does not set the <see cref="SavedSessionId"/> itself
|
||||
/// </remarks>
|
||||
public static async Task<APIResult> LoginWithCredentialsAsync(string email, string password)
|
||||
{
|
||||
FormUrlEncodedContent data = GetLoginContent(new Dictionary<string, string> { { "user", email }, { "pass", password } });
|
||||
return await LoginAsync(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A login API call that uses the <see cref="SavedSessionId"/>
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <b>Note:</b> this method only returns a response from the server and does not set the <see cref="SavedSessionId"/> itself
|
||||
/// </remarks>
|
||||
public static async Task<APIResult> LoginWithSessionAsync()
|
||||
{
|
||||
if (string.IsNullOrEmpty(SavedSessionId))
|
||||
return new APIResult() { Success = false, SilentFail = true, Error = ASError.GetGenericError(new Exception("No active session available")) };
|
||||
|
||||
FormUrlEncodedContent data = GetLoginContent(new Dictionary<string, string> { { "reuse_session", SavedSessionId }, { "xunitysession", UnauthSessionId } });
|
||||
return await LoginAsync(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A login API call that uses the <see cref="CloudProjectSettings.accessToken"/><para/>
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <b>Note:</b> this method only returns a response from the server and does not set the <see cref="SavedSessionId"/> itself
|
||||
/// </remarks>
|
||||
/// <param name="token">Cloud access token. Can be retrieved by calling <see cref="CloudProjectSettings.accessToken"/></param>
|
||||
public static async Task<APIResult> LoginWithTokenAsync(string token)
|
||||
{
|
||||
FormUrlEncodedContent data = GetLoginContent(new Dictionary<string, string> { { "user_access_token", token } });
|
||||
return await LoginAsync(data);
|
||||
}
|
||||
|
||||
private static async Task<APIResult> LoginAsync(FormUrlEncodedContent data)
|
||||
{
|
||||
OverrideAssetStoreUrl();
|
||||
Uri uri = new Uri($"{AssetStoreProdUrl}/login");
|
||||
|
||||
httpClient.DefaultRequestHeaders.Clear();
|
||||
httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
|
||||
|
||||
try
|
||||
{
|
||||
var response = await httpClient.PostAsync(uri, data);
|
||||
return UploadValuesCompletedLogin(response);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new APIResult() { Success = false, Error = ASError.GetGenericError(e) };
|
||||
}
|
||||
}
|
||||
|
||||
private static APIResult UploadValuesCompletedLogin(HttpResponseMessage response)
|
||||
{
|
||||
ASDebug.Log($"Upload Values Complete {response.ReasonPhrase}");
|
||||
ASDebug.Log($"Login success? {response.IsSuccessStatusCode}");
|
||||
try
|
||||
{
|
||||
response.EnsureSuccessStatusCode();
|
||||
var responseResult = response.Content.ReadAsStringAsync().Result;
|
||||
var success = JSONParser.AssetStoreResponseParse(responseResult, out ASError error, out JsonValue jsonResult);
|
||||
if (success)
|
||||
return new APIResult() { Success = true, Response = jsonResult };
|
||||
else
|
||||
return new APIResult() { Success = false, Error = error };
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
return new APIResult() { Success = false, Error = ASError.GetLoginError(response, ex) };
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Package Metadata API
|
||||
|
||||
private static async Task<JsonValue> GetPackageDataMain()
|
||||
{
|
||||
return await GetAssetStoreData(APIUri("asset-store-tools", "metadata/0", SavedSessionId));
|
||||
}
|
||||
|
||||
private static async Task<JsonValue> GetPackageDataExtra()
|
||||
{
|
||||
return await GetAssetStoreData(APIUri("management", "packages", SavedSessionId));
|
||||
}
|
||||
|
||||
private static async Task<JsonValue> GetCategories(bool useCached)
|
||||
{
|
||||
if (useCached)
|
||||
{
|
||||
if (AssetStoreCache.GetCachedCategories(out JsonValue cachedCategoryJson))
|
||||
return cachedCategoryJson;
|
||||
|
||||
ASDebug.LogWarning("Failed to retrieve cached category data. Proceeding to download");
|
||||
}
|
||||
var categoryJson = await GetAssetStoreData(APIUri("management", "categories", SavedSessionId));
|
||||
AssetStoreCache.CacheCategories(categoryJson);
|
||||
|
||||
return categoryJson;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve data for all packages associated with the currently logged in account (identified by <see cref="SavedSessionId"/>)
|
||||
/// </summary>
|
||||
/// <param name="useCached"></param>
|
||||
/// <returns></returns>
|
||||
public static async Task<APIResult> GetFullPackageDataAsync(bool useCached)
|
||||
{
|
||||
if (useCached)
|
||||
{
|
||||
if (AssetStoreCache.GetCachedPackageMetadata(out JsonValue cachedData))
|
||||
return new APIResult() { Success = true, Response = cachedData };
|
||||
|
||||
ASDebug.LogWarning("Failed to retrieve cached package metadata. Proceeding to download");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var jsonMainData = await GetPackageDataMain();
|
||||
var jsonExtraData = await GetPackageDataExtra();
|
||||
var jsonCategoryData = await GetCategories(useCached);
|
||||
|
||||
var joinedData = MergePackageData(jsonMainData, jsonExtraData, jsonCategoryData);
|
||||
AssetStoreCache.CachePackageMetadata(joinedData);
|
||||
|
||||
return new APIResult() { Success = true, Response = joinedData };
|
||||
}
|
||||
catch (OperationCanceledException e)
|
||||
{
|
||||
ASDebug.Log("Package metadata download operation cancelled");
|
||||
DisposeDownloadCancellation();
|
||||
return new APIResult() { Success = false, SilentFail = true, Error = ASError.GetGenericError(e) };
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new APIResult() { Success = false, Error = ASError.GetGenericError(e) };
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the thumbnail textures for all packages within the provided json structure and perform a given action after each retrieval
|
||||
/// </summary>
|
||||
/// <param name="packageJson">A json file retrieved from <see cref="GetFullPackageDataAsync(bool)"/></param>
|
||||
/// <param name="useCached">Return cached thumbnails if they are found</param>
|
||||
/// <param name="onSuccess">
|
||||
/// Action to perform upon a successful thumbnail retrieval <para/>
|
||||
/// <see cref="string"/> - Package Id <br/>
|
||||
/// <see cref="Texture2D"/> - Associated Thumbnail
|
||||
/// </param>
|
||||
/// <param name="onFail">
|
||||
/// Action to perform upon a failed thumbnail retrieval <para/>
|
||||
/// <see cref="string"/> - Package Id <br/>
|
||||
/// <see cref="ASError"/> - Associated error
|
||||
/// </param>
|
||||
public static async void GetPackageThumbnails(JsonValue packageJson, bool useCached, Action<string, Texture2D> onSuccess, Action<string, ASError> onFail)
|
||||
{
|
||||
SetupDownloadCancellation();
|
||||
var packageDict = packageJson["packages"].AsDict();
|
||||
var packageEnum = packageDict.GetEnumerator();
|
||||
|
||||
for (int i = 0; i < packageDict.Count; i++)
|
||||
{
|
||||
packageEnum.MoveNext();
|
||||
var package = packageEnum.Current;
|
||||
|
||||
try
|
||||
{
|
||||
s_downloadCancellationSource.Token.ThrowIfCancellationRequested();
|
||||
|
||||
if (package.Value["icon_url"]
|
||||
.IsNull()) // If no URL is found in the package metadata, use the default image
|
||||
{
|
||||
Texture2D fallbackTexture = null;
|
||||
ASDebug.Log($"Package {package.Key} has no thumbnail. Returning default image");
|
||||
onSuccess?.Invoke(package.Key, fallbackTexture);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (useCached &&
|
||||
AssetStoreCache.GetCachedTexture(package.Key,
|
||||
out Texture2D texture)) // Try returning cached thumbnails first
|
||||
{
|
||||
ASDebug.Log($"Returning cached thumbnail for package {package.Key}");
|
||||
onSuccess?.Invoke(package.Key, texture);
|
||||
continue;
|
||||
}
|
||||
|
||||
var textureBytes =
|
||||
await DownloadPackageThumbnail(package.Value["icon_url"].AsString());
|
||||
Texture2D tex = new Texture2D(1, 1, TextureFormat.RGBA32, false);
|
||||
tex.LoadImage(textureBytes);
|
||||
AssetStoreCache.CacheTexture(package.Key, tex);
|
||||
ASDebug.Log($"Returning downloaded thumbnail for package {package.Key}");
|
||||
onSuccess?.Invoke(package.Key, tex);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
DisposeDownloadCancellation();
|
||||
ASDebug.Log("Package thumbnail download operation cancelled");
|
||||
return;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
onFail?.Invoke(package.Key, ASError.GetGenericError(e));
|
||||
}
|
||||
finally
|
||||
{
|
||||
packageEnum.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<byte[]> DownloadPackageThumbnail(string url)
|
||||
{
|
||||
// icon_url is presented without http/https
|
||||
Uri uri = new Uri($"https:{url}");
|
||||
|
||||
var textureBytes = await httpClient.GetAsync(uri, s_downloadCancellationSource.Token).
|
||||
ContinueWith((response) => response.Result.Content.ReadAsByteArrayAsync().Result, s_downloadCancellationSource.Token);
|
||||
s_downloadCancellationSource.Token.ThrowIfCancellationRequested();
|
||||
return textureBytes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve, update the cache and return the updated data for a previously cached package
|
||||
/// </summary>
|
||||
public static async Task<APIResult> GetRefreshedPackageData(string packageId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var refreshedDataJson = await GetPackageDataExtra();
|
||||
var refreshedPackage = default(JsonValue);
|
||||
|
||||
// Find the updated package data in the latest data json
|
||||
foreach (var p in refreshedDataJson["packages"].AsList())
|
||||
{
|
||||
if (p["id"] == packageId)
|
||||
{
|
||||
refreshedPackage = p["versions"].AsList()[p["versions"].AsList().Count - 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (refreshedPackage.Equals(default(JsonValue)))
|
||||
return new APIResult() { Success = false, Error = ASError.GetGenericError(new MissingMemberException($"Unable to find downloaded package data for package id {packageId}")) };
|
||||
|
||||
// Check if the supplied package id data has been cached and if it contains the corresponding package
|
||||
if (!AssetStoreCache.GetCachedPackageMetadata(out JsonValue cachedData) ||
|
||||
!cachedData["packages"].AsDict().ContainsKey(packageId))
|
||||
return new APIResult() { Success = false, Error = ASError.GetGenericError(new MissingMemberException($"Unable to find cached package id {packageId}")) };
|
||||
|
||||
var cachedPackage = cachedData["packages"].AsDict()[packageId];
|
||||
|
||||
// Retrieve the category map
|
||||
var categoryJson = await GetCategories(true);
|
||||
var categories = CreateCategoryDictionary(categoryJson);
|
||||
|
||||
// Update the package data
|
||||
cachedPackage["name"] = refreshedPackage["name"].AsString();
|
||||
cachedPackage["status"] = refreshedPackage["status"].AsString();
|
||||
cachedPackage["extra_info"].AsDict()["category_info"].AsDict()["id"] = refreshedPackage["category_id"].AsString();
|
||||
cachedPackage["extra_info"].AsDict()["category_info"].AsDict()["name"] =
|
||||
categories.ContainsKey(refreshedPackage["category_id"]) ? categories[refreshedPackage["category_id"].AsString()] : "Unknown";
|
||||
cachedPackage["extra_info"].AsDict()["modified"] = refreshedPackage["modified"].AsString();
|
||||
cachedPackage["extra_info"].AsDict()["size"] = refreshedPackage["size"].AsString();
|
||||
|
||||
AssetStoreCache.CachePackageMetadata(cachedData);
|
||||
return new APIResult() { Success = true, Response = cachedPackage };
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
ASDebug.Log("Package metadata download operation cancelled");
|
||||
DisposeDownloadCancellation();
|
||||
return new APIResult() { Success = false, SilentFail = true };
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new APIResult() { Success = false, Error = ASError.GetGenericError(e) };
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve all Unity versions that the given package has already had uploaded content with
|
||||
/// </summary>
|
||||
/// <param name="packageId"></param>
|
||||
/// <param name="versionId"></param>
|
||||
/// <returns></returns>
|
||||
public static List<string> GetPackageUploadedVersions(string packageId, string versionId)
|
||||
{
|
||||
var versions = new List<string>();
|
||||
try
|
||||
{
|
||||
// Retrieve the data for already uploaded versions (should prevent interaction with Uploader)
|
||||
var versionsTask = Task.Run(() => GetAssetStoreData(APIUri("content", $"preview/{packageId}/{versionId}", SavedSessionId)));
|
||||
if (!versionsTask.Wait(5000))
|
||||
throw new TimeoutException("Could not retrieve uploaded versions within a reasonable time interval");
|
||||
|
||||
var versionsJson = versionsTask.Result;
|
||||
foreach (var version in versionsJson["content"].AsDict()["unity_versions"].AsList())
|
||||
versions.Add(version.AsString());
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
ASDebug.Log("Package version download operation cancelled");
|
||||
DisposeDownloadCancellation();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ASDebug.LogError(e);
|
||||
}
|
||||
|
||||
return versions;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Package Upload API
|
||||
|
||||
/// <summary>
|
||||
/// Upload a content file (.unitypackage) to a provided package version
|
||||
/// </summary>
|
||||
/// <param name="versionId"></param>
|
||||
/// <param name="packageName">Name of the package. Only used for identifying the package in <see cref="OngoingUpload"/> class</param>
|
||||
/// <param name="filePath">Path to the .unitypackage file</param>
|
||||
/// <param name="localPackageGuid">The <see cref="AssetDatabase.AssetPathToGUID(string)"/> value of the main content folder for the provided package</param>
|
||||
/// <param name="localPackagePath">The local path (relative to the root project folder) of the main content folder for the provided package</param>
|
||||
/// <param name="localProjectPath">The path to the project that this package was built from</param>
|
||||
/// <returns></returns>
|
||||
public static async Task<PackageUploadResult> UploadPackageAsync(string versionId, string packageName, string filePath,
|
||||
string localPackageGuid, string localPackagePath, string localProjectPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
ASDebug.Log("Upload task starting");
|
||||
EditorApplication.LockReloadAssemblies();
|
||||
|
||||
if (!IsUploading) // Only subscribe before the first upload
|
||||
EditorApplication.playModeStateChanged += EditorPlayModeStateChangeHandler;
|
||||
|
||||
var progressData = new OngoingUpload(versionId, packageName);
|
||||
ActiveUploads.TryAdd(versionId, progressData);
|
||||
|
||||
var result = await Task.Run(() => UploadPackageTask(progressData, filePath, localPackageGuid, localPackagePath, localProjectPath));
|
||||
|
||||
ActiveUploads.TryRemove(versionId, out OngoingUpload _);
|
||||
|
||||
ASDebug.Log("Upload task finished");
|
||||
return result;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ASDebug.LogError("Upload task failed with an exception: " + e);
|
||||
ActiveUploads.TryRemove(versionId, out OngoingUpload _);
|
||||
return PackageUploadResult.PackageUploadFail(ASError.GetGenericError(e));
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!IsUploading) // Only unsubscribe after the last upload
|
||||
EditorApplication.playModeStateChanged -= EditorPlayModeStateChangeHandler;
|
||||
|
||||
EditorApplication.UnlockReloadAssemblies();
|
||||
}
|
||||
}
|
||||
|
||||
private static PackageUploadResult UploadPackageTask(OngoingUpload currentUpload, string filePath,
|
||||
string localPackageGuid, string localPackagePath, string localProjectPath)
|
||||
{
|
||||
ASDebug.Log("Preparing to upload package within API");
|
||||
string api = "asset-store-tools";
|
||||
string uri = $"package/{currentUpload.VersionId}/unitypackage";
|
||||
|
||||
Dictionary<string, string> packageParams = new Dictionary<string, string>
|
||||
{
|
||||
// Note: project_path is currently used to store UI selections
|
||||
{"root_guid", localPackageGuid},
|
||||
{"root_path", localPackagePath},
|
||||
{"project_path", localProjectPath}
|
||||
};
|
||||
|
||||
ASDebug.Log($"Creating upload request for {currentUpload.VersionId} {currentUpload.PackageName}");
|
||||
|
||||
FileStream requestFileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
|
||||
|
||||
bool responseTimedOut = false;
|
||||
long chunkSize = 32768;
|
||||
try
|
||||
{
|
||||
ASDebug.Log("Starting upload process...");
|
||||
|
||||
var content = new StreamContent(requestFileStream, (int)chunkSize);
|
||||
var response = httpClient.PutAsync(APIUri(api, uri, SavedSessionId, packageParams), content, currentUpload.CancellationToken);
|
||||
|
||||
// Progress tracking
|
||||
int updateIntervalMs = 100;
|
||||
bool allBytesSent = false;
|
||||
DateTime timeOfCompletion = default(DateTime);
|
||||
|
||||
while (!response.IsCompleted)
|
||||
{
|
||||
float uploadProgress = (float)requestFileStream.Position / requestFileStream.Length * 100;
|
||||
currentUpload.UpdateProgress(uploadProgress);
|
||||
Thread.Sleep(updateIntervalMs);
|
||||
|
||||
// A timeout for rare cases, when package uploading reaches 100%, but PutAsync 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)
|
||||
{
|
||||
responseTimedOut = true;
|
||||
currentUpload.Cancel();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2020.3 - although cancellation token shows a requested cancellation, the HttpClient
|
||||
// tends to return a false 'IsCanceled' value, thus yielding an exception when attempting to read the response.
|
||||
// For now we'll just check the token as well, but this needs to be investigated later on.
|
||||
if (response.IsCanceled || currentUpload.CancellationToken.IsCancellationRequested)
|
||||
currentUpload.CancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var responseString = response.Result.Content.ReadAsStringAsync().Result;
|
||||
|
||||
var success = JSONParser.AssetStoreResponseParse(responseString, out ASError error, out JsonValue json);
|
||||
ASDebug.Log("Upload response JSON: " + json.ToString());
|
||||
if (success)
|
||||
return PackageUploadResult.PackageUploadSuccess();
|
||||
else
|
||||
return PackageUploadResult.PackageUploadFail(error);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// Uploading is canceled
|
||||
if (!responseTimedOut)
|
||||
{
|
||||
ASDebug.Log("Upload operation cancelled");
|
||||
return PackageUploadResult.PackageUploadCancelled();
|
||||
}
|
||||
else
|
||||
{
|
||||
ASDebug.LogWarning("All data has been uploaded, but waiting for the response timed out");
|
||||
return PackageUploadResult.PackageUploadResponseTimeout();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ASDebug.LogError("Upload operation encountered an undefined exception: " + e);
|
||||
var fullError = e.InnerException != null ? ASError.GetGenericError(e.InnerException) : ASError.GetGenericError(e);
|
||||
return PackageUploadResult.PackageUploadFail(fullError);
|
||||
}
|
||||
finally
|
||||
{
|
||||
requestFileStream.Dispose();
|
||||
currentUpload.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cancel the uploading task for a package with the provided package id
|
||||
/// </summary>
|
||||
public static void AbortPackageUpload(string packageId)
|
||||
{
|
||||
ActiveUploads[packageId]?.Cancel();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Utility Methods
|
||||
|
||||
public static async Task<APIResult> GetLatestAssetStoreToolsVersion()
|
||||
{
|
||||
try
|
||||
{
|
||||
var url = "https://api.assetstore.unity3d.com/package/latest-version/115";
|
||||
var result = await httpClient.GetAsync(url);
|
||||
|
||||
result.EnsureSuccessStatusCode();
|
||||
|
||||
var resultStr = await result.Content.ReadAsStringAsync();
|
||||
|
||||
var json = JSONParser.SimpleParse(resultStr);
|
||||
|
||||
return new APIResult() { Success = true, Response = json };
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new APIResult() { Success = false, Error = ASError.GetGenericError(e) };
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetLicenseHash()
|
||||
{
|
||||
return UnityEditorInternal.InternalEditorUtility.GetAuthToken().Substring(0, 40);
|
||||
}
|
||||
|
||||
private static string GetHardwareHash()
|
||||
{
|
||||
return UnityEditorInternal.InternalEditorUtility.GetAuthToken().Substring(40, 40);
|
||||
}
|
||||
|
||||
private static FormUrlEncodedContent GetLoginContent(Dictionary<string, string> loginData)
|
||||
{
|
||||
loginData.Add("unityversion", Application.unityVersion);
|
||||
loginData.Add("toolversion", ToolVersion);
|
||||
loginData.Add("license_hash", GetLicenseHash());
|
||||
loginData.Add("hardware_hash", GetHardwareHash());
|
||||
|
||||
return new FormUrlEncodedContent(loginData);
|
||||
}
|
||||
|
||||
private static async Task<JsonValue> GetAssetStoreData(Uri uri)
|
||||
{
|
||||
SetupDownloadCancellation();
|
||||
|
||||
var response = await httpClient.GetAsync(uri, s_downloadCancellationSource.Token)
|
||||
.ContinueWith((x) => x.Result.Content.ReadAsStringAsync().Result, s_downloadCancellationSource.Token);
|
||||
s_downloadCancellationSource.Token.ThrowIfCancellationRequested();
|
||||
|
||||
if (!JSONParser.AssetStoreResponseParse(response, out var error, out var jsonMainData))
|
||||
throw error.Exception;
|
||||
|
||||
return jsonMainData;
|
||||
}
|
||||
|
||||
private static Uri APIUri(string apiPath, string endPointPath, string sessionId)
|
||||
{
|
||||
return APIUri(apiPath, endPointPath, sessionId, null);
|
||||
}
|
||||
|
||||
// Method borrowed from A$ tools, could maybe be simplified to only retain what is necessary?
|
||||
private static Uri APIUri(string apiPath, string endPointPath, string sessionId, IDictionary<string, string> extraQuery)
|
||||
{
|
||||
Dictionary<string, string> extraQueryMerged;
|
||||
|
||||
if (extraQuery == null)
|
||||
extraQueryMerged = new Dictionary<string, string>();
|
||||
else
|
||||
extraQueryMerged = new Dictionary<string, string>(extraQuery);
|
||||
|
||||
extraQueryMerged.Add("unityversion", Application.unityVersion);
|
||||
extraQueryMerged.Add("toolversion", ToolVersion);
|
||||
extraQueryMerged.Add("xunitysession", sessionId);
|
||||
|
||||
string uriPath = $"{AssetStoreProdUrl}/api/{apiPath}/{endPointPath}.json";
|
||||
UriBuilder uriBuilder = new UriBuilder(uriPath);
|
||||
|
||||
StringBuilder queryToAppend = new StringBuilder();
|
||||
foreach (KeyValuePair<string, string> queryPair in extraQueryMerged)
|
||||
{
|
||||
string queryName = queryPair.Key;
|
||||
string queryValue = Uri.EscapeDataString(queryPair.Value);
|
||||
|
||||
queryToAppend.AppendFormat("&{0}={1}", queryName, queryValue);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(uriBuilder.Query))
|
||||
uriBuilder.Query = uriBuilder.Query.Substring(1) + queryToAppend;
|
||||
else
|
||||
uriBuilder.Query = queryToAppend.Remove(0, 1).ToString();
|
||||
|
||||
return uriBuilder.Uri;
|
||||
}
|
||||
|
||||
private static JsonValue MergePackageData(JsonValue mainPackageData, JsonValue extraPackageData, JsonValue categoryData)
|
||||
{
|
||||
ASDebug.Log($"Main package data\n{mainPackageData}");
|
||||
var mainDataDict = mainPackageData["packages"].AsDict();
|
||||
|
||||
// Most likely both of them will be true at the same time, but better to be safe
|
||||
if (mainDataDict.Count == 0 || !extraPackageData.ContainsKey("packages"))
|
||||
return new JsonValue();
|
||||
|
||||
ASDebug.Log($"Extra package data\n{extraPackageData}");
|
||||
var extraDataDict = extraPackageData["packages"].AsList();
|
||||
|
||||
var categories = CreateCategoryDictionary(categoryData);
|
||||
|
||||
foreach (var md in mainDataDict)
|
||||
{
|
||||
foreach (var ed in extraDataDict)
|
||||
{
|
||||
if (ed["id"].AsString() != md.Key)
|
||||
continue;
|
||||
|
||||
// Create a field for extra data
|
||||
var extraData = JsonValue.NewDict();
|
||||
|
||||
// Add category field
|
||||
var categoryEntry = JsonValue.NewDict();
|
||||
|
||||
var categoryId = ed["category_id"].AsString();
|
||||
var categoryName = categories.ContainsKey(categoryId) ? categories[categoryId] : "Unknown";
|
||||
|
||||
categoryEntry["id"] = categoryId;
|
||||
categoryEntry["name"] = categoryName;
|
||||
|
||||
extraData["category_info"] = categoryEntry;
|
||||
|
||||
// Add modified time and size
|
||||
var versions = ed["versions"].AsList();
|
||||
extraData["modified"] = versions[versions.Count - 1]["modified"];
|
||||
extraData["size"] = versions[versions.Count - 1]["size"];
|
||||
|
||||
md.Value.AsDict()["extra_info"] = extraData;
|
||||
}
|
||||
}
|
||||
|
||||
mainPackageData.AsDict()["packages"] = new JsonValue(mainDataDict);
|
||||
return mainPackageData;
|
||||
}
|
||||
|
||||
private static Dictionary<string, string> CreateCategoryDictionary(JsonValue json)
|
||||
{
|
||||
var categories = new Dictionary<string, string>();
|
||||
|
||||
var list = json.AsList();
|
||||
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
var category = list[i].AsDict();
|
||||
if (category["status"].AsString() == "deprecated")
|
||||
continue;
|
||||
categories.Add(category["id"].AsString(), category["assetstore_name"].AsString());
|
||||
}
|
||||
|
||||
return categories;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the account data is for a valid publisher account
|
||||
/// </summary>
|
||||
/// <param name="json">Json structure retrieved from one of the API login methods</param>
|
||||
public static bool IsPublisherValid(JsonValue json, out ASError error)
|
||||
{
|
||||
error = ASError.GetPublisherNullError(json["name"]);
|
||||
|
||||
if (!json.ContainsKey("publisher"))
|
||||
return false;
|
||||
|
||||
// If publisher account is not created - let them know
|
||||
return !json["publisher"].IsNull();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cancel all data retrieval tasks
|
||||
/// </summary>
|
||||
public static void AbortDownloadTasks()
|
||||
{
|
||||
s_downloadCancellationSource?.Cancel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cancel all data uploading tasks
|
||||
/// </summary>
|
||||
public static void AbortUploadTasks()
|
||||
{
|
||||
foreach (var upload in ActiveUploads)
|
||||
{
|
||||
AbortPackageUpload(upload.Key);
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetupDownloadCancellation()
|
||||
{
|
||||
if (s_downloadCancellationSource != null && s_downloadCancellationSource.IsCancellationRequested)
|
||||
DisposeDownloadCancellation();
|
||||
|
||||
if (s_downloadCancellationSource == null)
|
||||
s_downloadCancellationSource = new CancellationTokenSource();
|
||||
}
|
||||
|
||||
private static void DisposeDownloadCancellation()
|
||||
{
|
||||
s_downloadCancellationSource?.Dispose();
|
||||
s_downloadCancellationSource = null;
|
||||
}
|
||||
|
||||
private static void EditorPlayModeStateChangeHandler(PlayModeStateChange state)
|
||||
{
|
||||
if (state != 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");
|
||||
}
|
||||
|
||||
private static void OverrideAssetStoreUrl()
|
||||
{
|
||||
var args = Environment.GetCommandLineArgs();
|
||||
for (var i = 0; i < args.Length; i++)
|
||||
{
|
||||
if (!args[i].Equals("-assetStoreUrl"))
|
||||
continue;
|
||||
|
||||
if (i + 1 >= args.Length)
|
||||
return;
|
||||
|
||||
ASDebug.Log($"Overriding A$ URL to: {args[i + 1]}");
|
||||
AssetStoreProdUrl = args[i + 1];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9e3cae7082463da41b807724242fd617
|
||||
guid: 930cfc857321b1048bf9607d4c8f89d3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine.Analytics;
|
||||
|
||||
namespace AssetStoreTools.Uploader.Data
|
||||
{
|
||||
internal static class ASAnalytics
|
||||
{
|
||||
private const int VersionId = 3;
|
||||
private const int MaxEventsPerHour = 20;
|
||||
private const int MaxNumberOfElements = 1000;
|
||||
|
||||
private const string VendorKey = "unity.assetStoreTools";
|
||||
private const string EventName = "assetStoreTools";
|
||||
|
||||
static bool EnableAnalytics()
|
||||
{
|
||||
#if UNITY_2023_2_OR_NEWER
|
||||
return true;
|
||||
#else
|
||||
var result = EditorAnalytics.RegisterEventWithLimit(EventName, MaxEventsPerHour, MaxNumberOfElements, VendorKey, VersionId);
|
||||
return result == AnalyticsResult.Ok;
|
||||
#endif
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public struct AnalyticsData
|
||||
#if UNITY_2023_2_OR_NEWER
|
||||
: IAnalytic.IData
|
||||
#endif
|
||||
{
|
||||
public string ToolVersion;
|
||||
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;
|
||||
}
|
||||
|
||||
#if UNITY_2023_2_OR_NEWER
|
||||
[AnalyticInfo(eventName: EventName, vendorKey: VendorKey, version: VersionId, maxEventsPerHour: MaxEventsPerHour, maxNumberOfElements: MaxNumberOfElements)]
|
||||
private class AssetStoreToolsAnalytic : IAnalytic
|
||||
{
|
||||
private AnalyticsData _data;
|
||||
|
||||
public AssetStoreToolsAnalytic(AnalyticsData data)
|
||||
{
|
||||
_data = data;
|
||||
}
|
||||
|
||||
public bool TryGatherData(out IAnalytic.IData data, out Exception error)
|
||||
{
|
||||
error = null;
|
||||
data = _data;
|
||||
return data != null;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public static void SendUploadingEvent(AnalyticsData data)
|
||||
{
|
||||
if (!EditorAnalytics.enabled)
|
||||
return;
|
||||
|
||||
if (!EnableAnalytics())
|
||||
return;
|
||||
|
||||
#if UNITY_2023_2_OR_NEWER
|
||||
var analytic = new AssetStoreToolsAnalytic(data);
|
||||
EditorAnalytics.SendAnalytic(analytic);
|
||||
#else
|
||||
EditorAnalytics.SendEventWithLimit(EventName, data, VersionId);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1095145789a64767a6add837eea19786
|
||||
timeCreated: 1658832954
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 11.4.4
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/Data/ASAnalytics.cs
|
||||
uploadId: 712972
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3eb6991a3db8cc34dad63504bc6c3c0e
|
||||
guid: 771776e4d51c47945b3449d4de948c00
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using PackageModel = AssetStoreTools.Api.Models.Package;
|
||||
|
||||
namespace AssetStoreTools.Uploader.Data
|
||||
{
|
||||
internal interface IPackage
|
||||
{
|
||||
string PackageId { get; }
|
||||
string VersionId { get; }
|
||||
string Name { get; }
|
||||
string Status { get; }
|
||||
string Category { get; }
|
||||
bool IsCompleteProject { get; }
|
||||
string RootGuid { get; }
|
||||
string RootPath { get; }
|
||||
string ProjectPath { get; }
|
||||
string Modified { get; }
|
||||
string Size { get; }
|
||||
bool IsDraft { get; }
|
||||
Texture2D Icon { get; }
|
||||
|
||||
event Action OnUpdate;
|
||||
event Action OnIconUpdate;
|
||||
|
||||
string FormattedSize();
|
||||
string FormattedModified();
|
||||
|
||||
void UpdateData(PackageModel source);
|
||||
void UpdateIcon(Texture2D texture);
|
||||
|
||||
PackageModel ToModel();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b92f2ed98d0b31a479aa2bfd95528fbd
|
||||
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/Data/Abstractions/IPackage.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AssetStoreTools.Uploader.Data
|
||||
{
|
||||
internal interface IPackageContent
|
||||
{
|
||||
event Action<IWorkflow> OnActiveWorkflowChanged;
|
||||
|
||||
IWorkflow GetActiveWorkflow();
|
||||
List<IWorkflow> GetAvailableWorkflows();
|
||||
void SetActiveWorkflow(IWorkflow workflow);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 45ce41158c3174149b7056a30ac901db
|
||||
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/Data/Abstractions/IPackageContent.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AssetStoreTools.Uploader.Data
|
||||
{
|
||||
internal interface IPackageGroup
|
||||
{
|
||||
string Name { get; }
|
||||
List<IPackage> Packages { get; }
|
||||
|
||||
event Action<List<IPackage>> OnPackagesSorted;
|
||||
event Action<List<IPackage>> OnPackagesFiltered;
|
||||
|
||||
void Sort(PackageSorting sortingType);
|
||||
void Filter(string filter);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f683845071b8891498156d95a1a5c2dd
|
||||
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/Data/Abstractions/IPackageGroup.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,36 @@
|
||||
using AssetStoreTools.Api;
|
||||
using AssetStoreTools.Api.Responses;
|
||||
using AssetStoreTools.Exporter;
|
||||
using AssetStoreTools.Validator.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AssetStoreTools.Uploader.Data
|
||||
{
|
||||
internal interface IWorkflow
|
||||
{
|
||||
string Name { get; }
|
||||
string DisplayName { get; }
|
||||
string PackageName { get; }
|
||||
string PackageExtension { get; }
|
||||
bool IsPathSet { get; }
|
||||
|
||||
event Action OnChanged;
|
||||
event Action<UploadStatus?, float?> OnUploadStateChanged;
|
||||
|
||||
bool GenerateHighQualityPreviews { get; set; }
|
||||
ValidationSettings LastValidationSettings { get; }
|
||||
ValidationResult LastValidationResult { get; }
|
||||
|
||||
IEnumerable<string> GetAllPaths();
|
||||
ValidationResult Validate();
|
||||
Task<PackageExporterResult> ExportPackage(string outputPath);
|
||||
Task<bool> ValidatePackageUploadedVersions();
|
||||
|
||||
Task<PackageUploadResponse> UploadPackage(string exportedPackagePath);
|
||||
void AbortUpload();
|
||||
void ResetUploadStatus();
|
||||
Task RefreshPackage();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a2f796eadafa774bae89cf3939611dd
|
||||
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/Data/Abstractions/IWorkflow.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,18 @@
|
||||
using AssetStoreTools.Api;
|
||||
using AssetStoreTools.Api.Responses;
|
||||
using AssetStoreTools.Uploader.Services.Analytics.Data;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine.Analytics;
|
||||
|
||||
namespace AssetStoreTools.Uploader.Data
|
||||
{
|
||||
internal interface IWorkflowServices
|
||||
{
|
||||
Task<PackageUploadedUnityVersionDataResponse> GetPackageUploadedVersions(IPackage package, int timeoutMs);
|
||||
Task<PackageUploadResponse> UploadPackage(IPackageUploader uploader, IProgress<float> progress);
|
||||
void StopUploading(IPackageUploader uploader);
|
||||
AnalyticsResult SendAnalytic(IAssetStoreAnalytic data);
|
||||
Task<RefreshedPackageDataResponse> UpdatePackageData(IPackage package);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ae017363fa41ff4d9926dc4a5852246
|
||||
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/Data/Abstractions/IWorkflowServices.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,253 @@
|
||||
using AssetStoreTools.Api;
|
||||
using AssetStoreTools.Api.Responses;
|
||||
using AssetStoreTools.Exporter;
|
||||
using AssetStoreTools.Previews;
|
||||
using AssetStoreTools.Previews.Data;
|
||||
using AssetStoreTools.Previews.Generators;
|
||||
using AssetStoreTools.Uploader.Services.Analytics.Data;
|
||||
using AssetStoreTools.Utility;
|
||||
using AssetStoreTools.Validator;
|
||||
using AssetStoreTools.Validator.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AssetStoreTools.Uploader.Data
|
||||
{
|
||||
internal abstract class WorkflowBase : IWorkflow
|
||||
{
|
||||
protected IPackage Package;
|
||||
|
||||
public abstract string Name { get; }
|
||||
public abstract string DisplayName { get; }
|
||||
public string PackageName => Package.Name;
|
||||
public abstract string PackageExtension { get; }
|
||||
public abstract bool IsPathSet { get; }
|
||||
|
||||
protected string LocalPackageGuid;
|
||||
protected string LocalPackagePath;
|
||||
protected string LocalProjectPath;
|
||||
|
||||
public bool GenerateHighQualityPreviews { get; set; }
|
||||
public ValidationSettings LastValidationSettings { get; private set; }
|
||||
public ValidationResult LastValidationResult { get; private set; }
|
||||
|
||||
private IWorkflowServices _services;
|
||||
private IPackageUploader _activeUploader;
|
||||
|
||||
public abstract event Action OnChanged;
|
||||
public event Action<UploadStatus?, float?> OnUploadStateChanged;
|
||||
|
||||
public WorkflowBase(IPackage package, IWorkflowServices services)
|
||||
{
|
||||
Package = package;
|
||||
_services = services;
|
||||
}
|
||||
|
||||
public abstract IEnumerable<string> GetAllPaths();
|
||||
|
||||
public abstract IValidator CreateValidator();
|
||||
|
||||
public ValidationResult Validate()
|
||||
{
|
||||
var validator = CreateValidator();
|
||||
var result = CreateValidator().Validate();
|
||||
|
||||
LastValidationSettings = validator.Settings;
|
||||
LastValidationResult = result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected IPreviewGenerator CreatePreviewGenerator(List<string> inputPaths)
|
||||
{
|
||||
PreviewGenerationSettings settings;
|
||||
IPreviewGenerator generator;
|
||||
|
||||
// Filter out ProjectSettings
|
||||
inputPaths = inputPaths.Where(x => x == "Assets" || x.StartsWith("Assets/") || x.StartsWith("Packages/")).ToList();
|
||||
|
||||
if (!GenerateHighQualityPreviews)
|
||||
{
|
||||
settings = new NativePreviewGenerationSettings()
|
||||
{
|
||||
InputPaths = inputPaths.ToArray(),
|
||||
OverwriteExisting = false,
|
||||
OutputPath = Constants.Previews.Native.DefaultOutputPath,
|
||||
Format = Constants.Previews.Native.DefaultFormat,
|
||||
PreviewFileNamingFormat = Constants.Previews.DefaultFileNameFormat,
|
||||
WaitForPreviews = Constants.Previews.Native.DefaultWaitForPreviews,
|
||||
ChunkedPreviewLoading = Constants.Previews.Native.DefaultChunkedPreviewLoading,
|
||||
ChunkSize = Constants.Previews.Native.DefaultChunkSize
|
||||
};
|
||||
|
||||
generator = new NativePreviewGenerator((NativePreviewGenerationSettings)settings);
|
||||
}
|
||||
else
|
||||
{
|
||||
settings = new CustomPreviewGenerationSettings()
|
||||
{
|
||||
InputPaths = inputPaths.ToArray(),
|
||||
OverwriteExisting = false,
|
||||
Width = Constants.Previews.Custom.DefaultWidth,
|
||||
Height = Constants.Previews.Custom.DefaultHeight,
|
||||
Depth = Constants.Previews.Custom.DefaultDepth,
|
||||
NativeWidth = Constants.Previews.Custom.DefaultNativeWidth,
|
||||
NativeHeight = Constants.Previews.Custom.DefaultNativeHeight,
|
||||
OutputPath = Constants.Previews.Custom.DefaultOutputPath,
|
||||
Format = Constants.Previews.Custom.DefaultFormat,
|
||||
PreviewFileNamingFormat = Constants.Previews.DefaultFileNameFormat,
|
||||
AudioSampleColor = Constants.Previews.Custom.DefaultAudioSampleColor,
|
||||
AudioBackgroundColor = Constants.Previews.Custom.DefaultAudioBackgroundColor,
|
||||
};
|
||||
|
||||
generator = new CustomPreviewGenerator((CustomPreviewGenerationSettings)settings);
|
||||
}
|
||||
|
||||
return generator;
|
||||
}
|
||||
|
||||
public abstract IPackageExporter CreateExporter(string outputPath);
|
||||
|
||||
public virtual async Task<PackageExporterResult> ExportPackage(string outputPath)
|
||||
{
|
||||
var exporter = CreateExporter(outputPath);
|
||||
var result = await exporter.Export();
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<bool> ValidatePackageUploadedVersions()
|
||||
{
|
||||
var unityVersionSupported = string.Compare(Application.unityVersion, Constants.Uploader.MinRequiredUnitySupportVersion, StringComparison.Ordinal) >= 0;
|
||||
if (unityVersionSupported)
|
||||
return true;
|
||||
|
||||
var response = await _services.GetPackageUploadedVersions(Package, 5000);
|
||||
if (response.Cancelled || response.Success == false)
|
||||
return true;
|
||||
|
||||
return response.UnityVersions.Any(x => string.Compare(x, Constants.Uploader.MinRequiredUnitySupportVersion, StringComparison.Ordinal) >= 0);
|
||||
}
|
||||
|
||||
private bool ValidatePackageBeforeUpload(string packagePath, out string error)
|
||||
{
|
||||
error = string.Empty;
|
||||
|
||||
if (!File.Exists(packagePath))
|
||||
{
|
||||
error = $"File '{packagePath}' was not found.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ValidatePackageSize(packagePath, out error))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool ValidatePackageSize(string packagePath, out string error)
|
||||
{
|
||||
error = string.Empty;
|
||||
|
||||
long packageSize = new FileInfo(packagePath).Length;
|
||||
long packageSizeLimit = Constants.Uploader.MaxPackageSizeBytes;
|
||||
|
||||
if (packageSize <= packageSizeLimit)
|
||||
return true;
|
||||
|
||||
float packageSizeInGB = packageSize / (float)1073741824; // (1024 * 1024 * 1024)
|
||||
float maxPackageSizeInGB = packageSizeLimit / (float)1073741824;
|
||||
error = $"The size of your package ({packageSizeInGB:0.0} GB) exceeds the maximum allowed package size of {maxPackageSizeInGB:0} GB. " +
|
||||
$"Please reduce the size of your package.";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task<PackageUploadResponse> UploadPackage(string packagePath)
|
||||
{
|
||||
if (!ValidatePackageBeforeUpload(packagePath, out var error))
|
||||
{
|
||||
return new PackageUploadResponse() { Success = false, Status = UploadStatus.Fail, Exception = new Exception(error) };
|
||||
}
|
||||
|
||||
_activeUploader = CreatePackageUploader(packagePath);
|
||||
var progress = new Progress<float>();
|
||||
|
||||
var time = System.Diagnostics.Stopwatch.StartNew();
|
||||
|
||||
progress.ProgressChanged += ReportUploadProgress;
|
||||
var response = await _services.UploadPackage(_activeUploader, progress);
|
||||
progress.ProgressChanged -= ReportUploadProgress;
|
||||
|
||||
// Send analytics
|
||||
time.Stop();
|
||||
if (!response.Cancelled)
|
||||
SendAnalytics(packagePath, response.Status, time.Elapsed.TotalSeconds);
|
||||
|
||||
OnUploadStateChanged?.Invoke(response.Status, null);
|
||||
_activeUploader = null;
|
||||
return response;
|
||||
}
|
||||
|
||||
protected abstract IPackageUploader CreatePackageUploader(string exportedPackagePath);
|
||||
|
||||
private void ReportUploadProgress(object _, float value)
|
||||
{
|
||||
OnUploadStateChanged?.Invoke(null, value);
|
||||
}
|
||||
|
||||
private void SendAnalytics(string packagePath, UploadStatus uploadStatus, double timeTakenSeconds)
|
||||
{
|
||||
try
|
||||
{
|
||||
var analytic = new PackageUploadAnalytic(
|
||||
packageId: Package.PackageId,
|
||||
category: Package.Category,
|
||||
usedValidator: LastValidationResult != null,
|
||||
validationSettings: LastValidationSettings,
|
||||
validationResult: LastValidationResult,
|
||||
uploadFinishedReason: uploadStatus,
|
||||
timeTaken: timeTakenSeconds,
|
||||
packageSize: new FileInfo(packagePath).Length,
|
||||
workflow: Name
|
||||
);
|
||||
|
||||
var result = _services.SendAnalytic(analytic);
|
||||
}
|
||||
catch (Exception e) { ASDebug.LogError($"Could not send analytics: {e}"); }
|
||||
}
|
||||
|
||||
public void AbortUpload()
|
||||
{
|
||||
if (_activeUploader != null)
|
||||
_services.StopUploading(_activeUploader);
|
||||
|
||||
_activeUploader = null;
|
||||
}
|
||||
|
||||
public void ResetUploadStatus()
|
||||
{
|
||||
OnUploadStateChanged?.Invoke(UploadStatus.Default, 0f);
|
||||
}
|
||||
|
||||
public async Task RefreshPackage()
|
||||
{
|
||||
var response = await _services.UpdatePackageData(Package);
|
||||
if (!response.Success)
|
||||
return;
|
||||
|
||||
Package.UpdateData(response.Package);
|
||||
}
|
||||
|
||||
public abstract bool IsPathValid(string path, out string reason);
|
||||
|
||||
protected abstract void Serialize();
|
||||
|
||||
protected abstract void Deserialize();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d0e87ee17aa944c42b1c335abe19daaf
|
||||
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/Data/Abstractions/WorkflowBase.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,329 @@
|
||||
using AssetStoreTools.Api;
|
||||
using AssetStoreTools.Exporter;
|
||||
using AssetStoreTools.Uploader.Data.Serialization;
|
||||
using AssetStoreTools.Utility;
|
||||
using AssetStoreTools.Validator;
|
||||
using AssetStoreTools.Validator.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using PackageInfo = UnityEditor.PackageManager.PackageInfo;
|
||||
|
||||
namespace AssetStoreTools.Uploader.Data
|
||||
{
|
||||
internal class AssetsWorkflow : WorkflowBase
|
||||
{
|
||||
public override string Name => "AssetsWorkflow";
|
||||
public override string DisplayName => "From Assets Folder";
|
||||
public override string PackageExtension => ".unitypackage";
|
||||
public override bool IsPathSet => !string.IsNullOrEmpty(_mainExportPath);
|
||||
public bool IsCompleteProject => Package.IsCompleteProject;
|
||||
|
||||
private AssetsWorkflowState _stateData;
|
||||
|
||||
private string _mainExportPath;
|
||||
private bool _includeDependencies;
|
||||
private List<PackageInfo> _dependencies;
|
||||
private List<string> _specialFolders;
|
||||
|
||||
public override event Action OnChanged;
|
||||
|
||||
// Special folders that would not work if not placed directly in the 'Assets' folder
|
||||
private readonly string[] _extraAssetFolderNames =
|
||||
{
|
||||
"Editor Default Resources", "Gizmos", "Plugins",
|
||||
"StreamingAssets", "Standard Assets", "WebGLTemplates",
|
||||
"ExternalDependencyManager", "XR"
|
||||
};
|
||||
|
||||
public AssetsWorkflow(IPackage package, AssetsWorkflowState stateData, IWorkflowServices services)
|
||||
: base(package, services)
|
||||
{
|
||||
_stateData = stateData;
|
||||
Deserialize();
|
||||
}
|
||||
|
||||
public string GetMainExportPath()
|
||||
{
|
||||
return _mainExportPath;
|
||||
}
|
||||
|
||||
public void SetMainExportPath(string path, bool serialize)
|
||||
{
|
||||
_mainExportPath = path;
|
||||
SetMetadata();
|
||||
if (serialize)
|
||||
Serialize();
|
||||
}
|
||||
|
||||
private void SetMetadata()
|
||||
{
|
||||
LocalPackageGuid = AssetDatabase.AssetPathToGUID(_mainExportPath);
|
||||
LocalPackagePath = _mainExportPath;
|
||||
LocalProjectPath = _mainExportPath;
|
||||
}
|
||||
|
||||
public bool GetIncludeDependencies()
|
||||
{
|
||||
return _includeDependencies;
|
||||
}
|
||||
|
||||
public void SetIncludeDependencies(bool value, bool serialize)
|
||||
{
|
||||
_includeDependencies = value;
|
||||
// Note: make sure that exporting does not fail when
|
||||
// a serialized dependency that has been removed from a project is sent to exporter
|
||||
if (serialize)
|
||||
Serialize();
|
||||
}
|
||||
|
||||
public List<PackageInfo> GetDependencies()
|
||||
{
|
||||
return _dependencies;
|
||||
}
|
||||
|
||||
public void SetDependencies(IEnumerable<string> dependencies, bool serialize)
|
||||
{
|
||||
_dependencies.Clear();
|
||||
foreach (var dependency in dependencies)
|
||||
{
|
||||
if (!PackageUtility.GetPackageByPackageName(dependency, out var package))
|
||||
continue;
|
||||
_dependencies.Add(package);
|
||||
}
|
||||
|
||||
if (serialize)
|
||||
Serialize();
|
||||
}
|
||||
|
||||
public List<string> GetSpecialFolders()
|
||||
{
|
||||
return _specialFolders;
|
||||
}
|
||||
|
||||
public void SetSpecialFolders(IEnumerable<string> specialFolders, bool serialize)
|
||||
{
|
||||
_specialFolders.Clear();
|
||||
foreach (var folder in specialFolders)
|
||||
{
|
||||
_specialFolders.Add(folder);
|
||||
}
|
||||
|
||||
if (serialize)
|
||||
Serialize();
|
||||
}
|
||||
|
||||
public override bool IsPathValid(string path, out string error)
|
||||
{
|
||||
error = string.Empty;
|
||||
|
||||
var pathIsFolder = Directory.Exists(path);
|
||||
if (!pathIsFolder)
|
||||
{
|
||||
error = "Path must point to a valid folder";
|
||||
return false;
|
||||
}
|
||||
|
||||
var pathWithinAssetsFolder = path.StartsWith("Assets/") && path != "Assets/";
|
||||
if (pathWithinAssetsFolder)
|
||||
return true;
|
||||
|
||||
var pathIsAssetsFolder = path == "Assets" || path == "Assets/";
|
||||
if (pathIsAssetsFolder)
|
||||
{
|
||||
var assetsFolderSelectionAllowed = Package.IsCompleteProject;
|
||||
if (assetsFolderSelectionAllowed)
|
||||
return true;
|
||||
|
||||
error = "'Assets' folder is only available for packages tagged as a 'Complete Project'.";
|
||||
return false;
|
||||
}
|
||||
|
||||
error = "Selected folder path must be within the project's Assets.";
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<string> GetAvailableDependencies()
|
||||
{
|
||||
var registryPackages = PackageUtility.GetAllRegistryPackages();
|
||||
return registryPackages.Select(x => x.name).ToList();
|
||||
}
|
||||
|
||||
public List<string> GetAvailableSpecialFolders()
|
||||
{
|
||||
var specialFolders = new List<string>();
|
||||
|
||||
foreach (var extraAssetFolderName in _extraAssetFolderNames)
|
||||
{
|
||||
var fullExtraPath = "Assets/" + extraAssetFolderName;
|
||||
|
||||
if (!Directory.Exists(fullExtraPath))
|
||||
continue;
|
||||
|
||||
if (_mainExportPath.ToLower().StartsWith(fullExtraPath.ToLower()))
|
||||
continue;
|
||||
|
||||
// Don't include nested paths
|
||||
if (!fullExtraPath.ToLower().StartsWith(_mainExportPath.ToLower()))
|
||||
specialFolders.Add(fullExtraPath);
|
||||
}
|
||||
|
||||
return specialFolders;
|
||||
}
|
||||
|
||||
public override IEnumerable<string> GetAllPaths()
|
||||
{
|
||||
var paths = new List<string>()
|
||||
{
|
||||
_mainExportPath
|
||||
};
|
||||
paths.AddRange(GetSpecialFolders());
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
public override IValidator CreateValidator()
|
||||
{
|
||||
var validationPaths = GetAllPaths();
|
||||
|
||||
var validationSettings = new CurrentProjectValidationSettings()
|
||||
{
|
||||
Category = Package.Category,
|
||||
ValidationPaths = validationPaths.ToList(),
|
||||
ValidationType = ValidationType.UnityPackage
|
||||
};
|
||||
|
||||
var validator = new CurrentProjectValidator(validationSettings);
|
||||
return validator;
|
||||
}
|
||||
|
||||
public override IPackageExporter CreateExporter(string outputPath)
|
||||
{
|
||||
var exportPaths = GetAllPaths().ToList();
|
||||
|
||||
if (IsCompleteProject && !exportPaths.Contains("ProjectSettings"))
|
||||
{
|
||||
exportPaths.Add("ProjectSettings");
|
||||
}
|
||||
|
||||
var dependenciesToInclude = new List<string>();
|
||||
if (_includeDependencies)
|
||||
{
|
||||
dependenciesToInclude.AddRange(_dependencies.Select(x => x.name));
|
||||
}
|
||||
|
||||
if (ASToolsPreferences.Instance.UseLegacyExporting)
|
||||
{
|
||||
var exportSettings = new LegacyExporterSettings()
|
||||
{
|
||||
ExportPaths = exportPaths.ToArray(),
|
||||
OutputFilename = outputPath,
|
||||
IncludeDependencies = _includeDependencies,
|
||||
};
|
||||
|
||||
return new LegacyPackageExporter(exportSettings);
|
||||
}
|
||||
else
|
||||
{
|
||||
var exportSettings = new DefaultExporterSettings()
|
||||
{
|
||||
ExportPaths = exportPaths.ToArray(),
|
||||
OutputFilename = outputPath,
|
||||
Dependencies = dependenciesToInclude.ToArray(),
|
||||
PreviewGenerator = CreatePreviewGenerator(exportPaths),
|
||||
};
|
||||
|
||||
return new DefaultPackageExporter(exportSettings);
|
||||
}
|
||||
}
|
||||
|
||||
protected override IPackageUploader CreatePackageUploader(string exportedPackagePath)
|
||||
{
|
||||
var uploaderSettings = new UnityPackageUploadSettings()
|
||||
{
|
||||
UnityPackagePath = exportedPackagePath,
|
||||
VersionId = Package.VersionId,
|
||||
RootGuid = LocalPackageGuid,
|
||||
RootPath = LocalPackagePath,
|
||||
ProjectPath = LocalProjectPath
|
||||
};
|
||||
|
||||
var uploader = new UnityPackageUploader(uploaderSettings);
|
||||
return uploader;
|
||||
}
|
||||
|
||||
protected override void Serialize()
|
||||
{
|
||||
_stateData.SetMainPath(_mainExportPath);
|
||||
_stateData.SetIncludeDependencies(_includeDependencies);
|
||||
_stateData.SetDependencies(_dependencies.Select(x => x.name));
|
||||
_stateData.SetSpecialFolders(_specialFolders);
|
||||
OnChanged?.Invoke();
|
||||
}
|
||||
|
||||
protected override void Deserialize()
|
||||
{
|
||||
_mainExportPath = _stateData.GetMainPath();
|
||||
|
||||
_specialFolders = new List<string>();
|
||||
foreach (var path in _stateData.GetSpecialFolders())
|
||||
{
|
||||
_specialFolders.Add(path);
|
||||
}
|
||||
|
||||
_includeDependencies = _stateData.GetIncludeDependencies();
|
||||
|
||||
_dependencies = new List<PackageInfo>();
|
||||
foreach (var dependency in _stateData.GetDependencies())
|
||||
{
|
||||
if (!PackageUtility.GetPackageByPackageName(dependency, out var package))
|
||||
continue;
|
||||
|
||||
_dependencies.Add(package);
|
||||
}
|
||||
|
||||
DeserializeFromUploadedData();
|
||||
}
|
||||
|
||||
private void DeserializeFromUploadedData()
|
||||
{
|
||||
DeserializeFromUploadedDataByGuid();
|
||||
DeserializeFromUploadedDataByPath();
|
||||
}
|
||||
|
||||
private void DeserializeFromUploadedDataByGuid()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_mainExportPath))
|
||||
return;
|
||||
|
||||
var lastUploadedGuid = Package.RootGuid;
|
||||
if (string.IsNullOrEmpty(lastUploadedGuid))
|
||||
return;
|
||||
|
||||
var potentialPackagePath = AssetDatabase.GUIDToAssetPath(lastUploadedGuid);
|
||||
DeserializeFromUploadedDataByPath(potentialPackagePath);
|
||||
}
|
||||
|
||||
private void DeserializeFromUploadedDataByPath()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_mainExportPath))
|
||||
return;
|
||||
|
||||
var lastUploadedPath = Package.ProjectPath;
|
||||
if (string.IsNullOrEmpty(lastUploadedPath))
|
||||
return;
|
||||
|
||||
DeserializeFromUploadedDataByPath(lastUploadedPath);
|
||||
}
|
||||
|
||||
private void DeserializeFromUploadedDataByPath(string path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path) || !IsPathValid(path, out var _))
|
||||
return;
|
||||
|
||||
_mainExportPath = path;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2e5fee0cad7655f458d9b600f4ae6d02
|
||||
guid: 4657d35aaf9d70948a0840dc615f64ec
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -13,6 +13,6 @@ AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 11.4.4
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/Utility/AssetStoreCache.cs
|
||||
uploadId: 712972
|
||||
packageVersion: 12.0.1
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/Data/AssetsWorkflow.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,251 @@
|
||||
using AssetStoreTools.Api;
|
||||
using AssetStoreTools.Exporter;
|
||||
using AssetStoreTools.Uploader.Data.Serialization;
|
||||
using AssetStoreTools.Utility;
|
||||
using AssetStoreTools.Validator;
|
||||
using AssetStoreTools.Validator.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEditor.PackageManager;
|
||||
using PackageInfo = UnityEditor.PackageManager.PackageInfo;
|
||||
using PackageManager = UnityEditor.PackageManager;
|
||||
|
||||
namespace AssetStoreTools.Uploader.Data
|
||||
{
|
||||
internal class HybridPackageWorkflow : WorkflowBase
|
||||
{
|
||||
public override string Name => "HybridPackageWorkflow";
|
||||
public override string DisplayName => "Local UPM Package";
|
||||
public override string PackageExtension => ".unitypackage";
|
||||
public override bool IsPathSet => _packageInfo != null;
|
||||
|
||||
private HybridPackageWorkflowState _stateData;
|
||||
|
||||
private PackageInfo _packageInfo;
|
||||
private List<PackageInfo> _dependencies;
|
||||
|
||||
public override event Action OnChanged;
|
||||
|
||||
public HybridPackageWorkflow(IPackage package, HybridPackageWorkflowState stateData, IWorkflowServices services)
|
||||
: base(package, services)
|
||||
{
|
||||
_stateData = stateData;
|
||||
Deserialize();
|
||||
}
|
||||
|
||||
public PackageInfo GetPackage()
|
||||
{
|
||||
return _packageInfo;
|
||||
}
|
||||
|
||||
public void SetPackage(PackageInfo packageInfo, bool serialize)
|
||||
{
|
||||
if (packageInfo == null)
|
||||
throw new ArgumentException("Package is null");
|
||||
|
||||
_packageInfo = packageInfo;
|
||||
SetMetadata();
|
||||
if (serialize)
|
||||
Serialize();
|
||||
}
|
||||
|
||||
public void SetPackage(string packageManifestPath, bool serialize)
|
||||
{
|
||||
if (!PackageUtility.GetPackageByManifestPath(packageManifestPath, out var package))
|
||||
throw new ArgumentException("Path does not correspond to a valid package");
|
||||
|
||||
SetPackage(package, serialize);
|
||||
}
|
||||
|
||||
private void SetMetadata()
|
||||
{
|
||||
LocalPackageGuid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(_packageInfo.GetManifestAsset()));
|
||||
LocalPackagePath = _packageInfo.assetPath;
|
||||
LocalProjectPath = _packageInfo.name;
|
||||
}
|
||||
|
||||
public List<PackageInfo> GetDependencies()
|
||||
{
|
||||
return _dependencies;
|
||||
}
|
||||
|
||||
public void SetDependencies(IEnumerable<string> dependencies, bool serialize)
|
||||
{
|
||||
_dependencies.Clear();
|
||||
foreach (var dependency in dependencies)
|
||||
{
|
||||
if (!PackageUtility.GetPackageByPackageName(dependency, out var package))
|
||||
continue;
|
||||
_dependencies.Add(package);
|
||||
}
|
||||
|
||||
if (serialize)
|
||||
Serialize();
|
||||
}
|
||||
|
||||
public List<PackageInfo> GetAvailableDependencies()
|
||||
{
|
||||
var availableDependencies = new List<PackageInfo>();
|
||||
if (_packageInfo == null)
|
||||
return availableDependencies;
|
||||
|
||||
var packageDependencies = _packageInfo.dependencies.Select(x => x.name);
|
||||
foreach (var dependency in packageDependencies)
|
||||
{
|
||||
if (!PackageUtility.GetPackageByPackageName(dependency, out var package))
|
||||
continue;
|
||||
|
||||
if (package.source != PackageManager.PackageSource.Local
|
||||
&& package.source != PackageManager.PackageSource.Embedded)
|
||||
continue;
|
||||
|
||||
availableDependencies.Add(package);
|
||||
}
|
||||
|
||||
return availableDependencies;
|
||||
}
|
||||
|
||||
public override IEnumerable<string> GetAllPaths()
|
||||
{
|
||||
var paths = new List<string>();
|
||||
|
||||
if (_packageInfo == null)
|
||||
return paths;
|
||||
|
||||
paths.Add(_packageInfo.assetPath);
|
||||
paths.AddRange(_dependencies.Select(x => x.assetPath));
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
public override bool IsPathValid(string path, out string reason)
|
||||
{
|
||||
reason = string.Empty;
|
||||
|
||||
if (!PackageUtility.GetPackageByManifestPath(path, out var package))
|
||||
{
|
||||
reason = "Selected path must point to a package manifest for a package that is imported into the current project";
|
||||
return false;
|
||||
}
|
||||
|
||||
var packageSourceValid = package.source == PackageSource.Embedded || package.source == PackageSource.Local;
|
||||
if (!packageSourceValid)
|
||||
{
|
||||
reason = "Selected package must be a local or an embedded package";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override IValidator CreateValidator()
|
||||
{
|
||||
var validationPaths = GetAllPaths();
|
||||
|
||||
var validationSettings = new CurrentProjectValidationSettings()
|
||||
{
|
||||
Category = Package?.Category,
|
||||
ValidationPaths = validationPaths.ToList(),
|
||||
ValidationType = ValidationType.UnityPackage
|
||||
};
|
||||
|
||||
var validator = new CurrentProjectValidator(validationSettings);
|
||||
return validator;
|
||||
}
|
||||
|
||||
public override IPackageExporter CreateExporter(string outputPath)
|
||||
{
|
||||
var exportPaths = GetAllPaths();
|
||||
|
||||
var exportSettings = new DefaultExporterSettings()
|
||||
{
|
||||
ExportPaths = exportPaths.ToArray(),
|
||||
OutputFilename = outputPath,
|
||||
PreviewGenerator = CreatePreviewGenerator(exportPaths.ToList())
|
||||
};
|
||||
|
||||
return new DefaultPackageExporter(exportSettings);
|
||||
}
|
||||
|
||||
protected override IPackageUploader CreatePackageUploader(string exportedPackagePath)
|
||||
{
|
||||
var uploaderSettings = new UnityPackageUploadSettings()
|
||||
{
|
||||
UnityPackagePath = exportedPackagePath,
|
||||
VersionId = Package.VersionId,
|
||||
RootGuid = LocalPackageGuid,
|
||||
RootPath = LocalPackagePath,
|
||||
ProjectPath = LocalProjectPath
|
||||
};
|
||||
|
||||
var uploader = new UnityPackageUploader(uploaderSettings);
|
||||
return uploader;
|
||||
}
|
||||
|
||||
protected override void Serialize()
|
||||
{
|
||||
if (_packageInfo == null)
|
||||
return;
|
||||
|
||||
_stateData.SetPackageName(_packageInfo.name);
|
||||
_stateData.SetPackageDependencies(_dependencies.Select(x => x.name).OrderBy(x => x));
|
||||
OnChanged?.Invoke();
|
||||
}
|
||||
|
||||
protected override void Deserialize()
|
||||
{
|
||||
var packageName = _stateData.GetPackageName();
|
||||
if (PackageUtility.GetPackageByPackageName(packageName, out var package))
|
||||
_packageInfo = package;
|
||||
|
||||
_dependencies = new List<PackageInfo>();
|
||||
var dependencies = _stateData.GetPackageDependencies();
|
||||
foreach (var dependency in dependencies)
|
||||
{
|
||||
if (PackageUtility.GetPackageByPackageName(dependency, out var packageDependency))
|
||||
_dependencies.Add(packageDependency);
|
||||
}
|
||||
|
||||
DeserializeFromUploadedData();
|
||||
}
|
||||
|
||||
private void DeserializeFromUploadedData()
|
||||
{
|
||||
DeserializeFromUploadedDataByPackageName();
|
||||
DeserializeFromUploadedDataByPackageGuid();
|
||||
}
|
||||
|
||||
private void DeserializeFromUploadedDataByPackageName()
|
||||
{
|
||||
if (_packageInfo != null)
|
||||
return;
|
||||
|
||||
var lastUploadedPackageName = Package.ProjectPath;
|
||||
if (!PackageUtility.GetPackageByPackageName(lastUploadedPackageName, out var package))
|
||||
return;
|
||||
|
||||
_packageInfo = package;
|
||||
}
|
||||
|
||||
private void DeserializeFromUploadedDataByPackageGuid()
|
||||
{
|
||||
if (_packageInfo != null)
|
||||
return;
|
||||
|
||||
var lastUploadedGuid = Package.RootGuid;
|
||||
if (string.IsNullOrEmpty(lastUploadedGuid))
|
||||
return;
|
||||
|
||||
var potentialPackageManifestPath = AssetDatabase.GUIDToAssetPath(lastUploadedGuid);
|
||||
if (string.IsNullOrEmpty(potentialPackageManifestPath) || !IsPathValid(potentialPackageManifestPath, out var _))
|
||||
return;
|
||||
|
||||
if (!PackageUtility.GetPackageByManifestPath(potentialPackageManifestPath, out var package))
|
||||
return;
|
||||
|
||||
_packageInfo = package;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3061839aba3894246a20195639eeda1f
|
||||
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/Data/HybridPackageWorkflow.cs
|
||||
uploadId: 724584
|
||||
@@ -1,39 +0,0 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace AssetStoreTools.Uploader.Data
|
||||
{
|
||||
internal class OngoingUpload : IDisposable
|
||||
{
|
||||
private CancellationTokenSource _cancellationTokenSource;
|
||||
|
||||
public string VersionId { get; }
|
||||
public string PackageName { get; }
|
||||
public float Progress { get; private set; }
|
||||
public CancellationToken CancellationToken => _cancellationTokenSource.Token;
|
||||
|
||||
public OngoingUpload(string versionId, string packageName)
|
||||
{
|
||||
VersionId = versionId;
|
||||
PackageName = packageName;
|
||||
Progress = 0f;
|
||||
_cancellationTokenSource = new CancellationTokenSource();
|
||||
}
|
||||
|
||||
public void Cancel()
|
||||
{
|
||||
_cancellationTokenSource?.Cancel();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_cancellationTokenSource?.Dispose();
|
||||
_cancellationTokenSource = null;
|
||||
}
|
||||
|
||||
public void UpdateProgress(float newProgress)
|
||||
{
|
||||
Progress = newProgress;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using PackageModel = AssetStoreTools.Api.Models.Package;
|
||||
|
||||
namespace AssetStoreTools.Uploader.Data
|
||||
{
|
||||
internal class Package : IPackage
|
||||
{
|
||||
private PackageModel _source;
|
||||
|
||||
public string PackageId => _source.PackageId;
|
||||
public string VersionId => _source.VersionId;
|
||||
public string Name => _source.Name;
|
||||
public string Status => _source.Status;
|
||||
public string Category => _source.Category;
|
||||
public bool IsCompleteProject => _source.IsCompleteProject;
|
||||
public string RootGuid => _source.RootGuid;
|
||||
public string RootPath => _source.RootPath;
|
||||
public string ProjectPath => _source.ProjectPath;
|
||||
public string Modified => _source.Modified;
|
||||
public string Size => _source.Size;
|
||||
public string IconUrl => _source.IconUrl;
|
||||
public bool IsDraft => Status.Equals("draft", StringComparison.OrdinalIgnoreCase);
|
||||
public Texture2D Icon { get; private set; }
|
||||
|
||||
public event Action OnUpdate;
|
||||
public event Action OnIconUpdate;
|
||||
|
||||
public Package(PackageModel packageSource)
|
||||
{
|
||||
_source = packageSource;
|
||||
}
|
||||
|
||||
public void UpdateIcon(Texture2D texture)
|
||||
{
|
||||
if (texture == null)
|
||||
return;
|
||||
|
||||
Icon = texture;
|
||||
OnIconUpdate?.Invoke();
|
||||
}
|
||||
|
||||
public string FormattedSize()
|
||||
{
|
||||
var defaultSize = "0.00 MB";
|
||||
if (float.TryParse(Size, out var sizeBytes))
|
||||
return $"{sizeBytes / (1024f * 1024f):0.00} MB";
|
||||
|
||||
return defaultSize;
|
||||
}
|
||||
|
||||
public string FormattedModified()
|
||||
{
|
||||
var defaultDate = "Unknown";
|
||||
if (DateTime.TryParse(Modified, out var dt))
|
||||
return dt.Date.ToString("yyyy-MM-dd");
|
||||
|
||||
return defaultDate;
|
||||
}
|
||||
|
||||
public void UpdateData(PackageModel source)
|
||||
{
|
||||
if (source == null)
|
||||
throw new ArgumentException("Provided package is null");
|
||||
|
||||
_source = source;
|
||||
OnUpdate?.Invoke();
|
||||
}
|
||||
|
||||
public PackageModel ToModel()
|
||||
{
|
||||
var model = new PackageModel()
|
||||
{
|
||||
PackageId = _source.PackageId,
|
||||
VersionId = _source.VersionId,
|
||||
Name = _source.Name,
|
||||
Status = _source.Status,
|
||||
Category = _source.Category,
|
||||
IsCompleteProject = _source.IsCompleteProject,
|
||||
RootGuid = _source.RootGuid,
|
||||
RootPath = _source.RootPath,
|
||||
ProjectPath = _source.ProjectPath,
|
||||
Modified = _source.Modified,
|
||||
Size = _source.Size,
|
||||
IconUrl = _source.IconUrl
|
||||
};
|
||||
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 684fca3fffd79d944a32d9b3adbfc007
|
||||
guid: fc2198164bbd6394b87c51a74fe2915e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -13,6 +13,6 @@ AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 11.4.4
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/AssetStoreAPI.cs
|
||||
uploadId: 712972
|
||||
packageVersion: 12.0.1
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/Data/Package.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,68 @@
|
||||
using AssetStoreTools.Uploader.Data.Serialization;
|
||||
using AssetStoreTools.Uploader.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace AssetStoreTools.Uploader.Data
|
||||
{
|
||||
internal class PackageContent : IPackageContent
|
||||
{
|
||||
private IWorkflow _activeWorkflow;
|
||||
private List<IWorkflow> _workflows;
|
||||
private WorkflowStateData _workflowStateData;
|
||||
|
||||
private ICachingService _cachingService;
|
||||
|
||||
public event Action<IWorkflow> OnActiveWorkflowChanged;
|
||||
|
||||
public PackageContent(List<IWorkflow> workflows, WorkflowStateData workflowStateData, ICachingService cachingService)
|
||||
{
|
||||
_workflows = workflows;
|
||||
_workflowStateData = workflowStateData;
|
||||
_cachingService = cachingService;
|
||||
|
||||
foreach (var workflow in _workflows)
|
||||
{
|
||||
workflow.OnChanged += Serialize;
|
||||
}
|
||||
|
||||
Deserialize();
|
||||
}
|
||||
|
||||
public IWorkflow GetActiveWorkflow()
|
||||
{
|
||||
return _activeWorkflow;
|
||||
}
|
||||
|
||||
public void SetActiveWorkflow(IWorkflow workflow)
|
||||
{
|
||||
_activeWorkflow = workflow;
|
||||
|
||||
OnActiveWorkflowChanged?.Invoke(_activeWorkflow);
|
||||
|
||||
Serialize();
|
||||
}
|
||||
|
||||
public List<IWorkflow> GetAvailableWorkflows()
|
||||
{
|
||||
return _workflows;
|
||||
}
|
||||
|
||||
private void Serialize()
|
||||
{
|
||||
_workflowStateData.SetActiveWorkflow(_activeWorkflow.Name);
|
||||
_cachingService.CacheWorkflowStateData(_workflowStateData);
|
||||
}
|
||||
|
||||
private void Deserialize()
|
||||
{
|
||||
var serializedWorkflow = _workflowStateData.GetActiveWorkflow();
|
||||
var workflow = _workflows.FirstOrDefault(x => x.Name == serializedWorkflow);
|
||||
if (workflow != null)
|
||||
_activeWorkflow = workflow;
|
||||
else
|
||||
_activeWorkflow = _workflows[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f36086f9380a49949ab45463abc6fee8
|
||||
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/Data/PackageContent.cs
|
||||
uploadId: 724584
|
||||
@@ -1,36 +0,0 @@
|
||||
namespace AssetStoreTools.Uploader.Data
|
||||
{
|
||||
internal class PackageData
|
||||
{
|
||||
public string Id { get; }
|
||||
public string Name { get; }
|
||||
public string VersionId { get; }
|
||||
public string Status { get; }
|
||||
public string Category { get; }
|
||||
public bool IsCompleteProject { get; }
|
||||
public string LastUploadedPath { get; }
|
||||
public string LastUploadedGuid { get; }
|
||||
|
||||
public string LastDate { get; }
|
||||
public string LastSize { get; }
|
||||
|
||||
public PackageData(string id, string name, string versionId, string status, string category, bool isCompleteProject, string lastUploadedPath, string lastUploadedGuid, string lastDate, string lastSize)
|
||||
{
|
||||
Id = id;
|
||||
Name = name;
|
||||
VersionId = versionId;
|
||||
Status = status;
|
||||
Category = category;
|
||||
IsCompleteProject = isCompleteProject;
|
||||
LastUploadedPath = lastUploadedPath;
|
||||
LastUploadedGuid = lastUploadedGuid;
|
||||
LastDate = lastDate;
|
||||
LastSize = lastSize;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Id} {Name} {VersionId} {Status} {Category} {LastUploadedPath} {LastUploadedGuid} {IsCompleteProject} {LastDate} {LastSize}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8157930875be4972a48c870a3d1e8ff1
|
||||
timeCreated: 1658919930
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 11.4.4
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/Data/PackageData.cs
|
||||
uploadId: 712972
|
||||
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace AssetStoreTools.Uploader.Data
|
||||
{
|
||||
internal class PackageGroup : IPackageGroup
|
||||
{
|
||||
private class FilteredPackage
|
||||
{
|
||||
public IPackage Package;
|
||||
public bool IsInFilter;
|
||||
}
|
||||
|
||||
public string Name { get; private set; }
|
||||
public List<IPackage> Packages { get; private set; }
|
||||
|
||||
private List<FilteredPackage> _filteredPackages;
|
||||
|
||||
public event Action<List<IPackage>> OnPackagesSorted;
|
||||
public event Action<List<IPackage>> OnPackagesFiltered;
|
||||
|
||||
public PackageGroup(string name, List<IPackage> packages)
|
||||
{
|
||||
Name = name;
|
||||
Packages = packages;
|
||||
|
||||
_filteredPackages = new List<FilteredPackage>();
|
||||
foreach (var package in Packages)
|
||||
_filteredPackages.Add(new FilteredPackage() { Package = package, IsInFilter = true });
|
||||
}
|
||||
|
||||
public void Sort(PackageSorting sortingType)
|
||||
{
|
||||
switch (sortingType)
|
||||
{
|
||||
case PackageSorting.Name:
|
||||
_filteredPackages = _filteredPackages.OrderBy(x => x.Package.Name).ToList();
|
||||
break;
|
||||
case PackageSorting.Date:
|
||||
_filteredPackages = _filteredPackages.OrderByDescending(x => x.Package.Modified).ToList();
|
||||
break;
|
||||
case PackageSorting.Category:
|
||||
_filteredPackages = _filteredPackages.OrderBy(x => x.Package.Category).ThenBy(x => x.Package.Name).ToList();
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException("Undefined sorting type");
|
||||
}
|
||||
|
||||
OnPackagesSorted?.Invoke(_filteredPackages.Where(x => x.IsInFilter).Select(x => x.Package).ToList());
|
||||
}
|
||||
|
||||
public void Filter(string filter)
|
||||
{
|
||||
foreach (var package in _filteredPackages)
|
||||
{
|
||||
bool inFilter = package.Package.Name.ToLower().Contains(filter.ToLower());
|
||||
package.IsInFilter = inFilter;
|
||||
}
|
||||
|
||||
OnPackagesFiltered?.Invoke(_filteredPackages.Where(x => x.IsInFilter).Select(x => x.Package).ToList());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 601fdada4edc5b94eb83a21d1a01ed26
|
||||
guid: c9cc17f6b95bb2c42913a1451b9af29e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -13,6 +13,6 @@ AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 11.4.4
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/Data/OngoingUpload.cs
|
||||
uploadId: 712972
|
||||
packageVersion: 12.0.1
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/Data/PackageGroup.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace AssetStoreTools.Uploader.Data
|
||||
{
|
||||
internal enum PackageSorting
|
||||
{
|
||||
Name,
|
||||
Category,
|
||||
Date
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b1d61d0de90e022469b5ed312d4b7beb
|
||||
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/Data/PackageSorting.cs
|
||||
uploadId: 724584
|
||||
@@ -1,46 +0,0 @@
|
||||
using AssetStoreTools.Utility;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AssetStoreTools.Uploader.Data
|
||||
{
|
||||
internal class PackageUploadResult
|
||||
{
|
||||
public enum UploadStatus
|
||||
{
|
||||
Default = 0,
|
||||
Success = 1,
|
||||
Fail = 2,
|
||||
Cancelled = 3,
|
||||
ResponseTimeout = 4
|
||||
}
|
||||
|
||||
public UploadStatus Status;
|
||||
public ASError Error;
|
||||
|
||||
private PackageUploadResult() { }
|
||||
|
||||
public static PackageUploadResult PackageUploadSuccess() => new PackageUploadResult() { Status = UploadStatus.Success };
|
||||
|
||||
public static PackageUploadResult PackageUploadFail(ASError e) => new PackageUploadResult() { Status = UploadStatus.Fail, Error = e };
|
||||
|
||||
public static PackageUploadResult PackageUploadCancelled() => new PackageUploadResult() { Status = UploadStatus.Cancelled };
|
||||
|
||||
public static PackageUploadResult PackageUploadResponseTimeout() => new PackageUploadResult() { Status = UploadStatus.ResponseTimeout };
|
||||
|
||||
public static Color GetColorByStatus(UploadStatus status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
default:
|
||||
case UploadStatus.Default:
|
||||
return new Color(0.13f, 0.59f, 0.95f);
|
||||
case UploadStatus.Success:
|
||||
return new Color(0f, 0.50f, 0.14f);
|
||||
case UploadStatus.Cancelled:
|
||||
return new Color(0.78f, 0.59f, 0f);
|
||||
case UploadStatus.Fail:
|
||||
return new Color(0.69f, 0.04f, 0.04f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d6e2d6bcfe000764e9330d78017e32bc
|
||||
guid: 0b05e199f21f636439844a8cc7e2c225
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -0,0 +1,59 @@
|
||||
using AssetStoreTools.Utility;
|
||||
using Newtonsoft.Json;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
|
||||
namespace AssetStoreTools.Uploader.Data.Serialization
|
||||
{
|
||||
internal class AssetPath
|
||||
{
|
||||
[JsonProperty("path")]
|
||||
private string _path = string.Empty;
|
||||
[JsonProperty("guid")]
|
||||
private string _guid = string.Empty;
|
||||
|
||||
[JsonIgnore]
|
||||
public string Path { get => _path; set { SetAssetPath(value); } }
|
||||
[JsonIgnore]
|
||||
public string Guid { get => _guid; set { _guid = value; } }
|
||||
|
||||
public AssetPath() { }
|
||||
|
||||
public AssetPath(string path)
|
||||
{
|
||||
SetAssetPath(path);
|
||||
}
|
||||
|
||||
private void SetAssetPath(string path)
|
||||
{
|
||||
_path = path.Replace("\\", "/");
|
||||
if (TryGetGuid(_path, out var guid))
|
||||
_guid = guid;
|
||||
}
|
||||
|
||||
private bool TryGetGuid(string path, out string guid)
|
||||
{
|
||||
guid = string.Empty;
|
||||
|
||||
var relativePath = FileUtility.AbsolutePathToRelativePath(path, ASToolsPreferences.Instance.EnableSymlinkSupport);
|
||||
|
||||
if (!relativePath.StartsWith("Assets/") && !relativePath.StartsWith("Packages/"))
|
||||
return false;
|
||||
|
||||
guid = AssetDatabase.AssetPathToGUID(relativePath);
|
||||
return !string.IsNullOrEmpty(guid);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var pathFromGuid = AssetDatabase.GUIDToAssetPath(_guid);
|
||||
if (!string.IsNullOrEmpty(pathFromGuid) && (File.Exists(pathFromGuid) || Directory.Exists(pathFromGuid)))
|
||||
return pathFromGuid;
|
||||
|
||||
if (File.Exists(_path) || Directory.Exists(_path))
|
||||
return _path;
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 920ff8e4ffe77ec44bede985593cc187
|
||||
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/Data/Serialization/AssetPath.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,77 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AssetStoreTools.Uploader.Data.Serialization
|
||||
{
|
||||
internal class AssetsWorkflowState
|
||||
{
|
||||
[JsonProperty("main_path")]
|
||||
private AssetPath _mainPath;
|
||||
[JsonProperty("special_folders")]
|
||||
private List<AssetPath> _specialFolders;
|
||||
[JsonProperty("include_dependencies")]
|
||||
private bool _includeDependencies;
|
||||
[JsonProperty("dependencies")]
|
||||
private List<string> _dependencies;
|
||||
|
||||
public AssetsWorkflowState()
|
||||
{
|
||||
_mainPath = new AssetPath();
|
||||
_includeDependencies = false;
|
||||
_dependencies = new List<string>();
|
||||
_specialFolders = new List<AssetPath>();
|
||||
}
|
||||
|
||||
public string GetMainPath()
|
||||
{
|
||||
return _mainPath?.ToString();
|
||||
}
|
||||
|
||||
public void SetMainPath(string path)
|
||||
{
|
||||
_mainPath = new AssetPath(path);
|
||||
}
|
||||
|
||||
public bool GetIncludeDependencies()
|
||||
{
|
||||
return _includeDependencies;
|
||||
}
|
||||
|
||||
public void SetIncludeDependencies(bool value)
|
||||
{
|
||||
_includeDependencies = value;
|
||||
}
|
||||
|
||||
public List<string> GetDependencies()
|
||||
{
|
||||
return _dependencies;
|
||||
}
|
||||
|
||||
public void SetDependencies(IEnumerable<string> dependencies)
|
||||
{
|
||||
_dependencies = new List<string>();
|
||||
foreach (var dependency in dependencies)
|
||||
_dependencies.Add(dependency);
|
||||
}
|
||||
|
||||
public List<string> GetSpecialFolders()
|
||||
{
|
||||
var specialFolders = new List<string>();
|
||||
foreach (var folder in _specialFolders)
|
||||
{
|
||||
var path = folder.ToString();
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
specialFolders.Add(path);
|
||||
}
|
||||
|
||||
return specialFolders;
|
||||
}
|
||||
|
||||
public void SetSpecialFolders(List<string> specialFolders)
|
||||
{
|
||||
_specialFolders = new List<AssetPath>();
|
||||
foreach (var path in specialFolders)
|
||||
_specialFolders.Add(new AssetPath(path));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 505f0a5aa753b4445a467539e150190a
|
||||
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/Data/Serialization/AssetsWorkflowStateData.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,41 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AssetStoreTools.Uploader.Data.Serialization
|
||||
{
|
||||
internal class HybridPackageWorkflowState
|
||||
{
|
||||
[JsonProperty("package_name")]
|
||||
private string _packageName;
|
||||
[JsonProperty("dependencies")]
|
||||
private List<string> _dependencies;
|
||||
|
||||
public HybridPackageWorkflowState()
|
||||
{
|
||||
_packageName = string.Empty;
|
||||
_dependencies = new List<string>();
|
||||
}
|
||||
|
||||
public string GetPackageName()
|
||||
{
|
||||
return _packageName;
|
||||
}
|
||||
|
||||
public void SetPackageName(string packageName)
|
||||
{
|
||||
_packageName = packageName;
|
||||
}
|
||||
|
||||
public List<string> GetPackageDependencies()
|
||||
{
|
||||
return _dependencies;
|
||||
}
|
||||
|
||||
public void SetPackageDependencies(IEnumerable<string> dependencies)
|
||||
{
|
||||
_dependencies.Clear();
|
||||
foreach (var dependency in dependencies)
|
||||
_dependencies.Add(dependency);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2848375fcb0a4174495573190bfc3900
|
||||
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/Data/Serialization/HybridPackageWorkflowState.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,25 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace AssetStoreTools.Uploader.Data.Serialization
|
||||
{
|
||||
internal class UnityPackageWorkflowState
|
||||
{
|
||||
[JsonProperty("package_path")]
|
||||
private AssetPath _packagePath;
|
||||
|
||||
public UnityPackageWorkflowState()
|
||||
{
|
||||
_packagePath = new AssetPath();
|
||||
}
|
||||
|
||||
public string GetPackagePath()
|
||||
{
|
||||
return _packagePath?.ToString();
|
||||
}
|
||||
|
||||
public void SetPackagePath(string path)
|
||||
{
|
||||
_packagePath = new AssetPath(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 101a66adc88639b43b07cc28214474cf
|
||||
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/Data/Serialization/UnityPackageWorkflowStateData.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,68 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
namespace AssetStoreTools.Uploader.Data.Serialization
|
||||
{
|
||||
internal class WorkflowStateData
|
||||
{
|
||||
[JsonProperty("package_id")]
|
||||
private string _packageId;
|
||||
[JsonProperty("active_workflow")]
|
||||
private string _activeWorkflow;
|
||||
[JsonProperty("assets_workflow")]
|
||||
private AssetsWorkflowState _assetsWorkflow;
|
||||
[JsonProperty("unitypackage_workflow")]
|
||||
private UnityPackageWorkflowState _unityPackageWorkflow;
|
||||
[JsonProperty("hybrid_workflow")]
|
||||
private HybridPackageWorkflowState _hybridPackageWorkflow;
|
||||
|
||||
public WorkflowStateData()
|
||||
{
|
||||
_activeWorkflow = string.Empty;
|
||||
|
||||
_assetsWorkflow = new AssetsWorkflowState();
|
||||
_unityPackageWorkflow = new UnityPackageWorkflowState();
|
||||
_hybridPackageWorkflow = new HybridPackageWorkflowState();
|
||||
}
|
||||
|
||||
public WorkflowStateData(string packageId) : this()
|
||||
{
|
||||
SetPackageId(packageId);
|
||||
}
|
||||
|
||||
public string GetPackageId()
|
||||
{
|
||||
return _packageId;
|
||||
}
|
||||
|
||||
public void SetPackageId(string packageId)
|
||||
{
|
||||
_packageId = packageId;
|
||||
}
|
||||
|
||||
public string GetActiveWorkflow()
|
||||
{
|
||||
return _activeWorkflow;
|
||||
}
|
||||
|
||||
public void SetActiveWorkflow(string activeWorkflow)
|
||||
{
|
||||
_activeWorkflow = activeWorkflow;
|
||||
}
|
||||
|
||||
public AssetsWorkflowState GetAssetsWorkflowState()
|
||||
{
|
||||
return _assetsWorkflow;
|
||||
}
|
||||
|
||||
public UnityPackageWorkflowState GetUnityPackageWorkflowState()
|
||||
{
|
||||
return _unityPackageWorkflow;
|
||||
}
|
||||
|
||||
public HybridPackageWorkflowState GetHybridPackageWorkflowState()
|
||||
{
|
||||
return _hybridPackageWorkflow;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eecebbc83661a4f41a14e293c9fc3331
|
||||
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/Data/Serialization/WorkflowStateData.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,135 @@
|
||||
using AssetStoreTools.Api;
|
||||
using AssetStoreTools.Exporter;
|
||||
using AssetStoreTools.Uploader.Data.Serialization;
|
||||
using AssetStoreTools.Validator;
|
||||
using AssetStoreTools.Validator.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AssetStoreTools.Uploader.Data
|
||||
{
|
||||
internal class UnityPackageWorkflow : WorkflowBase
|
||||
{
|
||||
public override string Name => "UnityPackageWorkflow";
|
||||
public override string DisplayName => "Pre-exported .unitypackage";
|
||||
public override string PackageExtension => ".unitypackage";
|
||||
public override bool IsPathSet => !string.IsNullOrEmpty(_packagePath);
|
||||
|
||||
private UnityPackageWorkflowState _workflowState;
|
||||
private string _packagePath;
|
||||
|
||||
public override event Action OnChanged;
|
||||
|
||||
public UnityPackageWorkflow(IPackage package, UnityPackageWorkflowState workflowState, IWorkflowServices services)
|
||||
: base(package, services)
|
||||
{
|
||||
_workflowState = workflowState;
|
||||
Deserialize();
|
||||
}
|
||||
|
||||
public void SetPackagePath(string path, bool serialize)
|
||||
{
|
||||
_packagePath = path;
|
||||
SetMetadata();
|
||||
if (serialize)
|
||||
Serialize();
|
||||
}
|
||||
|
||||
private void SetMetadata()
|
||||
{
|
||||
LocalPackageGuid = string.Empty;
|
||||
LocalPackagePath = string.Empty;
|
||||
LocalProjectPath = _packagePath;
|
||||
}
|
||||
|
||||
public string GetPackagePath()
|
||||
{
|
||||
return _packagePath;
|
||||
}
|
||||
|
||||
public override IEnumerable<string> GetAllPaths()
|
||||
{
|
||||
return new List<string>() { _packagePath };
|
||||
}
|
||||
|
||||
public override bool IsPathValid(string path, out string error)
|
||||
{
|
||||
error = null;
|
||||
|
||||
var pathIsUnityPackage = path.EndsWith(PackageExtension);
|
||||
var pathExists = File.Exists(path);
|
||||
|
||||
if (!pathIsUnityPackage || !pathExists)
|
||||
{
|
||||
error = "Path must point to a .unitypackage file";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override IValidator CreateValidator()
|
||||
{
|
||||
var validationSettings = new ExternalProjectValidationSettings()
|
||||
{
|
||||
Category = Package.Category,
|
||||
PackagePath = GetPackagePath()
|
||||
};
|
||||
|
||||
var validator = new ExternalProjectValidator(validationSettings);
|
||||
return validator;
|
||||
}
|
||||
|
||||
public override IPackageExporter CreateExporter(string _)
|
||||
{
|
||||
// This workflow already takes exported packages as input
|
||||
throw new InvalidOperationException($"{nameof(UnityPackageWorkflow)} already takes exported packages as input");
|
||||
}
|
||||
|
||||
public override Task<PackageExporterResult> ExportPackage(string _)
|
||||
{
|
||||
return Task.FromResult(new PackageExporterResult() { Success = true, ExportedPath = GetPackagePath() });
|
||||
}
|
||||
|
||||
protected override IPackageUploader CreatePackageUploader(string exportedPackagePath)
|
||||
{
|
||||
var uploaderSettings = new UnityPackageUploadSettings()
|
||||
{
|
||||
VersionId = Package.VersionId,
|
||||
UnityPackagePath = exportedPackagePath,
|
||||
RootGuid = LocalPackageGuid,
|
||||
RootPath = LocalPackagePath,
|
||||
ProjectPath = LocalProjectPath
|
||||
};
|
||||
|
||||
var uploader = new UnityPackageUploader(uploaderSettings);
|
||||
return uploader;
|
||||
}
|
||||
|
||||
protected override void Serialize()
|
||||
{
|
||||
_workflowState.SetPackagePath(_packagePath);
|
||||
OnChanged?.Invoke();
|
||||
}
|
||||
|
||||
protected override void Deserialize()
|
||||
{
|
||||
_packagePath = _workflowState.GetPackagePath();
|
||||
DeserializeFromUploadedData();
|
||||
}
|
||||
|
||||
private void DeserializeFromUploadedData()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_packagePath))
|
||||
return;
|
||||
|
||||
var potentialPackagePath = Package.ProjectPath;
|
||||
if (string.IsNullOrEmpty(potentialPackagePath) || !IsPathValid(potentialPackagePath, out var _))
|
||||
return;
|
||||
|
||||
_packagePath = potentialPackagePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 47ee1db30792bf84aa1af8be7ce0dee6
|
||||
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/Data/UnityPackageWorkflow.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,53 @@
|
||||
using AssetStoreTools.Api;
|
||||
using AssetStoreTools.Api.Responses;
|
||||
using AssetStoreTools.Uploader.Services.Analytics;
|
||||
using AssetStoreTools.Uploader.Services.Analytics.Data;
|
||||
using AssetStoreTools.Uploader.Services.Api;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine.Analytics;
|
||||
|
||||
namespace AssetStoreTools.Uploader.Data
|
||||
{
|
||||
internal class WorkflowServices : IWorkflowServices
|
||||
{
|
||||
private IPackageDownloadingService _downloadingService;
|
||||
private IPackageUploadingService _uploadingService;
|
||||
private IAnalyticsService _analyticsService;
|
||||
|
||||
public WorkflowServices(
|
||||
IPackageDownloadingService downloadingService,
|
||||
IPackageUploadingService uploadingService,
|
||||
IAnalyticsService analyticsService)
|
||||
{
|
||||
_downloadingService = downloadingService;
|
||||
_uploadingService = uploadingService;
|
||||
_analyticsService = analyticsService;
|
||||
}
|
||||
|
||||
public Task<PackageUploadedUnityVersionDataResponse> GetPackageUploadedVersions(IPackage package, int timeoutMs)
|
||||
{
|
||||
return _downloadingService.GetPackageUploadedVersions(package, timeoutMs);
|
||||
}
|
||||
|
||||
public Task<PackageUploadResponse> UploadPackage(IPackageUploader uploader, IProgress<float> progress)
|
||||
{
|
||||
return _uploadingService.UploadPackage(uploader, progress);
|
||||
}
|
||||
|
||||
public void StopUploading(IPackageUploader uploader)
|
||||
{
|
||||
_uploadingService.StopUploading(uploader);
|
||||
}
|
||||
|
||||
public Task<RefreshedPackageDataResponse> UpdatePackageData(IPackage package)
|
||||
{
|
||||
return _downloadingService.UpdatePackageData(package);
|
||||
}
|
||||
|
||||
public AnalyticsResult SendAnalytic(IAssetStoreAnalytic data)
|
||||
{
|
||||
return _analyticsService.Send(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a78b96ae30966e94ba9ffdddf19c1692
|
||||
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/Data/WorkflowServices.cs
|
||||
uploadId: 724584
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 854f6f9e93b37204eb2e6042138643bc
|
||||
guid: d9787842821f3d041904186d0e0cc61d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7562bae25c6218744a023670e3a2f06f
|
||||
guid: 17f95678acdb51548908d81be7146b5b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: df1fca726619f2f4fae3bd93b0ef5a8b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace AssetStoreTools.Uploader.Services.Analytics.Data
|
||||
{
|
||||
interface IAssetStoreAnalyticData
|
||||
#if UNITY_2023_2_OR_NEWER
|
||||
: UnityEngine.Analytics.IAnalytic.IData
|
||||
#endif
|
||||
{ }
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4d983b64bd0866a428f937434252f537
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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}"); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a834946d92154754493879c5fcc7dbc9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -0,0 +1,4 @@
|
||||
namespace AssetStoreTools.Uploader.Services
|
||||
{
|
||||
internal interface IUploaderService { }
|
||||
}
|
||||
@@ -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
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 02e4a5ee9e2fb7941b876b207078e01d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user