Example #1
0
        /// <summary>
        /// Handles removal of updaters when Document closes.
        /// </summary>
        public void DocumentClosing(object sender, DocumentClosingEventArgs args)
        {
            try
            {
                var doc = args.Document;
                if (null == doc)
                {
                    return;
                }

                var centralPath = RevitUtil.GetCentralFilePath(doc);
                if (!configDictionary.ContainsKey(centralPath))
                {
                    return;
                }

                var config = configDictionary[centralPath];
                UpdaterUtil.UnregisterUpdaters(doc, config);
                configDictionary.Remove(centralPath);
            }
            catch (Exception ex)
            {
                Log.AppendLog(LogMessageType.EXCEPTION, ex.Message);
            }
        }
Example #2
0
        private bool DownloadButtonClicked(GUIButton button, object obj)
        {
            if (string.IsNullOrWhiteSpace(latestVersionFolder))
            {
                return(false);
            }

            button.Enabled       = false;
            launchButton.Enabled = false;

            XDocument doc = null;

            try
            {
                doc = FetchXML("filelist.xml");
            }

            catch (Exception e)
            {
                SetUpdateInfoBox("Error while updating: " + e.Message);
                launchButton.Enabled = true;
                return(false);
            }

            updateInfoBox.ClearChildren();

            latestVersionFiles = UpdaterUtil.GetFileList(doc);
            filesToDownload    = UpdaterUtil.GetRequiredFiles(doc);

            string updaterVersion = ToolBox.GetAttributeString(doc.Root, "updaterversion", "1.1");

            if (updaterVersion != UpdaterUtil.Version)
            {
                ShowError("Warning", "The update may contain changes which can't be installed by the autoupdater. If you receive any error messages during the install, please download and install the update manually.");
            }

            string dir = Directory.GetCurrentDirectory();

            filesToDownloadCount = filesToDownload.Count;
            if (filesToDownloadCount > 0)
            {
                //WebClient webClient = new WebClient();
                //webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
                ////webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);

                //webClient.DownloadFileAsync(new Uri(latestVersionFolder + filesToDownload[0]), dir);
                DownloadNextFile();
            }

            return(true);
        }
Example #3
0
        /// <summary>
        /// Creates a new folder, copies the specified files there and creates a metadata file with install instructions.
        /// </summary>
        public static void CreateWorkshopItemStaging(List <ContentFile> contentFiles, out Workshop.Editor itemEditor, out ContentPackage contentPackage)
        {
            var stagingFolder = new DirectoryInfo(WorkshopItemStagingFolder);

            if (stagingFolder.Exists)
            {
                SaveUtil.ClearFolder(stagingFolder.FullName);
            }
            else
            {
                stagingFolder.Create();
            }
            Directory.CreateDirectory(Path.Combine(WorkshopItemStagingFolder, "Submarines"));
            Directory.CreateDirectory(Path.Combine(WorkshopItemStagingFolder, "Mods"));
            Directory.CreateDirectory(Path.Combine(WorkshopItemStagingFolder, "Mods", "ModName"));

            itemEditor                     = instance.client.Workshop.CreateItem(Workshop.ItemType.Community);
            itemEditor.Visibility          = Workshop.Editor.VisibilityType.Public;
            itemEditor.WorkshopUploadAppId = AppID;
            itemEditor.Folder              = stagingFolder.FullName;

            string previewImagePath = Path.GetFullPath(Path.Combine(itemEditor.Folder, PreviewImageName));

            File.Copy("Content/DefaultWorkshopPreviewImage.png", previewImagePath);

            //copy content files to the staging folder
            List <string> copiedFilePaths = new List <string>();

            foreach (ContentFile file in contentFiles)
            {
                string relativePath    = UpdaterUtil.GetRelativePath(Path.GetFullPath(file.Path), Environment.CurrentDirectory);
                string destinationPath = Path.Combine(stagingFolder.FullName, relativePath);
                //make sure the directory exists
                Directory.CreateDirectory(Path.GetDirectoryName(destinationPath));
                File.Copy(file.Path, destinationPath);
                copiedFilePaths.Add(destinationPath);
            }
            System.Diagnostics.Debug.Assert(copiedFilePaths.Count == contentFiles.Count);

            //create a new content package and include the copied files in it
            contentPackage = ContentPackage.CreatePackage("ContentPackage", Path.Combine(itemEditor.Folder, MetadataFileName), false);
            for (int i = 0; i < copiedFilePaths.Count; i++)
            {
                contentPackage.AddFile(copiedFilePaths[i], contentFiles[i].Type);
            }

            contentPackage.Save(Path.Combine(stagingFolder.FullName, MetadataFileName));
        }
