7 const float IMAGE_SIZE_RATIO = 16.0 / 9.0;
9 static const ResourceName DIALOGS_CONFIG =
"{26F075E5D30629E5}Configs/ContentBrowser/ContentBrowserDialogs.conf";
12 static const float NO_LOADING_OVERLAY_DURATION_MS = 500;
15 static const ResourceName ADDON_DEFAULT_THUMBNAIL =
"{04EB797EBF59CDEF}UI/Textures/Workshop/AddonThumbnails/workshop_defaultFallback_UI.edds";
16 static const ResourceName SCENARIO_SP_DEFAULT_THUMBNAIL =
"{17D65C6D78C7722C}UI/Textures/Workshop/AddonThumbnails/workshop_scenarios_UI.edds";
17 static const ResourceName SCENARIO_MP_DEFAULT_THUMBNAIL =
"{62A03BAAAED612E8}UI/Textures/Workshop/AddonThumbnails/workshop_mpScenarios_UI.edds";
20 static const ResourceName ADDON_TYPE_FILTER_CATEGORY_CONFIG =
"{A557E41062372854}Configs/ContentBrowser/Filters/category_type.conf";
21 static ref map<string, string> s_sAddonTagImageMap;
24 static ref map<string, ResourceName> s_sAddonTagDefaultThumbnailMap;
26 static const string WIDGET_LIST =
"AddonList";
30 static const string MESSAGE_MOD_NOT_AVAILABLE =
"#AR-Workshop_State_NotAvailable";
31 static const string MESSAGE_MOD_NOT_AVAILABLE_REMOVED =
"#AR-Workshop_State_Removed";
32 static const string MESSAGE_MOD_NOT_AVAILABLE_INCOMPATIBLE =
"#AR-Workshop_State_Incompatible";
33 static const string MESSAGE_MOD_AVAILABLE_WHEN_UPDATED =
"#AR-Workshop_State_UpdateRequired";
34 static const string MESSAGE_MOD_DOWNLOAD_NOT_FINISHED =
"#AR-Workshop_State_DownloadNotFinished";
37 static const string MESSAGE_VERBOSE_MOD_NOT_AVAILABLE =
"#AR-Workshop_State_NotAvailableDesc";
38 static const string MESSAGE_VERBOSE_MOD_NOT_AVAILABLE_REMOVED =
"#AR-Workshop_State_RemovedDesc";
39 static const string MESSAGE_VERBOSE_MOD_NOT_AVAILABLE_INCOMPATIBLE =
"#AR-Workshop_State_IncompatibleDesc";
40 static const string MESSAGE_VERBOSE_MOD_AVAILABLE_WHEN_UPDATED =
"#AR-Workshop_State_UpdateRequiredDesc";
41 static const string MESSAGE_VERBOSE_MOD_DOWNLOAD_NOT_FINISHED =
"#AR-Workshop_State_DownloadNotFinishedDesc";
44 static const string ICON_MOD_NOT_AVAILABLE =
"not-available";
45 static const string ICON_MOD_NOT_AVAILABLE_REMOVED =
"cancelCircle";
46 static const string ICON_MOD_NOT_AVAILABLE_INCOMPATIBLE =
"incompatible";
47 static const string ICON_MOD_AVAILABLE_WHEN_UPDATED =
"available-when-updated";
48 static const string ICON_MOD_DOWNLOAD_NOT_FINISHED =
"downloading";
57 static void OnGameStart()
68 static void TryOpenWorkshop()
71 if (mgr.GetUgcPrivilege())
72 ContentBrowserUI.Create();
75 mgr.m_OnUgcPrivilegeResult.Insert(OnTryOpenWorkshopUgcPrivilegeResult);
76 mgr.NegotiateUgcPrivilegeAsync();
81 protected static void OnTryOpenWorkshopUgcPrivilegeResult(
bool result)
84 mgr.m_OnUgcPrivilegeResult.Remove(OnTryOpenWorkshopUgcPrivilegeResult);
86 ContentBrowserUI.Create();
97 static string GetTagImage(
string tag)
100 return s_sAddonTagImageMap.Get(tag);
106 array<WorkshopTag> tagObjs = {};
108 WorkshopItem internalItem = item.GetWorkshopItem();
110 if (!internalItem || !s_sAddonTagDefaultThumbnailMap)
111 return ADDON_DEFAULT_THUMBNAIL;
114 internalItem.GetTags(tagObjs);
115 foreach (WorkshopTag tagObj : tagObjs)
117 string tagStr = tagObj.Name();
120 if (s_sAddonTagDefaultThumbnailMap.Contains(tagStr))
121 return s_sAddonTagDefaultThumbnailMap.Get(tagStr);
124 return ADDON_DEFAULT_THUMBNAIL;
128 static bool GetConnectionState()
130 auto backend =
GetGame().GetBackendApi();
131 bool connected = backend.IsActive() && backend.IsAuthenticated();
137 static int GetPreferedTileImageWidth()
139 const float scale = 260.0/1920.0;
141 GetGame().GetWorkspace().GetScreenSize(w, h);
142 int widthInt = scale*w;
151 static void TryPlayScenario(notnull MissionWorkshopItem scenario)
153 int nCompleted, nTotal;
157 mgr.GetDownloadQueueState(nCompleted, nTotal);
160 SCR_StartScenarioWhileDownloadingDialog.CreateDialog(scenario);
167 static void TryHostScenario(notnull MissionWorkshopItem scenario, notnull
SCR_DSConfig config)
169 int nCompleted, nTotal;
173 mgr.GetDownloadQueueState(nCompleted, nTotal);
178 scenario.Host(config);
192 if (!item.GetOffline() || item.GetRestricted())
195 bool newEnabled = !item.GetEnabled();
196 SetAddonEnabled(item, newEnabled);
202 static void OnEnableAddonToggleButton(
SCR_WorkshopItem item, SCR_ModularButtonComponent buttonComp)
207 if (!item.GetOffline() || item.GetRestricted())
211 bool newEnabled = buttonComp.GetToggled();
212 SetAddonEnabled(item, newEnabled);
220 array<ref SCR_WorkshopItem> offlineAndDependent =
SCR_AddonManager.SelectItemsAnd(
221 item.GetDependentAddons(),
224 if (!offlineAndDependent.IsEmpty())
232 static bool GetHighestPriorityProblemDescription(
SCR_WorkshopItem item, out
string descriptionShort, out
bool critical)
235 if (!item.GetOffline())
243 descriptionShort =
"#AR-Workshop_State_MissingDependencies";
248 descriptionShort =
"#AR-Workshop_State_MustEnableDependencies";
253 descriptionShort =
"#AR-Workshop_State_UpdateAvailable";
258 descriptionShort =
"#AR-Workshop_State_DependencyUpdateAvailable";
263 descriptionShort =
string.Empty;
268 descriptionShort =
string.Empty;
278 bool downloading = item.GetDownloadAction() !=
null || item.GetDependencyCompositeAction() !=
null;
284 if (!item.GetOffline())
285 return "#AR-Workshop_ButtonDownload";
294 default:
return string.Empty;
301 return "#AR-Workshop_ButtonCancel";
311 if (!item.GetRestricted())
314 if (item.GetReportedByMe())
315 return "#AR-Workshop_State_Reported";
316 else if (item.GetBlocked())
317 return "#AR-Workshop_State_Banned";
319 return "#AR-Workshop_State_Restricted";
322 protected static ref ScriptInvoker<> m_OnDownloadConfirmDisplayed =
new ScriptInvoker<>();
325 static ScriptInvoker GetOnDownloadConfirmDisplayed()
327 return m_OnDownloadConfirmDisplayed;
335 bool downloading = item.GetDownloadAction() !=
null || item.GetDependencyCompositeAction() !=
null;
344 if (!item.GetOffline())
347 dlRequest.GetOnDownloadConfirmDisplayed().Remove(OnDownloadConfirmDisplayed);
348 dlRequest.GetOnDownloadConfirmDisplayed().Insert(OnDownloadConfirmDisplayed);
361 dlRequest.GetOnDownloadConfirmDisplayed().Remove(OnDownloadConfirmDisplayed);
362 dlRequest.GetOnDownloadConfirmDisplayed().Insert(OnDownloadConfirmDisplayed);
368 item.SetDependenciesEnabled(
true);
380 array<ref SCR_WorkshopItemActionDownload> actionsToCancel = {};
383 actionsToCancel.Insert(actionThisItem);
385 if (actionDependenciesThisItem)
387 array<ref SCR_WorkshopItemAction> dependencyActions = actionDependenciesThisItem.GetActions();
388 foreach (
auto a : dependencyActions)
392 actionsToCancel.Insert(downloadAction);
408 if (m_OnDownloadConfirmDisplayed)
409 m_OnDownloadConfirmDisplayed.Invoke(downloadSequence, confirmDialog);
414 static string GetRevisionAvailabilityErrorMessage(WorkshopItem item)
417 return MESSAGE_MOD_NOT_AVAILABLE;
419 return GetRevisionAvailabilityErrorMessage(
SCR_AddonManager.ItemAvailability(item));
435 return MESSAGE_MOD_NOT_AVAILABLE;
439 static string GetRevisionAvailabilityErrorMessageVerbose(WorkshopItem item)
442 return MESSAGE_VERBOSE_MOD_NOT_AVAILABLE;
444 return GetRevisionAvailabilityErrorMessageVerbose(
SCR_AddonManager.ItemAvailability(item));
460 return MESSAGE_VERBOSE_MOD_NOT_AVAILABLE;
464 static string GetRevisionAvailabilityErrorTexture(WorkshopItem item)
467 return ICON_MOD_NOT_AVAILABLE;
469 return GetRevisionAvailabilityErrorTexture(
SCR_AddonManager.ItemAvailability(item));
485 return ICON_MOD_NOT_AVAILABLE;
493 static string FormatVersion(
string version)
495 return string.Format(
"v. %1", version);
500 static string GetReportTypeString(EWorkshopReportType eReportType)
502 const int REPORT_REASONS_COUNT = EWorkshopReportType.EWREPORT_OTHER + 1;
503 const string REPORT_REASONS[REPORT_REASONS_COUNT] =
505 "#AR-Workshop_Report_InappropiateContent",
506 "#AR-Workshop_Report_OffensiveLanguage",
507 "#AR-Workshop_Report_Missleading_NonFunctional",
508 "#AR-Workshop_Report_Spam",
509 "#AR-Workshop_Report_Scam",
510 "#AR-Workshop_Report_Malicious",
511 "#AR-Workshop_Report_IPInfringement",
512 "#AR-Workshop_Report_Other"
515 int reportType = eReportType;
517 if (reportType < 0 || reportType >= REPORT_REASONS_COUNT)
520 return REPORT_REASONS[reportType];
529 protected static void Callback_OnAddonsChecked()
531 array<string> bannedAddons = {};
532 GetGame().GetBackendApi().GetWorkshop().GetBannedItems(bannedAddons);
534 if (bannedAddons.IsEmpty())
542 protected static void SetAddonEnabled(
SCR_WorkshopItem item,
bool newEnabled)
544 item.SetEnabled(newEnabled);
549 item.SetDependenciesEnabled(
true);
554 array<ref SCR_WorkshopItem> offlineAndEnabled =
SCR_AddonManager.SelectItemsAnd(
555 item.GetDependentAddons(),
558 if (!offlineAndEnabled.IsEmpty())
566 protected static void InitAddonTagMaps()
568 s_sAddonTagImageMap =
new map<string, string>;
569 s_sAddonTagDefaultThumbnailMap =
new map<string, ResourceName>;
572 SCR_FilterCategory cat = SCR_ConfigHelperT<SCR_FilterCategory>.GetConfigObject(ADDON_TYPE_FILTER_CATEGORY_CONFIG);
578 string internalName = filter.m_sInternalName;
579 internalName.ToLower();
580 s_sAddonTagImageMap.Insert(internalName, filter.m_sImageName);
585 if (!filterTag.m_sDefaultThumbnail.IsEmpty())
586 s_sAddonTagDefaultThumbnailMap.Insert(internalName, filterTag.m_sDefaultThumbnail);
629 if (
m_Item.GetSubscribed())
630 m_Item.SetSubscribed(
false);
645 protected ref array<SCR_WorkshopItem> m_aItems = {};
661 override void OnConfirm()
665 if (item.GetEnabled())
668 if (item.GetSubscribed())
669 item.SetSubscribed(
false);
671 item.DeleteLocally();
682 ref array<ref SCR_WorkshopItemActionDownload>
m_aActions;
684 protected const ResourceName
DOWNLOAD_LINE_LAYOUT =
"{1C5D2CC10D7A1BC3}UI/layouts/Menus/ContentBrowser/DownloadManager/DownloadManager_AddonDownloadLineNonInteractive.layout";
709 comp.InitForCancelDownloadAction(action);
729 protected ref array<ref SCR_WorkshopItemActionDownload>
m_aActions = {};
730 protected ref array<SCR_DownloadManager_AddonDownloadLine> m_aLineCompents = {};
732 protected static const string TAG_ALL =
"server_download_all_cancel";
733 protected static const string TAG_REQUIRED =
"server_download_required";
734 protected static const string TAG_UNRELATED =
"server_download_unrelated_cancel";
736 protected const ResourceName
DOWNLOAD_LINE_LAYOUT =
"{1C5D2CC10D7A1BC3}UI/layouts/Menus/ContentBrowser/DownloadManager/DownloadManager_AddonDownloadLineNonInteractive.layout";
782 comp.InitForServerDownloadAction(action);
784 m_aLineCompents.Insert(comp);
787 super.OnMenuOpen(preset);
796 ref array<string> m_aItemNames = {};
801 m_aItemNames.Copy(items);
810 string message =
"#AR-Workshop_Baned_Item";
811 for (
int i = 0; i < m_aItemNames.Count(); i++)
812 message = message +
"\n- " + m_aItemNames[i];
822 ref array<ref SCR_WorkshopItem> m_aItems = {};
823 protected ref array<SCR_DownloadManager_AddonDownloadLine> m_aDownloadLines = {};
825 protected ResourceName ADDON_LINE_LAYOUT =
"{BB5AEDDA3C4134FD}UI/layouts/Menus/ContentBrowser/DownloadManager/DownloadManager_AddonDownloadLineConfirmation.layout";
831 foreach (
auto i : items)
834 if (!preset.IsEmpty())
846 Widget w =
GetGame().GetWorkspace().CreateWidgets(ADDON_LINE_LAYOUT,
layout);
849 comp.InitForWorkshopItem(item,
null,
false);
851 m_aDownloadLines.Insert(comp);
856 static SCR_AddonListDialog CreateItemsList(array<ref SCR_WorkshopItem> items,
string preset, ResourceName dialogsConfig =
"")
858 if (dialogsConfig ==
"")
863 return addonListDialog;
868 static SCR_AddonListDialog CreateRestrictedAddonsDownload(array<ref SCR_WorkshopItem> items)
870 return DisplayRestrictedAddonsList(items,
"error_restricted_dependencies_download",
"error_reported_dependencies_download");
875 static SCR_AddonListDialog CreateRestrictedAddonsJoinServer(array<ref SCR_WorkshopItem> items)
877 return DisplayRestrictedAddonsList(items,
"error_restricted_addons_join_server",
"error_reported_addons_join_server");
882 static SCR_AddonListDialog DisplayRestrictedAddonsList(array<ref SCR_WorkshopItem> items,
string tagBlocked,
string tagReported)
887 if (!banned.IsEmpty())
903 array<SCR_DownloadManager_AddonDownloadLine> GetDonwloadLines()
905 return m_aDownloadLines;
915 protected bool m_bNewEnabledValue;
918 override void OnConfirm()
924 if (item.GetOffline())
926 item.SetEnabled(m_bNewEnabledValue);
941 m_Dependency = dependency;
942 m_bNewEnabledValue =
false;
952 override void OnConfirm()
955 m_Dependency.SetEnabled(
false);
961 override void OnCancel()
964 m_Dependency.SetEnabled(
true);
976 protected const string WIDGET_TXT_TYPE_MSG =
"TxtTypeMsg";
977 protected const string WIDGET_TXT_COMMENT =
"TxtComment";
980 protected TextWidget m_wTxtTypeMsg;
981 protected TextWidget m_wTxtComment;
984 protected bool m_bAuthorReport =
false;
992 m_bAuthorReport = authorReport;
1000 string reportDescription;
1001 EWorkshopReportType reportType;
1003 if (!m_bAuthorReport)
1004 m_Item.GetReport(reportType, reportDescription);
1009 m_wTxtTypeMsg = TextWidget.Cast(
m_wRoot.FindAnyWidget(WIDGET_TXT_TYPE_MSG));
1010 m_wTxtComment = TextWidget.Cast(
m_wRoot.FindAnyWidget(WIDGET_TXT_COMMENT));
1013 if (!m_bAuthorReport)
1014 SetMessage(
"#AR-Workshop_CancelReportDescription");
1016 m_wTxtTypeMsg.SetText(reportTypeStr);
1017 m_wTxtComment.SetText(reportDescription);
1021 override void OnConfirm()
1025 m_Action =
m_Item.CancelReport();
1026 m_Action.m_OnCompleted.Insert(Callback_OnSuccess);
1027 m_Action.m_OnFailed.Insert(Callback_OnFailed);
1028 m_Action.Activate();
1030 m_OnConfirm.Invoke(
this);
1034 void Callback_OnSuccess()
1036 m_LoadingOverlayDlg.CloseAnimated();
1041 void Callback_OnFailed()
1043 m_LoadingOverlayDlg.CloseAnimated();
1075 override void OnConfirm()
1077 if (
m_Item.GetSubscribed())
1078 m_Item.SetSubscribed(
false);
1084 if (item.GetEnabled())
1085 item.SetEnabled(
false);
1098 protected const string LOADING_BACKGROUND_IMAGE =
"{75455009AFED376B}UI/Textures/Workshop/AddonThumbnails/workshop_loading_UI.edds";
1110 override void ShowDefaultImage()
1121 override void ShowLoadingImage(
string fallbackImage)
1126 if (fallbackImage.IsEmpty())
1136 super.ShowLoadingImage(fallbackImage);
1142 class SCR_ScenarioBackendImageComponent : SCR_BackendImageComponent
1144 protected ref MissionWorkshopItem
m_Scenario;
1170 if (fallbackImage.IsEmpty())
1181 super.ShowLoadingImage(fallbackImage);