17 protected static int s_iLastPingUpdate = -1;
18 protected static int s_iLastStatusUpdate = -1;
19 protected static ServiceStatusItem s_MainStatus;
20 protected static const ref array<ServiceStatusItem> SERVICE_STATUSES = {};
23 protected static const int COMM_STATUS_CHECK_FREQUENCY_MS = 500;
24 protected static const int FIRST_REFRESH_DELAY = 1000;
26 static const int REFRESH_COOLDOWN = 10000;
27 static const int CONNECTION_CHECK_EXPIRE_TIME = 15000;
28 static const int AUTOMATIC_REFRESH_RATE = 60000;
31 static const string STATUS_OK =
"ok";
32 static const string STATUS_ERROR =
"error";
35 static const string SERVICE_ACCOUNT_PROFILE =
"game-identity";
36 static const string SERVICE_XBOX =
"game-identity";
37 static const string SERVICE_BI_BACKEND_MULTIPLAYER =
"game-api";
38 static const string SERVICE_WORKSHOP =
"reforger-workshop-api";
41 static const int PING_MAX = 999;
42 static const int PING_THRESHOLD_GOOD = 100;
43 static const int PING_THRESHOLD_BAD = 300;
44 static const int PING_THRESHOLD_AWFUL = 600;
47 protected static bool s_bIsCheckingCommStatus;
48 protected static float s_fLastReceivedCommResponseTime;
50 protected static float s_fPingStartTime;
52 protected static bool s_bFirstRefresh =
true;
59 static bool IsBackendEnabled()
61 return GetGame().GetBackendApi() &&
GetGame().GetBackendApi().IsRunning();
65 static bool IsBackendReady()
67 return GetGame().GetBackendApi() &&
GetGame().GetBackendApi().IsActive();
71 static bool IsBackendInitializing()
73 return GetGame().GetBackendApi() &&
GetGame().GetBackendApi().IsInitializing();
80 protected static bool IsPinging()
82 return GetGame().GetBackendApi() &&
GetGame().GetBackendApi().GetCommTestStatus() == 1;
89 static void RefreshPing()
94 if (!s_bFirstRefresh && !CanRefresh())
97 if (IsInRefreshCooldown())
100 GetGame().GetCallqueue().CallLater(RefreshPing, (REFRESH_COOLDOWN - GetPingAge()) + 100);
110 s_bFirstRefresh =
false;
111 s_bIsCheckingCommStatus =
true;
114 GetGame().GetCallqueue().CallLater(RefreshPing_Internal, FIRST_REFRESH_DELAY);
118 RefreshPing_Internal();
122 protected static void RefreshPing_Internal()
125 if (IsBackendReady())
126 GetGame().GetBackendApi().RefreshCommStatus();
130 s_fPingStartTime = System.GetTickCount();
136 protected static void StartStatusCheck()
138 s_bIsCheckingCommStatus =
true;
140 if (s_OnCommStatusCheckStart)
141 s_OnCommStatusCheckStart.Invoke();
144 GetGame().GetCallqueue().CallLater(CheckStatus, COMM_STATUS_CHECK_FREQUENCY_MS);
148 protected static void CheckStatus()
150 s_bIsCheckingCommStatus =
false;
152 if (IsBackendReady())
155 CheckBackendStatus();
161 protected static void CheckCommStatus()
163 BackendApi backend =
GetGame().GetBackendApi();
166 if (IsPinging() && !IsPingingStuck())
175 if (!backend || IsPingingStuck() || !IsBackendReady())
178 s_eLastReceivedCommStatus = backend.GetCommTestStatus();
184 s_iLastPingUpdate = System.GetTickCount();
185 s_fLastReceivedCommResponseTime = backend.GetCommResponseTime();
188 if (s_OnCommStatusCheckFinished)
189 s_OnCommStatusCheckFinished.Invoke(s_eLastReceivedCommStatus, s_fLastReceivedCommResponseTime, backend.GetCommTimeLastSuccess(), backend.GetCommTimeLastFail());
194 protected static void CheckBackendStatus()
197 if (!
GetGame().GetBackendApi() || IsPingingStuck())
203 if (IsBackendReady())
204 RefreshPing_Internal();
210 static void ClearRefreshQueue()
212 GetGame().GetCallqueue().Remove(RefreshPing);
218 return s_eLastReceivedCommStatus;
224 static int GetPingValue()
226 if (!IsBackendReady() || s_eLastReceivedCommStatus ==
SCR_ECommStatus.FAILED)
229 return Math.Round(s_fLastReceivedCommResponseTime);
234 static int GetPingAge()
236 return System.GetTickCount() - s_iLastPingUpdate;
241 static bool CanRefresh()
243 return !s_bIsCheckingCommStatus && !IsInRefreshCooldown();
247 static bool IsInRefreshCooldown()
249 return GetPingAge() < REFRESH_COOLDOWN;
253 static bool IsPingingStuck()
255 return System.GetTickCount() - s_fPingStartTime >= CONNECTION_CHECK_EXPIRE_TIME;
262 static void RefreshStatuses()
264 if (!IsBackendReady())
267 s_MainStatus =
GetGame().GetBackendApi().GetMainStatus();
269 SERVICE_STATUSES.Clear();
270 ServiceStatusItem item;
271 for (
int i, cnt =
GetGame().GetBackendApi().GetStatusCount(); i < cnt; i++)
273 item =
GetGame().GetBackendApi().GetStatusItem(i);
275 SERVICE_STATUSES.Insert(item);
278 s_iLastStatusUpdate = System.GetTickCount();
280 #ifdef SERVICES_DEBUG
286 static ServiceStatusItem GetMainStatus()
294 static ServiceStatusItem GetStatusByName(
string statusName)
296 ServiceStatusItem result;
298 statusName.ToLower();
299 string serviceNameLC;
301 foreach (ServiceStatusItem statusItem : SERVICE_STATUSES)
303 serviceNameLC = statusItem.Name();
304 serviceNameLC.ToLower();
306 if (serviceNameLC == statusName)
314 static void GetStatuses(notnull array<ServiceStatusItem> statuses)
316 statuses.Copy(SERVICE_STATUSES);
320 static bool AreServicesReady()
322 return s_MainStatus && !SERVICE_STATUSES.IsEmpty();
327 static int GetStatusesAge()
329 if (!IsBackendReady())
332 return Math.Round((System.GetTickCount() - s_iLastStatusUpdate) * 0.001);
338 return !
GetGame().IsPlatformGameConsole() && service.m_bConsoleExclusive;
342 static bool IsServiceActive(
string serviceName)
347 ServiceStatusItem serviceStatus = GetStatusByName(serviceName);
351 return serviceStatus.Status() == STATUS_OK;
356 static bool AreMultiplayerServicesAvailable()
358 return IsServiceActive(SERVICE_BI_BACKEND_MULTIPLAYER);
362 static bool IsBackendConnectionAvailable()
372 if (!s_OnCommStatusCheckFinished)
375 return s_OnCommStatusCheckFinished;
381 if (!s_OnCommStatusCheckStart)
384 return s_OnCommStatusCheckStart;
390 Print(
"--------------------------------------------------");
391 Print(
"SERVICE STATUS DEBUG");
392 Print(
"--------------------------------------------------");
393 if (!
GetGame().GetBackendApi())
395 Print(
"no backend API found.");
399 Print(
"is main service found: " + (
GetGame().GetBackendApi().GetMainStatus() !=
null));
400 Print(
"number of services found: " +
GetGame().GetBackendApi().GetStatusCount());
403 PrintFormat(
"Service %1: %2 (Name/Status/Message: %3/%4/%5)", -1, s_MainStatus, s_MainStatus.Name(), s_MainStatus.Status(), s_MainStatus.Message());
405 Print(
"Main Status not found");
407 foreach (
int index, ServiceStatusItem statusItem : SERVICE_STATUSES)
410 PrintFormat(
"Service %1: %2 (Name/Status/Message: %3/%4/%5)",
index, statusItem, statusItem.Name(), statusItem.Status(), statusItem.Message());
413 Print(
"--------------------------------------------------");
420 class SCR_BackendServiceDisplayPresets
423 protected ref array<ref SCR_BackendServiceDisplay> m_aServices;
428 array<ref SCR_BackendServiceDisplay> services = {};
430 services = m_aServices;
449 [
Attribute(
"0",
desc:
"set true if this service should be ignored when on PC")]
450 bool m_bConsoleExclusive;