13 const string TAG_DETAILS_FALLBACK_SEACHING =
"Searching";
14 const string TAG_DETAILS_FALLBACK_EMPTY =
"Empty";
15 const string TAG_MESSAGE_SEARCHING =
"SEARCHING";
16 const string TAG_MESSAGE_CONNECTING =
"CONNECTING";
18 const int SERVER_LIST_VIEW_SIZE = 32;
19 const int ROOM_CONTENT_LOAD_DELAY = 500;
20 const int ROOM_REFRESH_RATE = 10 * 1000;
24 static const int HIGH_PING_SERVER_THRESHOLD = 200;
80 protected ref RoomJoinData
m_JoinData =
new RoomJoinData();
98 protected ref SCR_GetRoomsIds
m_SearchIds =
new SCR_GetRoomsIds();
135 if (workshopApi && workshopApi.NeedAddonsScan())
136 workshopApi.ScanOfflineItems();
168 GetGame().GetGameBlocklist().UpdateBlockList();
176 newsButton.SetVisible(
false);
177 newsButton.SetEnabled(
false);
200 super.OnMenuOpened();
214 super.OnMenuFocusGained();
257 super.OnMenuUpdate(tDelta);
268 EInputDeviceType inputDeviceType =
GetGame().GetInputManager().GetLastUsedInputDevice();
271 if (shouldUpdateButtons)
299 bool versionMismatch, unjoinable;
300 bool enabled = entry && entry.
GetIsEnabled(versionMismatch, unjoinable);
301 bool visible = entry &&
GetGame().GetInputManager().GetLastUsedInputDevice() != EInputDeviceType.MOUSE;
304 m_Widgets.m_JoinButton.SetVisible(visible && !unjoinable,
false);
307 m_Widgets.m_DetailsButton.SetVisible(visible && !unjoinable,
false);
310 m_Widgets.m_FavoritesButton.SetVisible(visible && enabled,
false);
312 if (!enabled || !visible)
355 if (!SocialComponent.IsMultiplayerAllowed())
397 if (!multiplayerDialog)
401 multiplayerDialog.m_OnConfirm.Clear();
405 multiplayerDialog.m_OnCancel.Clear();
416 SCR_EListMenuWidgetFocus focus = SCR_EListMenuWidgetFocus.FILTERING;
418 focus = SCR_EListMenuWidgetFocus.LIST;
421 m_FilterPanel.ShowFilterListBox(focus == SCR_EListMenuWidgetFocus.FILTERING);
455 if (room && room.Joinable())
467 switch (
Math.Floor(multiplier))
512 m_bQuickJoin =
GetGame().GetInputManager().GetLastUsedInputDevice() != EInputDeviceType.MOUSE;
515 if (entry.GetRoomInfo() && entry.GetRoomInfo().Joinable())
532 string lastId =
m_Lobby.GetPreviousRoomId();
534 if (!
m_Lobby.IsPingAvailable())
564 m_Dialogs.DisplayDialog(EJoinDialogState.BACKEND_TIMEOUT);
640 int currentRoomsCount =
m_Lobby.TotalRoomCount();
653 if (!SocialComponent.IsMultiplayerAllowed())
659 PrintDebug(
"Missing important component references!",
"DisplayRooms");
667 PrintDebug(
"Could not find addon mngr to verify ugc privilege",
"DisplayRooms");
685 int roomCount =
m_Lobby.TotalRoomCount();
777 m_Lobby.SetViewSize(SERVER_LIST_VIEW_SIZE);
794 PrintDebug(
string.Format(
"Success - servers found: %1",
m_Lobby.TotalRoomCount()),
"OnSearchRoomsSuccess");
807 if (callback.GetRestResult() ==
ERestResult.EREST_ERROR_TIMEOUT)
810 PrintDebug(
"time out!",
"OnSearchRoomsTimeOut");
814 PrintDebug(
string.Format(
"Room search fail - code: %1 | restCode: %2 | apiCode: %3", callback.GetHttpCode(), callback.GetRestResult(), callback.GetApiCode()),
"OnSearchRoomsFail");
835 string strParams = lobby.GetStrParams();
836 if (!strParams.IsEmpty())
887 m_Lobby.SetRefreshRate(ROOM_REFRESH_RATE);
957 if (!room.IsAuthorized())
961 array<Dependency> roomMod = {};
962 room.GetItems(roomMod);
969 if (room.IsDownloadListLoaded())
1020 m_TabView.AddTab(
"",
"#AR-Workshop_ButtonHost");
1060 array<SCR_ServerBrowserEntryComponent> entries =
m_ScrollableList.GetRoomEntries();
1111 bool isCrossEnabled =
GetGame().IsCrossPlayEnabled();
1122 if (enabled.m_FilterComponent)
1124 enabled.m_FilterComponent.SetVisible(isCrossEnabled);
1125 enabled.m_FilterComponent.SetEnabled(isCrossEnabled);
1138 if (disabled.m_FilterComponent)
1140 disabled.m_FilterComponent.SetVisible(isCrossEnabled);
1141 disabled.m_FilterComponent.SetEnabled(isCrossEnabled);
1145 m_FilterPanel.SelectFilter(disabled, !isCrossEnabled,
false);
1153 protected void SwitchFocus(SCR_EListMenuWidgetFocus focus,
bool force =
false)
1162 case SCR_EListMenuWidgetFocus.LIST:
1172 case SCR_EListMenuWidgetFocus.FILTERING:
1178 case SCR_EListMenuWidgetFocus.SORTING:
1180 focusTarget =
m_Widgets.m_wSortSessionFavorite;
1187 if (!focusTarget || !focusTarget.IsVisible())
1190 focusTarget =
m_Widgets.m_wSortSessionFavorite;
1194 GetGame().GetWorkspace().SetFocusedWidget(focusTarget);
1204 filter.m_sInternalName = filterName;
1238 SCR_FilterEntry targetFilter = filterSet.FindFilter(filter.m_sInternalName);
1241 if (targetFilter && targetFilter.
GetSelected() != filter.GetSelected())
1260 GetGame().GetWorkspace().SetFocusedWidget(w);
1288 m_Widgets.m_wContent.SetVisible(!showWrap);
1290 m_Widgets.m_wPanelEmpty.SetVisible(showWrap);
1302 m_Widgets.m_RefreshButton.SetVisible(!showWrap,
false);
1305 m_Widgets.m_DirectJoinButton.SetVisible(!showWrap,
false);
1308 m_Widgets.m_FilterButton.SetVisible(!showWrap,
false);
1329 wrapLayout.SetVisible(
false);
1370 m_Widgets.m_wHostNewServerButton.SetVisible(
false);
1373 bool onlyFavorite =
id == SCR_EServerBrowserTabs.FAVORITES;
1374 bool onlyOfficial =
id == SCR_EServerBrowserTabs.OFFICIAL;
1375 bool onlyCommunity =
id == SCR_EServerBrowserTabs.COMMUNITY;
1376 bool onlyRecent =
id == SCR_EServerBrowserTabs.RECENT;
1377 bool onlyOwned =
id == SCR_EServerBrowserTabs.HOST;
1391 m_Widgets.m_wHostNewServerButton.SetVisible(onlyOwned);
1392 m_Widgets.m_wHostNewServerButton.SetEnabled(onlyOwned);
1419 if (show ||
m_Lobby.TotalRoomCount() == 0)
1437 if (!
GetGame().IsCrossPlayEnabled() && filter.
GetCategory().m_sInternalName ==
"Crossplay")
1451 if (callback.GetRestResult() ==
ERestResult.EREST_ERROR_TIMEOUT)
1453 PrintDebug(
"Scroll timeout!",
"OnScrollResponse");
1456 PrintDebug(
"Scroll error!",
"OnScrollResponse");
1463 bool loadedRoomFocused =
false;
1465 loadedRoomFocused =
true;
1472 PrintDebug(
"No room found",
"OnScrollSuccess");
1474 if (
m_Lobby.TotalRoomCount() > 0)
1488 if (loadedRoomFocused)
1506 int pos = entriesC * page;
1512 array<Room> rooms = {};
1541 int roomId =
m_aRooms.Find(roomClicked);
1571 if (callback.GetRestResult() ==
ERestResult.EREST_ERROR_TIMEOUT)
1573 PrintDebug(
"Timeout!",
"OnRoomSetFavoriteResponse");
1577 PrintDebug(
"Error!",
"OnRoomSetFavoriteResponse");
1601 string lastId =
m_Lobby.GetPreviousRoomId();
1620 Dependency scenarioMod = room.HostScenarioMod();
1638 m_Dialogs.UpdateRoomDetailsScenarioImage(scenarioItem);
1639 m_Dialogs.UpdateServerFullScenarioImage(scenarioItem);
1660 PrintDebug(
"No room found for can join room check",
"CanJoinRoom");
1669 return versionMatch && !
m_ModsManager.HasBlockedMods() && room.Joinable();
1678 string clientV =
GetGame().GetBuildVersion();
1679 string roomV = room.GameVersion();
1682 return (clientV == roomV);
1700 Widget wfocused =
GetGame().GetWorkspace().GetFocusedWidget();
1705 EInputDeviceType inputDevice =
GetGame().GetInputManager().GetLastUsedInputDevice();
1708 if (inputDevice == EInputDeviceType.MOUSE && (
GetEntryUnderCursor() || isCursorOnInnerButton))
1753 m_Widgets.m_HostButton.SetScenario(scenario);
1765 string scenarioId = mission.Id();
1774 if (modId !=
string.Empty)
1786 return room && room.GetPing() >= HIGH_PING_SERVER_THRESHOLD;
1804 PrintDebug(
"Quick join is not possible because there is no selected server",
"JoinActions_Join");
1849 PrintDebug(
"Invalid format of direct join",
"JoinProcess_FindRoom");
1861 m_Dialogs.DisplayDialog(EJoinDialogState.SEARCHING_SERVER);
1875 PrintDebug(
"No room found through direct join!",
"JoinProcess_OnFindRoomSuccess");
1902 m_Dialogs.DisplayDialog(EJoinDialogState.SERVER_NOT_FOUND);
1931 m_Dialogs.DisplayDialog(EJoinDialogState.SEARCHING_SERVER);
1999 m_Dialogs.DisplayDialog(EJoinDialogState.VERSION_MISMATCH);
2014 m_Dialogs.DisplayDialog(EJoinDialogState.HIGH_PING_SERVER);
2066 m_Dialogs.DisplayDialog(EJoinDialogState.PASSWORD_REQUIRED);
2083 Print(
"ServerBrowserMenuUI - OnPasswordVerified() - NULL ROOM");
2098 m_Dialogs.DisplayDialog(EJoinDialogState.PASSWORD_REQUIRED);
2128 if (!blockedPlayers || blockedPlayers.IsEmpty())
2134 m_Dialogs.CreateBlockedPlayersWarningDialog(blockedPlayers);
2157 array<ref SCR_WorkshopItem> items = {};
2158 array<Dependency> dependencies = {};
2161 if (
m_ModsManager.GetRoomItemsScripted().Count() == dependencies.Count())
2170 if (!dependencies.IsEmpty())
2209 array<Dependency> deps = {};
2215 m_Dialogs.DisplayDialog(EJoinDialogState.MOD_UGC_PRIVILEGE_MISSING);
2234 array<ref SCR_WorkshopItem> updated =
m_ModsManager.GetRoomItemsUpdated();
2235 array<ref SCR_WorkshopItem> outdated =
m_ModsManager.GetRoomItemsToUpdate();
2238 bool modsUpdated = outdated.IsEmpty();
2273 m_Dialogs.DisplayDialog(EJoinDialogState.CHECKING_CONTENT);
2326 array<ref SCR_WorkshopItem> items =
m_ModsManager.GetRoomItemsScripted();
2329 bool restricted = restricedMods.Count() > 0;
2346 array<ref SCR_WorkshopItem> items =
m_ModsManager.GetRoomItemsScripted();
2370 m_Dialogs.DisplayDialog(EJoinDialogState.UNRELATED_DOWNLOADS_CANCELING);
2388 array<ref SCR_WorkshopItem> items =
m_ModsManager.GetRoomItemsScripted();
2390 if (!downloads.IsEmpty())
2405 array<ref SCR_WorkshopItem> items =
m_ModsManager.GetRoomItemsScripted();
2458 int nCompleted, nTotal;
2478 PrintDebug(
"Missing m_JoinProcessTargetRoom!",
"OnInteruptDownloadConfirm");
2494 m_Dialogs.DisplayDialog(EJoinDialogState.JOIN);
2517 GetGame().GetMenuManager().CloseAllMenus();
2518 GetGame().GetBackendApi().GetWorkshop().Cleanup();
2534 if (callback.GetRestResult() ==
ERestResult.EREST_ERROR_TIMEOUT)
2546 if (apiCode ==
EApiCode.EACODE_ERROR_MP_ROOM_QUEUE_JOIN)
2548 else if (apiCode ==
EApiCode.EACODE_ERROR_MP_ROOM_QUEUE_FULL)
2550 else if (apiCode ==
EApiCode.EACODE_ERROR_MP_ROOM_IS_FULL)
2570 dialog.
Init(joinRoom, result, joinRoom.HostScenario());
2626 m_Lobby.GetJoinRoom().LeaveJoinQueue();
2638 EApiCode apiCode = callback.GetApiCode();
2645 if (apiCode ==
EApiCode.EACODE_ERROR_MP_ROOM_QUEUE_WAIT)
2680 m_Dialogs.GetOnJoinProcessCancel().Clear();
2681 m_Dialogs.GetOnDownloadComplete().Clear();
2701 m_Dialogs.GetOnDownloadComplete().Clear();
2775 protected void PrintDebug(
string msg,
string functionName =
string.Empty)
2779 string fncStr =
string.Empty;
2780 if (functionName !=
string.Empty)
2781 fncStr =
string.Format(
" Fnc: %1()", functionName);
2784 PrintFormat(
"[ServerBrowserMenuUI]%1 -- Msg: %2", fncStr, msg);
2791class SCR_GetRoomsIds
extends GetRoomsIds
2818enum SCR_EServerBrowserTabs
bool IsPlatformGameConsole()
ArmaReforgerScripted GetGame()
InputManager GetInputManager()
ScriptInvokerBase< ScriptInvokerVoidMethod > ScriptInvokerVoid
SCR_EJoinDownloadsConfirmationDialogType
Enum for confirmation dialogs that guide the player through the download processes required to join t...
proto native void Close()
GameSessionStorage is used to store data for whole lifetime of game executable run....
ref ScriptInvoker m_OnUgcPrivilegeResult
void NegotiateUgcPrivilegeAsync()
static array< ref SCR_WorkshopItem > SelectItemsBasic(array< ref SCR_WorkshopItem > items, EWorkshopItemQuery query)
bool GetUgcPrivilege()
Returns immediate value of UserPrivilege.USER_GEN_CONTENT.
static array< ref SCR_WorkshopItem > SelectItemsOr(array< ref SCR_WorkshopItem > items, EWorkshopItemQuery query)
static SCR_AddonManager GetInstance()
static SCR_ConfigurableDialogUi CreateFromPreset(ResourceName presetsResourceName, string tag, SCR_ConfigurableDialogUi customDialogObj=null)
Creates a dialog from preset.
void GetDownloadQueueState(out int nCompleted, out int nTotal)
Might get delayed by a frame! Just use it for UI.
void ClearFailedDownloads()
static SCR_DownloadManager GetInstance()
array< ref SCR_WorkshopItemActionDownload > GetDownloadQueue()
array< ref SCR_WorkshopItemActionDownload > DownloadItems(array< ref SCR_WorkshopItem > items)
array< ref SCR_WorkshopItemActionDownload > GetUnrelatedDownloads(array< ref SCR_WorkshopItem > requiredItems)
ref ScriptInvoker m_OnConfirm
Widget m_wCategoryTitleWidget
SCR_FilterEntry FindFilter(string internalName)
Finds a filter by internal name.
bool GetSelected(bool defaultValue=false)
Returns the selected flag.
SCR_FilterCategory GetCategory()
Returns the category of this filter.
void SetSelected(bool newValue)
Sets the selected flag, doesn't do anything special.
SCR_FilterCategory FindFilterCategory(string internalName)
Finds a filter category by its internal name.
static void SetReconnectEnabled(bool enabled)
static ScriptInvokerVoid GetOnCancel()
static ScriptInvokerVoid GetOnReconnect()
Pooled scrollable list with server entries handling.
Show list of reported mods and provide option to cancel reports.
ScriptInvoker GetOnAllReportsCanceled()
Scripted room callback specific for single room.
This component handles server entry and visiualization of server data.
bool GetIsEnabled(out bool versionMismatch, out bool unjoinable)
ref ScriptInvoker m_OnFavorites
void SetCanJoin(bool canJoin)
ScriptInvokerRoom GetOnRetryFullServerJoin()
void Init(Room room, SCR_EJoinFailUI mode, MissionWorkshopItem scenario, ScriptInvokerVoid onFavoritesResponse=null)
ScriptInvokerVoid GetOnLeaveQueueRequest()
ScriptInvokerVoid GetOnFavorite()
static const int CONNECTION_CHECK_EXPIRE_TIME
static bool IsAuthenticated()
static bool IsBackendReady()
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
proto void PrintFormat(string fmt, void param1=NULL, void param2=NULL, void param3=NULL, void param4=NULL, void param5=NULL, void param6=NULL, void param7=NULL, void param8=NULL, void param9=NULL, LogLevel level=LogLevel.NORMAL)
@ GENERIC
Default entity type (inherited from GenericEntity).
@ ALL
Everything except general switch.
ERestResult
States and result + error code produced by RestApi.