Example #4
0
 public void DocumentClosing(object sender, DocumentClosingEventArgs args)
 {
     try
     {
         Document doc = args.Document;
         if (null != doc)
         {
             //unregister updater
             SheetManagerConfiguration config = DataStorageUtil.GetConfiguration(doc);
             bool unregistered = UpdaterUtil.UnregisterUpdaters(doc, config);
         }
     }
     catch (Exception ex)
     {
         MessageBox.Show("Failed to unregister updater.\n" + ex.Message, "Sheet Manager : Unregister Updater", MessageBoxButton.OK, MessageBoxImage.Warning);
     }
 }
Example #5
0
 public void DocumentOpened(object sender, DocumentOpenedEventArgs args)
 {
     try
     {
         Document doc = args.Document;
         if (null != doc)
         {
             SheetManagerConfiguration config = DataStorageUtil.GetConfiguration(doc);
             if (config.AutoUpdate && !string.IsNullOrEmpty(config.DatabaseFile))
             {
                 if (File.Exists(config.DatabaseFile))
                 {
                     //register updater
                     bool registered = UpdaterUtil.RegisterUpdaters(doc, config);
                 }
             }
         }
     }
     catch (Exception ex)
     {
         MessageBox.Show("Failed to trigger the document opened event.\n" + ex.Message, "Document Opened Event", MessageBoxButton.OK, MessageBoxImage.Warning);
     }
 }
Example #6
0
        private void DownloadNextFile()
        {
            string dir = Directory.GetCurrentDirectory() + "\\UpdateFiles";

            if (filesDownloaded == filesToDownload.Count)
            {
                progressBar.Visible    = false;
                downloadButton.Visible = false;
                //updateInfoBox.Visible = false;

                updateInfoText.Text = "Installing update...";

                try
                {
                    UpdaterUtil.InstallUpdatedFiles(dir);
                }

                catch (Exception e)
                {
                    updateInfoText.Text = "Update failed";
                    ShowError("Error while installing the update", e.Message);

                    launchButton.Enabled = true;
                    return;
                }

                settings.WasGameUpdated = true;

                UpdaterUtil.CleanUnnecessaryFiles(latestVersionFiles);

                updateInfoText.Text  = "The game was updated succesfully!";
                launchButton.Enabled = true;

                //MessageBox.Show("Download completed!");
                return;
            }

            updateInfoText.Text = "Downloading file " + filesDownloaded + "/" + filesToDownloadCount;

            GUITextBlock textBlock = new GUITextBlock(
                new Rectangle(0, 0, 0, 17),
                "Downloading " + filesToDownload[filesDownloaded] + "...", "",
                Alignment.TopLeft, Alignment.TopLeft,
                updateInfoBox, false, GUI.SmallFont);

            textBlock.CanBeFocused = false;

            updateInfoBox.BarScroll = 1.0f;

            WebClient webClient = new WebClient();

            webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);

            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }

            string fileDir = dir + "\\" + Path.GetDirectoryName(filesToDownload[filesDownloaded]);

            if (!string.IsNullOrWhiteSpace(fileDir) && !Directory.Exists(fileDir))
            {
                Directory.CreateDirectory(fileDir);
            }

            webClient.DownloadFileAsync(new Uri(latestVersionFolder + filesToDownload[filesDownloaded]), @dir + "\\" + filesToDownload[filesDownloaded]);
        }
