public ContentPackage(string filePath, string setPath = "")
            : this()
        {
            filePath = filePath.CleanUpPath();
            if (!string.IsNullOrEmpty(setPath))
            {
                setPath = setPath.CleanUpPath();
            }
            XDocument doc = XMLExtensions.TryLoadXml(filePath);

            Path = setPath == string.Empty ? filePath : setPath;

            if (doc?.Root == null)
            {
                DebugConsole.ThrowError("Couldn't load content package \"" + filePath + "\"!");
                IsCorrupt = true;
                return;
            }

            Name = doc.Root.GetAttributeString("name", "");
            HideInWorkshopMenu = doc.Root.GetAttributeBool("hideinworkshopmenu", false);
            isCorePackage      = doc.Root.GetAttributeBool("corepackage", false);
            SteamWorkshopId    = doc.Root.GetAttributeUInt64("steamworkshopid", 0);
            string workshopUrl = doc.Root.GetAttributeString("steamworkshopurl", "");

            if (!string.IsNullOrEmpty(workshopUrl))
            {
                SteamWorkshopId = SteamManager.GetWorkshopItemIDFromUrl(workshopUrl);
            }
            string versionStr = doc.Root.GetAttributeString("gameversion", "0.0.0.0");

            try
            {
                GameVersion = new Version(versionStr);
            }
            catch
            {
                DebugConsole.ThrowError($"Invalid version number in content package \"{Name}\" ({versionStr}).");
                GameVersion = GameMain.Version;
            }
            if (doc.Root.Attribute("installtime") != null)
            {
                InstallTime = ToolBox.Epoch.ToDateTime(doc.Root.GetAttributeUInt("installtime", 0));
            }

            List <string> errorMsgs = new List <string>();

            foreach (XElement subElement in doc.Root.Elements())
            {
                if (subElement.Name.ToString().Equals("executable", StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }
                if (!Enum.TryParse(subElement.Name.ToString(), true, out ContentType type))
                {
                    errorMsgs.Add("Error in content package \"" + Name + "\" - \"" + subElement.Name.ToString() + "\" is not a valid content type.");
                    type = ContentType.None;
                }
                files.Add(new ContentFile(subElement.GetAttributeString("file", ""), type, this));
            }

            if (Files.Count == 0)
            {
                //no files defined, find a submarine in here
                //because somehow people have managed to upload
                //mods without contentfile definitions
                string folder = System.IO.Path.GetDirectoryName(filePath);
                if (File.Exists(System.IO.Path.Combine(folder, Name + ".sub")))
                {
                    files.Add(new ContentFile(System.IO.Path.Combine(folder, Name + ".sub"), ContentType.Submarine, this));
                }
                else
                {
                    errorMsgs.Add("Error in content package \"" + Name + "\" - no content files defined.");
                }
            }

            bool compatible = IsCompatible();

            //If we know that the package is not compatible, don't display error messages.
            if (compatible)
            {
                foreach (string errorMsg in errorMsgs)
                {
                    DebugConsole.ThrowError(errorMsg);
                }
            }
        }