예제 #1
0
        void PrintItemDetails()
        {
            const int MAX_LENGTH = 40;

            MySandboxGame.Log.WriteLineAndConsole(string.Format("Visibility: {0}", m_visibility));
            MySandboxGame.Log.WriteLineAndConsole(string.Format("Tags: {0}", string.Join(", ", m_tags)));

            if (!string.IsNullOrEmpty(m_description))
            {
                MySandboxGame.Log.WriteLineAndConsole($"Description: {m_description.Substring(0, Math.Min(m_description.Length, MAX_LENGTH))}{(m_description.Length > MAX_LENGTH ? "..." : "")}");
            }

            if (!string.IsNullOrEmpty(m_changelog))
            {
                MySandboxGame.Log.WriteLineAndConsole($"Changelog: {m_changelog.Substring(0, Math.Min(m_changelog.Length, MAX_LENGTH))}{(m_changelog.Length > MAX_LENGTH ? "..." : "")}");
            }
#if SE
            MySandboxGame.Log.WriteLineAndConsole(string.Format("DLC requirements: {0}",
                                                                (m_dlcs?.Length > 0 ? string.Join(", ", m_dlcs.Select(i =>
            {
                try { return(Sandbox.Game.MyDLCs.DLCs[i].Name); }
                catch { return($"Unknown({i})"); }
            })) : "None")));
#endif
            MySandboxGame.Log.WriteLineAndConsole(string.Format("Dependencies: {0}", (m_deps?.Length > 0 ? string.Empty : "None")));

            if (m_deps?.Length > 0)
            {
                var depItems = new List <MyWorkshopItem>();
                var width    = Console.IsOutputRedirected ? 256 : Console.WindowWidth;
#if SE
                var depIds = new List <WorkshopId>();
                foreach (var item in m_deps)
                {
                    depIds.Add(new WorkshopId(item, MyGameService.GetDefaultUGC().ServiceName));
                }

                if (MyWorkshop.GetItemsBlockingUGC(depIds, depItems))
#else
                if (MyWorkshop.GetItemsBlocking(m_deps, depItems))
#endif
                { depItems.ForEach(i => MySandboxGame.Log.WriteLineAndConsole(string.Format("{0,15} -> {1}",
                                                                                            i.Id, i.Title.Substring(0, Math.Min(i.Title.Length, width - 45))))); }
                else
                {
                    MySandboxGame.Log.WriteLineAndConsole(string.Format("     {0}", string.Join(", ", m_deps)));
                }
            }
            MySandboxGame.Log.WriteLineAndConsole(string.Format("Thumbnail: {0}", m_previewFilename ?? "No change"));
            ValidateThumbnail();
        }
