예제 #1
0
        /// <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;
        }
예제 #2
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;
 }
예제 #3
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 (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;
        }