void DoFileList( WorkspaceInfo wkInfo, List <string> paths, IAssetStatusCache assetStatusCache, MetaCache metaCache) { mFileListScrollPosition = GUILayout.BeginScrollView( mFileListScrollPosition, EditorStyles.helpBox, GUILayout.ExpandHeight(true)); foreach (string path in paths) { if (MetaPath.IsMetaPath(path)) { continue; } Texture fileIcon = Directory.Exists(path) ? Images.GetDirectoryIcon() : Images.GetFileIcon(path); string label = WorkspacePath.GetWorkspaceRelativePath( wkInfo.ClientPath, path); if (metaCache.HasMeta(path)) { label = string.Concat(label, UnityConstants.TREEVIEW_META_LABEL); } GUIContent content = new GUIContent( label, fileIcon); GUILayout.Label( content, GUILayout.Height(UnityConstants.TREEVIEW_ROW_HEIGHT)); Rect iconRect = GUILayoutUtility.GetLastRect(); DoStatusOverlays( iconRect, assetStatusCache, path); } GUILayout.EndScrollView(); }
// Exports the active song in the music chip public void ExportSong(string path, MusicChip musicChip, SoundChip soundChip, int id) { var currentSong = musicChip.songs[id]; var selectedPatterns = new int[currentSong.end]; Array.Copy(currentSong.patterns, selectedPatterns, selectedPatterns.Length); var filePath = WorkspacePath.Parse(path); if (Exists(filePath)) { filePath = filePath.AppendDirectory("Wavs").AppendDirectory("Songs"); if (!Exists(filePath)) { CreateDirectory(filePath); } try { filePath = UniqueFilePath(filePath.AppendFile("song " + id + " - " + currentSong.name + ".wav")); Console.WriteLine("Export song to " + filePath); // TODO exporting sprites doesn't work if (locator.GetService(typeof(ExportService).FullName) is ExportService exportService) { exportService.ExportSong(filePath.Path, musicChip, soundChip, selectedPatterns); // exportService.StartExport(); } } catch (Exception e) { // TODO this needs to go through the error system? Console.WriteLine(e); throw; } // TODO saving song doesn't work // runner.exportService.ExportSong(filePath.Path, musicChip, soundChip); // // runner.StartExport(); } }
static Texture GetIcon( string wkPath, IncomingChangeInfo incomingChange) { bool isDirectory = incomingChange.GetRevision(). Type == EnumRevisionType.enDirectory; if (isDirectory || incomingChange.IsXLink()) { return(Images.GetDirectoryIcon()); } string fullPath = WorkspacePath.GetWorkspacePathFromCmPath( wkPath, incomingChange.GetPath(), Path.DirectorySeparatorChar); return(Images.GetFileIcon(fullPath)); }
public void PlayWav(WorkspacePath workspacePath) { if (workspace.Exists(workspacePath) && workspacePath.GetExtension() == ".wav") { if (currentSound != null) { StopWav(); } using (var stream = workspace.OpenFile(workspacePath, FileAccess.Read)) { currentSound = SoundEffect.FromStream(stream).CreateInstance(); } currentSound.Play(); } }
public Image ReadImage(WorkspacePath src, string maskHex = "#ff00ff", string[] colorRefs = null) { PNGReader reader = null; using (var memoryStream = new MemoryStream()) { using (var fileStream = workspace.OpenFile(src, FileAccess.Read)) { fileStream.CopyTo(memoryStream); fileStream.Close(); } reader = new PNGReader(memoryStream.ToArray(), maskHex); } var tmpColorChip = new ColorChip(); var imageParser = new SpriteImageParser(reader, tmpColorChip); // Manually call each step imageParser.ParseImageData(); // If no colors are passed in, used the image's palette if (colorRefs == null) { colorRefs = reader.colorPalette.Select(c => ColorUtils.RgbToHex(c.R, c.G, c.B)).ToArray(); } // Resize the color chip tmpColorChip.total = colorRefs.Length; // Add the colors for (int i = 0; i < colorRefs.Length; i++) { tmpColorChip.UpdateColorAt(i, colorRefs[i]); } // Parse the image with the new colors imageParser.CreateImage(); // Return the new image from the parser return(imageParser.image); }
public override async Task ExecuteAsync(IOperationExecutionContext context) { string repositoryUrl = await this.GetRepositoryUrlAsync().ConfigureAwait(false); string branchDesc = string.IsNullOrEmpty(this.Branch) ? "" : $" on '{this.Branch}' branch"; string tagDesc = string.IsNullOrEmpty(this.Tag) ? "" : $" tagged '{this.Tag}'"; this.LogInformation($"Getting source from '{repositoryUrl}'{branchDesc}{tagDesc}..."); var workspacePath = WorkspacePath.Resolve(context, repositoryUrl, this.WorkspaceDiskPath); if (this.CleanWorkspace) { this.LogDebug($"Clearing workspace path '{workspacePath.FullPath}'..."); var fileOps = context.Agent.GetService <IFileOperationsExecuter>(); await fileOps.ClearDirectoryAsync(workspacePath.FullPath).ConfigureAwait(false); } var client = this.CreateClient(context, repositoryUrl, workspacePath); bool valid = await client.IsRepositoryValidAsync().ConfigureAwait(false); if (!valid) { await client.CloneAsync( new GitCloneOptions { Branch = this.Branch, RecurseSubmodules = this.RecurseSubmodules } ).ConfigureAwait(false); } await client.UpdateAsync( new GitUpdateOptions { RecurseSubmodules = this.RecurseSubmodules, Branch = this.Branch, Tag = this.Tag } ).ConfigureAwait(false); await client.ArchiveAsync(context.ResolvePath(this.DiskPath)).ConfigureAwait(false); this.LogInformation("Get source complete."); }
public void RemoveDisk(WorkspacePath path) { if (Exists(path)) { // Check to see if this is a zip SaveDisk(path); // Remove disk from the mount point Mounts.Remove(Get(path)); if (_disks.Contains(path)) { _disks.Remove(path); } // // InvalidateDisks(); } }
public string DiskPhysicalRoot(WorkspacePath disk) { var physicalPath = ""; if (Exists(disk)) { if (Get(disk).Value is PhysicalFileSystem fileSystem) { physicalPath = fileSystem.PhysicalRoot; } else if (Get(disk).Value is ZipFileSystem system) { physicalPath = system.PhysicalRoot; } } return(physicalPath); }
public bool WriteAccess(WorkspacePath path) { var canWrite = false; try { // We need to make sure we have a directory to write to var filePath = path.IsDirectory ? path : path.ParentPath; // Make sure the directory exists first if (Exists(filePath)) { try { // Create a unique folder path name var uniqueFolderPath = filePath.AppendDirectory(DateTime.Now.ToString("yyyyMMddHHmmssfff")); // Create the unique folder CreateDirectory(uniqueFolderPath); // If we don't throw an error (which is caught above) we have written to the directory canWrite = true; // Delete the folder we just created Delete(uniqueFolderPath); } catch { // runner.DisplayWarning("'"+path+"' does not have write access"); // Can't write a file } } } catch { // Console.WriteLine("Workspace Write Error:\n"+e.Message); // Console.WriteLine(e); // throw; } return(canWrite); }
public bool ValidateGameInDir(WorkspacePath filePath) { if (!Exists(filePath)) { return(false); } var flag = 0; foreach (var file in requiredFiles) { if (Exists(filePath.AppendFile(file))) { flag++; } } return(flag == requiredFiles.Count); }
internal static void AsFullyChecked(WorkspaceInfo wkInfo) { string rootPath = WorkspacePath.GetWorkspacePathFromCmPath( wkInfo.ClientPath, "/", Path.DirectorySeparatorChar); WorkspaceTreeNode rootWkNode = CmConnection.Get().GetWorkspaceTreeHandler(). WkGetWorkspaceTreeNode(rootPath); FullyCheckedDirectory rootDirectory = new FullyCheckedDirectory(); rootDirectory.MountId = MountPointId.WORKSPACE_ROOT; rootDirectory.ItemId = rootWkNode.RevInfo.ItemId; List <FullyCheckedDirectory> directoryList = new List <FullyCheckedDirectory>(); directoryList.Add(rootDirectory); FullyCheckedDirectoriesStorage.Save(wkInfo, directoryList); }
public void AddDisk(WorkspacePath path, IFileSystem disk) { // If we are out of open disks, remove the last one if (TotalDisks == MaxDisks) { RemoveDisk(Disks.Last()); } // Attempt to remove the disk if it is already inserted RemoveDisk(path); // Add the new disk to the disk mount Mounts.Add(new KeyValuePair <WorkspacePath, IFileSystem>(path, disk)); if (!_disks.Contains(path)) { _disks.Add(path); } // InvalidateDisks(); }
public override async Task ExecuteAsync(IOperationExecutionContext context) { string repositoryUrl = await this.GetRepositoryUrlAsync(context.CancellationToken).ConfigureAwait(false); if (string.IsNullOrEmpty(repositoryUrl)) { this.LogError("RepositoryUrl is not specified. It must be included in either the referenced credential or in the RepositoryUrl argument of the operation."); return; } string branchDesc = string.IsNullOrEmpty(this.Branch) ? "" : $" on '{this.Branch}' branch"; this.LogInformation($"Tag '{repositoryUrl}'{branchDesc} as '{this.Tag}'..."); var client = this.CreateClient(context, repositoryUrl, WorkspacePath.Resolve(context, repositoryUrl, this.WorkspaceDiskPath)); bool valid = await client.IsRepositoryValidAsync().ConfigureAwait(false); if (!valid) { await client.CloneAsync( new GitCloneOptions { Branch = this.Branch, RecurseSubmodules = this.RecurseSubmodules } ).ConfigureAwait(false); } await client.UpdateAsync( new GitUpdateOptions { RecurseSubmodules = this.RecurseSubmodules, Branch = this.Branch, Ref = this.CommitHash } ).ConfigureAwait(false); await client.TagAsync(this.Tag, this.CommitHash, this.TagMessage, this.Force).ConfigureAwait(false); this.LogInformation("Tag complete."); }
// Make sure you can only eject a disk by forcing the path to be in the disk mounts scope public void EjectDisk(WorkspacePath filePath) { RemoveDisk(filePath); // What happens when there are no disks if (TotalDisks > 1) { try { // Get the next disk name var diskName = Disks.First().Path.Replace("/", ""); // Attempt to run the fist disk AutoRunGameFromDisk(diskName); } catch { // ignored } } }
public string ReadTextFromFile(WorkspacePath filePath) { // var filePath = FileSystemPath.Parse(path); if (Exists(filePath)) { var text = ""; using (var file = OpenFile(filePath, FileAccess.Read)) { text = file.ReadAllText(); file.Close(); file.Dispose(); } return(text); //file.ReadAllText(); } // Always return an empty string if no file was found return(""); }
public string[] SplitFileName(WorkspacePath filePath) { var split = filePath.EntityName.Split('.').ToList(); var results = new string[2]; results[0] = split[0]; split.RemoveAt(0); if (filePath.IsFile) { results[1] = "." + string.Join(".", split); } else { results[1] = ""; } return(results); }
void DoFileList( WorkspaceInfo wkInfo, List <string> paths, IAssetStatusCache assetStatusCache, MetaCache metaCache) { mFileListScrollPosition = GUILayout.BeginScrollView( mFileListScrollPosition, EditorStyles.helpBox, GUILayout.ExpandHeight(true)); foreach (string path in paths) { if (MetaPath.IsMetaPath(path)) { continue; } Texture fileIcon = Directory.Exists(path) ? Images.GetDirectoryIcon() : Images.GetFileIcon(path); string label = WorkspacePath.GetWorkspaceRelativePath( wkInfo.ClientPath, path); if (metaCache.HasMeta(path)) { label = string.Concat(label, UnityConstants.TREEVIEW_META_LABEL); } AssetsOverlays.AssetStatus assetStatus = assetStatusCache.GetStatusForPath(path); Rect selectionRect = EditorGUILayout.GetControlRect(); DoListViewItem(selectionRect, fileIcon, label, assetStatus); } GUILayout.EndScrollView(); }
public bool SaveTextToFile(WorkspacePath filePath, string text, bool autoCreate = false) { if (Exists(filePath)) { Delete(filePath); } // TODO need to look into how to clear the bytes before writing to it? var file = CreateFile(filePath); if (file != null) { var bytes = Encoding.ASCII.GetBytes(text); file.Write(bytes); file.Close(); return(true); } return(false); }
private string BuildFullDataSourceName() { // Some odd data sources (i.e. raster functions) can have XML in the various names if (DataSourceName != null && DataSourceName.StartsWith("<Xml") && DataSourceName.Contains("FunctionRasterDatasetName")) { return("XML Raster Function Defintion"); } //Still protect against other fields with illegal paths if (DataSourceName == null || DataSourceName.StartsWith("<")) { return(null); } if (WorkspacePath == null || WorkspacePath.StartsWith("<")) { return(DataSourceName); } if (Container == null || Container.StartsWith("<")) { return(Path.Combine(WorkspacePath, DataSourceName)); } return(Path.Combine(WorkspacePath, Container, DataSourceName)); }
internal static Dictionary <string, LockStatusData> ForLocks( string wkPath, Dictionary <WorkspaceTreeNode, LockInfo> lockInfoByNode) { Dictionary <string, LockStatusData> result = BuildPathDictionary.ForPlatform <LockStatusData>(); LockOwnerNameResolver nameResolver = new LockOwnerNameResolver(); foreach (WorkspaceTreeNode node in lockInfoByNode.Keys) { LockStatusData lockStatusData = BuildLockStatusData( node, lockInfoByNode[node], nameResolver); string nodeWkPath = WorkspacePath.GetWorkspacePathFromCmPath( wkPath, WorkspaceNodeOperations.GetCmPath(node), PathHelper.GetDirectorySeparatorChar(wkPath)); result.Add(nodeWkPath, lockStatusData); } return(result); }
public Dictionary <string, object> CreateExe(string name, WorkspacePath[] files, WorkspacePath template, WorkspacePath exportPath, string[] libFileNames = null) { var response = new Dictionary <string, object> { { "success", false }, { "message", "" } }; // var buildFilePath = template.ParentPath.AppendFile("build.json"); // // if (workspace.Exists(buildFilePath)) // { // var buildText = ""; // // using (var file = workspace.OpenFile(buildFilePath, FileAccess.Read)) // { // buildText = file.ReadAllText(); // file.Close(); // file.Dispose(); // } var platform = template.EntityName.Split(' ')[1].Split('.')[0]; var contentPath = platform == "Mac" ? name + ".app/Contents/Resources/Content/DefaultGame/" : "Content/DefaultGame/"; // Make sure the source is a pv8 file if (workspace.Exists(template) && template.GetExtension() == ".pvr") { workspace.CreateDirectoryRecursive(exportPath); exportPath = exportPath.AppendFile(name + ".zip"); // Remove platform from name name = name.Split(' ')[0]; using (Stream fsIn = workspace.OpenFile(template, FileAccess.Read)) using (var zfIn = new ZipFile(fsIn)) { using (Stream fsOut = workspace.CreateFile(exportPath)) { using (var zfOut = new ZipOutputStream(fsOut)) { // Copy over all of the contents of the template to a new Zip file foreach (ZipEntry zipEntry in zfIn) { if (!zipEntry.IsFile) { // Ignore directories continue; } var entryFileName = zipEntry.Name; if (!entryFileName.Contains(contentPath)) { Stream fsInput = null; long size = 0; // Check to see if there is a bios file if (entryFileName.EndsWith("bios.json")) { // Create a reader from a new copy of the zipEntry StreamReader reader = new StreamReader(zfIn.GetInputStream(zipEntry)); // Read out all of the text var text = reader.ReadToEnd(); // // Replace the base directory with the game name and no spaces text = text.Replace(@"GameRunner", name.Replace(" " + platform, " ").Replace(" ", "")); text = text.Replace(@"PV8 Game Runner", name.Replace(" " + platform, "")); // Create a new memory stream in place of the zip file entry fsInput = new MemoryStream(); // Wrap the stream in a writer var writer = new StreamWriter(fsInput); // Write the text to the stream writer.Write(text); // Flush the stream and set it back to the begining writer.Flush(); fsInput.Seek(0, SeekOrigin.Begin); // Get the size so we know how big it is later on size = fsInput.Length; } // Clean up path for mac builds if (platform == "Mac") { if (entryFileName.StartsWith("Runner.app")) { // We rename the default Runner.app path to the game name to rename everything in the exe entryFileName = entryFileName.Replace("Runner.app", name + ".app"); } } else { // fsInput = new MemoryStream(); // We need to look for the launch script if (entryFileName == "Pixel Vision 8 Runner") { // Create a reader from a new copy of the zipEntry StreamReader reader = new StreamReader(zfIn.GetInputStream(zipEntry)); // Read out all of the text string text = reader.ReadToEnd(); // // Replace the default name with the game name text = text.Replace(@"Pixel\ Vision\ 8\ Runner", name.Replace(" ", @"\ ")); // Create a new memory stream in place of the zip file entry fsInput = new MemoryStream(); // Wrap the stream in a writer var writer = new StreamWriter(fsInput); // Write the text to the stream writer.Write(text); // Flush the stream and set it back to the begining writer.Flush(); fsInput.Seek(0, SeekOrigin.Begin); // Get the size so we know how big it is later on size = fsInput.Length; } // Rename all the executibale files in the linux build entryFileName = entryFileName.Replace("Pixel Vision 8 Runner", name); } // Check to see if we have a stream if (fsInput == null) { // Get a stream from the current zip entry fsInput = zfIn.GetInputStream(zipEntry); size = zipEntry.Size; } using (fsInput) { ZipEntry newEntry = new ZipEntry(entryFileName) { DateTime = DateTime.Now, Size = size }; zfOut.PutNextEntry(newEntry); var buffer = new byte[4096]; StreamUtils.Copy(fsInput, zfOut, buffer); fsInput.Close(); zfOut.CloseEntry(); } } } // Copy over all of the game files var list = from p in files where workspace.fileExtensions.Any(val => p.EntityName.EndsWith(val)) select p; // Readjust the content path contentPath = platform == "Mac" ? name + ".app/Contents/Resources/Content/DefaultGame/" : "Content/DefaultGame/"; foreach (var file in list) { var entryFileName = contentPath + file.EntityName; using (var fileStream = workspace.OpenFile(file, FileAccess.Read)) { var newEntry = new ZipEntry(entryFileName) { DateTime = DateTime.Now, Size = fileStream.Length }; zfOut.PutNextEntry(newEntry); var buffer = new byte[4096]; StreamUtils.Copy(fileStream, zfOut, buffer); zfOut.CloseEntry(); fileStream.Close(); } } // Copy over all of the library files if (libFileNames != null) { var libFileData = new Dictionary <string, byte[]>(); workspace.IncludeLibDirectoryFiles(libFileData); var total = libFileNames.Length; for (int i = 0; i < total; i++) { var fileName = libFileNames[i] + ".lua"; if (libFileData.ContainsKey(fileName)) { var entryFileName = contentPath + fileName; using (var fileStream = new MemoryStream(libFileData[fileName])) { var newEntry = new ZipEntry(entryFileName) { DateTime = DateTime.Now, Size = fileStream.Length }; zfOut.PutNextEntry(newEntry); var buffer = new byte[4096]; StreamUtils.Copy(fileStream, zfOut, buffer); zfOut.CloseEntry(); fileStream.Close(); } } } } } } } // } } return(response); }
public Dictionary <string, object> CreateDisk(string gameName, WorkspacePath[] filePaths, WorkspacePath exportPath, int maxFileSize = 512, string[] libFileNames = null) { var response = new Dictionary <string, object> { { "success", false }, { "message", "" } }; try { // Create a path to the temp directory for the builds var tmpExportPath = WorkspacePath.Root.AppendDirectory("Tmp").AppendDirectory("Builds"); // Make sure there is a builds folder in the Tmp directory if (workspace.Exists(tmpExportPath) == false) { workspace.CreateDirectory(tmpExportPath); } // Create a folder with the timestamp tmpExportPath = tmpExportPath.AppendDirectory(DateTime.Now.ToString("yyyyMMddHHmmss")); workspace.CreateDirectory(tmpExportPath); // Add the zip filename to it var tmpZipPath = tmpExportPath.AppendFile(gameName + ".pv8"); // 'using' statements guarantee the stream is closed properly which is a big source // of problems otherwise. Its exception safe as well which is great. using (var OutputStream = new ZipOutputStream(workspace.CreateFile(tmpZipPath))) { // Define the compression level // 0 - store only to 9 - means best compression OutputStream.SetLevel(4); var buffer = new byte[4096]; foreach (var file in filePaths) { if (file.IsFile) { // Using GetFileName makes the result compatible with XP // as the resulting path is not absolute. var entry = new ZipEntry(file.EntityName) { DateTime = DateTime.Now }; // Setup the entry data as required. // Crc and size are handled by the library for seakable streams // so no need to do them here. // Could also use the last write time or similar for the file. OutputStream.PutNextEntry(entry); using (var fs = workspace.OpenFile(file, FileAccess.Read) as FileStream) { // Using a fixed size buffer here makes no noticeable difference for output // but keeps a lid on memory usage. int sourceBytes; do { sourceBytes = fs.Read(buffer, 0, buffer.Length); OutputStream.Write(buffer, 0, sourceBytes); } while (sourceBytes > 0); } } } // Copy all the lib files if (libFileNames != null) { var libFileData = new Dictionary <string, byte[]>(); workspace.IncludeLibDirectoryFiles(libFileData); var total = libFileNames.Length; for (var i = 0; i < total; i++) { var fileName = libFileNames[i] + ".lua"; if (libFileData.ContainsKey(fileName)) { // var tmpPath = fileName; var entry = new ZipEntry(fileName); OutputStream.PutNextEntry(entry); using (Stream fs = new MemoryStream(libFileData[fileName])) { // Using a fixed size buffer here makes no noticeable difference for output // but keeps a lid on memory usage. int sourceBytes; do { sourceBytes = fs.Read(buffer, 0, buffer.Length); OutputStream.Write(buffer, 0, sourceBytes); } while (sourceBytes > 0); } } } } // Copy the file to the right location var fileSize = OutputStream.Length / 1024; response.Add("fileSize", fileSize); // Finish is important to ensure trailing information for a Zip file is appended. Without this // the created file would be invalid. OutputStream.Finish(); // Close is important to wrap things up and unlock the file. OutputStream.Close(); // Console.WriteLine("FileSize " + fileSize); if (fileSize > maxFileSize) { response["message"] = "The game is too big to compile. You'll need to reduce the file size or increase the game size to create a new build."; return(response); } // Move the new build over exportPath = workspace.UniqueFilePath(exportPath.AppendDirectory("Build")); // workspace.CreateDirectory(exportPath); workspace.CreateDirectoryRecursive(exportPath); exportPath = exportPath.AppendFile(tmpZipPath.EntityName); workspace.Copy(tmpZipPath, exportPath); response["success"] = true; response["message"] = "A new build was created in " + exportPath + "."; response["path"] = exportPath.Path; } } catch (Exception ex) { // No need to rethrow the exception as for our purposes its handled. response["message"] = "Unable to create a build for " + gameName + " " + ex; // Console.WriteLine("Exception during processing {0}", ex); } return(response); }
public bool SaveTextToFile(string filePath, string text, bool autoCreate = false) { var path = WorkspacePath.Parse(filePath); return(workspace.SaveTextToFile(path, text, autoCreate)); }
/// <summary> /// This will read a text file from a valid workspace path and return it as a string. This can read .txt, .json and /// .lua files. /// </summary> /// <param name="path">A valid workspace path.</param> /// <returns>Returns the contents of the file as a string.</returns> public string ReadTextFile(string path) { var filePath = WorkspacePath.Parse(path); return(workspace.ReadTextFromFile(filePath)); }
/// <summary> /// Helper function to create a new text file. /// </summary> /// <param name="dest"></param> /// <param name="defaultText"></param> public void SaveText(WorkspacePath dest, string defaultText = "") { workspace.SaveTextToFile(dest, defaultText, true); }
public string ReadText(WorkspacePath src) { return(workspace.ReadTextFromFile(src)); }
public Dictionary <string, object> ReadJson(WorkspacePath src) { var text = ReadText(src); return(Json.Deserialize(text) as Dictionary <string, object>); }
private void UserControl_Loaded(object sender, RoutedEventArgs e) { WorkspacePath.Focus(); }
public ZipDiskExporter(string fileName, WorkspaceService workspaceService) : base(fileName) { diskPath = WorkspacePath.Parse(fileName); this.workspaceService = workspaceService; this.FileLoadHelper = new WorkspaceFileLoadHelper(this.workspaceService); }
public string AutoRunGameFromDisk(string diskName) { var diskPath = WorkspacePath.Root.AppendDirectory("Disks") .AppendDirectory(diskName); var autoRunPath = diskPath.AppendFile("info.json"); // Try to read the disk's info file and see if there is an auto run path try { // Only run a disk if there is an auto run file in there if (Exists(autoRunPath)) { var json = ReadTextFromFile(autoRunPath); var autoRunData = Json.Deserialize(json) as Dictionary <string, object>; var tmpPath = autoRunData["AutoRun"] as string; // Get the auto run from the json file var newDiskPath = WorkspacePath.Parse($"/Disks/{diskName}{tmpPath}"); // Change the disk path to the one in the auto-run file if (Exists(newDiskPath)) { diskPath = newDiskPath; } } } catch { // ignored } // Always validate that the disk is a valid game before trying to load it. if (ValidateGameInDir(diskPath)) { // TODO need to make sure the auto run disk is at the top of the list // Move the new disk to the top of the list var diskPaths = new List <string>(); // Add the remaining disks foreach (var disk in Disks) { diskPaths.Add(DiskPhysicalRoot(disk)); } // Remove the old disks EjectAll(); // Mount all the disks foreach (var oldPath in diskPaths) { MountDisk(oldPath); } return(diskPath.Path); } return(null); }