first commit
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AssetStoreTools.Utility
|
||||
{
|
||||
internal static class ASDebug
|
||||
{
|
||||
private enum LogType
|
||||
{
|
||||
Log,
|
||||
Warning,
|
||||
Error
|
||||
}
|
||||
|
||||
private static bool s_debugModeEnabled = EditorPrefs.GetBool("ASTDebugMode");
|
||||
|
||||
public static bool DebugModeEnabled
|
||||
{
|
||||
get => s_debugModeEnabled;
|
||||
set
|
||||
{
|
||||
s_debugModeEnabled = value;
|
||||
EditorPrefs.SetBool("ASTDebugMode", value);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Log(object message)
|
||||
{
|
||||
LogMessage(message, LogType.Log);
|
||||
}
|
||||
|
||||
public static void LogWarning(object message)
|
||||
{
|
||||
LogMessage(message, LogType.Warning);
|
||||
}
|
||||
|
||||
public static void LogError(object message)
|
||||
{
|
||||
LogMessage(message, LogType.Error);
|
||||
}
|
||||
|
||||
private static void LogMessage(object message, LogType type)
|
||||
{
|
||||
if (!DebugModeEnabled)
|
||||
return;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case LogType.Log:
|
||||
Debug.Log(message);
|
||||
break;
|
||||
case LogType.Warning:
|
||||
Debug.LogWarning(message);
|
||||
break;
|
||||
case LogType.Error:
|
||||
Debug.LogError(message);
|
||||
break;
|
||||
default:
|
||||
Debug.Log(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 478caa497d99100429a0509fa487bfe4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 11.4.3
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Utility/ASDebug.cs
|
||||
uploadId: 681981
|
||||
@@ -0,0 +1,93 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 265ad6f65404f8c42aec35d3b8e6f970
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 11.4.3
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Utility/ASError.cs
|
||||
uploadId: 681981
|
||||
@@ -0,0 +1,140 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
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();
|
||||
}
|
||||
|
||||
private void Load()
|
||||
{
|
||||
CheckForUpdates = PlayerPrefs.GetInt("AST_CheckForUpdates", 1) == 1;
|
||||
LegacyVersionCheck = PlayerPrefs.GetInt("AST_LegacyVersionCheck", 1) == 1;
|
||||
UploadVersionCheck = PlayerPrefs.GetInt("AST_UploadVersionCheck", 1) == 1;
|
||||
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)
|
||||
{
|
||||
PlayerPrefs.SetInt("AST_CheckForUpdates", CheckForUpdates ? 1 : 0);
|
||||
PlayerPrefs.SetInt("AST_LegacyVersionCheck", LegacyVersionCheck ? 1 : 0);
|
||||
PlayerPrefs.SetInt("AST_UploadVersionCheck", UploadVersionCheck ? 1 : 0);
|
||||
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)
|
||||
OnSettingsChange?.Invoke();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Periodically check if an update for the Asset Store Publishing Tools is available
|
||||
/// </summary>
|
||||
public bool CheckForUpdates;
|
||||
|
||||
/// <summary>
|
||||
/// Check if legacy Asset Store Tools are in the Project
|
||||
/// </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>
|
||||
/// Enables Junction symlink support
|
||||
/// </summary>
|
||||
public bool EnableSymlinkSupport;
|
||||
|
||||
/// <summary>
|
||||
/// 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.");
|
||||
public static readonly GUIContent LegacyVersionCheckLabel = EditorGUIUtility.TrTextContent("Legacy ASTools Check", "Enable Legacy Asset Store Tools version checking.");
|
||||
public static readonly GUIContent UploadVersionCheckLabel = EditorGUIUtility.TrTextContent("Upload Version Check", "Check if the package has been uploader from a correct Unity version at least once.");
|
||||
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 void OpenSettings()
|
||||
{
|
||||
SettingsService.OpenProjectSettings(SettingsPath);
|
||||
}
|
||||
|
||||
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())
|
||||
{
|
||||
preferences.CheckForUpdates = EditorGUILayout.Toggle(Styles.CheckForUpdatesLabel, preferences.CheckForUpdates);
|
||||
preferences.LegacyVersionCheck = EditorGUILayout.Toggle(Styles.LegacyVersionCheckLabel, preferences.LegacyVersionCheck);
|
||||
preferences.UploadVersionCheck = EditorGUILayout.Toggle(Styles.UploadVersionCheckLabel, preferences.UploadVersionCheck);
|
||||
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));
|
||||
var type = unityEditorAssembly.GetType("UnityEditor.SettingsWindow+GUIScope");
|
||||
return Activator.CreateInstance(type) as IDisposable;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b75179c8d22a35b42a543d6fa7857ce0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 11.4.3
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Utility/ASToolsPreferences.cs
|
||||
uploadId: 681981
|
||||
@@ -0,0 +1,251 @@
|
||||
using AssetStoreTools.Uploader;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
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 VisualElement _loadingContainer;
|
||||
private VisualElement _versionInfoContainer;
|
||||
|
||||
private Image _loadingImage;
|
||||
private double _lastTimeSinceStartup;
|
||||
private double _timeSinceLoadingImageChange;
|
||||
private int _loadingImageIndex;
|
||||
|
||||
private static bool _updateCheckPerformed
|
||||
{
|
||||
get
|
||||
{
|
||||
return SessionState.GetBool("AST_UpdateChecked", false);
|
||||
}
|
||||
set
|
||||
{
|
||||
SessionState.SetBool("AST_UpdateChecked", value);
|
||||
}
|
||||
}
|
||||
|
||||
static ASToolsUpdater()
|
||||
{
|
||||
// Retrieving cached SessionState/PlayerPrefs values is not allowed from an instance field initializer
|
||||
EditorApplication.update += CheckForUpdatesAfterEditorUpdate;
|
||||
}
|
||||
|
||||
private static async void CheckForUpdatesAfterEditorUpdate()
|
||||
{
|
||||
EditorApplication.update -= CheckForUpdatesAfterEditorUpdate;
|
||||
|
||||
if (!ShouldCheckForUpdates())
|
||||
return;
|
||||
|
||||
await CheckForUpdates((success, currentVersion, latestVersion) =>
|
||||
{
|
||||
if (success && currentVersion < latestVersion)
|
||||
{
|
||||
AssetStoreTools.OpenUpdateChecker();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static bool ShouldCheckForUpdates()
|
||||
{
|
||||
if (!ASToolsPreferences.Instance.CheckForUpdates)
|
||||
return false;
|
||||
|
||||
return _updateCheckPerformed == false;
|
||||
}
|
||||
|
||||
private static async Task CheckForUpdates(Action<bool, Version, Version> OnUpdatesChecked)
|
||||
{
|
||||
_updateCheckPerformed = true;
|
||||
var latestVersionResult = await AssetStoreAPI.GetLatestAssetStoreToolsVersion();
|
||||
if (!latestVersionResult.Success)
|
||||
{
|
||||
OnUpdatesChecked?.Invoke(false, null, null);
|
||||
return;
|
||||
}
|
||||
|
||||
Version currentVersion = null;
|
||||
Version latestVersion = null;
|
||||
|
||||
try
|
||||
{
|
||||
var latestVersionStr = latestVersionResult.Response["version"].AsString();
|
||||
var currentVersionStr = PackageUtility.GetAllPackages().FirstOrDefault(x => x.name == "com.unity.asset-store-tools").version;
|
||||
|
||||
currentVersion = new Version(currentVersionStr);
|
||||
latestVersion = new Version(latestVersionStr);
|
||||
}
|
||||
catch
|
||||
{
|
||||
OnUpdatesChecked?.Invoke(false, null, null);
|
||||
}
|
||||
|
||||
OnUpdatesChecked?.Invoke(true, currentVersion, latestVersion);
|
||||
}
|
||||
|
||||
protected override void Init()
|
||||
{
|
||||
base.Init();
|
||||
|
||||
rootVisualElement.styleSheets.Add(StyleSelector.UpdaterWindow.UpdaterWindowStyle);
|
||||
rootVisualElement.styleSheets.Add(StyleSelector.UpdaterWindow.UpdaterWindowTheme);
|
||||
|
||||
SetupLoadingSpinner();
|
||||
_ = CheckForUpdates(OnVersionsRetrieved);
|
||||
}
|
||||
|
||||
private void OnVersionsRetrieved(bool success, Version currentVersion, Version latestVersion)
|
||||
{
|
||||
if (_loadingContainer != null)
|
||||
_loadingContainer.style.display = DisplayStyle.None;
|
||||
|
||||
if (success)
|
||||
{
|
||||
SetupVersionInfo(currentVersion, latestVersion);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetupFailInfo();
|
||||
}
|
||||
}
|
||||
|
||||
private void SetupLoadingSpinner()
|
||||
{
|
||||
_loadingContainer = new VisualElement();
|
||||
_loadingContainer.AddToClassList("loading-container");
|
||||
_loadingImage = new Image();
|
||||
EditorApplication.update += LoadingSpinLoop;
|
||||
|
||||
_loadingContainer.Add(_loadingImage);
|
||||
rootVisualElement.Add(_loadingContainer);
|
||||
}
|
||||
|
||||
private void SetupVersionInfo(Version currentVersion, Version latestVersion)
|
||||
{
|
||||
_versionInfoContainer = new VisualElement();
|
||||
_versionInfoContainer.AddToClassList("version-info-container");
|
||||
|
||||
AddDescriptionLabels(currentVersion, latestVersion);
|
||||
AddUpdateButtons(currentVersion, latestVersion);
|
||||
AddCheckForUpdatesToggle();
|
||||
|
||||
rootVisualElement.Add(_versionInfoContainer);
|
||||
}
|
||||
|
||||
private void AddDescriptionLabels(Version currentVersion, Version latestVersion)
|
||||
{
|
||||
var descriptionText = currentVersion < latestVersion ?
|
||||
"An update to the Asset Store Publishing Tools is available. Updating to the latest version is highly recommended." :
|
||||
"Asset Store Publishing Tools are up to date!";
|
||||
|
||||
var labelContainer = new VisualElement();
|
||||
labelContainer.AddToClassList("version-info-container-labels");
|
||||
var descriptionLabel = new Label(descriptionText);
|
||||
descriptionLabel.AddToClassList("version-info-container-labels-description");
|
||||
|
||||
var currentVersionRow = new VisualElement();
|
||||
currentVersionRow.AddToClassList("version-info-container-labels-row");
|
||||
var latestVersionRow = new VisualElement();
|
||||
latestVersionRow.AddToClassList("version-info-container-labels-row");
|
||||
|
||||
var currentVersionLabel = new Label("Current version:");
|
||||
currentVersionLabel.AddToClassList("version-info-container-labels-row-identifier");
|
||||
var latestVersionLabel = new Label("Latest version:");
|
||||
latestVersionLabel.AddToClassList("version-info-container-labels-row-identifier");
|
||||
|
||||
var currentVersionLabelValue = new Label(currentVersion.ToString());
|
||||
var latestVersionLabelValue = new Label(latestVersion.ToString());
|
||||
|
||||
currentVersionRow.Add(currentVersionLabel);
|
||||
currentVersionRow.Add(currentVersionLabelValue);
|
||||
latestVersionRow.Add(latestVersionLabel);
|
||||
latestVersionRow.Add(latestVersionLabelValue);
|
||||
|
||||
labelContainer.Add(descriptionLabel);
|
||||
labelContainer.Add(currentVersionRow);
|
||||
labelContainer.Add(latestVersionRow);
|
||||
|
||||
_versionInfoContainer.Add(labelContainer);
|
||||
}
|
||||
|
||||
private void AddUpdateButtons(Version currentVersion, Version latestVersion)
|
||||
{
|
||||
if (currentVersion >= latestVersion)
|
||||
return;
|
||||
|
||||
var buttonContainer = new VisualElement();
|
||||
buttonContainer.AddToClassList("version-info-container-buttons");
|
||||
var latestVersionButton = new Button(() => Application.OpenURL(AssetStoreToolsUrl)) { text = "Get the latest version" };
|
||||
var skipVersionButton = new Button(Close) { text = "Skip for now" };
|
||||
|
||||
buttonContainer.Add(latestVersionButton);
|
||||
buttonContainer.Add(skipVersionButton);
|
||||
|
||||
_versionInfoContainer.Add(buttonContainer);
|
||||
}
|
||||
|
||||
private void AddCheckForUpdatesToggle()
|
||||
{
|
||||
var toggleContainer = new VisualElement();
|
||||
toggleContainer.AddToClassList("version-info-container-toggle");
|
||||
var checkForUpdatesToggle = new Toggle() { text = "Check for Updates", value = ASToolsPreferences.Instance.CheckForUpdates };
|
||||
checkForUpdatesToggle.RegisterValueChangedCallback(OnCheckForUpdatesToggleChanged);
|
||||
|
||||
toggleContainer.Add(checkForUpdatesToggle);
|
||||
_versionInfoContainer.Add(toggleContainer);
|
||||
}
|
||||
|
||||
private void OnCheckForUpdatesToggleChanged(ChangeEvent<bool> evt)
|
||||
{
|
||||
ASToolsPreferences.Instance.CheckForUpdates = evt.newValue;
|
||||
ASToolsPreferences.Instance.Save();
|
||||
}
|
||||
|
||||
private void SetupFailInfo()
|
||||
{
|
||||
var failContainer = new VisualElement();
|
||||
failContainer.AddToClassList("fail-container");
|
||||
|
||||
var failImage = new Image();
|
||||
var failDescription = new Label("Asset Store Publishing Tools could not retrieve information about the latest version.");
|
||||
|
||||
failContainer.Add(failImage);
|
||||
failContainer.Add(failDescription);
|
||||
|
||||
rootVisualElement.Add(failContainer);
|
||||
}
|
||||
|
||||
private void LoadingSpinLoop()
|
||||
{
|
||||
var currentTimeSinceStartup = EditorApplication.timeSinceStartup;
|
||||
var deltaTime = EditorApplication.timeSinceStartup - _lastTimeSinceStartup;
|
||||
_lastTimeSinceStartup = currentTimeSinceStartup;
|
||||
|
||||
_timeSinceLoadingImageChange += deltaTime;
|
||||
if (_timeSinceLoadingImageChange < 0.075)
|
||||
return;
|
||||
|
||||
_timeSinceLoadingImageChange = 0;
|
||||
|
||||
_loadingImage.image = EditorGUIUtility.IconContent($"WaitSpin{_loadingImageIndex++:00}").image;
|
||||
if (_loadingImageIndex > 11)
|
||||
_loadingImageIndex = 0;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
EditorApplication.update -= LoadingSpinLoop;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2ac370b9d2279ed4c9faec7134ba2759
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 11.4.3
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Utility/ASToolsUpdater.cs
|
||||
uploadId: 681981
|
||||
@@ -0,0 +1,139 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
|
||||
namespace AssetStoreTools.Utility
|
||||
{
|
||||
internal static class FileUtility
|
||||
{
|
||||
private class RenameInfo
|
||||
{
|
||||
public string OriginalName;
|
||||
public string CurrentName;
|
||||
}
|
||||
|
||||
public static void CopyDirectory(string sourceDir, string destinationDir, bool recursive)
|
||||
{
|
||||
// Get information about the source directory
|
||||
var dir = new DirectoryInfo(sourceDir);
|
||||
|
||||
// Check if the source directory exists
|
||||
if (!dir.Exists)
|
||||
throw new DirectoryNotFoundException($"Source directory not found: {dir.FullName}");
|
||||
|
||||
// Cache directories before we start copying
|
||||
DirectoryInfo[] dirs = dir.GetDirectories();
|
||||
|
||||
// Create the destination directory
|
||||
Directory.CreateDirectory(destinationDir);
|
||||
|
||||
// Get the files in the source directory and copy to the destination directory
|
||||
foreach (FileInfo file in dir.GetFiles())
|
||||
{
|
||||
string targetFilePath = Path.Combine(destinationDir, file.Name);
|
||||
file.CopyTo(targetFilePath);
|
||||
}
|
||||
|
||||
// If recursive and copying subdirectories, recursively call this method
|
||||
if (recursive)
|
||||
{
|
||||
foreach (DirectoryInfo subDir in dirs)
|
||||
{
|
||||
string newDestinationDir = Path.Combine(destinationDir, subDir.Name);
|
||||
CopyDirectory(subDir.FullName, newDestinationDir, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsMissingMetaFiles(params string[] sourcePaths)
|
||||
{
|
||||
foreach (var sourcePath in sourcePaths)
|
||||
{
|
||||
var allDirectories = Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories);
|
||||
foreach (var dir in allDirectories)
|
||||
{
|
||||
var dirInfo = new DirectoryInfo(dir);
|
||||
if (dirInfo.Name.EndsWith("~"))
|
||||
{
|
||||
var nestedContent = dirInfo.GetFileSystemInfos("*", SearchOption.AllDirectories);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void GenerateMetaFiles(params string[] sourcePaths)
|
||||
{
|
||||
var renameInfos = new List<RenameInfo>();
|
||||
|
||||
foreach (var sourcePath in sourcePaths)
|
||||
{
|
||||
var hiddenDirectoriesInPath = Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories).Where(x => x.EndsWith("~"));
|
||||
foreach (var hiddenDir in hiddenDirectoriesInPath)
|
||||
renameInfos.Add(new RenameInfo() { CurrentName = hiddenDir, OriginalName = hiddenDir });
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
EditorApplication.LockReloadAssemblies();
|
||||
|
||||
// Order paths from longest to shortest to avoid having to rename them multiple times
|
||||
renameInfos = renameInfos.OrderByDescending(x => x.OriginalName.Length).ToList();
|
||||
|
||||
try
|
||||
{
|
||||
AssetDatabase.StartAssetEditing();
|
||||
foreach (var renameInfo in renameInfos)
|
||||
{
|
||||
renameInfo.CurrentName = renameInfo.OriginalName.TrimEnd('~');
|
||||
Directory.Move(renameInfo.OriginalName, renameInfo.CurrentName);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
AssetDatabase.StopAssetEditing();
|
||||
AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);
|
||||
}
|
||||
|
||||
// Restore the original path names in reverse order
|
||||
renameInfos = renameInfos.OrderBy(x => x.OriginalName.Length).ToList();
|
||||
|
||||
try
|
||||
{
|
||||
AssetDatabase.StartAssetEditing();
|
||||
foreach (var renameInfo in renameInfos)
|
||||
{
|
||||
Directory.Move(renameInfo.CurrentName, renameInfo.OriginalName);
|
||||
|
||||
if (File.Exists($"{renameInfo.CurrentName}.meta"))
|
||||
File.Delete($"{renameInfo.CurrentName}.meta");
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
AssetDatabase.StopAssetEditing();
|
||||
AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
EditorApplication.UnlockReloadAssemblies();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 80819cf6868374d478a8a38ebaba8e27
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 11.4.3
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Utility/FileUtility.cs
|
||||
uploadId: 681981
|
||||
772
Packages/com.unity.asset-store-tools/Editor/Utility/Json.cs
Normal file
772
Packages/com.unity.asset-store-tools/Editor/Utility/Json.cs
Normal file
@@ -0,0 +1,772 @@
|
||||
/*
|
||||
* 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());
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 1
|
||||
guid: 0a7878c3076bf174ea5c0a1cf7bd3a39
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 11.4.3
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Utility/Json.cs
|
||||
uploadId: 681981
|
||||
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AssetStoreTools.Utility
|
||||
{
|
||||
[InitializeOnLoad]
|
||||
internal class LegacyToolsRemover
|
||||
{
|
||||
private const string MessagePart1 = "A legacy version of Asset Store Tools " +
|
||||
"was detected at the following path:\n";
|
||||
private const string MessagePart2 = "\n\nHaving both the legacy and the latest version installed at the same time is not supported " +
|
||||
"and might prevent the latest version from functioning properly.\n\nWould you like the legacy version to be removed automatically?";
|
||||
|
||||
static LegacyToolsRemover()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Application.isBatchMode)
|
||||
return;
|
||||
|
||||
CheckAndRemoveLegacyTools();
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
private static void CheckAndRemoveLegacyTools()
|
||||
{
|
||||
if (!ASToolsPreferences.Instance.LegacyVersionCheck || !ProjectContainsLegacyTools(out string path))
|
||||
return;
|
||||
|
||||
var relativePath = path.Substring(Application.dataPath.Length - "Assets".Length).Replace("\\", "/");
|
||||
var result = EditorUtility.DisplayDialog("Asset Store Tools", MessagePart1 + relativePath + MessagePart2, "Yes", "No");
|
||||
|
||||
// If "No" - do nothing
|
||||
if (!result)
|
||||
return;
|
||||
|
||||
// If "Yes" - remove legacy tools
|
||||
File.Delete(path);
|
||||
File.Delete(path + ".meta");
|
||||
RemoveEmptyFolders(Path.GetDirectoryName(path)?.Replace("\\", "/"));
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
// We could also optionally prevent future execution here
|
||||
// but the ProjectContainsLegacyTools() function runs in less
|
||||
// than a milisecond on an empty project
|
||||
}
|
||||
|
||||
private static bool ProjectContainsLegacyTools(out string path)
|
||||
{
|
||||
path = null;
|
||||
|
||||
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
if (assembly.ManifestModule.Name == "AssetStoreTools.dll")
|
||||
{
|
||||
path = assembly.Location;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(path))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void RemoveEmptyFolders(string directory)
|
||||
{
|
||||
if (directory.EndsWith(Application.dataPath))
|
||||
return;
|
||||
|
||||
if (Directory.GetFiles(directory).Length == 0 && Directory.GetDirectories(directory).Length == 0)
|
||||
{
|
||||
var parentPath = Path.GetDirectoryName(directory).Replace("\\", "/");
|
||||
|
||||
Directory.Delete(directory);
|
||||
File.Delete(directory + ".meta");
|
||||
|
||||
RemoveEmptyFolders(parentPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 46ead42026b1f0b4e94153e1a7e10d12
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 11.4.3
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Utility/LegacyToolsRemover.cs
|
||||
uploadId: 681981
|
||||
@@ -0,0 +1,58 @@
|
||||
#if UNITY_2019 || UNITY_2020
|
||||
using System;
|
||||
using System.Reflection;
|
||||
#endif
|
||||
using UnityEngine;
|
||||
using UnityEditor.PackageManager;
|
||||
using System.Linq;
|
||||
|
||||
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)
|
||||
{
|
||||
var path = packageInfo.resolvedPath.Replace("\\", "/");
|
||||
|
||||
var rootProjectPath = Application.dataPath.Substring(0, Application.dataPath.Length - "Assets".Length);
|
||||
if (path.StartsWith(rootProjectPath))
|
||||
path = path.Substring(rootProjectPath.Length);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
public static PackageInfo[] GetAllPackages()
|
||||
{
|
||||
#if UNITY_2019 || UNITY_2020
|
||||
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
|
||||
var packages = PackageInfo.GetAllRegisteredPackages();
|
||||
#endif
|
||||
return packages;
|
||||
}
|
||||
|
||||
public static PackageInfo[] GetAllLocalPackages()
|
||||
{
|
||||
var packages = GetAllPackages();
|
||||
var localPackages = packages.Where(x => x.source == PackageSource.Embedded || x.source == PackageSource.Local)
|
||||
.Where(x => x.isDirectDependency).ToArray();
|
||||
return localPackages;
|
||||
}
|
||||
|
||||
public static PackageInfo[] GetAllRegistryPackages()
|
||||
{
|
||||
var packages = GetAllPackages();
|
||||
var registryPackages = packages.Where(x => x.source == PackageSource.Registry || x.source == PackageSource.BuiltIn)
|
||||
.OrderBy(x => string.Compare(x.type, "module", System.StringComparison.OrdinalIgnoreCase) == 0)
|
||||
.ThenBy(x => x.name).ToArray();
|
||||
|
||||
return registryPackages;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 605ea62f8b11d674a95a53f895df4c67
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 11.4.3
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Utility/PackageUtility.cs
|
||||
uploadId: 681981
|
||||
@@ -0,0 +1,58 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace AssetStoreTools.Utility
|
||||
{
|
||||
internal static class StyleSelector
|
||||
{
|
||||
private static StyleSheet GetStylesheet(string stylesheetPath)
|
||||
{
|
||||
return AssetDatabase.LoadAssetAtPath<StyleSheet>(stylesheetPath);
|
||||
}
|
||||
|
||||
public static class UploaderWindow
|
||||
{
|
||||
private const string StylesPath = "Packages/com.unity.asset-store-tools/Editor/Uploader/Styles";
|
||||
|
||||
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 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 class ValidatorWindow
|
||||
{
|
||||
private const string StylesPath = "Packages/com.unity.asset-store-tools/Editor/Validator/Styles";
|
||||
|
||||
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 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8b066ce502a289a4ca311a86fbf83f45
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 11.4.3
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Utility/StyleSelector.cs
|
||||
uploadId: 681981
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f730eb0b8c48c434d93cc60a0b8aff40
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5367435d9abe935438f4d7b588a55488
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
.loading-container > VisualElement > Image {
|
||||
--unity-image: resource("d_WaitSpin00");
|
||||
}
|
||||
|
||||
.fail-container > Image {
|
||||
--unity-image: resource("console.erroricon@2x");
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 225786b34a57ee440b0c1b213902214a
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
|
||||
disableValidation: 0
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 11.4.3
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Utility/Styles/Updater/Updater_Dark.uss
|
||||
uploadId: 681981
|
||||
@@ -0,0 +1,7 @@
|
||||
.loading-container > VisualElement > Image {
|
||||
--unity-image: resource("WaitSpin00");
|
||||
}
|
||||
|
||||
.fail-container > Image {
|
||||
--unity-image: resource("console.erroricon@2x");
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8cdc065c428afe14c96781ac6fd73d73
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
|
||||
disableValidation: 0
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 11.4.3
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Utility/Styles/Updater/Updater_Light.uss
|
||||
uploadId: 681981
|
||||
@@ -0,0 +1,76 @@
|
||||
.loading-container {
|
||||
flex-grow: 1;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.loading-container > Image {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.version-info-container {
|
||||
flex-grow: 1;
|
||||
margin: 0 5px 5px 5px;
|
||||
}
|
||||
|
||||
.version-info-container-labels {
|
||||
flex-grow: 1;
|
||||
margin-bottom: 10px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.version-info-container-labels-description {
|
||||
flex-grow: 0.5;
|
||||
margin-bottom: 5px;
|
||||
white-space: normal;
|
||||
-unity-text-align: middle-left;
|
||||
}
|
||||
|
||||
.version-info-container-labels-row {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.version-info-container-labels-row-identifier {
|
||||
-unity-font-style: bold;
|
||||
}
|
||||
|
||||
.version-info-container-buttons {
|
||||
flex-direction: row;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.version-info-container-buttons > Button {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
flex-basis: 100%;
|
||||
height: 25px;
|
||||
}
|
||||
|
||||
.version-info-container-toggle {
|
||||
align-self: flex-end;
|
||||
}
|
||||
|
||||
.version-info-container-toggle > Toggle > VisualElement > Label {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.fail-container {
|
||||
flex-grow: 1;
|
||||
flex-direction: row;
|
||||
margin: 0 5px 5px 5px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.fail-container > Image {
|
||||
flex-shrink: 0;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.fail-container > Label {
|
||||
flex-shrink: 1;
|
||||
white-space: normal;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: daf82dcb916f6ae498d03a6a127122c6
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
|
||||
disableValidation: 0
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 11.4.3
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Utility/Styles/Updater/Updater_Main.uss
|
||||
uploadId: 681981
|
||||
@@ -0,0 +1,67 @@
|
||||
using System.IO;
|
||||
|
||||
namespace AssetStoreTools.Utility
|
||||
{
|
||||
internal static class SymlinkUtil
|
||||
{
|
||||
private const FileAttributes FolderSymlinkAttributes = FileAttributes.Directory | FileAttributes.ReparsePoint;
|
||||
|
||||
public static bool FindSymlinkFolderRelative(string folderPathAbsolute, out string relativePath)
|
||||
{
|
||||
// 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))
|
||||
continue;
|
||||
|
||||
// Compare metadata of outside directory with a directories within the project
|
||||
if (!CompareDirectories(absoluteInfo, relativeInfo))
|
||||
continue;
|
||||
|
||||
// Found symlink within the project, assign it
|
||||
relativePath = fullPath;
|
||||
return true;
|
||||
}
|
||||
|
||||
relativePath = string.Empty;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool CompareDirectories(DirectoryInfo directory, DirectoryInfo directory2)
|
||||
{
|
||||
var contents = directory.EnumerateFileSystemInfos("*", SearchOption.AllDirectories).GetEnumerator();
|
||||
var contents2 = directory2.EnumerateFileSystemInfos("*", SearchOption.AllDirectories).GetEnumerator();
|
||||
|
||||
while (true)
|
||||
{
|
||||
var firstNext = contents.MoveNext();
|
||||
var secondNext = contents2.MoveNext();
|
||||
|
||||
if (firstNext != secondNext)
|
||||
return false;
|
||||
|
||||
if (!firstNext && !secondNext)
|
||||
break;
|
||||
|
||||
var equals = contents.Current?.Name == contents2.Current?.Name
|
||||
&& contents.Current?.LastWriteTime == contents2.Current?.LastWriteTime;
|
||||
|
||||
if (!equals)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 92092535fd064bb1843017f98db213e1
|
||||
timeCreated: 1659013521
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 11.4.3
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Utility/SymlinkUtil.cs
|
||||
uploadId: 681981
|
||||
Reference in New Issue
Block a user