123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- //
- // Copyright 2020 Electronic Arts Inc.
- //
- // The Command & Conquer Map Editor and corresponding source code is free
- // software: you can redistribute it and/or modify it under the terms of
- // the GNU General Public License as published by the Free Software Foundation,
- // either version 3 of the License, or (at your option) any later version.
- // The Command & Conquer Map Editor and corresponding source code is distributed
- // in the hope that it will be useful, but with permitted additional restrictions
- // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
- // distributed with this program. You should have received a copy of the
- // GNU General Public License along with permitted additional restrictions
- // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
- using MobiusEditor.Model;
- using Steamworks;
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.IO;
- using System.Text;
- using System.Windows.Forms;
- namespace MobiusEditor.Utility
- {
- public interface ISteamworksOperation : IDisposable
- {
- bool Done { get; }
- bool Failed { get; }
- string Status { get; }
- void OnSuccess();
- void OnFailed();
- }
- public class SteamworksUGCPublishOperation : ISteamworksOperation
- {
- private readonly string ugcPath;
- private readonly IList<string> tags;
- private readonly Action onSuccess;
- private readonly Action<string> onFailed;
- private CallResult<CreateItemResult_t> createItemResult;
- private CallResult<SubmitItemUpdateResult_t> submitItemUpdateResult;
- private SteamSection steamSection = new SteamSection();
- public bool Done => !(createItemResult?.IsActive() ?? false) && !(submitItemUpdateResult?.IsActive() ?? false);
- public bool Failed { get; private set; }
- public string Status { get; private set; }
- public SteamworksUGCPublishOperation(string ugcPath, SteamSection steamSection, IList<string> tags, Action onSuccess, Action<string> onFailed)
- {
- this.ugcPath = ugcPath;
- this.steamSection = steamSection;
- this.tags = tags;
- this.onSuccess = onSuccess;
- this.onFailed = onFailed;
- if (steamSection.PublishedFileId == PublishedFileId_t.Invalid.m_PublishedFileId)
- {
- CreateUGCItem();
- }
- else
- {
- UpdateUGCItem();
- }
- Status = "Publishing UGC...";
- }
- public void OnSuccess() => onSuccess();
- public void OnFailed() => onFailed(Status);
- private void CreateUGCItem()
- {
- var steamAPICall = SteamUGC.CreateItem(SteamUtils.GetAppID(), EWorkshopFileType.k_EWorkshopFileTypeCommunity);
- if (steamAPICall == SteamAPICall_t.Invalid)
- {
- Failed = true;
- Status = "Publishing failed.";
- return;
- }
- createItemResult = CallResult<CreateItemResult_t>.Create(OnCreateItemResult);
- createItemResult.Set(steamAPICall);
- }
- private void UpdateUGCItem()
- {
- var updateHandle = SteamUGC.StartItemUpdate(SteamUtils.GetAppID(), new PublishedFileId_t(steamSection.PublishedFileId));
- if (updateHandle == UGCUpdateHandle_t.Invalid)
- {
- Failed = true;
- Status = "Publishing failed.";
- return;
- }
- bool success = true;
- success = success && SteamUGC.SetItemContent(updateHandle, ugcPath);
- success = success && SteamUGC.SetItemPreview(updateHandle, steamSection.PreviewFile);
- success = success && SteamUGC.SetItemUpdateLanguage(updateHandle, "English");
- success = success && SteamUGC.SetItemTitle(updateHandle, steamSection.Title);
- success = success && SteamUGC.SetItemDescription(updateHandle, steamSection.Description);
- success = success && SteamUGC.SetItemVisibility(updateHandle, steamSection.Visibility);
- success = success && SteamUGC.SetItemTags(updateHandle, tags);
- if (!success)
- {
- Failed = true;
- Status = "Publishing failed.";
- return;
- }
- var steamAPICall = SteamUGC.SubmitItemUpdate(updateHandle, "");
- if (steamAPICall == SteamAPICall_t.Invalid)
- {
- Failed = true;
- Status = "Publishing failed.";
- return;
- }
- submitItemUpdateResult = CallResult<SubmitItemUpdateResult_t>.Create(OnSubmitItemUpdateResult);
- submitItemUpdateResult.Set(steamAPICall);
- }
- private void OnCreateItemResult(CreateItemResult_t callback, bool ioFailure)
- {
- if (ioFailure)
- {
- Failed = true;
- Status = "Publishing failed.";
- return;
- }
- switch (callback.m_eResult)
- {
- case EResult.k_EResultOK:
- steamSection.PublishedFileId = callback.m_nPublishedFileId.m_PublishedFileId;
- UpdateUGCItem();
- break;
- case EResult.k_EResultFileNotFound:
- Failed = true;
- Status = "UGC not found.";
- break;
- case EResult.k_EResultNotLoggedOn:
- Failed = true;
- Status = "Not logged on.";
- break;
- default:
- Failed = true;
- Status = "Publishing failed.";
- break;
- }
- }
- private void OnSubmitItemUpdateResult(SubmitItemUpdateResult_t callback, bool ioFailure)
- {
- if (ioFailure)
- {
- Failed = true;
- Status = "Publishing failed.";
- return;
- }
- switch (callback.m_eResult)
- {
- case EResult.k_EResultOK:
- Status = "Done.";
- steamSection.PublishedFileId = callback.m_nPublishedFileId.m_PublishedFileId;
- break;
- case EResult.k_EResultFileNotFound:
- Failed = true;
- Status = "UGC not found.";
- break;
- case EResult.k_EResultLimitExceeded:
- Failed = true;
- Status = "Size limit exceeded.";
- break;
- default:
- Failed = true;
- Status = string.Format("Publishing failed. ({0})", callback.m_eResult);
- break;
- }
- }
- #region IDisposable Support
- private bool disposedValue = false;
- protected virtual void Dispose(bool disposing)
- {
- if (!disposedValue)
- {
- if (disposing)
- {
- createItemResult?.Dispose();
- submitItemUpdateResult?.Dispose();
- }
- disposedValue = true;
- }
- }
- public void Dispose()
- {
- Dispose(true);
- }
- #endregion
- }
- public static class SteamworksUGC
- {
- public static bool IsInit { get; private set; }
- public static ISteamworksOperation CurrentOperation { get; private set; }
- public static string WorkshopURL
- {
- get
- {
- var app_id = IsInit ? SteamUtils.GetAppID() : AppId_t.Invalid;
- if (app_id == AppId_t.Invalid)
- {
- return string.Empty;
- }
- return string.Format("http://steamcommunity.com/app/{0}/workshop/", app_id.ToString());
- }
- }
- public static bool IsSteamBuild => File.Exists("steam_appid.txt");
- private static Callback<GameLobbyJoinRequested_t> GameLobbyJoinRequested;
- public static bool Init()
- {
- if (IsInit)
- {
- return true;
- }
- if (!IsSteamBuild)
- {
- return false;
- }
- if (!Packsize.Test())
- {
- return false;
- }
- if (!DllCheck.Test())
- {
- return false;
- }
- if (!SteamAPI.Init())
- {
- return false;
- }
- SteamClient.SetWarningMessageHook(new SteamAPIWarningMessageHook_t(SteamAPIDebugTextHook));
- GameLobbyJoinRequested = Callback<GameLobbyJoinRequested_t>.Create(OnGameLobbyJoinRequested);
- IsInit = true;
- return IsInit;
- }
- public static void Shutdown()
- {
- if (IsInit)
- {
- GameLobbyJoinRequested?.Dispose();
- GameLobbyJoinRequested = null;
- CurrentOperation?.Dispose();
- CurrentOperation = null;
- SteamAPI.Shutdown();
- IsInit = false;
- }
- }
- public static void Service()
- {
- SteamAPI.RunCallbacks();
- if (CurrentOperation?.Done ?? false)
- {
- if (CurrentOperation.Failed)
- {
- CurrentOperation.OnFailed();
- }
- else
- {
- CurrentOperation.OnSuccess();
- }
- CurrentOperation.Dispose();
- CurrentOperation = null;
- }
- }
- public static bool PublishUGC(string ugcPath, SteamSection steamSection, IList<string> tags, Action onSuccess, Action<string> onFailed)
- {
- if (CurrentOperation != null)
- {
- return false;
- }
- CurrentOperation = new SteamworksUGCPublishOperation(ugcPath, steamSection, tags, onSuccess, onFailed);
- return true;
- }
- private static void SteamAPIDebugTextHook(int nSeverity, StringBuilder pchDebugText)
- {
- Debug.WriteLine(pchDebugText);
- }
- private static void OnGameLobbyJoinRequested(GameLobbyJoinRequested_t data)
- {
- MessageBox.Show("You cannot accept an invitation to a multiplayer game while using the map editor.", "Steam", MessageBoxButtons.OK, MessageBoxIcon.Information);
- }
- }
- }
|