using System; using System.Linq; using UnityEditor; using UnityEngine; using Codice.Client.Common; using Codice.Client.Common.Threading; using Codice.CM.Common; using Codice.LogWrapper; using PlasticGui.WorkspaceWindow.Home; using PlasticGui; namespace Unity.PlasticSCM.Editor.AssetUtils.Processor { internal class UnityCloudProjectLinkMonitor : AssetModificationProcessor { internal class CloudSettings { internal string OrganizationId; internal string OrganizationName; internal string ProjectId; internal string ProjectName; } /// <summary> /// Factory class to retrieve the cloud settings for the current project. /// </summary> internal static Func<CloudSettings> CloudSettingsFactory = () => new CloudSettings() { OrganizationId = CloudProjectSettings.organizationId, OrganizationName = CloudProjectSettings.organizationName, ProjectId = CloudProjectSettings.projectId, ProjectName = CloudProjectSettings.projectName }; /// <summary> /// Checks if the workspace project is aligned with the linked project in the cloud settings (if any). /// If not, logs a warning message for users to inform about the issue and give indications on how to re-link. /// </summary> internal static void CheckCloudProjectAlignmentAsync(WorkspaceInfo wkInfo) { mLog.Debug("Checking for cloud project alignment..."); mCachedWkInfo = wkInfo; CloudSettings cloudSettings = CloudSettingsFactory(); if (string.IsNullOrEmpty(cloudSettings.OrganizationId) || string.IsNullOrEmpty(cloudSettings.ProjectId)) { mCachedCloudSettings = cloudSettings; mLog.Debug("The project is not connected to Unity Cloud"); return; } if (cloudSettings.OrganizationId.Equals(mCachedCloudSettings.OrganizationId) && cloudSettings.ProjectId.Equals(mCachedCloudSettings.ProjectId)) { mLog.Debug("The linked project didn't change"); return; } mCachedCloudSettings = cloudSettings; CheckCloudProjectAlignmentAsync(); } static void CheckCloudProjectAlignmentAsync() { PlasticThreadPool.Run(delegate { try { RepositorySpec repSpec = PlasticGui.Plastic.API.GetRepositorySpec(mCachedWkInfo); if (repSpec == null || !OrganizationsInformation.IsUnityOrganization(repSpec.Server)) { mLog.Debug("Skipping check for not covered organization"); return; } RepositoryInfo repositoryProject = ProjectInfo.ForRepSpec(repSpec); if (repositoryProject == null || !repositoryProject.GUID.ToString().Equals(mCachedCloudSettings.ProjectId)) { string repositoryOrganizationName = CloudServer.GetOrganizationName(ResolveServer.ToDisplayString(repSpec.Server)); string repositoryProjectName = CloudProject.GetProjectName(repSpec.Name); LogMismatchingProject( mCachedCloudSettings.OrganizationName, mCachedCloudSettings.ProjectName, repositoryOrganizationName, repositoryProjectName); } else { mLog.Debug("The linked cloud project is properly aligned"); } } catch (Exception e) { ExceptionsHandler.LogException(typeof(UnityCloudProjectLinkMonitor).Name, e); } }); } static void LogMismatchingProject(string cloudOrganization, string cloudProject, string repoOrganization, string repoProject) { string localOrganizationAndProject = string.Format("{0}/{1}", repoOrganization, repoProject); string cloudOrganizationAndProject = string.Format("{0}/{1}", cloudOrganization, cloudProject); string mismatchingProjectMessage = string.Format( PlasticLocalization.Name.MismatchingRepositoryProjectMessage.GetString(), cloudOrganizationAndProject, localOrganizationAndProject, localOrganizationAndProject, repoOrganization, localOrganizationAndProject, cloudOrganizationAndProject ); Debug.LogWarning(mismatchingProjectMessage); mLog.Warn(mismatchingProjectMessage); } static string[] OnWillSaveAssets(string[] paths) { if (mCachedWkInfo != null && paths.Any(path => path.Equals(ProjectSettingsAsset))) { CheckCloudProjectAlignmentAsync(mCachedWkInfo); } return paths; } static WorkspaceInfo mCachedWkInfo; static CloudSettings mCachedCloudSettings = new CloudSettings(); static readonly string ProjectSettingsAsset = "ProjectSettings/ProjectSettings.asset"; static readonly ILog mLog = PlasticApp.GetLogger("UnityCloudProjectLinkMonitor"); } }