private void ParseSourceFile(float progress, string file, ref List <ClassModel> data, int gcLimit, ref int gcCount) { MigrationWindow.DisplayProgressBar("Exporting IDs", "Exporting IDs " + Path.GetFileName(file), progress); IEnumerable <string> lines = File.ReadLines(file); string className; foreach (string line in lines) { Match match = constants.RegexGuid.Match(line); if (!match.Success) { continue; } className = getTypeByMetafileFileName(file); if (String.IsNullOrEmpty(className)) { continue; } data.Add(new ClassModel(className, match.Value)); break; } gcCount++; if (gcCount > gcLimit) { GC.Collect(); } }
public void ExportCurrentClassData(string rootPath) { string idExportPath = rootPath + constants.RelativeExportPath; List <ClassModel> IDs = idController.ExportClassData(rootPath); var jsonSerializerSettings = new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Serialize, PreserveReferencesHandling = PreserveReferencesHandling.Objects, Formatting = constants.IndentJson }; string jsonField = JsonConvert.SerializeObject(IDs, jsonSerializerSettings); if (!Directory.Exists(Path.GetDirectoryName(idExportPath))) { Directory.CreateDirectory(Path.GetDirectoryName(idExportPath)); } File.WriteAllText(idExportPath, jsonField); string logMessage = "All IDs were exported to " + constants.RelativeExportPath + "."; Debug.Log(logMessage); if (Administration.Instance.ShowInfoPopups) { MigrationWindow.DisplayDialog("Export completed successfully", logMessage); } }
/// <summary> /// Gets all the classes in the project and gets the name of the class, the guid that unity assigned and the fileID. /// Then checks all to be serialized fields and returns them in a list /// </summary> /// <returns></returns> /// <exception cref="NotImplementedException"></exception> public List <ClassModel> ExportClassData(string path) { //Get all meta files string[] classMetaFiles = Directory.GetFiles(path, "*.cs.meta", SearchOption.AllDirectories); //Get all dlls string[] dllMetaFiles = Directory.GetFiles(path, "*.dll.meta", SearchOption.AllDirectories); int gcCount = 0; int gcLimit = 50000; List <ClassModel> classes = new List <ClassModel>(); string file; for (var i = 0; i < classMetaFiles.Length; i++) { file = classMetaFiles[i]; ParseSourceFile((float)i / classMetaFiles.Length, file, ref classes, gcLimit, ref gcCount); } string metaFile; for (var i = 0; i < dllMetaFiles.Length; i++) { metaFile = dllMetaFiles[i]; ParseDLLFile((float)i / dllMetaFiles.Length, metaFile, ref classes, gcLimit, ref gcCount); } GC.Collect(); MigrationWindow.ClearProgressBar(); return(classes); }
/// <summary> /// Get the Type of a class by the name of the class. /// </summary> /// <param name="path">The path of the meta file we're getting the name from</param> /// <returns></returns> private string getTypeByMetafileFileName(string path) { string fileName = Path.GetFileName(path); fileName = fileName.Replace(".cs.meta", ""); string fileNameLower = fileName.ToLower(); if (cachedLowerTypeList == null) { cachedLowerTypeList = assemblies.SelectMany(assembly => assembly.GetTypes()) .Select(type => new KeyValuePair <string, Type>(type.Name.ToLower(), type)).ToArray(); } Type[] types = cachedLowerTypeList.Where(loweredTypeName => loweredTypeName.Key == fileNameLower) .Select(pair => pair.Value).ToArray(); if (types.Length == 0) { Debug.Log("Checked for type \"" + fileName + "\" no types were found."); return(null); } if (types.Length == 1) { return(types[0].FullName); } // Check if they're monoBehaviours and if they are return those. List <Type> monoBehaviours = new List <Type>(); foreach (Type type in types) { if (type.IsSubclassOf(typeof(MonoBehaviour)) && // Apparently we sometimes use the same dll in the same project causing the same classes(including same namespace), using the same name. // As this causes the same fileID we just use the first one monoBehaviours.FirstOrDefault(mono => mono.Name == type.Name) == null) { monoBehaviours.Add(type); } } if (monoBehaviours.Count == 0) { Debug.LogWarning("Class : " + fileName + " could not be found and is not an MonoBehaviour so will skip"); return(null); } if (monoBehaviours.Count == 1) { return(monoBehaviours[0].FullName); } string[] options = monoBehaviours.Select(type => type.FullName).ToArray(); return(MigrationWindow.OpenOptionsWindow("Class cannot be found, select which one to choose", fileName, options)); }
/// <summary> /// Migrate all prefabs /// </summary> /// <param name="destinationProjectPath"></param> /// <param name="originalProjectPath"></param> /// <param name="onComplete"></param> public void MigrateAllPrefabs(string destinationProjectPath, string originalProjectPath = null, Action onComplete = null, List <ScriptMapping> scriptMappings = null) { if (originalProjectPath == null) { ThreadUtility.RunWaitMainTask(() => { originalProjectPath = EditorUtility.OpenFolderPanel("Export all prefabs in folder", destinationProjectPath, ""); } ); } if (string.IsNullOrEmpty(originalProjectPath)) { Debug.Log("Copy prefabs aborted, no path given."); return; } //Deserialize the ScriptMappings if (scriptMappings == null && File.Exists(destinationProjectPath + constants.RelativeScriptMappingPath)) { scriptMappings = MappingController.DeserializeMapping(destinationProjectPath + constants.RelativeScriptMappingPath); } List <PrefabModel> prefabs = prefabController.ExportPrefabs(originalProjectPath + "/Assets"); for (var i = 0; i < prefabs.Count; i++) { PrefabModel prefab = prefabs[i]; MigrationWindow.DisplayProgressBar("Migrating prefab (" + (i + 1) + "/" + prefabs.Count + ")", info: "Migrating prefab: " + prefab.Path.Substring(originalProjectPath.Length), progress: (float)(i + 1) / prefabs.Count); ThreadUtility.RunWaitTask(() => { MigratePrefab(prefab.Path, originalProjectPath, destinationProjectPath, prefabs, prefab.Guid, scriptMappings); } ); GC.Collect(); } MigrationWindow.ClearProgressBar(); ThreadUtility.RunMainTask(() => { AssetDatabase.Refresh(); }); Debug.Log("Migrated all prefabs"); if (onComplete != null) { onComplete.Invoke(); } }
/// <summary> /// Finds the new GUID and fileID from the old IDs and the new IDs by checking for the classname in both /// </summary> /// <param name="newIDs"></param> /// <param name="old"></param> /// <returns></returns> private ClassModel findNewID(List <ClassModel> newIDs, ClassModel old) { if (old == null) { throw new NullReferenceException("Old ClassData cannot be null in the findNewID"); } // Check if there is an exact match ClassModel newFileModel = newIDs.FirstOrDefault(data => data.FullName.Equals(old.FullName)); if (newFileModel != null) { return(newFileModel); } //Get all classes including all subclasses and check if it might be a subclass Dictionary <string, ClassModel> allClassData = generateOptions(newIDs); if (allClassData.ContainsKey(old.Name)) { return(allClassData[old.Name]); } // Check if there is an exact match with only the classname ClassModel[] classModels = allClassData.Select(pair => pair.Value) .Where(model => model.NameLower == old.NameLower).ToArray(); if (classModels.Length == 1) { return(classModels[0]); } // Generate the options for the options window string[] options = allClassData.Select(pair => pair.Key) .OrderBy(name => Levenshtein.Compute(name, old.FullName)).ToArray(); // Open the options window string result = MigrationWindow.OpenOptionsWindow( "Could not find class, please select which class to use", old.FullName, options ); // Return the selected class if (string.IsNullOrEmpty(result)) { Debug.LogError("[Data loss] Could not find class for : " + old.FullName + " and no new class was chosen. This script will not be migrated!"); return(null); } return(allClassData[result]); }
/// <summary> /// Gets all the classes in the project and gets the name of the class, the guid that unity assigned and the fileID. /// Then checks all to be serialized fields and returns them in a list /// </summary> /// <returns></returns> /// <exception cref="NotImplementedException"></exception> public List <ClassModel> ExportClassData(string path) { float progress = 0; //Get all meta files string[] classMetaFiles = Directory.GetFiles(path, "*.cs.meta", SearchOption.AllDirectories); //Get all dlls string[] dllMetaFiles = Directory.GetFiles(path, "*.dll.meta", SearchOption.AllDirectories); int totalFiles = classMetaFiles.Length + dllMetaFiles.Length; int gcCount = 0; int gcLimit = 50000; List <ClassModel> classes = new List <ClassModel>(); for (var i = 0; i < classMetaFiles.Length; i++) { string file = classMetaFiles[i]; ParseSourceFile((float)i / classMetaFiles.Length, file, ref classes, gcLimit, ref gcCount); } // Loop through dlls if (!constants.DEBUG) { // Thread[] dllThreads = new Thread[dllMetaFiles.Length]; for (var i = 0; i < dllMetaFiles.Length; i++) { string metaFile = dllMetaFiles[i]; // dllThreads[i] = // new Thread(() => ParseDLLFile((float)i / dllMetaFiles.Length, metaFile, ref classes, gcLimit, ref gcCount) // ) ; // dllThreads[i].Start(); } // bool stillRunning = true; // while (stillRunning) // { // int threadsRunning = dllThreads.Where(thread => thread.IsAlive).ToArray().Length; // stillRunning = threadsRunning > 0; // // MigrationWindow.DisplayProgressBar("Exporting IDs from DLLs", // "Threads running " + threadsRunning + "/" + dllThreads.Length, // threadsRunning / dllThreads.Length); // Thread.Sleep(100); // } } MigrationWindow.ClearProgressBar(); return(classes); }
private void ParseDLLFile(float progress, string metaFile, ref List <ClassModel> data, int gcLimit, ref int gcCount) { MigrationWindow.DisplayProgressBar("Exporting IDs", "Exporting IDs " + Path.GetFileName(metaFile), progress); string text = File.ReadAllText(metaFile); Match match = constants.RegexGuid.Match(text); if (!match.Success) { Debug.LogError("Could not parse the guid from the dll meta file. File : " + metaFile); } string file = metaFile.Replace(".meta", ""); try { if (Path.GetFileName(file).Contains("Newtonsoft.Json") || Path.GetFileName(file).Contains("YamlDotNet")) { return; } Assembly assembly = Assembly.LoadFile(file); foreach (Type type in assembly.GetTypes()) { if (!type.IsSubclassOf(typeof(MonoBehaviour))) { continue; } MigrationWindow.DisplayProgressBar("Exporting IDs", "Exporting IDs " + type, progress); data.Add(new ClassModel(type, match.Value, FileIDUtil.Compute(type).ToString())); gcCount++; if (gcCount > gcLimit) { GC.Collect(); } } } catch (Exception e) { Debug.LogWarning("Could not load assembly : " + file + "\nException : " + e); } }
/// <summary> /// Replaces all old GUIDs and old fileIDs with the new GUID and fileID and returns a the new scenefile. /// This can be saved as an .unity file and then be opened in the editor. /// </summary> /// <param name="fileToChange"></param> /// <param name="oldIDs"></param> /// <param name="newIDs"></param> /// <param name="foundScripts"></param> /// <returns></returns> /// <exception cref="NotImplementedException"></exception> public string[] TransformIDs(string fileToChange, List <ClassModel> oldIDs, List <ClassModel> newIDs, ref List <FoundScript> foundScripts) { MigrationWindow.DisplayProgressBar("Migration started", "Start importing current project classData and migrating scene.", 0.5f); if (oldIDs == null || newIDs == null || foundScripts == null) { throw new NullReferenceException("Some of the data with which to export is null."); } string[] linesToChange = File.ReadAllLines(fileToChange); linesToChange = MigrateGUIDsAndFieldIDs(linesToChange, oldIDs, newIDs, ref foundScripts); MigrationWindow.ClearProgressBar(); return(linesToChange); }
/// <summary> /// Generate a mapping of all scriptMappings in a project. /// Which means it creates a mapping between versions. /// </summary> /// <param name="oldIDs"></param> /// <param name="newIDs"></param> /// <returns></returns> public void MapAllClasses(List <ClassModel> oldIDs, List <ClassModel> newIDs) { ThreadUtility.RunTask(() => { MigrationWindow.DisplayProgressBar("starting migration export", "Mapping classes", 0.4f); mappingController.MapAllClasses(oldIDs, newIDs, mergedScriptMapping => { SaveScriptMappings(constants.RootDirectory, mergedScriptMapping); MigrationWindow.ClearProgressBar(); ThreadUtility.RunMainTask(() => { EditorUtility.DisplayDialog("Completed mapping", "Completed the mapping. Saved the mapping to: " + constants.RelativeScriptMappingPath, "Ok"); }); }); }); }
public List <PrefabModel> ExportPrefabs(string path) { //Get all prefabs string[] prefabMetaFiles = Directory.GetFiles(path, "*.prefab.meta", SearchOption.AllDirectories); List <PrefabModel> prefabModels = new List <PrefabModel>(prefabMetaFiles.Length); for (var i = 0; i < prefabMetaFiles.Length; i++) { string file = prefabMetaFiles[i]; MigrationWindow.DisplayProgressBar("Exporting Prefabs", "Exporting prefab " + Path.GetFileName(file), prefabMetaFiles.Length / i); ParsePrefabFile(file, ref prefabModels); } return(prefabModels); }
/// <summary> /// Migrate all scenes in a project at once at once /// </summary> /// <param name="projectToExportFromPath">The path of the project that needs to be migrated to the current project</param> /// <param name="onComplete">Runs after all scenes have been exported</param> public void MigrateAllScenes(string projectToExportFromPath = null, Action onComplete = null) { MigrationWindow.DisplayProgressBar("Migrating scenes", "Migrating scenes", 0.2f); if (projectToExportFromPath == null) { projectToExportFromPath = EditorUtility.OpenFolderPanel("Export all scenes in folder", constants.RootDirectory, ""); } if (string.IsNullOrEmpty(projectToExportFromPath)) { Debug.Log("Migrating all scenes aborted, no path given."); MigrationWindow.ClearProgressBar(); return; } ThreadUtility.RunTask(() => { string[] sceneFiles = Directory.GetFiles(projectToExportFromPath, "*.unity", SearchOption.AllDirectories); for (var i = 0; i < sceneFiles.Length; i++) { string scene = sceneFiles[i]; MigrationWindow.DisplayProgressBar("Migrating scenes (" + (i + 1) + "/" + sceneFiles.Length + ")", "Migrating scene: " + scene.Substring(projectToExportFromPath.Length), (float)(i + 1) / sceneFiles.Length); ThreadUtility.RunWaitTask(() => { MigrateScene(scene, constants.RootDirectory); }); GC.Collect(); } MigrationWindow.ClearProgressBar(); Debug.Log("Migrated all scenes"); if (onComplete != null) { onComplete.Invoke(); } }); }
public void PostSimiasStart() { bool accountPrompt = false; try { globalProperties.InitializeServerList(); DomainInformation[] domains; domains = this.simiasWebService.GetDomains(false); foreach (DomainInformation dw in domains) { try { if (dw.IsSlave) { preferences.AddDomainToList(dw); if (this.simiasWebService.GetRememberOption(dw.ID) == false) this.simiasWebService.StorePassPhrase(dw.ID, "", CredentialType.None, false); } BeginInvoke(globalProperties.addDomainToListDelegate, new object[] { dw }); preferences.SetProxyForDomain(dw.HostUrl, false); } catch { } } if (domains.Length.Equals(0)) { this.NoAccounts = true; accountPrompt = true; } } catch { } if (worker == null) { worker = new Thread(new ThreadStart(eventThreadProc)); worker.Name = "FormsTaryApp Event"; worker.IsBackground = true; worker.Priority = ThreadPriority.BelowNormal; worker.Start(); } shellNotifyIcon.Text = resourceManager.GetString("iFolderServices"); shellNotifyIcon.Icon = trayIcon; try { if (accountPrompt == false) { if ((!Preferences.HideiFolderInTray && RegularStart) || ShowWindow ) { this.globalProperties.Show(); } updateOverlayIcons(); string iFolderKey = @"SOFTWARE\Novell\iFolder"; RegistryKey regKey = Registry.CurrentUser.CreateSubKey(iFolderKey); int Migration = (int)regKey.GetValue("MigrationPrompt", (int)1); if (Migration == 1) { if (iFolder2Present() == true) { bool migrate = MigrationPrompt(); if (migrate == true) { Novell.FormsTrayApp.MigrationWindow migrationWindow = new MigrationWindow(this.ifWebService, this.simiasWebService); migrationWindow.ShowDialog(this); } } } } if (accountPrompt) { bool status = false; string filePathValue; System.Object[] args = new System.Object[5]; try { Assembly idAssembly = Assembly.LoadFrom(AutoAccountConstants.assemblyName); if (idAssembly != null) { Type type = idAssembly.GetType(AutoAccountConstants.autoAccountClass); if (null != type) { args[0] = ifWebService; args[1] = simiasWebService; args[2] = simiasManager; args[3] = globalProperties; args[4] = this; System.Object autoAccount = Activator.CreateInstance(type, args); MethodInfo method = type.GetMethod(AutoAccountConstants.autoAccountCreateAccountsMethod); status = (bool)method.Invoke(autoAccount, null); if (status) { method = type.GetMethod(AutoAccountConstants.autoAccountPrefMethod); method.Invoke(autoAccount, null); PropertyInfo info = type.GetProperty(AutoAccountConstants.autoAccountFilePath); filePathValue = (string)info.GetValue(autoAccount, null); FormsTrayApp.log.Debug("File path value is {0}", filePathValue); System.IO.FileInfo fileInfo = new System.IO.FileInfo(filePathValue); System.IO.FileInfo backupFileInfo = new System.IO.FileInfo(filePathValue + ".backup"); if(File.Exists(filePathValue + ".backup")) { backupFileInfo.Delete(); } fileInfo.MoveTo(filePathValue + ".backup"); } } } } catch (Exception ex) { FormsTrayApp.log.Info("Error: {0}", ex.Message); FormsTrayApp.log.Debug("Exception Type {0}", ex.GetType()); FormsTrayApp.log.Debug("StackTrace {0}", ex.StackTrace); } if (!status) { DomainInformation[] domains; domains = this.simiasWebService.GetDomains(false); if (domains.Length.Equals(0)) { AccountWizard accountWizard = new AccountWizard(ifWebService, simiasWebService, simiasManager, true, this.preferences, this.globalProperties); accountWizard.EnterpriseConnect += new Novell.Wizard.AccountWizard.EnterpriseConnectDelegate(preferences_EnterpriseConnect); wizardRunning = true; DialogResult result = accountWizard.ShowDialog(); wizardRunning = false; if (result == DialogResult.OK) { preferences_DisplayiFolderDialog(this, new EventArgs()); } } } else if (!wizardRunning) { if (globalProperties.Visible) { globalProperties.Activate(); } else { DomainInformation[] domains; domains = this.simiasWebService.GetDomains(false); if (!domains.Length.Equals(0)) globalProperties.Show(); } } } } catch (Exception e1) { MessageBox.Show(string.Format("Exception: {0}--{1}", e1.Message, e1.StackTrace)); } }