Exemple #1
0
        internal void UpdateMod(ModEntry m, Settings settings)
        {
            // Check if mod directory exists
            if (!Directory.Exists(m.Path))
            {
                Log.Warn($"Hiding mod {m.ID} because the directory {m.Path} no longer exists.");
                m.AddState(ModState.NotInstalled);
                m.AddState(ModState.NotLoaded);
                m.isHidden = true;
                return;
            }

            // Check if in ModPaths
            if (!settings.ModPaths.Any(modPath => m.IsInModPath(modPath)))
            {
                Log.Warn($"The mod {m.ID} is not located in any of the configured mod directories -> ModState.NotLoaded");
                m.AddState(ModState.NotLoaded);
            }

            // Update Source
            if (m.Source == ModSource.Unknown)
            {
                if (m.Path.IndexOf(@"\SteamApps\workshop\", StringComparison.OrdinalIgnoreCase) != -1)
                {
                    m.SetSource(ModSource.SteamWorkshop);
                }
                else
                {
                    // in workshop path but not loaded via steam
                    m.SetSource(ModSource.Manual);
                }

                Log.Info("Updated unknown mod source to " + m.Source);
            }

            // Ensure source ID exists
            if (m.WorkshopID <= 0)
            {
                if (m.Source == ModSource.SteamWorkshop && long.TryParse(Path.GetFileName(m.Path), out var sourceID))
                {
                    m.WorkshopID = sourceID;
                }
                else
                {
                    m.WorkshopID = new ModInfo(m.GetModInfoFile()).PublishedFileID;
                }

                if (m.WorkshopID > 0)
                {
                    Log.Info("Updated uninitialized WorkShop Id to " + m.WorkshopID);
                }
            }

            // Fill Date Added
            if (!m.DateAdded.HasValue)
            {
                m.DateAdded = DateTime.Now;
            }

            SteamUGCDetails_t workshopDetails = new SteamUGCDetails_t();

            // Check Workshop for infos
            if (m.WorkshopID != 0)
            {
                workshopDetails = Workshop.GetDetails((ulong)m.WorkshopID, string.IsNullOrEmpty(m.Description));
            }

            if (workshopDetails.m_eResult == EResult.k_EResultOK)
            {
                Log.Debug("Processing Workshop details for " + m.ID);

                if (!m.ManualName)
                {
                    m.Name = workshopDetails.m_rgchTitle;
                }

                m.DateCreated = DateTimeOffset.FromUnixTimeSeconds(workshopDetails.m_rtimeCreated).DateTime;
                m.DateUpdated = DateTimeOffset.FromUnixTimeSeconds(workshopDetails.m_rtimeUpdated).DateTime;

                if (workshopDetails.m_rtimeAddedToUserList > 0)
                {
                    m.DateAdded = DateTimeOffset.FromUnixTimeSeconds(workshopDetails.m_rtimeAddedToUserList).DateTime;
                }

                //m.Author = SteamWorkshop.GetUsername(value.m_ulSteamIDOwner);
                //MessageBox.Show(m.Author);

                // Update directory size
                m.RealizeSize(workshopDetails.m_nFileSize);
                if (m.Size < 0)
                {
                    m.RealizeSize(Directory.EnumerateFiles(m.Path, "*", SearchOption.AllDirectories).Sum(fileName => new FileInfo(fileName).Length));
                }

                if (string.IsNullOrEmpty(m.Description))
                {
                    m.Description = workshopDetails.m_rgchDescription;
                }

                if (workshopDetails.m_ulSteamIDOwner > 0)
                {
                    string newAuthorName = Workshop.GetUsername(workshopDetails.m_ulSteamIDOwner);

                    // Getusername() sometimes returns null, an empty string or "[unknown]".
                    // We do not want to overwrite a potentially already correct author name in that case.
                    if (!string.IsNullOrEmpty(newAuthorName) && newAuthorName != "[unknown]")
                    {
                        m.Author = newAuthorName;
                    }
                }

                // Check Workshop for updates
                if (m.Source == ModSource.SteamWorkshop)
                {
                    if (Workshop.GetDownloadStatus((ulong)m.WorkshopID).HasFlag(EItemState.k_EItemStateNeedsUpdate))
                    {
                        Log.Info("Update available for " + m.ID);
                        m.AddState(ModState.UpdateAvailable);
                    }
                }

                // Check if it is built for WOTC
                try
                {
                    // Parse .XComMod file
                    var modInfo = new ModInfo(m.GetModInfoFile());
                    m.SetRequiresWOTC(modInfo.RequiresXPACK);
                }
                catch (InvalidOperationException ex)
                {
                    Log.Error("Failed parsing XComMod file for " + m.ID, ex);
                    SentrySdk.CaptureException(ex);
                    Debug.Fail(ex.Message);
                }
            }
            else
            {
                Log.Debug("Processing local information for " + m.ID);

                m.DateCreated = Directory.GetCreationTime(m.Path);
                m.DateUpdated = Directory.GetLastWriteTime(m.Path);

                // Update directory size
                // slow, but necessary ?
                m.RealizeSize(Directory.EnumerateFiles(m.Path, "*", SearchOption.AllDirectories).Sum(fileName => new FileInfo(fileName).Length));

                // Update Name and Description
                // look for .XComMod file
                try
                {
                    // Parse .XComMod file
                    var modInfo = new ModInfo(m.GetModInfoFile());

                    if (!m.ManualName || m.Name == "")
                    {
                        m.Name = modInfo.Title;
                    }

                    m.Description = modInfo.Description;
                    m.SetRequiresWOTC(modInfo.RequiresXPACK);
                }
                catch (InvalidOperationException ex)
                {
                    Log.Error("Failed parsing XComMod file for " + m.ID, ex);
                    SentrySdk.CaptureException(ex);
                    Debug.Fail(ex.Message);
                }
            }
        }
Exemple #2
0
 public string GetCategory(ModEntry mod)
 {
     return(Entries.First(entry => entry.Value.Entries.Contains(mod)).Key);
 }
Exemple #3
0
        internal void UpdateMod(ModEntry m, Settings settings)
        {
            // Check if in ModPaths
            if (!settings.ModPaths.Any(modPath => m.IsInModPath(modPath)))
            {
                m.State |= ModState.NotLoaded;
            }

            // Update Source
            if (m.Source == ModSource.Unknown)
            {
                if (m.Path.IndexOf(@"\SteamApps\workshop\", StringComparison.OrdinalIgnoreCase) != -1)
                {
                    m.Source = ModSource.SteamWorkshop;
                }

                else
                {
                    // in workshop path but not loaded via steam
                    m.Source = ModSource.Manual;
                }
            }

            // Ensure source ID exists
            if (m.WorkshopID <= 0)
            {
                long sourceID;

                if (m.Source == ModSource.SteamWorkshop && long.TryParse(Path.GetFileName(m.Path), out sourceID))
                {
                    m.Source = ModSource.Manual;
                }

                else
                {
                    sourceID = new ModInfo(m.GetModInfoFile()).PublishedFileID;
                }

                m.WorkshopID = sourceID;
            }

            // Fill Date Added
            if (!m.DateAdded.HasValue)
            {
                m.DateAdded = DateTime.Now;
            }


            // Check Workshop for infos
            if (m.WorkshopID != 0)
            {
                var publishedID = (ulong)m.WorkshopID;

                var value = Workshop.GetDetails(publishedID);

                if (!m.ManualName)
                {
                    m.Name = value.m_rgchTitle;
                }

                m.DateCreated = DateTimeOffset.FromUnixTimeSeconds(value.m_rtimeCreated).DateTime;
                m.DateUpdated = DateTimeOffset.FromUnixTimeSeconds(value.m_rtimeUpdated).DateTime;

                if (value.m_rtimeAddedToUserList > 0)
                {
                    m.DateAdded = DateTimeOffset.FromUnixTimeSeconds(value.m_rtimeAddedToUserList).DateTime;
                }

                //m.Author = SteamWorkshop.GetUsername(value.m_ulSteamIDOwner);
                //MessageBox.Show(m.Author);

                // Update directory size
                m.Size = value.m_nFileSize;
                if (m.Size < 0)
                {
                    m.Size = Directory.EnumerateFiles(m.Path, "*", SearchOption.AllDirectories).Sum(fileName => new FileInfo(fileName).Length);
                }

                // Check Workshop for updates
                if (m.Source == ModSource.SteamWorkshop)
                {
                    if (
                        Workshop.GetDownloadStatus((ulong)m.WorkshopID)
                        .HasFlag(EItemState.k_EItemStateNeedsUpdate))
                    {
                        m.State |= ModState.UpdateAvailable;
                    }
                }
            }
            else
            {
                // Update directory size
                // slow, but necessary ?
                m.Size = Directory.EnumerateFiles(m.Path, "*", SearchOption.AllDirectories).Sum(fileName => new FileInfo(fileName).Length);
            }
        }
Exemple #4
0
        public ModEntry Import(string modDir, ModSource source = ModSource.Unknown)
        {
            // Check if Mod already loaded
            if (FindByPath(modDir) != null)
            {
                return(null);
            }

            // look for .XComMod file
            string infoFile = FindModInfo(modDir);

            if (infoFile == null)
            {
                return(null);
            }

            var modID = Path.GetFileNameWithoutExtension(infoFile);

            // Parse .XComMod file
            var modinfo = new ModInfo(infoFile);

            var mod = new ModEntry
            {
                Name      = modinfo.Title ?? "Unnamed Mod",
                ID        = modID,
                Path      = modDir,
                isActive  = false,
                DateAdded = DateTime.Now
            };

            mod.AddState(ModState.New);
            mod.SetRequiresWOTC(modinfo.RequiresXPACK);
            mod.SetSource(source);

            if (source == ModSource.SteamWorkshop)
            {
                // for Workshop mods, the folder name represents the Workshop-Id
                var s = modDir.Split(Path.DirectorySeparatorChar).Last();

                if (long.TryParse(s, out var workShopId))
                {
                    mod.WorkshopID = workShopId;
                }
                else
                {
                    Log.Error($"Unable to parse WorkShop-Id ({s}) from Steam mod directory " + modDir);
                    MessageBox.Show("A mod could not be loaded because the workshop ID failed to parse." +
                                    $"\nPlease check that the following directory conforms to valid workshop numbering.\n\nPath: {modDir}");
                    return(null);
                }
            }
            else if (source == ModSource.Manual)
            {
                // for mods from a custom mod path with custom folder names, we check if the XComMod file contains a Workshop-Id (i.e. publishedfileid)
                mod.WorkshopID = modinfo.PublishedFileID;
            }

            AddMod(modinfo.Category, mod);

            return(mod);
        }
Exemple #5
0
        public ModEntry Import(string modDir, ModSource source = ModSource.Unknown)
        {
            if (FindByPath(modDir) != null)
            {
                // Mod already loaded
                return(null);
            }

            // look for .XComMod file
            string infoFile;

            try
            {
                infoFile = Directory.GetFiles(modDir, "*.XComMod", SearchOption.TopDirectoryOnly).SingleOrDefault();
            }
            catch (InvalidOperationException)
            {
                MessageBox.Show(
                    $"A mod could not be loaded since it contains multiple .xcommod files\r\nPlease notify the mod creator.\r\n\r\nPath: {modDir}");
                return(null);
            }

            if (infoFile == null)
            {
                return(null);
            }

            var modID  = Path.GetFileNameWithoutExtension(infoFile);
            var isDupe = All.Any(m => m.ID == modID && string.Compare(m.Path, modDir, StringComparison.OrdinalIgnoreCase) == 0);

            // Parse .XComMod file
            var modinfo = new ModInfo(infoFile);

            var mod = new ModEntry
            {
                ID        = modID,
                Name      = modinfo.Title ?? "Unnamed Mod",
                Path      = modDir,
                Source    = source,
                isActive  = false,
                DateAdded = DateTime.Now,
                State     = ModState.New
            };

            if (source == ModSource.SteamWorkshop)
            {
                var s = modDir.Split(Path.DirectorySeparatorChar).Last();
                try
                {
                    mod.WorkshopID = Convert.ToInt64(s);
                }
                catch (Exception)
                {
                    MessageBox.Show(
                        $"A mod could not be loaded because the workshop ID failed to parse.\r\nPlease check that the following directory conforms to valid workshop numbering.\r\n\r\nPath: {modDir}");
                    return(null);
                }
            }

            AddMod(modinfo.Category, mod);

            // mark dupes
            if (isDupe)
            {
                foreach (var m in All.Where(m => m.ID == modID))
                {
                    m.State |= ModState.DuplicateID;
                }
            }

            return(mod);
        }
Exemple #6
0
        public void RemoveMod(ModEntry mod)
        {
            var category = GetCategory(mod);

            this[category].Entries.Remove(mod);
        }
Exemple #7
0
        void UpdateSteamMod(ModEntry m, SteamUGCDetails_t workshopDetails)
        {
            if (m == null || m.WorkshopID <= 0)
            {
                return;
            }

            if (workshopDetails.m_eResult != EResult.k_EResultOK)
            {
                return;
            }

            Log.Debug("Processing Workshop details for " + m.ID);

            if (!m.ManualName)
            {
                m.Name = workshopDetails.m_rgchTitle;
            }

            m.DateCreated = DateTimeOffset.FromUnixTimeSeconds(workshopDetails.m_rtimeCreated).DateTime;
            m.DateUpdated = DateTimeOffset.FromUnixTimeSeconds(workshopDetails.m_rtimeUpdated).DateTime;

            if (workshopDetails.m_rtimeAddedToUserList > 0)
            {
                m.DateAdded = DateTimeOffset.FromUnixTimeSeconds(workshopDetails.m_rtimeAddedToUserList).DateTime;
            }

            // Update directory size
            m.RealizeSize(workshopDetails.m_nFileSize);
            if (m.Size < 0)
            {
                m.RealizeSize(Directory.EnumerateFiles(m.Path, "*", SearchOption.AllDirectories).Sum(fileName => new FileInfo(fileName).Length));
            }

            if (string.IsNullOrEmpty(m.Description))
            {
                m.Description = workshopDetails.m_rgchDescription;
            }

            // Request mod author name if necessary.
            if (string.IsNullOrEmpty(m.Author) || m.Author == ModEntry.DEFAULT_AUTHOR_NAME)
            {
                if (workshopDetails.m_ulSteamIDOwner > 0)
                {
                    string newAuthorName = Workshop.GetUsername(workshopDetails.m_ulSteamIDOwner);

                    // Getusername() sometimes returns null, an empty string or "[unknown]".
                    // We do not want to overwrite a potentially already correct author name in that case.
                    if (!string.IsNullOrEmpty(newAuthorName) && newAuthorName != "[unknown]")
                    {
                        m.Author = newAuthorName;
                    }
                }
            }

            // We buffer the Steam tags so we do nor require another full UGC workshop request when the user chooses to use them.
            m.SteamTags = workshopDetails.m_rgchTags.Split(',').Select(s => s.TrimStart(' ').TrimEnd(' ')).Where(s => !string.IsNullOrWhiteSpace(s)).ToList();

            // If the mod has dependencies, request the workshop id's of those mods.
            if (workshopDetails.m_unNumChildren > 0)
            {
                var dependencies = Workshop.GetDependencies(workshopDetails);

                if (dependencies != null)
                {
                    m.Dependencies.Clear();
                    m.Dependencies.AddRange(dependencies.ConvertAll(val => (long)val));
                }
                else
                {
                    Log.Warn($"Dependency request for {m.WorkshopID} failed.");
                }
            }

            // Check Workshop for updates
            if (Workshop.GetDownloadStatus((ulong)m.WorkshopID).HasFlag(EItemState.k_EItemStateNeedsUpdate))
            {
                Log.Info("Update available for " + m.ID);
                m.AddState(ModState.UpdateAvailable);
            }

            // Check if it is built for WOTC
            try
            {
                // Parse .XComMod file
                var modInfo = new ModInfo(m.GetModInfoFile());
                m.SetRequiresWOTC(modInfo.RequiresXPACK);
            }
            catch (InvalidOperationException ex)
            {
                Log.Error("Failed parsing XComMod file for " + m.ID, ex);
                Debug.Fail(ex.Message);
            }
        }
Exemple #8
0
        bool VerifyModState(ModEntry m, Settings settings)
        {
            // Check if mod directory exists
            if (!Directory.Exists(m.Path))
            {
                Log.Warn($"Hiding mod {m.ID} because the directory {m.Path} no longer exists.");
                m.AddState(ModState.NotInstalled);
                m.AddState(ModState.NotLoaded);
                m.isHidden = true;
                return(false);
            }

            // Check if in ModPaths
            if (!settings.ModPaths.Any(m.IsInModPath))
            {
                Log.Warn($"The mod {m.ID} is not located in any of the configured mod directories -> ModState.NotLoaded");
                m.AddState(ModState.NotLoaded);
            }

            // Update Source
            if (m.Source == ModSource.Unknown)
            {
                if (m.Path.IndexOf(@"\SteamApps\workshop\", StringComparison.OrdinalIgnoreCase) != -1)
                {
                    m.SetSource(ModSource.SteamWorkshop);
                }
                else
                {
                    // in workshop path but not loaded via steam
                    m.SetSource(ModSource.Manual);
                }

                Log.Info("Updated unknown mod source to " + m.Source);
            }

            // Ensure source ID exists
            if (m.WorkshopID <= 0)
            {
                if (m.Source == ModSource.SteamWorkshop && long.TryParse(Path.GetFileName(m.Path), out var sourceID))
                {
                    m.WorkshopID = sourceID;
                }
                else
                {
                    m.WorkshopID = new ModInfo(m.GetModInfoFile()).PublishedFileID;
                }

                if (m.WorkshopID > 0)
                {
                    Log.Info("Updated uninitialized WorkShop Id to " + m.WorkshopID);
                }
            }

            // Fill Date Added
            if (!m.DateAdded.HasValue)
            {
                m.DateAdded = DateTime.Now;
            }

            return(true);
        }
Exemple #9
0
 public async void UpdateModAsync(ModEntry m, Settings settings)
 {
     await UpdateModsAsync(new List <ModEntry> {
         m
     }, settings);
 }
Exemple #10
0
        internal void UpdateMod(ModEntry m, Settings settings)
        {
            // Check if mod directory exists
            if (!Directory.Exists(m.Path))
            {
                m.AddState(ModState.NotInstalled);
                m.AddState(ModState.NotLoaded);
                m.isHidden = true;
                return;
            }

            // Check if in ModPaths
            if (!settings.ModPaths.Any(modPath => m.IsInModPath(modPath)))
            {
                m.AddState(ModState.NotLoaded);
            }

            // Update Source
            if (m.Source == ModSource.Unknown)
            {
                if (m.Path.IndexOf(@"\SteamApps\workshop\", StringComparison.OrdinalIgnoreCase) != -1)
                {
                    m.SetSource(ModSource.SteamWorkshop);
                }

                else
                {
                    // in workshop path but not loaded via steam
                    m.SetSource(ModSource.Manual);
                }
            }

            // Ensure source ID exists
            if (m.WorkshopID <= 0)
            {
                long sourceID;

                if (m.Source == ModSource.SteamWorkshop && long.TryParse(Path.GetFileName(m.Path), out sourceID))
                {
                    m.WorkshopID = sourceID;
                }
                else
                {
                    m.WorkshopID = new ModInfo(m.GetModInfoFile()).PublishedFileID;
                }
            }

            // Fill Date Added
            if (!m.DateAdded.HasValue)
            {
                m.DateAdded = DateTime.Now;
            }


            // Check Workshop for infos
            if (m.WorkshopID != 0)
            {
                var publishedID = (ulong)m.WorkshopID;

                var value = Workshop.GetDetails(publishedID, string.IsNullOrEmpty(m.Description));

                if (!m.ManualName)
                {
                    m.Name = value.m_rgchTitle;
                }

                m.DateCreated = DateTimeOffset.FromUnixTimeSeconds(value.m_rtimeCreated).DateTime;
                m.DateUpdated = DateTimeOffset.FromUnixTimeSeconds(value.m_rtimeUpdated).DateTime;

                if (value.m_rtimeAddedToUserList > 0)
                {
                    m.DateAdded = DateTimeOffset.FromUnixTimeSeconds(value.m_rtimeAddedToUserList).DateTime;
                }

                //m.Author = SteamWorkshop.GetUsername(value.m_ulSteamIDOwner);
                //MessageBox.Show(m.Author);

                // Update directory size
                m.RealizeSize(value.m_nFileSize);
                if (m.Size < 0)
                {
                    m.RealizeSize(Directory.EnumerateFiles(m.Path, "*", SearchOption.AllDirectories).Sum(fileName => new FileInfo(fileName).Length));
                }

                if (string.IsNullOrEmpty(m.Description))
                {
                    m.Description = value.m_rgchDescription;
                }

                if (value.m_ulSteamIDOwner > 0)
                {
                    m.Author = Workshop.GetUsername(value.m_ulSteamIDOwner);
                    if (string.IsNullOrEmpty(m.Author))
                    {
                        m.Author = "Unknown";
                    }
                }

                // Check Workshop for updates
                if (m.Source == ModSource.SteamWorkshop)
                {
                    if (
                        Workshop.GetDownloadStatus((ulong)m.WorkshopID)
                        .HasFlag(EItemState.k_EItemStateNeedsUpdate))
                    {
                        m.AddState(ModState.UpdateAvailable);
                    }
                }

                // Check if it is built for WOTC
                try
                {
                    // Parse .XComMod file
                    var modinfo = new ModInfo(m.GetModInfoFile());
                    m.SetRequiresWOTC(modinfo.RequiresXPACK);
                }
                catch (InvalidOperationException)
                {
                    return;
                }
            }
            else
            {
                m.DateCreated = Directory.GetCreationTime(m.Path);
                m.DateUpdated = Directory.GetLastWriteTime(m.Path);


                // Update directory size
                // slow, but necessary ?
                m.RealizeSize(Directory.EnumerateFiles(m.Path, "*", SearchOption.AllDirectories).Sum(fileName => new FileInfo(fileName).Length));

                // Update Name and Description
                // look for .XComMod file
                try
                {
                    // Parse .XComMod file
                    var modinfo = new ModInfo(m.GetModInfoFile());
                    if (!m.ManualName || m.Name == "")
                    {
                        m.Name = modinfo.Title;
                    }

                    m.Description = modinfo.Description;
                    m.SetRequiresWOTC(modinfo.RequiresXPACK);
                }
                catch (InvalidOperationException)
                {
                    return;
                }
            }
        }
Exemple #11
0
        public ModEntry Import(string modDir, ModSource source = ModSource.Unknown)
        {
            if (FindByPath(modDir) != null)
            {
                // Mod already loaded
                return(null);
            }

            // look for .XComMod file
            string infoFile = FindModInfo(modDir);

            if (infoFile == null)
            {
                return(null);
            }

            var modID  = Path.GetFileNameWithoutExtension(infoFile);
            var isDupe = All.Any(m => m.ID == modID && string.Compare(m.Path, modDir, StringComparison.OrdinalIgnoreCase) == 0);

            // Parse .XComMod file
            var modinfo = new ModInfo(infoFile);

            var mod = new ModEntry
            {
                Name      = modinfo.Title ?? "Unnamed Mod",
                ID        = modID,
                Path      = modDir,
                isActive  = false,
                DateAdded = DateTime.Now
            };

            mod.AddState(ModState.New);
            mod.SetRequiresWOTC(modinfo.RequiresXPACK);
            mod.SetSource(source);

            if (source == ModSource.SteamWorkshop)
            {
                var s = modDir.Split(Path.DirectorySeparatorChar).Last();
                try
                {
                    mod.WorkshopID = Convert.ToInt64(s);
                }
                catch (Exception)
                {
                    MessageBox.Show(
                        $"A mod could not be loaded because the workshop ID failed to parse.\r\nPlease check that the following directory conforms to valid workshop numbering.\r\n\r\nPath: {modDir}");
                    return(null);
                }
            }

            AddMod(modinfo.Category, mod);

            // mark dupes
            if (isDupe)
            {
                foreach (var m in All.Where(m => m.ID == modID))
                {
                    m.AddState(ModState.DuplicateID);
                }
            }

            return(mod);
        }