Example #7
0
        /// <summary>
        /// Disables a workshop item by removing the files from the game folder.
        /// </summary>
        public static bool DisableWorkShopItem(Workshop.Item item, out string errorMsg)
        {
            if (!item.Installed)
            {
                errorMsg = "Cannot disable workshop item \"" + item.Title + "\" because it has not been installed.";
                DebugConsole.NewMessage(errorMsg, Microsoft.Xna.Framework.Color.Red);
                return(false);
            }

            ContentPackage contentPackage = new ContentPackage(Path.Combine(item.Directory.FullName, MetadataFileName));
            string         installedContentPackagePath = GetWorkshopItemContentPackagePath(contentPackage);

            var           allPackageFiles = Directory.GetFiles(item.Directory.FullName, "*", SearchOption.AllDirectories);
            List <string> nonContentFiles = new List <string>();

            foreach (string file in allPackageFiles)
            {
                if (file == MetadataFileName)
                {
                    continue;
                }
                string relativePath = UpdaterUtil.GetRelativePath(file, item.Directory.FullName);
                string fullPath     = Path.GetFullPath(relativePath);
                if (contentPackage.Files.Any(f => { string fp = Path.GetFullPath(f.Path); return(fp == fullPath); }))
                {
                    continue;
                }
                if (ContentPackage.IsModFilePathAllowed(relativePath))
                {
                    nonContentFiles.Add(relativePath);
                }
            }
            if (File.Exists(installedContentPackagePath))
            {
                File.Delete(installedContentPackagePath);
            }

            bool wasSub = contentPackage.Files.Any(f => f.Type == ContentType.Submarine);

            HashSet <string> directories = new HashSet <string>();

            try
            {
                foreach (ContentFile contentFile in contentPackage.Files)
                {
                    if (!ContentPackage.IsModFilePathAllowed(contentFile))
                    {
                        //Workshop items are not allowed to add or modify files in the Content or Data folders;
                        continue;
                    }
                    if (!File.Exists(contentFile.Path))
                    {
                        continue;
                    }
                    File.Delete(contentFile.Path);
                    directories.Add(Path.GetDirectoryName(contentFile.Path));
                }
                foreach (string nonContentFile in nonContentFiles)
                {
                    if (!ContentPackage.IsModFilePathAllowed(nonContentFile))
                    {
                        //Workshop items are not allowed to add or modify files in the Content or Data folders;
                        continue;
                    }
                    if (!File.Exists(nonContentFile))
                    {
                        continue;
                    }
                    File.Delete(nonContentFile);
                    directories.Add(Path.GetDirectoryName(nonContentFile));
                }

                foreach (string directory in directories)
                {
                    if (string.IsNullOrWhiteSpace(directory) || !Directory.Exists(directory))
                    {
                        continue;
                    }
                    if (Directory.GetFiles(directory, "*", SearchOption.AllDirectories).Count() == 0)
                    {
                        Directory.Delete(directory, recursive: true);
                    }
                }

                ContentPackage.List.RemoveAll(cp => System.IO.Path.GetFullPath(cp.Path) == System.IO.Path.GetFullPath(installedContentPackagePath));
                GameMain.Config.SelectedContentPackages.RemoveWhere(cp => !ContentPackage.List.Contains(cp));
                GameMain.Config.SaveNewPlayerConfig();
            }
            catch (Exception e)
            {
                errorMsg = "Disabling the workshop item \"" + item.Title + "\" failed. " + e.Message;
                DebugConsole.NewMessage(errorMsg, Microsoft.Xna.Framework.Color.Red);
                return(false);
            }

            if (wasSub)
            {
                Submarine.RefreshSavedSubs();
            }

            errorMsg = "";
            return(true);
        }