예제 #2
0
        /// <summary>
        /// Publishes the mod to the workshop
        /// </summary>
        /// <returns></returns>
        public bool Publish()
        {
            bool newMod = false;

            if (!Directory.Exists(m_modPath))
            {
                MySandboxGame.Log.WriteLineAndConsole(string.Format("Directory does not exist {0}. Wrong option?", m_modPath ?? string.Empty));
                return(false);
            }

            // Upload/Publish
#if SE
            if (((IMod)this).ModId == 0)
#else
            if (m_modId == 0)
#endif
            {
                MySandboxGame.Log.WriteLineAndConsole(string.Format("Uploading new {0}: {1}", m_type.ToString(), m_title));
                newMod = true;

#if SE
                if (m_modId.Length == 0)
                {
                    m_modId = new WorkshopId[1] {
                        new WorkshopId(0, MyGameService.GetDefaultUGC().ServiceName)
                    }
                }
                ;
#endif
            }
            else
            {
                MySandboxGame.Log.WriteLineAndConsole(string.Format("Updating {0}: {1}; {2}", m_type.ToString(), m_modId.AsString(), m_title));
            }

            // Add the global game filter for file extensions
            _globalIgnoredExtensions?.ForEach(s => m_ignoredExtensions.Add(s));

            // Process Tags
            ProcessTags();

            PrintItemDetails();

            MyWorkshopItem[] items = null;

            if (m_dryrun)
            {
                MySandboxGame.Log.WriteLineAndConsole("DRY-RUN; Publish skipped");
                return(true);
            }
            else
            {
                if (_publishMethod != null)
                {
                    InjectedMethod.ChangeLog = m_changelog;
#if SE
                    var result = _publishMethod(m_modPath, m_title, m_description, m_modId, (MyPublishedFileVisibility)(m_visibility ?? PublishedFileVisibility.Private), m_tags, m_ignoredExtensions, m_ignoredPaths, m_dlcs, out items);
                    PublishSuccess = result.Item1 == MyGameServiceCallResult.OK;

                    if (PublishSuccess)
                    {
                        m_modId = items.Select(i => new WorkshopId(i.Id, i.ServiceName)).ToArray();
                    }
#else
                    m_modId = _publishMethod(m_modPath, m_title, m_description, m_modId, (MyPublishedFileVisibility)(m_visibility ?? PublishedFileVisibility.Private), m_tags, m_ignoredExtensions, m_ignoredPaths);
#endif
                }
                else
                {
                    MySandboxGame.Log.WriteLineAndConsole(string.Format(Constants.ERROR_Reflection, "PublishItemBlocking"));
                }

                // SE libraries don't support updating dependencies, so we have to do that separately
                WorkshopHelper.PublishDependencies(m_modId, m_deps, m_depsToRemove);
            }
            if (((IMod)this).ModId == 0 || !PublishSuccess)
            {
                MySandboxGame.Log.WriteLineAndConsole("Upload/Publish FAILED!");
                return(false);
            }
            else
            {
                MySandboxGame.Log.WriteLineAndConsole(string.Format("Upload/Publish success: {0}", m_modId.AsString()));
                if (newMod)
                {
#if SE
                    if (MyWorkshop.GenerateModInfo(m_modPath, items, MyGameService.UserId))
#else
                    if (MyWorkshop.UpdateModMetadata(m_modPath, m_modId, MySteam.UserId))
#endif
                    {
                        MySandboxGame.Log.WriteLineAndConsole(string.Format("Create modinfo.sbmi success: {0}", m_modId.AsString()));
                    }
                    else
                    {
                        MySandboxGame.Log.WriteLineAndConsole(string.Format("Create modinfo.sbmi FAILED: {0}", m_modId.AsString()));
                        return(false);
                    }
                }
            }
            return(true);
        }

        bool FillPropertiesFromPublished()
        {
            var results = new List <MyWorkshopItem>();

#if SE
            if (MyWorkshop.GetItemsBlockingUGC(m_modId.ToList(), results))
#else
            if (MyWorkshop.GetItemsBlocking(new List <ulong>()
            {
                m_modId
            }, results))
#endif
            {
                System.Threading.Thread.Sleep(1000); // Fix for DLC not being filled in
                if (results.Count > 0)
                {
#if SE
                    m_workshopItems[m_modId[0]] = results[0];

                    if (m_modId.Length > 1 && results.Count > 1)
                    {
                        m_workshopItems[m_modId[1]] = results[1];
                    }
#else
                    if (results.Count > 1)
                    {
                        m_modId = results[0].Id;
                    }
#endif

                    m_title = results[0].Title;

                    // Check if the mod owner in the sbmi matches steam owner
                    var owner = results[0].OwnerId;

                    if (m_visibility == null)
                    {
                        m_visibility = (PublishedFileVisibility)(int)results[0].Visibility;
                    }

#if SE
                    m_dlcs = results[0].DLCs.ToArray();
#endif
                    m_deps = results[0].Dependencies.ToArray();

                    MyDebug.AssertDebug(owner == MyGameService.UserId);
                    if (owner != MyGameService.UserId)
                    {
                        MySandboxGame.Log.WriteLineAndConsole(string.Format("Owner mismatch! Mod owner: {0}; Current user: {1}", owner, MyGameService.UserId));
                        MySandboxGame.Log.WriteLineAndConsole("Upload/Publish FAILED!");
                        return(false);
                    }
                    return(true);
                }
                return(false);
            }
            return(true);
        }

        void ProcessTags()
        {
            // TODO: This code could be better.

            // Get the list of existing tags, if there are any
            var existingTags = GetTags();
            var length       = m_tags.Length;

            // Order or tag processing matters
            // 1) Copy mod type into tags
            var modtype = m_type.ToString();

            // 2) Verify the modtype matches what was listed in the workshop
            // TODO If type doesn't match, process as workshop type
            if (existingTags != null && existingTags.Length > 0)
            {
                MyDebug.AssertRelease(existingTags.Contains(modtype, StringComparer.InvariantCultureIgnoreCase), string.Format("Mod type '{0}' does not match workshop '{1}'", modtype, existingTags[0]));
            }

#if SE
            // 3a) check if user passed in the 'development' tag
            // If so, remove it, and mark the mod as 'dev' so it doesn't get flagged later
            if (m_tags.Contains(MyWorkshop.WORKSHOP_DEVELOPMENT_TAG))
            {
                m_tags  = (from tag in m_tags where tag != MyWorkshop.WORKSHOP_DEVELOPMENT_TAG select tag).ToArray();
                m_isDev = true;
            }
#endif
            // 3b If tags contain mod type, remove it
            if (m_tags.Contains(modtype, StringComparer.InvariantCultureIgnoreCase))
            {
                m_tags = (from tag in m_tags where string.Compare(tag, modtype, true) != 0 select tag).ToArray();
            }

            // 4)
            if (m_tags.Length == 1 && m_tags[0] == null && existingTags != null && existingTags.Length > 0)
            {
                // 4a) If user passed no tags, use existing ones
                Array.Resize(ref m_tags, existingTags.Length);
                Array.Copy(existingTags, m_tags, existingTags.Length);
            }
            else
            {
                // 4b) Verify passed in tags are valid for this mod type
                var validTags = new List <MyWorkshop.Category>()
                {
#if SE
                    // 'obsolete' tag is always available, as is 'No Mods' and 'experimental'
                    new MyWorkshop.Category()
                    {
                        Id = "obsolete"
                    },
                    new MyWorkshop.Category()
                    {
                        Id = "no mods"
                    },
                    new MyWorkshop.Category()
                    {
                        Id = "experimental"
                    },
#endif
                };
                switch (m_type)
                {
                case WorkshopType.Mod:
                    MyWorkshop.ModCategories.ForEach(c => validTags.Add(c));
                    // Mods have extra tags not in this list
#if SE
                    validTags.Add(new MyWorkshop.Category()
                    {
                        Id = "campaign"
                    });
                    validTags.Add(new MyWorkshop.Category()
                    {
                        Id = "font"
                    });
                    validTags.Add(new MyWorkshop.Category()
                    {
                        Id = "noscripts"
                    });
#endif
                    break;

                case WorkshopType.Blueprint:
                    MyWorkshop.BlueprintCategories.ForEach(c => validTags.Add(c));
#if SE
                    // Blueprints have extra tags not in this list
                    validTags.Add(new MyWorkshop.Category()
                    {
                        Id = "large_grid"
                    });
                    validTags.Add(new MyWorkshop.Category()
                    {
                        Id = "small_grid"
                    });
                    validTags.Add(new MyWorkshop.Category()
                    {
                        Id = "safe"
                    });                                                             // Mod.io only?
#endif
                    break;

                case WorkshopType.Scenario:
                    MyWorkshop.ScenarioCategories.ForEach(c => validTags.Add(c));
                    break;

                case WorkshopType.World:
                    MyWorkshop.WorldCategories.ForEach(c => validTags.Add(c));
                    break;

                case WorkshopType.IngameScript:
                    //tags = new MyWorkshop.Category[0];     // There are none currently
                    break;

                default:
                    MyDebug.FailRelease("Invalid category.");
                    break;
                }

                // This query gets all the items in 'm_tags' that do *not* exist in 'validTags'
                // This is for detecting invalid tags passed in
                var invalidItems = from utag in m_tags
                                   where !(
                    from tag in validTags
                    select tag.Id
                    ).Contains(utag, StringComparer.InvariantCultureIgnoreCase)
                                   select utag;

                if (invalidItems.Count() > 0)
                {
                    MySandboxGame.Log.WriteLineAndConsole(string.Format("{0} invalid tags: {1}", (m_force ? "Forced" : "Removing"), string.Join(", ", invalidItems)));

                    if (!m_force)
                    {
                        m_tags = (from tag in m_tags where !invalidItems.Contains(tag) select tag).ToArray();
                    }
                }

                // Now prepend the 'Type' tag
                string[] newTags = new string[m_tags.Length + 1];
                newTags[0] = m_type.ToString();

                var tags = from tag in validTags select tag.Id;

                // Convert all tags to proper-case
                for (var x = 0; x < m_tags.Length; x++)
                {
                    var tag    = m_tags[x];
                    var newtag = (from vtag in tags where (string.Compare(vtag, tag, true) == 0) select vtag).FirstOrDefault();

                    if (!string.IsNullOrEmpty(newtag))
                    {
                        newTags[x + 1] = newtag;
                    }
                    else
                    {
                        newTags[x + 1] = m_tags[x];
                    }
                }

                m_tags = newTags;
            }
#if SE
            // 5) Set or clear development tag
            if (m_isDev)
            {
                // If user selected dev, add dev tag
                if (!m_tags.Contains(MyWorkshop.WORKSHOP_DEVELOPMENT_TAG))
                {
                    Array.Resize(ref m_tags, m_tags.Length + 1);
                    m_tags[m_tags.Length - 1] = MyWorkshop.WORKSHOP_DEVELOPMENT_TAG;
                }
            }
            else
            {
                // If not, remove tag
                if (m_tags.Contains(MyWorkshop.WORKSHOP_DEVELOPMENT_TAG))
                {
                    m_tags = (from tag in m_tags where tag != MyWorkshop.WORKSHOP_DEVELOPMENT_TAG select tag).ToArray();
                }
            }
#endif
            // 6) Strip empty values
            m_tags = m_tags.Where(x => !string.IsNullOrEmpty(x)).ToArray();

            // Done
        }

        string[] GetTags()
        {
            var results = new List <MyWorkshopItem>();

#if SE
            if (MyWorkshop.GetItemsBlockingUGC(m_modId.ToList(), results))
#else
            if (MyWorkshop.GetItemsBlocking(new List <ulong>()
            {
                m_modId
            }, results))
#endif
            {
                if (results.Count > 0)
                {
                    return(results[0].Tags.ToArray());
                }
                else
                {
                    return(null);
                }
            }

            return(null);
        }

        uint[] GetDLC()
        {
#if SE
            var results = new List <MyWorkshopItem>();

            if (MyWorkshop.GetItemsBlockingUGC(m_modId.ToList(), results))
            {
                if (results.Count > 0)
                {
                    return(results[0].DLCs.ToArray());
                }
                else
                {
                    return(null);
                }
            }
#endif
            return(null);
        }

        PublishedFileVisibility GetVisibility()
        {
            var results = new List <MyWorkshopItem>();

#if SE
            if (MyWorkshop.GetItemsBlockingUGC(m_modId.ToList(), results))
#else
            if (MyWorkshop.GetItemsBlocking(new List <ulong>()
            {
                m_modId
            }, results))
#endif
            {
                if (results.Count > 0)
                {
                    return((PublishedFileVisibility)(int)results[0].Visibility);
                }
                else
                {
                    return(PublishedFileVisibility.Private);
                }
            }

            return(PublishedFileVisibility.Private);
        }
