コード例 #1
0
ファイル: Addon.cs プロジェクト: whisperity/SharpGMad
        /// <summary>
        /// Initializes a new content file using pure content as storage.
        /// </summary>
        /// <param name="path">The path of the file WITHIN the addon.</param>
        /// <param name="content">The array of bytes containing the already set content.</param>
        public ContentFile(string path, byte[] content)
        {
            Storage = ContentStorageType.Filesystem;
            Path    = path;

            ExternalFile = new FileStream(ContentFile.GenerateExternalPath(path), FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None);

            Content = content;
        }
コード例 #2
0
        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 (gboConvertMetadata.Visible == 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 (gboConvertMetadata.Visible == true)
            {
                // Load the addon metadata from the old file structure: info.txt/addon.txt
                if (!File.Exists(txtFolder.Text + Path.DirectorySeparatorChar + "info.txt") &&
                    !File.Exists(txtFolder.Text + Path.DirectorySeparatorChar + "addon.txt"))
                {
                    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 = String.Empty;;
                try
                {
                    if (File.Exists(txtFolder.Text + Path.DirectorySeparatorChar + "info.txt"))
                    {
                        legacyInfo = File.ReadAllText(txtFolder.Text + Path.DirectorySeparatorChar + "info.txt");
                    }
                    else if (File.Exists(txtFolder.Text + Path.DirectorySeparatorChar + "addon.txt"))
                    {
                        legacyInfo = File.ReadAllText(txtFolder.Text + Path.DirectorySeparatorChar + "addon.txt");
                    }
                }
                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]*)\"[\\s]*\"([\\s\\S]*?)\"",
                                                                       RegexOptions.IgnoreCase | RegexOptions.Multiline);
                MatchCollection matches = regex.Matches(legacyInfo);

                // info.txt/addon.txt files usually have these values not directly mapped into GMAs as well.
                string AuthorName  = String.Empty;
                string AuthorEmail = String.Empty;
                string AuthorURL   = String.Empty;
                string Version     = String.Empty;
                string Date        = String.Empty;

                foreach (Match keyMatch in matches)
                {
                    if (keyMatch.Groups.Count == 3)
                    {
                        // All match should have 2 groups matched (the 0th group is the whole match.)
                        switch (keyMatch.Groups[1].Value.ToLowerInvariant())
                        {
                        case "name":
                            addon.Title = keyMatch.Groups[2].Value;
                            break;

                        case "version":
                            Version = keyMatch.Groups[2].Value;
                            break;

                        case "up_date":
                            Date = keyMatch.Groups[2].Value;
                            break;

                        case "author_name":
                            //addon.Author = keyMatch.Groups[2].Value;
                            // GMAD writer only writes "Author Name" right now...
                            AuthorName = keyMatch.Groups[2].Value;
                            break;

                        case "author_email":
                            AuthorEmail = keyMatch.Groups[2].Value;
                            break;

                        case "author_url":
                            AuthorURL = keyMatch.Groups[2].Value;
                            break;

                        case "info":
                            addon.Description = keyMatch.Groups[2].Value;
                            break;
                        }
                    }
                }

                // Prettify the loaded Description.
                string newDescription    = String.Empty;
                bool   hasNewDescription = (!String.IsNullOrWhiteSpace(AuthorName) || !String.IsNullOrWhiteSpace(AuthorEmail) ||
                                            !String.IsNullOrWhiteSpace(AuthorURL) || !String.IsNullOrWhiteSpace(Version) ||
                                            !String.IsNullOrWhiteSpace(Date));

                if (hasNewDescription)
                {
                    newDescription = "## Converted by SharpGMad " + Program.PrettyVersion + " at " +
                                     DateTime.Now.ToString("ddd MM dd hh:mm:ss yyyy",
                                                           System.Globalization.CultureInfo.InvariantCulture) +
                                     " (+" + TimeZoneInfo.Local.BaseUtcOffset.ToString("hhmm") + ")";
                }

                if (!String.IsNullOrWhiteSpace(AuthorName))
                {
                    newDescription += "\n# AuthorName: " + AuthorName;
                }

                if (!String.IsNullOrWhiteSpace(AuthorEmail))
                {
                    newDescription += "\n# AuthorEmail: " + AuthorEmail;
                }

                if (!String.IsNullOrWhiteSpace(AuthorURL))
                {
                    newDescription += "\n# AuthorURL: " + AuthorURL;
                }

                if (!String.IsNullOrWhiteSpace(Version))
                {
                    newDescription += "\n# Version: " + Version;
                }

                if (!String.IsNullOrWhiteSpace(Date))
                {
                    newDescription += "\n# Date: " + Date;
                }

                if (hasNewDescription)
                {
                    // If anything was added to the prettifiction
                    newDescription   += "\n## End conversion info";
                    addon.Description = newDescription +
                                        (!String.IsNullOrWhiteSpace(addon.Description) ? Environment.NewLine + addon.Description : null);
                }

                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('\\', '/');

                if (file == "addon.json" || file == "info.txt")
                {
                    continue; // Don't read the metadata file
                }
                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 created the addon.", "Create addon",
                                MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else if (errors.Count == 1)
            {
                MessageBox.Show("Successfully created the addon.\nThe file " + errors[0].Path + " was not added " +
                                "because " + errors[0].Type, "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;
        }
コード例 #3
0
ファイル: LegacyExtract.cs プロジェクト: whisperity/SharpGMad
        private void btnExtract_Click(object sender, EventArgs e)
        {
            List <string> extractFailures = new List <string>();

            //
            // If an out path hasn't been provided, make our own
            //
            if (txtFolder.Text == String.Empty)
            {
                txtFolder.Text = Path.GetFileNameWithoutExtension(txtFile.Text);
            }

            //
            // Remove slash, add slash (enforces a slash)
            //
            txtFolder.Text = txtFolder.Text.TrimEnd('/');
            txtFolder.Text = txtFolder.Text + '/';
            Addon addon;

            try
            {
                FileStream fs = new FileStream(txtFile.Text, FileMode.Open, FileAccess.ReadWrite);
                addon = new Addon(new Reader(fs));
            }
            catch (Exception ex)
            {
                MessageBox.Show("Can't open the selected file.\nError happened: " + ex.Message,
                                "Failed to extract addon", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                return;
            }

            foreach (ContentFile entry in addon.Files)
            {
                // Make sure folder exists
                try
                {
                    Directory.CreateDirectory(txtFolder.Text + Path.GetDirectoryName(entry.Path));
                }
                catch (Exception)
                {
                    // Noop
                }
                // Write the file to the disk
                try
                {
                    using (FileStream file = new FileStream(txtFolder.Text + entry.Path, FileMode.Create, FileAccess.Write))
                    {
                        file.Write(entry.Content, 0, (int)entry.Size);
                    }
                }
                catch (Exception)
                {
                    extractFailures.Add(entry.Path);
                }
            }

            if (chkWriteLegacy.Checked) // Write a legacy info.txt schema
            {
                // The description has paramteres if the addon was created by a conversion.
                // Extract them out.

                Regex regex = new System.Text.RegularExpressions.Regex("^# ([\\s\\S]*?): ([\\s\\S]*?)$",
                                                                       RegexOptions.IgnoreCase | RegexOptions.Multiline);
                MatchCollection matches = regex.Matches(addon.Description);

                // info.txt/addon.txt files usually have these values not directly mapped into GMAs as well.
                string AuthorName  = String.Empty;
                string AuthorEmail = String.Empty;
                string AuthorURL   = String.Empty;
                string Version     = String.Empty;
                string Date        = String.Empty;

                foreach (Match keyMatch in matches)
                {
                    if (keyMatch.Groups.Count == 3)
                    {
                        // All match should have 2 groups matched (the 0th group is the whole match.)
                        switch (keyMatch.Groups[1].Value.ToLowerInvariant())
                        {
                        case "version":
                            Version = keyMatch.Groups[2].Value.TrimEnd('\n', '\r', '\t');
                            break;

                        case "date":
                            Date = keyMatch.Groups[2].Value.TrimEnd('\n', '\r', '\t');
                            break;

                        case "authorname":
                            AuthorName = keyMatch.Groups[2].Value.TrimEnd('\n', '\r', '\t');
                            break;

                        case "authoremail":
                            AuthorEmail = keyMatch.Groups[2].Value.TrimEnd('\n', '\r', '\t');
                            break;

                        case "authorurl":
                            AuthorURL = keyMatch.Groups[2].Value.TrimEnd('\n', '\r', '\t');
                            break;
                        }
                    }
                }

                string endConversionInfo = "## End conversion info";
                string description       = addon.Description;
                if (addon.Description.IndexOf(endConversionInfo) > 0)
                {
                    description = addon.Description.Substring(addon.Description.IndexOf(endConversionInfo) +
                                                              endConversionInfo.Length);
                    description = description.TrimStart('\r', '\n');
                }

                File.WriteAllText(txtFolder.Text + Path.DirectorySeparatorChar + "info.txt", "\"AddonInfo\"\n" +
                                  "{\n" +
                                  "\t" + "\"name\"" + "\t" + "\"" + addon.Title + "\"\n" +
                                  "\t" + "\"version\"" + "\t" + "\"" + Version + "\"\n" +
                                  "\t" + "\"up_date\"" + "\t" + "\"" + (String.IsNullOrWhiteSpace(Date) ?
                                                                        addon.Timestamp.ToString("ddd MM dd hh:mm:ss yyyy", System.Globalization.CultureInfo.InvariantCulture) :
                                                                        DateTime.Now.ToString("ddd MM dd hh:mm:ss yyyy", System.Globalization.CultureInfo.InvariantCulture) +
                                                                        " (+" + TimeZoneInfo.Local.BaseUtcOffset.ToString("hhmm") + ")") + "\"\n" +
                                  "\t" + "\"author_name\"" + "\t" + "\"" + AuthorName + "\"\n" + // addon.Author would be nice
                                  "\t" + "\"author_email\"" + "\t" + "\"" + AuthorEmail + "\"\n" +
                                  "\t" + "\"author_url\"" + "\t" + "\"" + AuthorURL + "\"\n" +
                                  "\t" + "\"info\"" + "\t" + "\"" + description + "\"\n" +
                                  "\t" + "\"override\"" + "\t" + "\"1\"\n" +
                                  "}");
            }

            if (extractFailures.Count == 0)
            {
                MessageBox.Show("Successfully extracted the addon.", "Extract addon",
                                MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else if (extractFailures.Count == 1)
            {
                MessageBox.Show("Failed to extract " + extractFailures[0], "Extract addon",
                                MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            else if (extractFailures.Count > 1)
            {
                DialogResult showFailedFiles = MessageBox.Show(extractFailures.Count + " files failed to extract." +
                                                               "\n\nShow a list of failures?", "Extract addon", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);

                if (showFailedFiles == DialogResult.Yes)
                {
                    string temppath = ContentFile.GenerateExternalPath(
                        new Random().Next() + "_failedExtracts") + ".txt";

                    try
                    {
                        File.WriteAllText(temppath,
                                          "These files failed to extract:\r\n\r\n" +
                                          String.Join("\r\n", extractFailures.ToArray()));
                    }
                    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,
                    });
                }
            }

            btnAbort_Click(sender, e); // Close the form
            return;
        }