Example #8
0
        /// <summary>
        /// Enables a workshop item by moving it to the game folder.
        /// </summary>
        public static bool EnableWorkShopItem(Workshop.Item item, bool allowFileOverwrite, out string errorMsg)
        {
            if (!item.Installed)
            {
                errorMsg = TextManager.GetWithVariable("WorkshopErrorInstallRequiredToEnable", "[itemname]", item.Title);
                DebugConsole.NewMessage(errorMsg, Microsoft.Xna.Framework.Color.Red);
                return(false);
            }

            string         metaDataFilePath      = Path.Combine(item.Directory.FullName, MetadataFileName);
            ContentPackage contentPackage        = new ContentPackage(metaDataFilePath);
            string         newContentPackagePath = GetWorkshopItemContentPackagePath(contentPackage);

            if (!contentPackage.IsCompatible())
            {
                errorMsg = TextManager.GetWithVariables(contentPackage.GameVersion <= new Version(0, 0, 0, 0) ? "IncompatibleContentPackageUnknownVersion" : "IncompatibleContentPackage",
                                                        new string[3] {
                    "[packagename]", "[packageversion]", "[gameversion]"
                }, new string[3] {
                    contentPackage.Name, contentPackage.GameVersion.ToString(), GameMain.Version.ToString()
                });
                return(false);
            }

            if (contentPackage.CorePackage && !contentPackage.ContainsRequiredCorePackageFiles(out List <ContentType> missingContentTypes))
            {
                errorMsg = TextManager.GetWithVariables("ContentPackageMissingCoreFiles", new string[2] {
                    "[packagename]", "[missingfiletypes]"
                },
                                                        new string[2] {
                    contentPackage.Name, string.Join(", ", missingContentTypes)
                }, new bool[2] {
                    false, true
                });
                return(false);
            }

            var           allPackageFiles = Directory.GetFiles(item.Directory.FullName, "*", SearchOption.AllDirectories);
            List <string> nonContentFiles = new List <string>();

            foreach (string file in allPackageFiles)
            {
                if (file == metaDataFilePath)
                {
                    continue;
                }
                string relativePath = UpdaterUtil.GetRelativePath(file, item.Directory.FullName);
                string fullPath     = Path.GetFullPath(relativePath);
                if (contentPackage.Files.Any(f => { string fp = Path.GetFullPath(f.Path); return(fp == fullPath); }))
                {
                    continue;
                }
                if (ContentPackage.IsModFilePathAllowed(relativePath))
                {
                    nonContentFiles.Add(relativePath);
                }
            }

            if (!allowFileOverwrite)
            {
                if (File.Exists(newContentPackagePath) && !CheckFileEquality(newContentPackagePath, metaDataFilePath))
                {
                    errorMsg = TextManager.GetWithVariables("WorkshopErrorOverwriteOnEnable", new string[2] {
                        "[itemname]", "[filename]"
                    }, new string[2] {
                        item.Title, newContentPackagePath
                    });
                    DebugConsole.NewMessage(errorMsg, Microsoft.Xna.Framework.Color.Red);
                    return(false);
                }

                foreach (ContentFile contentFile in contentPackage.Files)
                {
                    string sourceFile = Path.Combine(item.Directory.FullName, contentFile.Path);
                    if (File.Exists(sourceFile) && File.Exists(contentFile.Path) && !CheckFileEquality(sourceFile, contentFile.Path))
                    {
                        errorMsg = TextManager.GetWithVariables("WorkshopErrorOverwriteOnEnable", new string[2] {
                            "[itemname]", "[filename]"
                        }, new string[2] {
                            item.Title, contentFile.Path
                        });
                        DebugConsole.NewMessage(errorMsg, Microsoft.Xna.Framework.Color.Red);
                        return(false);
                    }
                }
            }

            try
            {
                foreach (ContentFile contentFile in contentPackage.Files)
                {
                    string sourceFile = Path.Combine(item.Directory.FullName, contentFile.Path);

                    //path not allowed -> the content file must be a reference to an external file (such as some vanilla file outside the Mods folder)
                    if (!ContentPackage.IsModFilePathAllowed(contentFile))
                    {
                        //the content package is trying to copy a file to a prohibited path, which is not allowed
                        if (File.Exists(sourceFile))
                        {
                            errorMsg = TextManager.GetWithVariable("WorkshopErrorIllegalPathOnEnable", "[filename]", contentFile.Path);
                            return(false);
                        }
                        //not trying to copy anything, so this is a reference to an external file
                        //if the external file doesn't exist, we cannot enable the package
                        else if (!File.Exists(contentFile.Path))
                        {
                            errorMsg = TextManager.GetWithVariable("WorkshopErrorEnableFailed", "[itemname]", item.Title) + " " + TextManager.GetWithVariable("WorkshopFileNotFound", "[path]", "\"" + contentFile.Path + "\"");
                            return(false);
                        }
                        continue;
                    }
                    else if (!File.Exists(sourceFile))
                    {
                        if (File.Exists(contentFile.Path))
                        {
                            //the file is already present in the game folder, all good
                            continue;
                        }
                        else
                        {
                            //file not present in either the mod or the game folder -> cannot enable the package
                            errorMsg = TextManager.GetWithVariable("WorkshopErrorEnableFailed", "[itemname]", item.Title) + " " + TextManager.GetWithVariable("WorkshopFileNotFound", "[path]", "\"" + contentFile.Path + "\"");
                            return(false);
                        }
                    }

                    //make sure the destination directory exists
                    Directory.CreateDirectory(Path.GetDirectoryName(contentFile.Path));
                    File.Copy(sourceFile, contentFile.Path, overwrite: true);
                }

                foreach (string nonContentFile in nonContentFiles)
                {
                    string sourceFile = Path.Combine(item.Directory.FullName, nonContentFile);
                    if (!File.Exists(sourceFile))
                    {
                        continue;
                    }
                    if (!ContentPackage.IsModFilePathAllowed(nonContentFile))
                    {
                        DebugConsole.ThrowError(TextManager.GetWithVariable("WorkshopErrorIllegalPathOnEnable", "[filename]", nonContentFile));
                        continue;
                    }
                    Directory.CreateDirectory(Path.GetDirectoryName(nonContentFile));
                    File.Copy(sourceFile, nonContentFile, overwrite: true);
                }
            }
            catch (Exception e)
            {
                errorMsg = TextManager.GetWithVariable("WorkshopErrorEnableFailed", "[itemname]", item.Title) + " {" + e.Message + "}";
                DebugConsole.NewMessage(errorMsg, Microsoft.Xna.Framework.Color.Red);
                return(false);
            }

            var newPackage = new ContentPackage(contentPackage.Path, newContentPackagePath)
            {
                SteamWorkshopUrl = item.Url,
                InstallTime      = item.Modified > item.Created ? item.Modified : item.Created
            };

            newPackage.Save(newContentPackagePath);
            ContentPackage.List.Add(newPackage);
            if (newPackage.CorePackage)
            {
                //if enabling a core package, disable all other core packages
                GameMain.Config.SelectedContentPackages.RemoveWhere(cp => cp.CorePackage);
            }
            GameMain.Config.SelectedContentPackages.Add(newPackage);
            GameMain.Config.SaveNewPlayerConfig();

            if (newPackage.Files.Any(f => f.Type == ContentType.Submarine))
            {
                Submarine.RefreshSavedSubs();
            }

            errorMsg = "";
            return(true);
        }
