public Dictionary <string, object> CreateDisk(string name, Dictionary <WorkspacePath, WorkspacePath> files, WorkspacePath dest, int maxFileSize = 512) { var fileLoader = new WorkspaceFileLoadHelper(workspace); dest = workspace.UniqueFilePath(dest.AppendDirectory("Build")).AppendPath(name + ".pv8"); var diskExporter = new DiskExporter(dest.Path, fileLoader, files, maxFileSize); if (((DesktopRunner)runner).ExportService is GameDataExportService exportService) { exportService.Clear(); exportService.AddExporter(diskExporter); exportService.StartExport(); // Update the response diskExporter.Response["success"] = true; diskExporter.Response["message"] = "A new build was created in " + dest + "."; diskExporter.Response["path"] = dest.Path; } else { diskExporter.Response["success"] = false; diskExporter.Response["message"] = "Couldn't find the service to save a disk."; } return(diskExporter.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); }