/// <summary> /// Legacy GMAD operation to create an addon file using contents of a specified folder. /// </summary> /// <param name="strFolder">The folder containing the raw content.</param> /// <param name="strOutfile">The path of the addon file to write.</param> /// <param name="warnInvalid">Whether there should be a warning for files failing to validate /// instead of a full exception halt.</param> /// <returns>Integer error code: 0 if success, 1 if error.</returns> static int CreateAddonFile(string strFolder, string strOutfile, bool warnInvalid, bool gmod12convert = false) { // // Make sure there's a slash on the end // strFolder = strFolder.TrimEnd('/'); strFolder = strFolder + "/"; // // Make sure OutFile ends in .gma // strOutfile = Path.GetFileNameWithoutExtension(strOutfile); strOutfile += ".gma"; Console.WriteLine("Looking in folder \"" + strFolder + "\""); Addon addon = null; if (!gmod12convert) { // // Load the Addon Info file // Json addonInfo; try { addonInfo = new Json(strFolder + "addon.json"); } catch (AddonJSONException ex) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(strFolder + "addon.json error: " + ex.Message); Console.ResetColor(); return 1; } addon = new Addon(addonInfo); } else if (gmod12convert) { // Load the addon metadata from the old file structure: info.txt or addon.txt. string legacyInfoFile; if (File.Exists(strFolder + "\\info.txt")) legacyInfoFile = "info.txt"; else if (File.Exists(strFolder + "\\addon.txt")) legacyInfoFile = "addon.txt"; else { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Failed to find legacy addon metadata file \"info.txt\" or \"addon.txt\""); Console.ResetColor(); return 1; } string legacyInfo; try { legacyInfo = File.ReadAllText(strFolder + Path.DirectorySeparatorChar + legacyInfoFile); } catch (Exception ex) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Failed to read metadata."); Console.ResetColor(); Console.WriteLine(ex.Message); return 1; } addon = new Addon(); // Parse the read data Regex regex = new System.Text.RegularExpressions.Regex("\"([A-Za-z_\r\n])*\"", RegexOptions.IgnoreCase); MatchCollection matches = regex.Matches(legacyInfo); foreach (Match keyMatch in matches) { if (keyMatch.Value.ToLowerInvariant() == "\"name\"") addon.Title = keyMatch.NextMatch().Value; else if (keyMatch.Value.ToLowerInvariant() == "\"info\"") addon.Description = keyMatch.NextMatch().Value; else if (keyMatch.Value.ToLowerInvariant() == "\"author_name\"") addon.Author = keyMatch.NextMatch().Value; // Current GMAD writer only writes "Author Name", not real value } Console.WriteLine(addon.Title + " by " + addon.Author); Console.WriteLine("You need to set the title, and optionally, the tags for this addon!"); SetType(addon); SetTags(addon); } // // Get a list of files in the specified folder // foreach (string f in Directory.GetFiles(strFolder, "*", SearchOption.AllDirectories)) { string file = f; file = file.Replace(strFolder, String.Empty); file = file.Replace('\\', '/'); Console.WriteLine("\t" + file); try { addon.CheckRestrictions(file); addon.AddFile(file, File.ReadAllBytes(f)); } catch (IOException) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Unable to read file " + file); Console.ResetColor(); continue; } catch (IgnoredException) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("\t\t[Ignored]"); Console.ResetColor(); continue; } catch (WhitelistException) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("\t\t[Not allowed by whitelist]"); Console.ResetColor(); if (!warnInvalid) return 1; } } // // Sort the list into alphabetical order, no real reason - we're just ODC // addon.Sort(); // // Create an addon file in a buffer // // // Save the buffer to the provided name // FileStream fs; try { fs = new FileStream(strOutfile, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None); } catch (Exception) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Couldn't save to file \"" + strOutfile + "\""); Console.ResetColor(); return 1; } fs.SetLength(0); try { Writer.Create(addon, fs); } catch (Exception) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Failed to create the addon."); Console.ResetColor(); return 1; } fs.Flush(); // // Success! // Console.WriteLine("Successfully saved to \"" + strOutfile + "\" [" + ((int)fs.Length).HumanReadableSize() + "]"); fs.Dispose(); return 0; }
/// <summary> /// Sets up a new instance of Addon using the metadata provided from the specified JSON. /// </summary> /// <param name="addonJson">The JSON instance containing the metadata to use.</param> public Addon(Json addonJson) : this() { Title = addonJson.Title; Description = addonJson.Description; Type = addonJson.Type; Tags = new List<string>(addonJson.Tags); Ignores = new List<string>(addonJson.Ignores); FormatVersion = Addon.Version; SteamID = (ulong)0; AddonVersion = (int)1; Timestamp = DateTime.Now; }
private void btnCreate_Click(object sender, EventArgs e) { if (cmbTag1.SelectedItem == cmbTag2.SelectedItem && !(cmbTag1.SelectedItem.ToString() == "(empty)" && cmbTag2.SelectedItem.ToString() == "(empty)")) { MessageBox.Show("You selected the same tag twice!", "Update metadata", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); return; } List<CreateError> errors = new List<CreateError>(); // // Make sure there's a slash on the end // txtFolder.Text = txtFolder.Text.TrimEnd('/'); txtFolder.Text = txtFolder.Text + "/"; // // Make sure OutFile ends in .gma // txtFile.Text = Path.GetFileNameWithoutExtension(txtFile.Text); txtFile.Text += ".gma"; Addon addon = null; if (chkConvertNeeded.Checked == false) { // // Load the Addon Info file // Json addonInfo; try { addonInfo = new Json(txtFolder.Text + "addon.json"); } catch (AddonJSONException ex) { MessageBox.Show(ex.Message, "addon.json parse error", MessageBoxButtons.OK, MessageBoxIcon.Stop); return; } addon = new Addon(addonInfo); } else if (chkConvertNeeded.Checked == true) { // Load the addon metadata from the old file structure: info.txt or addon.txt. string legacyInfoFile; if (File.Exists(txtFolder.Text + "\\info.txt")) legacyInfoFile = "info.txt"; else if (File.Exists(txtFolder.Text + "\\addon.txt")) legacyInfoFile = "addon.txt"; else { MessageBox.Show("A legacy metadata file \"info.txt\" or \"addon.txt\" could not be found!", "Failed to create the addon", MessageBoxButtons.OK, MessageBoxIcon.Stop); return; } string legacyInfo; try { legacyInfo = File.ReadAllText(txtFolder.Text + Path.DirectorySeparatorChar + legacyInfoFile); } catch (Exception ex) { MessageBox.Show("There was an error reading the metadata.\n\n" + ex.Message, "Failed to create the addon", MessageBoxButtons.OK, MessageBoxIcon.Stop); return; } addon = new Addon(); // Parse the read data Regex regex = new System.Text.RegularExpressions.Regex("\"([A-Za-z_\r\n])*\"", RegexOptions.IgnoreCase); MatchCollection matches = regex.Matches(legacyInfo); foreach (Match keyMatch in matches) { if (keyMatch.Value.ToLowerInvariant() == "\"name\"") addon.Title = keyMatch.NextMatch().Value; else if (keyMatch.Value.ToLowerInvariant() == "\"info\"") addon.Description = keyMatch.NextMatch().Value; else if (keyMatch.Value.ToLowerInvariant() == "\"author_name\"") addon.Author = keyMatch.NextMatch().Value; // Current GMAD writer only writes "Author Name", not real value } if (cmbType.SelectedItem != null && Tags.TypeExists(cmbType.SelectedItem.ToString())) addon.Type = cmbType.SelectedItem.ToString(); else { // This should not happen in normal operation // nontheless we check against it MessageBox.Show("The selected type is invalid!", "Update metadata", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); return; } if (((cmbTag1.SelectedItem.ToString() != "(empty)") && !Tags.TagExists(cmbTag1.SelectedItem.ToString())) || ((cmbTag2.SelectedItem.ToString() != "(empty)") && !Tags.TagExists(cmbTag2.SelectedItem.ToString()))) { // This should not happen in normal operation // nontheless we check against it MessageBox.Show("The selected tags are invalid!", "Update metadata", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); return; } addon.Tags = new List<string>(2); if (cmbTag1.SelectedItem.ToString() != "(empty)") addon.Tags.Add(cmbTag1.SelectedItem.ToString()); if (cmbTag2.SelectedItem.ToString() != "(empty)") addon.Tags.Add(cmbTag2.SelectedItem.ToString()); } // // Get a list of files in the specified folder // foreach (string f in Directory.GetFiles(txtFolder.Text, "*", SearchOption.AllDirectories)) { string file = f; file = file.Replace(txtFolder.Text, String.Empty); file = file.Replace('\\', '/'); try { addon.CheckRestrictions(file); addon.AddFile(file, File.ReadAllBytes(f)); } catch (IOException) { errors.Add(new CreateError() { Path = file, Type = CreateErrorType.FileRead }); continue; } catch (IgnoredException) { errors.Add(new CreateError() { Path = file, Type = CreateErrorType.Ignored }); continue; } catch (WhitelistException) { errors.Add(new CreateError() { Path = file, Type = CreateErrorType.WhitelistFailure }); if (!chkWarnInvalid.Checked) { MessageBox.Show("The following file is not allowed by the whitelist:\n" + file, "Failed to create the addon", MessageBoxButtons.OK, MessageBoxIcon.Stop); return; } } } // // Sort the list into alphabetical order, no real reason - we're just ODC // addon.Sort(); // // Create an addon file in a buffer // // // Save the buffer to the provided name // FileStream gmaFS; try { gmaFS = new FileStream(txtFile.Text, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None); gmaFS.SetLength(0); // Truncate the file Writer.Create(addon, gmaFS); } catch (Exception be) { MessageBox.Show("An exception happened while compiling the addon.\n\n" + be.Message, "Failed to create the addon", MessageBoxButtons.OK, MessageBoxIcon.Stop); return; } gmaFS.Flush(); // // Success! // if (errors.Count == 0) MessageBox.Show("Successfully extracted the addon.", "Create addon", MessageBoxButtons.OK, MessageBoxIcon.Information); else if (errors.Count == 1) MessageBox.Show("Successfully created the addon.\nThe file " + errors[0] + " was not added.", "Create addon", MessageBoxButtons.OK, MessageBoxIcon.Warning); else if (errors.Count > 1) { DialogResult showFailedFiles = MessageBox.Show(errors.Count + " files failed to add." + "\n\nShow a list of failures?", "Create addon", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); if (showFailedFiles == DialogResult.Yes) { string temppath = ContentFile.GenerateExternalPath( new Random().Next() + "_failedCreations") + ".txt"; string msgboxMessage = String.Empty; foreach (CreateError err in errors) { msgboxMessage += err.Path + ", "; switch (err.Type) { case CreateErrorType.FileRead: msgboxMessage += "failed to read the file"; break; case CreateErrorType.Ignored: msgboxMessage += "the file is ignored by the addon's configuration"; break; case CreateErrorType.WhitelistFailure: msgboxMessage += "the file is not allowed by the global whitelist"; break; } msgboxMessage += "\r\n"; } msgboxMessage = msgboxMessage.TrimEnd('\r', '\n'); try { File.WriteAllText(temppath, "These files failed to add:\r\n\r\n" + msgboxMessage); } catch (Exception) { MessageBox.Show("Can't show the list, an error happened generating it.", "Extract addon", MessageBoxButtons.OK, MessageBoxIcon.Stop); return; } // The file will be opened by the user's default text file handler (Notepad?) System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(temppath) { UseShellExecute = true, }); } } gmaFS.Dispose(); btnAbort_Click(sender, e); // Close the form return; }