public void ExportPattern(WorkspacePath filePath, MusicChip musicChip, SoundChip soundChip, int id) { var selectedPatterns = new int[id]; if (!Exists(filePath)) { CreateDirectory(filePath); } try { filePath = UniqueFilePath(filePath.AppendFile("pattern+" + id + ".wav")); // 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; } }
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); }
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); }