public static void ProcessAssetFile(string filename, string assetPath, string originalName, string replacementName,
                                     ProcessFileDelegate processFileHandler, ProcessSceneDelegate processSceneHandler, ProcessPrefabDelegate processPrefabHandler)
 {
     try
     {
         processFileHandler(filename, assetPath, originalName, replacementName, processSceneHandler, processPrefabHandler);
     }
     catch (System.Exception e)
     {
         if (assetPath.Contains("NavMesh"))
         {
             report += "Did not process " + filename + " but it appears to be a NavMesh so this should be fine. Result: " + e.Message + "\n";
         }
         else if (assetPath.Contains("Terrain"))
         {
             report += "Did not process " + filename + " but it appears to be a Terrain so this should be fine. Result: " + e.Message + "\n";
         }
         else
         {
             report += "Unable to process " + filename + ": " + e.Message + "\n";
         }
     }
 }
        public static void ProcessQuestInFile(string filename, string assetPath, string originalName, string replacementName,
                                              ProcessSceneDelegate processSceneHandler, ProcessPrefabDelegate processPrefabHandler)
        {
            if (string.IsNullOrEmpty(filename) || string.IsNullOrEmpty(originalName))
            {
                return;
            }
            var text = File.ReadAllText(filename);

            if (string.IsNullOrEmpty(text))
            {
                return;
            }
            var replace = !string.IsNullOrEmpty(replacementName);

            // Find/replace Lua expressions that use the original quest name:
            // Item[]
            var originalLuaExpression    = "Item[\"" + DialogueLua.StringToTableIndex(originalName) + "\"]";
            var replacementLuaExpression = string.IsNullOrEmpty(replacementName.Trim()) ? string.Empty : "Item[\"" + DialogueLua.StringToTableIndex(replacementName) + "\"]";
            var found = FindText(originalLuaExpression, replacementLuaExpression, replace, ref text);

            // Quest[]
            originalLuaExpression    = "Quest[\"" + DialogueLua.StringToTableIndex(originalName) + "\"]";
            replacementLuaExpression = string.IsNullOrEmpty(replacementName.Trim()) ? string.Empty : "Quest[\"" + DialogueLua.StringToTableIndex(replacementName) + "\"]";
            found = FindText(originalLuaExpression, replacementLuaExpression, replace, ref text) || found;
            // Quest functions
            found = FindLuaFunction("CurrentQuestState", originalName, replacementName, replace, ref text) || found;
            found = FindLuaFunction("SetQuestState", originalName, replacementName, replace, ref text) || found;
            found = FindLuaFunction("CurrentQuestEntryState", originalName, replacementName, replace, ref text) || found;
            found = FindLuaFunction("SetQuestEntryState", originalName, replacementName, replace, ref text) || found;

            if (found && replace)
            {
                File.WriteAllText(filename, text);
                AssetDatabase.Refresh();
            }

            // If it's a dialogue database, find/replace actual quest name, too:
            if (text.Contains("globalUserScript")) // DBs contain this string; used to minimize attempts to load non-database assets.
            {
                AssetDatabase.Refresh();
                var database = AssetDatabase.LoadAssetAtPath <DialogueDatabase>(assetPath);
                if (database != null)
                {
                    var quest = database.GetItem(originalName);
                    if (quest != null)
                    {
                        found = true;
                        if (replace)
                        {
                            quest.Name = replacementName;
                            EditorUtility.SetDirty(database);
                            AssetDatabase.SaveAssets();
                        }
                    }
                }
            }

            // If file is a scene, open it to check for any components such as DialogueSystemTrigger that use QuestPopup:
            if (assetPath.EndsWith(".unity"))
            {
                // Open scene:
                var sceneName = Path.GetFileNameWithoutExtension(filename);
                EditorSceneManager.OpenScene(filename);
                var scene = EditorSceneManager.GetSceneByName(sceneName);
                if (!scene.IsValid())
                {
                    return;
                }

                // Call scene checking delegate:
                var foundInScene = processSceneHandler(originalName, replacementName);
                if (foundInScene)
                {
                    // If found and replaced, save scene:
                    found = true;
                    if (replace)
                    {
                        EditorSceneManager.MarkSceneDirty(scene);
                        EditorSceneManager.SaveScene(scene);
                    }
                }
            }
            // If file is a prefab, check it:
            else if (assetPath.EndsWith(".prefab"))
            {
                var foundInPrefab = processPrefabHandler(assetPath, originalName, replacementName);
                if (foundInPrefab)
                {
                    found = true;
                    if (replace)
                    {
                        AssetDatabase.SaveAssets();
                    }
                }
            }

            // Update report:
            if (found)
            {
                report += (replace ? "Replaced in: " : "Found in: ") + assetPath + "\n";
            }
        }
        public static void ProcessAssets(string title, string originalName, string replacementName,
                                         ProcessFileDelegate processFileHandler, ProcessSceneDelegate processSceneHandler, ProcessPrefabDelegate processPrefabHandler)
        {
            AssetDatabase.SaveAssets();
            var cancel = false;

            // Save open scenes:
            if (!UnityEditor.SceneManagement.EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
            {
                report += "Cancelled.\n";
                return;
            }

            if (!string.IsNullOrEmpty(replacementName))
            {
                // Close open assets:
                if (Selection.activeObject is DialogueDatabase || Selection.activeObject is LocalizedTextTable)
                {
                    Selection.activeObject = null;
                }
                if (DialogueEditor.DialogueEditorWindow.instance != null)
                {
                    DialogueEditor.DialogueEditorWindow.instance.Close();
                }
            }

            if (!string.IsNullOrEmpty(ignoreFilesRegex))
            {
                report += "Ignoring files matching: " + ignoreFilesRegex + "\n";
            }

            // Record serialization mode and force text:
            var originalSerializationMode = EditorSettings.serializationMode;

            if (EditorSettings.serializationMode != SerializationMode.ForceText)
            {
                cancel  = EditorUtility.DisplayCancelableProgressBar("Text Serialization Required", "Switching to Force Text serialization mode. This may take a while.", 0);
                report += "Set serialization mode to Force Text.\n";
                EditorSettings.serializationMode = SerializationMode.ForceText;
                if (cancel)
                {
                    report += "Update process cancelled. Serialization mode is set to Force Text. To set it back to " + originalSerializationMode + " use menu item Edit > Project Settings > Editor.\n";
                    return;
                }
            }

            // Force visible meta files:
            var originalExternalVersionControl = versionControlMode;

            if (!versionControlMode.Equals(ExternalVersionControlVisibleMetaFiles))
            {
                cancel             = EditorUtility.DisplayCancelableProgressBar("Visible Meta Files Required", "Switching Version Control Mode to Visible Meta Files. This may take a while.", 0);
                report            += "Set version control mode to Visible Meta Files.\n";
                versionControlMode = ExternalVersionControlVisibleMetaFiles;
                if (cancel)
                {
                    report += "Update process cancelled. Serialization mode is " + EditorSettings.serializationMode + " and Version Control Mode is " +
                              versionControlMode + ". To change these settings, use menu item Edit > Project Settings > Editor.\n";
                    return;
                }
            }

            // Record currently open scene:
            var originalScenePath = EditorSceneManager.GetActiveScene().path;

            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();

            var isWindows = Application.platform == RuntimePlatform.WindowsEditor;

            try
            {
                // Update all scene, scriptable object, and prefab files:
                var files = Directory.GetFiles(Application.dataPath, "*.*", SearchOption.AllDirectories)
                            .Where(s => s.EndsWith(".unity") || s.EndsWith(".asset") || s.EndsWith(".prefab")).ToArray();
                for (int i = 0; i < files.Length; i++)
                {
                    var filename  = files[i];
                    var assetPath = filename;
                    if (isWindows)
                    {
                        assetPath = assetPath.Replace("\\", "/");
                    }
                    assetPath = "Assets" + assetPath.Substring(Application.dataPath.Length);
                    if (Regex.IsMatch(assetPath, ignoreFilesRegex))
                    {
                        continue;                                             // Ignore this file.
                    }
                    cancel = EditorUtility.DisplayCancelableProgressBar(title, filename, (float)i / (float)files.Length);
                    ProcessAssetFile(filename, assetPath, originalName, replacementName, processFileHandler, processSceneHandler, processPrefabHandler);
                    if (cancel)
                    {
                        if (EditorSettings.serializationMode != originalSerializationMode)
                        {
                            report += "Update process cancelled. Serialization mode is set to Force Text. To set it back to " + originalSerializationMode + " use menu item Edit > Project Settings > Editor.\n";
                        }
                        return;
                    }
                }
            }
            catch (Exception e)
            {
                report += e.Message + "\n";
                Debug.LogException(e);
            }
            finally
            {
                EditorUtility.ClearProgressBar();
                AssetDatabase.Refresh();

                if (!cancel)
                {
                    // Restore original serialization mode:
                    if (originalSerializationMode != SerializationMode.ForceText)
                    {
                        EditorUtility.DisplayProgressBar(title, "Restoring original serialization mode. This may take a while.", 0.99f);
                        report += "Set serialization mode to " + originalSerializationMode + "\n.";
                        EditorSettings.serializationMode = originalSerializationMode;
                    }
                    // Restore original version control mode:
                    if (originalExternalVersionControl != ExternalVersionControlVisibleMetaFiles)
                    {
                        EditorUtility.DisplayProgressBar(title, "Restoring original version control mode. This may take a while.", 0.995f);
                        report            += "Set version control mode to " + originalExternalVersionControl + ".\n";
                        versionControlMode = originalExternalVersionControl;
                    }
                }

                // Return to original scene:
                if (!string.IsNullOrEmpty(originalScenePath) && EditorSceneManager.GetActiveScene().path != originalScenePath)
                {
                    EditorSceneManager.OpenScene(originalScenePath);
                }
            }
        }
        public static void ProcessVariableInFile(string filename, string assetPath, string originalName, string replacementName,
                                                 ProcessSceneDelegate processSceneHandler, ProcessPrefabDelegate processPrefabHandler)
        {
            if (string.IsNullOrEmpty(filename) || string.IsNullOrEmpty(originalName))
            {
                return;
            }
            var text = File.ReadAllText(filename);

            if (string.IsNullOrEmpty(text))
            {
                return;
            }
            var replace = !string.IsNullOrEmpty(replacementName);

            // Find/replace Lua expressions that use the original variable name:
            var originalLuaExpression    = "Variable[\"" + DialogueLua.StringToTableIndex(originalName) + "\"]";
            var replacementLuaExpression = string.IsNullOrEmpty(replacementName.Trim()) ? string.Empty : "Variable[\"" + DialogueLua.StringToTableIndex(replacementName) + "\"]";
            var found = text.Contains(originalLuaExpression);

            if (found && replace)
            {
                text = text.Replace(originalLuaExpression, replacementLuaExpression);
            }

            // Find/replace [var=variable] tags that use the original variable name:
            var originalVarTag    = "[var=" + DialogueLua.StringToTableIndex(originalName) + "]";
            var replacementVarTag = string.IsNullOrEmpty(replacementName.Trim()) ? string.Empty : "Variable[\"" + DialogueLua.StringToTableIndex(replacementName) + "\"]";
            var foundVarTag       = text.Contains(originalVarTag);

            if (foundVarTag)
            {
                found = true;
                if (replace)
                {
                    text = text.Replace(originalVarTag, replacementVarTag);
                }
            }

            if (found && replace)
            {
                File.WriteAllText(filename, text);
                AssetDatabase.Refresh();
            }

            // If it's a dialogue database, find/replace actual variable name, too:
            if (text.Contains("globalUserScript")) // DBs contain this string; used to minimize attempts to load non-database assets.
            {
                AssetDatabase.Refresh();
                var database = AssetDatabase.LoadAssetAtPath <DialogueDatabase>(assetPath);
                if (database != null)
                {
                    var variable = database.GetVariable(originalName);
                    if (variable != null)
                    {
                        found = true;
                        if (replace)
                        {
                            variable.Name = replacementName;
                            EditorUtility.SetDirty(database);
                            AssetDatabase.SaveAssets();
                        }
                    }
                }
            }

            // If file is a scene, open it to check for any components such as IncrementOnDestroy that use VariablePopup:
            if (assetPath.EndsWith(".unity"))
            {
                // Open scene:
                var sceneName = Path.GetFileNameWithoutExtension(filename);
                EditorSceneManager.OpenScene(filename);
                var scene = EditorSceneManager.GetSceneByName(sceneName);
                if (!scene.IsValid())
                {
                    return;
                }

                // Call scene checking delegate:
                var foundInScene = processSceneHandler(originalName, replacementName);
                if (foundInScene)
                {
                    // If found and replaced, save scene:
                    found = true;
                    if (replace)
                    {
                        EditorSceneManager.MarkSceneDirty(scene);
                        EditorSceneManager.SaveScene(scene);
                    }
                }
            }
            // If file is a prefab, check it:
            else if (assetPath.EndsWith(".prefab"))
            {
                var foundInPrefab = processPrefabHandler(assetPath, originalName, replacementName);
                if (foundInPrefab)
                {
                    found = true;
                    if (replace)
                    {
                        AssetDatabase.SaveAssets();
                    }
                }
            }

            // Update report:
            if (found)
            {
                report += (replace ? "Replaced in: " : "Found in: ") + assetPath + "\n";
            }
        }