update libs

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

View File

@@ -7,26 +7,27 @@ namespace AssetStoreTools.Utility
{
private enum LogType
{
Log,
Info,
Warning,
Error
}
private static bool s_debugModeEnabled = EditorPrefs.GetBool("ASTDebugMode");
private static string FormatInfo(object message) => $"<b>[AST Info]</b> {message}";
private static string FormatWarning(object message) => $"<color=yellow><b>[AST Warning]</b></color> {message}";
private static string FormatError(object message) => $"<color=red><b>[AST Error]</b></color> {message}";
private static bool s_debugModeEnabled = EditorPrefs.GetBool(Constants.Debug.DebugModeKey);
public static bool DebugModeEnabled
{
get => s_debugModeEnabled;
set
{
s_debugModeEnabled = value;
EditorPrefs.SetBool("ASTDebugMode", value);
}
set { s_debugModeEnabled = value; EditorPrefs.SetBool(Constants.Debug.DebugModeKey, value); }
}
public static void Log(object message)
{
LogMessage(message, LogType.Log);
LogMessage(message, LogType.Info);
}
public static void LogWarning(object message)
@@ -41,19 +42,19 @@ namespace AssetStoreTools.Utility
private static void LogMessage(object message, LogType type)
{
if (!DebugModeEnabled)
if (!DebugModeEnabled)
return;
switch (type)
{
case LogType.Log:
Debug.Log(message);
case LogType.Info:
Debug.Log(FormatInfo(message));
break;
case LogType.Warning:
Debug.LogWarning(message);
Debug.LogWarning(FormatWarning(message));
break;
case LogType.Error:
Debug.LogError(message);
Debug.LogError(FormatError(message));
break;
default:
Debug.Log(message);

View File

@@ -13,6 +13,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/Utility/ASDebug.cs
uploadId: 712972
uploadId: 724584

View File

@@ -1,93 +0,0 @@
using System;
using System.Net;
using System.Net.Http;
namespace AssetStoreTools.Utility
{
/// <summary>
/// A structure for retrieving and converting errors from Asset Store Tools class methods
/// </summary>
internal class ASError
{
public string Message { get; private set; }
public Exception Exception { get; private set; }
public ASError() { }
public static ASError GetGenericError(Exception ex)
{
ASError error = new ASError()
{
Message = ex.Message,
Exception = ex
};
return error;
}
public static ASError GetLoginError(HttpResponseMessage response) => GetLoginError(response, null);
public static ASError GetLoginError(HttpResponseMessage response, HttpRequestException ex)
{
ASError error = new ASError() { Exception = ex };
switch (response.StatusCode)
{
// Add common error codes here
case HttpStatusCode.Unauthorized:
error.Message = "Incorrect email and/or password. Please try again.";
break;
case HttpStatusCode.InternalServerError:
error.Message = "Authentication request failed\nIf you were logging in with your Unity Cloud account, please make sure you are still logged in.\n" +
"This might also be caused by too many invalid login attempts - if that is the case, please try again later.";
break;
default:
ParseHtmlMessage(response, out string message);
error.Message = message;
break;
}
return error;
}
public static ASError GetPublisherNullError(string publisherName)
{
ASError error = new ASError
{
Message = $"Your Unity ID {publisherName} is not currently connected to a publisher account. " +
$"Please create a publisher profile."
};
return error;
}
private static bool ParseHtmlMessage(HttpResponseMessage response, out string message)
{
message = "An undefined error has been encountered";
string html = response.Content.ReadAsStringAsync().Result;
if (!html.Contains("<!DOCTYPE HTML"))
return false;
message += " with the following message:\n\n";
var startIndex = html.IndexOf("<p>", StringComparison.Ordinal) + "<p>".Length;
var endIndex = html.IndexOf("</p>", StringComparison.Ordinal);
if (startIndex == -1 || endIndex == -1)
return false;
string htmlBodyMessage = html.Substring(startIndex, (endIndex - startIndex));
htmlBodyMessage = htmlBodyMessage.Replace("\n", " ");
message += htmlBodyMessage;
message += "\n\nIf this error message is not very informative, please report this to Unity";
return true;
}
public override string ToString()
{
return Message;
}
}
}

View File

@@ -6,14 +6,13 @@ using UnityEngine;
namespace AssetStoreTools.Utility
{
internal class ASToolsPreferences
{
private static ASToolsPreferences s_instance;
public static ASToolsPreferences Instance => s_instance ?? (s_instance = new ASToolsPreferences());
public static event Action OnSettingsChange;
private ASToolsPreferences()
{
Load();
@@ -27,7 +26,6 @@ namespace AssetStoreTools.Utility
DisplayHiddenMetaDialog = PlayerPrefs.GetInt("AST_HiddenFolderMetaCheck", 1) == 1;
EnableSymlinkSupport = PlayerPrefs.GetInt("AST_EnableSymlinkSupport", 0) == 1;
UseLegacyExporting = PlayerPrefs.GetInt("AST_UseLegacyExporting", 0) == 1;
DisplayUploadDialog = PlayerPrefs.GetInt("AST_DisplayUploadDialog", 0) == 1;
}
public void Save(bool triggerSettingsChange = false)
@@ -38,10 +36,9 @@ namespace AssetStoreTools.Utility
PlayerPrefs.SetInt("AST_HiddenFolderMetaCheck", DisplayHiddenMetaDialog ? 1 : 0);
PlayerPrefs.SetInt("AST_EnableSymlinkSupport", EnableSymlinkSupport ? 1 : 0);
PlayerPrefs.SetInt("AST_UseLegacyExporting", UseLegacyExporting ? 1 : 0);
PlayerPrefs.SetInt("AST_DisplayUploadDialog", DisplayUploadDialog ? 1 : 0);
PlayerPrefs.Save();
if(triggerSettingsChange)
if (triggerSettingsChange)
OnSettingsChange?.Invoke();
}
@@ -55,16 +52,16 @@ namespace AssetStoreTools.Utility
/// </summary>
public bool LegacyVersionCheck;
/// <summary>
/// Check if the package has been uploader from a correct Unity version at least once
/// </summary>
public bool UploadVersionCheck;
/// <summary>
/// Enables a DisplayDialog when hidden folders are found to be missing meta files
/// </summary>
public bool DisplayHiddenMetaDialog;
/// <summary>
/// Check if the package has been uploaded from a correct Unity version at least once
/// </summary>
public bool UploadVersionCheck;
/// <summary>
/// Enables Junction symlink support
/// </summary>
@@ -74,17 +71,12 @@ namespace AssetStoreTools.Utility
/// Enables legacy exporting for Folder Upload workflow
/// </summary>
public bool UseLegacyExporting;
/// <summary>
/// Enables DisplayDialog to be shown after the uploading ends
/// </summary>
public bool DisplayUploadDialog;
}
internal class ASToolsPreferencesProvider : SettingsProvider
{
private const string SettingsPath = "Project/Asset Store Tools";
private class Styles
{
public static readonly GUIContent CheckForUpdatesLabel = EditorGUIUtility.TrTextContent("Check for Updates", "Periodically check if an update for the Asset Store Publishing Tools is available.");
@@ -93,7 +85,7 @@ namespace AssetStoreTools.Utility
public static readonly GUIContent DisplayHiddenMetaDialogLabel = EditorGUIUtility.TrTextContent("Display Hidden Folder Meta Dialog", "Show a DisplayDialog when hidden folders are found to be missing meta files.\nNote: this only affects hidden folders ending with a '~' character");
public static readonly GUIContent EnableSymlinkSupportLabel = EditorGUIUtility.TrTextContent("Enable Symlink Support", "Enable Junction Symlink support. Note: folder selection validation will take longer.");
public static readonly GUIContent UseLegacyExportingLabel = EditorGUIUtility.TrTextContent("Use Legacy Exporting", "Enabling this option uses native Unity methods when exporting packages for the Folder Upload workflow.\nNote: individual package dependency selection when choosing to 'Include Package Manifest' is unavailable when this option is enabled.");
public static readonly GUIContent DisplayUploadDialogLabel = EditorGUIUtility.TrTextContent("Display Upload Dialog", "Show a DisplayDialog after the package uploading has finished.");
public static readonly GUIContent UseCustomPreviewsLabel = EditorGUIUtility.TrTextContent("Enable High Quality Previews (experimental)", "Override native asset preview retrieval with higher-quality preview generation");
}
public static void OpenSettings()
@@ -103,10 +95,11 @@ namespace AssetStoreTools.Utility
private ASToolsPreferencesProvider(string path, SettingsScope scopes, IEnumerable<string> keywords = null)
: base(path, scopes, keywords) { }
public override void OnGUI(string searchContext)
{
var preferences = ASToolsPreferences.Instance;
EditorGUI.BeginChangeCheck();
using (CreateSettingsWindowGUIScope())
{
@@ -116,20 +109,21 @@ namespace AssetStoreTools.Utility
preferences.DisplayHiddenMetaDialog = EditorGUILayout.Toggle(Styles.DisplayHiddenMetaDialogLabel, preferences.DisplayHiddenMetaDialog);
preferences.EnableSymlinkSupport = EditorGUILayout.Toggle(Styles.EnableSymlinkSupportLabel, preferences.EnableSymlinkSupport);
preferences.UseLegacyExporting = EditorGUILayout.Toggle(Styles.UseLegacyExportingLabel, preferences.UseLegacyExporting);
preferences.DisplayUploadDialog = EditorGUILayout.Toggle(Styles.DisplayUploadDialogLabel, preferences.DisplayUploadDialog);
}
if (EditorGUI.EndChangeCheck())
{
ASToolsPreferences.Instance.Save(true);
}
}
[SettingsProvider]
public static SettingsProvider CreateAssetStoreToolsSettingProvider()
{
var provider = new ASToolsPreferencesProvider(SettingsPath, SettingsScope.Project, GetSearchKeywordsFromGUIContentProperties<Styles>());
return provider;
}
private IDisposable CreateSettingsWindowGUIScope()
{
var unityEditorAssembly = Assembly.GetAssembly(typeof(EditorWindow));

View File

@@ -13,6 +13,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/Utility/ASToolsPreferences.cs
uploadId: 712972
uploadId: 724584

View File

@@ -1,4 +1,4 @@
using AssetStoreTools.Uploader;
using AssetStoreTools.Api;
using System;
using System.Linq;
using System.Threading.Tasks;
@@ -11,10 +11,10 @@ namespace AssetStoreTools.Utility
[InitializeOnLoad]
internal class ASToolsUpdater : AssetStoreToolsWindow
{
private const string AssetStoreToolsUrl = "https://assetstore.unity.com/packages/tools/utilities/asset-store-publishing-tools-115";
protected override string WindowTitle => "Asset Store Tools Update Check";
private static IAssetStoreApi _api;
private VisualElement _loadingContainer;
private VisualElement _versionInfoContainer;
@@ -37,6 +37,7 @@ namespace AssetStoreTools.Utility
static ASToolsUpdater()
{
_api = new AssetStoreApi(new AssetStoreClient());
// Retrieving cached SessionState/PlayerPrefs values is not allowed from an instance field initializer
EditorApplication.update += CheckForUpdatesAfterEditorUpdate;
}
@@ -68,7 +69,7 @@ namespace AssetStoreTools.Utility
private static async Task CheckForUpdates(Action<bool, Version, Version> OnUpdatesChecked)
{
_updateCheckPerformed = true;
var latestVersionResult = await AssetStoreAPI.GetLatestAssetStoreToolsVersion();
var latestVersionResult = await _api.GetLatestAssetStoreToolsVersion();
if (!latestVersionResult.Success)
{
OnUpdatesChecked?.Invoke(false, null, null);
@@ -80,7 +81,7 @@ namespace AssetStoreTools.Utility
try
{
var latestVersionStr = latestVersionResult.Response["version"].AsString();
var latestVersionStr = latestVersionResult.Version;
var currentVersionStr = PackageUtility.GetAllPackages().FirstOrDefault(x => x.name == "com.unity.asset-store-tools").version;
currentVersion = new Version(currentVersionStr);
@@ -96,8 +97,6 @@ namespace AssetStoreTools.Utility
protected override void Init()
{
base.Init();
rootVisualElement.styleSheets.Add(StyleSelector.UpdaterWindow.UpdaterWindowStyle);
rootVisualElement.styleSheets.Add(StyleSelector.UpdaterWindow.UpdaterWindowTheme);
@@ -123,7 +122,7 @@ namespace AssetStoreTools.Utility
private void SetupLoadingSpinner()
{
_loadingContainer = new VisualElement();
_loadingContainer.AddToClassList("loading-container");
_loadingContainer.AddToClassList("updater-loading-container");
_loadingImage = new Image();
EditorApplication.update += LoadingSpinLoop;
@@ -134,8 +133,8 @@ namespace AssetStoreTools.Utility
private void SetupVersionInfo(Version currentVersion, Version latestVersion)
{
_versionInfoContainer = new VisualElement();
_versionInfoContainer.AddToClassList("version-info-container");
_versionInfoContainer.AddToClassList("updater-info-container");
AddDescriptionLabels(currentVersion, latestVersion);
AddUpdateButtons(currentVersion, latestVersion);
AddCheckForUpdatesToggle();
@@ -150,19 +149,19 @@ namespace AssetStoreTools.Utility
"Asset Store Publishing Tools are up to date!";
var labelContainer = new VisualElement();
labelContainer.AddToClassList("version-info-container-labels");
labelContainer.AddToClassList("updater-info-container-labels");
var descriptionLabel = new Label(descriptionText);
descriptionLabel.AddToClassList("version-info-container-labels-description");
descriptionLabel.AddToClassList("updater-info-container-labels-description");
var currentVersionRow = new VisualElement();
currentVersionRow.AddToClassList("version-info-container-labels-row");
currentVersionRow.AddToClassList("updater-info-container-labels-row");
var latestVersionRow = new VisualElement();
latestVersionRow.AddToClassList("version-info-container-labels-row");
latestVersionRow.AddToClassList("updater-info-container-labels-row");
var currentVersionLabel = new Label("Current version:");
currentVersionLabel.AddToClassList("version-info-container-labels-row-identifier");
currentVersionLabel.AddToClassList("updater-info-container-labels-row-identifier");
var latestVersionLabel = new Label("Latest version:");
latestVersionLabel.AddToClassList("version-info-container-labels-row-identifier");
latestVersionLabel.AddToClassList("updater-info-container-labels-row-identifier");
var currentVersionLabelValue = new Label(currentVersion.ToString());
var latestVersionLabelValue = new Label(latestVersion.ToString());
@@ -185,8 +184,8 @@ namespace AssetStoreTools.Utility
return;
var buttonContainer = new VisualElement();
buttonContainer.AddToClassList("version-info-container-buttons");
var latestVersionButton = new Button(() => Application.OpenURL(AssetStoreToolsUrl)) { text = "Get the latest version" };
buttonContainer.AddToClassList("updater-info-container-buttons");
var latestVersionButton = new Button(() => Application.OpenURL(Constants.Updater.AssetStoreToolsUrl)) { text = "Get the latest version" };
var skipVersionButton = new Button(Close) { text = "Skip for now" };
buttonContainer.Add(latestVersionButton);
@@ -198,7 +197,7 @@ namespace AssetStoreTools.Utility
private void AddCheckForUpdatesToggle()
{
var toggleContainer = new VisualElement();
toggleContainer.AddToClassList("version-info-container-toggle");
toggleContainer.AddToClassList("updater-info-container-toggle");
var checkForUpdatesToggle = new Toggle() { text = "Check for Updates", value = ASToolsPreferences.Instance.CheckForUpdates };
checkForUpdatesToggle.RegisterValueChangedCallback(OnCheckForUpdatesToggleChanged);
@@ -215,7 +214,7 @@ namespace AssetStoreTools.Utility
private void SetupFailInfo()
{
var failContainer = new VisualElement();
failContainer.AddToClassList("fail-container");
failContainer.AddToClassList("updater-fail-container");
var failImage = new Image();
var failDescription = new Label("Asset Store Publishing Tools could not retrieve information about the latest version.");

View File

@@ -13,6 +13,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/Utility/ASToolsUpdater.cs
uploadId: 712972
uploadId: 724584

View File

@@ -0,0 +1,266 @@
using System.IO;
using CacheConstants = AssetStoreTools.Constants.Cache;
namespace AssetStoreTools.Utility
{
internal static class CacheUtil
{
public static bool GetFileFromTempCache(string fileName, out string filePath)
{
return GetCacheFile(CacheConstants.TempCachePath, fileName, out filePath);
}
public static bool GetFileFromPersistentCache(string fileName, out string filePath)
{
return GetCacheFile(CacheConstants.PersistentCachePath, fileName, out filePath);
}
public static bool GetFileFromProjectPersistentCache(string projectPath, string fileName, out string filePath)
{
return GetCacheFile(Path.Combine(projectPath, CacheConstants.PersistentCachePath), fileName, out filePath);
}
private static bool GetCacheFile(string rootPath, string fileName, out string filePath)
{
filePath = Path.Combine(rootPath, fileName);
return File.Exists(filePath);
}
public static void CreateFileInTempCache(string fileName, object content, bool overwrite)
{
CreateCacheFile(CacheConstants.TempCachePath, fileName, content, overwrite);
}
public static void CreateFileInPersistentCache(string fileName, object content, bool overwrite)
{
CreateCacheFile(CacheConstants.PersistentCachePath, fileName, content, overwrite);
}
private static void CreateCacheFile(string rootPath, string fileName, object content, bool overwrite)
{
if (!Directory.Exists(rootPath))
Directory.CreateDirectory(rootPath);
var fullPath = Path.Combine(rootPath, fileName);
bool willUpdate = false;
if (File.Exists(fullPath))
{
if (overwrite)
{
File.Delete(fullPath);
willUpdate = true;
}
else
return;
}
switch (content)
{
case byte[] bytes:
File.WriteAllBytes(fullPath, bytes);
break;
default:
File.WriteAllText(fullPath, content.ToString());
break;
}
var keyword = willUpdate ? "Updating" : "Creating";
ASDebug.Log($"{keyword} cache file: '{fullPath}'");
}
public static void DeleteFileFromTempCache(string fileName)
{
DeleteFileFromCache(CacheConstants.TempCachePath, fileName);
}
public static void DeleteFileFromPersistentCache(string fileName)
{
DeleteFileFromCache(CacheConstants.PersistentCachePath, fileName);
}
private static void DeleteFileFromCache(string rootPath, string fileName)
{
var path = Path.Combine(rootPath, fileName);
if (File.Exists(path))
File.Delete(path);
}
//private static void CreateFileInPersistentCache(string fileName, object content, bool overwrite)
//{
// CreateCacheFile(CacheConstants.PersistentCachePath, fileName, content, overwrite);
//}
//private static void CreateCacheFile(string rootPath, string fileName, object content, bool overwrite)
//{
// if (!Directory.Exists(rootPath))
// Directory.CreateDirectory(rootPath);
// var fullPath = Path.Combine(rootPath, fileName);
// if (File.Exists(fullPath))
// {
// if (overwrite)
// File.Delete(fullPath);
// else
// return;
// }
// switch (content)
// {
// case byte[] bytes:
// File.WriteAllBytes(fullPath, bytes);
// break;
// default:
// File.WriteAllText(fullPath, content.ToString());
// break;
// }
// ASDebug.Log($"Creating cached file: '{fullPath}'");
//}
//public static void ClearTempCache()
//{
// if (!File.Exists(Path.Combine(CacheConstants.TempCachePath, CacheConstants.PackageDataFile)))
// return;
// // Cache consists of package data and package texture thumbnails. We don't clear
// // texture thumbnails here since they are less likely to change. They are still
// // deleted and redownloaded every project restart (because of being stored in the 'Temp' folder)
// var fullPath = Path.Combine(CacheConstants.TempCachePath, CacheConstants.PackageDataFile);
// ASDebug.Log($"Deleting cached file '{fullPath}'");
// File.Delete(fullPath);
//}
//public static void CachePackageMetadata(List<Package> data)
//{
// var serializerSettings = new JsonSerializerSettings()
// {
// ContractResolver = Package.CachedPackageResolver.Instance,
// Formatting = Formatting.Indented
// };
// CreateFileInTempCache(CacheConstants.PackageDataFile, JsonConvert.SerializeObject(data, serializerSettings), true);
//}
//public static 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 static bool GetCachedPackageMetadata(out List<Package> data)
//{
// data = new List<Package>();
// var path = Path.Combine(CacheConstants.TempCachePath, CacheConstants.PackageDataFile);
// if (!File.Exists(path))
// return false;
// try
// {
// var serializerSettings = new JsonSerializerSettings()
// {
// ContractResolver = Package.CachedPackageResolver.Instance
// };
// data = JsonConvert.DeserializeObject<List<Package>>(File.ReadAllText(path, Encoding.UTF8), serializerSettings);
// return true;
// }
// catch
// {
// return false;
// }
//}
//public static void CacheTexture(string packageId, Texture2D texture)
//{
// CreateFileInTempCache($"{packageId}.png", texture.EncodeToPNG(), true);
//}
//public static bool GetCachedTexture(string packageId, out Texture2D texture)
//{
// texture = new Texture2D(1, 1);
// var path = Path.Combine(CacheConstants.TempCachePath, $"{packageId}.png");
// if (!File.Exists(path))
// return false;
// texture.LoadImage(File.ReadAllBytes(path));
// return true;
//}
//public static void CacheWorkflowStateData(string packageId, WorkflowStateData data)
//{
// var fileName = $"{packageId}-workflowStateData.asset";
// CreateFileInPersistentCache(fileName, JsonConvert.SerializeObject(data, Formatting.Indented), true);
//}
//public static bool GetCachedWorkflowStateData(string packageId, out WorkflowStateData data)
//{
// data = null;
// var path = Path.Combine(CacheConstants.PersistentCachePath, $"{packageId}-workflowStateData.asset");
// if (!File.Exists(path))
// return false;
// data = JsonConvert.DeserializeObject<WorkflowStateData>(File.ReadAllText(path, Encoding.UTF8));
// return true;
//}
//public static void CacheValidationStateData(ValidationStateData data)
//{
// var serializerSettings = new JsonSerializerSettings()
// {
// ContractResolver = ValidationStateDataContractResolver.Instance,
// Formatting = Formatting.Indented,
// TypeNameHandling = TypeNameHandling.Auto,
// Converters = new List<JsonConverter>() { new StringEnumConverter() }
// };
// CreateFileInPersistentCache(CacheConstants.ValidationResultFile, JsonConvert.SerializeObject(data, serializerSettings), true);
//}
//public static bool GetCachedValidationStateData(out ValidationStateData data)
//{
// return GetCachedValidationStateData(Constants.RootProjectPath, out data);
//}
//public static bool GetCachedValidationStateData(string projectPath, out ValidationStateData data)
//{
// data = null;
// var path = Path.Combine(projectPath, CacheConstants.PersistentCachePath, CacheConstants.ValidationResultFile);
// if (!File.Exists(path))
// return false;
// try
// {
// var serializerSettings = new JsonSerializerSettings()
// {
// ContractResolver = ValidationStateDataContractResolver.Instance,
// Formatting = Formatting.Indented,
// TypeNameHandling = TypeNameHandling.Auto,
// Converters = new List<JsonConverter>() { new StringEnumConverter() }
// };
// data = JsonConvert.DeserializeObject<ValidationStateData>(File.ReadAllText(path, Encoding.UTF8), serializerSettings);
// return true;
// }
// catch (System.Exception e)
// {
// UnityEngine.Debug.LogException(e);
// return false;
// }
//}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 265ad6f65404f8c42aec35d3b8e6f970
guid: 2e5fee0cad7655f458d9b600f4ae6d02
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/Utility/ASError.cs
uploadId: 712972
packageVersion: 12.0.1
assetPath: Packages/com.unity.asset-store-tools/Editor/Utility/CacheUtil.cs
uploadId: 724584

View File

@@ -13,6 +13,40 @@ namespace AssetStoreTools.Utility
public string CurrentName;
}
public static string AbsolutePathToRelativePath(string path, bool allowSymlinks)
{
if (!File.Exists(path) && !Directory.Exists(path))
return path;
string convertedPath = path.Replace("\\", "/");
var allPackages = PackageUtility.GetAllPackages();
foreach (var package in allPackages)
{
if (Path.GetFullPath(package.resolvedPath) != Path.GetFullPath(convertedPath)
&& !Path.GetFullPath(convertedPath).StartsWith(Path.GetFullPath(package.resolvedPath) + Path.DirectorySeparatorChar))
continue;
convertedPath = Path.GetFullPath(convertedPath)
.Replace(Path.GetFullPath(package.resolvedPath), package.assetPath)
.Replace("\\", "/");
return convertedPath;
}
if (convertedPath.StartsWith(Constants.RootProjectPath))
{
convertedPath = convertedPath.Substring(Constants.RootProjectPath.Length);
}
else
{
if (allowSymlinks && SymlinkUtil.FindSymlinkFolderRelative(convertedPath, out var symlinkPath))
convertedPath = symlinkPath;
}
return convertedPath;
}
public static void CopyDirectory(string sourceDir, string destinationDir, bool recursive)
{
// Get information about the source directory
@@ -46,29 +80,49 @@ namespace AssetStoreTools.Utility
}
}
public static bool IsMissingMetaFiles(params string[] sourcePaths)
public static bool ShouldHaveMeta(string assetPath)
{
if (string.IsNullOrEmpty(assetPath))
return false;
// Meta files never have other metas
if (assetPath.EndsWith(".meta", System.StringComparison.OrdinalIgnoreCase))
return false;
// File System entries ending with '~' are hidden in the context of ADB
if (assetPath.EndsWith("~"))
return false;
// File System entries whose names start with '.' are hidden in the context of ADB
var assetName = assetPath.Replace("\\", "/").Split('/').Last();
if (assetName.StartsWith("."))
return false;
return true;
}
public static bool IsMissingMetaFiles(IEnumerable<string> sourcePaths)
{
foreach (var sourcePath in sourcePaths)
{
if (!Directory.Exists(sourcePath))
continue;
var allDirectories = Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories);
foreach (var dir in allDirectories)
{
var dirInfo = new DirectoryInfo(dir);
if (dirInfo.Name.EndsWith("~"))
if (!dirInfo.Name.EndsWith("~"))
continue;
var nestedContent = dirInfo.GetFileSystemInfos("*", SearchOption.AllDirectories);
foreach (var nested in nestedContent)
{
var nestedContent = dirInfo.GetFileSystemInfos("*", SearchOption.AllDirectories);
if (!ShouldHaveMeta(nested.FullName))
continue;
foreach (var nested in nestedContent)
{
// .meta files, hidden files and OSX .DS_STORE files do not require their own metas
if (nested.FullName.EndsWith(".meta")
|| nested.FullName.EndsWith("~")
|| nested.Name.Equals(".DS_Store"))
continue;
if (!File.Exists(nested.FullName + ".meta"))
return true;
}
if (!File.Exists(nested.FullName + ".meta"))
return true;
}
}
}
@@ -76,17 +130,31 @@ namespace AssetStoreTools.Utility
return false;
}
public static void GenerateMetaFiles(params string[] sourcePaths)
public static void GenerateMetaFiles(IEnumerable<string> sourcePaths)
{
var renameInfos = new List<RenameInfo>();
foreach (var sourcePath in sourcePaths)
{
if (!Directory.Exists(sourcePath))
continue;
var hiddenDirectoriesInPath = Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories).Where(x => x.EndsWith("~"));
foreach (var hiddenDir in hiddenDirectoriesInPath)
renameInfos.Add(new RenameInfo() { CurrentName = hiddenDir, OriginalName = hiddenDir });
{
var hiddenDirRelative = AbsolutePathToRelativePath(hiddenDir, ASToolsPreferences.Instance.EnableSymlinkSupport);
if (!hiddenDirRelative.StartsWith("Assets/") && !hiddenDirRelative.StartsWith("Packages/"))
{
ASDebug.LogWarning($"Path {sourcePath} is not part of the Asset Database and will be skipped");
continue;
}
renameInfos.Add(new RenameInfo() { CurrentName = hiddenDirRelative, OriginalName = hiddenDirRelative });
}
}
if (renameInfos.Count == 0)
return;
try
{
@@ -108,6 +176,7 @@ namespace AssetStoreTools.Utility
{
AssetDatabase.StopAssetEditing();
AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);
AssetDatabase.ReleaseCachedFileHandles();
}
// Restore the original path names in reverse order
@@ -119,7 +188,6 @@ namespace AssetStoreTools.Utility
foreach (var renameInfo in renameInfos)
{
Directory.Move(renameInfo.CurrentName, renameInfo.OriginalName);
if (File.Exists($"{renameInfo.CurrentName}.meta"))
File.Delete($"{renameInfo.CurrentName}.meta");
}

View File

@@ -13,6 +13,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/Utility/FileUtility.cs
uploadId: 712972
uploadId: 724584

View File

@@ -1,772 +0,0 @@
/*
* Simple recursive descending JSON parser and
* JSON string builder.
*
* Jonas Drewsen - (C) Unity3d.com - 2010-2012
*
* JSONParser parser = new JSONParser(" { \"hello\" : 42.3 } ");
* JSONValue value = parser.Parse();
*
* bool is_it_float = value.isFloat();
* float the_float = value.asFloat();
* string the_string = value.Get("sub.structure.access").asString();
*
*/
using System.Collections.Generic;
using System;
namespace AssetStoreTools.Utility.Json
{
/*
* JSON value structure
*
* Example:
* JSONValue v = JSONValue.NewDict();
* v["hello"] = JSONValue.NewString("world");
* asset(v["hello"].AsString() == "world");
*
*/
internal struct JsonValue
{
public JsonValue(object o)
{
data = o;
}
public static implicit operator JsonValue(string s)
{
return new JsonValue(s);
}
public static implicit operator string(JsonValue s)
{
return s.AsString();
}
public static implicit operator JsonValue(float s)
{
return new JsonValue(s);
}
public static implicit operator float(JsonValue s)
{
return s.AsFloat();
}
public static implicit operator JsonValue(bool s)
{
return new JsonValue(s);
}
public static implicit operator bool(JsonValue s)
{
return s.AsBool();
}
public static implicit operator JsonValue(int s)
{
return new JsonValue((float)s);
}
public static implicit operator int(JsonValue s)
{
return (int)s.AsFloat();
}
public static implicit operator JsonValue(List<JsonValue> s)
{
return new JsonValue(s);
}
public static implicit operator List<JsonValue>(JsonValue s)
{
return s.AsList();
}
public static implicit operator Dictionary<string, JsonValue>(JsonValue s)
{
return s.AsDict();
}
public bool IsString() { return data is string; }
public bool IsFloat() { return data is float; }
public bool IsList() { return data is List<JsonValue>; }
public bool IsDict() { return data is Dictionary<string, JsonValue>; }
public bool IsBool() { return data is bool; }
public bool IsNull() { return data == null; }
public string AsString(bool nothrow = false)
{
if (data is string)
return (string)data;
if (!nothrow)
throw new JSONTypeException("Tried to read non-string json value as string");
return "";
}
public float AsFloat(bool nothrow = false)
{
if (data is float)
return (float)data;
if (!nothrow)
throw new JSONTypeException("Tried to read non-float json value as float");
return 0.0f;
}
public bool AsBool(bool nothrow = false)
{
if (data is bool)
return (bool)data;
if (!nothrow)
throw new JSONTypeException("Tried to read non-bool json value as bool");
return false;
}
public List<JsonValue> AsList(bool nothrow = false)
{
if (data is List<JsonValue>)
return (List<JsonValue>)data;
if (!nothrow)
throw new JSONTypeException("Tried to read " + data.GetType().Name + " json value as list");
return null;
}
public Dictionary<string, JsonValue> AsDict(bool nothrow = false)
{
if (data is Dictionary<string, JsonValue>)
return (Dictionary<string, JsonValue>)data;
if (!nothrow)
throw new JSONTypeException("Tried to read non-dictionary json value as dictionary");
return null;
}
public static JsonValue NewString(string val)
{
return new JsonValue(val);
}
public static JsonValue NewFloat(float val)
{
return new JsonValue(val);
}
public static JsonValue NewDict()
{
return new JsonValue(new Dictionary<string, JsonValue>());
}
public static JsonValue NewList()
{
return new JsonValue(new List<JsonValue>());
}
public static JsonValue NewBool(bool val)
{
return new JsonValue(val);
}
public static JsonValue NewNull()
{
return new JsonValue(null);
}
public JsonValue InitList()
{
data = new List<JsonValue>();
return this;
}
public JsonValue InitDict()
{
data = new Dictionary<string, JsonValue>();
return this;
}
public JsonValue this[string index]
{
get
{
Dictionary<string, JsonValue> dict = AsDict();
return dict[index];
}
set
{
if (data == null)
data = new Dictionary<string, JsonValue>();
Dictionary<string, JsonValue> dict = AsDict();
dict[index] = value;
}
}
public bool ContainsKey(string index)
{
if (!IsDict())
return false;
return AsDict().ContainsKey(index);
}
// Get the specified field in a dict or null json value if
// no such field exists. The key can point to a nested structure
// e.g. key1.key2 in { key1 : { key2 : 32 } }
public JsonValue Get(string key, out bool found)
{
found = false;
if (!IsDict())
return new JsonValue(null);
JsonValue value = this;
foreach (string part in key.Split('.'))
{
if (!value.ContainsKey(part))
return new JsonValue(null);
value = value[part];
}
found = true;
return value;
}
public JsonValue Get(string key)
{
bool found;
return Get(key, out found);
}
public bool Copy(string key, ref string dest)
{
return Copy(key, ref dest, true);
}
public bool Copy(string key, ref string dest, bool allowCopyNull)
{
bool found;
JsonValue jv = Get(key, out found);
if (found && (!jv.IsNull() || allowCopyNull))
dest = jv.IsNull() ? null : jv.AsString();
return found;
}
public bool Copy(string key, ref bool dest)
{
bool found;
JsonValue jv = Get(key, out found);
if (found && !jv.IsNull())
dest = jv.AsBool();
return found;
}
public bool Copy(string key, ref int dest)
{
bool found;
JsonValue jv = Get(key, out found);
if (found && !jv.IsNull())
dest = (int)jv.AsFloat();
return found;
}
// Convenience dict value setting
public void Set(string key, string value)
{
Set(key, value, true);
}
public void Set(string key, string value, bool allowNull)
{
if (value == null)
{
if (!allowNull)
return;
this[key] = NewNull();
return;
}
this[key] = NewString(value);
}
// Convenience dict value setting
public void Set(string key, float value)
{
this[key] = NewFloat(value);
}
// Convenience dict value setting
public void Set(string key, bool value)
{
this[key] = NewBool(value);
}
// Convenience list value add
public void Add(string value)
{
List<JsonValue> list = AsList();
if (value == null)
{
list.Add(NewNull());
return;
}
list.Add(NewString(value));
}
// Convenience list value add
public void Add(float value)
{
List<JsonValue> list = AsList();
list.Add(NewFloat(value));
}
// Convenience list value add
public void Add(bool value)
{
List<JsonValue> list = AsList();
list.Add(NewBool(value));
}
public override string ToString()
{
return ToString(null, "");
}
/*
* Serialize a JSON value to string.
* This will recurse down through dicts and list type JSONValues.
*/
public string ToString(string curIndent, string indent)
{
bool indenting = curIndent != null;
if (IsString())
{
return "\"" + EncodeString(AsString()) + "\"";
}
else if (IsFloat())
{
return AsFloat().ToString();
}
else if (IsList())
{
string res = "[";
string delim = "";
foreach (JsonValue i in AsList())
{
res += delim + i.ToString();
delim = ", ";
}
return res + "]";
}
else if (IsDict())
{
string res = "{" + (indenting ? "\n" : "");
string delim = "";
foreach (KeyValuePair<string, JsonValue> kv in AsDict())
{
res += delim + curIndent + indent + '"' + EncodeString(kv.Key) + "\" : " + kv.Value.ToString(curIndent + indent, indent);
delim = ", " + (indenting ? "\n" : "");
}
return res + (indenting ? "\n" + curIndent : "") + "}";
}
else if (IsBool())
{
return AsBool() ? "true" : "false";
}
else if (IsNull())
{
return "null";
}
else
{
throw new JSONTypeException("Cannot serialize json value of unknown type");
}
}
// Encode a string into a json string
private static string EncodeString(string str)
{
str = str.Replace("\\", "\\\\");
str = str.Replace("\"", "\\\"");
str = str.Replace("/", "\\/");
str = str.Replace("\b", "\\b");
str = str.Replace("\f", "\\f");
str = str.Replace("\n", "\\n");
str = str.Replace("\r", "\\r");
str = str.Replace("\t", "\\t");
// We do not use \uXXXX specifier but direct unicode in the string.
return str;
}
object data;
}
internal class JSONParseException : Exception
{
public JSONParseException(string msg) : base(msg)
{
}
}
internal class JSONTypeException : Exception
{
public JSONTypeException(string msg) : base(msg)
{
}
}
/*
* Top down recursive JSON parser
*
* Example:
* string json = "{ \"hello\" : \"world\", \"age\" : 100000, "sister" : null }";
* JSONValue val = JSONParser.SimpleParse(json);
* asset( val["hello"].AsString() == "world" );
*
*/
internal class JSONParser
{
private string json;
private int line;
private int linechar;
private int len;
private int idx;
private int pctParsed;
private char cur;
public static JsonValue SimpleParse(string jsondata)
{
var parser = new JSONParser(jsondata);
try
{
return parser.Parse();
}
catch (JSONParseException ex)
{
Console.WriteLine(ex.Message);
//DebugUtils.LogError(ex.Message);
}
return new JsonValue(null);
}
public static bool AssetStoreResponseParse(string responseJson, out ASError error, out JsonValue jval)
{
jval = new JsonValue();
error = null;
try
{
JSONParser parser = new JSONParser(responseJson);
jval = parser.Parse();
}
catch (JSONParseException)
{
error = ASError.GetGenericError(new Exception("Error parsing reply from AssetStore"));
return false;
}
// Some json responses return an error field on error
if (jval.ContainsKey("error"))
{
// Server side error message
// Do not write to console since this is an error that
// is "expected" ie. can be handled by the gui.
error = ASError.GetGenericError(new Exception(jval["error"].AsString(true)));
}
// Some json responses return status+message fields instead of an error field. Go figure.
else if (jval.ContainsKey("status") && jval["status"].AsString(true) != "ok")
{
error = ASError.GetGenericError(new Exception(jval["message"].AsString(true)));
}
return error == null;
}
/*
* Setup a parse to be ready for parsing the given string
*/
public JSONParser(string jsondata)
{
// TODO: fix that parser needs trailing spaces;
json = jsondata + " ";
line = 1;
linechar = 1;
len = json.Length;
idx = 0;
pctParsed = 0;
}
/*
* Parse the entire json data string into a JSONValue structure hierarchy
*/
public JsonValue Parse()
{
cur = json[idx];
return ParseValue();
}
private char Next()
{
if (cur == '\n')
{
line++;
linechar = 0;
}
idx++;
if (idx >= len)
throw new JSONParseException("End of json while parsing at " + PosMsg());
linechar++;
int newPct = (int)((float)idx * 100f / (float)len);
if (newPct != pctParsed)
{
pctParsed = newPct;
}
cur = json[idx];
return cur;
}
private void SkipWs()
{
const string ws = " \n\t\r";
while (ws.IndexOf(cur) != -1) Next();
}
private string PosMsg()
{
return "line " + line.ToString() + ", column " + linechar.ToString();
}
private JsonValue ParseValue()
{
// Skip spaces
SkipWs();
switch (cur)
{
case '[':
return ParseArray();
case '{':
return ParseDict();
case '"':
return ParseString();
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return ParseNumber();
case 't':
case 'f':
case 'n':
return ParseConstant();
default:
throw new JSONParseException("Cannot parse json value starting with '" + json.Substring(idx, 5) + "' at " + PosMsg());
}
}
private JsonValue ParseArray()
{
Next();
SkipWs();
List<JsonValue> arr = new List<JsonValue>();
while (cur != ']')
{
arr.Add(ParseValue());
SkipWs();
if (cur == ',')
{
Next();
SkipWs();
}
}
Next();
return new JsonValue(arr);
}
private JsonValue ParseDict()
{
Next();
SkipWs();
Dictionary<string, JsonValue> dict = new Dictionary<string, JsonValue>();
while (cur != '}')
{
JsonValue key = ParseValue();
if (!key.IsString())
throw new JSONParseException("Key not string type at " + PosMsg());
SkipWs();
if (cur != ':')
throw new JSONParseException("Missing dict entry delimiter ':' at " + PosMsg());
Next();
dict.Add(key.AsString(), ParseValue());
SkipWs();
if (cur == ',')
{
Next();
SkipWs();
}
}
Next();
return new JsonValue(dict);
}
static char[] endcodes = { '\\', '"' };
private JsonValue ParseString()
{
string res = "";
Next();
while (idx < len)
{
int endidx = json.IndexOfAny(endcodes, idx);
if (endidx < 0)
throw new JSONParseException("missing '\"' to end string at " + PosMsg());
res += json.Substring(idx, endidx - idx);
if (json[endidx] == '"')
{
cur = json[endidx];
idx = endidx;
break;
}
endidx++; // get escape code
if (endidx >= len)
throw new JSONParseException("End of json while parsing while parsing string at " + PosMsg());
// char at endidx is \
char ncur = json[endidx];
switch (ncur)
{
case '"':
goto case '/';
case '\\':
goto case '/';
case '/':
res += ncur;
break;
case 'b':
res += '\b';
break;
case 'f':
res += '\f';
break;
case 'n':
res += '\n';
break;
case 'r':
res += '\r';
break;
case 't':
res += '\t';
break;
case 'u':
// Unicode char specified by 4 hex digits
string digit = "";
if (endidx + 4 >= len)
throw new JSONParseException("End of json while parsing while parsing unicode char near " + PosMsg());
digit += json[endidx + 1];
digit += json[endidx + 2];
digit += json[endidx + 3];
digit += json[endidx + 4];
try
{
int d = Int32.Parse(digit, System.Globalization.NumberStyles.AllowHexSpecifier);
res += (char)d;
}
catch (FormatException)
{
throw new JSONParseException("Invalid unicode escape char near " + PosMsg());
}
endidx += 4;
break;
default:
throw new JSONParseException("Invalid escape char '" + ncur + "' near " + PosMsg());
}
idx = endidx + 1;
}
if (idx >= len)
throw new JSONParseException("End of json while parsing while parsing string near " + PosMsg());
cur = json[idx];
Next();
return new JsonValue(res);
}
private JsonValue ParseNumber()
{
string resstr = "";
if (cur == '-')
{
resstr = "-";
Next();
}
while (cur >= '0' && cur <= '9')
{
resstr += cur;
Next();
}
if (cur == '.')
{
Next();
resstr += '.';
while (cur >= '0' && cur <= '9')
{
resstr += cur;
Next();
}
}
if (cur == 'e' || cur == 'E')
{
resstr += "e";
Next();
if (cur != '-' && cur != '+')
{
// throw new JSONParseException("Missing - or + in 'e' potent specifier at " + PosMsg());
resstr += cur;
Next();
}
while (cur >= '0' && cur <= '9')
{
resstr += cur;
Next();
}
}
try
{
float f = Convert.ToSingle(resstr);
return new JsonValue(f);
}
catch (Exception)
{
throw new JSONParseException("Cannot convert string to float : '" + resstr + "' at " + PosMsg());
}
}
private JsonValue ParseConstant()
{
string c = "" + cur + Next() + Next() + Next();
Next();
if (c == "true")
{
return new JsonValue(true);
}
else if (c == "fals")
{
if (cur == 'e')
{
Next();
return new JsonValue(false);
}
}
else if (c == "null")
{
return new JsonValue(null);
}
throw new JSONParseException("Invalid token at " + PosMsg());
}
};
}

View File

@@ -1,9 +0,0 @@
fileFormatVersion: 1
guid: 0a7878c3076bf174ea5c0a1cf7bd3a39
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 11.4.4
assetPath: Packages/com.unity.asset-store-tools/Editor/Utility/Json.cs
uploadId: 712972

View File

@@ -13,6 +13,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/Utility/LegacyToolsRemover.cs
uploadId: 712972
uploadId: 724584

View File

@@ -1,34 +1,63 @@
#if UNITY_2019 || UNITY_2020
#if !UNITY_2021_1_OR_NEWER
using System;
using System.Reflection;
#endif
using UnityEngine;
using UnityEditor.PackageManager;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEditor.PackageManager;
using UnityEngine;
using PackageInfo = UnityEditor.PackageManager.PackageInfo;
namespace AssetStoreTools.Utility
{
internal static class PackageUtility
{
/// <summary>
/// Returns the package path on disk. If the path is within the root
/// project folder, the returned path will be relative to the root project folder.
/// Otherwise, an absolute path is returned
/// </summary>
public static string GetConvenientPath(this PackageInfo packageInfo)
public class PackageInfoSampleMetadata
{
var path = packageInfo.resolvedPath.Replace("\\", "/");
public string DisplayName;
public string Description;
public string Path;
}
var rootProjectPath = Application.dataPath.Substring(0, Application.dataPath.Length - "Assets".Length);
if (path.StartsWith(rootProjectPath))
path = path.Substring(rootProjectPath.Length);
public class PackageInfoUnityVersionMetadata
{
/// <summary>
/// Major bit of the Unity version, e.g. 2021.3
/// </summary>
public string Version;
/// <summary>
/// Minor bit of the Unity version, e.g. 0f1
/// </summary>
public string Release;
return path;
public override string ToString()
{
if (string.IsNullOrEmpty(Version))
return Release;
if (string.IsNullOrEmpty(Release))
return Release;
return $"{Version}.{Release}";
}
}
/// <summary>
/// Returns a package identifier, consisting of package name and package version
/// </summary>
/// <param name="package"></param>
/// <returns></returns>
public static string GetPackageIdentifier(this PackageInfo package)
{
return $"{package.name}-{package.version}";
}
public static PackageInfo[] GetAllPackages()
{
#if UNITY_2019 || UNITY_2020
#if !UNITY_2021_1_OR_NEWER
var method = typeof(PackageInfo).GetMethod("GetAll", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static, null, new Type[0], null);
var packages = method?.Invoke(null, null) as PackageInfo[];
#else
@@ -54,5 +83,88 @@ namespace AssetStoreTools.Utility
return registryPackages;
}
public static bool GetPackageByManifestPath(string packageManifestPath, out PackageInfo package)
{
package = null;
if (string.IsNullOrEmpty(packageManifestPath))
return false;
var fileInfo = new FileInfo(packageManifestPath);
if (!fileInfo.Exists)
return false;
var allPackages = GetAllPackages();
package = allPackages.FirstOrDefault(x => Path.GetFullPath(x.resolvedPath).Equals(fileInfo.Directory.FullName));
return package != null;
}
public static bool GetPackageByPackageName(string packageName, out PackageInfo package)
{
package = null;
if (string.IsNullOrEmpty(packageName))
return false;
return GetPackageByManifestPath($"Packages/{packageName}/package.json", out package);
}
public static TextAsset GetManifestAsset(this PackageInfo packageInfo)
{
return AssetDatabase.LoadAssetAtPath<TextAsset>($"{packageInfo.assetPath}/package.json");
}
public static List<PackageInfoSampleMetadata> GetSamples(this PackageInfo packageInfo)
{
var samples = new List<PackageInfoSampleMetadata>();
var packageManifest = packageInfo.GetManifestAsset();
var json = JObject.Parse(packageManifest.text);
if (!json.ContainsKey("samples") || json["samples"].Type != JTokenType.Array)
return samples;
var sampleList = json["samples"].ToList();
foreach (JObject sample in sampleList)
{
var displayName = string.Empty;
var description = string.Empty;
var path = string.Empty;
if (sample.ContainsKey("displayName"))
displayName = sample["displayName"].ToString();
if (sample.ContainsKey("description"))
description = sample["description"].ToString();
if (sample.ContainsKey("path"))
path = sample["path"].ToString();
if (!string.IsNullOrEmpty(displayName) || !string.IsNullOrEmpty(description) || !string.IsNullOrEmpty(path))
samples.Add(new PackageInfoSampleMetadata() { DisplayName = displayName, Description = description, Path = path });
}
return samples;
}
public static PackageInfoUnityVersionMetadata GetUnityVersion(this PackageInfo packageInfo)
{
var packageManifest = packageInfo.GetManifestAsset();
var json = JObject.Parse(packageManifest.text);
var unityVersion = string.Empty;
var unityRelease = string.Empty;
if (json.ContainsKey("unity"))
unityVersion = json["unity"].ToString();
if (json.ContainsKey("unityRelease"))
unityRelease = json["unityRelease"].ToString();
return new PackageInfoUnityVersionMetadata()
{
Version = unityVersion,
Release = unityRelease
};
}
}
}

View File

@@ -13,6 +13,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/Utility/PackageUtility.cs
uploadId: 712972
uploadId: 724584

View File

@@ -0,0 +1,113 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace AssetStoreTools.Utility
{
internal abstract class ServiceProvider<Service>
{
private Dictionary<Type, Service> _services = new Dictionary<Type, Service>();
private Dictionary<Type, Func<Service>> _queuedServices = new Dictionary<Type, Func<Service>>();
protected class MissingServiceDependencyException : Exception
{
public Type ServiceType { get; private set; }
public Type MissingDependencyType { get; private set; }
public MissingServiceDependencyException(Type serviceType, Type missingDependencyType)
{
ServiceType = serviceType;
MissingDependencyType = missingDependencyType;
}
}
protected ServiceProvider()
{
RegisterServices();
CreateRegisteredServices();
}
protected abstract void RegisterServices();
protected void Register<TService, TInstance>() where TService : Service where TInstance : TService
{
Register<TService>(() => CreateServiceInstance(typeof(TInstance)));
}
protected void Register<TService>(Func<Service> initializer) where TService : Service
{
_queuedServices.Add(typeof(TService), initializer);
}
private void CreateRegisteredServices()
{
if (_queuedServices.Count == 0)
return;
var createdAnyService = false;
var missingServices = new List<MissingServiceDependencyException>();
foreach (var service in _queuedServices)
{
try
{
var instance = service.Value.Invoke();
_services.Add(service.Key, instance);
createdAnyService = true;
}
catch (MissingServiceDependencyException e)
{
missingServices.Add(e);
}
}
foreach (var createdService in _services)
{
_queuedServices.Remove(createdService.Key);
}
if (!createdAnyService)
{
var message = string.Join(", ", missingServices.Select(x => $"{x.ServiceType} depends on {x.MissingDependencyType}"));
throw new Exception("Could not create the following services due to missing dependencies: " + message);
}
// Recursively register remaining queued services that may have failed
// due to missing depenedencies that are now registered
CreateRegisteredServices();
}
private Service CreateServiceInstance(Type concreteType)
{
if (concreteType.IsAbstract)
throw new Exception($"Cannot create an instance of an abstract class {concreteType}");
var constructor = concreteType.GetConstructors().First();
var expectedParameters = constructor.GetParameters();
var parametersToUse = new List<object>();
foreach (var parameter in expectedParameters)
{
if (!_services.ContainsKey(parameter.ParameterType))
throw new MissingServiceDependencyException(concreteType, parameter.ParameterType);
parametersToUse.Add(_services[parameter.ParameterType]);
}
return (Service)constructor.Invoke(parametersToUse.ToArray());
}
public T GetService<T>() where T : Service
{
return (T)GetService(typeof(T));
}
public object GetService(Type type)
{
if (!_services.ContainsKey(type))
throw new Exception($"Service of type {type} is not registered");
return _services[type];
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 2fcadafa6431d1647a82d35e6e4a13c5
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/Utility/ServiceProvider.cs
uploadId: 724584

View File

@@ -1,58 +1,55 @@
using UnityEditor;
using System;
using UnityEditor;
using UnityEngine.UIElements;
using WindowStyles = AssetStoreTools.Constants.WindowStyles;
namespace AssetStoreTools.Utility
{
internal static class StyleSelector
{
private static StyleSheet GetStylesheet(string stylesheetPath)
private static StyleSheet GetStylesheet(string rootPath, string filePath)
{
return AssetDatabase.LoadAssetAtPath<StyleSheet>(stylesheetPath);
var path = $"{rootPath}/{filePath}.uss";
var sheet = AssetDatabase.LoadAssetAtPath<StyleSheet>(path);
if (sheet == null)
throw new Exception($"Stylesheet '{path}' was not found");
return sheet;
}
private static StyleSheet GetStylesheetTheme(string rootPath, string filePath)
{
var suffix = !EditorGUIUtility.isProSkin ? "Light" : "Dark";
return GetStylesheet(rootPath, filePath + suffix);
}
public static class UploaderWindow
{
private const string StylesPath = "Packages/com.unity.asset-store-tools/Editor/Uploader/Styles";
public static StyleSheet UploaderWindowStyle => GetStylesheet(WindowStyles.UploaderStylesPath, "Style");
public static StyleSheet UploaderWindowTheme => GetStylesheetTheme(WindowStyles.UploaderStylesPath, "Theme");
public static StyleSheet BaseWindowStyle => GetStylesheet($"{StylesPath}/Base/BaseWindow_Main.uss");
public static StyleSheet BaseWindowTheme => !EditorGUIUtility.isProSkin ?
GetStylesheet($"{StylesPath}/Base/BaseWindow_Light.uss") :
GetStylesheet($"{StylesPath}/Base/BaseWindow_Dark.uss");
public static StyleSheet LoginViewStyle => GetStylesheet(WindowStyles.UploaderStylesPath, "LoginView/Style");
public static StyleSheet LoginViewTheme => GetStylesheetTheme(WindowStyles.UploaderStylesPath, "LoginView/Theme");
public static StyleSheet LoginWindowStyle => GetStylesheet($"{StylesPath}/Login/Login_Main.uss");
public static StyleSheet LoginWindowTheme => !EditorGUIUtility.isProSkin ?
GetStylesheet($"{StylesPath}/Login/Login_Light.uss") :
GetStylesheet($"{StylesPath}/Login/Login_Dark.uss");
public static StyleSheet UploadWindowStyle => GetStylesheet($"{StylesPath}/Upload/UploadWindow_Main.uss");
public static StyleSheet UploadWindowTheme => !EditorGUIUtility.isProSkin ?
GetStylesheet($"{StylesPath}/Upload/UploadWindow_Light.uss") :
GetStylesheet($"{StylesPath}/Upload/UploadWindow_Dark.uss");
public static StyleSheet AllPackagesStyle => GetStylesheet($"{StylesPath}/Upload/AllPackages/AllPackages_Main.uss");
public static StyleSheet AllPackagesTheme => !EditorGUIUtility.isProSkin ?
GetStylesheet($"{StylesPath}/Upload/AllPackages/AllPackages_Light.uss") :
GetStylesheet($"{StylesPath}/Upload/AllPackages/AllPackages_Dark.uss");
public static StyleSheet PackageListViewStyle => GetStylesheet(WindowStyles.UploaderStylesPath, "PackageListView/Style");
public static StyleSheet PackageListViewTheme => GetStylesheetTheme(WindowStyles.UploaderStylesPath, "PackageListView/Theme");
}
public static class ValidatorWindow
public static class ValidatorWindow
{
private const string StylesPath = "Packages/com.unity.asset-store-tools/Editor/Validator/Styles";
public static StyleSheet ValidatorWindowStyle => GetStylesheet(WindowStyles.ValidatorStylesPath, "Style");
public static StyleSheet ValidatorWindowTheme => GetStylesheetTheme(WindowStyles.ValidatorStylesPath, "Theme");
}
public static StyleSheet ValidatorWindowStyle => GetStylesheet($"{StylesPath}/Validator_Main.uss");
public static StyleSheet ValidatorWindowTheme => !EditorGUIUtility.isProSkin ?
GetStylesheet($"{StylesPath}/Validator_Light.uss") :
GetStylesheet($"{StylesPath}/Validator_Dark.uss");
public static class PreviewGeneratorWindow
{
public static StyleSheet PreviewGeneratorWindowStyle => GetStylesheet(WindowStyles.PreviewGeneratorStylesPath, "Style");
public static StyleSheet PreviewGeneratorWindowTheme => GetStylesheetTheme(WindowStyles.PreviewGeneratorStylesPath, "Theme");
}
public static class UpdaterWindow
{
private const string StylesPath = "Packages/com.unity.asset-store-tools/Editor/Utility/Styles/Updater";
public static StyleSheet UpdaterWindowStyle => GetStylesheet($"{StylesPath}/Updater_Main.uss");
public static StyleSheet UpdaterWindowTheme => !EditorGUIUtility.isProSkin ?
GetStylesheet($"{StylesPath}/Updater_Light.uss") :
GetStylesheet($"{StylesPath}/Updater_Dark.uss");
public static StyleSheet UpdaterWindowStyle => GetStylesheet(WindowStyles.UpdaterStylesPath, "Style");
public static StyleSheet UpdaterWindowTheme => GetStylesheetTheme(WindowStyles.UpdaterStylesPath, "Theme");
}
}
}

View File

@@ -13,6 +13,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/Utility/StyleSelector.cs
uploadId: 712972
uploadId: 724584

View File

@@ -1,61 +1,61 @@
.loading-container {
.updater-loading-container {
flex-grow: 1;
align-items: center;
justify-content: center;
}
.loading-container > Image {
.updater-loading-container > Image {
width: 16px;
height: 16px;
}
.version-info-container {
.updater-info-container {
flex-grow: 1;
margin: 0 5px 5px 5px;
}
.version-info-container-labels {
.updater-info-container-labels {
flex-grow: 1;
margin-bottom: 10px;
margin-top: 5px;
}
.version-info-container-labels-description {
.updater-info-container-labels-description {
flex-grow: 0.5;
margin-bottom: 5px;
white-space: normal;
-unity-text-align: middle-left;
}
.version-info-container-labels-row {
.updater-info-container-labels-row {
flex-direction: row;
}
.version-info-container-labels-row-identifier {
.updater-info-container-labels-row-identifier {
-unity-font-style: bold;
}
.version-info-container-buttons {
.updater-info-container-buttons {
flex-direction: row;
margin-bottom: 5px;
}
.version-info-container-buttons > Button {
.updater-info-container-buttons > Button {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 100%;
height: 25px;
}
.version-info-container-toggle {
.updater-info-container-toggle {
align-self: flex-end;
}
.version-info-container-toggle > Toggle > VisualElement > Label {
.updater-info-container-toggle > Toggle > VisualElement > Label {
margin-left: 5px;
}
.fail-container {
.updater-fail-container {
flex-grow: 1;
flex-direction: row;
margin: 0 5px 5px 5px;
@@ -63,14 +63,14 @@
align-items: center;
}
.fail-container > Image {
.updater-fail-container > Image {
flex-shrink: 0;
width: 36px;
height: 36px;
margin-right: 5px;
}
.fail-container > Label {
.updater-fail-container > Label {
flex-shrink: 1;
white-space: normal;
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 225786b34a57ee440b0c1b213902214a
guid: 23112eed1f211274c94028490f81007c
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
@@ -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/Utility/Styles/Updater/Updater_Dark.uss
uploadId: 712972
packageVersion: 12.0.1
assetPath: Packages/com.unity.asset-store-tools/Editor/Utility/Styles/Updater/Style.uss
uploadId: 724584

View File

@@ -0,0 +1,3 @@
.updater-fail-container > Image {
--unity-image: resource("console.erroricon@2x");
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: daf82dcb916f6ae498d03a6a127122c6
guid: 0cbf43b8dabcd1242b32ed3ed2167a54
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
@@ -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/Utility/Styles/Updater/Updater_Main.uss
uploadId: 712972
packageVersion: 12.0.1
assetPath: Packages/com.unity.asset-store-tools/Editor/Utility/Styles/Updater/ThemeDark.uss
uploadId: 724584

View File

@@ -0,0 +1,3 @@
.updater-fail-container > Image {
--unity-image: resource("console.erroricon@2x");
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 8cdc065c428afe14c96781ac6fd73d73
guid: d453bb92cd1f35943b1c5f652837ada9
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
@@ -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/Utility/Styles/Updater/Updater_Light.uss
uploadId: 712972
packageVersion: 12.0.1
assetPath: Packages/com.unity.asset-store-tools/Editor/Utility/Styles/Updater/ThemeLight.uss
uploadId: 724584

View File

@@ -1,7 +0,0 @@
.loading-container > VisualElement > Image {
--unity-image: resource("d_WaitSpin00");
}
.fail-container > Image {
--unity-image: resource("console.erroricon@2x");
}

View File

@@ -1,7 +0,0 @@
.loading-container > VisualElement > Image {
--unity-image: resource("WaitSpin00");
}
.fail-container > Image {
--unity-image: resource("console.erroricon@2x");
}

View File

@@ -10,24 +10,24 @@ namespace AssetStoreTools.Utility
{
// Get directory info for path outside of the project
var absoluteInfo = new DirectoryInfo(folderPathAbsolute);
// Get all directories within the project
var allFolderPaths = Directory.GetDirectories("Assets", "*", SearchOption.AllDirectories);
foreach (var path in allFolderPaths)
{
var fullPath = path.Replace("\\", "/");
// Get directory info for one of the paths within the project
var relativeInfo = new DirectoryInfo(fullPath);
// Check if project's directory is a symlink
if (!relativeInfo.Attributes.HasFlag(FolderSymlinkAttributes))
if (!relativeInfo.Attributes.HasFlag(FolderSymlinkAttributes))
continue;
// Compare metadata of outside directory with a directories within the project
if (!CompareDirectories(absoluteInfo, relativeInfo))
if (!CompareDirectories(absoluteInfo, relativeInfo))
continue;
// Found symlink within the project, assign it
relativePath = fullPath;
return true;
@@ -36,7 +36,7 @@ namespace AssetStoreTools.Utility
relativePath = string.Empty;
return false;
}
private static bool CompareDirectories(DirectoryInfo directory, DirectoryInfo directory2)
{
var contents = directory.EnumerateFileSystemInfos("*", SearchOption.AllDirectories).GetEnumerator();
@@ -53,7 +53,7 @@ namespace AssetStoreTools.Utility
if (!firstNext && !secondNext)
break;
var equals = contents.Current?.Name == contents2.Current?.Name
var equals = contents.Current?.Name == contents2.Current?.Name
&& contents.Current?.LastWriteTime == contents2.Current?.LastWriteTime;
if (!equals)
@@ -62,6 +62,6 @@ namespace AssetStoreTools.Utility
return true;
}
}
}

View File

@@ -5,6 +5,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/Utility/SymlinkUtil.cs
uploadId: 712972
uploadId: 724584