예제 #3
0
        static bool ProcessItemsDownload(WorkshopType type, string[] paths, Options options)
        {
            if (paths == null)
            {
                return(true);
            }

            var width = Console.IsOutputRedirected ? 256 : Console.WindowWidth;

            var items  = new List <MyWorkshopItem>();
            var modids = paths.Select(ulong.Parse);

            MySandboxGame.Log.WriteLineAndConsole(string.Format("Processing {0}s...", type.ToString()));

            var downloadPath = WorkshopHelper.GetWorkshopItemPath(type);

#if SE
            var workshopIds = new List <VRage.Game.WorkshopId>();
            foreach (var id in modids)
            {
                workshopIds.Add(new VRage.Game.WorkshopId(id, MyGameService.GetDefaultUGC().ServiceName));
            }

            if (MyWorkshop.GetItemsBlockingUGC(workshopIds, items))
#else
            if (MyWorkshop.GetItemsBlocking(modids, items))
#endif
            {
                System.Threading.Thread.Sleep(1000); // Fix for DLC not being filled in

                bool success = false;
                if (type == WorkshopType.Mod)
                {
#if SE
                    var result = MyWorkshop.DownloadModsBlockingUGC(items, null);
#else
                    var result = MyWorkshop.DownloadModsBlocking(items, null);
#endif
                    success = result.Success;
                }
                else
                {
                    if (type == WorkshopType.Blueprint)
                    {
                        var loopsuccess = false;
                        foreach (var item in items)
                        {
#if SE
                            loopsuccess = MyWorkshop.DownloadBlueprintBlockingUGC(item);
#else
                            loopsuccess = MyWorkshop.DownloadBlueprintBlocking(item, null);
#endif
                            if (!loopsuccess)
                            {
                                MySandboxGame.Log.WriteLineAndConsole(string.Format("Download of {0} FAILED!", item.Id));
                            }
                            else
                            {
                                success = true;
                            }
                        }
                    }
#if SE
                    else if (type == WorkshopType.IngameScript)
                    {
                        var loopsuccess = false;
                        foreach (var item in items)
                        {
                            loopsuccess = MyWorkshop.DownloadScriptBlocking(item);
                            if (!loopsuccess)
                            {
                                MySandboxGame.Log.WriteLineAndConsole(string.Format("Download of {0} FAILED!", item.Id));
                            }
                            else
                            {
                                success = true;
                            }
                        }
                    }
#endif
#if SE
                    else if (type == WorkshopType.World || type == WorkshopType.Scenario)
                    {
                        var    loopsuccess = false;
                        string path;
                        MyWorkshop.MyWorkshopPathInfo pathinfo = type == WorkshopType.World ?
                                                                 MyWorkshop.MyWorkshopPathInfo.CreateWorldInfo() :
                                                                 MyWorkshop.MyWorkshopPathInfo.CreateScenarioInfo();

                        foreach (var item in items)
                        {
                            // This downloads and extracts automatically, no control over it
                            loopsuccess = MyWorkshop.TryCreateWorldInstanceBlocking(item, pathinfo, out path, false);
                            if (!loopsuccess)
                            {
                                MySandboxGame.Log.WriteLineAndConsole(string.Format("Download of {0} FAILED!", item.Id));
                            }
                            else
                            {
                                MySandboxGame.Log.WriteLineAndConsole(string.Format("Downloaded '{0}' to {1}", item.Title, path));
                                success = true;
                            }
                        }
                    }
#endif
                    else
                    {
                        throw new NotSupportedException(string.Format("Downloading of {0} not yet supported.", type.ToString()));
                    }
                }

                if (success)
                {
                    MySandboxGame.Log.WriteLineAndConsole("Download success!");
                }
                else
                {
                    MySandboxGame.Log.WriteLineAndConsole("Download FAILED!");
                    return(false);
                }

                foreach (var item in items)
                {
                    MySandboxGame.Log.WriteLineAndConsole(string.Format("Downloading mod: {0}; {1}", item.Id, item.Title));
                    MySandboxGame.Log.WriteLineAndConsole(string.Format("Visibility: {0}", item.Visibility));
                    MySandboxGame.Log.WriteLineAndConsole(string.Format("Tags: {0}", string.Join(", ", string.Join(", ", item.Tags))));

#if SE
                    MySandboxGame.Log.WriteLineAndConsole(string.Format("DLC requirements: {0}",
                                                                        (item.DLCs.Count > 0 ? string.Join(", ", item.DLCs.Select(i =>
                    {
                        try { return(Sandbox.Game.MyDLCs.DLCs[i].Name); }
                        catch { return($"Unknown({i})"); }
                    })) : "None")));
#endif
                    MySandboxGame.Log.WriteLineAndConsole(string.Format("Dependencies: {0}", (item.Dependencies.Count > 0 ? string.Empty : "None")));

                    if (item.Dependencies.Count > 0)
                    {
                        List <MyWorkshopItem> depItems = new List <MyWorkshopItem>();
#if SE
                        workshopIds.Clear();
                        foreach (var id in item.Dependencies)
                        {
                            workshopIds.Add(new VRage.Game.WorkshopId(id, MyGameService.GetDefaultUGC().ServiceName));
                        }

                        if (MyWorkshop.GetItemsBlockingUGC(workshopIds, depItems))
#else
                        if (MyWorkshop.GetItemsBlocking(item.Dependencies, depItems))
#endif
                        { depItems.ForEach(i => MySandboxGame.Log.WriteLineAndConsole(string.Format("{0,15} -> {1}",
                                                                                                    i.Id, i.Title.Substring(0, Math.Min(i.Title.Length, width - 45))))); }
                        else
                        {
                            MySandboxGame.Log.WriteLineAndConsole(string.Format("     {0}", string.Join(", ", item.Dependencies)));
                        }
                    }

                    MySandboxGame.Log.WriteLineAndConsole(string.Format("Location: {0}", item.Folder));

                    if (options.Extract)
                    {
                        var mod = new Downloader(downloadPath, item);
                        mod.Extract();
                    }
                    MySandboxGame.Log.WriteLineAndConsole(string.Empty);
                }
            }
            return(true);
        }