using UnityEditor; using UnityEngine; using System; using System.Collections.Generic; using System.Linq; using System.IO; using System.Security.Cryptography.X509Certificates; using Perforce.P4; using log4net; namespace P4Connect { // Use the Config Class to hold current configuration and persist it through runs. [Serializable] public class Config : ScriptableObject { private static readonly ILog log = LogManager.GetLogger(typeof(Config)); public const string P4ConfigDefault = ".p4config"; public const string P4BridgeDllName = "p4bridge.dll"; public const string P4BridgeDylibName = "libp4bridge.dylib"; // Config Class mostly static but is also a singleton private static Config _pInstance; public static Config Instance { get { if (_pInstance == null) { _pInstance = ScriptableObject.CreateInstance<P4Connect.Config>() ; //as Config; } if (_pInstance == null) { Debug.Log("P4 _pInstance is null"); } return _pInstance; } } // Helper property to indicate that P4 can be used public static bool ValidConfiguration { get { return PerforceEnabled && Valid; } } // Event triggered when the configuration changes public delegate void OnPrefsChanged(); public static event OnPrefsChanged PrefsChanged; // Keep a Queue of Pending OnPostProcessAllAssets requests // which can persist thru a run / pause or asset import public static Queue<PostProcessorRequest> PostProcessorRequestQueue; private static List<PostProcessorRequest> _postProcessorRequestList = null; /// <summary> /// This event is called when the Config Class is enabled. /// On initial startup and when a Unity Restart occurs (importing assets, after running the game) /// </summary> public void OnEnable() { _inOnEnable = true; hideFlags = HideFlags.HideAndDontSave; _pInstance = this; // don't initialize if we are currently not in Editor Mode if (IsGameStarting() || IsGameRunning() || IsGameStopping()) { return; } #if DEBUG // Debug.Log("Config:OnEnable()"); #endif // Restore the Post Processor Queue from the List if (_postProcessorRequestList != null && _postProcessorRequestList.Count > 0) PostProcessorRequestQueue = new Queue<PostProcessorRequest>(_postProcessorRequestList); // Hook up play mode callback //EditorApplication.playmodeStateChanged -= PlayModeCallback; //EditorApplication.playmodeStateChanged += PlayModeCallback; ConfigurePerforce(); _inOnEnable = false; } private static bool _inOnEnable = false; public static bool InOnEnable() { return _inOnEnable; } public static bool IsGameStarting() { return ! EditorApplication.isPlaying && EditorApplication.isPlayingOrWillChangePlaymode; } public static bool IsGameStopping() { return EditorApplication.isPlaying && !EditorApplication.isPlayingOrWillChangePlaymode; } public static bool IsGameRunning() { return EditorApplication.isPlaying; } public static bool IsEditing() { return !(IsGameStarting() || IsGameRunning() || IsGameStopping()); } static public void PlayModeCallback() { string result = ""; if (EditorApplication.isPlaying) { if (EditorApplication.isPlayingOrWillChangePlaymode) { result += "PLAYING "; } else { result += "STOPPING "; } } else { if (EditorApplication.isPlayingOrWillChangePlaymode) { result += "STARTING "; } else { result += "STOPPED "; } } if (UnityEngine.Application.isEditor) { result += "A_EDITING "; } if (UnityEngine.Application.isPlaying) { result += "A_PLAYING "; } if (EditorApplication.isCompiling) { result += "COMPILING "; } if (EditorApplication.isUpdating) { result += "UPDATING "; } if (EditorApplication.isPaused) { result += "PAUSED "; } Debug.Log(result); } public static void OnDisable() { Debug.Log("Config:OnDisable()"); // Save the Queue to the list _postProcessorRequestList = PostProcessorRequestQueue.ToList(); } public static void ConfigurePerforce() { // If No Config values are set, so load them in from the Config Asset or EditorPrefs if (string.IsNullOrEmpty(Config.ServerUri)) { ResetValues(); bool foundConfigAsset = ReadConfigAsset(); if (foundConfigAsset) { Debug.Log("Loading Configuration Asset"); Config.SaveMode = SaveSettingsMode.ConfigAsset; } else { Debug.Log("Loading Configuration EditorPrefs"); Config.SaveMode = SaveSettingsMode.EditorPrefs; ReadPrefs(); } LastSavedConnection = new ConnectionConfig(true); DefaultConnection = new ConnectionConfig(true); } if (PerforceEnabled) { if (EnableLog) { Logger.Initialize(); // initialize logging if not done before } if (DefaultConnection.Tested && DefaultConnection.Valid) { Valid = true; LastGoodConnection = new ConnectionConfig(DefaultConnection); //Debug.Log("Reconnecting ..."); } else { // Create a Default Connection from the Config settings. Config.DefaultConnection.FromConfig(); Valid = CheckSettings(DefaultConnection); } if (Valid) { Icons.UpdateDisplay(); } } } /// <summary> /// Reads connection settings from Prefs at least once /// </summary> public static void Initialize() { } /// <summary> /// Checks the that settings are valid /// </summary> public static bool CheckSettings(ConnectionConfig cfg) { //Debug.Log("CheckSettings: " + cfg.ToString()); if (PerforceEnabled) { bool goodConnection = TestConnectionConfig(cfg); // Test Configuration if (!goodConnection) { Debug.LogWarning("P4Connect - Perforce integration is enabled but inactive: " + cfg.Summary() + "\n Go to Edit->Perforce Settings to update your settings"); } else { if (!InOnEnable()) { ConnectionWizard.CloseWindows(); PasswordPrompt.CloseWindows(); } // Debug.Log("P4Connect - Perforce Integration is Active"); return true; } } return false; } /// <summary> /// Updates the current configuration state after checking all the settings /// </summary> public static bool TestConnectionConfig(ConnectionConfig cfg) { bool returnValue = false; bool makingProgress = false; const string title = "P4Connect - Hold on"; if (Config.LastGoodConnection.Valid && Config.LastGoodConnection.Matches(cfg)) { //Debug.Log("Using LastGoodConnection"); cfg = LastGoodConnection; // Use LastGoodConnection return true; } try { cfg.Tested = true; if (!cfg.MetafilesValid) { makingProgress = true; EditorUtility.DisplayProgressBar(title, "Checking Meta Files", 0.2f); cfg.MetafilesValid = P4Connect.VerifySettings.CheckMetaFiles(); } if (cfg.MetafilesValid && !cfg.ServerValid) { makingProgress = true; EditorUtility.DisplayProgressBar(title, "Checking Server", 0.4f); cfg.ServerValid = P4Connect.VerifySettings.CheckServerUri(cfg); } if (cfg.ServerValid && !cfg.PasswordValid) { makingProgress = true; EditorUtility.DisplayProgressBar(title, "Checking Login", 0.6f); cfg.PasswordValid = P4Connect.VerifySettings.CheckUsernamePassword(cfg); } if (cfg.PasswordValid && !cfg.WorkspaceValid) { makingProgress = true; EditorUtility.DisplayProgressBar(title, "Checking Workspace", 0.8f); cfg.WorkspaceValid = P4Connect.VerifySettings.CheckWorkspace(cfg); } if (cfg.WorkspaceValid && !cfg.ProjectRootValid) { makingProgress = true; EditorUtility.DisplayProgressBar(title, "Checking Project Root", 0.9f); cfg.ProjectRootValid = P4Connect.VerifySettings.CheckProjectRoot(cfg); } returnValue = cfg.ProjectRootValid; } catch (Exception ex) { log.Debug("TestConnectionConfig exception: " + ex.ToString()); log.Debug("TestConnectionConfig exception", ex); } if (makingProgress) { try { EditorUtility.ClearProgressBar(); } catch (Exception ex) { } } if (returnValue == true) { // Save as LastGoodConnection Config.LastGoodConnection = cfg; } return returnValue; } public static void SetProjectRootDirectory() { if (Config.ValidConfiguration) { //log.Debug("conn status: " + DefaultConnection.Summary() ); Engine.PerformConnectionOperation(con => { // project root in perforce syntax var spec = FileSpec.LocalSpec(System.IO.Path.Combine(Main.RootPath, "...")); var mappings = con.P4Client.GetClientFileMappings(spec); if (mappings != null && mappings.Count > 0) { // string ProjectRoot; ClientProjectRoot = mappings[0].ClientPath.Path; DepotProjectRoot = mappings[0].DepotPath.Path; //log.Debug("ClientProjectRoot: " + ClientProjectRoot); //log.Debug("DepotProjectRoot: " + DepotProjectRoot); } else { Debug.LogError("Unable to determine Project Root! "); } }); } } #region Instance Variables [SerializeField] private string _serverUri; [SerializeField] private string _username; [SerializeField] private string _password; [SerializeField] private string _workspace; [SerializeField] private bool _unityVsSupport; [SerializeField] private bool _perforceEnabled; [SerializeField] private bool _includeSolutionFiles; [SerializeField] private bool _includeProjectFiles; [SerializeField] private bool _showPaths; [SerializeField] private bool _askBeforeCheckout; [SerializeField] private bool _displayStatusIcons; [SerializeField] private string _hostname; [SerializeField] private string _charset; [SerializeField] private string _diffToolPathname; [SerializeField] private bool _displayP4Timings; [SerializeField] private bool _echoP4Commands; [SerializeField] private bool _checkStatusForMenus; [SerializeField] private bool _warnOnSpecialCharacters; [SerializeField] private int _checkStatusForMenusMaxItems; [SerializeField] private int _operationBatchCount; [SerializeField] private int _connectionTimeOut; [SerializeField] private string _ignoreName; [SerializeField] private string _ignoreLines; [SerializeField] private bool _useTypemap; [SerializeField] private bool _enableLog; [SerializeField] private Logger.LogLevel _consoleLogLevel; [SerializeField] private string _logPath; [SerializeField] private string _clientProjectRootMatch; [SerializeField] private IList<FileSpec> _projectFileSpec; [SerializeField] private string _depotProjectRoot; [SerializeField] private string _localProjectRoot; [SerializeField] private bool _valid; [SerializeField] private string _clientProjectRoot; [SerializeField] private SaveSettingsMode _currentSaveMode = SaveSettingsMode.EditorPrefs; [SerializeField] private ConnectionConfig _defaultConnection; [SerializeField] private ConnectionConfig _lastGoodConnection; [SerializeField] private ConnectionConfig _lastSavedConnection; #endregion #region Properties public static string ServerUri { get { return Instance._serverUri; } set { Instance._serverUri = value; } } public static string Username { get { return Instance._username; } set { Instance._username = value; } } public static string Password { get { return Instance._password; } set { Instance._password = value; } } public static string Workspace { get { return Instance._workspace; } set { Instance._workspace = value; } } public static bool UnityVsSupport { get { return Instance._unityVsSupport; } set { Instance._unityVsSupport = value; } } public static bool PerforceEnabled { get { return Instance._perforceEnabled; } set { Instance._perforceEnabled = value; } } public static bool IncludeSolutionFiles { get { return Instance._includeSolutionFiles; } set { Instance._includeSolutionFiles = value; } } public static bool IncludeProjectFiles { get { return Instance._includeProjectFiles; } set { Instance._includeProjectFiles = value; } } public static bool ShowPaths { get { return Instance._showPaths; } set { Instance._showPaths = value; } } public static bool AskBeforeCheckout { get { return Instance._askBeforeCheckout; } set { Instance._askBeforeCheckout = value; } } public static bool DisplayStatusIcons { get { return Instance._displayStatusIcons; } set { Instance._displayStatusIcons = value; } } public static string Hostname { get { return Instance._hostname; } set { Instance._hostname = value; } } public static string Charset { get { return Instance._charset; } set { Instance._charset = value; } } public static string DiffToolPathname { get { return Instance._diffToolPathname; } set { Instance._diffToolPathname = value; } } public static bool DisplayP4Timings { get { return Instance._displayP4Timings; } set { Instance._displayP4Timings = value; } } public static bool EchoP4Commands { get { return Instance._echoP4Commands; } set { Instance._echoP4Commands = value; } } public static bool CheckStatusForMenus { get { return Instance._checkStatusForMenus; } set { Instance._checkStatusForMenus = value; } } public static bool WarnOnSpecialCharacters { get { return Instance._warnOnSpecialCharacters; } set { Instance._warnOnSpecialCharacters = value; } } public static int CheckStatusForMenusMaxItems { get { return Instance._checkStatusForMenusMaxItems; } set { Instance._checkStatusForMenusMaxItems = value; } } public static int OperationBatchCount { get { return Instance._operationBatchCount; } set { Instance._operationBatchCount = value; } } public static int ConnectionTimeOut { get { return Instance._connectionTimeOut; } set { Instance._connectionTimeOut = value; } } public static string IgnoreName { get { return Instance._ignoreName; } set { Instance._ignoreName = value; } } public static string IgnoreLines { get { return Instance._ignoreLines; } set { Instance._ignoreLines = value; } } public static bool UseTypemap { get { return Instance._useTypemap; } set { Instance._useTypemap = value; } } public static bool EnableLog { get { return Instance._enableLog; } set { Instance._enableLog = value; } } public static Logger.LogLevel ConsoleLogLevel { get { return Instance._consoleLogLevel; } set { Instance._consoleLogLevel = value; } } public static string LogPath { get { return Instance._logPath; } set { Instance._logPath = value; } } public static string ClientProjectRoot // Client path associated with project root (has /...) { get { return (Instance._clientProjectRoot); } set { Instance._clientProjectRoot = value; ClientProjectRootMatch = ClientProjectRoot.Substring(0, Math.Max(0, ClientProjectRoot.Length - 4)); ProjectFileSpec = FileSpec.ClientSpecList(new string[1] { Instance._clientProjectRoot }); } } // Client path without the /... stuff. public static string ClientProjectRootMatch { set { Instance._clientProjectRootMatch = value; } get { return Instance._clientProjectRootMatch; } } // File Spec which describes the scope of the project (with /...) public static IList<FileSpec> ProjectFileSpec { set { Instance._projectFileSpec = value; } get { return Instance._projectFileSpec; } } // Depot path associated with project root (has /...) public static string DepotProjectRoot { get { return Instance._depotProjectRoot; } set { Instance._depotProjectRoot = value; } } // Local path associated with project root public static string LocalProjectRoot { get { return Instance._localProjectRoot; } set { Instance._localProjectRoot = value; } } // Connection Settings Have been Tested public static bool Valid { set { Instance._valid = value; } get { return Instance._valid; } } public static SaveSettingsMode SaveMode { get { return Instance._currentSaveMode; } set { Instance._currentSaveMode = value; } } public static ConnectionConfig DefaultConnection { get { if (Instance._defaultConnection == null) { Instance._defaultConnection = new ConnectionConfig(); } return (Instance._defaultConnection); } set { Instance._defaultConnection = value; } } public static ConnectionConfig LastGoodConnection { get { if (Instance._lastGoodConnection == null) { Instance._lastGoodConnection = new ConnectionConfig(); } return (Instance._lastGoodConnection); } set { Instance._lastGoodConnection = value; } } public static ConnectionConfig LastSavedConnection { get { if (Instance._lastSavedConnection == null) { Instance._lastSavedConnection = new ConnectionConfig(); } return (Instance._lastSavedConnection); } set { Instance._lastSavedConnection = value; } } #endregion public enum SaveSettingsMode { EditorPrefs, ConfigAsset, } public static void ResetValues() { // Set some default values ServerUri = "localhost:1666"; Username = Environment.UserName.Replace(' ', '_'); Password = ""; Workspace = (Username + "_" + Main.ProjectName + "_" + Environment.MachineName).Replace(' ', '_'); UnityVsSupport = false; PerforceEnabled = false; IncludeProjectFiles = false; IncludeSolutionFiles = false; ShowPaths = false; AskBeforeCheckout = false; DisplayStatusIcons = true; Hostname = ""; Charset = ""; DiffToolPathname = ""; DisplayP4Timings = false; EchoP4Commands = false; CheckStatusForMenus = true; CheckStatusForMenusMaxItems = 10; ConnectionTimeOut = 30; WarnOnSpecialCharacters = true; IgnoreName = ""; IgnoreLines = ""; UseTypemap = false; EnableLog = false; LogPath = DefaultLogFile(); ConsoleLogLevel = Logger.LogLevel.Info; } // Get an OS dependent path to the default p4connect log file. public static string DefaultLogFile() { string rv = ""; if (Application.platform == RuntimePlatform.OSXEditor) { rv = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "Library/Logs/Unity/p4connect.log"); } else // (Application.platform == RuntimePlatform.WindowsEditor) { rv = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Unity\\Editor\\p4connect.log"); } rv = rv.Replace('/', System.IO.Path.DirectorySeparatorChar); //Debug.Log("DefaultLogFile: " + rv); return rv; } #region P4CONFIG public static string FindP4ConfigFile(string config) { if (!String.IsNullOrEmpty(config)) { string path = Application.dataPath; while (path != null) { var directoryName = Path.GetDirectoryName(path); if (!String.IsNullOrEmpty(directoryName)) { string[] files = System.IO.Directory.GetFiles(directoryName, config); if (files.Any()) { return files[0]; } } path = directoryName; } } return null; } public static void LoadP4ConfigFile(string path) { string line; char[] equalsChars = { '=' }; System.IO.StreamReader file = new System.IO.StreamReader(path); while ((line = file.ReadLine()) != null) { string[] segments = line.Split(equalsChars); if (segments.Length >= 2) { string key = segments[0]; string val = segments[1]; switch (segments[0]) { case "P4PORT": { ServerUri = val; } break; case "P4USER": { Username = val; } break; case "P4CLIENT": { Workspace = val; } break; case "P4PASSWD": { Password = val; } break; case "P4HOST": { Hostname = val; } break; case "P4CHARSET": { Charset = val; } break; } } } file.Close(); } #endregion #region Environment // Check for the "well known" Perforce environment variables. public static bool ReadEnvironment() { bool found = false; string value = Environment.GetEnvironmentVariable("P4PORT"); if (value != null) { Config.ServerUri = value; found = true; } value = Environment.GetEnvironmentVariable("P4USER"); if (value != null) { Config.Username = value; found = true; } value = Environment.GetEnvironmentVariable("P4PASSWD"); if (value != null) { Config.Password = value; found = true; } value = Environment.GetEnvironmentVariable("P4CLIENT"); if (value != null) { Config.Workspace = value; found = true; } value = Environment.GetEnvironmentVariable("P4HOST"); if (value != null) { Config.Hostname = value; found = true; } value = Environment.GetEnvironmentVariable("P4CHARSET"); if (value != null) { Config.Charset = value; found = true; } value = Environment.GetEnvironmentVariable("P4IGNORE"); if (value != null) { Config.IgnoreName = value; found = true; } //Config.Refresh(); return found; } #endregion #region ConfigAsset static string configAssetFile = "Config.asset"; static string configAssetPath = Path.Combine(Utils.GetEditorAssetRelativeDirectory(), configAssetFile); public static void WriteConfigAsset() { ConfigAsset asset = ScriptableObject.CreateInstance<ConfigAsset>(); asset.CopyConfigToAsset(); AssetDatabase.CreateAsset(asset, configAssetPath); AssetDatabase.SaveAssets(); } public static bool ReadConfigAsset() { ConfigAsset asset = AssetDatabase.LoadAssetAtPath(configAssetPath, (typeof(ConfigAsset))) as ConfigAsset; if (asset != null) { asset.CopyAssetToConfig(); return true; } else { return false; } } public static void DeleteConfigAsset() { if (!AssetDatabase.DeleteAsset(configAssetPath)) { System.IO.File.Delete(System.IO.Path.Combine(Main.RootPath, configAssetPath)); } } /* If the inspector is used to view a Config Asset, these properties control the presentation */ [CustomEditor(typeof(ConfigAsset))] public class ConfigAssetPropertiesEditor : Editor { public override void OnInspectorGUI() { GUI.enabled = false; DrawDefaultInspector(); GUI.enabled = true; } } #endregion #region Registry Names // These are the names under which the connection settings are stored in the registry public const string ServerUriPrefName = "ServerURI"; public const string UserNamePrefName = "UserName"; public const string PasswordPrefName = "Password"; public const string WorkspacePrefName = "Workspace"; public const string PerforceEnabledPrefName = "Enabled"; public const string UnityVsSupportPrefName = "UnityVSSupport"; public const string IncludeProjectFilesPrefName = "IncludeProjectFiles"; public const string IncludeSolutionFilesPrefName = "IncludeSolutionFiles"; public const string ShowPathsPrefName = "ShowPaths"; public const string AskBeforeCheckoutPrefName = "AskBeforeCheckout"; public const string DisplayStatusIconsPrefName = "DisplayStatusIcons"; public const string HostnamePrefName = "Hostname"; public const string DiffToolPathnamePrefName = "DiffToolPathname"; public const string DisplayP4TimingsPrefName = "DisplayTimings"; public const string DisplayP4CommandsPrefName = "DisplayCommands"; public const string CheckStatusForMenusPrefName = "CheckStatusForMenus"; public const string CheckStatusForMenusMaxItemsPrefName = "CheckStatusForMenusMaxItems"; public const string OperationBatchCountPrefName = "OperationBatchCount"; public const string ConnectionTimeOutPrefName = "ConnectionTimeOut"; public const string WarnOnSpecialCharactersPrefName = "WarnOnSpecialCharacters"; public const string UseIgnorePrefName = "UseIgnore"; public const string IgnoreNamePrefName = "IgnoreName"; public const string EnableLogPrefName = "EnableLog"; public const string ConsoleLogLevelPrefName = "ConsoleLogLevel"; public const string LogPathPrefName = "LogPath"; public const string IgnoreLinesPrefName = "IgnoreLines"; public const string UseTypemapPrefName = "UseTypemap"; #endregion #region EditorPreferences // Utility method to read connection prefs from the registry public static void ReadPrefs() { // Check if the keys exist, and if so, read the values out // Otherwise, leave the existing values if (HasStringPrefNotEmpty(ServerUriPrefName)) ServerUri = GetPrefString(ServerUriPrefName); if (HasStringPrefNotEmpty(UserNamePrefName)) Username = GetPrefString(UserNamePrefName); if (HasStringPrefNotEmpty(PasswordPrefName)) { Password = Secure.DecryptString(GetPrefString(PasswordPrefName)); } if (HasStringPrefNotEmpty(WorkspacePrefName)) Workspace = GetPrefString(WorkspacePrefName); if (HasPref(PerforceEnabledPrefName)) PerforceEnabled = GetPrefBool(PerforceEnabledPrefName); if (HasPref(UnityVsSupportPrefName)) UnityVsSupport = GetPrefBool(UnityVsSupportPrefName); if (HasPref(IncludeProjectFilesPrefName)) IncludeProjectFiles = GetPrefBool(IncludeProjectFilesPrefName); if (HasPref(IncludeSolutionFilesPrefName)) IncludeSolutionFiles = GetPrefBool(IncludeSolutionFilesPrefName); if (HasPref(ShowPathsPrefName)) ShowPaths = GetPrefBool(ShowPathsPrefName); if (HasPref(AskBeforeCheckoutPrefName)) AskBeforeCheckout = GetPrefBool(AskBeforeCheckoutPrefName); if (HasPref(DisplayStatusIconsPrefName)) DisplayStatusIcons = GetPrefBool(DisplayStatusIconsPrefName); if (HasStringPrefNotEmpty(HostnamePrefName)) Hostname = GetPrefString(HostnamePrefName); if (HasStringPrefNotEmpty(DiffToolPathnamePrefName)) DiffToolPathname = GetPrefString(DiffToolPathnamePrefName); if (HasPref(DisplayP4TimingsPrefName)) DisplayP4Timings = GetPrefBool(DisplayP4TimingsPrefName); if (HasPref(DisplayP4CommandsPrefName)) EchoP4Commands = GetPrefBool(DisplayP4CommandsPrefName); if (HasPref(CheckStatusForMenusPrefName)) CheckStatusForMenus = GetPrefBool(CheckStatusForMenusPrefName); if (HasPref(CheckStatusForMenusMaxItemsPrefName)) CheckStatusForMenusMaxItems = GetPrefInt(CheckStatusForMenusMaxItemsPrefName); if (HasPref(OperationBatchCountPrefName)) OperationBatchCount = GetPrefInt(OperationBatchCountPrefName); if (HasPref(ConnectionTimeOutPrefName)) ConnectionTimeOut = GetPrefInt(ConnectionTimeOutPrefName); if (HasPref(WarnOnSpecialCharactersPrefName)) WarnOnSpecialCharacters = GetPrefBool(WarnOnSpecialCharactersPrefName); if (HasStringPrefNotEmpty(IgnoreNamePrefName)) IgnoreName = GetPrefString(IgnoreNamePrefName); if (HasStringPrefNotEmpty(IgnoreLinesPrefName)) IgnoreLines = GetPrefString(IgnoreLinesPrefName); if (HasPref(UseTypemapPrefName)) UseTypemap = GetPrefBool(UseTypemapPrefName); if (HasPref(EnableLogPrefName)) EnableLog = GetPrefBool(EnableLogPrefName); if (HasPref(ConsoleLogLevelPrefName)) ConsoleLogLevel = (Logger.LogLevel)GetPrefInt(ConsoleLogLevelPrefName); if (HasStringPrefNotEmpty(LogPathPrefName)) LogPath = GetPrefString(LogPathPrefName); //Config.Refresh(); // Notify users that prefs changed if (PrefsChanged != null) PrefsChanged(); } // Utility method to write our the connection prefs to the registry public static void WritePrefs() { SetPrefString(ServerUriPrefName, ServerUri); SetPrefString(UserNamePrefName, Username); if (!String.IsNullOrEmpty(Password)) { //SetPrefString(PasswordPrefName, Password); SetPrefString(PasswordPrefName, Secure.EncryptString(Password)); } SetPrefString(WorkspacePrefName, Workspace); SetPrefBool(PerforceEnabledPrefName, PerforceEnabled); SetPrefBool(UnityVsSupportPrefName, UnityVsSupport); SetPrefBool(IncludeProjectFilesPrefName, IncludeProjectFiles); SetPrefBool(IncludeSolutionFilesPrefName, IncludeSolutionFiles); SetPrefBool(ShowPathsPrefName, ShowPaths); SetPrefBool(AskBeforeCheckoutPrefName, AskBeforeCheckout); SetPrefBool(DisplayStatusIconsPrefName, DisplayStatusIcons); SetPrefString(HostnamePrefName, Hostname); SetPrefString(DiffToolPathnamePrefName, DiffToolPathname); SetPrefBool(DisplayP4TimingsPrefName, DisplayP4Timings); SetPrefBool(DisplayP4CommandsPrefName, EchoP4Commands); SetPrefBool(CheckStatusForMenusPrefName, CheckStatusForMenus); SetPrefInt(CheckStatusForMenusMaxItemsPrefName, CheckStatusForMenusMaxItems); SetPrefInt(OperationBatchCountPrefName, OperationBatchCount); SetPrefInt(ConnectionTimeOutPrefName, ConnectionTimeOut); SetPrefBool(WarnOnSpecialCharactersPrefName, WarnOnSpecialCharacters); SetPrefString(IgnoreNamePrefName, IgnoreName); SetPrefString(IgnoreLinesPrefName, IgnoreLines); SetPrefBool(UseTypemapPrefName, UseTypemap); SetPrefBool(EnableLogPrefName, EnableLog); SetPrefInt(ConsoleLogLevelPrefName, (int)ConsoleLogLevel); SetPrefString(LogPathPrefName, LogPath); } static string GetFullPrefName(string aPrefName) { return "P4Connect_" + Main.ProjectName + "_" + aPrefName; } static bool HasPref(string aPrefName) { return EditorPrefs.HasKey(GetFullPrefName(aPrefName)); } static bool HasStringPrefNotEmpty(string aPrefName) { return (!String.IsNullOrEmpty(EditorPrefs.GetString(GetFullPrefName(aPrefName)))); } static void SetPrefString(string aPrefName, string aPref) { EditorPrefs.SetString(GetFullPrefName(aPrefName), aPref); } static void SetPrefInt(string aPrefName, int aPref) { EditorPrefs.SetInt(GetFullPrefName(aPrefName), aPref); } static void SetPrefBool(string aPrefName, bool aPref) { EditorPrefs.SetBool(GetFullPrefName(aPrefName), aPref); } static string GetPrefString(string aPrefName) { return EditorPrefs.GetString(GetFullPrefName(aPrefName)); } static int GetPrefInt(string aPrefName) { return EditorPrefs.GetInt(GetFullPrefName(aPrefName)); } static bool GetPrefBool(string aPrefName) { return EditorPrefs.GetBool(GetFullPrefName(aPrefName)); } // [MenuItem("Edit/Delete Project EditorPrefs", false, 300)] static void DeleteAllEditorPrefs() { // Delete All keys for this project EditorPrefs.DeleteKey(ServerUriPrefName); EditorPrefs.DeleteKey(UserNamePrefName); EditorPrefs.DeleteKey(PasswordPrefName); EditorPrefs.DeleteKey(WorkspacePrefName); EditorPrefs.DeleteKey(UnityVsSupportPrefName); EditorPrefs.DeleteKey(IncludeProjectFilesPrefName); EditorPrefs.DeleteKey(IncludeSolutionFilesPrefName); EditorPrefs.DeleteKey(ShowPathsPrefName); EditorPrefs.DeleteKey(AskBeforeCheckoutPrefName); EditorPrefs.DeleteKey(DisplayStatusIconsPrefName); EditorPrefs.DeleteKey(HostnamePrefName); EditorPrefs.DeleteKey(DiffToolPathnamePrefName); EditorPrefs.DeleteKey(DisplayP4TimingsPrefName); EditorPrefs.DeleteKey(DisplayP4CommandsPrefName); EditorPrefs.DeleteKey(CheckStatusForMenusPrefName); EditorPrefs.DeleteKey(CheckStatusForMenusMaxItemsPrefName); EditorPrefs.DeleteKey(OperationBatchCountPrefName); EditorPrefs.DeleteKey(ConnectionTimeOutPrefName); EditorPrefs.DeleteKey(WarnOnSpecialCharactersPrefName); EditorPrefs.DeleteKey(IgnoreNamePrefName); EditorPrefs.DeleteKey(IgnoreLinesPrefName); EditorPrefs.DeleteKey(UseTypemapPrefName); EditorPrefs.DeleteKey(EnableLogPrefName); EditorPrefs.DeleteKey(ConsoleLogLevelPrefName); } #endregion } [Serializable] public class ConfigAsset : ScriptableObject { // These are the config values // We serialize this Class and place it in the P4Connect/Editor Asset Hierarchy public string ServerUri; public string Username; [HideInInspector] public string Password; public string Workspace; public string Hostname; public string Charset; public bool UnityVsSupport; public bool PerforceEnabled; public bool IncludeProjectFiles; public bool IncludeSolutionFiles; public bool ShowPaths; public bool AskBeforeCheckout; public bool DisplayStatusIcons; public string DiffToolPathname; public bool DisplayP4Timings; public bool DisplayP4Commands; public bool CheckStatusForMenus; public int CheckStatusForMenusMaxItems; public int ConnectionTimeOut; public bool WarnOnSpecialCharacters; public string IgnoreName; public bool EnableLog; public Logger.LogLevel ConsoleLogLevel; public string LogPath; public string IgnoreLines; public bool UseTypemap; // Copy the contents of this ConfigAsset into the P4Connect Config class. public void CopyAssetToConfig() { Config.ServerUri = ServerUri; Config.Username = Username; Config.Password = Password; Config.Workspace = Workspace; Config.Hostname = Hostname; Config.Charset = Charset; Config.UnityVsSupport = UnityVsSupport; Config.PerforceEnabled = PerforceEnabled; Config.IncludeProjectFiles = IncludeProjectFiles; Config.IncludeSolutionFiles = IncludeSolutionFiles; Config.ShowPaths = ShowPaths; Config.AskBeforeCheckout = AskBeforeCheckout; Config.DisplayStatusIcons = DisplayStatusIcons; Config.DiffToolPathname = DiffToolPathname; Config.DisplayP4Timings = DisplayP4Timings; Config.EchoP4Commands = DisplayP4Commands; Config.CheckStatusForMenus = CheckStatusForMenus; Config.CheckStatusForMenusMaxItems = CheckStatusForMenusMaxItems; Config.ConnectionTimeOut = ConnectionTimeOut; Config.WarnOnSpecialCharacters = WarnOnSpecialCharacters; Config.IgnoreName = IgnoreName; Config.EnableLog = EnableLog; Config.ConsoleLogLevel = ConsoleLogLevel; Config.LogPath = LogPath; Config.IgnoreLines = IgnoreLines; Config.UseTypemap = UseTypemap; } // Seed a ConfigAsset with data from the Config Class public void CopyConfigToAsset() { ServerUri = Config.ServerUri; Username = Config.Username; Password = Config.Password; Workspace = Config.Workspace; Hostname = Config.Hostname; Charset = Config.Charset; UnityVsSupport = Config.UnityVsSupport; PerforceEnabled = Config.PerforceEnabled; IncludeProjectFiles = Config.IncludeProjectFiles; IncludeSolutionFiles = Config.IncludeSolutionFiles; ShowPaths = Config.ShowPaths; AskBeforeCheckout = Config.AskBeforeCheckout; DisplayStatusIcons = Config.DisplayStatusIcons; DiffToolPathname = Config.DiffToolPathname; DisplayP4Timings = Config.DisplayP4Timings; DisplayP4Commands = Config.EchoP4Commands; CheckStatusForMenus = Config.CheckStatusForMenus; CheckStatusForMenusMaxItems = Config.CheckStatusForMenusMaxItems; ConnectionTimeOut = Config.ConnectionTimeOut; WarnOnSpecialCharacters = Config.WarnOnSpecialCharacters; IgnoreName = Config.IgnoreName; EnableLog = Config.EnableLog; ConsoleLogLevel = Config.ConsoleLogLevel; LogPath = Config.LogPath; IgnoreLines = Config.IgnoreLines; UseTypemap = Config.UseTypemap; } } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 21852 | cswiedler | Branch //guest/cswiedler/p4connect | ||
//guest/perforce_software/p4connect/main/src/P4Connect/P4Connect/P4Connect.Config.cs | |||||
#11 | 20275 | Norman Morse |
Update source to match 2016.2 patch 2 release Much thrashing of source during refactor. Proper caching of asset statuses, reducing fstats issued. Some bug fixes by Liz Lam Cleanup of Pending changes, rework of initialization and play/stop play transitions |
||
#10 | 19279 | Norman Morse |
Update workshop from internal changes. These Changes are the basis of the 2016.2 release - Dropped support for Unity 4 - Built in Unity 5 - Fixed assembly misidentifications. - Fixed problem where configuration dialog would pop up between runs |
||
#9 | 18942 | Norman Morse | 2016.1 Patch 2 changes | ||
#8 | 18665 | Norman Morse | 16.2 preparation checkin | ||
#7 | 18462 | Norman Morse |
Final Changes needed for 2016.1 release New Icons. New Icon Packaging. Unity 4 compatibility changes. |
||
#6 | 18436 | Norman Morse |
A lot of clean up. PackageIcons was a mess Needed to remove GUIStyle Saving because textures are getting lost. |
||
#5 | 18418 | Norman Morse |
Many changes from the dev branch. Icons are packaged differently. Style Sheet is created / used New ConnectionWizard Dialog New PasswordDialog Generate -a tickets Update version to 2016.1.0.0 |
||
#4 | 16384 | Norman Morse | Move test code out of DEBUG block | ||
#3 | 16383 | Norman Morse |
Changed Password storage obfuscation code. Added debug for EditorPrefs issue on OSX |
||
#2 | 16350 | Norman Morse |
Minor Code Clean Up Minor Documentation Clean Up Changed Post Processor callback to ignore directories Added option to use Server Typemap |
||
#1 | 16209 | Norman Morse | Move entire source tree into "main" branch so workshop code will act correctly. | ||
//guest/perforce_software/p4connect/src/P4Connect/P4Connect/P4Connect.Config.cs | |||||
#28 | 16163 | Norman Morse |
Import latest changes from 2015.2/1245676 Fixes disconnect issue on "run" Fixes SSL versioning problem on OSX Added VS2015 support to project files |
||
#27 | 16117 | Norman Morse |
Fix for EditorPrefs related Disconnection. Cleaned up some code. Removed Spurious Comments Initialize Config from within Main |
||
#26 | 15424 | Norman Morse |
Fixed exceptions in Dialogs. Updated release Notes. Added checks to menus for PerforceEnabled |
||
#25 | 15401 | Norman Morse |
Fixed serialization of Config so P4Connect remains connected after a Game Run Cleaned up some menus. |
||
#24 | 15383 | Norman Morse |
Improved Diagnostics, cleaned up unnecessary log output Moved some Dialog Initialization to OnEnable() Fixed Unity 5.1.1 incompatibilities Added Operation support for In Depot Deleted files |
||
#23 | 15298 | Norman Morse | Fix Version Stamping to not use UpdateVersion.exe for personal (workshop) builds. | ||
#22 | 15266 | Norman Morse |
Integrated "UpdateVersion" tool to update the VersionInfo and the DLL properties with information from "Version" EC generates the Version file for us in builds. Workshop users need to generate their own Release number with two zeros (like 2015.2.0.0) which will have the last two numbers replaced with change ID. |
||
#21 | 15244 | Norman Morse |
Better Directory support in "add" "get latest" "refresh" and other commands. Improved Project Root detection Various Bug Fixes and Clean up |
||
#20 | 15146 | Norman Morse |
Rewrote Config Dialog to resize well and work both vertically and horizontally. Fixed some internal issues in file handling. Removed .bytes from default type of "text" |
||
#19 | 15079 | Norman Morse |
Rewrote AssetStatusCache to Cache AssetStatuses and FileMetaData Fixed Edge conditions on Engine Operations Change Debug output defaults. Will now Checkout files which request to be "added" but which already exist in perforce. Output P4Connect version to log on initialization. |
||
#18 | 14801 | Norman Morse |
GA.9 changes. Fixed debug message exceptions Improved Pending Changes dialog for large changesets Changed configuration to allow saving configuration with Perforce disabled. Improved restart after recompile, automatically attempts connection now unless disabled. |
||
#17 | 14193 | Norman Morse |
GA.7 release Refactor Pending Changes Resolve Submit issues. Fixed Menu entries. Handle mismatched file and meta states. |
||
#16 | 13864 | Norman Morse | Final fixes for GA.5 release. | ||
#15 | 13813 | Norman Morse |
Changed Config to call CheckProjectRoot which creates ClientProjectRoot and DepotProjectRoot Filter files in changelists to include only files under the Project root. Run fstat on files in the default change to make sure we have complete metadata |
||
#14 | 13596 | Norman Morse |
GA.3 fixes Update release notes. Fix config dialog initialization, update version Disable warnings for PackageIcons.cs, Fix crash in GetLockState() call |
||
#13 | 13269 | Norman Morse |
Bumped version to 2.7 GA 2 Fixed problem with Hung Config Window and no previous settings Fixed code to automattically attempt to connect to Perforce Server if configuration allows. |
||
#12 | 12862 | Norman Morse |
Fixed problem with an empty default change list not refresshing. Fixed crash in is_ignored Removed a lot of log output |
||
#11 | 12568 | Norman Morse | Fixed some error handling during Perforce Configuration | ||
#10 | 12566 | Norman Morse |
Fixed hang when restarting after rebuild Updated Release String to GA |
||
#9 | 12554 | Norman Morse |
Changed OSX DLL checking code. Improved re-connection after restart |
||
#8 | 12553 | Norman Morse |
integrate from internal main Build fixes for EC. Major changes to Configuration and re-initialization code. Bug fixes |
||
#7 | 12512 | Norman Morse | Integrate from Dev branch, preparing for Beta3 release | ||
#6 | 12368 | Norman Morse |
Improved config dialog. Perforce defaults to Enabled |
||
#5 | 12251 | Norman Morse |
Fixes for Beta 2 release Mostly Configuration dialog bug fixes |
||
#4 | 12135 | Norman Morse |
Integrate dev branch changes into main. This code is the basiis of the 2.7 BETA release which provides Unity 5 compatibility |
||
#3 | 11378 | Norman Morse |
P4Config support. Debugging DLL Loading issues |
||
#2 | 11224 | Norman Morse |
Add P4Config support to P4Connect. It checks for a P4Config Environment variable, and if found, looks for the controlling P4Config file. It then pre-populates the settings with information from P4Config and kicks off a validate. You can re-run the P4Config routine by turning on and off the checkbox from within the P4Connect settings. |
||
#1 | 10940 | Norman Morse |
Inital Workshop release of P4Connect. Released under BSD-2 license |