Example #9
0
        /// <summary>
        /// Enables a workshop item by moving it to the game folder.
        /// </summary>
        public static bool EnableWorkShopItem(Workshop.Item item, bool allowFileOverwrite, out string errorMsg)
        {
            if (!item.Installed)
            {
                errorMsg = TextManager.Get("WorkshopErrorInstallRequiredToEnable").Replace("[itemname]", item.Title);
                DebugConsole.NewMessage(errorMsg, Microsoft.Xna.Framework.Color.Red);
                return(false);
            }

            string         metaDataFilePath      = Path.Combine(item.Directory.FullName, MetadataFileName);
            ContentPackage contentPackage        = new ContentPackage(metaDataFilePath);
            string         newContentPackagePath = GetWorkshopItemContentPackagePath(contentPackage);

            var           allPackageFiles = Directory.GetFiles(item.Directory.FullName, "*", SearchOption.AllDirectories);
            List <string> nonContentFiles = new List <string>();

            foreach (string file in allPackageFiles)
            {
                if (file == metaDataFilePath)
                {
                    continue;
                }
                string relativePath = UpdaterUtil.GetRelativePath(file, item.Directory.FullName);
                string fullPath     = Path.GetFullPath(relativePath);
                if (contentPackage.Files.Any(f => { string fp = Path.GetFullPath(f.Path); return(fp == fullPath); }))
                {
                    continue;
                }
                if (ContentPackage.IsModFilePathAllowed(relativePath))
                {
                    nonContentFiles.Add(relativePath);
                }
            }

            if (!allowFileOverwrite)
            {
                if (File.Exists(newContentPackagePath))
                {
                    errorMsg = TextManager.Get("WorkshopErrorOverwriteOnEnable")
                               .Replace("[itemname]", item.Title)
                               .Replace("[filename]", newContentPackagePath);
                    DebugConsole.NewMessage(errorMsg, Microsoft.Xna.Framework.Color.Red);
                    return(false);
                }

                foreach (ContentFile contentFile in contentPackage.Files)
                {
                    string sourceFile = Path.Combine(item.Directory.FullName, contentFile.Path);
                    if (File.Exists(sourceFile) && File.Exists(contentFile.Path))
                    {
                        errorMsg = TextManager.Get("WorkshopErrorOverwriteOnEnable")
                                   .Replace("[itemname]", item.Title)
                                   .Replace("[filename]", contentFile.Path);
                        DebugConsole.NewMessage(errorMsg, Microsoft.Xna.Framework.Color.Red);
                        return(false);
                    }
                }
            }

            try
            {
                foreach (ContentFile contentFile in contentPackage.Files)
                {
                    string sourceFile = Path.Combine(item.Directory.FullName, contentFile.Path);
                    if (!File.Exists(sourceFile))
                    {
                        continue;
                    }
                    if (!ContentPackage.IsModFilePathAllowed(contentFile))
                    {
                        DebugConsole.ThrowError(TextManager.Get("WorkshopErrorIllegalPathOnEnable").Replace("[filename]", contentFile.Path));
                        continue;
                    }

                    //make sure the destination directory exists
                    Directory.CreateDirectory(Path.GetDirectoryName(contentFile.Path));
                    File.Copy(sourceFile, contentFile.Path, overwrite: true);
                }

                foreach (string nonContentFile in nonContentFiles)
                {
                    string sourceFile = Path.Combine(item.Directory.FullName, nonContentFile);
                    if (!File.Exists(sourceFile))
                    {
                        continue;
                    }
                    if (!ContentPackage.IsModFilePathAllowed(nonContentFile))
                    {
                        DebugConsole.ThrowError(TextManager.Get("WorkshopErrorIllegalPathOnEnable").Replace("[filename]", nonContentFile));
                        continue;
                    }
                    Directory.CreateDirectory(Path.GetDirectoryName(nonContentFile));
                    File.Copy(sourceFile, nonContentFile, overwrite: true);
                }
            }
            catch (Exception e)
            {
                errorMsg = TextManager.Get("WorkshopErrorEnableFailed").Replace("[itemname]", item.Title) + " " + e.Message;
                DebugConsole.NewMessage(errorMsg, Microsoft.Xna.Framework.Color.Red);
                return(false);
            }

            var newPackage = new ContentPackage(contentPackage.Path, newContentPackagePath)
            {
                SteamWorkshopUrl = item.Url,
                InstallTime      = item.Modified > item.Created ? item.Modified : item.Created
            };

            newPackage.Save(newContentPackagePath);
            ContentPackage.List.Add(newPackage);
            if (newPackage.CorePackage)
            {
                //if enabling a core package, disable all other core packages
                GameMain.Config.SelectedContentPackages.RemoveWhere(cp => cp.CorePackage);
            }
            GameMain.Config.SelectedContentPackages.Add(newPackage);
            GameMain.Config.SaveNewPlayerConfig();

            if (newPackage.Files.Any(f => f.Type == ContentType.Submarine))
            {
                Submarine.RefreshSavedSubs();
            }

            errorMsg = "";
            return(true);
        }
