private void OnUGCDetailsComplete(SteamUGCQueryCompleted_t callback, bool ioError) { var result = callback.m_eResult; var handle = callback.m_handle; PublishedFileId_t id; if (!ioError && result == EResult.k_EResultOK) { var allResults = ListPool <SteamUGCDetails_t, SteamUGCServiceFixed> .Allocate(); for (uint i = 0U; i < callback.m_unNumResultsReturned; i++) { if (SteamUGC.GetQueryUGCResult(handle, i, out SteamUGCDetails_t details) && allMods.TryGetValue(id = details.m_nPublishedFileId, out ModInfo mod)) { #if false PUtil.LogDebug("Updated mod {0:D} ({1})".F(id.m_PublishedFileId, details.m_rgchTitle)); #endif mod.Populate(details); // Queue up the preview image download.Queue(id); preview.Queue(id); allResults.Add(details); } } ModUpdateDetails.OnInstalledUpdate(allResults); allResults.Recycle(); } SteamUGC.ReleaseQueryUGCRequest(handle); onQueryComplete?.Dispose(); onQueryComplete = null; }
/// <summary> /// Applied after OnSteamUGCQueryDetailsCompleted runs. /// </summary> internal static void Postfix(HashSet <SteamUGCDetails_t> ___publishes) { if (___publishes != null) { ModUpdateDetails.OnInstalledUpdate(___publishes); } }
/// <summary> /// Applied after Update runs. /// </summary> internal static void Postfix() { if (ModUpdateDetails.ScrubConfig()) { UpdateMainMenu(); } }
protected override void OnComplete(PublishedFileId_t id, int _) { var mod = SteamUGCServiceFixed.Instance.GetInfo(id); string path = ModUpdateHandler.GetDownloadPath(id.m_PublishedFileId); bool ok = false; string expectedPath = mod.installPath; #if DEBUG PUtil.LogDebug("Downloaded mod: {0:D}".F(id.m_PublishedFileId)); #endif if (expectedPath == null) { mod.Summon(); expectedPath = mod.installPath; } // Copy zip to the install_path and destroy it if (expectedPath != null) { if (File.Exists(path)) { try { File.Copy(path, expectedPath, true); ok = true; } catch (IOException e) { PUtil.LogWarning("Unable to copy file {0} to {1}:".F(path, expectedPath)); PUtil.LogExcWarn(e); } catch (UnauthorizedAccessException) { PUtil.LogWarning("Access to {0} is denied!".F(expectedPath)); } ExtensionMethods.RemoveOldDownload(path); } mod.state = SteamUGCServiceFixed.SteamModState.Updated; if (ok && id.GetGlobalLastModified(out System.DateTime when)) { ModUpdateDetails.UpdateConfigFor(id.m_PublishedFileId, when); } } else { PUtil.LogWarning("Unable to find install path for {0:D}!".F(id. m_PublishedFileId)); } }
/// <summary> /// Replace the Update function of SteamUGCService with this version that actually /// waits for the return and uses the same API as Mod Updater's regular mode. /// </summary> public void Process() { var toQuery = ListPool <PublishedFileId_t, SteamUGCServiceFixed> .Allocate(); var toRemove = ListPool <PublishedFileId_t, SteamUGCServiceFixed> .Allocate(); var toAdd = HashSetPool <PublishedFileId_t, SteamUGCServiceFixed> .Allocate(); var toUpdate = HashSetPool <PublishedFileId_t, SteamUGCServiceFixed> .Allocate(); var loadPreviews = ListPool <SteamUGCService.Mod, SteamUGCServiceFixed> .Allocate(); int n = clients.Count; // Mass request the details of all mods at once foreach (var pair in allMods) { var mod = pair.Value; var id = pair.Key; switch (mod.state) { case SteamModState.NeedsDetails: toQuery.Add(id); break; case SteamModState.PendingDestroy: toRemove.Add(id); break; case SteamModState.DetailsDirty: // Details were downloaded, send out a quick update of all the mod names // in mass at the beginning even if some downloads are pending if (mod.clientSeen) { toUpdate.Add(id); } else { toAdd.Add(id); } mod.state = SteamModState.Subscribed; break; default: break; } if (mod.previewDirty) { loadPreviews.Add(mod.ugcMod); mod.previewDirty = false; } } if (toQuery.Count > 0 && onQueryComplete == null) { QueryUGCDetails(toQuery.ToArray()); } toQuery.Recycle(); bool idle = download.Idle; if (idle) { // Avoid spamming by only notifying when all outstanding mods are downloaded foreach (var pair in allMods) { var mod = pair.Value; var id = pair.Key; if (mod.state == SteamModState.Updated) { mod.Summon(); if (mod.clientSeen) { toUpdate.Add(id); } else { toAdd.Add(id); } mod.state = SteamModState.Subscribed; } } } if (toAdd.Count > 0 || toUpdate.Count > 0 || toRemove.Count > 0 || loadPreviews. Count > 0) { firstEvent = true; // Event needs to be triggered for (int i = 0; i < n; i++) { clients[i].UpdateMods(toAdd, toUpdate, toRemove, loadPreviews); } if (n > 0) { foreach (var added in toAdd) { // Mods that were successfully added will be updated in the future if (allMods.TryGetValue(added, out ModInfo info)) { info.clientSeen = true; } } } } // Actually destroy all pending destroy mods foreach (var id in toRemove) { if (allMods.TryRemove(id, out ModInfo destroyed)) { destroyed.Dispose(); } } loadPreviews.Recycle(); toAdd.Recycle(); toUpdate.Recycle(); toRemove.Recycle(); if (wasIdle != idle || ModUpdateDetails.ScrubConfig()) { // Runs on foreground thread wasIdle = idle; ModUpdateDatePatches.UpdateMainMenu(); } }