Example #10
0
        public void DocumentOpened(object sender, DocumentOpenedEventArgs args)
        {
            try
            {
                var doc = args.Document;
                if (null == doc)
                {
                    return;
                }

                var sheetConfig = new SheetManagerConfiguration(doc);
                if (doc.IsWorkshared)
                {
                    if (!ServerUtilities.GetByCentralPath(sheetConfig.CentralPath, "configurations/centralpath",
                                                          out Configuration configFound))
                    {
                        return;
                    }
                    if (null != configFound)
                    {
                        foreach (var updater in configFound.Updaters)
                        {
                            if (updater.UpdaterName != "Sheet Tracker")
                            {
                                continue;
                            }

                            sheetConfig.AutoUpdate   = updater.IsUpdaterOn;
                            sheetConfig.DatabaseFile = configFound.SheetDatabase;
                            break;
                        }
                    }
                }

                if (sheetConfig.AutoUpdate && !string.IsNullOrEmpty(sheetConfig.DatabaseFile))
                {
                    if (File.Exists(sheetConfig.DatabaseFile))
                    {
                        //update project info
                        var dbManager    = new UpdaterDataManager(sheetConfig.DatabaseFile);
                        var projects     = dbManager.GetLinkedProjects();
                        var projectFound = projects.Where(x => x.FilePath == sheetConfig.CentralPath).ToList();
                        if (projectFound.Any())
                        {
                            var linkedProject = projectFound.First();
                            sheetConfig.ModelId = linkedProject.Id;
                        }
                        else
                        {
                            var dbOpened = SheetDataWriter.OpenDatabase(sheetConfig.DatabaseFile);
                            if (dbOpened)
                            {
                                var linkedProject = new LinkedProject(sheetConfig.ModelId)
                                {
                                    FilePath      = sheetConfig.CentralPath,
                                    ProjectNumber = doc.ProjectInformation.Number,
                                    ProjectName   = doc.ProjectInformation.Name,
                                    LinkedBy      = Environment.UserName,
                                    LinkedDate    = DateTime.Now
                                };
                                SheetDataWriter.ChangeLinkedProject(linkedProject, CommandType.INSERT);
                                SheetDataWriter.CloseDatabse();
                            }
                        }

                        UpdaterUtil.RegisterUpdaters(doc, sheetConfig);
                    }
                }

                if (!configDictionary.ContainsKey(sheetConfig.CentralPath))
                {
                    configDictionary.Add(sheetConfig.CentralPath, sheetConfig);
                }
            }
            catch (Exception ex)
            {
                Log.AppendLog(LogMessageType.EXCEPTION, ex.Message);
            }
        }
        public void TestCurrentTimelineTime()
        {
            AtemMockServerWrapper.Each(_output, _pool, null, DeviceTestCases.HyperDecks, helper =>
            {
                ImmutableList <ICommand> allCommands = helper.Server.GetParsedDataDump();
                List <HyperDeckSettingsGetCommand> settingsCommands = allCommands.OfType <HyperDeckSettingsGetCommand>().ToList();
                List <HyperDeckPlayerGetCommand> playerCommands     = allCommands.OfType <HyperDeckPlayerGetCommand>().ToList();

                foreach (IBMDSwitcherHyperDeck deck in GetHyperDecks(helper))
                {
                    deck.GetId(out long id);

                    HyperDeckSettingsGetCommand cmd   = settingsCommands.Single(c => c.Id == id);
                    HyperDeckPlayerGetCommand playCmd = playerCommands.Single(c => c.Id == id);

                    // Force it to be connected
                    AtemState stateBefore = helper.Helper.BuildLibState();
                    cmd.Status            = HyperDeckConnectionStatus.Connected;
                    stateBefore.Hyperdecks[(int)id].Settings.Status = HyperDeckConnectionStatus.Connected;
                    stateBefore.Hyperdecks[(int)id].Player.State    = HyperDeckPlayerState.Idle;
                    helper.SendFromServerAndWaitForChange(stateBefore, cmd);

                    // Define a clip
                    stateBefore.Hyperdecks[(int)id].Clips =
                        UpdaterUtil.CreateList(1, i => new HyperdeckState.ClipState());
                    helper.SendFromServerAndWaitForChange(stateBefore, new HyperDeckClipCountCommand
                    {
                        Id        = (uint)id,
                        ClipCount = 1,
                    });
                    var clipCmd = new HyperDeckClipInfoCommand
                    {
                        HyperdeckId = (uint)id,
                        ClipId      = 0,
                        Name        = "something 123",
                        Duration    = new HyperDeckTime {
                            Hour = 24
                        },
                        TimelineStart = new HyperDeckTime(),
                        TimelineEnd   = new HyperDeckTime {
                            Hour = 24
                        },
                    };
                    AtemStateBuilder.Update(stateBefore, clipCmd);
                    helper.SendFromServerAndWaitForChange(stateBefore, clipCmd);
                    stateBefore = helper.Helper.BuildLibState();

                    // Set the clip to be playing
                    HyperDeckStorageGetCommand srcCmd = new HyperDeckStorageGetCommand
                    {
                        Id = (uint)id,
                        ActiveStorageMedia  = 0,
                        CurrentClipId       = 0,
                        FrameRate           = 50000,
                        TimeScale           = 1000,
                        RemainingRecordTime = new HyperDeckTime(),
                    };
                    AtemStateBuilder.Update(stateBefore, srcCmd);
                    helper.SendFromServerAndWaitForChange(stateBefore, srcCmd);
                    stateBefore = helper.Helper.BuildLibState();

                    HyperdeckState deckState = stateBefore.Hyperdecks[(int)id];

                    // Now try the stuff
                    for (int i = 0; i < 5; i++)
                    {
                        uint hours   = (uint)Randomiser.RangeInt(1, 20);
                        uint minutes = (uint)Randomiser.RangeInt(1, 59);
                        uint seconds = (uint)Randomiser.RangeInt(1, 59);
                        uint frames  = (uint)Randomiser.RangeInt(1, 20);
                        deckState.Player.ClipTime = new HyperDeckTime();
                        playCmd.TimelineTime      = deckState.Player.TimelineTime = new HyperDeckTime
                        {
                            Hour = hours, Minute = minutes, Second = seconds, Frame = frames
                        };

                        helper.SendFromServerAndWaitForChange(stateBefore, playCmd);
                    }
                }
            });
        }
        public void TestClipsInfo()
        {
            AtemMockServerWrapper.Each(_output, _pool, null, DeviceTestCases.HyperDecks, helper =>
            {
                ImmutableList <ICommand> allCommands = helper.Server.GetParsedDataDump();
                List <HyperDeckSettingsGetCommand> settingsCommands = allCommands.OfType <HyperDeckSettingsGetCommand>().ToList();

                foreach (IBMDSwitcherHyperDeck deck in GetHyperDecks(helper))
                {
                    deck.GetId(out long id);
                    HyperDeckSettingsGetCommand cmd = settingsCommands.Single(c => c.Id == id);

                    // Force it to be connected
                    AtemState stateBefore = helper.Helper.BuildLibState();
                    cmd.Status            = HyperDeckConnectionStatus.Connected;
                    stateBefore.Hyperdecks[(int)id].Settings.Status = HyperDeckConnectionStatus.Connected;
                    stateBefore.Hyperdecks[(int)id].Player.State    = HyperDeckPlayerState.Idle;
                    helper.SendFromServerAndWaitForChange(stateBefore, cmd);

                    stateBefore = helper.Helper.BuildLibState();
                    HyperdeckState hyperdeckState = stateBefore.Hyperdecks[(int)id];

                    for (int i = 0; i < 5; i++)
                    {
                        // Change the length
                        var newCmd = new HyperDeckClipCountCommand
                        {
                            Id        = (uint)id,
                            ClipCount = (uint)Randomiser.RangeInt(2, 5)
                        };
                        hyperdeckState.Clips = UpdaterUtil
                                               .CreateList(newCmd.ClipCount, o => new HyperdeckState.ClipState());

                        helper.SendFromServerAndWaitForChange(stateBefore, newCmd, -1, (sdkState, libState) =>
                        {
                            // Sdk likes to randomly give back some stale data, so lets focus on just the length
                            sdkState.Hyperdecks[(int)id].Clips = UpdaterUtil
                                                                 .CreateList((uint)sdkState.Hyperdecks[(int)id].Clips.Count,
                                                                             o => new HyperdeckState.ClipState());
                        });

                        // Now fill in some clip info
                        var infoCmd = new HyperDeckClipInfoCommand
                        {
                            HyperdeckId = (uint)id,
                            ClipId      = 1,
                            Name        = Randomiser.String(64),

                            TimelineStart = new HyperDeckTime
                            {
                                Hour   = (uint)Randomiser.RangeInt(2, 8),
                                Minute = (uint)Randomiser.RangeInt(2, 50),
                                Second = (uint)Randomiser.RangeInt(2, 50),
                                Frame  = (uint)Randomiser.RangeInt(2, 50),
                            },

                            TimelineEnd = new HyperDeckTime
                            {
                                Hour   = (uint)Randomiser.RangeInt(4, 18),
                                Minute = (uint)Randomiser.RangeInt(2, 50),
                                Second = (uint)Randomiser.RangeInt(2, 50),
                                Frame  = (uint)Randomiser.RangeInt(2, 50),
                            },

                            Duration = new HyperDeckTime
                            {
                                Hour   = (uint)Randomiser.RangeInt(10, 20),
                                Minute = (uint)Randomiser.RangeInt(2, 50),
                                Second = (uint)Randomiser.RangeInt(2, 50),
                                Frame  = (uint)Randomiser.RangeInt(2, 50),
                            },
                        };
                        hyperdeckState.Clips[(int)infoCmd.ClipId].Name          = infoCmd.Name;
                        hyperdeckState.Clips[(int)infoCmd.ClipId].Duration      = infoCmd.Duration;
                        hyperdeckState.Clips[(int)infoCmd.ClipId].TimelineStart = infoCmd.TimelineStart;
                        hyperdeckState.Clips[(int)infoCmd.ClipId].TimelineEnd   = infoCmd.TimelineEnd;

                        helper.SendFromServerAndWaitForChange(stateBefore, infoCmd);
                    }
                }
            });
        }